From 7c0db166f81fbe8c8b913d7f26048e337d383605 Mon Sep 17 00:00:00 2001 From: short <> Date: Thu, 1 May 2003 10:15:18 +0000 Subject: [PATCH] update for HEAD-2003050101 --- ChangeLog | 309 + INSTALL | 3 +- Makefile | 382 +- NEWS | 15 - README | 26 +- apps/tests/Makefile | 15 +- apps/tests/bitblt/bitblt.c | 137 + apps/tests/bitblt/bitblt.cpp | 138 - apps/tests/bitblt/makefile | 66 +- apps/tests/dibtest/dibtest.c | 239 +- apps/tests/dibtest/makefile | 2 +- apps/tests/hivetest/hivetest.c | 48 +- apps/tests/lpc/makefile | 11 + apps/tests/{simple => messagebox}/.cvsignore | 0 apps/tests/{simple => messagebox}/makefile | 0 apps/tests/{simple => messagebox}/simple.c | 0 apps/tests/mstest/Makefile | 11 + apps/tests/nptest/Makefile | 11 + apps/tests/patblt/patblt.cpp | 4 + apps/tests/shaptest/makefile | 21 + apps/tests/shaptest/shaptest.c | 192 + apps/tests/shm/makefile | 11 + apps/tests/tests/hello2/.cvsignore | 3 - apps/tests/tests/hello2/Makefile | 26 - apps/tests/tests/hello2/hello2.c | 9 - apps/tests/wm_erasebkgnd/BACKBITMAP.BMP | Bin 0 -> 26566 bytes apps/tests/wm_erasebkgnd/Demo_WM_ERASEBKGND.cpp | 175 + apps/tests/wm_erasebkgnd/makefile | 66 + apps/tests/wm_paint/Listing1_1.cpp | 129 - apps/tests/wm_paint/makefile | 66 +- apps/tests/wm_paint/wm_paint.c | 128 + apps/testsets/Makefile | 60 +- apps/utils/Makefile | 20 +- apps/utils/cabman/main.cpp | 2 +- apps/utils/cabman/makefile | 64 +- apps/utils/pice/makefile | 20 +- baseaddress.cfg | 3 + bootc.lst | 2 +- bootcd.bat | 35 +- bootdata/hivecls.inf | 15 + bootdata/hivedef.inf | 12 + bootdata/hivesft.inf | 10 + bootdata/hivesys.inf | 324 + bootdata/readme.txt | 55 + bootdata/txtsetup.sif | 111 + drivers/bus/pci/pci.c | 4 +- drivers/dd/blue/blue.c | 12 +- drivers/dd/blue/makefile | 2 + drivers/dd/floppy/Makefile | 2 + drivers/dd/floppy/floppy.c | 16 +- drivers/dd/floppy/floppy.h | 2 +- drivers/dd/floppy/isr.c | 15 + drivers/dd/mouse/.cvsignore | 1 - drivers/dd/mouse/makefile | 13 - drivers/dd/mouse/mouse.c | 270 - drivers/dd/vga/display/main/enable.c | 4 +- drivers/dd/vga/display/makefile | 3 +- drivers/dd/vga/display/objects/bitblt.c | 18 +- drivers/dd/vga/display/objects/copybits.c | 39 + drivers/dd/vga/display/objects/lineto.c | 129 +- drivers/dd/vga/display/objects/pointer.c | 22 +- drivers/dd/vga/display/vgavideo/vgavideo.c | 74 +- drivers/dd/vga/makefile | 24 +- drivers/dd/vga/miniport/makefile | 2 +- drivers/dd/videoprt/.cvsignore | 4 + drivers/dd/videoprt/Makefile | 15 + drivers/dd/videoprt/videoprt.c | 1215 +++ .../{vidport/vidport.def => videoprt/videoprt.def} | 0 .../{vidport/vidport.edf => videoprt/videoprt.edf} | 0 .../{vidport/vidport.rc => videoprt/videoprt.rc} | 0 drivers/dd/vidport/.cvsignore | 4 - drivers/dd/vidport/makefile | 15 - drivers/dd/vidport/vidport.c | 806 -- drivers/dd/vidport/vidport.h | 16 - drivers/fs/cdfs/cdfs.h | 1 - drivers/fs/cdfs/cleanup.c | 11 +- drivers/fs/cdfs/close.c | 5 +- drivers/fs/cdfs/create.c | 9 +- drivers/fs/cdfs/dirctl.c | 2 +- drivers/fs/cdfs/fcb.c | 10 +- drivers/fs/cdfs/fsctl.c | 4 +- drivers/fs/cdfs/makefile | 2 + drivers/fs/cdfs/rw.c | 4 +- drivers/fs/ntfs/create.c | 5 +- drivers/fs/ntfs/dirctl.c | 2 +- drivers/fs/ntfs/fcb.c | 12 +- drivers/fs/ntfs/fsctl.c | 4 +- drivers/fs/ntfs/makefile | 2 + drivers/fs/ntfs/ntfs.h | 1 - drivers/fs/vfat/cleanup.c | 40 +- drivers/fs/vfat/close.c | 24 +- drivers/fs/vfat/create.c | 24 +- drivers/fs/vfat/dir.c | 2 +- drivers/fs/vfat/dirwr.c | 6 +- drivers/fs/vfat/fcb.c | 18 +- drivers/fs/vfat/finfo.c | 4 +- drivers/fs/vfat/flush.c | 11 +- drivers/fs/vfat/fsctl.c | 10 +- drivers/fs/vfat/makefile | 2 + drivers/fs/vfat/misc.c | 19 +- drivers/fs/vfat/rw.c | 18 +- drivers/fs/vfat/vfat.h | 39 +- drivers/input/include/mouse.h | 50 - drivers/input/keyboard/makefile | 2 + drivers/input/mouclass/mouclass.c | 67 +- drivers/input/mouclass/mouclass.h | 3 + drivers/input/psaux/mouse.c | 217 +- drivers/input/psaux/mouse.h | 70 +- drivers/input/psaux/psaux.c | 9 +- drivers/input/psaux/psaux.h | 3 +- drivers/input/sermouse/mouse.c | 272 - drivers/input/sermouse/mouse.h | 12 - drivers/input/sermouse/sermouse.c | 382 +- drivers/input/sermouse/sermouse.h | 80 - drivers/lib/zlib/Make_vms.com | 115 - drivers/lib/zlib/Makefile | 31 - drivers/lib/zlib/contrib/asm386/zlibvc.dsp | 651 -- drivers/lib/zlib/contrib/asm386/zlibvc.dsw | 41 - drivers/lib/zlib/contrib/minizip/zlibvc.dsp | 651 -- drivers/lib/zlib/contrib/minizip/zlibvc.dsw | 41 - drivers/lib/zlib/makefile.reactos | 26 - drivers/net/ndis/ndis.def | 2 +- drivers/net/ndis/ndis.edf | 2 +- drivers/net/ndis/ndis/miniport.c | 16 +- drivers/net/ndis/ndis/stubs.c | 5 +- drivers/net/packet/Makefile | 11 +- drivers/storage/atapi/atapi.c | 5 +- drivers/storage/atapi/makefile | 2 + drivers/storage/cdrom/makefile | 2 + drivers/storage/class2/class2.c | 11 +- drivers/storage/class2/makefile | 2 + drivers/storage/disk/disk.c | 906 +- drivers/storage/disk/disk.h | 250 - drivers/storage/disk/makefile | 2 + drivers/storage/disk/partitio.h | 41 - drivers/storage/scsiport/makefile | 2 + drivers/storage/scsiport/scsiport.c | 19 +- hal/halx86/Makefile | 4 +- hal/halx86/bios32.c | 144 - hal/halx86/bus.c | 89 +- hal/halx86/drive.c | 8 +- hal/halx86/halinit.c | 5 +- hal/halx86/include/hal.h | 8 + hal/halx86/include/mps.h | 10 + hal/halx86/isa.c | 10 + hal/halx86/mbr.c | 25 - hal/halx86/mp.c | 117 +- hal/halx86/mpsirql.c | 367 +- hal/halx86/pci.c | 168 +- hal/halx86/sysbus.c | 16 +- hal/halx86/sysinfo.c | 59 +- iface/addsys/w32ksvc.db | 2 + include/ascii.h | 8 +- include/base.h | 5 +- include/basetsd.h | 2 +- include/csrss/csrss.h | 46 +- include/ddk/cctypes.h | 1 - include/ddk/class2.h | 2 +- include/ddk/cmtypes.h | 3 +- include/ddk/defines.h | 6 +- include/ddk/exfuncs.h | 5 +- include/ddk/extypes.h | 4 +- include/ddk/fsfuncs.h | 108 +- include/ddk/fstypes.h | 9 + include/ddk/halfuncs.h | 26 +- include/ddk/haltypes.h | 39 +- include/ddk/iodef.h | 11 + include/ddk/iofuncs.h | 4 +- include/ddk/iotypes.h | 44 +- include/ddk/kefuncs.h | 3 + include/ddk/ketypes.h | 6 +- include/ddk/ntddblue.h | 10 +- include/ddk/ntddk.h | 3 +- include/ddk/ntddmou.h | 71 + include/ddk/ntddvid.h | 10 + include/ddk/ntifs.h | 6 +- include/ddk/obtypes.h | 19 +- include/ddk/psfuncs.h | 5 +- include/ddk/pstypes.h | 3 + include/ddk/sefuncs.h | 8 + include/ddk/setypes.h | 9 + include/ddk/winddi.h | 2 +- include/debug.h | 57 +- include/defines.h | 35 +- include/epsapi.h | 227 + include/freetype/config/ftconfig.h | 187 - include/freetype/config/ftmodule.h | 10 - include/freetype/config/ftoption.h | 395 - include/freetype/freetype.h | 2286 ----- include/freetype/ftbbox.h | 72 - include/freetype/fterrors.h | 166 - include/freetype/ftglyph.h | 422 - include/freetype/ftimage.h | 1003 -- include/freetype/ftmm.h | 175 - include/freetype/ftmodule.h | 274 - include/freetype/ftnames.h | 52 - include/freetype/ftoutln.h | 344 - include/freetype/ftrender.h | 191 - include/freetype/ftsystem.h | 101 - include/freetype/fttypes.h | 400 - include/freetype/internal/autohint.h | 195 - include/freetype/internal/ftcalc.h | 123 - include/freetype/internal/ftdebug.h | 232 - include/freetype/internal/ftdriver.h | 182 - include/freetype/internal/ftextend.h | 178 - include/freetype/internal/ftlist.h | 113 - include/freetype/internal/ftmemory.h | 127 - include/freetype/internal/ftobjs.h | 532 -- include/freetype/internal/ftstream.h | 361 - include/freetype/internal/psnames.h | 220 - include/freetype/internal/sfnt.h | 492 - include/freetype/internal/t1errors.h | 67 - include/freetype/internal/t1types.h | 188 - include/freetype/internal/t2errors.h | 121 - include/freetype/internal/t2types.h | 218 - include/freetype/internal/tterrors.h | 121 - include/freetype/internal/tttypes.h | 1582 ---- include/freetype/t1tables.h | 235 - include/freetype/ttnameid.h | 698 -- include/freetype/tttables.h | 583 -- include/freetype/tttags.h | 66 - include/fslib/vfatlib.h | 28 + include/funcs.h | 6 + include/getopt.h | 52 +- include/kernel32/error.h | 9 +- include/kernel32/kernel32.h | 8 + include/msvcrt/ctype.h | 4 +- include/msvcrt/internal/tls.h | 3 + include/msvcrt/sys/stat.h | 41 +- include/napi/i386/floatsave.h | 11 + include/napi/i386/segment.h | 341 - include/napi/teb.h | 85 +- include/net/ndis.h | 10 +- include/ntdll/dbg.h | 4 + include/ntdll/rtl.h | 15 + include/ntos/rtl.h | 27 +- include/ntos/rtltypes.h | 18 +- include/ntos/synch.h | 3 + include/ntos/types.h | 22 +- include/ntos/zw.h | 199 +- include/ntos/zwtypes.h | 150 +- include/reactos/version.h | 4 +- include/rosrtl/thread.h | 53 + include/structs.h | 465 +- include/tchar.h | 4 +- include/unicode.h | 8 +- include/win32k/bitmaps.h | 1 + include/win32k/debug1.h | 42 +- include/win32k/misc.h | 3 + include/win32k/ntuser.h | 85 +- include/win32k/region.h | 5 + include/win32k/text.h | 20 +- install.bat | 15 +- lib/advapi32/advapi32.def | 17 +- lib/advapi32/makefile | 10 +- lib/advapi32/misc/.cvsignore | 1 + lib/advapi32/reg/.cvsignore | 1 + lib/advapi32/reg/reg.c | 723 +- lib/advapi32/sec/.cvsignore | 1 + lib/advapi32/service/.cvsignore | 1 + lib/advapi32/token/.cvsignore | 1 + lib/crtdll/crtdll.def | 2 +- lib/crtdll/makefile | 3 +- lib/crtdll/math/ftol.c | 6 - lib/epsapi/enum/drivers.c | 227 + lib/epsapi/enum/modules.c | 176 + lib/epsapi/enum/processes.c | 378 + lib/epsapi/makefile | 18 + lib/fmifs/format.c | 33 +- lib/fmifs/makefile | 8 +- lib/freetype/.cvsignore | 5 + lib/freetype/ChangeLog | 5782 ++++++++++++ lib/freetype/Jamfile | 132 + lib/freetype/Jamfile.in | 133 + lib/freetype/Jamrules | 61 + lib/freetype/Makefile | 57 + lib/freetype/Makefile.freetype | 32 + lib/freetype/README | 42 + lib/freetype/README.ROS | 68 + lib/freetype/builds/amiga/README | 90 + .../amiga/include/freetype/config/ftconfig.h | 20 + .../amiga/include/freetype/config/ftmodule.h | 123 + lib/freetype/builds/amiga/makefile | 207 + lib/freetype/builds/amiga/smakefile | 236 + lib/freetype/builds/amiga/src/base/ftdebug.c | 185 + lib/freetype/builds/amiga/src/base/ftsystem.c | 450 + lib/freetype/builds/ansi/ansi-def.mk | 94 + lib/freetype/builds/ansi/ansi.mk | 20 + lib/freetype/builds/beos/beos-def.mk | 96 + lib/freetype/builds/beos/beos.mk | 19 + lib/freetype/builds/beos/detect.mk | 41 + lib/freetype/builds/compiler/ansi-cc.mk | 81 + lib/freetype/builds/compiler/bcc-dev.mk | 80 + lib/freetype/builds/compiler/bcc.mk | 80 + lib/freetype/builds/compiler/gcc-dev.mk | 89 + lib/freetype/builds/compiler/gcc.mk | 78 + lib/freetype/builds/compiler/intelc.mk | 84 + lib/freetype/builds/compiler/unix-lcc.mk | 85 + lib/freetype/builds/compiler/visualage.mk | 76 + lib/freetype/builds/compiler/visualc.mk | 79 + lib/freetype/builds/compiler/watcom.mk | 81 + lib/freetype/builds/compiler/win-lcc.mk | 81 + lib/freetype/builds/detect.mk | 143 + lib/freetype/builds/dos/detect.mk | 111 + lib/freetype/builds/dos/dos-def.mk | 59 + lib/freetype/builds/dos/dos-gcc.mk | 22 + lib/freetype/builds/freetype.mk | 307 + lib/freetype/builds/link_dos.mk | 41 + lib/freetype/builds/link_std.mk | 41 + lib/freetype/builds/mac/README | 14 + lib/freetype/builds/mac/freetype.make | 3 + lib/freetype/builds/mac/ftlib.prj | Bin 0 -> 603 bytes lib/freetype/builds/modules.mk | 76 + lib/freetype/builds/newline | 1 + lib/freetype/builds/os2/detect.mk | 75 + lib/freetype/builds/os2/os2-def.mk | 58 + lib/freetype/builds/os2/os2-dev.mk | 33 + lib/freetype/builds/os2/os2-gcc.mk | 27 + lib/freetype/builds/toplevel.mk | 135 + lib/freetype/builds/unix/.cvsignore | 8 + lib/freetype/builds/unix/aclocal.m4 | 3665 ++++++++ lib/freetype/builds/unix/config.guess | 1409 +++ lib/freetype/builds/unix/config.sub | 1473 +++ lib/freetype/builds/unix/configure | 9831 ++++++++++++++++++++ lib/freetype/builds/unix/configure.ac | 116 + lib/freetype/builds/unix/detect.mk | 87 + lib/freetype/builds/unix/freetype-config.in | 104 + lib/freetype/builds/unix/freetype2.m4 | 143 + lib/freetype/builds/unix/ft-munmap.m4 | 31 + lib/freetype/builds/unix/ft2unix.h | 60 + lib/freetype/builds/unix/ftconfig.in | 261 + lib/freetype/builds/unix/ftsystem.c | 334 + lib/freetype/builds/unix/install-sh | 269 + lib/freetype/builds/unix/install.mk | 93 + lib/freetype/builds/unix/ltmain.sh | 5062 ++++++++++ lib/freetype/builds/unix/mkinstalldirs | 111 + lib/freetype/builds/unix/unix-cc.in | 84 + lib/freetype/builds/unix/unix-def.in | 99 + lib/freetype/builds/unix/unix-dev.mk | 25 + lib/freetype/builds/unix/unix-lcc.mk | 23 + lib/freetype/builds/unix/unix.mk | 57 + lib/freetype/builds/unix/unixddef.mk | 56 + lib/freetype/builds/vms/descrip.mms | 25 + lib/freetype/builds/vms/ftconfig.h | 238 + lib/freetype/builds/vms/ftsystem.c | 321 + lib/freetype/builds/win32/detect.mk | 61 + lib/freetype/builds/win32/ftdebug.c | 211 + lib/freetype/builds/win32/visualc/freetype.dsp | 345 + lib/freetype/builds/win32/visualc/freetype.dsw | 29 + lib/freetype/builds/win32/visualc/index.html | 27 + lib/freetype/builds/win32/w32-bcc.mk | 23 + lib/freetype/builds/win32/w32-bccd.mk | 26 + lib/freetype/builds/win32/w32-dev.mk | 38 + lib/freetype/builds/win32/w32-gcc.mk | 29 + lib/freetype/builds/win32/w32-icc.mk | 22 + lib/freetype/builds/win32/w32-intl.mk | 23 + lib/freetype/builds/win32/w32-lcc.mk | 24 + lib/freetype/builds/win32/w32-mingw32.mk | 31 + lib/freetype/builds/win32/w32-vcc.mk | 23 + lib/freetype/builds/win32/w32-wat.mk | 26 + lib/freetype/builds/win32/win32-def.mk | 61 + lib/freetype/config.mk | 31 + lib/freetype/configure | 60 + lib/freetype/descrip.mms | 73 + lib/freetype/devel/ft2build.h | 41 + lib/freetype/devel/ftoption.h | 502 + lib/freetype/docs/CHANGES | 2036 ++++ lib/freetype/docs/CUSTOMIZE | 117 + lib/freetype/docs/DEBUG | 183 + lib/freetype/docs/FTL.txt | 174 + lib/freetype/docs/GPL.txt | 339 + lib/freetype/docs/INSTALL | 65 + lib/freetype/docs/INSTALL.ANY | 96 + lib/freetype/docs/INSTALL.GNU | 128 + lib/freetype/docs/INSTALL.UNX | 181 + lib/freetype/docs/INSTALL.VMS | 35 + lib/freetype/docs/PATENTS | 27 + lib/freetype/docs/TODO | 13 + lib/freetype/docs/TRUETYPE | 23 + lib/freetype/docs/UPGRADE.UNX | 124 + lib/freetype/docs/VERSION.DLL | 90 + lib/freetype/docs/license.txt | 28 + lib/freetype/docs/modules.txt | 14 + lib/freetype/freetype.def | 273 + lib/freetype/i386/.cvsignore | 2 + lib/freetype/i386/setjmplongjmp.s | 87 + lib/freetype/include/freetype/cache/ftccache.h | 304 + lib/freetype/include/freetype/cache/ftccmap.h | 216 + lib/freetype/include/freetype/cache/ftcglyph.h | 193 + lib/freetype/include/freetype/cache/ftcimage.h | 312 + lib/freetype/include/freetype/cache/ftcmanag.h | 244 + lib/freetype/include/freetype/cache/ftcsbits.h | 275 + lib/freetype/include/freetype/cache/ftlru.h | 202 + lib/freetype/include/freetype/config/ftconfig.h | 334 + lib/freetype/include/freetype/config/ftheader.h | 535 ++ lib/freetype/include/freetype/config/ftmodule.h | 19 + lib/freetype/include/freetype/config/ftoption.h | 497 + lib/freetype/include/freetype/config/ftstdlib.h | 140 + lib/freetype/include/freetype/freetype.h | 2866 ++++++ lib/freetype/include/freetype/ftbbox.h | 83 + lib/freetype/include/freetype/ftbdf.h | 182 + lib/freetype/include/freetype/ftcache.h | 415 + lib/freetype/include/freetype/ftchapters.h | 69 + lib/freetype/include/freetype/fterrdef.h | 229 + lib/freetype/include/freetype/fterrors.h | 207 + lib/freetype/include/freetype/ftglyph.h | 517 + lib/freetype/include/freetype/ftgzip.h | 86 + lib/freetype/include/freetype/ftimage.h | 1241 +++ lib/freetype/include/freetype/ftincrem.h | 287 + lib/freetype/include/freetype/ftlist.h | 268 + lib/freetype/include/freetype/ftmac.h | 128 + lib/freetype/include/freetype/ftmm.h | 203 + lib/freetype/include/freetype/ftmoderr.h | 149 + lib/freetype/include/freetype/ftmodule.h | 307 + lib/freetype/include/freetype/ftoutln.h | 400 + lib/freetype/include/freetype/ftpfr.h | 156 + lib/freetype/include/freetype/ftrender.h | 229 + lib/freetype/include/freetype/ftsizes.h | 151 + lib/freetype/include/freetype/ftsnames.h | 161 + lib/freetype/include/freetype/ftstroker.h | 139 + lib/freetype/include/freetype/ftsynth.h | 65 + lib/freetype/include/freetype/ftsysio.h | 195 + lib/freetype/include/freetype/ftsysmem.h | 202 + lib/freetype/include/freetype/ftsystem.h | 309 + lib/freetype/include/freetype/fttrigon.h | 325 + lib/freetype/include/freetype/fttypes.h | 558 ++ lib/freetype/include/freetype/ftwinfnt.h | 129 + lib/freetype/include/freetype/ftxf86.h | 53 + lib/freetype/include/freetype/internal/autohint.h | 205 + lib/freetype/include/freetype/internal/bdftypes.h | 58 + lib/freetype/include/freetype/internal/cfftypes.h | 256 + lib/freetype/include/freetype/internal/fnttypes.h | 114 + lib/freetype/include/freetype/internal/ftcalc.h | 77 + lib/freetype/include/freetype/internal/ftcore.h | 185 + lib/freetype/include/freetype/internal/ftdebug.h | 196 + lib/freetype/include/freetype/internal/ftdriver.h | 202 + lib/freetype/include/freetype/internal/ftexcept.h | 82 + lib/freetype/include/freetype/internal/ftgloadr.h | 153 + lib/freetype/include/freetype/internal/fthash.h | 502 + lib/freetype/include/freetype/internal/ftmemory.h | 296 + lib/freetype/include/freetype/internal/ftobject.h | 533 ++ lib/freetype/include/freetype/internal/ftobjs.h | 820 ++ lib/freetype/include/freetype/internal/ftstream.h | 498 + lib/freetype/include/freetype/internal/fttrace.h | 106 + lib/freetype/include/freetype/internal/internal.h | 57 + lib/freetype/include/freetype/internal/pcftypes.h | 56 + lib/freetype/include/freetype/internal/pfr.h | 36 + lib/freetype/include/freetype/internal/psaux.h | 717 ++ lib/freetype/include/freetype/internal/pshints.h | 626 ++ lib/freetype/include/freetype/internal/psnames.h | 241 + lib/freetype/include/freetype/internal/sfnt.h | 549 ++ lib/freetype/include/freetype/internal/t1types.h | 199 + lib/freetype/include/freetype/internal/t42types.h | 55 + lib/freetype/include/freetype/internal/tttypes.h | 1669 ++++ lib/freetype/include/freetype/t1tables.h | 391 + lib/freetype/include/freetype/ttnameid.h | 1076 +++ lib/freetype/include/freetype/tttables.h | 662 ++ lib/freetype/include/freetype/tttags.h | 74 + lib/freetype/include/ft2build.h | 39 + lib/freetype/install | 2 + lib/freetype/objs/.cvsignore | 5 + .../freetype/obj => lib/freetype/objs}/README | 0 lib/freetype/rosglue.c | 172 + lib/freetype/src/Jamfile | 17 + lib/freetype/src/autohint/CatharonLicense.txt | 123 + lib/freetype/src/autohint/Jamfile | 21 + lib/freetype/src/autohint/ahangles.c | 147 + lib/freetype/src/autohint/ahangles.h | 64 + lib/freetype/src/autohint/aherrors.h | 40 + lib/freetype/src/autohint/ahglobal.c | 398 + lib/freetype/src/autohint/ahglobal.h | 59 + lib/freetype/src/autohint/ahglyph.c | 1595 ++++ lib/freetype/src/autohint/ahglyph.h | 95 + lib/freetype/src/autohint/ahhint.c | 1786 ++++ lib/freetype/src/autohint/ahhint.h | 75 + lib/freetype/src/autohint/ahloader.h | 61 + lib/freetype/src/autohint/ahmodule.c | 137 + lib/freetype/src/autohint/ahmodule.h | 42 + lib/freetype/src/autohint/ahoptim.c | 882 ++ lib/freetype/src/autohint/ahoptim.h | 137 + lib/freetype/src/autohint/ahtypes.h | 533 ++ lib/freetype/src/autohint/autohint.c | 32 + lib/freetype/src/autohint/descrip.mms | 25 + lib/freetype/src/autohint/mather.py | 78 + lib/freetype/src/autohint/module.mk | 25 + lib/freetype/src/autohint/rules.mk | 78 + lib/freetype/src/base/Jamfile | 37 + lib/freetype/src/base/descrip.mms | 23 + lib/freetype/src/base/ftapi.c | 121 + lib/freetype/src/base/ftbase.c | 34 + lib/freetype/src/base/ftbbox.c | 653 ++ lib/freetype/src/base/ftbdf.c | 96 + lib/freetype/src/base/ftcalc.c | 561 ++ lib/freetype/src/base/ftdbgmem.c | 718 ++ lib/freetype/src/base/ftdebug.c | 197 + lib/freetype/src/base/ftexcept.c | 197 + lib/freetype/src/base/ftgloadr.c | 361 + lib/freetype/src/base/ftglyph.c | 684 ++ lib/freetype/src/base/fthash.c | 246 + lib/freetype/src/base/ftinit.c | 161 + lib/freetype/src/base/ftlist.c | 217 + lib/freetype/src/base/ftmac.c | 919 ++ lib/freetype/src/base/ftmm.c | 126 + lib/freetype/src/base/ftnames.c | 94 + lib/freetype/src/base/ftobject.c | 396 + lib/freetype/src/base/ftobjs.c | 2667 ++++++ lib/freetype/src/base/ftoutln.c | 658 ++ lib/freetype/src/base/ftpfr.c | 105 + lib/freetype/src/base/ftstream.c | 803 ++ lib/freetype/src/base/ftstroker.c | 1577 ++++ lib/freetype/src/base/ftsynth.c | 286 + lib/freetype/src/base/ftsysio.c | 131 + lib/freetype/src/base/ftsysmem.c | 30 + lib/freetype/src/base/ftsystem.c | 303 + lib/freetype/src/base/fttrigon.c | 487 + lib/freetype/src/base/fttype1.c | 87 + lib/freetype/src/base/ftutil.c | 330 + lib/freetype/src/base/ftwinfnt.c | 55 + lib/freetype/src/base/ftxf86.c | 80 + lib/freetype/src/base/rules.mk | 94 + lib/freetype/src/bdf/Jamfile | 21 + lib/freetype/src/bdf/README | 148 + lib/freetype/src/bdf/bdf.c | 34 + lib/freetype/src/bdf/bdf.h | 295 + lib/freetype/src/bdf/bdfdrivr.c | 725 ++ lib/freetype/src/bdf/bdfdrivr.h | 74 + lib/freetype/src/bdf/bdferror.h | 44 + lib/freetype/src/bdf/bdflib.c | 2436 +++++ lib/freetype/src/bdf/descrip.mms | 23 + lib/freetype/src/bdf/module.mk | 31 + lib/freetype/src/bdf/rules.mk | 79 + lib/freetype/src/cache/Jamfile | 27 + lib/freetype/src/cache/descrip.mms | 26 + lib/freetype/src/cache/ftcache.c | 31 + lib/freetype/src/cache/ftccache.c | 807 ++ lib/freetype/src/cache/ftccache.i | 157 + lib/freetype/src/cache/ftccmap.c | 459 + lib/freetype/src/cache/ftcerror.h | 40 + lib/freetype/src/cache/ftcglyph.c | 115 + lib/freetype/src/cache/ftcimage.c | 399 + lib/freetype/src/cache/ftcmanag.c | 765 ++ lib/freetype/src/cache/ftcsbits.c | 557 ++ lib/freetype/src/cache/ftlru.c | 394 + lib/freetype/src/cache/rules.mk | 80 + lib/freetype/src/cff/Jamfile | 21 + lib/freetype/src/cff/cff.c | 29 + lib/freetype/src/cff/cffcmap.c | 326 + lib/freetype/src/cff/cffcmap.h | 88 + lib/freetype/src/cff/cffdrivr.c | 420 + lib/freetype/src/cff/cffdrivr.h | 39 + lib/freetype/src/cff/cfferrs.h | 41 + lib/freetype/src/cff/cffgload.c | 2504 +++++ lib/freetype/src/cff/cffgload.h | 214 + lib/freetype/src/cff/cffload.c | 2267 +++++ lib/freetype/src/cff/cffload.h | 74 + lib/freetype/src/cff/cffobjs.c | 575 ++ lib/freetype/src/cff/cffobjs.h | 160 + lib/freetype/src/cff/cffparse.c | 681 ++ lib/freetype/src/cff/cffparse.h | 69 + lib/freetype/src/cff/cfftoken.h | 97 + lib/freetype/src/cff/descrip.mms | 23 + lib/freetype/src/cff/module.mk | 22 + lib/freetype/src/cff/rules.mk | 71 + lib/freetype/src/cid/Jamfile | 21 + lib/freetype/src/cid/ciderrs.h | 40 + lib/freetype/src/cid/cidgload.c | 435 + lib/freetype/src/cid/cidgload.h | 51 + lib/freetype/src/cid/cidload.c | 546 ++ lib/freetype/src/cid/cidload.h | 57 + lib/freetype/src/cid/cidobjs.c | 448 + lib/freetype/src/cid/cidobjs.h | 158 + lib/freetype/src/cid/cidparse.c | 155 + lib/freetype/src/cid/cidparse.h | 116 + lib/freetype/src/cid/cidriver.c | 113 + lib/freetype/src/cid/cidriver.h | 39 + lib/freetype/src/cid/cidtoken.h | 96 + lib/freetype/src/cid/descrip.mms | 23 + lib/freetype/src/cid/module.mk | 21 + lib/freetype/src/cid/rules.mk | 70 + lib/freetype/src/cid/type1cid.c | 29 + lib/freetype/src/gzip/Jamfile | 8 + lib/freetype/src/gzip/adler32.c | 48 + lib/freetype/src/gzip/descrip.mms | 23 + lib/freetype/src/gzip/ftgzip.c | 564 ++ lib/freetype/src/gzip/infblock.c | 386 + lib/freetype/src/gzip/infblock.h | 36 + lib/freetype/src/gzip/infcodes.c | 250 + lib/freetype/src/gzip/infcodes.h | 31 + .../lib/zlib => lib/freetype/src/gzip}/inffixed.h | 0 lib/freetype/src/gzip/inflate.c | 273 + lib/freetype/src/gzip/inftrees.c | 460 + lib/freetype/src/gzip/inftrees.h | 63 + lib/freetype/src/gzip/infutil.c | 86 + lib/freetype/src/gzip/infutil.h | 96 + lib/freetype/src/gzip/rules.mk | 74 + lib/freetype/src/gzip/zconf.h | 278 + lib/freetype/src/gzip/zlib.h | 830 ++ lib/freetype/src/gzip/zutil.c | 181 + lib/freetype/src/gzip/zutil.h | 216 + lib/freetype/src/otlayout/otlayout.h | 205 + lib/freetype/src/otlayout/otlbase.c | 181 + lib/freetype/src/otlayout/otlbase.h | 14 + lib/freetype/src/otlayout/otlcommn.c | 940 ++ lib/freetype/src/otlayout/otlcommn.h | 277 + lib/freetype/src/otlayout/otlconf.h | 78 + lib/freetype/src/otlayout/otlgdef.c | 175 + lib/freetype/src/otlayout/otlgdef.h | 14 + lib/freetype/src/otlayout/otlgpos.c | 980 ++ lib/freetype/src/otlayout/otlgpos.h | 14 + lib/freetype/src/otlayout/otlgsub.c | 867 ++ lib/freetype/src/otlayout/otlgsub.h | 26 + lib/freetype/src/otlayout/otljstf.c | 189 + lib/freetype/src/otlayout/otljstf.h | 14 + lib/freetype/src/otlayout/otlparse.c | 142 + lib/freetype/src/otlayout/otlparse.h | 99 + lib/freetype/src/otlayout/otltable.h | 60 + lib/freetype/src/otlayout/otltags.h | 88 + lib/freetype/src/otlayout/otlutils.h | 33 + lib/freetype/src/pcf/Jamfile | 21 + lib/freetype/src/pcf/descrip.mms | 35 + lib/freetype/src/pcf/module.mk | 32 + lib/freetype/src/pcf/pcf.c | 36 + lib/freetype/src/pcf/pcf.h | 237 + lib/freetype/src/pcf/pcfdriver.c | 545 ++ lib/freetype/src/pcf/pcfdriver.h | 44 + lib/freetype/src/pcf/pcferror.h | 40 + lib/freetype/src/pcf/pcfread.c | 1058 +++ lib/freetype/src/pcf/pcfread.h | 45 + lib/freetype/src/pcf/pcfutil.c | 215 + lib/freetype/src/pcf/pcfutil.h | 58 + lib/freetype/src/pcf/readme | 114 + lib/freetype/src/pcf/rules.mk | 80 + lib/freetype/src/pfr/Jamfile | 21 + lib/freetype/src/pfr/descrip.mms | 23 + lib/freetype/src/pfr/module.mk | 22 + lib/freetype/src/pfr/pfr.c | 29 + lib/freetype/src/pfr/pfrcmap.c | 158 + lib/freetype/src/pfr/pfrcmap.h | 46 + lib/freetype/src/pfr/pfrdrivr.c | 168 + lib/freetype/src/pfr/pfrdrivr.h | 39 + lib/freetype/src/pfr/pfrerror.h | 40 + lib/freetype/src/pfr/pfrgload.c | 801 ++ lib/freetype/src/pfr/pfrgload.h | 49 + lib/freetype/src/pfr/pfrload.c | 1021 ++ lib/freetype/src/pfr/pfrload.h | 118 + lib/freetype/src/pfr/pfrobjs.c | 481 + lib/freetype/src/pfr/pfrobjs.h | 96 + lib/freetype/src/pfr/pfrsbit.c | 669 ++ lib/freetype/src/pfr/pfrsbit.h | 36 + lib/freetype/src/pfr/pfrtypes.h | 360 + lib/freetype/src/pfr/rules.mk | 71 + lib/freetype/src/psaux/Jamfile | 21 + lib/freetype/src/psaux/descrip.mms | 23 + lib/freetype/src/psaux/module.mk | 22 + lib/freetype/src/psaux/psaux.c | 28 + lib/freetype/src/psaux/psauxerr.h | 41 + lib/freetype/src/psaux/psauxmod.c | 118 + lib/freetype/src/psaux/psauxmod.h | 38 + lib/freetype/src/psaux/psobjs.c | 1406 +++ lib/freetype/src/psaux/psobjs.h | 204 + lib/freetype/src/psaux/rules.mk | 72 + lib/freetype/src/psaux/t1cmap.c | 454 + lib/freetype/src/psaux/t1cmap.h | 124 + lib/freetype/src/psaux/t1decode.c | 1170 +++ lib/freetype/src/psaux/t1decode.h | 65 + lib/freetype/src/pshinter/Jamfile | 21 + lib/freetype/src/pshinter/descrip.mms | 23 + lib/freetype/src/pshinter/module.mk | 22 + lib/freetype/src/pshinter/pshalgo.h | 53 + lib/freetype/src/pshinter/pshalgo1.c | 785 ++ lib/freetype/src/pshinter/pshalgo1.h | 110 + lib/freetype/src/pshinter/pshalgo2.c | 1557 ++++ lib/freetype/src/pshinter/pshalgo2.h | 203 + lib/freetype/src/pshinter/pshalgo3.c | 1958 ++++ lib/freetype/src/pshinter/pshalgo3.h | 255 + lib/freetype/src/pshinter/pshglob.c | 743 ++ lib/freetype/src/pshinter/pshglob.h | 187 + lib/freetype/src/pshinter/pshinter.c | 30 + lib/freetype/src/pshinter/pshmod.c | 120 + lib/freetype/src/pshinter/pshmod.h | 39 + lib/freetype/src/pshinter/pshrec.c | 1211 +++ lib/freetype/src/pshinter/pshrec.h | 180 + lib/freetype/src/pshinter/rules.mk | 74 + lib/freetype/src/psnames/Jamfile | 21 + lib/freetype/src/psnames/descrip.mms | 23 + lib/freetype/src/psnames/module.mk | 22 + lib/freetype/src/psnames/psmodule.c | 357 + lib/freetype/src/psnames/psmodule.h | 38 + lib/freetype/src/psnames/psnamerr.h | 41 + lib/freetype/src/psnames/psnames.c | 25 + lib/freetype/src/psnames/pstables.h | 2967 ++++++ lib/freetype/src/psnames/rules.mk | 71 + lib/freetype/src/raster/Jamfile | 21 + lib/freetype/src/raster/descrip.mms | 23 + lib/freetype/src/raster/ftraster.c | 3288 +++++++ lib/freetype/src/raster/ftraster.h | 46 + lib/freetype/src/raster/ftrend1.c | 273 + lib/freetype/src/raster/ftrend1.h | 44 + lib/freetype/src/raster/module.mk | 22 + lib/freetype/src/raster/raster.c | 26 + lib/freetype/src/raster/rasterrs.h | 41 + lib/freetype/src/raster/rules.mk | 70 + lib/freetype/src/sfnt/Jamfile | 21 + lib/freetype/src/sfnt/descrip.mms | 23 + lib/freetype/src/sfnt/module.mk | 22 + lib/freetype/src/sfnt/rules.mk | 75 + lib/freetype/src/sfnt/sfdriver.c | 335 + lib/freetype/src/sfnt/sfdriver.h | 38 + lib/freetype/src/sfnt/sferrors.h | 39 + lib/freetype/src/sfnt/sfnt.c | 37 + lib/freetype/src/sfnt/sfobjs.c | 829 ++ lib/freetype/src/sfnt/sfobjs.h | 54 + lib/freetype/src/sfnt/ttcmap.c | 1110 +++ lib/freetype/src/sfnt/ttcmap.h | 45 + lib/freetype/src/sfnt/ttcmap0.c | 1784 ++++ lib/freetype/src/sfnt/ttcmap0.h | 74 + lib/freetype/src/sfnt/ttload.c | 1870 ++++ lib/freetype/src/sfnt/ttload.h | 137 + lib/freetype/src/sfnt/ttpost.c | 521 ++ lib/freetype/src/sfnt/ttpost.h | 46 + lib/freetype/src/sfnt/ttsbit.c | 1467 +++ lib/freetype/src/sfnt/ttsbit.h | 59 + lib/freetype/src/smooth/Jamfile | 21 + lib/freetype/src/smooth/descrip.mms | 23 + lib/freetype/src/smooth/ftgrays.c | 2159 +++++ lib/freetype/src/smooth/ftgrays.h | 57 + lib/freetype/src/smooth/ftsmerrs.h | 41 + lib/freetype/src/smooth/ftsmooth.c | 371 + lib/freetype/src/smooth/ftsmooth.h | 49 + lib/freetype/src/smooth/module.mk | 22 + lib/freetype/src/smooth/rules.mk | 70 + lib/freetype/src/smooth/smooth.c | 26 + lib/freetype/src/tools/cordic.py | 78 + lib/freetype/src/tools/docmaker/content.py | 547 ++ lib/freetype/src/tools/docmaker/docmaker.py | 149 + lib/freetype/src/tools/docmaker/formatter.py | 194 + lib/freetype/src/tools/docmaker/sources.py | 355 + lib/freetype/src/tools/docmaker/tohtml.py | 476 + lib/freetype/src/tools/docmaker/utils.py | 87 + lib/freetype/src/tools/glnames.py | 1722 ++++ lib/freetype/src/tools/test_bbox.c | 160 + lib/freetype/src/tools/test_trig.c | 236 + lib/freetype/src/truetype/Jamfile | 21 + lib/freetype/src/truetype/descrip.mms | 23 + lib/freetype/src/truetype/module.mk | 22 + lib/freetype/src/truetype/rules.mk | 71 + lib/freetype/src/truetype/truetype.c | 32 + lib/freetype/src/truetype/ttdriver.c | 428 + lib/freetype/src/truetype/ttdriver.h | 38 + lib/freetype/src/truetype/tterrors.h | 40 + lib/freetype/src/truetype/ttgload.c | 1798 ++++ lib/freetype/src/truetype/ttgload.h | 55 + lib/freetype/src/truetype/ttinterp.c | 7496 +++++++++++++++ lib/freetype/src/truetype/ttinterp.h | 317 + lib/freetype/src/truetype/ttobjs.c | 865 ++ lib/freetype/src/truetype/ttobjs.h | 423 + lib/freetype/src/truetype/ttpload.c | 264 + lib/freetype/src/truetype/ttpload.h | 48 + lib/freetype/src/type1/Jamfile | 21 + lib/freetype/src/type1/descrip.mms | 23 + lib/freetype/src/type1/module.mk | 22 + lib/freetype/src/type1/rules.mk | 73 + lib/freetype/src/type1/t1afm.c | 282 + lib/freetype/src/type1/t1afm.h | 66 + lib/freetype/src/type1/t1driver.c | 279 + lib/freetype/src/type1/t1driver.h | 38 + lib/freetype/src/type1/t1errors.h | 40 + lib/freetype/src/type1/t1gload.c | 414 + lib/freetype/src/type1/t1gload.h | 46 + lib/freetype/src/type1/t1load.c | 1807 ++++ lib/freetype/src/type1/t1load.h | 84 + lib/freetype/src/type1/t1objs.c | 541 ++ lib/freetype/src/type1/t1objs.h | 170 + lib/freetype/src/type1/t1parse.c | 460 + lib/freetype/src/type1/t1parse.h | 135 + lib/freetype/src/type1/t1tokens.h | 80 + lib/freetype/src/type1/type1.c | 33 + lib/freetype/src/type42/Jamfile | 21 + lib/freetype/src/type42/descrip.mms | 23 + lib/freetype/src/type42/module.mk | 22 + lib/freetype/src/type42/rules.mk | 69 + lib/freetype/src/type42/t42drivr.c | 169 + lib/freetype/src/type42/t42drivr.h | 38 + lib/freetype/src/type42/t42error.h | 40 + lib/freetype/src/type42/t42objs.c | 630 ++ lib/freetype/src/type42/t42objs.h | 126 + lib/freetype/src/type42/t42parse.c | 994 ++ lib/freetype/src/type42/t42parse.h | 89 + lib/freetype/src/type42/type42.c | 25 + lib/freetype/src/winfonts/Jamfile | 8 + lib/freetype/src/winfonts/descrip.mms | 23 + lib/freetype/src/winfonts/fnterrs.h | 41 + lib/freetype/src/winfonts/module.mk | 21 + lib/freetype/src/winfonts/rules.mk | 65 + lib/freetype/src/winfonts/winfnt.c | 689 ++ lib/freetype/src/winfonts/winfnt.h | 39 + lib/freetype/tests/Jamfile | 41 + lib/freetype/tests/gview.c | 1488 +++ lib/fslib/vfatlib/.cvsignore | 4 + lib/fslib/vfatlib/Makefile | 14 + lib/fslib/vfatlib/vfatlib.c | 530 ++ lib/fslib/vfatlib/vfatlib.h | 57 + lib/gdi32/main/.cvsignore | 1 + lib/gdi32/makefile | 27 +- lib/gdi32/misc/.cvsignore | 1 + lib/gdi32/misc/stubs.c | 65 - lib/gdi32/misc/stubsa.c | 2 +- lib/gdi32/misc/stubsw.c | 2 +- lib/gdi32/objects/.cvsignore | 1 + lib/gdi32/objects/dc.c | 28 + lib/gdi32/objects/fillshap.c | 29 + lib/gdi32/objects/line.c | 9 +- lib/gdi32/objects/text.c | 18 +- lib/iphlpapi/makefile | 5 + lib/iprtprio/makefile | 5 + lib/kernel32/.cvsignore | 1 + lib/kernel32/MSG00409.bin | Bin 292 -> 0 bytes lib/kernel32/debug/.cvsignore | 2 + lib/kernel32/debug/break.c | 29 + lib/kernel32/debug/debugger.c | 75 + lib/kernel32/debug/output.c | 490 + lib/kernel32/errcodes.rc | 7 - lib/kernel32/errormsg.mak | 18 - lib/kernel32/file/cnotify.c | 104 +- lib/kernel32/file/copy.c | 8 +- lib/kernel32/file/create.c | 42 + lib/kernel32/file/curdir.c | 2 +- lib/kernel32/file/dir.c | 10 +- lib/kernel32/file/file.c | 353 +- lib/kernel32/file/find.c | 108 +- lib/kernel32/file/iocompl.c | 220 +- lib/kernel32/k32.h | 1 + lib/kernel32/kernel32.def | 1 - lib/kernel32/kernel32.edf | 3 +- lib/kernel32/makefile | 49 +- lib/kernel32/mem/isbad.c | 39 +- lib/kernel32/misc/console.c | 295 +- lib/kernel32/misc/debug.c | 113 - lib/kernel32/misc/dllmain.c | 212 +- lib/kernel32/misc/env.c | 14 +- lib/kernel32/misc/error.c | 13 - lib/kernel32/misc/errormsg.c | 58 +- lib/kernel32/misc/handle.c | 29 +- lib/kernel32/misc/res.c | 48 +- lib/kernel32/misc/stubs.c | 22 +- lib/kernel32/process/create.c | 790 +- lib/kernel32/process/proc.c | 72 +- lib/kernel32/synch/wait.c | 277 +- lib/kernel32/thread/thread.c | 373 +- lib/kernel32/thread/tls.c | 10 +- lib/makefile | 4 +- lib/msafd/makefile | 17 +- lib/msafd/misc/.cvsignore | 1 + lib/msvcrt/Makefile | 5 +- lib/msvcrt/ctype/toupper.c | 2 +- lib/msvcrt/except/seh.s | 13 + lib/msvcrt/math/ftol.c | 6 - lib/msvcrt/misc/cpp.c | 533 ++ lib/msvcrt/misc/crtmain.c | 13 - lib/msvcrt/misc/dllmain.c | 7 +- lib/msvcrt/misc/environ.c | 12 +- lib/msvcrt/misc/getargs.c | 8 +- lib/msvcrt/msvcrt.def | 24 +- lib/msvcrt/process/process.c | 21 + lib/msvcrt/process/threadx.c | 19 +- lib/msvcrt/setjmp/.cvsignore | 3 - lib/msvcrt/setjmp/i386/.cvsignore | 2 + lib/msvcrt/setjmp/i386/setjmp.s | 111 + lib/msvcrt/setjmp/setjmp.c | 142 - lib/msvcrt/stdio/stdhnd.c | 6 +- lib/msvcrt/stdio/vfprintf.c | 10 +- lib/msvcrt/stdio/vfwprint.c | 12 +- lib/msvcrt/stdlib/malloc.c | 47 +- lib/msvcrt/sys_stat/stat.c | 9 + lib/ntdll/dbg/brkpoint.c | 31 +- lib/ntdll/dbg/debug.c | 37 + lib/ntdll/def/ntdll.def | 11 +- lib/ntdll/def/ntdll.edf | 11 +- lib/ntdll/ldr/entry.S | 18 + lib/ntdll/ldr/res.c | 4 +- lib/ntdll/ldr/startup.c | 7 +- lib/ntdll/ldr/utils.c | 88 +- lib/ntdll/makefile | 18 +- lib/ntdll/rtl/encode.c | 75 + lib/ntdll/rtl/exception.c | 20 +- lib/ntdll/rtl/i386/.cvsignore | 1 + lib/ntdll/rtl/i386/ftol.c | 35 + lib/ntdll/rtl/math.c | 6 - lib/ntdll/rtl/nls.c | 25 +- lib/ntdll/rtl/path.c | 15 +- lib/ntdll/rtl/process.c | 177 +- lib/ntdll/rtl/resource.c | 2 +- lib/ntdll/rtl/thread.c | 353 +- lib/ntdll/rtl/unicode.c | 55 + lib/ntdll/string/ctype.c | 5 + lib/psapi/enum/module.c | 274 - lib/psapi/enum/process.c | 110 - lib/psapi/include/internal/psapi.h | 90 - lib/psapi/makefile | 15 +- lib/psapi/misc/malloc.c | 8 +- lib/psapi/misc/win32.c | 42 +- lib/rosrtl/makefile | 23 + lib/rosrtl/thread/context.c | 105 + lib/rosrtl/thread/create.c | 260 + lib/tgetopt/Makefile | 19 + lib/tgetopt/_wgetopt.c | 15 + lib/tgetopt/getopt.c | 135 + lib/user32/Makefile | 21 +- lib/user32/controls/scrollbar.c | 237 +- lib/user32/misc/desktop.c | 2 +- lib/user32/misc/resources.c | 20 +- lib/user32/misc/stubs.c | 25 + lib/user32/misc/timer.c | 39 +- lib/user32/resources/obm_close.bmp | Bin 478 -> 246 bytes lib/user32/resources/obm_dnarrow.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_dnarrowd.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_dnarrowi.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_lfarrow.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_lfarrowd.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_lfarrowi.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_reduce.bmp | Bin 230 -> 0 bytes lib/user32/resources/obm_reduced.bmp | Bin 230 -> 0 bytes lib/user32/resources/obm_restore.bmp | Bin 230 -> 0 bytes lib/user32/resources/obm_restored.bmp | Bin 230 -> 0 bytes lib/user32/resources/obm_rgarrow.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_rgarrowd.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_rgarrowi.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_uparrow.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_uparrowd.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_uparrowi.bmp | Bin 322 -> 0 bytes lib/user32/resources/obm_zoom.bmp | Bin 230 -> 0 bytes lib/user32/resources/obm_zoomd.bmp | Bin 230 -> 0 bytes lib/user32/user32.def | 6 +- lib/user32/user32.edf | 6 +- lib/user32/user32.rc | 3 - lib/user32/windows/dc.c | 2 +- lib/user32/windows/defwnd.c | 778 +- lib/user32/windows/draw.c | 65 +- lib/user32/windows/message.c | 1 + lib/user32/windows/messagebox.c | 12 +- lib/user32/windows/paint.c | 19 +- lib/user32/windows/window.c | 95 +- lib/winedbgc/Makefile | 1 + lib/winedbgc/trace.c | 82 + lib/winedbgc/trace.h | 72 + lib/winedbgc/winedbgc.c | 82 +- lib/winmm/dllmain.c | 4 - lib/winmm/misc/stubs.c | 24 + lib/winmm/winmm.def | 5 +- lib/winmm/winmm.edf | 5 +- lib/winspool/.cvsignore | 9 + lib/winspool/Makefile | 38 + lib/winspool/stubs.c | 1073 +++ lib/winspool/winspool.def | 114 + lib/winspool/winspool.edf | 114 + lib/winspool/winspool.rc | 41 + lib/ws2_32/makefile | 4 +- lib/ws2_32/misc/.cvsignore | 1 + lib/ws2help/makefile | 4 + lib/wshirda/makefile | 4 + lib/wsock32/.cvsignore | 9 + lib/wsock32/Makefile | 36 + lib/wsock32/stubs.c | 834 ++ lib/wsock32/wsock32.def | 54 + lib/wsock32/wsock32.edf | 56 + lib/wsock32/wsock32.rc | 41 + {drivers/lib => lib}/zlib/.cvsignore | 0 {drivers/lib => lib}/zlib/ChangeLog | 0 {drivers/lib => lib}/zlib/FAQ | 0 {drivers/lib => lib}/zlib/INDEX | 0 lib/zlib/Make_vms.com | 115 + lib/zlib/Makefile | 25 + {drivers/lib => lib}/zlib/Makefile.in | 0 {drivers/lib => lib}/zlib/Makefile.riscos | 0 {drivers/lib => lib}/zlib/README | 0 {drivers/lib => lib}/zlib/adler32.c | 0 {drivers/lib => lib}/zlib/algorithm.txt | 0 {drivers/lib => lib}/zlib/amiga/Makefile.pup | 0 {drivers/lib => lib}/zlib/amiga/Makefile.sas | 0 {drivers/lib => lib}/zlib/compress.c | 0 {drivers/lib => lib}/zlib/configure | 0 {drivers/lib => lib}/zlib/contrib/README.contrib | 0 .../lib => lib}/zlib/contrib/asm386/gvmat32.asm | 0 .../lib => lib}/zlib/contrib/asm386/gvmat32c.c | 0 .../lib => lib}/zlib/contrib/asm386/mkgvmt32.bat | 0 .../lib => lib}/zlib/contrib/asm386/zlibvc.def | 0 lib/zlib/contrib/asm386/zlibvc.dsp | 651 ++ lib/zlib/contrib/asm386/zlibvc.dsw | 41 + .../lib => lib}/zlib/contrib/asm586/README.586 | 0 {drivers/lib => lib}/zlib/contrib/asm586/match.S | 0 .../lib => lib}/zlib/contrib/asm686/README.686 | 0 {drivers/lib => lib}/zlib/contrib/asm686/match.S | 0 {drivers/lib => lib}/zlib/contrib/delphi/zlib.mak | 0 .../lib => lib}/zlib/contrib/delphi/zlibdef.pas | 0 .../lib => lib}/zlib/contrib/delphi2/d_zlib.bpr | 0 .../lib => lib}/zlib/contrib/delphi2/d_zlib.cpp | 0 .../lib => lib}/zlib/contrib/delphi2/readme.txt | 0 {drivers/lib => lib}/zlib/contrib/delphi2/zlib.bpg | 0 {drivers/lib => lib}/zlib/contrib/delphi2/zlib.bpr | 0 {drivers/lib => lib}/zlib/contrib/delphi2/zlib.cpp | 0 {drivers/lib => lib}/zlib/contrib/delphi2/zlib.pas | 0 .../lib => lib}/zlib/contrib/delphi2/zlib32.bpr | 0 .../lib => lib}/zlib/contrib/delphi2/zlib32.cpp | 0 .../lib => lib}/zlib/contrib/iostream/test.cpp | 0 .../lib => lib}/zlib/contrib/iostream/zfstream.cpp | 0 .../lib => lib}/zlib/contrib/iostream/zfstream.h | 0 .../lib => lib}/zlib/contrib/iostream2/zstream.h | 0 .../zlib/contrib/iostream2/zstream_test.cpp | 0 .../zlib/contrib/minizip/ChangeLogUnzip | 0 {drivers/lib => lib}/zlib/contrib/minizip/Makefile | 0 .../lib => lib}/zlib/contrib/minizip/miniunz.c | 0 .../lib => lib}/zlib/contrib/minizip/minizip.c | 0 .../lib => lib}/zlib/contrib/minizip/readme.txt | 0 {drivers/lib => lib}/zlib/contrib/minizip/unzip.c | 0 .../lib => lib}/zlib/contrib/minizip/unzip.def | 0 {drivers/lib => lib}/zlib/contrib/minizip/unzip.h | 0 {drivers/lib => lib}/zlib/contrib/minizip/zip.c | 0 {drivers/lib => lib}/zlib/contrib/minizip/zip.def | 0 {drivers/lib => lib}/zlib/contrib/minizip/zip.h | 0 .../lib => lib}/zlib/contrib/minizip/zlibvc.def | 0 lib/zlib/contrib/minizip/zlibvc.dsp | 651 ++ lib/zlib/contrib/minizip/zlibvc.dsw | 41 + {drivers/lib => lib}/zlib/contrib/untgz/Makefile | 0 .../lib => lib}/zlib/contrib/untgz/makefile.w32 | 0 {drivers/lib => lib}/zlib/contrib/untgz/untgz.c | 0 {drivers/lib => lib}/zlib/contrib/visual-basic.txt | 0 {drivers/lib => lib}/zlib/crc32.c | 0 {drivers/lib => lib}/zlib/deflate.c | 0 {drivers/lib => lib}/zlib/deflate.h | 0 {drivers/lib => lib}/zlib/descrip.mms | 0 {drivers/lib => lib}/zlib/example.c | 0 {drivers/lib => lib}/zlib/gzio.c | 0 {drivers/lib => lib}/zlib/infblock.c | 0 {drivers/lib => lib}/zlib/infblock.h | 0 {drivers/lib => lib}/zlib/infcodes.c | 0 {drivers/lib => lib}/zlib/infcodes.h | 0 {drivers/lib => lib}/zlib/inffast.c | 0 {drivers/lib => lib}/zlib/inffast.h | 0 lib/zlib/inffixed.h | 151 + {drivers/lib => lib}/zlib/inflate.c | 0 {drivers/lib => lib}/zlib/inftrees.c | 0 {drivers/lib => lib}/zlib/inftrees.h | 0 {drivers/lib => lib}/zlib/infutil.c | 0 {drivers/lib => lib}/zlib/infutil.h | 0 {drivers/lib => lib}/zlib/maketree.c | 0 {drivers/lib => lib}/zlib/minigzip.c | 0 {drivers/lib => lib}/zlib/msdos/Makefile.b32 | 0 {drivers/lib => lib}/zlib/msdos/Makefile.bor | 0 {drivers/lib => lib}/zlib/msdos/Makefile.dj2 | 0 {drivers/lib => lib}/zlib/msdos/Makefile.emx | 0 {drivers/lib => lib}/zlib/msdos/Makefile.msc | 0 {drivers/lib => lib}/zlib/msdos/Makefile.tc | 0 {drivers/lib => lib}/zlib/msdos/Makefile.w32 | 0 {drivers/lib => lib}/zlib/msdos/Makefile.wat | 0 {drivers/lib => lib}/zlib/msdos/zlib.def | 0 {drivers/lib => lib}/zlib/msdos/zlib.rc | 0 {drivers/lib => lib}/zlib/nt/Makefile.emx | 0 {drivers/lib => lib}/zlib/nt/Makefile.gcc | 0 {drivers/lib => lib}/zlib/nt/Makefile.nt | 0 {drivers/lib => lib}/zlib/nt/zlib.dnt | 0 {drivers/lib => lib}/zlib/os2/Makefile.os2 | 0 {drivers/lib => lib}/zlib/os2/zlib.def | 0 {drivers/lib => lib}/zlib/trees.c | 0 {drivers/lib => lib}/zlib/trees.h | 0 {drivers/lib => lib}/zlib/uncompr.c | 0 {drivers/lib => lib}/zlib/zconf.h | 0 {drivers/lib => lib}/zlib/zlib.3 | 0 {drivers/lib => lib}/zlib/zlib.h | 0 {drivers/lib => lib}/zlib/zlib.html | 0 {drivers/lib => lib}/zlib/zutil.c | 0 {drivers/lib => lib}/zlib/zutil.h | 0 loaders/boot/boot.asm | 309 - loaders/boot/boot.inc | 196 - loaders/boot/boot.mak | 77 - loaders/boot/bootbk.asm | 313 - loaders/boot/osldr.asm | 340 - loaders/boot/osldr.txt | 12 - loaders/dos/loadros.asm | 16 +- ntoskrnl/Makefile | 29 +- ntoskrnl/cc/copy.c | 11 +- ntoskrnl/cc/misc.c | 95 +- ntoskrnl/cc/pin.c | 2 +- ntoskrnl/cc/view.c | 46 +- ntoskrnl/cm/cm.h | 68 +- ntoskrnl/cm/import.c | 410 +- ntoskrnl/cm/ntfunc.c | 328 +- ntoskrnl/cm/regfile.c | 1982 +++- ntoskrnl/cm/registry.c | 677 +- ntoskrnl/cm/regobj.c | 59 +- ntoskrnl/ex/fmutex.c | 4 +- ntoskrnl/ex/init.c | 10 +- ntoskrnl/ex/sysinfo.c | 116 +- ntoskrnl/fs/mcb.c | 149 +- ntoskrnl/fs/util.c | 16 +- ntoskrnl/include/internal/io.h | 4 - ntoskrnl/include/internal/kd.h | 2 +- ntoskrnl/include/internal/ke.h | 8 +- ntoskrnl/include/internal/ntoskrnl.h | 3 +- ntoskrnl/include/internal/ob.h | 3 + ntoskrnl/include/internal/ps.h | 2 +- ntoskrnl/include/internal/se.h | 9 + ntoskrnl/io/arcname.c | 4 +- ntoskrnl/io/buildirp.c | 20 +- ntoskrnl/io/cleanup.c | 19 +- ntoskrnl/io/device.c | 5 +- ntoskrnl/io/file.c | 98 +- ntoskrnl/io/fs.c | 157 +- ntoskrnl/io/iocomp.c | 302 +- ntoskrnl/io/iomgr.c | 1 - ntoskrnl/io/iowork.c | 3 +- ntoskrnl/io/lock.c | 16 +- ntoskrnl/io/parttab.c | 26 +- ntoskrnl/io/symlink.c | 406 +- ntoskrnl/io/xhaldisp.c | 7 +- ntoskrnl/io/xhaldrv.c | 443 +- ntoskrnl/kd/gdbstub.c | 724 +- ntoskrnl/ke/bug.c | 62 +- ntoskrnl/ke/catch.c | 114 +- ntoskrnl/ke/i386/exp.c | 45 +- ntoskrnl/ke/i386/irq.c | 119 +- ntoskrnl/ke/i386/kernel.c | 2 +- ntoskrnl/ke/i386/trap.s | 5 +- ntoskrnl/ke/i386/usertrap.c | 3 + ntoskrnl/ke/kthread.c | 5 + ntoskrnl/ke/main.c | 96 +- ntoskrnl/ke/queue.c | 129 +- ntoskrnl/ke/spinlock.c | 4 +- ntoskrnl/ke/wait.c | 977 +- ntoskrnl/ldr/init.c | 291 +- ntoskrnl/ldr/loader.c | 46 +- ntoskrnl/lpc/reply.c | 2 +- ntoskrnl/mm/anonmem.c | 6 +- ntoskrnl/mm/balance.c | 18 +- ntoskrnl/mm/pageop.c | 4 +- ntoskrnl/mm/section.c | 114 +- ntoskrnl/mm/virtual.c | 1 + ntoskrnl/nt/nttimer.c | 63 +- ntoskrnl/ntoskrnl.def | 27 +- ntoskrnl/ntoskrnl.edf | 27 +- ntoskrnl/ob/handle.c | 82 +- ntoskrnl/ob/namespc.c | 3 + ntoskrnl/ob/object.c | 3 +- ntoskrnl/ob/security.c | 108 +- ntoskrnl/ob/symlink.c | 339 + ntoskrnl/ps/create.c | 35 +- ntoskrnl/ps/process.c | 13 +- ntoskrnl/ps/thread.c | 29 +- ntoskrnl/ps/tinfo.c | 10 +- ntoskrnl/rtl/i386/exception.c | 9 +- ntoskrnl/se/acl.c | 95 +- ntoskrnl/se/sd.c | 832 +- ntoskrnl/se/semgr.c | 55 + rosbin.txt | 2 +- rules.mak | 11 +- subsys/csrss/api.h | 6 + subsys/csrss/api/conio.c | 433 +- subsys/csrss/api/handle.c | 36 +- subsys/csrss/api/process.c | 162 +- subsys/csrss/api/wapi.c | 5 + subsys/smss/init.c | 2 +- subsys/system/cmd/.cvsignore | 16 + subsys/system/cmd/alias.c | 356 + subsys/system/cmd/attrib.c | 356 + subsys/system/cmd/batch.c | 450 + subsys/system/cmd/batch.h | 43 + subsys/system/cmd/beep.c | 57 + subsys/system/cmd/bugs.txt | 15 + subsys/system/cmd/call.c | 95 + subsys/system/cmd/chcp.c | 85 + subsys/system/cmd/choice.c | 331 + subsys/system/cmd/cls.c | 65 + subsys/system/cmd/cmd.c | 1190 +++ subsys/system/cmd/cmd.h | 415 + subsys/system/cmd/cmd.rc | 40 + subsys/system/cmd/cmdinput.c | 527 ++ subsys/system/cmd/cmdtable.c | 263 + subsys/system/cmd/cmdver.h | 2 + subsys/system/cmd/color.c | 131 + subsys/system/cmd/config.h | 106 + subsys/system/cmd/console.c | 302 + subsys/system/cmd/copy.c | 755 ++ subsys/system/cmd/date.c | 261 + subsys/system/cmd/del.c | 348 + subsys/system/cmd/delay.c | 58 + subsys/system/cmd/dir.c | 1223 +++ subsys/system/cmd/dirstack.c | 237 + subsys/system/cmd/echo.c | 148 + subsys/system/cmd/error.c | 175 + subsys/system/cmd/filecomp.c | 339 + subsys/system/cmd/files.txt | 61 + subsys/system/cmd/for.c | 157 + subsys/system/cmd/free.c | 165 + subsys/system/cmd/goto.c | 109 + subsys/system/cmd/history.c | 526 ++ subsys/system/cmd/history.txt | 367 + subsys/system/cmd/if.c | 212 + subsys/system/cmd/internal.c | 468 + subsys/system/cmd/label.c | 120 + subsys/system/cmd/license.txt | 342 + subsys/system/cmd/locale.c | 184 + subsys/system/cmd/makefile | 37 + subsys/system/cmd/memory.c | 110 + subsys/system/cmd/misc.c | 598 ++ subsys/system/cmd/move.c | 265 + subsys/system/cmd/msgbox.c | 174 + subsys/system/cmd/path.c | 90 + subsys/system/cmd/pause.c | 66 + subsys/system/cmd/prompt.c | 225 + subsys/system/cmd/readme.txt | 69 + subsys/system/cmd/redir.c | 216 + subsys/system/cmd/ren.c | 281 + subsys/system/cmd/screen.c | 111 + subsys/system/cmd/set.c | 128 + subsys/system/cmd/shift.c | 70 + subsys/system/cmd/start.c | 129 + subsys/system/cmd/strtoclr.c | 290 + subsys/system/cmd/time.c | 221 + subsys/system/cmd/timer.c | 246 + subsys/system/cmd/title.c | 42 + subsys/system/cmd/todo.txt | 16 + subsys/system/cmd/type.c | 111 + subsys/system/cmd/ver.c | 147 + subsys/system/cmd/verify.c | 57 + subsys/system/cmd/vol.c | 113 + subsys/system/cmd/where.c | 333 + subsys/system/cmd/window.c | 247 + subsys/system/cmd/wishlist.txt | 15 + subsys/system/format/format.c | 516 + subsys/system/format/makefile | 20 + subsys/system/shell/.cvsignore | 6 - subsys/system/shell/makefile | 21 - subsys/system/shell/shell.c | 504 - subsys/system/shell/shell.rc | 38 - subsys/system/usetup/bootsup.c | 167 +- subsys/system/usetup/bootsup.h | 4 + subsys/system/usetup/console.c | 30 +- subsys/system/usetup/console.h | 2 +- subsys/system/usetup/format.c | 57 + subsys/system/usetup/format.h | 35 + subsys/system/usetup/infcache.c | 1559 ++++ subsys/system/usetup/infcache.h | 130 + subsys/system/usetup/makefile | 9 +- subsys/system/usetup/partlist.c | 535 +- subsys/system/usetup/partlist.h | 24 +- subsys/system/usetup/progress.h | 2 +- subsys/system/usetup/registry.c | 652 ++ subsys/system/usetup/registry.h | 40 + subsys/system/usetup/usetup.c | 1753 ++-- subsys/system/usetup/usetup.h | 21 + subsys/system/winlogon/makefile | 2 +- subsys/system/winlogon/setup.c | 195 + subsys/system/winlogon/setup.h | 36 + subsys/system/winlogon/winlogon.c | 109 +- subsys/win32k/dib/dib.c | 5 + subsys/win32k/dib/dib.h | 84 +- subsys/win32k/dib/dib16bpp.c | 201 + subsys/win32k/dib/dib1bpp.c | 87 +- subsys/win32k/dib/dib24bpp.c | 154 +- subsys/win32k/dib/dib32bpp.c | 203 + subsys/win32k/dib/dib4bpp.c | 101 +- subsys/win32k/dib/dib8bpp.c | 201 + subsys/win32k/eng/bitblt.c | 324 +- subsys/win32k/eng/clip.c | 14 +- subsys/win32k/eng/copybits.c | 48 +- subsys/win32k/eng/device.c | 14 +- subsys/win32k/eng/handle.c | 17 +- subsys/win32k/eng/lineto.c | 272 +- subsys/win32k/eng/misc.c | 119 + subsys/win32k/eng/misc.h | 28 + subsys/win32k/eng/mouse.c | 312 +- subsys/win32k/eng/objects.h | 33 +- subsys/win32k/eng/paint.c | 48 +- subsys/win32k/eng/palette.c | 8 +- subsys/win32k/eng/surface.c | 110 +- subsys/win32k/eng/transblt.c | 6 + subsys/win32k/eng/xlate.c | 171 +- subsys/win32k/freetype/.cvsignore | 3 - subsys/win32k/freetype/CHANGES | 904 -- subsys/win32k/freetype/builds/.cvsignore | 3 - subsys/win32k/freetype/builds/ansi/ansi.mk | 134 - subsys/win32k/freetype/builds/detect.mk | 130 - subsys/win32k/freetype/builds/dos/detect.mk | 87 - subsys/win32k/freetype/builds/dos/dos-gcc.mk | 134 - subsys/win32k/freetype/builds/freetype.mk | 279 - subsys/win32k/freetype/builds/mac/ftlib.prj | Bin 603 -> 0 bytes subsys/win32k/freetype/builds/mac/readme | 11 - subsys/win32k/freetype/builds/modules.mk | 75 - subsys/win32k/freetype/builds/os2/detect.mk | 62 - subsys/win32k/freetype/builds/os2/os2-dev.mk | 137 - subsys/win32k/freetype/builds/os2/os2-gcc.mk | 135 - subsys/win32k/freetype/builds/unix/aclocal.m4 | 430 - subsys/win32k/freetype/builds/unix/config.guess | 1273 --- subsys/win32k/freetype/builds/unix/config.sub | 1319 --- subsys/win32k/freetype/builds/unix/configure | 2514 ----- subsys/win32k/freetype/builds/unix/configure.in | 74 - subsys/win32k/freetype/builds/unix/detect.mk | 59 - subsys/win32k/freetype/builds/unix/ftconfig.in | 172 - subsys/win32k/freetype/builds/unix/ftsystem.c | 306 - subsys/win32k/freetype/builds/unix/install-sh | 250 - subsys/win32k/freetype/builds/unix/ltconfig | 3078 ------ subsys/win32k/freetype/builds/unix/ltmain.sh | 4012 -------- subsys/win32k/freetype/builds/unix/mkinstalldirs | 40 - subsys/win32k/freetype/builds/unix/unix.in | 216 - subsys/win32k/freetype/builds/win32/detect.mk | 90 - subsys/win32k/freetype/builds/win32/w32-dev.mk | 140 - subsys/win32k/freetype/builds/win32/w32-gcc.mk | 138 - subsys/win32k/freetype/builds/win32/w32-icc.mk | 122 - subsys/win32k/freetype/builds/win32/w32-lcc.mk | 130 - subsys/win32k/freetype/builds/win32/w32-vcc.mk | 129 - subsys/win32k/freetype/ctype.c | 706 -- subsys/win32k/freetype/docs/build | 264 - .../win32k/freetype/docs/design/build-system.html | 910 -- .../win32k/freetype/docs/design/demo-programs.png | 1 - .../win32k/freetype/docs/design/drivers-list.png | 1 - subsys/win32k/freetype/docs/design/index.html | 791 -- subsys/win32k/freetype/docs/design/io-frames.html | 343 - .../freetype/docs/design/library-compilation.png | 1 - subsys/win32k/freetype/docs/design/logo1.png | 1 - .../freetype/docs/design/objects_diagram.png | 1 - .../freetype/docs/design/objects_diagram2.png | 1 - .../freetype/docs/design/platform-detection.png | 1 - .../freetype/docs/design/system-interface.html | 258 - subsys/win32k/freetype/docs/docmaker.py | 516 - subsys/win32k/freetype/docs/freetype2.html | 352 - subsys/win32k/freetype/docs/ft2faq.html | 502 - subsys/win32k/freetype/docs/glnames.py | 1706 ---- subsys/win32k/freetype/docs/glyphs/Image1.png | 1 - subsys/win32k/freetype/docs/glyphs/Image2.png | 1 - subsys/win32k/freetype/docs/glyphs/Image3.png | 1 - subsys/win32k/freetype/docs/glyphs/Image4.png | 1 - subsys/win32k/freetype/docs/glyphs/bbox1.png | 1 - subsys/win32k/freetype/docs/glyphs/bbox2.png | 1 - .../freetype/docs/glyphs/body_comparison.png | 1 - .../win32k/freetype/docs/glyphs/bravo_kerned.png | 1 - .../win32k/freetype/docs/glyphs/bravo_unkerned.png | 1 - subsys/win32k/freetype/docs/glyphs/clipping.png | 1 - subsys/win32k/freetype/docs/glyphs/down_flow.png | 1 - subsys/win32k/freetype/docs/glyphs/grid_1.png | 1 - subsys/win32k/freetype/docs/glyphs/index.html | 1626 ---- .../win32k/freetype/docs/glyphs/points_conic.png | 1 - .../win32k/freetype/docs/glyphs/points_conic2.png | 1 - .../win32k/freetype/docs/glyphs/points_cubic.png | 1 - .../win32k/freetype/docs/glyphs/points_segment.png | 1 - subsys/win32k/freetype/docs/glyphs/twlewis1.png | 1 - subsys/win32k/freetype/docs/glyphs/twlewis2.png | 1 - subsys/win32k/freetype/docs/glyphs/up_flow.png | 1 - subsys/win32k/freetype/docs/tutorial/index.html | 871 -- subsys/win32k/freetype/docs/tutorial/step1.html | 956 -- subsys/win32k/freetype/docs/tutorial/step2.html | 1399 --- subsys/win32k/freetype/grfont.c | 415 - subsys/win32k/freetype/grfont.h | 16 - .../freetype/include/freetype/config/ftconfig.h | 187 - .../freetype/include/freetype/config/ftmodule.h | 10 - .../freetype/include/freetype/config/ftoption.h | 395 - subsys/win32k/freetype/include/freetype/freetype.h | 2286 ----- subsys/win32k/freetype/include/freetype/ftbbox.h | 72 - subsys/win32k/freetype/include/freetype/fterrors.h | 166 - subsys/win32k/freetype/include/freetype/ftglyph.h | 422 - subsys/win32k/freetype/include/freetype/ftimage.h | 1003 -- subsys/win32k/freetype/include/freetype/ftmm.h | 175 - subsys/win32k/freetype/include/freetype/ftmodule.h | 274 - subsys/win32k/freetype/include/freetype/ftnames.h | 52 - subsys/win32k/freetype/include/freetype/ftoutln.h | 344 - subsys/win32k/freetype/include/freetype/ftrender.h | 191 - subsys/win32k/freetype/include/freetype/ftsystem.h | 101 - subsys/win32k/freetype/include/freetype/fttypes.h | 400 - .../freetype/include/freetype/internal/autohint.h | 195 - .../freetype/include/freetype/internal/ftcalc.h | 123 - .../freetype/include/freetype/internal/ftdebug.h | 225 - .../freetype/include/freetype/internal/ftdriver.h | 182 - .../freetype/include/freetype/internal/ftextend.h | 178 - .../freetype/include/freetype/internal/ftlist.h | 113 - .../freetype/include/freetype/internal/ftmemory.h | 127 - .../freetype/include/freetype/internal/ftobjs.h | 532 -- .../freetype/include/freetype/internal/ftstream.h | 361 - .../freetype/include/freetype/internal/psnames.h | 220 - .../freetype/include/freetype/internal/sfnt.h | 492 - .../freetype/include/freetype/internal/t1errors.h | 67 - .../freetype/include/freetype/internal/t1types.h | 188 - .../freetype/include/freetype/internal/t2errors.h | 121 - .../freetype/include/freetype/internal/t2types.h | 218 - .../freetype/include/freetype/internal/tterrors.h | 121 - .../freetype/include/freetype/internal/tttypes.h | 1582 ---- subsys/win32k/freetype/include/freetype/t1tables.h | 235 - subsys/win32k/freetype/include/freetype/ttnameid.h | 698 -- subsys/win32k/freetype/include/freetype/tttables.h | 583 -- subsys/win32k/freetype/include/freetype/tttags.h | 66 - subsys/win32k/freetype/license.txt | 164 - subsys/win32k/freetype/src/autohint/.cvsignore | 3 - .../freetype/src/autohint/CatharonLicense.txt | 123 - subsys/win32k/freetype/src/autohint/ahangles.c | 137 - subsys/win32k/freetype/src/autohint/ahangles.h | 63 - subsys/win32k/freetype/src/autohint/ahglobal.c | 402 - subsys/win32k/freetype/src/autohint/ahglobal.h | 52 - subsys/win32k/freetype/src/autohint/ahglyph.c | 1299 --- subsys/win32k/freetype/src/autohint/ahglyph.h | 93 - subsys/win32k/freetype/src/autohint/ahhint.c | 1398 --- subsys/win32k/freetype/src/autohint/ahhint.h | 72 - subsys/win32k/freetype/src/autohint/ahloader.h | 124 - subsys/win32k/freetype/src/autohint/ahmodule.c | 127 - subsys/win32k/freetype/src/autohint/ahmodule.h | 32 - subsys/win32k/freetype/src/autohint/ahoptim.c | 889 -- subsys/win32k/freetype/src/autohint/ahoptim.h | 136 - subsys/win32k/freetype/src/autohint/ahtypes.h | 492 - subsys/win32k/freetype/src/autohint/autohint.c | 43 - subsys/win32k/freetype/src/autohint/mather.py | 78 - subsys/win32k/freetype/src/autohint/module.mk | 7 - subsys/win32k/freetype/src/autohint/rules.mk | 77 - subsys/win32k/freetype/src/base/.cvsignore | 3 - subsys/win32k/freetype/src/base/ftbase.c | 42 - subsys/win32k/freetype/src/base/ftcalc.c | 773 -- subsys/win32k/freetype/src/base/ftdebug.c | 124 - subsys/win32k/freetype/src/base/ftextend.c | 332 - subsys/win32k/freetype/src/base/ftglyph.c | 1184 --- subsys/win32k/freetype/src/base/ftinit.c | 156 - subsys/win32k/freetype/src/base/ftlist.c | 301 - subsys/win32k/freetype/src/base/ftmm.c | 176 - subsys/win32k/freetype/src/base/ftnames.c | 70 - subsys/win32k/freetype/src/base/ftobjs.c | 3246 ------- subsys/win32k/freetype/src/base/ftoutln.c | 842 -- subsys/win32k/freetype/src/base/ftstream.c | 818 -- subsys/win32k/freetype/src/base/ftsystem.c | 307 - subsys/win32k/freetype/src/base/rules.mk | 83 - subsys/win32k/freetype/src/cff/.cvsignore | 2 - subsys/win32k/freetype/src/cff/cff.c | 40 - subsys/win32k/freetype/src/cff/module.mk | 7 - subsys/win32k/freetype/src/cff/rules.mk | 69 - subsys/win32k/freetype/src/cff/t2driver.c | 377 - subsys/win32k/freetype/src/cff/t2driver.h | 30 - subsys/win32k/freetype/src/cff/t2gload.c | 2045 ---- subsys/win32k/freetype/src/cff/t2gload.h | 213 - subsys/win32k/freetype/src/cff/t2load.c | 757 -- subsys/win32k/freetype/src/cff/t2load.h | 69 - subsys/win32k/freetype/src/cff/t2objs.c | 600 -- subsys/win32k/freetype/src/cff/t2objs.h | 148 - subsys/win32k/freetype/src/cff/t2parse.c | 641 -- subsys/win32k/freetype/src/cff/t2parse.h | 70 - subsys/win32k/freetype/src/cff/t2tokens.h | 96 - subsys/win32k/freetype/src/cid/.cvsignore | 3 - subsys/win32k/freetype/src/cid/cidafm.c | 293 - subsys/win32k/freetype/src/cid/cidafm.h | 78 - subsys/win32k/freetype/src/cid/cidgload.c | 1558 ---- subsys/win32k/freetype/src/cid/cidgload.h | 198 - subsys/win32k/freetype/src/cid/cidload.c | 537 -- subsys/win32k/freetype/src/cid/cidload.h | 70 - subsys/win32k/freetype/src/cid/cidobjs.c | 380 - subsys/win32k/freetype/src/cid/cidobjs.h | 141 - subsys/win32k/freetype/src/cid/cidparse.c | 1024 -- subsys/win32k/freetype/src/cid/cidparse.h | 353 - subsys/win32k/freetype/src/cid/cidriver.c | 259 - subsys/win32k/freetype/src/cid/cidriver.h | 29 - subsys/win32k/freetype/src/cid/cidtokens.h | 99 - subsys/win32k/freetype/src/cid/module.mk | 6 - subsys/win32k/freetype/src/cid/rules.mk | 69 - subsys/win32k/freetype/src/cid/type1cid.c | 40 - subsys/win32k/freetype/src/macfond/.cvsignore | 3 - subsys/win32k/freetype/src/macfond/fonddrvr.c | 616 -- subsys/win32k/freetype/src/otlayout/.cvsignore | 3 - subsys/win32k/freetype/src/otlayout/oltypes.c | 614 -- subsys/win32k/freetype/src/otlayout/oltypes.h | 310 - subsys/win32k/freetype/src/psnames/.cvsignore | 3 - subsys/win32k/freetype/src/psnames/module.mk | 7 - subsys/win32k/freetype/src/psnames/psmodule.c | 320 - subsys/win32k/freetype/src/psnames/psmodule.h | 29 - subsys/win32k/freetype/src/psnames/psnames.c | 24 - subsys/win32k/freetype/src/psnames/pstables.h | 2942 ------ subsys/win32k/freetype/src/psnames/rules.mk | 70 - subsys/win32k/freetype/src/raster1/.cvsignore | 3 - subsys/win32k/freetype/src/raster1/ftraster.c | 3300 ------- subsys/win32k/freetype/src/raster1/ftraster.h | 50 - subsys/win32k/freetype/src/raster1/ftrend1.c | 275 - subsys/win32k/freetype/src/raster1/ftrend1.h | 37 - subsys/win32k/freetype/src/raster1/module.mk | 7 - subsys/win32k/freetype/src/raster1/raster1.c | 35 - subsys/win32k/freetype/src/raster1/rules.mk | 69 - subsys/win32k/freetype/src/sfnt/.cvsignore | 3 - subsys/win32k/freetype/src/sfnt/module.mk | 7 - subsys/win32k/freetype/src/sfnt/rules.mk | 73 - subsys/win32k/freetype/src/sfnt/sfdriver.c | 225 - subsys/win32k/freetype/src/sfnt/sfdriver.h | 29 - subsys/win32k/freetype/src/sfnt/sfnt.c | 57 - subsys/win32k/freetype/src/sfnt/sfobjs.c | 561 -- subsys/win32k/freetype/src/sfnt/sfobjs.h | 57 - subsys/win32k/freetype/src/sfnt/ttcmap.c | 550 -- subsys/win32k/freetype/src/sfnt/ttcmap.h | 45 - subsys/win32k/freetype/src/sfnt/ttload.c | 1676 ---- subsys/win32k/freetype/src/sfnt/ttload.h | 132 - subsys/win32k/freetype/src/sfnt/ttpost.c | 536 -- subsys/win32k/freetype/src/sfnt/ttpost.h | 52 - subsys/win32k/freetype/src/sfnt/ttsbit.c | 1444 --- subsys/win32k/freetype/src/sfnt/ttsbit.h | 65 - subsys/win32k/freetype/src/smooth/.cvsignore | 3 - subsys/win32k/freetype/src/smooth/ftgrays.c | 1969 ---- subsys/win32k/freetype/src/smooth/ftgrays.h | 52 - subsys/win32k/freetype/src/smooth/ftsmooth.c | 220 - subsys/win32k/freetype/src/smooth/ftsmooth.h | 35 - subsys/win32k/freetype/src/smooth/module.mk | 7 - subsys/win32k/freetype/src/smooth/rules.mk | 69 - subsys/win32k/freetype/src/smooth/smooth.c | 35 - subsys/win32k/freetype/src/truetype/.cvsignore | 3 - subsys/win32k/freetype/src/truetype/module.mk | 7 - subsys/win32k/freetype/src/truetype/rules.mk | 70 - subsys/win32k/freetype/src/truetype/truetype.c | 47 - subsys/win32k/freetype/src/truetype/ttdriver.c | 511 - subsys/win32k/freetype/src/truetype/ttdriver.h | 31 - subsys/win32k/freetype/src/truetype/ttgload.c | 1477 --- subsys/win32k/freetype/src/truetype/ttgload.h | 69 - subsys/win32k/freetype/src/truetype/ttinterp.c | 7544 --------------- subsys/win32k/freetype/src/truetype/ttinterp.h | 278 - subsys/win32k/freetype/src/truetype/ttobjs.c | 734 -- subsys/win32k/freetype/src/truetype/ttobjs.h | 412 - subsys/win32k/freetype/src/truetype/ttpload.c | 273 - subsys/win32k/freetype/src/truetype/ttpload.h | 51 - subsys/win32k/freetype/src/type1/.cvsignore | 3 - subsys/win32k/freetype/src/type1/module.mk0 | 6 - subsys/win32k/freetype/src/type1/rules.mk0 | 74 - subsys/win32k/freetype/src/type1/t1afm.c | 293 - subsys/win32k/freetype/src/type1/t1afm.h | 70 - subsys/win32k/freetype/src/type1/t1driver.c | 381 - subsys/win32k/freetype/src/type1/t1driver.h | 30 - subsys/win32k/freetype/src/type1/t1gload.c | 1823 ---- subsys/win32k/freetype/src/type1/t1gload.h | 326 - subsys/win32k/freetype/src/type1/t1hinter.c | 1347 --- subsys/win32k/freetype/src/type1/t1hinter.h | 273 - subsys/win32k/freetype/src/type1/t1load.c | 1594 ---- subsys/win32k/freetype/src/type1/t1load.h | 57 - subsys/win32k/freetype/src/type1/t1objs.c | 544 -- subsys/win32k/freetype/src/type1/t1objs.h | 172 - subsys/win32k/freetype/src/type1/t1parse.c | 761 -- subsys/win32k/freetype/src/type1/t1parse.h | 261 - subsys/win32k/freetype/src/type1/t1tokens.c | 1101 --- subsys/win32k/freetype/src/type1/t1tokens.h | 258 - subsys/win32k/freetype/src/type1/type1.c | 59 - subsys/win32k/freetype/src/type1z/.cvsignore | 3 - subsys/win32k/freetype/src/type1z/Readme.txt | 10 - subsys/win32k/freetype/src/type1z/module.mk | 7 - subsys/win32k/freetype/src/type1z/rules.mk | 72 - subsys/win32k/freetype/src/type1z/type1z.c | 49 - subsys/win32k/freetype/src/type1z/z1afm.c | 293 - subsys/win32k/freetype/src/type1z/z1afm.h | 79 - subsys/win32k/freetype/src/type1z/z1driver.c | 340 - subsys/win32k/freetype/src/type1z/z1driver.h | 29 - subsys/win32k/freetype/src/type1z/z1gload.c | 1482 --- subsys/win32k/freetype/src/type1z/z1gload.h | 187 - subsys/win32k/freetype/src/type1z/z1load.c | 1725 ---- subsys/win32k/freetype/src/type1z/z1load.h | 93 - subsys/win32k/freetype/src/type1z/z1objs.c | 398 - subsys/win32k/freetype/src/type1z/z1objs.h | 161 - subsys/win32k/freetype/src/type1z/z1parse.c | 1398 --- subsys/win32k/freetype/src/type1z/z1parse.h | 363 - subsys/win32k/freetype/src/type1z/z1tokens.h | 132 - subsys/win32k/freetype/src/winfonts/.cvsignore | 3 - subsys/win32k/freetype/src/winfonts/module.mk | 6 - subsys/win32k/freetype/src/winfonts/rules.mk | 64 - subsys/win32k/freetype/src/winfonts/winfnt.c | 623 -- subsys/win32k/freetype/src/winfonts/winfnt.h | 150 - subsys/win32k/include/dce.h | 1 + subsys/win32k/include/guicheck.h | 2 +- subsys/win32k/include/inteng.h | 38 + subsys/win32k/include/winsta.h | 2 + subsys/win32k/main/dllmain.c | 21 +- subsys/win32k/makefile | 31 +- subsys/win32k/misc/driver.c | 78 +- subsys/win32k/ntuser/guicheck.c | 23 +- subsys/win32k/ntuser/input.c | 2 +- subsys/win32k/ntuser/message.c | 18 +- subsys/win32k/ntuser/metric.c | 129 +- subsys/win32k/ntuser/painting.c | 60 +- subsys/win32k/ntuser/stubs.c | 61 - subsys/win32k/ntuser/timer.c | 362 + subsys/win32k/ntuser/windc.c | 28 + subsys/win32k/ntuser/window.c | 240 +- subsys/win32k/ntuser/winsta.c | 12 + subsys/win32k/objects/bitmaps.c | 14 +- subsys/win32k/objects/brush.c | 23 +- subsys/win32k/objects/cliprgn.c | 4 +- subsys/win32k/objects/color.c | 15 +- subsys/win32k/objects/coord.c | 69 +- subsys/win32k/objects/dc.c | 228 +- subsys/win32k/objects/dib.c | 23 +- subsys/win32k/objects/fillshap.c | 184 +- subsys/win32k/objects/gdiobj.c | 31 +- subsys/win32k/objects/icm.c | 2 +- subsys/win32k/objects/line.c | 105 +- subsys/win32k/objects/metafile.c | 2 +- subsys/win32k/objects/objconv.c | 46 +- subsys/win32k/objects/paint.c | 2 +- subsys/win32k/objects/path.c | 2 +- subsys/win32k/objects/pen.c | 2 +- subsys/win32k/objects/polyfill.c | 548 ++ subsys/win32k/objects/print.c | 2 +- subsys/win32k/objects/rect.c | 2 +- subsys/win32k/objects/region.c | 2 +- subsys/win32k/objects/text.c | 357 +- subsys/win32k/objects/wingl.c | 2 +- subsys/win32k/stubs/stubs.c | 1 - subsys/win32k/win32k.def | 4 +- subsys/win32k/win32k.edf | 4 +- system.hiv | 21 +- tools/.cvsignore | 2 + tools/Makefile | 43 +- tools/cdmake/.cvsignore | 10 + tools/cdmake/Makefile | 40 + tools/cdmake/cdmake.c | 1320 +++ tools/cdmake/llmosrt.c | 106 + tools/cdmake/readme.txt | 94 + tools/helper.mk | 167 +- tools/mkflpimg.c | 347 + tools/mkhive/.cvsignore | 2 + tools/mkhive/Makefile | 49 + tools/mkhive/binhive.c | 1385 +++ tools/mkhive/binhive.h | 36 + tools/mkhive/infcache.c | 1479 +++ tools/mkhive/infcache.h | 132 + tools/mkhive/mkhive.c | 149 + tools/mkhive/mkhive.h | 77 + tools/mkhive/reginf.c | 470 + tools/mkhive/reginf.h | 37 + tools/mkhive/registry.c | 714 ++ tools/mkhive/registry.h | 306 + tools/rline.c | 137 + txtsetup.sif | 98 - 1622 files changed, 230435 insertions(+), 140767 deletions(-) delete mode 100644 NEWS create mode 100644 apps/tests/bitblt/bitblt.c delete mode 100644 apps/tests/bitblt/bitblt.cpp rename apps/tests/{simple => messagebox}/.cvsignore (100%) rename apps/tests/{simple => messagebox}/makefile (100%) rename apps/tests/{simple => messagebox}/simple.c (100%) create mode 100644 apps/tests/shaptest/makefile create mode 100644 apps/tests/shaptest/shaptest.c delete mode 100644 apps/tests/tests/hello2/.cvsignore delete mode 100644 apps/tests/tests/hello2/Makefile delete mode 100644 apps/tests/tests/hello2/hello2.c create mode 100644 apps/tests/wm_erasebkgnd/BACKBITMAP.BMP create mode 100644 apps/tests/wm_erasebkgnd/Demo_WM_ERASEBKGND.cpp create mode 100644 apps/tests/wm_erasebkgnd/makefile delete mode 100644 apps/tests/wm_paint/Listing1_1.cpp create mode 100644 apps/tests/wm_paint/wm_paint.c create mode 100644 bootdata/hivecls.inf create mode 100644 bootdata/hivedef.inf create mode 100644 bootdata/hivesft.inf create mode 100644 bootdata/hivesys.inf create mode 100644 bootdata/readme.txt create mode 100644 bootdata/txtsetup.sif delete mode 100644 drivers/dd/mouse/.cvsignore delete mode 100644 drivers/dd/mouse/makefile delete mode 100644 drivers/dd/mouse/mouse.c create mode 100644 drivers/dd/vga/display/objects/copybits.c create mode 100644 drivers/dd/videoprt/.cvsignore create mode 100644 drivers/dd/videoprt/Makefile create mode 100644 drivers/dd/videoprt/videoprt.c rename drivers/dd/{vidport/vidport.def => videoprt/videoprt.def} (100%) rename drivers/dd/{vidport/vidport.edf => videoprt/videoprt.edf} (100%) rename drivers/dd/{vidport/vidport.rc => videoprt/videoprt.rc} (100%) delete mode 100644 drivers/dd/vidport/.cvsignore delete mode 100644 drivers/dd/vidport/makefile delete mode 100644 drivers/dd/vidport/vidport.c delete mode 100644 drivers/dd/vidport/vidport.h delete mode 100644 drivers/input/include/mouse.h delete mode 100644 drivers/input/sermouse/mouse.c delete mode 100644 drivers/input/sermouse/mouse.h delete mode 100644 drivers/input/sermouse/sermouse.h delete mode 100644 drivers/lib/zlib/Make_vms.com delete mode 100644 drivers/lib/zlib/Makefile delete mode 100644 drivers/lib/zlib/contrib/asm386/zlibvc.dsp delete mode 100644 drivers/lib/zlib/contrib/asm386/zlibvc.dsw delete mode 100644 drivers/lib/zlib/contrib/minizip/zlibvc.dsp delete mode 100644 drivers/lib/zlib/contrib/minizip/zlibvc.dsw delete mode 100644 drivers/lib/zlib/makefile.reactos delete mode 100644 drivers/storage/disk/disk.h delete mode 100644 drivers/storage/disk/partitio.h delete mode 100644 hal/halx86/bios32.c delete mode 100644 hal/halx86/mbr.c create mode 100644 include/ddk/ntddmou.h create mode 100644 include/epsapi.h delete mode 100644 include/freetype/config/ftconfig.h delete mode 100644 include/freetype/config/ftmodule.h delete mode 100644 include/freetype/config/ftoption.h delete mode 100644 include/freetype/freetype.h delete mode 100644 include/freetype/ftbbox.h delete mode 100644 include/freetype/fterrors.h delete mode 100644 include/freetype/ftglyph.h delete mode 100644 include/freetype/ftimage.h delete mode 100644 include/freetype/ftmm.h delete mode 100644 include/freetype/ftmodule.h delete mode 100644 include/freetype/ftnames.h delete mode 100644 include/freetype/ftoutln.h delete mode 100644 include/freetype/ftrender.h delete mode 100644 include/freetype/ftsystem.h delete mode 100644 include/freetype/fttypes.h delete mode 100644 include/freetype/internal/autohint.h delete mode 100644 include/freetype/internal/ftcalc.h delete mode 100644 include/freetype/internal/ftdebug.h delete mode 100644 include/freetype/internal/ftdriver.h delete mode 100644 include/freetype/internal/ftextend.h delete mode 100644 include/freetype/internal/ftlist.h delete mode 100644 include/freetype/internal/ftmemory.h delete mode 100644 include/freetype/internal/ftobjs.h delete mode 100644 include/freetype/internal/ftstream.h delete mode 100644 include/freetype/internal/psnames.h delete mode 100644 include/freetype/internal/sfnt.h delete mode 100644 include/freetype/internal/t1errors.h delete mode 100644 include/freetype/internal/t1types.h delete mode 100644 include/freetype/internal/t2errors.h delete mode 100644 include/freetype/internal/t2types.h delete mode 100644 include/freetype/internal/tterrors.h delete mode 100644 include/freetype/internal/tttypes.h delete mode 100644 include/freetype/t1tables.h delete mode 100644 include/freetype/ttnameid.h delete mode 100644 include/freetype/tttables.h delete mode 100644 include/freetype/tttags.h create mode 100755 include/fslib/vfatlib.h create mode 100644 include/napi/i386/floatsave.h create mode 100644 include/rosrtl/thread.h delete mode 100644 lib/crtdll/math/ftol.c create mode 100644 lib/epsapi/enum/drivers.c create mode 100644 lib/epsapi/enum/modules.c create mode 100644 lib/epsapi/enum/processes.c create mode 100644 lib/epsapi/makefile create mode 100644 lib/freetype/.cvsignore create mode 100644 lib/freetype/ChangeLog create mode 100644 lib/freetype/Jamfile create mode 100644 lib/freetype/Jamfile.in create mode 100644 lib/freetype/Jamrules create mode 100644 lib/freetype/Makefile create mode 100644 lib/freetype/Makefile.freetype create mode 100644 lib/freetype/README create mode 100644 lib/freetype/README.ROS create mode 100644 lib/freetype/builds/amiga/README create mode 100644 lib/freetype/builds/amiga/include/freetype/config/ftconfig.h create mode 100644 lib/freetype/builds/amiga/include/freetype/config/ftmodule.h create mode 100644 lib/freetype/builds/amiga/makefile create mode 100644 lib/freetype/builds/amiga/smakefile create mode 100644 lib/freetype/builds/amiga/src/base/ftdebug.c create mode 100644 lib/freetype/builds/amiga/src/base/ftsystem.c create mode 100644 lib/freetype/builds/ansi/ansi-def.mk create mode 100644 lib/freetype/builds/ansi/ansi.mk create mode 100644 lib/freetype/builds/beos/beos-def.mk create mode 100644 lib/freetype/builds/beos/beos.mk create mode 100644 lib/freetype/builds/beos/detect.mk create mode 100644 lib/freetype/builds/compiler/ansi-cc.mk create mode 100644 lib/freetype/builds/compiler/bcc-dev.mk create mode 100644 lib/freetype/builds/compiler/bcc.mk create mode 100644 lib/freetype/builds/compiler/gcc-dev.mk create mode 100644 lib/freetype/builds/compiler/gcc.mk create mode 100644 lib/freetype/builds/compiler/intelc.mk create mode 100644 lib/freetype/builds/compiler/unix-lcc.mk create mode 100644 lib/freetype/builds/compiler/visualage.mk create mode 100644 lib/freetype/builds/compiler/visualc.mk create mode 100644 lib/freetype/builds/compiler/watcom.mk create mode 100644 lib/freetype/builds/compiler/win-lcc.mk create mode 100644 lib/freetype/builds/detect.mk create mode 100644 lib/freetype/builds/dos/detect.mk create mode 100644 lib/freetype/builds/dos/dos-def.mk create mode 100644 lib/freetype/builds/dos/dos-gcc.mk create mode 100644 lib/freetype/builds/freetype.mk create mode 100644 lib/freetype/builds/link_dos.mk create mode 100644 lib/freetype/builds/link_std.mk create mode 100644 lib/freetype/builds/mac/README create mode 100644 lib/freetype/builds/mac/freetype.make create mode 100644 lib/freetype/builds/mac/ftlib.prj create mode 100644 lib/freetype/builds/modules.mk create mode 100644 lib/freetype/builds/newline create mode 100644 lib/freetype/builds/os2/detect.mk create mode 100644 lib/freetype/builds/os2/os2-def.mk create mode 100644 lib/freetype/builds/os2/os2-dev.mk create mode 100644 lib/freetype/builds/os2/os2-gcc.mk create mode 100644 lib/freetype/builds/toplevel.mk create mode 100644 lib/freetype/builds/unix/.cvsignore create mode 100644 lib/freetype/builds/unix/aclocal.m4 create mode 100644 lib/freetype/builds/unix/config.guess create mode 100644 lib/freetype/builds/unix/config.sub create mode 100644 lib/freetype/builds/unix/configure create mode 100644 lib/freetype/builds/unix/configure.ac create mode 100644 lib/freetype/builds/unix/detect.mk create mode 100644 lib/freetype/builds/unix/freetype-config.in create mode 100644 lib/freetype/builds/unix/freetype2.m4 create mode 100644 lib/freetype/builds/unix/ft-munmap.m4 create mode 100644 lib/freetype/builds/unix/ft2unix.h create mode 100644 lib/freetype/builds/unix/ftconfig.in create mode 100644 lib/freetype/builds/unix/ftsystem.c create mode 100644 lib/freetype/builds/unix/install-sh create mode 100644 lib/freetype/builds/unix/install.mk create mode 100644 lib/freetype/builds/unix/ltmain.sh create mode 100644 lib/freetype/builds/unix/mkinstalldirs create mode 100644 lib/freetype/builds/unix/unix-cc.in create mode 100644 lib/freetype/builds/unix/unix-def.in create mode 100644 lib/freetype/builds/unix/unix-dev.mk create mode 100644 lib/freetype/builds/unix/unix-lcc.mk create mode 100644 lib/freetype/builds/unix/unix.mk create mode 100644 lib/freetype/builds/unix/unixddef.mk create mode 100644 lib/freetype/builds/vms/descrip.mms create mode 100644 lib/freetype/builds/vms/ftconfig.h create mode 100644 lib/freetype/builds/vms/ftsystem.c create mode 100644 lib/freetype/builds/win32/detect.mk create mode 100644 lib/freetype/builds/win32/ftdebug.c create mode 100644 lib/freetype/builds/win32/visualc/freetype.dsp create mode 100644 lib/freetype/builds/win32/visualc/freetype.dsw create mode 100644 lib/freetype/builds/win32/visualc/index.html create mode 100644 lib/freetype/builds/win32/w32-bcc.mk create mode 100644 lib/freetype/builds/win32/w32-bccd.mk create mode 100644 lib/freetype/builds/win32/w32-dev.mk create mode 100644 lib/freetype/builds/win32/w32-gcc.mk create mode 100644 lib/freetype/builds/win32/w32-icc.mk create mode 100644 lib/freetype/builds/win32/w32-intl.mk create mode 100644 lib/freetype/builds/win32/w32-lcc.mk create mode 100644 lib/freetype/builds/win32/w32-mingw32.mk create mode 100644 lib/freetype/builds/win32/w32-vcc.mk create mode 100644 lib/freetype/builds/win32/w32-wat.mk create mode 100644 lib/freetype/builds/win32/win32-def.mk create mode 100644 lib/freetype/config.mk create mode 100644 lib/freetype/configure create mode 100644 lib/freetype/descrip.mms create mode 100644 lib/freetype/devel/ft2build.h create mode 100644 lib/freetype/devel/ftoption.h create mode 100644 lib/freetype/docs/CHANGES create mode 100644 lib/freetype/docs/CUSTOMIZE create mode 100644 lib/freetype/docs/DEBUG create mode 100644 lib/freetype/docs/FTL.txt create mode 100644 lib/freetype/docs/GPL.txt create mode 100644 lib/freetype/docs/INSTALL create mode 100644 lib/freetype/docs/INSTALL.ANY create mode 100644 lib/freetype/docs/INSTALL.GNU create mode 100644 lib/freetype/docs/INSTALL.UNX create mode 100644 lib/freetype/docs/INSTALL.VMS create mode 100644 lib/freetype/docs/PATENTS create mode 100644 lib/freetype/docs/TODO create mode 100644 lib/freetype/docs/TRUETYPE create mode 100644 lib/freetype/docs/UPGRADE.UNX create mode 100644 lib/freetype/docs/VERSION.DLL create mode 100644 lib/freetype/docs/license.txt create mode 100644 lib/freetype/docs/modules.txt create mode 100644 lib/freetype/freetype.def create mode 100644 lib/freetype/i386/.cvsignore create mode 100644 lib/freetype/i386/setjmplongjmp.s create mode 100644 lib/freetype/include/freetype/cache/ftccache.h create mode 100644 lib/freetype/include/freetype/cache/ftccmap.h create mode 100644 lib/freetype/include/freetype/cache/ftcglyph.h create mode 100644 lib/freetype/include/freetype/cache/ftcimage.h create mode 100644 lib/freetype/include/freetype/cache/ftcmanag.h create mode 100644 lib/freetype/include/freetype/cache/ftcsbits.h create mode 100644 lib/freetype/include/freetype/cache/ftlru.h create mode 100644 lib/freetype/include/freetype/config/ftconfig.h create mode 100644 lib/freetype/include/freetype/config/ftheader.h create mode 100644 lib/freetype/include/freetype/config/ftmodule.h create mode 100644 lib/freetype/include/freetype/config/ftoption.h create mode 100644 lib/freetype/include/freetype/config/ftstdlib.h create mode 100644 lib/freetype/include/freetype/freetype.h create mode 100644 lib/freetype/include/freetype/ftbbox.h create mode 100644 lib/freetype/include/freetype/ftbdf.h create mode 100644 lib/freetype/include/freetype/ftcache.h create mode 100644 lib/freetype/include/freetype/ftchapters.h create mode 100644 lib/freetype/include/freetype/fterrdef.h create mode 100644 lib/freetype/include/freetype/fterrors.h create mode 100644 lib/freetype/include/freetype/ftglyph.h create mode 100644 lib/freetype/include/freetype/ftgzip.h create mode 100644 lib/freetype/include/freetype/ftimage.h create mode 100644 lib/freetype/include/freetype/ftincrem.h create mode 100644 lib/freetype/include/freetype/ftlist.h create mode 100644 lib/freetype/include/freetype/ftmac.h create mode 100644 lib/freetype/include/freetype/ftmm.h create mode 100644 lib/freetype/include/freetype/ftmoderr.h create mode 100644 lib/freetype/include/freetype/ftmodule.h create mode 100644 lib/freetype/include/freetype/ftoutln.h create mode 100644 lib/freetype/include/freetype/ftpfr.h create mode 100644 lib/freetype/include/freetype/ftrender.h create mode 100644 lib/freetype/include/freetype/ftsizes.h create mode 100644 lib/freetype/include/freetype/ftsnames.h create mode 100644 lib/freetype/include/freetype/ftstroker.h create mode 100644 lib/freetype/include/freetype/ftsynth.h create mode 100644 lib/freetype/include/freetype/ftsysio.h create mode 100644 lib/freetype/include/freetype/ftsysmem.h create mode 100644 lib/freetype/include/freetype/ftsystem.h create mode 100644 lib/freetype/include/freetype/fttrigon.h create mode 100644 lib/freetype/include/freetype/fttypes.h create mode 100644 lib/freetype/include/freetype/ftwinfnt.h create mode 100644 lib/freetype/include/freetype/ftxf86.h create mode 100644 lib/freetype/include/freetype/internal/autohint.h create mode 100644 lib/freetype/include/freetype/internal/bdftypes.h create mode 100644 lib/freetype/include/freetype/internal/cfftypes.h create mode 100644 lib/freetype/include/freetype/internal/fnttypes.h create mode 100644 lib/freetype/include/freetype/internal/ftcalc.h create mode 100644 lib/freetype/include/freetype/internal/ftcore.h create mode 100644 lib/freetype/include/freetype/internal/ftdebug.h create mode 100644 lib/freetype/include/freetype/internal/ftdriver.h create mode 100644 lib/freetype/include/freetype/internal/ftexcept.h create mode 100644 lib/freetype/include/freetype/internal/ftgloadr.h create mode 100644 lib/freetype/include/freetype/internal/fthash.h create mode 100644 lib/freetype/include/freetype/internal/ftmemory.h create mode 100644 lib/freetype/include/freetype/internal/ftobject.h create mode 100644 lib/freetype/include/freetype/internal/ftobjs.h create mode 100644 lib/freetype/include/freetype/internal/ftstream.h create mode 100644 lib/freetype/include/freetype/internal/fttrace.h create mode 100644 lib/freetype/include/freetype/internal/internal.h create mode 100644 lib/freetype/include/freetype/internal/pcftypes.h create mode 100644 lib/freetype/include/freetype/internal/pfr.h create mode 100644 lib/freetype/include/freetype/internal/psaux.h create mode 100644 lib/freetype/include/freetype/internal/pshints.h create mode 100644 lib/freetype/include/freetype/internal/psnames.h create mode 100644 lib/freetype/include/freetype/internal/sfnt.h create mode 100644 lib/freetype/include/freetype/internal/t1types.h create mode 100644 lib/freetype/include/freetype/internal/t42types.h create mode 100644 lib/freetype/include/freetype/internal/tttypes.h create mode 100644 lib/freetype/include/freetype/t1tables.h create mode 100644 lib/freetype/include/freetype/ttnameid.h create mode 100644 lib/freetype/include/freetype/tttables.h create mode 100644 lib/freetype/include/freetype/tttags.h create mode 100644 lib/freetype/include/ft2build.h create mode 100644 lib/freetype/install create mode 100644 lib/freetype/objs/.cvsignore rename {subsys/win32k/freetype/obj => lib/freetype/objs}/README (100%) create mode 100644 lib/freetype/rosglue.c create mode 100644 lib/freetype/src/Jamfile create mode 100644 lib/freetype/src/autohint/CatharonLicense.txt create mode 100644 lib/freetype/src/autohint/Jamfile create mode 100644 lib/freetype/src/autohint/ahangles.c create mode 100644 lib/freetype/src/autohint/ahangles.h create mode 100644 lib/freetype/src/autohint/aherrors.h create mode 100644 lib/freetype/src/autohint/ahglobal.c create mode 100644 lib/freetype/src/autohint/ahglobal.h create mode 100644 lib/freetype/src/autohint/ahglyph.c create mode 100644 lib/freetype/src/autohint/ahglyph.h create mode 100644 lib/freetype/src/autohint/ahhint.c create mode 100644 lib/freetype/src/autohint/ahhint.h create mode 100644 lib/freetype/src/autohint/ahloader.h create mode 100644 lib/freetype/src/autohint/ahmodule.c create mode 100644 lib/freetype/src/autohint/ahmodule.h create mode 100644 lib/freetype/src/autohint/ahoptim.c create mode 100644 lib/freetype/src/autohint/ahoptim.h create mode 100644 lib/freetype/src/autohint/ahtypes.h create mode 100644 lib/freetype/src/autohint/autohint.c create mode 100644 lib/freetype/src/autohint/descrip.mms create mode 100644 lib/freetype/src/autohint/mather.py create mode 100644 lib/freetype/src/autohint/module.mk create mode 100644 lib/freetype/src/autohint/rules.mk create mode 100644 lib/freetype/src/base/Jamfile create mode 100644 lib/freetype/src/base/descrip.mms create mode 100644 lib/freetype/src/base/ftapi.c create mode 100644 lib/freetype/src/base/ftbase.c create mode 100644 lib/freetype/src/base/ftbbox.c create mode 100644 lib/freetype/src/base/ftbdf.c create mode 100644 lib/freetype/src/base/ftcalc.c create mode 100644 lib/freetype/src/base/ftdbgmem.c create mode 100644 lib/freetype/src/base/ftdebug.c create mode 100644 lib/freetype/src/base/ftexcept.c create mode 100644 lib/freetype/src/base/ftgloadr.c create mode 100644 lib/freetype/src/base/ftglyph.c create mode 100644 lib/freetype/src/base/fthash.c create mode 100644 lib/freetype/src/base/ftinit.c create mode 100644 lib/freetype/src/base/ftlist.c create mode 100644 lib/freetype/src/base/ftmac.c create mode 100644 lib/freetype/src/base/ftmm.c create mode 100644 lib/freetype/src/base/ftnames.c create mode 100644 lib/freetype/src/base/ftobject.c create mode 100644 lib/freetype/src/base/ftobjs.c create mode 100644 lib/freetype/src/base/ftoutln.c create mode 100644 lib/freetype/src/base/ftpfr.c create mode 100644 lib/freetype/src/base/ftstream.c create mode 100644 lib/freetype/src/base/ftstroker.c create mode 100644 lib/freetype/src/base/ftsynth.c create mode 100644 lib/freetype/src/base/ftsysio.c create mode 100644 lib/freetype/src/base/ftsysmem.c create mode 100644 lib/freetype/src/base/ftsystem.c create mode 100644 lib/freetype/src/base/fttrigon.c create mode 100644 lib/freetype/src/base/fttype1.c create mode 100644 lib/freetype/src/base/ftutil.c create mode 100644 lib/freetype/src/base/ftwinfnt.c create mode 100644 lib/freetype/src/base/ftxf86.c create mode 100644 lib/freetype/src/base/rules.mk create mode 100644 lib/freetype/src/bdf/Jamfile create mode 100644 lib/freetype/src/bdf/README create mode 100644 lib/freetype/src/bdf/bdf.c create mode 100644 lib/freetype/src/bdf/bdf.h create mode 100644 lib/freetype/src/bdf/bdfdrivr.c create mode 100644 lib/freetype/src/bdf/bdfdrivr.h create mode 100644 lib/freetype/src/bdf/bdferror.h create mode 100644 lib/freetype/src/bdf/bdflib.c create mode 100644 lib/freetype/src/bdf/descrip.mms create mode 100644 lib/freetype/src/bdf/module.mk create mode 100644 lib/freetype/src/bdf/rules.mk create mode 100644 lib/freetype/src/cache/Jamfile create mode 100644 lib/freetype/src/cache/descrip.mms create mode 100644 lib/freetype/src/cache/ftcache.c create mode 100644 lib/freetype/src/cache/ftccache.c create mode 100644 lib/freetype/src/cache/ftccache.i create mode 100644 lib/freetype/src/cache/ftccmap.c create mode 100644 lib/freetype/src/cache/ftcerror.h create mode 100644 lib/freetype/src/cache/ftcglyph.c create mode 100644 lib/freetype/src/cache/ftcimage.c create mode 100644 lib/freetype/src/cache/ftcmanag.c create mode 100644 lib/freetype/src/cache/ftcsbits.c create mode 100644 lib/freetype/src/cache/ftlru.c create mode 100644 lib/freetype/src/cache/rules.mk create mode 100644 lib/freetype/src/cff/Jamfile create mode 100644 lib/freetype/src/cff/cff.c create mode 100644 lib/freetype/src/cff/cffcmap.c create mode 100644 lib/freetype/src/cff/cffcmap.h create mode 100644 lib/freetype/src/cff/cffdrivr.c create mode 100644 lib/freetype/src/cff/cffdrivr.h create mode 100644 lib/freetype/src/cff/cfferrs.h create mode 100644 lib/freetype/src/cff/cffgload.c create mode 100644 lib/freetype/src/cff/cffgload.h create mode 100644 lib/freetype/src/cff/cffload.c create mode 100644 lib/freetype/src/cff/cffload.h create mode 100644 lib/freetype/src/cff/cffobjs.c create mode 100644 lib/freetype/src/cff/cffobjs.h create mode 100644 lib/freetype/src/cff/cffparse.c create mode 100644 lib/freetype/src/cff/cffparse.h create mode 100644 lib/freetype/src/cff/cfftoken.h create mode 100644 lib/freetype/src/cff/descrip.mms create mode 100644 lib/freetype/src/cff/module.mk create mode 100644 lib/freetype/src/cff/rules.mk create mode 100644 lib/freetype/src/cid/Jamfile create mode 100644 lib/freetype/src/cid/ciderrs.h create mode 100644 lib/freetype/src/cid/cidgload.c create mode 100644 lib/freetype/src/cid/cidgload.h create mode 100644 lib/freetype/src/cid/cidload.c create mode 100644 lib/freetype/src/cid/cidload.h create mode 100644 lib/freetype/src/cid/cidobjs.c create mode 100644 lib/freetype/src/cid/cidobjs.h create mode 100644 lib/freetype/src/cid/cidparse.c create mode 100644 lib/freetype/src/cid/cidparse.h create mode 100644 lib/freetype/src/cid/cidriver.c create mode 100644 lib/freetype/src/cid/cidriver.h create mode 100644 lib/freetype/src/cid/cidtoken.h create mode 100644 lib/freetype/src/cid/descrip.mms create mode 100644 lib/freetype/src/cid/module.mk create mode 100644 lib/freetype/src/cid/rules.mk create mode 100644 lib/freetype/src/cid/type1cid.c create mode 100644 lib/freetype/src/gzip/Jamfile create mode 100644 lib/freetype/src/gzip/adler32.c create mode 100644 lib/freetype/src/gzip/descrip.mms create mode 100644 lib/freetype/src/gzip/ftgzip.c create mode 100644 lib/freetype/src/gzip/infblock.c create mode 100644 lib/freetype/src/gzip/infblock.h create mode 100644 lib/freetype/src/gzip/infcodes.c create mode 100644 lib/freetype/src/gzip/infcodes.h rename {drivers/lib/zlib => lib/freetype/src/gzip}/inffixed.h (100%) create mode 100644 lib/freetype/src/gzip/inflate.c create mode 100644 lib/freetype/src/gzip/inftrees.c create mode 100644 lib/freetype/src/gzip/inftrees.h create mode 100644 lib/freetype/src/gzip/infutil.c create mode 100644 lib/freetype/src/gzip/infutil.h create mode 100644 lib/freetype/src/gzip/rules.mk create mode 100644 lib/freetype/src/gzip/zconf.h create mode 100644 lib/freetype/src/gzip/zlib.h create mode 100644 lib/freetype/src/gzip/zutil.c create mode 100644 lib/freetype/src/gzip/zutil.h create mode 100644 lib/freetype/src/otlayout/otlayout.h create mode 100644 lib/freetype/src/otlayout/otlbase.c create mode 100644 lib/freetype/src/otlayout/otlbase.h create mode 100644 lib/freetype/src/otlayout/otlcommn.c create mode 100644 lib/freetype/src/otlayout/otlcommn.h create mode 100644 lib/freetype/src/otlayout/otlconf.h create mode 100644 lib/freetype/src/otlayout/otlgdef.c create mode 100644 lib/freetype/src/otlayout/otlgdef.h create mode 100644 lib/freetype/src/otlayout/otlgpos.c create mode 100644 lib/freetype/src/otlayout/otlgpos.h create mode 100644 lib/freetype/src/otlayout/otlgsub.c create mode 100644 lib/freetype/src/otlayout/otlgsub.h create mode 100644 lib/freetype/src/otlayout/otljstf.c create mode 100644 lib/freetype/src/otlayout/otljstf.h create mode 100644 lib/freetype/src/otlayout/otlparse.c create mode 100644 lib/freetype/src/otlayout/otlparse.h create mode 100644 lib/freetype/src/otlayout/otltable.h create mode 100644 lib/freetype/src/otlayout/otltags.h create mode 100644 lib/freetype/src/otlayout/otlutils.h create mode 100644 lib/freetype/src/pcf/Jamfile create mode 100644 lib/freetype/src/pcf/descrip.mms create mode 100644 lib/freetype/src/pcf/module.mk create mode 100644 lib/freetype/src/pcf/pcf.c create mode 100644 lib/freetype/src/pcf/pcf.h create mode 100644 lib/freetype/src/pcf/pcfdriver.c create mode 100644 lib/freetype/src/pcf/pcfdriver.h create mode 100644 lib/freetype/src/pcf/pcferror.h create mode 100644 lib/freetype/src/pcf/pcfread.c create mode 100644 lib/freetype/src/pcf/pcfread.h create mode 100644 lib/freetype/src/pcf/pcfutil.c create mode 100644 lib/freetype/src/pcf/pcfutil.h create mode 100644 lib/freetype/src/pcf/readme create mode 100644 lib/freetype/src/pcf/rules.mk create mode 100644 lib/freetype/src/pfr/Jamfile create mode 100644 lib/freetype/src/pfr/descrip.mms create mode 100644 lib/freetype/src/pfr/module.mk create mode 100644 lib/freetype/src/pfr/pfr.c create mode 100644 lib/freetype/src/pfr/pfrcmap.c create mode 100644 lib/freetype/src/pfr/pfrcmap.h create mode 100644 lib/freetype/src/pfr/pfrdrivr.c create mode 100644 lib/freetype/src/pfr/pfrdrivr.h create mode 100644 lib/freetype/src/pfr/pfrerror.h create mode 100644 lib/freetype/src/pfr/pfrgload.c create mode 100644 lib/freetype/src/pfr/pfrgload.h create mode 100644 lib/freetype/src/pfr/pfrload.c create mode 100644 lib/freetype/src/pfr/pfrload.h create mode 100644 lib/freetype/src/pfr/pfrobjs.c create mode 100644 lib/freetype/src/pfr/pfrobjs.h create mode 100644 lib/freetype/src/pfr/pfrsbit.c create mode 100644 lib/freetype/src/pfr/pfrsbit.h create mode 100644 lib/freetype/src/pfr/pfrtypes.h create mode 100644 lib/freetype/src/pfr/rules.mk create mode 100644 lib/freetype/src/psaux/Jamfile create mode 100644 lib/freetype/src/psaux/descrip.mms create mode 100644 lib/freetype/src/psaux/module.mk create mode 100644 lib/freetype/src/psaux/psaux.c create mode 100644 lib/freetype/src/psaux/psauxerr.h create mode 100644 lib/freetype/src/psaux/psauxmod.c create mode 100644 lib/freetype/src/psaux/psauxmod.h create mode 100644 lib/freetype/src/psaux/psobjs.c create mode 100644 lib/freetype/src/psaux/psobjs.h create mode 100644 lib/freetype/src/psaux/rules.mk create mode 100644 lib/freetype/src/psaux/t1cmap.c create mode 100644 lib/freetype/src/psaux/t1cmap.h create mode 100644 lib/freetype/src/psaux/t1decode.c create mode 100644 lib/freetype/src/psaux/t1decode.h create mode 100644 lib/freetype/src/pshinter/Jamfile create mode 100644 lib/freetype/src/pshinter/descrip.mms create mode 100644 lib/freetype/src/pshinter/module.mk create mode 100644 lib/freetype/src/pshinter/pshalgo.h create mode 100644 lib/freetype/src/pshinter/pshalgo1.c create mode 100644 lib/freetype/src/pshinter/pshalgo1.h create mode 100644 lib/freetype/src/pshinter/pshalgo2.c create mode 100644 lib/freetype/src/pshinter/pshalgo2.h create mode 100644 lib/freetype/src/pshinter/pshalgo3.c create mode 100644 lib/freetype/src/pshinter/pshalgo3.h create mode 100644 lib/freetype/src/pshinter/pshglob.c create mode 100644 lib/freetype/src/pshinter/pshglob.h create mode 100644 lib/freetype/src/pshinter/pshinter.c create mode 100644 lib/freetype/src/pshinter/pshmod.c create mode 100644 lib/freetype/src/pshinter/pshmod.h create mode 100644 lib/freetype/src/pshinter/pshrec.c create mode 100644 lib/freetype/src/pshinter/pshrec.h create mode 100644 lib/freetype/src/pshinter/rules.mk create mode 100644 lib/freetype/src/psnames/Jamfile create mode 100644 lib/freetype/src/psnames/descrip.mms create mode 100644 lib/freetype/src/psnames/module.mk create mode 100644 lib/freetype/src/psnames/psmodule.c create mode 100644 lib/freetype/src/psnames/psmodule.h create mode 100644 lib/freetype/src/psnames/psnamerr.h create mode 100644 lib/freetype/src/psnames/psnames.c create mode 100644 lib/freetype/src/psnames/pstables.h create mode 100644 lib/freetype/src/psnames/rules.mk create mode 100644 lib/freetype/src/raster/Jamfile create mode 100644 lib/freetype/src/raster/descrip.mms create mode 100644 lib/freetype/src/raster/ftraster.c create mode 100644 lib/freetype/src/raster/ftraster.h create mode 100644 lib/freetype/src/raster/ftrend1.c create mode 100644 lib/freetype/src/raster/ftrend1.h create mode 100644 lib/freetype/src/raster/module.mk create mode 100644 lib/freetype/src/raster/raster.c create mode 100644 lib/freetype/src/raster/rasterrs.h create mode 100644 lib/freetype/src/raster/rules.mk create mode 100644 lib/freetype/src/sfnt/Jamfile create mode 100644 lib/freetype/src/sfnt/descrip.mms create mode 100644 lib/freetype/src/sfnt/module.mk create mode 100644 lib/freetype/src/sfnt/rules.mk create mode 100644 lib/freetype/src/sfnt/sfdriver.c create mode 100644 lib/freetype/src/sfnt/sfdriver.h create mode 100644 lib/freetype/src/sfnt/sferrors.h create mode 100644 lib/freetype/src/sfnt/sfnt.c create mode 100644 lib/freetype/src/sfnt/sfobjs.c create mode 100644 lib/freetype/src/sfnt/sfobjs.h create mode 100644 lib/freetype/src/sfnt/ttcmap.c create mode 100644 lib/freetype/src/sfnt/ttcmap.h create mode 100644 lib/freetype/src/sfnt/ttcmap0.c create mode 100644 lib/freetype/src/sfnt/ttcmap0.h create mode 100644 lib/freetype/src/sfnt/ttload.c create mode 100644 lib/freetype/src/sfnt/ttload.h create mode 100644 lib/freetype/src/sfnt/ttpost.c create mode 100644 lib/freetype/src/sfnt/ttpost.h create mode 100644 lib/freetype/src/sfnt/ttsbit.c create mode 100644 lib/freetype/src/sfnt/ttsbit.h create mode 100644 lib/freetype/src/smooth/Jamfile create mode 100644 lib/freetype/src/smooth/descrip.mms create mode 100644 lib/freetype/src/smooth/ftgrays.c create mode 100644 lib/freetype/src/smooth/ftgrays.h create mode 100644 lib/freetype/src/smooth/ftsmerrs.h create mode 100644 lib/freetype/src/smooth/ftsmooth.c create mode 100644 lib/freetype/src/smooth/ftsmooth.h create mode 100644 lib/freetype/src/smooth/module.mk create mode 100644 lib/freetype/src/smooth/rules.mk create mode 100644 lib/freetype/src/smooth/smooth.c create mode 100644 lib/freetype/src/tools/cordic.py create mode 100644 lib/freetype/src/tools/docmaker/content.py create mode 100644 lib/freetype/src/tools/docmaker/docmaker.py create mode 100644 lib/freetype/src/tools/docmaker/formatter.py create mode 100644 lib/freetype/src/tools/docmaker/sources.py create mode 100644 lib/freetype/src/tools/docmaker/tohtml.py create mode 100644 lib/freetype/src/tools/docmaker/utils.py create mode 100644 lib/freetype/src/tools/glnames.py create mode 100644 lib/freetype/src/tools/test_bbox.c create mode 100644 lib/freetype/src/tools/test_trig.c create mode 100644 lib/freetype/src/truetype/Jamfile create mode 100644 lib/freetype/src/truetype/descrip.mms create mode 100644 lib/freetype/src/truetype/module.mk create mode 100644 lib/freetype/src/truetype/rules.mk create mode 100644 lib/freetype/src/truetype/truetype.c create mode 100644 lib/freetype/src/truetype/ttdriver.c create mode 100644 lib/freetype/src/truetype/ttdriver.h create mode 100644 lib/freetype/src/truetype/tterrors.h create mode 100644 lib/freetype/src/truetype/ttgload.c create mode 100644 lib/freetype/src/truetype/ttgload.h create mode 100644 lib/freetype/src/truetype/ttinterp.c create mode 100644 lib/freetype/src/truetype/ttinterp.h create mode 100644 lib/freetype/src/truetype/ttobjs.c create mode 100644 lib/freetype/src/truetype/ttobjs.h create mode 100644 lib/freetype/src/truetype/ttpload.c create mode 100644 lib/freetype/src/truetype/ttpload.h create mode 100644 lib/freetype/src/type1/Jamfile create mode 100644 lib/freetype/src/type1/descrip.mms create mode 100644 lib/freetype/src/type1/module.mk create mode 100644 lib/freetype/src/type1/rules.mk create mode 100644 lib/freetype/src/type1/t1afm.c create mode 100644 lib/freetype/src/type1/t1afm.h create mode 100644 lib/freetype/src/type1/t1driver.c create mode 100644 lib/freetype/src/type1/t1driver.h create mode 100644 lib/freetype/src/type1/t1errors.h create mode 100644 lib/freetype/src/type1/t1gload.c create mode 100644 lib/freetype/src/type1/t1gload.h create mode 100644 lib/freetype/src/type1/t1load.c create mode 100644 lib/freetype/src/type1/t1load.h create mode 100644 lib/freetype/src/type1/t1objs.c create mode 100644 lib/freetype/src/type1/t1objs.h create mode 100644 lib/freetype/src/type1/t1parse.c create mode 100644 lib/freetype/src/type1/t1parse.h create mode 100644 lib/freetype/src/type1/t1tokens.h create mode 100644 lib/freetype/src/type1/type1.c create mode 100644 lib/freetype/src/type42/Jamfile create mode 100644 lib/freetype/src/type42/descrip.mms create mode 100644 lib/freetype/src/type42/module.mk create mode 100644 lib/freetype/src/type42/rules.mk create mode 100644 lib/freetype/src/type42/t42drivr.c create mode 100644 lib/freetype/src/type42/t42drivr.h create mode 100644 lib/freetype/src/type42/t42error.h create mode 100644 lib/freetype/src/type42/t42objs.c create mode 100644 lib/freetype/src/type42/t42objs.h create mode 100644 lib/freetype/src/type42/t42parse.c create mode 100644 lib/freetype/src/type42/t42parse.h create mode 100644 lib/freetype/src/type42/type42.c create mode 100644 lib/freetype/src/winfonts/Jamfile create mode 100644 lib/freetype/src/winfonts/descrip.mms create mode 100644 lib/freetype/src/winfonts/fnterrs.h create mode 100644 lib/freetype/src/winfonts/module.mk create mode 100644 lib/freetype/src/winfonts/rules.mk create mode 100644 lib/freetype/src/winfonts/winfnt.c create mode 100644 lib/freetype/src/winfonts/winfnt.h create mode 100644 lib/freetype/tests/Jamfile create mode 100644 lib/freetype/tests/gview.c create mode 100755 lib/fslib/vfatlib/.cvsignore create mode 100755 lib/fslib/vfatlib/Makefile create mode 100755 lib/fslib/vfatlib/vfatlib.c create mode 100755 lib/fslib/vfatlib/vfatlib.h create mode 100644 lib/gdi32/objects/fillshap.c delete mode 100644 lib/kernel32/MSG00409.bin create mode 100644 lib/kernel32/debug/.cvsignore create mode 100644 lib/kernel32/debug/break.c create mode 100644 lib/kernel32/debug/debugger.c create mode 100644 lib/kernel32/debug/output.c delete mode 100644 lib/kernel32/errcodes.rc delete mode 100644 lib/kernel32/errormsg.mak delete mode 100644 lib/kernel32/misc/debug.c delete mode 100644 lib/msvcrt/math/ftol.c create mode 100644 lib/msvcrt/misc/cpp.c delete mode 100644 lib/msvcrt/setjmp/.cvsignore create mode 100644 lib/msvcrt/setjmp/i386/.cvsignore create mode 100644 lib/msvcrt/setjmp/i386/setjmp.s delete mode 100644 lib/msvcrt/setjmp/setjmp.c create mode 100755 lib/ntdll/ldr/entry.S create mode 100644 lib/ntdll/rtl/encode.c create mode 100644 lib/ntdll/rtl/i386/ftol.c delete mode 100644 lib/psapi/enum/module.c delete mode 100644 lib/psapi/enum/process.c delete mode 100644 lib/psapi/include/internal/psapi.h create mode 100644 lib/rosrtl/makefile create mode 100644 lib/rosrtl/thread/context.c create mode 100644 lib/rosrtl/thread/create.c create mode 100644 lib/tgetopt/Makefile create mode 100644 lib/tgetopt/_wgetopt.c create mode 100644 lib/tgetopt/getopt.c delete mode 100644 lib/user32/resources/obm_dnarrow.bmp delete mode 100644 lib/user32/resources/obm_dnarrowd.bmp delete mode 100644 lib/user32/resources/obm_dnarrowi.bmp delete mode 100644 lib/user32/resources/obm_lfarrow.bmp delete mode 100644 lib/user32/resources/obm_lfarrowd.bmp delete mode 100644 lib/user32/resources/obm_lfarrowi.bmp delete mode 100644 lib/user32/resources/obm_reduce.bmp delete mode 100644 lib/user32/resources/obm_reduced.bmp delete mode 100644 lib/user32/resources/obm_restore.bmp delete mode 100644 lib/user32/resources/obm_restored.bmp delete mode 100644 lib/user32/resources/obm_rgarrow.bmp delete mode 100644 lib/user32/resources/obm_rgarrowd.bmp delete mode 100644 lib/user32/resources/obm_rgarrowi.bmp delete mode 100644 lib/user32/resources/obm_uparrow.bmp delete mode 100644 lib/user32/resources/obm_uparrowd.bmp delete mode 100644 lib/user32/resources/obm_uparrowi.bmp delete mode 100644 lib/user32/resources/obm_zoom.bmp delete mode 100644 lib/user32/resources/obm_zoomd.bmp create mode 100644 lib/winedbgc/trace.c create mode 100644 lib/winedbgc/trace.h create mode 100644 lib/winspool/.cvsignore create mode 100644 lib/winspool/Makefile create mode 100644 lib/winspool/stubs.c create mode 100644 lib/winspool/winspool.def create mode 100644 lib/winspool/winspool.edf create mode 100644 lib/winspool/winspool.rc create mode 100644 lib/wsock32/.cvsignore create mode 100644 lib/wsock32/Makefile create mode 100644 lib/wsock32/stubs.c create mode 100644 lib/wsock32/wsock32.def create mode 100644 lib/wsock32/wsock32.edf create mode 100644 lib/wsock32/wsock32.rc rename {drivers/lib => lib}/zlib/.cvsignore (100%) rename {drivers/lib => lib}/zlib/ChangeLog (100%) rename {drivers/lib => lib}/zlib/FAQ (100%) rename {drivers/lib => lib}/zlib/INDEX (100%) create mode 100644 lib/zlib/Make_vms.com create mode 100644 lib/zlib/Makefile rename {drivers/lib => lib}/zlib/Makefile.in (100%) rename {drivers/lib => lib}/zlib/Makefile.riscos (100%) rename {drivers/lib => lib}/zlib/README (100%) rename {drivers/lib => lib}/zlib/adler32.c (100%) rename {drivers/lib => lib}/zlib/algorithm.txt (100%) rename {drivers/lib => lib}/zlib/amiga/Makefile.pup (100%) rename {drivers/lib => lib}/zlib/amiga/Makefile.sas (100%) rename {drivers/lib => lib}/zlib/compress.c (100%) rename {drivers/lib => lib}/zlib/configure (100%) rename {drivers/lib => lib}/zlib/contrib/README.contrib (100%) rename {drivers/lib => lib}/zlib/contrib/asm386/gvmat32.asm (100%) rename {drivers/lib => lib}/zlib/contrib/asm386/gvmat32c.c (100%) rename {drivers/lib => lib}/zlib/contrib/asm386/mkgvmt32.bat (100%) rename {drivers/lib => lib}/zlib/contrib/asm386/zlibvc.def (100%) create mode 100644 lib/zlib/contrib/asm386/zlibvc.dsp create mode 100644 lib/zlib/contrib/asm386/zlibvc.dsw rename {drivers/lib => lib}/zlib/contrib/asm586/README.586 (100%) rename {drivers/lib => lib}/zlib/contrib/asm586/match.S (100%) rename {drivers/lib => lib}/zlib/contrib/asm686/README.686 (100%) rename {drivers/lib => lib}/zlib/contrib/asm686/match.S (100%) rename {drivers/lib => lib}/zlib/contrib/delphi/zlib.mak (100%) rename {drivers/lib => lib}/zlib/contrib/delphi/zlibdef.pas (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/d_zlib.bpr (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/d_zlib.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/readme.txt (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib.bpg (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib.bpr (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib.pas (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib32.bpr (100%) rename {drivers/lib => lib}/zlib/contrib/delphi2/zlib32.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/iostream/test.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/iostream/zfstream.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/iostream/zfstream.h (100%) rename {drivers/lib => lib}/zlib/contrib/iostream2/zstream.h (100%) rename {drivers/lib => lib}/zlib/contrib/iostream2/zstream_test.cpp (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/ChangeLogUnzip (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/Makefile (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/miniunz.c (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/minizip.c (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/readme.txt (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/unzip.c (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/unzip.def (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/unzip.h (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/zip.c (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/zip.def (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/zip.h (100%) rename {drivers/lib => lib}/zlib/contrib/minizip/zlibvc.def (100%) create mode 100644 lib/zlib/contrib/minizip/zlibvc.dsp create mode 100644 lib/zlib/contrib/minizip/zlibvc.dsw rename {drivers/lib => lib}/zlib/contrib/untgz/Makefile (100%) rename {drivers/lib => lib}/zlib/contrib/untgz/makefile.w32 (100%) rename {drivers/lib => lib}/zlib/contrib/untgz/untgz.c (100%) rename {drivers/lib => lib}/zlib/contrib/visual-basic.txt (100%) rename {drivers/lib => lib}/zlib/crc32.c (100%) rename {drivers/lib => lib}/zlib/deflate.c (100%) rename {drivers/lib => lib}/zlib/deflate.h (100%) rename {drivers/lib => lib}/zlib/descrip.mms (100%) rename {drivers/lib => lib}/zlib/example.c (100%) rename {drivers/lib => lib}/zlib/gzio.c (100%) rename {drivers/lib => lib}/zlib/infblock.c (100%) rename {drivers/lib => lib}/zlib/infblock.h (100%) rename {drivers/lib => lib}/zlib/infcodes.c (100%) rename {drivers/lib => lib}/zlib/infcodes.h (100%) rename {drivers/lib => lib}/zlib/inffast.c (100%) rename {drivers/lib => lib}/zlib/inffast.h (100%) create mode 100644 lib/zlib/inffixed.h rename {drivers/lib => lib}/zlib/inflate.c (100%) rename {drivers/lib => lib}/zlib/inftrees.c (100%) rename {drivers/lib => lib}/zlib/inftrees.h (100%) rename {drivers/lib => lib}/zlib/infutil.c (100%) rename {drivers/lib => lib}/zlib/infutil.h (100%) rename {drivers/lib => lib}/zlib/maketree.c (100%) rename {drivers/lib => lib}/zlib/minigzip.c (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.b32 (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.bor (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.dj2 (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.emx (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.msc (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.tc (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.w32 (100%) rename {drivers/lib => lib}/zlib/msdos/Makefile.wat (100%) rename {drivers/lib => lib}/zlib/msdos/zlib.def (100%) rename {drivers/lib => lib}/zlib/msdos/zlib.rc (100%) rename {drivers/lib => lib}/zlib/nt/Makefile.emx (100%) rename {drivers/lib => lib}/zlib/nt/Makefile.gcc (100%) rename {drivers/lib => lib}/zlib/nt/Makefile.nt (100%) rename {drivers/lib => lib}/zlib/nt/zlib.dnt (100%) rename {drivers/lib => lib}/zlib/os2/Makefile.os2 (100%) rename {drivers/lib => lib}/zlib/os2/zlib.def (100%) rename {drivers/lib => lib}/zlib/trees.c (100%) rename {drivers/lib => lib}/zlib/trees.h (100%) rename {drivers/lib => lib}/zlib/uncompr.c (100%) rename {drivers/lib => lib}/zlib/zconf.h (100%) rename {drivers/lib => lib}/zlib/zlib.3 (100%) rename {drivers/lib => lib}/zlib/zlib.h (100%) rename {drivers/lib => lib}/zlib/zlib.html (100%) rename {drivers/lib => lib}/zlib/zutil.c (100%) rename {drivers/lib => lib}/zlib/zutil.h (100%) delete mode 100644 loaders/boot/boot.asm delete mode 100644 loaders/boot/boot.inc delete mode 100644 loaders/boot/boot.mak delete mode 100644 loaders/boot/bootbk.asm delete mode 100644 loaders/boot/osldr.asm delete mode 100644 loaders/boot/osldr.txt create mode 100644 ntoskrnl/ob/symlink.c create mode 100644 subsys/system/cmd/.cvsignore create mode 100644 subsys/system/cmd/alias.c create mode 100644 subsys/system/cmd/attrib.c create mode 100644 subsys/system/cmd/batch.c create mode 100644 subsys/system/cmd/batch.h create mode 100644 subsys/system/cmd/beep.c create mode 100644 subsys/system/cmd/bugs.txt create mode 100644 subsys/system/cmd/call.c create mode 100644 subsys/system/cmd/chcp.c create mode 100644 subsys/system/cmd/choice.c create mode 100644 subsys/system/cmd/cls.c create mode 100644 subsys/system/cmd/cmd.c create mode 100644 subsys/system/cmd/cmd.h create mode 100644 subsys/system/cmd/cmd.rc create mode 100644 subsys/system/cmd/cmdinput.c create mode 100644 subsys/system/cmd/cmdtable.c create mode 100644 subsys/system/cmd/cmdver.h create mode 100644 subsys/system/cmd/color.c create mode 100644 subsys/system/cmd/config.h create mode 100644 subsys/system/cmd/console.c create mode 100644 subsys/system/cmd/copy.c create mode 100644 subsys/system/cmd/date.c create mode 100644 subsys/system/cmd/del.c create mode 100644 subsys/system/cmd/delay.c create mode 100644 subsys/system/cmd/dir.c create mode 100644 subsys/system/cmd/dirstack.c create mode 100644 subsys/system/cmd/echo.c create mode 100644 subsys/system/cmd/error.c create mode 100644 subsys/system/cmd/filecomp.c create mode 100644 subsys/system/cmd/files.txt create mode 100644 subsys/system/cmd/for.c create mode 100644 subsys/system/cmd/free.c create mode 100644 subsys/system/cmd/goto.c create mode 100644 subsys/system/cmd/history.c create mode 100644 subsys/system/cmd/history.txt create mode 100644 subsys/system/cmd/if.c create mode 100644 subsys/system/cmd/internal.c create mode 100644 subsys/system/cmd/label.c create mode 100644 subsys/system/cmd/license.txt create mode 100644 subsys/system/cmd/locale.c create mode 100644 subsys/system/cmd/makefile create mode 100644 subsys/system/cmd/memory.c create mode 100644 subsys/system/cmd/misc.c create mode 100644 subsys/system/cmd/move.c create mode 100644 subsys/system/cmd/msgbox.c create mode 100644 subsys/system/cmd/path.c create mode 100644 subsys/system/cmd/pause.c create mode 100644 subsys/system/cmd/prompt.c create mode 100644 subsys/system/cmd/readme.txt create mode 100644 subsys/system/cmd/redir.c create mode 100644 subsys/system/cmd/ren.c create mode 100644 subsys/system/cmd/screen.c create mode 100644 subsys/system/cmd/set.c create mode 100644 subsys/system/cmd/shift.c create mode 100644 subsys/system/cmd/start.c create mode 100644 subsys/system/cmd/strtoclr.c create mode 100644 subsys/system/cmd/time.c create mode 100644 subsys/system/cmd/timer.c create mode 100644 subsys/system/cmd/title.c create mode 100644 subsys/system/cmd/todo.txt create mode 100644 subsys/system/cmd/type.c create mode 100644 subsys/system/cmd/ver.c create mode 100644 subsys/system/cmd/verify.c create mode 100644 subsys/system/cmd/vol.c create mode 100644 subsys/system/cmd/where.c create mode 100644 subsys/system/cmd/window.c create mode 100644 subsys/system/cmd/wishlist.txt create mode 100755 subsys/system/format/format.c create mode 100755 subsys/system/format/makefile delete mode 100644 subsys/system/shell/.cvsignore delete mode 100644 subsys/system/shell/makefile delete mode 100644 subsys/system/shell/shell.c delete mode 100644 subsys/system/shell/shell.rc create mode 100755 subsys/system/usetup/format.c create mode 100755 subsys/system/usetup/format.h create mode 100644 subsys/system/usetup/infcache.c create mode 100644 subsys/system/usetup/infcache.h create mode 100644 subsys/system/usetup/registry.c create mode 100644 subsys/system/usetup/registry.h create mode 100644 subsys/system/winlogon/setup.c create mode 100644 subsys/system/winlogon/setup.h create mode 100644 subsys/win32k/dib/dib.c create mode 100644 subsys/win32k/dib/dib16bpp.c create mode 100644 subsys/win32k/dib/dib32bpp.c create mode 100644 subsys/win32k/dib/dib8bpp.c create mode 100644 subsys/win32k/eng/misc.c create mode 100644 subsys/win32k/eng/misc.h delete mode 100644 subsys/win32k/freetype/.cvsignore delete mode 100644 subsys/win32k/freetype/CHANGES delete mode 100644 subsys/win32k/freetype/builds/.cvsignore delete mode 100644 subsys/win32k/freetype/builds/ansi/ansi.mk delete mode 100644 subsys/win32k/freetype/builds/detect.mk delete mode 100644 subsys/win32k/freetype/builds/dos/detect.mk delete mode 100644 subsys/win32k/freetype/builds/dos/dos-gcc.mk delete mode 100644 subsys/win32k/freetype/builds/freetype.mk delete mode 100644 subsys/win32k/freetype/builds/mac/ftlib.prj delete mode 100644 subsys/win32k/freetype/builds/mac/readme delete mode 100644 subsys/win32k/freetype/builds/modules.mk delete mode 100644 subsys/win32k/freetype/builds/os2/detect.mk delete mode 100644 subsys/win32k/freetype/builds/os2/os2-dev.mk delete mode 100644 subsys/win32k/freetype/builds/os2/os2-gcc.mk delete mode 100644 subsys/win32k/freetype/builds/unix/aclocal.m4 delete mode 100644 subsys/win32k/freetype/builds/unix/config.guess delete mode 100644 subsys/win32k/freetype/builds/unix/config.sub delete mode 100644 subsys/win32k/freetype/builds/unix/configure delete mode 100644 subsys/win32k/freetype/builds/unix/configure.in delete mode 100644 subsys/win32k/freetype/builds/unix/detect.mk delete mode 100644 subsys/win32k/freetype/builds/unix/ftconfig.in delete mode 100644 subsys/win32k/freetype/builds/unix/ftsystem.c delete mode 100644 subsys/win32k/freetype/builds/unix/install-sh delete mode 100644 subsys/win32k/freetype/builds/unix/ltconfig delete mode 100644 subsys/win32k/freetype/builds/unix/ltmain.sh delete mode 100644 subsys/win32k/freetype/builds/unix/mkinstalldirs delete mode 100644 subsys/win32k/freetype/builds/unix/unix.in delete mode 100644 subsys/win32k/freetype/builds/win32/detect.mk delete mode 100644 subsys/win32k/freetype/builds/win32/w32-dev.mk delete mode 100644 subsys/win32k/freetype/builds/win32/w32-gcc.mk delete mode 100644 subsys/win32k/freetype/builds/win32/w32-icc.mk delete mode 100644 subsys/win32k/freetype/builds/win32/w32-lcc.mk delete mode 100644 subsys/win32k/freetype/builds/win32/w32-vcc.mk delete mode 100644 subsys/win32k/freetype/ctype.c delete mode 100644 subsys/win32k/freetype/docs/build delete mode 100644 subsys/win32k/freetype/docs/design/build-system.html delete mode 100644 subsys/win32k/freetype/docs/design/demo-programs.png delete mode 100644 subsys/win32k/freetype/docs/design/drivers-list.png delete mode 100644 subsys/win32k/freetype/docs/design/index.html delete mode 100644 subsys/win32k/freetype/docs/design/io-frames.html delete mode 100644 subsys/win32k/freetype/docs/design/library-compilation.png delete mode 100644 subsys/win32k/freetype/docs/design/logo1.png delete mode 100644 subsys/win32k/freetype/docs/design/objects_diagram.png delete mode 100644 subsys/win32k/freetype/docs/design/objects_diagram2.png delete mode 100644 subsys/win32k/freetype/docs/design/platform-detection.png delete mode 100644 subsys/win32k/freetype/docs/design/system-interface.html delete mode 100644 subsys/win32k/freetype/docs/docmaker.py delete mode 100644 subsys/win32k/freetype/docs/freetype2.html delete mode 100644 subsys/win32k/freetype/docs/ft2faq.html delete mode 100644 subsys/win32k/freetype/docs/glnames.py delete mode 100644 subsys/win32k/freetype/docs/glyphs/Image1.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/Image2.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/Image3.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/Image4.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/bbox1.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/bbox2.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/body_comparison.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/bravo_kerned.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/bravo_unkerned.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/clipping.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/down_flow.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/grid_1.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/index.html delete mode 100644 subsys/win32k/freetype/docs/glyphs/points_conic.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/points_conic2.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/points_cubic.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/points_segment.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/twlewis1.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/twlewis2.png delete mode 100644 subsys/win32k/freetype/docs/glyphs/up_flow.png delete mode 100644 subsys/win32k/freetype/docs/tutorial/index.html delete mode 100644 subsys/win32k/freetype/docs/tutorial/step1.html delete mode 100644 subsys/win32k/freetype/docs/tutorial/step2.html delete mode 100644 subsys/win32k/freetype/grfont.c delete mode 100644 subsys/win32k/freetype/grfont.h delete mode 100644 subsys/win32k/freetype/include/freetype/config/ftconfig.h delete mode 100644 subsys/win32k/freetype/include/freetype/config/ftmodule.h delete mode 100644 subsys/win32k/freetype/include/freetype/config/ftoption.h delete mode 100644 subsys/win32k/freetype/include/freetype/freetype.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftbbox.h delete mode 100644 subsys/win32k/freetype/include/freetype/fterrors.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftglyph.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftimage.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftmm.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftmodule.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftnames.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftoutln.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftrender.h delete mode 100644 subsys/win32k/freetype/include/freetype/ftsystem.h delete mode 100644 subsys/win32k/freetype/include/freetype/fttypes.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/autohint.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftcalc.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftdebug.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftdriver.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftextend.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftlist.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftmemory.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftobjs.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/ftstream.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/psnames.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/sfnt.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/t1errors.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/t1types.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/t2errors.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/t2types.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/tterrors.h delete mode 100644 subsys/win32k/freetype/include/freetype/internal/tttypes.h delete mode 100644 subsys/win32k/freetype/include/freetype/t1tables.h delete mode 100644 subsys/win32k/freetype/include/freetype/ttnameid.h delete mode 100644 subsys/win32k/freetype/include/freetype/tttables.h delete mode 100644 subsys/win32k/freetype/include/freetype/tttags.h delete mode 100644 subsys/win32k/freetype/license.txt delete mode 100644 subsys/win32k/freetype/src/autohint/.cvsignore delete mode 100644 subsys/win32k/freetype/src/autohint/CatharonLicense.txt delete mode 100644 subsys/win32k/freetype/src/autohint/ahangles.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahangles.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahglobal.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahglobal.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahglyph.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahglyph.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahhint.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahhint.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahloader.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahmodule.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahmodule.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahoptim.c delete mode 100644 subsys/win32k/freetype/src/autohint/ahoptim.h delete mode 100644 subsys/win32k/freetype/src/autohint/ahtypes.h delete mode 100644 subsys/win32k/freetype/src/autohint/autohint.c delete mode 100644 subsys/win32k/freetype/src/autohint/mather.py delete mode 100644 subsys/win32k/freetype/src/autohint/module.mk delete mode 100644 subsys/win32k/freetype/src/autohint/rules.mk delete mode 100644 subsys/win32k/freetype/src/base/.cvsignore delete mode 100644 subsys/win32k/freetype/src/base/ftbase.c delete mode 100644 subsys/win32k/freetype/src/base/ftcalc.c delete mode 100644 subsys/win32k/freetype/src/base/ftdebug.c delete mode 100644 subsys/win32k/freetype/src/base/ftextend.c delete mode 100644 subsys/win32k/freetype/src/base/ftglyph.c delete mode 100644 subsys/win32k/freetype/src/base/ftinit.c delete mode 100644 subsys/win32k/freetype/src/base/ftlist.c delete mode 100644 subsys/win32k/freetype/src/base/ftmm.c delete mode 100644 subsys/win32k/freetype/src/base/ftnames.c delete mode 100644 subsys/win32k/freetype/src/base/ftobjs.c delete mode 100644 subsys/win32k/freetype/src/base/ftoutln.c delete mode 100644 subsys/win32k/freetype/src/base/ftstream.c delete mode 100644 subsys/win32k/freetype/src/base/ftsystem.c delete mode 100644 subsys/win32k/freetype/src/base/rules.mk delete mode 100644 subsys/win32k/freetype/src/cff/.cvsignore delete mode 100644 subsys/win32k/freetype/src/cff/cff.c delete mode 100644 subsys/win32k/freetype/src/cff/module.mk delete mode 100644 subsys/win32k/freetype/src/cff/rules.mk delete mode 100644 subsys/win32k/freetype/src/cff/t2driver.c delete mode 100644 subsys/win32k/freetype/src/cff/t2driver.h delete mode 100644 subsys/win32k/freetype/src/cff/t2gload.c delete mode 100644 subsys/win32k/freetype/src/cff/t2gload.h delete mode 100644 subsys/win32k/freetype/src/cff/t2load.c delete mode 100644 subsys/win32k/freetype/src/cff/t2load.h delete mode 100644 subsys/win32k/freetype/src/cff/t2objs.c delete mode 100644 subsys/win32k/freetype/src/cff/t2objs.h delete mode 100644 subsys/win32k/freetype/src/cff/t2parse.c delete mode 100644 subsys/win32k/freetype/src/cff/t2parse.h delete mode 100644 subsys/win32k/freetype/src/cff/t2tokens.h delete mode 100644 subsys/win32k/freetype/src/cid/.cvsignore delete mode 100644 subsys/win32k/freetype/src/cid/cidafm.c delete mode 100644 subsys/win32k/freetype/src/cid/cidafm.h delete mode 100644 subsys/win32k/freetype/src/cid/cidgload.c delete mode 100644 subsys/win32k/freetype/src/cid/cidgload.h delete mode 100644 subsys/win32k/freetype/src/cid/cidload.c delete mode 100644 subsys/win32k/freetype/src/cid/cidload.h delete mode 100644 subsys/win32k/freetype/src/cid/cidobjs.c delete mode 100644 subsys/win32k/freetype/src/cid/cidobjs.h delete mode 100644 subsys/win32k/freetype/src/cid/cidparse.c delete mode 100644 subsys/win32k/freetype/src/cid/cidparse.h delete mode 100644 subsys/win32k/freetype/src/cid/cidriver.c delete mode 100644 subsys/win32k/freetype/src/cid/cidriver.h delete mode 100644 subsys/win32k/freetype/src/cid/cidtokens.h delete mode 100644 subsys/win32k/freetype/src/cid/module.mk delete mode 100644 subsys/win32k/freetype/src/cid/rules.mk delete mode 100644 subsys/win32k/freetype/src/cid/type1cid.c delete mode 100644 subsys/win32k/freetype/src/macfond/.cvsignore delete mode 100644 subsys/win32k/freetype/src/macfond/fonddrvr.c delete mode 100644 subsys/win32k/freetype/src/otlayout/.cvsignore delete mode 100644 subsys/win32k/freetype/src/otlayout/oltypes.c delete mode 100644 subsys/win32k/freetype/src/otlayout/oltypes.h delete mode 100644 subsys/win32k/freetype/src/psnames/.cvsignore delete mode 100644 subsys/win32k/freetype/src/psnames/module.mk delete mode 100644 subsys/win32k/freetype/src/psnames/psmodule.c delete mode 100644 subsys/win32k/freetype/src/psnames/psmodule.h delete mode 100644 subsys/win32k/freetype/src/psnames/psnames.c delete mode 100644 subsys/win32k/freetype/src/psnames/pstables.h delete mode 100644 subsys/win32k/freetype/src/psnames/rules.mk delete mode 100644 subsys/win32k/freetype/src/raster1/.cvsignore delete mode 100644 subsys/win32k/freetype/src/raster1/ftraster.c delete mode 100644 subsys/win32k/freetype/src/raster1/ftraster.h delete mode 100644 subsys/win32k/freetype/src/raster1/ftrend1.c delete mode 100644 subsys/win32k/freetype/src/raster1/ftrend1.h delete mode 100644 subsys/win32k/freetype/src/raster1/module.mk delete mode 100644 subsys/win32k/freetype/src/raster1/raster1.c delete mode 100644 subsys/win32k/freetype/src/raster1/rules.mk delete mode 100644 subsys/win32k/freetype/src/sfnt/.cvsignore delete mode 100644 subsys/win32k/freetype/src/sfnt/module.mk delete mode 100644 subsys/win32k/freetype/src/sfnt/rules.mk delete mode 100644 subsys/win32k/freetype/src/sfnt/sfdriver.c delete mode 100644 subsys/win32k/freetype/src/sfnt/sfdriver.h delete mode 100644 subsys/win32k/freetype/src/sfnt/sfnt.c delete mode 100644 subsys/win32k/freetype/src/sfnt/sfobjs.c delete mode 100644 subsys/win32k/freetype/src/sfnt/sfobjs.h delete mode 100644 subsys/win32k/freetype/src/sfnt/ttcmap.c delete mode 100644 subsys/win32k/freetype/src/sfnt/ttcmap.h delete mode 100644 subsys/win32k/freetype/src/sfnt/ttload.c delete mode 100644 subsys/win32k/freetype/src/sfnt/ttload.h delete mode 100644 subsys/win32k/freetype/src/sfnt/ttpost.c delete mode 100644 subsys/win32k/freetype/src/sfnt/ttpost.h delete mode 100644 subsys/win32k/freetype/src/sfnt/ttsbit.c delete mode 100644 subsys/win32k/freetype/src/sfnt/ttsbit.h delete mode 100644 subsys/win32k/freetype/src/smooth/.cvsignore delete mode 100644 subsys/win32k/freetype/src/smooth/ftgrays.c delete mode 100644 subsys/win32k/freetype/src/smooth/ftgrays.h delete mode 100644 subsys/win32k/freetype/src/smooth/ftsmooth.c delete mode 100644 subsys/win32k/freetype/src/smooth/ftsmooth.h delete mode 100644 subsys/win32k/freetype/src/smooth/module.mk delete mode 100644 subsys/win32k/freetype/src/smooth/rules.mk delete mode 100644 subsys/win32k/freetype/src/smooth/smooth.c delete mode 100644 subsys/win32k/freetype/src/truetype/.cvsignore delete mode 100644 subsys/win32k/freetype/src/truetype/module.mk delete mode 100644 subsys/win32k/freetype/src/truetype/rules.mk delete mode 100644 subsys/win32k/freetype/src/truetype/truetype.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttdriver.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttdriver.h delete mode 100644 subsys/win32k/freetype/src/truetype/ttgload.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttgload.h delete mode 100644 subsys/win32k/freetype/src/truetype/ttinterp.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttinterp.h delete mode 100644 subsys/win32k/freetype/src/truetype/ttobjs.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttobjs.h delete mode 100644 subsys/win32k/freetype/src/truetype/ttpload.c delete mode 100644 subsys/win32k/freetype/src/truetype/ttpload.h delete mode 100644 subsys/win32k/freetype/src/type1/.cvsignore delete mode 100644 subsys/win32k/freetype/src/type1/module.mk0 delete mode 100644 subsys/win32k/freetype/src/type1/rules.mk0 delete mode 100644 subsys/win32k/freetype/src/type1/t1afm.c delete mode 100644 subsys/win32k/freetype/src/type1/t1afm.h delete mode 100644 subsys/win32k/freetype/src/type1/t1driver.c delete mode 100644 subsys/win32k/freetype/src/type1/t1driver.h delete mode 100644 subsys/win32k/freetype/src/type1/t1gload.c delete mode 100644 subsys/win32k/freetype/src/type1/t1gload.h delete mode 100644 subsys/win32k/freetype/src/type1/t1hinter.c delete mode 100644 subsys/win32k/freetype/src/type1/t1hinter.h delete mode 100644 subsys/win32k/freetype/src/type1/t1load.c delete mode 100644 subsys/win32k/freetype/src/type1/t1load.h delete mode 100644 subsys/win32k/freetype/src/type1/t1objs.c delete mode 100644 subsys/win32k/freetype/src/type1/t1objs.h delete mode 100644 subsys/win32k/freetype/src/type1/t1parse.c delete mode 100644 subsys/win32k/freetype/src/type1/t1parse.h delete mode 100644 subsys/win32k/freetype/src/type1/t1tokens.c delete mode 100644 subsys/win32k/freetype/src/type1/t1tokens.h delete mode 100644 subsys/win32k/freetype/src/type1/type1.c delete mode 100644 subsys/win32k/freetype/src/type1z/.cvsignore delete mode 100644 subsys/win32k/freetype/src/type1z/Readme.txt delete mode 100644 subsys/win32k/freetype/src/type1z/module.mk delete mode 100644 subsys/win32k/freetype/src/type1z/rules.mk delete mode 100644 subsys/win32k/freetype/src/type1z/type1z.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1afm.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1afm.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1driver.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1driver.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1gload.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1gload.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1load.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1load.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1objs.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1objs.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1parse.c delete mode 100644 subsys/win32k/freetype/src/type1z/z1parse.h delete mode 100644 subsys/win32k/freetype/src/type1z/z1tokens.h delete mode 100644 subsys/win32k/freetype/src/winfonts/.cvsignore delete mode 100644 subsys/win32k/freetype/src/winfonts/module.mk delete mode 100644 subsys/win32k/freetype/src/winfonts/rules.mk delete mode 100644 subsys/win32k/freetype/src/winfonts/winfnt.c delete mode 100644 subsys/win32k/freetype/src/winfonts/winfnt.h create mode 100644 subsys/win32k/include/inteng.h create mode 100644 subsys/win32k/ntuser/timer.c create mode 100644 subsys/win32k/objects/polyfill.c create mode 100644 tools/cdmake/.cvsignore create mode 100644 tools/cdmake/Makefile create mode 100644 tools/cdmake/cdmake.c create mode 100644 tools/cdmake/llmosrt.c create mode 100644 tools/cdmake/readme.txt create mode 100644 tools/mkflpimg.c create mode 100644 tools/mkhive/.cvsignore create mode 100644 tools/mkhive/Makefile create mode 100644 tools/mkhive/binhive.c create mode 100644 tools/mkhive/binhive.h create mode 100644 tools/mkhive/infcache.c create mode 100644 tools/mkhive/infcache.h create mode 100644 tools/mkhive/mkhive.c create mode 100644 tools/mkhive/mkhive.h create mode 100644 tools/mkhive/reginf.c create mode 100644 tools/mkhive/reginf.h create mode 100644 tools/mkhive/registry.c create mode 100644 tools/mkhive/registry.h create mode 100755 tools/rline.c delete mode 100644 txtsetup.sif diff --git a/ChangeLog b/ChangeLog index ccae3af..e337dd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,312 @@ +2003-04-28 Casper S. Hornstrup + + * Makefile (DLLS): Add epsapi, psapi and wsock32. + * lib/ntdll/ldr/utils.c (LdrPerformRelocations): Handle the case where a + relocation crosses a page boundary. + (LdrFixupImports): Use image load address in calculatation of import + address list. + +2003-04-28 Casper S. Hornstrup + + * lib/fslib/vfatlib/vfatlib.h: New file. + * subsys/system/usetup/format.c: Ditto. + * subsys/system/usetup/format.h: Ditto. + * lib/fslib/vfatlib/vfatlib.c (GetShiftCount): Define. + (VfatWriteBootSector, VfatWriteFsInfo, VfatWriteFAT, + VfatWriteRootDirectory): New function. + (VfatFormat): Implement. + * subsys/system/usetup/bootsup.c: (InstallFat32BootCodeToFile): Use + 0x0000 as marker to disable backup boot sector. + (InstallFat32BootCodeToDisk): Add lower 8-bit to BackupBootSector. + Also treat 0x0000 as no backup boot sector is available. + * subsys/system/usetup/makefile (TARGET_SDKLIBS): Define. + (TARGET_OBJECTS): Add format.o. + * subsys/system/usetup/partlist.c (AddPartitionList): Initialize + PartNumber field. + (GetSelectedPartition): Set PartEntryNumber correctly. + (CreateSelectedPartition): Write partition information to disk. + (DeleteSelectedPartition): New function. + * subsys/system/usetup/partlist.h (PARTDATA): Add field CreatePartition. + (DeleteSelectedPartition): Prototype. + * subsys/system/usetup/usetup.c (ConfirmDeletePartition): New function. + (SelectPartitionPage): Support deletion of partition. + (FormatPartitionPage): Support formatting of partition. + +2003-04-27 Casper S. Hornstrup + + * tools/helper.mk (TARGET_ASFLAGS): Add -march and define MK_ARCH_ID. + * lib/ntdll/makefile (TARGET_ASFLAGS): Define as + "-I $(PATH_TO_TOP)/include". + (TARGET_OBJECTS): Add ldr/entry.o. + * lib/ntdll/ldr/startup.c: Move inline assembly code... + * lib/ntdll/ldr/entry.S: ...here. New file. + +2003-04-27 Casper S. Hornstrup + + * include/kernel32/kernel32.h (assert): Define. + * tools/mkhive/.cvsignore: New file. + +2003-04-18 Casper S. Hornstrup + + * subsys/system/usetup/partlist.c (AddPartitionList): Create + unpartitioned areas. + (CreatePartitionListNoGUI): Save disk geometry. + (PrintDiskData): Do not print hidden partition list entries. + (ScrollDownPartitionList, ScrollUpPartitionList): Skip hidden partition + list entries. + (GetActiveBootPartition): Use CurrentDisk as index. + (CreateSelectedPartition): New function. + * subsys/system/usetup/partlist.h (PARTDATA): Add field NewPartSize. + (PARTENTRY): Add fields StartingOffset and HidePartEntry. + (DISKENTRY): Add fields Cylinders, TracksPerCylinder, SectorsPerTrack, + and BytesPerSector; + (CreateSelectedPartition): Add Prototype. + * subsys/system/usetup/usetup.c (PAGE_NUMBER): Add CREATE_PARTITION_PAGE + and FORMAT_PARTITION_PAGE + (CurrentPartitionList, CurrentFileSystemList): New globals. + (SelectPartitionPage): Set CurrentPartitionList. + (PARTITION_SIZE_INPUT_FIELD_LENGTH): Define as 6. + (DrawInputField, ShowPartitionSizeInputBox, CreatePartitionPage, + CreateFileSystemList, DestroyFileSystemList, DrawFileSystemList, + ScrollDownFileSystemList, ScrollUpFileSystemList, FormatPartitionPage): + New functions. + (SelectFileSystemPage): Draw partition screen. + (CheckFileSystemPage): Handle CREATE_PARTITION_PAGE and + FORMAT_PARTITION_PAGE. + * subsys/system/usetup/usetup.h (FILE_SYSTEM, FILE_SYSTEM_LIST): Add enums. + +2003-04-17 Casper S. Hornstrup + + * tools/mkhive/infcache.c (InfpCacheFindSection, InfpCacheFindKeyLine, + InfFindFirstLine, InfFindFirstMatchLine, InfFindNextMatchLine, + InfGetLineCount): Change call to stricmp() to strcasecmp(). + * tools/mkhive/reginf.c (GetRootKey): Ditto. + * tools/mkhive/registry.c (RegSetValue, RegQueryValue): Ditto. + +2003-04-13 Casper S. Hornstrup + + * ntoskrnl/kd/gdbstub.c (KdEnterDebuggerException): Fix signed/unsigned + comparison warning. + * ntoskrnl/ke/i386/exp.c (KiKernelTrapHandler): Ditto. + * ntoskrnl/ke/i386/usertrap.c (KiUserTrapHandler): Ditto. + * tools/helper.mk: Do not install static libraries. + +2003-04-13 Casper S. Hornstrup + + * tools/Makefile: Fix rule for mkflpimg. + +2003-04-12 Casper S. Hornstrup + + * tools/cdmake/Makefile: Use HOST_CC. + * tools/cdmake/cdmake.c (MAX_PATH, DIR_SEPARATOR_CHAR, + DIR_SEPARATOR_STRING): Define. + (directory_record): Add fields name_on_cd and extension_on_cd. + (error_exit): Make a macro. Avoid using vfprintf and fprintf. + (write_directory_record, new_directory_record, compare_directory_order, + pass): Use name_on_cd and extension_on_cd. + (make_directory_records, get_file_specifications): Use DIR_SEPARATOR_CHAR. + (new_directory_record, make_directory_records): Linux implementations. + (main): Use DIR_SEPARATOR_CHAR. + +2003-04-06 Casper S. Hornstrup + + * lib/freetype/.cvsignore: Ignore nul. + +2003-04-06 Casper S. Hornstrup + + * drivers/storage/atapi/atapi.c (AtapiReadWrite): Expect an interrupt a + bit sooner. + * hal/halx86/isa.c (HalpGetIsaInterruptVector): Compute vector for MP. + * hal/halx86/pci.c (HalpGetPciInterruptVector): Ditto. + * hal/halx86/sysbus.c (HalpGetSystemInterruptVector): Ditto. + * hal/halx86/mp.c (AssignIrqVector): Rewrite. + (MpsTimerHandler): Disable for now. + (MpsSpuriousHandler): Do not acknowledge interrupt. + (HalAllProcessorsStarted): Only boot 1 CPU for now. + (RescheduleDpcRoutine): New function. + (RescheduleDpc): New variable. + (HalpInitMPS): Initialize RescheduleDpc. Fix bug in call to memset. + * hal/halx86/mpsirql.c: Rewrite. + * hal/halx86/include/mps.h (VECTOR2IRQ, IRQ2VECTOR, VECTOR2IRQL, + IRQL2VECTOR): New macros. + * ntoskrnl/ntoskrnl.def: Add KeRescheduleThread@0. + * ntoskrnl/ntoskrnl.edf: Ditto. + * ntoskrnl/include/internal/ke.h (KeRescheduleThread): Prototype. + * ntoskrnl/ke/kthread.c (KeRescheduleThread): New function. + * ntoskrnl/ke/i386/exp.c (KeInitExceptions): Remove unneeded call to + set_trap_gate(). + * ntoskrnl/ke/i386/irq.c (VECTOR2IRQ, IRQ2VECTOR, VECTOR2IRQL): Correct. + (IRQ_BASE): Define as FIRST_DEVICE_VECTOR. + (NR_IRQS): Define using IRQ_BASE. + (KeInitInterrupts): Use IRQ_BASE. + (KiInterruptDispatch2): Rewrite. + (KiInterruptDispatch): Ditto. + (KeConnectInterrupt): Pass Vector to HalEnableSystemInterrupt() for MP. + (KeDisconnectInterrupt): Pass Vector to HalDisableSystemInterrupt() for MP. + * ntoskrnl/ke/i386/trap.s (_KiTrapProlog): Change 0x124 to KPCR_CURRENT_THREAD. + +2003-04-06 Casper S. Hornstrup + + * Makefile: Add format. + * include/fslib/vfatlib.h (VfatFormat): Prototype. + * lib/fmifs/format.c (VfatFormat): Add stub. + * lib/fmifs/makefile (TARGET_LIBS): Add vfatlib.a. + * lib/fslib/vfatlib/vfatlib.c (VfatFormat): Add stub. + * tools/helper.mk: Do not install .sym files for static libraries. + * subsys/system/format: New directory. + * subsys/system/format/makefile: New file. + * subsys/system/format/format.c: Ditto. + +2003-04-05 Casper S. Hornstrup + + * include/fslib: New directory. + * lib/fslib: Ditto. + * lib/fslib/vfatlib: Ditto. + * include/fslib/vfatlib.h: New file. + * lib/fslib/vfatlib/.cvsignore: Ditto. + * lib/fslib/vfatlib/Makefile: Ditto. + * lib/fslib/vfatlib/vfatlib.c: Ditto. + * Makefile: Support file system libraries + * lib/zlib/Makefile: Remove nostrip target. + * tools/helper.mk: Add nostrip target. + +2003-04-05 Casper S. Hornstrup + + * tools/.cvsignore: Ignore rline. + +2003-04-05 Casper S. Hornstrup + + * bootcd.bat: Install dosmbr.bin. + * drivers/storage/disk/disk.c (DiskClassDeviceControl): Pass physical + device object to IoWritePartitionTable(). + * ntoskrnl/io/xhaldrv.c (xHalReadMBR): New function. + (xHalWriteMBR): Ditto. + (xHalExamineMBR): Use xHalReadMBR() to read MBR. + (xHalIoWritePartitionTable): Partial implement. + * subsys/system/usetup/bootsup.c (InstallMBRBootCodeToDisk): New function. + * subsys/system/usetup/bootsup.h (InstallMBRBootCodeToDisk): Prototype. + * subsys/system/usetup/partlist.c (CreatePartitionListNoGUI): New function. + (CreatePartitionList): Use CreatePartitionListNoGUI() to create partition + list. + (GetPartitionInformation): New function. + (MarkPartitionActive): Ditto. + * subsys/system/usetup/partlist.h (MarkPartitionActive): Prototype. + * subsys/system/usetup/usetup.c (SelectPartitionPage): Make SystemRootPath + point to the selected partition if no partitions are active. + (BootLoaderPage): If no partitions are active, then install a DOS MBR and + mark the selected partition active. + +2003-04-05 Casper S. Hornstrup + + * Makefile: Add bootcd target. + (BOOTCD_INSTALL): Set for bootcd install. + * rules.mak (TOPDIR): Define on windows. + (BOOTCD_DIR): Define. + (RLINE): Define. + * apps/tests/lpc/makefile: Handle BOOTCD_INSTALL. + * apps/tests/mstest/Makefile: Ditto. + * apps/tests/nptest/Makefile: Ditto. + * apps/tests/shm/makefile: Ditto. + * ntoskrnl/Makefile: Handle BOOTCD_INSTALL. Add bootcd target. + * drivers/dd/vga/makefile: Add bootcd target. + * drivers/dd/blue/makefile (TARGET_BOOTSTRAP): Define as yes. + * drivers/dd/floppy/Makefile: Ditto. + * drivers/fs/cdfs/makefile: Ditto. + * drivers/fs/ntfs/makefile: Ditto. + * drivers/fs/vfat/makefile: Ditto. + * drivers/input/keyboard/makefile: Ditto. + * drivers/storage/atapi/makefile: Ditto. + * drivers/storage/cdrom/makefile: Ditto. + * drivers/storage/class2/makefile: Ditto. + * drivers/storage/disk/makefile: Ditto. + * drivers/storage/scsiport/makefile: Ditto. + * hal/halx86/Makefile: Ditto. + * lib/ntdll/makefile: Ditto. + * subsys/system/usetup/makefile (TARGET_BOOTSTRAP): Define as yes. + (TARGET_BOOTSTRAP_NAME): Define as smss.exe. + * tools/Makefile: Add rline executable. + * tools/helper.mk: Support bootcd targets. + * tools/rline.c: New file. + +2003-04-04 Casper S. Hornstrup + + * lib/freetype/builds/compiler/gcc.mk (CC): Comment out; use CC from + rules.mak instead. + * lib/freetype/README.ROS: Note this in porting guide. + +2003-03-29 Casper S. Hornstrup + + * ntoskrnl/ex/sysinfo.c (SystemProcessInformation): Fix warning. + +2003-03-16 Casper S. Hornstrup + + * include/ntos/rtltypes.h (PRTL_BASE_PROCESS_START_ROUTINE): Define. + * lib/kernel32/process/create.c (RtlBaseProcessStartRoutine): Import. + (KlCreateFirstThread): Support images with native subsystem ID. + * lib/ntdll/def/ntdll.def (RtlBaseProcessStartRoutine): Export. + * lib/ntdll/def/ntdll.edf (RtlBaseProcessStartRoutine): Ditto. + * lib/ntdll/rtl/exception.c (RtlBaseProcessStart): Forward declare. + (RtlBaseProcessStartRoutine, RtlBaseProcessStart): Add. + +2003-03-16 Casper S. Hornstrup + + * include/defines.h (VS_FFI_SIGNATURE, VS_FFI_STRUCVERSION): Define. + +2003-03-16 Casper S. Hornstrup + + * ntoskrnl/ke/i386/exp.c (KiKernelTrapHandler): Use exception code + STATUS_ACCESS_VIOLATION for exception 14. + +2003-03-16 Casper S. Hornstrup + + * ntoskrnl/fs/util.c (FsRtlGetFileSize): Implement. + +2003-03-16 Casper S. Hornstrup + + * lib/ntdll/rtl/nls.c (RtlCustomCPToUnicodeN, RtlMultiByteToUnicodeN, + RtlOemToUnicodeN, RtlUnicodeToCustomCPN, RtlUnicodeToMultiByteN, + RtlUnicodeToMultiByteSize, RtlUnicodeToOemN, + RtlUpcaseUnicodeToCustomCPN, RtlUpcaseUnicodeToMultiByteN, + RtlUpcaseUnicodeToOemN): Assert when unimplemented code is reached. + +2003-03-16 Casper S. Hornstrup + + * include/ntos/zwtypes.h (FILE_BASIC_INFORMATION): Use LARGE_INTEGER, + not TIME type for time fields. + * lib/kernel32/file/copy.c (SetLastWriteTime): Adjust for new type. + (CopyFileExW): Ditto. + +2003-03-16 Casper S. Hornstrup + + * include/ntos/types.h (FALSE): Protect with #ifndef FALSE. + (TRUE): Protect with #ifndef TRUE. + +2003-03-16 Casper S. Hornstrup + + * include/napi/i386/segment.h (put_user, get_user, + bad_user_access_length, __segment_dummy, __sd, __const_sd, __put_user, + __get_user, __generic_memcpy_tofs, __constant_memcpy_tofs, COMMON, + __generic_memcpy_fromfs, __constant_memcpy_fromfs, memcpy_fromfs, + memcpy_tofs, get_fs_byte, get_fs_word, get_fs_long, put_fs_byte, + put_fs_word, put_fs_long, get_user_word, get_user_byte, get_user_long, + put_user_byte, put_user_word, put_user_long, get_fs, get_ds, set_fs, + set_ds): Remove. + +2003-03-16 Casper S. Hornstrup + + * include/ddk/pstypes.h (TLS_OUT_OF_INDEXES): Define. + +2003-02-18 Casper S. Hornstrup + + * ntoskrnl/cc/view.c (CcRosFlushDirtyPages): Treat a write attempt with + a return value of STATUS_END_OF_FILE as a successful write. + * ntoskrnl/cc/copy.c (WriteCacheSegment): Ditto. + +2003-02-18 Casper S. Hornstrup + + * ntoskrnl/cm/regfile.c (CmiRemoveSubKey): Kill warnings. + (CmiMergeFree): Ditto. + 2003-02-10 Casper S. Hornstrup * include/structs.h (OSVERSIONINFOEXA): Expand definition of diff --git a/INSTALL b/INSTALL index 81997a6..0446537 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,8 @@ 1. Build environment To build the system you need either mingw32 installed on Windows or a mingw32 -cross compiler running on unix. +cross compiler running on unix. You may obtain MinGW binaries that build +ReactOS from http://www.reactos.com. 2. Building ReactOS diff --git a/Makefile b/Makefile index 45bdfe1..6a34442 100644 --- a/Makefile +++ b/Makefile @@ -26,11 +26,16 @@ HALS = halx86 # acpi isapnp pci BUS = acpi isapnp pci -# User mode libraries +# Filesystem libraries +# vfatlib +LIB_FSLIB = vfatlib + +# User and kernel mode libraries # advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32 -# oleaut32 psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda -DLLS = advapi32 crtdll fmifs gdi32 kernel32 packet msafd msvcrt ntdll \ - secur32 user32 version winedbgc ws2help ws2_32 wshirda #winmm +# oleaut32 epsapi psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda +DLLS = rosrtl advapi32 crtdll fmifs freetype gdi32 kernel32 packet msafd msvcrt ntdll \ + epsapi psapi secur32 user32 version winedbgc winspool ws2help ws2_32 wsock32 \ + wshirda zlib #winmm SUBSYS = smss win32k csrss ntvdm @@ -46,12 +51,12 @@ LOADERS = dos # Driver support libraries #bzip2 zlib -DRIVERS_LIB = bzip2 zlib +DRIVERS_LIB = bzip2 # Kernel mode device drivers # Obsolete: ide -# beep blue floppy null parallel ramdrv serenum serial vga vidport -DEVICE_DRIVERS = beep blue floppy null serial vga vidport +# beep blue floppy null parallel ramdrv serenum serial vga videoprt +DEVICE_DRIVERS = beep blue floppy null serial vga videoprt # Kernel mode input drivers # keyboard mouclass psaux sermouse @@ -74,8 +79,8 @@ NET_DEVICE_DRIVERS = ne2000 STORAGE_DRIVERS = atapi cdrom class2 disk scsiport # System applications -# autochk lsass services shell winlogon -SYS_APPS = autochk services shell winlogon gstart usetup +# autochk cmd services format gstart usetup winlogon +SYS_APPS = autochk cmd services format gstart usetup winlogon # System services # rpcss eventlog @@ -97,23 +102,23 @@ endif KERNEL_DRIVERS = $(DRIVERS_LIB) $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) \ $(NET_DRIVERS) $(NET_DEVICE_DRIVERS) $(STORAGE_DRIVERS) -all: tools dk implib $(COMPONENTS) $(HALS) $(BUS) $(DLLS) $(SUBSYS) \ +all: tools dk implib $(COMPONENTS) $(HALS) $(BUS) $(LIB_FSLIB) $(DLLS) $(SUBSYS) \ $(LOADERS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) \ $(APPS) $(EXT_MODULES) #config: $(TOOLS:%=%_config) -depends: $(DLLS:%=%_depends) $(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \ +depends: $(LIB_FSLIB:%=%_depends) $(DLLS:%=%_depends) $(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \ $(EXT_MODULES:%=%_depends) $(POSIX_LIBS:%=%_depends) implib: $(COMPONENTS:%=%_implib) $(HALS:%=%_implib) $(BUS:%=%_implib) \ - $(DLLS:%=%_implib) $(LOADERS:%=%_implib) \ + $(LIB_FSLIB:%=%_implib) $(DLLS:%=%_implib) $(LOADERS:%=%_implib) \ $(KERNEL_DRIVERS:%=%_implib) $(SUBSYS:%=%_implib) \ $(SYS_APPS:%=%_implib) $(SYS_SVC:%=%_implib) \ $(APPS:%=%_implib) $(EXT_MODULES:%=%_implib) clean: tools dk_clean $(HALS:%=%_clean) \ - $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \ + $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(LIB_FSLIB:%=%_clean) $(DLLS:%=%_clean) \ $(LOADERS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) $(SUBSYS:%=%_clean) \ $(SYS_APPS:%=%_clean) $(SYS_SVC:%=%_clean) \ $(NET_APPS:%=%_clean) \ @@ -125,61 +130,80 @@ clean_after: install: tools install_dirs install_before \ $(COMPONENTS:%=%_install) $(HALS:%=%_install) $(BUS:%=%_install) \ - $(DLLS:%=%_install) $(LOADERS:%=%_install) \ + $(LIB_FSLIB:%=%_install) $(DLLS:%=%_install) $(LOADERS:%=%_install) \ $(KERNEL_DRIVERS:%=%_install) $(SUBSYS:%=%_install) \ $(SYS_APPS:%=%_install) $(SYS_SVC:%=%_install) \ $(APPS:%=%_install) $(EXT_MODULES:%=%_install) dist: $(TOOLS_PATH)/rcopy$(EXE_POSTFIX) dist_clean dist_dirs \ - $(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(DLLS:%=%_dist) \ - $(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \ + $(HALS:%=%_dist) $(COMPONENTS:%=%_dist) $(BUS:%=%_dist) $(LIB_FSLIB:%=%_dist) \ + $(DLLS:%=%_dist) $(LOADERS:%=%_dist) $(KERNEL_DRIVERS:%=%_dist) $(SUBSYS:%=%_dist) \ $(SYS_APPS:%=%_dist) $(SYS_SVC:%=%_dist) \ $(NET_APPS:%=%_dist) \ $(APPS:%=%_dist) $(EXT_MODULES:%=%_dist) -.PHONY: all depends implib clean clean_before install dist +bootcd_directory_layout: + $(RMKDIR) $(BOOTCD_DIR) + $(RMKDIR) $(BOOTCD_DIR)/bootdisk + $(RMKDIR) $(BOOTCD_DIR)/install + $(RMKDIR) $(BOOTCD_DIR)/reactos + $(RMKDIR) $(BOOTCD_DIR)/reactos/system32 + $(RMKDIR) $(BOOTCD_DIR)/loader + +bootcd_bootstrap_files: $(COMPONENTS:%=%_bootcd) $(HALS:%=%_bootcd) $(BUS:%=%_bootcd) \ + $(LIB_FSLIB:%=%_bootcd) $(DLLS:%=%_bootcd) $(KERNEL_DRIVERS:%=%_bootcd) \ + $(SUBSYS:%=%_bootcd) $(SYS_APPS:%=%_bootcd) + +bootcd: all bootcd_directory_layout bootcd_bootstrap_files + $(MAKE) install INSTALL_DIR=$(BOOTCD_DIR)/install INSTALL_SYMBOLS=no BOOTCD_INSTALL=yes + +.PHONY: all depends implib clean clean_before install dist bootcd_directory_layout \ +bootcd_bootstrap_files bootcd # # System Applications # $(SYS_APPS): %: - make -C subsys/system/$* + $(MAKE) -C subsys/system/$* $(SYS_APPS:%=%_implib): %_implib: - make -C subsys/system/$* implib + $(MAKE) -C subsys/system/$* implib $(SYS_APPS:%=%_clean): %_clean: - make -C subsys/system/$* clean + $(MAKE) -C subsys/system/$* clean $(SYS_APPS:%=%_dist): %_dist: - make -C subsys/system/$* dist + $(MAKE) -C subsys/system/$* dist $(SYS_APPS:%=%_install): %_install: - make -C subsys/system/$* install + $(MAKE) -C subsys/system/$* install + +$(SYS_APPS:%=%_bootcd): %_bootcd: + $(MAKE) -C subsys/system/$* bootcd -.PHONY: $(SYS_APPS) $(SYS_APPS:%=%_implib) $(SYS_APPS:%=%_clean) $(SYS_APPS:%=%_install) $(SYS_APPS:%=%_dist) +.PHONY: $(SYS_APPS) $(SYS_APPS:%=%_implib) $(SYS_APPS:%=%_clean) $(SYS_APPS:%=%_install) $(SYS_APPS:%=%_dist) $(SYS_APPS:%=%_bootcd) # # System Services # $(SYS_SVC): %: - make -C services/$* + $(MAKE) -C services/$* $(SYS_SVC:%=%_depends): %_depends: - make -C services/$* depends + $(MAKE) -C services/$* depends $(SYS_SVC:%=%_implib): %_implib: - make -C services/$* implib + $(MAKE) -C services/$* implib $(SYS_SVC:%=%_clean): %_clean: - make -C services/$* clean + $(MAKE) -C services/$* clean $(SYS_SVC:%=%_dist): %_dist: - make -C services/$* dist + $(MAKE) -C services/$* dist $(SYS_SVC:%=%_install): %_install: - make -C services/$* install + $(MAKE) -C services/$* install .PHONY: $(SYS_SVC) $(SYS_SVC:%=%_depends) $(SYS_SVC:%=%_implib) $(SYS_SVC:%=%_clean) $(SYS_SVC:%=%_install) $(SYS_SVC:%=%_dist) @@ -191,19 +215,19 @@ $(SYS_SVC:%=%_install): %_install: # Extra (optional system) Applications # $(APPS): %: - make -C apps/$* + $(MAKE) -C apps/$* $(APPS:%=%_implib): %_implib: - make -C apps/$* implib + $(MAKE) -C apps/$* implib $(APPS:%=%_clean): %_clean: - make -C apps/$* clean + $(MAKE) -C apps/$* clean $(APPS:%=%_dist): %_dist: - make -C apps/$* dist + $(MAKE) -C apps/$* dist $(APPS:%=%_install): %_install: - make -C apps/$* install + $(MAKE) -C apps/$* install .PHONY: $(APPS) $(APPS:%=%_implib) $(APPS:%=%_clean) $(APPS:%=%_install) $(APPS:%=%_dist) @@ -212,22 +236,22 @@ $(APPS:%=%_install): %_install: # External ports and subsystem personalities # $(EXTERNALS): %: - make -C $(ROOT_PATH)/$* + $(MAKE) -C $(ROOT_PATH)/$* $(EXTERNALS:%=%_depends): %_depends: - make -C $(ROOT_PATH)/$* depends + $(MAKE) -C $(ROOT_PATH)/$* depends $(EXTERNALS:%=%_implib): %_implib: - make -C $(ROOT_PATH)/$* implib + $(MAKE) -C $(ROOT_PATH)/$* implib $(EXTERNALS:%=%_clean): %_clean: - make -C $(ROOT_PATH)/$* clean + $(MAKE) -C $(ROOT_PATH)/$* clean $(EXTERNALS:%=%_dist): %_dist: - make -C $(ROOT_PATH)/$* dist + $(MAKE) -C $(ROOT_PATH)/$* dist $(EXTERNALS:%=%_install): %_install: - make -C $(ROOT_PATH)/$* install + $(MAKE) -C $(ROOT_PATH)/$* install .PHONY: $(EXTERNALS) $(EXTERNALS:%=%_depends) $(EXTERNALS:%=%_implib) $(EXTERNALS:%=%_clean) $(EXTERNALS:%=%_install) $(EXTERNALS:%=%_dist) @@ -236,12 +260,12 @@ $(EXTERNALS:%=%_install): %_install: # Tools # tools: - make -C tools + $(MAKE) -C tools tools_implib: tools_clean: - make -C tools clean + $(MAKE) -C tools clean tools_install: @@ -294,213 +318,241 @@ dk_dist: # Interfaces # iface_native: - make -C iface/native + $(MAKE) -C iface/native iface_native_implib: iface_native_clean: - make -C iface/native clean + $(MAKE) -C iface/native clean iface_native_install: iface_native_dist: +iface_native_bootcd: + iface_additional: - make -C iface/addsys + $(MAKE) -C iface/addsys iface_additional_implib: iface_additional_clean: - make -C iface/addsys clean + $(MAKE) -C iface/addsys clean iface_additional_install: iface_additional_dist: +iface_additional_bootcd: + .PHONY: iface_native iface_native_implib iface_native_clean iface_native_install \ - iface_native_dist \ + iface_native_dist iface_native_bootcd \ iface_additional iface_additional_implib iface_additional_clean \ - iface_additional_install iface_additional_dist + iface_additional_install iface_additional_dist iface_additional_bootcd # # Bus driver rules # $(BUS): %: - make -C drivers/bus/$* + $(MAKE) -C drivers/bus/$* $(BUS:%=%_implib): %_implib: - make -C drivers/bus/$* implib + $(MAKE) -C drivers/bus/$* implib $(BUS:%=%_clean): %_clean: - make -C drivers/bus/$* clean + $(MAKE) -C drivers/bus/$* clean $(BUS:%=%_install): %_install: - make -C drivers/bus/$* install + $(MAKE) -C drivers/bus/$* install $(BUS:%=%_dist): %_dist: - make -C drivers/bus/$* dist + $(MAKE) -C drivers/bus/$* dist + +$(BUS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/bus/$* bootcd .PHONY: $(BUS) $(BUS:%=%_implib) $(BUS:%=%_clean) \ - $(BUS:%=%_install) $(BUS:%=%_dist) + $(BUS:%=%_install) $(BUS:%=%_dist) $(BUS:%=%_bootcd) # # Driver support libraries rules # $(DRIVERS_LIB): %: - make -C drivers/lib/$* + $(MAKE) -C drivers/lib/$* $(DRIVERS_LIB:%=%_implib): %_implib: - make -C drivers/lib/$* implib + $(MAKE) -C drivers/lib/$* implib $(DRIVERS_LIB:%=%_clean): %_clean: - make -C drivers/lib/$* clean + $(MAKE) -C drivers/lib/$* clean $(DRIVERS_LIB:%=%_install): %_install: - make -C drivers/lib/$* install + $(MAKE) -C drivers/lib/$* install $(DRIVERS_LIB:%=%_dist): %_dist: - make -C drivers/lib/$* dist + $(MAKE) -C drivers/lib/$* dist + +$(DRIVERS_LIB:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/lib/$* bootcd .PHONY: $(DRIVERS_LIB) $(DRIVERS_LIB:%=%_implib) $(DRIVERS_LIB:%=%_clean) \ - $(DRIVERS_LIB:%=%_install) $(DRIVERS_LIB:%=%_dist) + $(DRIVERS_LIB:%=%_install) $(DRIVERS_LIB:%=%_dist) $(DRIVERS_LIB:%=%_bootcd) # # Device driver rules # $(DEVICE_DRIVERS): %: - make -C drivers/dd/$* + $(MAKE) -C drivers/dd/$* $(DEVICE_DRIVERS:%=%_implib): %_implib: - make -C drivers/dd/$* implib + $(MAKE) -C drivers/dd/$* implib $(DEVICE_DRIVERS:%=%_clean): %_clean: - make -C drivers/dd/$* clean + $(MAKE) -C drivers/dd/$* clean $(DEVICE_DRIVERS:%=%_install): %_install: - make -C drivers/dd/$* install + $(MAKE) -C drivers/dd/$* install $(DEVICE_DRIVERS:%=%_dist): %_dist: - make -C drivers/dd/$* dist + $(MAKE) -C drivers/dd/$* dist + +$(DEVICE_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/dd/$* bootcd .PHONY: $(DEVICE_DRIVERS) $(DEVICE_DRIVERS:%=%_implib) $(DEVICE_DRIVERS:%=%_clean) \ - $(DEVICE_DRIVERS:%=%_install) $(DEVICE_DRIVERS:%=%_dist) + $(DEVICE_DRIVERS:%=%_install) $(DEVICE_DRIVERS:%=%_dist) $(DEVICE_DRIVERS:%=%_bootcd) # # Input driver rules # $(INPUT_DRIVERS): %: - make -C drivers/input/$* + $(MAKE) -C drivers/input/$* $(INPUT_DRIVERS:%=%_implib): %_implib: - make -C drivers/input/$* implib + $(MAKE) -C drivers/input/$* implib $(INPUT_DRIVERS:%=%_clean): %_clean: - make -C drivers/input/$* clean + $(MAKE) -C drivers/input/$* clean $(INPUT_DRIVERS:%=%_install): %_install: - make -C drivers/input/$* install + $(MAKE) -C drivers/input/$* install $(INPUT_DRIVERS:%=%_dist): %_dist: - make -C drivers/input/$* dist + $(MAKE) -C drivers/input/$* dist + +$(INPUT_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/input/$* bootcd .PHONY: $(INPUT_DRIVERS) $(INPUT_DRIVERS:%=%_implib) $(INPUT_DRIVERS:%=%_clean)\ - $(INPUT_DRIVERS:%=%_install) $(INPUT_DRIVERS:%=%_dist) + $(INPUT_DRIVERS:%=%_install) $(INPUT_DRIVERS:%=%_dist) $(INPUT_DRIVERS:%=%_bootcd) $(FS_DRIVERS): %: - make -C drivers/fs/$* + $(MAKE) -C drivers/fs/$* $(FS_DRIVERS:%=%_implib): %_implib: - make -C drivers/fs/$* implib + $(MAKE) -C drivers/fs/$* implib $(FS_DRIVERS:%=%_clean): %_clean: - make -C drivers/fs/$* clean + $(MAKE) -C drivers/fs/$* clean $(FS_DRIVERS:%=%_install): %_install: - make -C drivers/fs/$* install + $(MAKE) -C drivers/fs/$* install $(FS_DRIVERS:%=%_dist): %_dist: - make -C drivers/fs/$* dist + $(MAKE) -C drivers/fs/$* dist + +$(FS_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/fs/$* bootcd .PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_implib) $(FS_DRIVERS:%=%_clean) \ - $(FS_DRIVERS:%=%_install) $(FS_DRIVERS:%=%_dist) + $(FS_DRIVERS:%=%_install) $(FS_DRIVERS:%=%_dist) $(FS_DRIVERS:%=%_bootcd) # # Network driver rules # $(NET_DRIVERS): %: - make -C drivers/net/$* + $(MAKE) -C drivers/net/$* $(NET_DRIVERS:%=%_implib): %_implib: - make -C drivers/net/$* implib + $(MAKE) -C drivers/net/$* implib $(NET_DRIVERS:%=%_clean): %_clean: - make -C drivers/net/$* clean + $(MAKE) -C drivers/net/$* clean $(NET_DRIVERS:%=%_install): %_install: - make -C drivers/net/$* install + $(MAKE) -C drivers/net/$* install $(NET_DRIVERS:%=%_dist): %_dist: - make -C drivers/net/$* dist + $(MAKE) -C drivers/net/$* dist + +$(NET_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/net/$* bootcd .PHONY: $(NET_DRIVERS) $(NET_DRIVERS:%=%_implib) $(NET_DRIVERS:%=%_clean) \ - $(NET_DRIVERS:%=%_install) $(NET_DRIVERS:%=%_dist) + $(NET_DRIVERS:%=%_install) $(NET_DRIVERS:%=%_dist) $(NET_DRIVERS:%=%_bootcd) $(NET_DEVICE_DRIVERS): %: - make -C drivers/net/dd/$* + $(MAKE) -C drivers/net/dd/$* $(NET_DEVICE_DRIVERS:%=%_implib): %_implib: - make -C drivers/net/dd/$* implib + $(MAKE) -C drivers/net/dd/$* implib $(NET_DEVICE_DRIVERS:%=%_clean): %_clean: - make -C drivers/net/dd/$* clean + $(MAKE) -C drivers/net/dd/$* clean $(NET_DEVICE_DRIVERS:%=%_install): %_install: - make -C drivers/net/dd/$* install + $(MAKE) -C drivers/net/dd/$* install $(NET_DEVICE_DRIVERS:%=%_dist): %_dist: - make -C drivers/net/dd/$* dist + $(MAKE) -C drivers/net/dd/$* dist + +$(NET_DEVICE_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/net/dd/$* bootcd .PHONY: $(NET_DEVICE_DRIVERS) $(NET_DEVICE_DRIVERS:%=%_clean) $(NET_DEVICE_DRIVERS:%=%_implib) \ - $(NET_DEVICE_DRIVERS:%=%_install) $(NET_DEVICE_DRIVERS:%=%_dist) + $(NET_DEVICE_DRIVERS:%=%_install) $(NET_DEVICE_DRIVERS:%=%_dist) $(NET_DEVICE_DRIVERS:%=%_bootcd) # # storage driver rules # $(STORAGE_DRIVERS): %: - make -C drivers/storage/$* + $(MAKE) -C drivers/storage/$* $(STORAGE_DRIVERS:%=%_implib): %_implib: - make -C drivers/storage/$* implib + $(MAKE) -C drivers/storage/$* implib $(STORAGE_DRIVERS:%=%_clean): %_clean: - make -C drivers/storage/$* clean + $(MAKE) -C drivers/storage/$* clean $(STORAGE_DRIVERS:%=%_install): %_install: - make -C drivers/storage/$* install + $(MAKE) -C drivers/storage/$* install $(STORAGE_DRIVERS:%=%_dist): %_dist: - make -C drivers/storage/$* dist + $(MAKE) -C drivers/storage/$* dist + +$(STORAGE_DRIVERS:%=%_bootcd): %_bootcd: + $(MAKE) -C drivers/storage/$* bootcd -.PHONY: $(STORAGE_DRIVERS) $(STORAGE_DRIVERS:%=%_clean) \ - $(STORAGE_DRIVERS:%=%_install) $(STORAGE_DRIVERS:%=%_dist) +.PHONY: $(STORAGE_DRIVERS) $(STORAGE_DRIVERS:%=%_clean) $(STORAGE_DRIVERS:%=%_implib) \ + $(STORAGE_DRIVERS:%=%_install) $(STORAGE_DRIVERS:%=%_dist) $(STORAGE_DRIVERS:%=%_bootcd) # # Kernel loaders # $(LOADERS): %: - make -C loaders/$* + $(MAKE) -C loaders/$* $(LOADERS:%=%_implib): %_implib: $(LOADERS:%=%_clean): %_clean: - make -C loaders/$* clean + $(MAKE) -C loaders/$* clean $(LOADERS:%=%_install): %_install: - make -C loaders/$* install + $(MAKE) -C loaders/$* install $(LOADERS:%=%_dist): %_dist: - make -C loaders/$* dist + $(MAKE) -C loaders/$* dist .PHONY: $(LOADERS) $(LOADERS:%=%_implib) $(LOADERS:%=%_clean) $(LOADERS:%=%_install) \ $(LOADERS:%=%_dist) @@ -510,112 +562,155 @@ $(LOADERS:%=%_dist): %_dist: # ntoskrnl: - make -C ntoskrnl + $(MAKE) -C ntoskrnl ntoskrnl_implib: - make -C ntoskrnl implib + $(MAKE) -C ntoskrnl implib ntoskrnl_clean: - make -C ntoskrnl clean + $(MAKE) -C ntoskrnl clean ntoskrnl_install: - make -C ntoskrnl install + $(MAKE) -C ntoskrnl install ntoskrnl_dist: - make -C ntoskrnl dist + $(MAKE) -C ntoskrnl dist -.PHONY: ntoskrnl ntoskrnl_implib ntoskrnl_clean ntoskrnl_install ntoskrnl_dist +ntoskrnl_bootcd: + $(MAKE) -C ntoskrnl bootcd + +.PHONY: ntoskrnl ntoskrnl_implib ntoskrnl_clean ntoskrnl_install ntoskrnl_dist ntoskrnl_bootcd # # Hardware Abstraction Layer import library # hallib: - make -C hal/hal + $(MAKE) -C hal/hal hallib_implib: - make -C hal/hal implib + $(MAKE) -C hal/hal implib hallib_clean: - make -C hal/hal clean + $(MAKE) -C hal/hal clean hallib_install: - make -C hal/hal install + $(MAKE) -C hal/hal install hallib_dist: - make -C hal/hal dist + $(MAKE) -C hal/hal dist + +hallib_bootcd: + $(MAKE) -C hal/hal bootcd -.PHONY: hallib hallib_implib hallib_clean hallib_install hallib_dist +.PHONY: hallib hallib_implib hallib_clean hallib_install hallib_dist hallib_bootcd # # Hardware Abstraction Layers # $(HALS): %: - make -C hal/$* + $(MAKE) -C hal/$* $(HALS:%=%_implib): %_implib: - make -C hal/$* implib + $(MAKE) -C hal/$* implib $(HALS:%=%_clean): %_clean: - make -C hal/$* clean + $(MAKE) -C hal/$* clean $(HALS:%=%_install): %_install: - make -C hal/$* install + $(MAKE) -C hal/$* install $(HALS:%=%_dist): %_dist: - make -C hal/$* dist + $(MAKE) -C hal/$* dist + +$(HALS:%=%_bootcd): %_bootcd: + $(MAKE) -C hal/$* bootcd + +.PHONY: $(HALS) $(HALS:%=%_implib) $(HALS:%=%_clean) $(HALS:%=%_install) $(HALS:%=%_dist) $(HALS:%=%_bootcd) -.PHONY: $(HALS) $(HALS:%=%_implib) $(HALS:%=%_clean) $(HALS:%=%_install) $(HALS:%=%_dist) +# +# File system libraries +# + +$(LIB_FSLIB): %: + $(MAKE) -C lib/fslib/$* + +$(LIB_FSLIB:%=%_depends): %_depends: + $(MAKE) -C lib/fslib/$* depends + +$(LIB_FSLIB:%=%_implib): %_implib: + $(MAKE) -C lib/fslib/$* implib + +$(LIB_FSLIB:%=%_clean): %_clean: + $(MAKE) -C lib/fslib/$* clean + +$(LIB_FSLIB:%=%_install): %_install: + $(MAKE) -C lib/fslib/$* install + +$(LIB_FSLIB:%=%_dist): %_dist: + $(MAKE) -C lib/fslib/$* dist + +$(LIB_FSLIB:%=%_bootcd): %_bootcd: + $(MAKE) -C lib/fslib/$* bootcd + +.PHONY: $(LIB_FSLIB) $(LIB_FSLIB:%=%_depends) $(LIB_FSLIB:%=%_implib) $(LIB_FSLIB:%=%_clean) \ +$(LIB_FSLIB:%=%_install) $(LIB_FSLIB:%=%_dist) $(LIB_FSLIB:%=%_bootcd) # # Required DLLs # $(DLLS): %: - make -C lib/$* + $(MAKE) -C lib/$* $(DLLS:%=%_depends): %_depends: - make -C lib/$* depends + $(MAKE) -C lib/$* depends $(DLLS:%=%_implib): %_implib: - make -C lib/$* implib + $(MAKE) -C lib/$* implib $(DLLS:%=%_clean): %_clean: - make -C lib/$* clean + $(MAKE) -C lib/$* clean $(DLLS:%=%_install): %_install: - make -C lib/$* install + $(MAKE) -C lib/$* install $(DLLS:%=%_dist): %_dist: - make -C lib/$* dist + $(MAKE) -C lib/$* dist -.PHONY: $(DLLS) $(DLLS:%=%_depends) $(DLLS:%=%_implib) $(DLLS:%=%_clean) $(DLLS:%=%_install) $(DLLS:%=%_dist) +$(DLLS:%=%_bootcd): %_bootcd: + $(MAKE) -C lib/$* bootcd + +.PHONY: $(DLLS) $(DLLS:%=%_depends) $(DLLS:%=%_implib) $(DLLS:%=%_clean) $(DLLS:%=%_install) $(DLLS:%=%_dist) $(DLLS:%=%_bootcd) # # Subsystem support modules # $(SUBSYS): %: - make -C subsys/$* + $(MAKE) -C subsys/$* $(SUBSYS:%=%_depends): %_depends: - make -C subsys/$* depends + $(MAKE) -C subsys/$* depends $(SUBSYS:%=%_implib): %_implib: - make -C subsys/$* implib + $(MAKE) -C subsys/$* implib $(SUBSYS:%=%_clean): %_clean: - make -C subsys/$* clean + $(MAKE) -C subsys/$* clean $(SUBSYS:%=%_install): %_install: - make -C subsys/$* install + $(MAKE) -C subsys/$* install $(SUBSYS:%=%_dist): %_dist: - make -C subsys/$* dist + $(MAKE) -C subsys/$* dist + +$(SUBSYS:%=%_bootcd): %_bootcd: + $(MAKE) -C subsys/$* bootcd .PHONY: $(SUBSYS) $(SUBSYS:%=%_depends) $(SUBSYS:%=%_implib) $(SUBSYS:%=%_clean) $(SUBSYS:%=%_install) \ - $(SUBSYS:%=%_dist) + $(SUBSYS:%=%_dist) $(SUBSYS:%=%_bootcd) # # Create an installation @@ -640,6 +735,25 @@ install_clean: $(RMDIR) $(INSTALL_DIR)/bin $(RMDIR) $(INSTALL_DIR) +ifneq ($(BOOTCD_INSTALL),) + +install_dirs: + $(RMKDIR) $(INSTALL_DIR) + +install_before: + #$(CP) bootdata/autorun.inf $(INSTALL_DIR)/../autorun.inf + $(CP) bootdata/readme.txt $(INSTALL_DIR)/../readme.txt + $(RLINE) bootdata/hivecls.inf $(INSTALL_DIR)/hivecls.inf + $(RLINE) bootdata/hivedef.inf $(INSTALL_DIR)/hivedef.inf + $(RLINE) bootdata/hivesft.inf $(INSTALL_DIR)/hivesft.inf + $(RLINE) bootdata/hivesys.inf $(INSTALL_DIR)/hivesys.inf + $(RLINE) bootdata/txtsetup.sif $(INSTALL_DIR)/txtsetup.sif + $(CP) system.hiv $(INSTALL_DIR)/system.hiv + $(CP) media/fonts/helb____.ttf $(INSTALL_DIR)/helb____.ttf + $(CP) media/fonts/timr____.ttf $(INSTALL_DIR)/timr____.ttf + +else # BOOTCD_INSTALL + install_dirs: $(RMKDIR) $(INSTALL_DIR) $(RMKDIR) $(INSTALL_DIR)/bin @@ -658,6 +772,8 @@ install_before: $(CP) media/fonts/helb____.ttf $(INSTALL_DIR)/media/fonts/helb____.ttf $(CP) media/fonts/timr____.ttf $(INSTALL_DIR)/media/fonts/timr____.ttf +endif # BOOTCD_INSTALL + .PHONY: install_clean install_dirs install_before diff --git a/NEWS b/NEWS deleted file mode 100644 index 65a0f1e..0000000 --- a/NEWS +++ /dev/null @@ -1,15 +0,0 @@ -0.0.14: Converted to PE format - All system libraries are now dlls - -0.0.13: Mostly bugfixes (I think) - -0.0.12: Added support for multiple processes (not really tested) - System calls - kernel32 now compiles (only as a static library) - Fixed invalid tss bug (hopefully) - Added section support - Added some of the ZwxxxVirtual calls - Added prototype caching functions (only the Minix fsd actually - uses them) - Added handle access and type checking - Prototype APC implementation (no support for user APCs) diff --git a/README b/README index c07458c..ac71c27 100644 --- a/README +++ b/README @@ -1,13 +1,21 @@ -About Reactos +======================== +ReactOS Version 0.1.x +Updated March 19th, 2003 +======================== -1. What is Reactos +1. What is ReactOS? -A project aiming to make an approximate clone of Windows NT, compatible -with most Windows applications. + ReactOS is an Open Source effort to develop a quality operating system +that is compatible with Windows NT applications and drivers. -The project has a website at http://www.reactos.com/ + The ReactOS project, although currently focused on Windows NT 4.0 +compatibility, is always keeping an eye towards compatibility with +future Windows NT releases, that is, Windows 2000 (NT 5.0) and +Windows XP (NT 5.1). -2. Building Reactos +More information is available at http://www.reactos.com. + +2. Building ReactOS See the INSTALL file for more details. @@ -17,8 +25,4 @@ See the doc subdirectory for some sparse notes 4. Who is responsible -See the CREDITS file - -5. Recent developments - -See the NEWS file +See the CREDITS file \ No newline at end of file diff --git a/apps/tests/Makefile b/apps/tests/Makefile index f65539f..0c9a699 100644 --- a/apps/tests/Makefile +++ b/apps/tests/Makefile @@ -8,13 +8,14 @@ include $(PATH_TO_TOP)/rules.mak # Test applications -# alive apc args atomtest bench consume copymove count dump_shared_data -# event file gditest hello isotest lpc mstest mutex nptest -# pteb regtest sectest shm simple thread vmtest winhello -TEST_APPS = alive apc args atomtest bench consume copymove count dump_shared_data \ - event file gditest hello isotest lpc mstest mutex nptest \ - pteb regtest sectest shm simple thread tokentest vmtest winhello dibtest \ - lock hivetest +# alive apc args atomtest bench bitblt consume copymove count dump_shared_data +# event file gditest hello isotest lpc messagebox mstest mutex nptest +# patblt pteb regtest sectest shm thread vmtest winhello shaptest +TEST_APPS = alive apc args atomtest bench consume copymove count \ + dump_shared_data event file gditest hello isotest lpc messagebox \ + mstest mutex event file gditest hello isotest lpc messagebox mstest \ + mutex nptest pteb regtest sectest shm thread tokentest vmtest \ + winhello dibtest lock hivetest shaptest TEST_MISC = diff --git a/apps/tests/bitblt/bitblt.c b/apps/tests/bitblt/bitblt.c new file mode 100644 index 0000000..d8d2424 --- /dev/null +++ b/apps/tests/bitblt/bitblt.c @@ -0,0 +1,137 @@ + +/* + * Windows 2000 Graphics API Black Book + * (BitBlt Bitmap Rendering Demo) + * + * Created by Damon Chandler + * Updates can be downloaded at: + * + * Please do not hesistate to e-mail me at dmc27@ee.cornell.edu + * if you have any questions about this code. + */ + + +#include + +HINSTANCE HInst; +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, + LPTSTR lpCmdLine, int nCmdShow) +{ + HInst = HInstance; + + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = HInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + /* wc.hbrBackground = reinterpret_cast(COLOR_BTNFACE + 1); */ + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszClassName = WndClassName; + + if (RegisterClass(&wc)) + { + HWND HWnd = + CreateWindow( + WndClassName, TEXT("BitBlt Bitmap Rendering Demo"), + WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | + WS_VISIBLE | WS_CLIPSIBLINGS, + 0, 0, 220, 230, + NULL, NULL, HInst, NULL + ); + + if (HWnd) + { + ShowWindow(HWnd, nCmdShow); + UpdateWindow(HWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} + +/* image related */ +BITMAP bmp; +LPCSTR filename = TEXT("lena.bmp"); +HDC HMemDC = NULL; +HBITMAP HOldBmp = NULL; + +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam) +{ + switch (Msg) + { + case WM_CREATE: + { + /* create a memory DC */ + HMemDC = CreateCompatibleDC(NULL); + if (HMemDC) + { + /* load a bitmap from file */ + HBITMAP HBmp = + /* static_cast */( + LoadImage(HInst, filename, IMAGE_BITMAP, + 0, 0, LR_LOADFROMFILE) + ); + if (HBmp) + { + /* extract dimensions of the bitmap */ + GetObject(HBmp, sizeof(BITMAP), &bmp); + + /* associate the bitmap with the memory DC */ + /* HOldBmp = static_cast */ + (SelectObject(HMemDC, HBmp) + ); + } + } + } + case WM_PAINT: + { + PAINTSTRUCT ps; + const HDC Hdc = BeginPaint(HWnd, &ps); +#if 0 + try +#endif + { + + /* TODO: add palette support (see Chapter 9)... */ + + + BitBlt(Hdc, 20, 15, + bmp.bmWidth, bmp.bmHeight, + HMemDC, 0, 0, + SRCCOPY); + } +#if 0 + catch (...) +#endif + { + EndPaint(HWnd, &ps); + } + EndPaint(HWnd, &ps); + break; + } + case WM_DESTROY: + { + /* clean up */ + DeleteObject(SelectObject(HMemDC, HOldBmp)); + DeleteDC(HMemDC); + + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(HWnd, Msg, WParam, LParam); +} diff --git a/apps/tests/bitblt/bitblt.cpp b/apps/tests/bitblt/bitblt.cpp deleted file mode 100644 index f49bfb7..0000000 --- a/apps/tests/bitblt/bitblt.cpp +++ /dev/null @@ -1,138 +0,0 @@ - -// ------------------------------------------------------------------ -// Windows 2000 Graphics API Black Book -// Chapter 1 - Listing 1.3 (BitBlt Bitmap Rendering Demo) -// -// Created by Damon Chandler -// Updates can be downloaded at: -// -// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu -// if you have any questions about this code. -// ------------------------------------------------------------------ - - -//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -#include -//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - -HINSTANCE HInst; -const char* WndClassName = "GMainWnd"; -LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, - LPARAM LParam); - - -int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, - LPTSTR lpCmdLine, int nCmdShow) -{ - HInst = HInstance; - - WNDCLASS wc; - memset(&wc, 0, sizeof(WNDCLASS)); - - wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; - wc.lpfnWndProc = MainWndProc; - wc.hInstance = HInstance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = reinterpret_cast(COLOR_BTNFACE + 1); - wc.lpszClassName = WndClassName; - - if (RegisterClass(&wc)) - { - HWND HWnd = - CreateWindow( - WndClassName, TEXT("BitBlt Bitmap Rendering Demo"), - WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | - WS_VISIBLE | WS_CLIPSIBLINGS, - 0, 0, 220, 230, - NULL, NULL, HInst, NULL - ); - - if (HWnd) - { - ShowWindow(HWnd, nCmdShow); - UpdateWindow(HWnd); - - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - return 0; -} -//------------------------------------------------------------------ - - -// image related -BITMAP bmp; -LPCSTR filename = TEXT("lena.bmp"); -HDC HMemDC = NULL; -HBITMAP HOldBmp = NULL; - -LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, - LPARAM LParam) -{ - switch (Msg) - { - case WM_CREATE: - { - // create a memory DC - HMemDC = CreateCompatibleDC(NULL); - if (HMemDC) - { - // load a bitmap from file - HBITMAP HBmp = - static_cast( - LoadImage(HInst, filename, IMAGE_BITMAP, - 0, 0, LR_LOADFROMFILE) - ); - if (HBmp) - { - // extract dimensions of the bitmap - GetObject(HBmp, sizeof(BITMAP), &bmp); - - // associate the bitmap with the memory DC - HOldBmp = static_cast( - SelectObject(HMemDC, HBmp) - ); - } - } - } - case WM_PAINT: - { - PAINTSTRUCT ps; - const HDC Hdc = BeginPaint(HWnd, &ps); - try - { - // - // TODO: add palette support (see Chapter 9)... - // - - BitBlt(Hdc, 20, 15, - bmp.bmWidth, bmp.bmHeight, - HMemDC, 0, 0, - SRCCOPY); - } - catch (...) - { - EndPaint(HWnd, &ps); - } - EndPaint(HWnd, &ps); - break; - } - case WM_DESTROY: - { - // clean up - DeleteObject(SelectObject(HMemDC, HOldBmp)); - DeleteDC(HMemDC); - - PostQuitMessage(0); - return 0; - } - } - return DefWindowProc(HWnd, Msg, WParam, LParam); -} -//------------------------------------------------------------------ diff --git a/apps/tests/bitblt/makefile b/apps/tests/bitblt/makefile index 8ce9863..bc1acb1 100644 --- a/apps/tests/bitblt/makefile +++ b/apps/tests/bitblt/makefile @@ -1,66 +1,20 @@ -# Makefile - Proj_Listing1_5.dsp -ifndef CFG -CFG=Proj_Listing1_5 - Win32 Debug -endif -CC=gcc -CFLAGS= -CXX=g++ -CXXFLAGS=$(CFLAGS) -RC=windres -O COFF -ifeq "$(CFG)" "Proj_Listing1_5 - Win32 Release" -CFLAGS+=-fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -W -LD=$(CXX) $(CXXFLAGS) -LDFLAGS= -LDFLAGS+=-Wl,--subsystem,windows -LIBS+=-lkernel32 -luser32 -lgdi32 -else -ifeq "$(CFG)" "Proj_Listing1_5 - Win32 Debug" -CFLAGS+=-fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -LD=$(CXX) $(CXXFLAGS) -LDFLAGS= -LDFLAGS+=-Wl,--subsystem,windows -LIBS+=-lkernel32 -luser32 -lgdi32 -endif -endif +PATH_TO_TOP = ../../.. -ifndef TARGET -TARGET=bitblt.exe -endif +TARGET_NORC = yes -.PHONY: all -all: $(TARGET) +TARGET_TYPE = program -%.o: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< +TARGET_APPTYPE = windows -%.o: %.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $< +TARGET_NAME = bitblt -%.res: %.rc - $(RC) $(CPPFLAGS) -o $@ -i $< +TARGET_SDKLIBS = kernel32.a gdi32.a -SOURCE_FILES= \ - bitblt.cpp +TARGET_OBJECTS = $(TARGET_NAME).o -HEADER_FILES= +include $(PATH_TO_TOP)/rules.mak -RESOURCE_FILES= - -SRCS=$(SOURCE_FILES) $(HEADER_FILES) $(RESOURCE_FILES) - -OBJS=$(patsubst %.rc,%.res,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(filter %.c %.cpp %.rc,$(SRCS))))) - -$(TARGET): $(OBJS) - $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) - -.PHONY: clean -clean: - -del $(OBJS) $(TARGET) - -.PHONY: depends -depends: - -$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $(filter %.c %.cpp,$(SRCS)) > Proj_Listing1_5.dep - --include Proj_Listing1_5.dep +include $(TOOLS_PATH)/helper.mk +# EOF diff --git a/apps/tests/dibtest/dibtest.c b/apps/tests/dibtest/dibtest.c index 81d532b..3ed2ebf 100644 --- a/apps/tests/dibtest/dibtest.c +++ b/apps/tests/dibtest/dibtest.c @@ -1,81 +1,196 @@ #include +#include +#include -extern BOOL STDCALL GdiDllInitialize(HANDLE hInstance, DWORD Event, LPVOID Reserved); +#define CELL_SIZE 10 -void __stdcall Test1BPP (HDC Desktop) +static RGBQUAD Colors[] = { - HDC TestDC; - HPEN WhitePen; - HBITMAP DIB1; - BITMAPINFOHEADER BitInf; - PBITMAPINFO BitPalInf; - DWORD bmiSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2; - - // Create a 1BPP DIB - BitPalInf = (PBITMAPINFO)malloc(bmiSize); - BitInf.biSize = sizeof(BITMAPINFOHEADER); - BitInf.biWidth = 50; - BitInf.biHeight = -50; // it's top down (since BI_RGB is used, the sign is operative of direction) - BitInf.biPlanes = 1; - BitInf.biBitCount = 1; - BitInf.biCompression = BI_RGB; - BitInf.biSizeImage = 0; - BitInf.biXPelsPerMeter = 0; - BitInf.biYPelsPerMeter = 0; - BitInf.biClrUsed = 0; - BitInf.biClrImportant = 0; - BitPalInf->bmiHeader = BitInf; - BitPalInf->bmiColors[1].rgbBlue = 255; - BitPalInf->bmiColors[1].rgbGreen = 255; - BitPalInf->bmiColors[1].rgbRed = 255; - BitPalInf->bmiColors[1].rgbReserved = 255; - BitPalInf->bmiColors[0].rgbBlue = 0; - BitPalInf->bmiColors[0].rgbGreen = 0; - BitPalInf->bmiColors[0].rgbRed = 0; - BitPalInf->bmiColors[0].rgbReserved = 0; - - DIB1 = (HBITMAP) CreateDIBSection(NULL, BitPalInf, DIB_RGB_COLORS, NULL, NULL, 0); - TestDC = CreateCompatibleDC(NULL); - SelectObject(TestDC, DIB1); - - // Draw a white rectangle on the 1BPP DIB - WhitePen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); - SelectObject(TestDC, WhitePen); - Rectangle(TestDC, 0, 0, 40, 40); - - // Blt the 1BPP DIB to the display - BitBlt(Desktop, 0, 0, 50, 50, TestDC, 0, 0, SRCCOPY); - - free(BitPalInf); -// Rectangle(Desktop, 50, 50, 200, 200); + { 0x00, 0x00, 0x00, 0x00 }, // black + { 0x00, 0x00, 0x80, 0x00 }, // red + { 0x00, 0x80, 0x00, 0x00 }, // green + { 0x00, 0x80, 0x80, 0x00 }, // brown + { 0x80, 0x00, 0x00, 0x00 }, // blue + { 0x80, 0x00, 0x80, 0x00 }, // magenta + { 0x80, 0x80, 0x00, 0x00 }, // cyan + { 0x80, 0x80, 0x80, 0x00 }, // dark gray + { 0xc0, 0xc0, 0xc0, 0x00 }, // light gray + { 0x00, 0x00, 0xFF, 0x00 }, // bright red + { 0x00, 0xFF, 0x00, 0x00 }, // bright green + { 0x00, 0xFF, 0xFF, 0x00 }, // bright yellow + { 0xFF, 0x00, 0x00, 0x00 }, // bright blue + { 0xFF, 0x00, 0xFF, 0x00 }, // bright magenta + { 0xFF, 0xFF, 0x00, 0x00 }, // bright cyan + { 0xFF, 0xFF, 0xFF, 0x00 } // bright white +}; + +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); + +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + WNDCLASS wc; + MSG msg; + HWND hWnd; + + wc.lpszClassName = "DibTestClass"; + wc.lpfnWndProc = MainWndProc; + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + hWnd = CreateWindow("DibTestClass", + "DIB Test", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + 25 * CELL_SIZE + 5, + 25 * CELL_SIZE + 20, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + ShowWindow(hWnd, nCmdShow); + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + return msg.wParam; } -void DIBTest(void) +static void PaintCells(HDC WindowDC, WORD BitCount1, WORD BitCount2, + int XDest, int YDest) { - HDC Desktop; + HBRUSH Brush; + RECT Rect; + UINT row, col; + BITMAPINFO *BitmapInfo; + HBITMAP DIB1, DIB2; + HDC DC1, DC2; - // Set up a DC called Desktop that accesses DISPLAY - Desktop = CreateDCA("DISPLAY", NULL, NULL, NULL); - if(Desktop == NULL) { - printf("Can't create desktop\n"); - return; + BitmapInfo = malloc(sizeof(BITMAPINFO) + 15 * sizeof(RGBQUAD)); + BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + BitmapInfo->bmiHeader.biWidth = 4 * CELL_SIZE + 9; + BitmapInfo->bmiHeader.biHeight = -(4 * CELL_SIZE + 9); // it's top down (since BI_RGB is used, the sign is operative of direction) + BitmapInfo->bmiHeader.biPlanes = 1; + BitmapInfo->bmiHeader.biBitCount = BitCount1; + BitmapInfo->bmiHeader.biCompression = BI_RGB; + BitmapInfo->bmiHeader.biSizeImage = 0; + BitmapInfo->bmiHeader.biXPelsPerMeter = 0; + BitmapInfo->bmiHeader.biYPelsPerMeter = 0; + BitmapInfo->bmiHeader.biClrUsed = 16; + BitmapInfo->bmiHeader.biClrImportant = 16; + for (col = 0; col < 16; col++) { + BitmapInfo->bmiColors[col] = Colors[col]; } + DIB1 = CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0); + DC1 = CreateCompatibleDC(NULL); + SelectObject(DC1, DIB1); - // 1BPP Test - Test1BPP(Desktop); + BitmapInfo->bmiHeader.biBitCount = BitCount2; + DIB2 = CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0); + DC2 = CreateCompatibleDC(NULL); + SelectObject(DC2, DIB2); + free(BitmapInfo); - Sleep(50000); + /* Now paint on the first bitmap */ + for (row = 0; row < 4; row++) + { + for (col = 0; col < 4; col++) + { + Brush = CreateSolidBrush(RGB(Colors[4 * row + col].rgbRed, + Colors[4 * row + col].rgbGreen, + Colors[4 * row + col].rgbBlue)); + Rect.left = CELL_SIZE * col + 5; + Rect.top = CELL_SIZE * row + 5; + Rect.right = Rect.left + CELL_SIZE; + Rect.bottom = Rect.top + CELL_SIZE; + FillRect(DC1, &Rect, Brush); + DeleteObject(Brush); + } + } - // Free up everything - DeleteDC(Desktop); + /* Copy the first bitmap to the second */ + BitBlt(DC2, 4, 4, 4 * CELL_SIZE, 4 * CELL_SIZE, DC1, 5, 5, SRCCOPY); + + /* Show results on screen */ + BitBlt(WindowDC, XDest, YDest, 4 * CELL_SIZE, 4 * CELL_SIZE, DC2, 4, 4, SRCCOPY); } -int main(int argc, char* argv[]) +LRESULT CALLBACK MainWndProc(HWND Wnd, UINT msg, WPARAM wParam, LPARAM lParam) { - printf("Entering DIBTest..\n"); + PAINTSTRUCT ps; + HDC WindowDC; + + switch(msg) + { + case WM_PAINT: + WindowDC = BeginPaint(Wnd, &ps); + + PaintCells(WindowDC, 4, 4, 0, 0); + PaintCells(WindowDC, 4, 8, 5 * CELL_SIZE, 0); + PaintCells(WindowDC, 4, 16, 10 * CELL_SIZE, 0); + PaintCells(WindowDC, 4, 24, 15 * CELL_SIZE, 0); + PaintCells(WindowDC, 4, 32, 20 * CELL_SIZE, 0); + + PaintCells(WindowDC, 8, 4, 0, 5 * CELL_SIZE); + PaintCells(WindowDC, 8, 8, 5 * CELL_SIZE, 5 * CELL_SIZE); + PaintCells(WindowDC, 8, 16, 10 * CELL_SIZE, 5 * CELL_SIZE); + PaintCells(WindowDC, 8, 24, 15 * CELL_SIZE, 5 * CELL_SIZE); + PaintCells(WindowDC, 8, 32, 20 * CELL_SIZE, 5 * CELL_SIZE); + + PaintCells(WindowDC, 16, 4, 0, 10 * CELL_SIZE); + PaintCells(WindowDC, 16, 8, 5 * CELL_SIZE, 10 * CELL_SIZE); + PaintCells(WindowDC, 16, 16, 10 * CELL_SIZE, 10 * CELL_SIZE); + PaintCells(WindowDC, 16, 24, 15 * CELL_SIZE, 10 * CELL_SIZE); + PaintCells(WindowDC, 16, 32, 20 * CELL_SIZE, 10 * CELL_SIZE); + + PaintCells(WindowDC, 24, 4, 0, 15 * CELL_SIZE); + PaintCells(WindowDC, 24, 8, 5 * CELL_SIZE, 15 * CELL_SIZE); + PaintCells(WindowDC, 24, 16, 10 * CELL_SIZE, 15 * CELL_SIZE); + PaintCells(WindowDC, 24, 24, 15 * CELL_SIZE, 15 * CELL_SIZE); + PaintCells(WindowDC, 24, 32, 20 * CELL_SIZE, 15 * CELL_SIZE); + + PaintCells(WindowDC, 32, 4, 0, 20 * CELL_SIZE); + PaintCells(WindowDC, 32, 8, 5 * CELL_SIZE, 20 * CELL_SIZE); + PaintCells(WindowDC, 32, 16, 10 * CELL_SIZE, 20 * CELL_SIZE); + PaintCells(WindowDC, 32, 24, 15 * CELL_SIZE, 20 * CELL_SIZE); + PaintCells(WindowDC, 32, 32, 20 * CELL_SIZE, 20 * CELL_SIZE); + + EndPaint(Wnd, &ps); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; - GdiDllInitialize (NULL, DLL_PROCESS_ATTACH, NULL); - DIBTest(); + default: + return DefWindowProc(Wnd, msg, wParam, lParam); + } return 0; } diff --git a/apps/tests/dibtest/makefile b/apps/tests/dibtest/makefile index b80799b..2960599 100644 --- a/apps/tests/dibtest/makefile +++ b/apps/tests/dibtest/makefile @@ -6,7 +6,7 @@ TARGET_NORC = yes TARGET_TYPE = program -TARGET_APPTYPE = console +TARGET_APPTYPE = windows TARGET_NAME = dibtest diff --git a/apps/tests/hivetest/hivetest.c b/apps/tests/hivetest/hivetest.c index 587526c..8ace59c 100644 --- a/apps/tests/hivetest/hivetest.c +++ b/apps/tests/hivetest/hivetest.c @@ -57,7 +57,7 @@ void CreateKeyTest(void) UNICODE_STRING KeyName; NTSTATUS Status; - dprintf("Create key: '\\Registry\\Machine\\Software\\testkey':\n"); + dprintf("Create key '\\Registry\\Machine\\Software\\testkey':\n"); RtlInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\testkey"); InitializeObjectAttributes(&ObjectAttributes, @@ -65,7 +65,7 @@ void CreateKeyTest(void) OBJ_CASE_INSENSITIVE, NULL, NULL); - dprintf("NtCreateKey: "); + dprintf("NtCreateKey:\n"); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, @@ -73,7 +73,7 @@ void CreateKeyTest(void) NULL, REG_OPTION_NON_VOLATILE, NULL); - dprintf("Status = %lx\n",Status); + dprintf(" Status = %lx\n",Status); if (NT_SUCCESS(Status)) { NtClose(hKey); @@ -96,17 +96,17 @@ void DeleteKeyTest(void) OBJ_CASE_INSENSITIVE, NULL, NULL); - dprintf("NtOpenKey: "); + dprintf("NtOpenKey:\n"); Status = NtOpenKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes); - dprintf("Status = %lx\n",Status); + dprintf(" Status = %lx\n",Status); if (!NT_SUCCESS(Status)) return; - dprintf("NtDeleteKey: "); + dprintf("NtDeleteKey:\n"); Status = NtDeleteKey(hKey); - dprintf("Status = %lx\n",Status); + dprintf(" Status = %lx\n",Status); NtClose(hKey); } @@ -130,21 +130,21 @@ void EnumerateKeyTest(void) OBJ_CASE_INSENSITIVE, NULL, NULL); - dprintf("NtOpenKey: "); + dprintf("NtOpenKey:\n"); Status = NtOpenKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes); - dprintf("Status = %lx\n", Status); + dprintf(" Status = %lx\n", Status); if (!NT_SUCCESS(Status)) return; - dprintf("NtQueryKey: "); + dprintf("NtQueryKey:\n"); Status = NtQueryKey(hKey, KeyBasicInformation, &KeyInformation[0], sizeof(KeyInformation), &Length); - dprintf("Status = %lx\n", Status); + dprintf(" Status = %lx\n", Status); if (NT_SUCCESS(Status)) { dprintf("\tKey Name = "); @@ -153,7 +153,7 @@ void EnumerateKeyTest(void) dprintf("\n"); } - dprintf("NtEnumerateKey: \n"); + dprintf("NtEnumerateKey:\n"); Index=0; while(NT_SUCCESS(Status)) { @@ -173,9 +173,9 @@ void EnumerateKeyTest(void) Index++; } - dprintf("NtClose: "); + dprintf("NtClose:\n"); Status = NtClose(hKey); - dprintf("Status = %lx\n", Status); + dprintf(" Status = %lx\n", Status); } @@ -187,7 +187,7 @@ void SetValueTest1(void) UNICODE_STRING ValueName; NTSTATUS Status; - dprintf("Create key: '\\Registry\\Machine\\Software\\testkey':\n"); + dprintf("Create key '\\Registry\\Machine\\Software\\testkey':\n"); RtlInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\testkey"); InitializeObjectAttributes(&ObjectAttributes, @@ -195,7 +195,7 @@ void SetValueTest1(void) OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL); - dprintf("NtCreateKey: "); + dprintf("NtCreateKey:\n"); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, @@ -203,20 +203,20 @@ void SetValueTest1(void) NULL, REG_OPTION_NON_VOLATILE, NULL); - dprintf("Status = %lx\n",Status); + dprintf(" Status = %lx\n",Status); if (!NT_SUCCESS(Status)) return; RtlInitUnicodeStringFromLiteral(&ValueName, L"TestValue"); - dprintf("NtSetValueKey: "); + dprintf("NtSetValueKey:\n"); Status = NtSetValueKey(hKey, &ValueName, 0, REG_SZ, (PVOID)L"TestString", 24); - dprintf("Status = %lx\n",Status); + dprintf(" Status = %lx\n",Status); NtClose(hKey); } @@ -230,7 +230,7 @@ void SetValueTest2(void) UNICODE_STRING ValueName; NTSTATUS Status; - dprintf("Create key: '\\Registry\\Machine\\Software\\testkey':\n"); + dprintf("Create key '\\Registry\\Machine\\Software\\testkey':\n"); RtlInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\testkey"); InitializeObjectAttributes(&ObjectAttributes, @@ -238,7 +238,7 @@ void SetValueTest2(void) OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL); - dprintf("NtCreateKey: "); + dprintf("NtCreateKey:\n"); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, @@ -273,7 +273,7 @@ void DeleteValueTest(void) HKEY KeyHandle; NTSTATUS Status; - dprintf("Open key: '\\Registry\\Machine\\Software\\testkey':\n"); + dprintf("Open key '\\Registry\\Machine\\Software\\testkey':\n"); RtlInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\testkey"); InitializeObjectAttributes(&ObjectAttributes, @@ -311,7 +311,7 @@ void EnumerateValueTest(void) HKEY hKey = NULL; NTSTATUS Status; - dprintf("Open key: '\\Registry\\Machine\\Software\\testkey':\n"); + dprintf("Open key '\\Registry\\Machine\\Software\\testkey':\n"); RtlInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\testkey"); InitializeObjectAttributes(&ObjectAttributes, @@ -326,7 +326,7 @@ void EnumerateValueTest(void) if (!NT_SUCCESS(Status)) return; - dprintf("Enumerate values: \n"); + dprintf("Enumerate values:\n"); Index = 0; while (Status == STATUS_SUCCESS) { diff --git a/apps/tests/lpc/makefile b/apps/tests/lpc/makefile index afa9b5c..6259c92 100644 --- a/apps/tests/lpc/makefile +++ b/apps/tests/lpc/makefile @@ -26,11 +26,22 @@ clean: .phony: implib clean +ifneq ($(BOOTCD_INSTALL),) + +install: $(PROGS:%=$(INSTALL_DIR)/%) + +$(PROGS:%=$(INSTALL_DIR)/%): $(INSTALL_DIR)/%: % + $(CP) $* $(INSTALL_DIR)/$* + +else # BOOTCD_INSTALL + install: $(PROGS:%=$(INSTALL_DIR)/bin/%) $(PROGS:%=$(INSTALL_DIR)/bin/%): $(INSTALL_DIR)/bin/%: % $(CP) $* $(INSTALL_DIR)/bin/$* +endif # BOOTCD_INSTALL + dist: $(PROGS:%=$(DIST_DIR)/apps/%) $(PROGS:%=$(DIST_DIR)/apps/%): $(DIST_DIR)/apps/%: % diff --git a/apps/tests/simple/.cvsignore b/apps/tests/messagebox/.cvsignore similarity index 100% rename from apps/tests/simple/.cvsignore rename to apps/tests/messagebox/.cvsignore diff --git a/apps/tests/simple/makefile b/apps/tests/messagebox/makefile similarity index 100% rename from apps/tests/simple/makefile rename to apps/tests/messagebox/makefile diff --git a/apps/tests/simple/simple.c b/apps/tests/messagebox/simple.c similarity index 100% rename from apps/tests/simple/simple.c rename to apps/tests/messagebox/simple.c diff --git a/apps/tests/mstest/Makefile b/apps/tests/mstest/Makefile index fd46a80..a386511 100644 --- a/apps/tests/mstest/Makefile +++ b/apps/tests/mstest/Makefile @@ -26,11 +26,22 @@ clean: .phony: implib clean +ifneq ($(BOOTCD_INSTALL),) + +install: $(PROGS:%=$(INSTALL_DIR)/%) + +$(PROGS:%=$(INSTALL_DIR)/%): $(INSTALL_DIR)/%: % + $(CP) $* $(INSTALL_DIR)/$* + +else # BOOTCD_INSTALL + install: $(PROGS:%=$(INSTALL_DIR)/bin/%) $(PROGS:%=$(INSTALL_DIR)/bin/%): $(INSTALL_DIR)/bin/%: % $(CP) $* $(INSTALL_DIR)/bin/$* +endif # BOOTCD_INSTALL + dist: $(PROGS:%=$(DIST_DIR)/apps/%) $(PROGS:%=$(DIST_DIR)/apps/%): $(DIST_DIR)/apps/%: % diff --git a/apps/tests/nptest/Makefile b/apps/tests/nptest/Makefile index 6f87406..f19655a 100644 --- a/apps/tests/nptest/Makefile +++ b/apps/tests/nptest/Makefile @@ -25,11 +25,22 @@ clean: .phony: implib clean +ifneq ($(BOOTCD_INSTALL),) + +install: $(PROGS:%=$(INSTALL_DIR)/%) + +$(PROGS:%=$(INSTALL_DIR)/%): $(INSTALL_DIR)/%: % + $(CP) $* $(INSTALL_DIR)/$* + +else # BOOTCD_INSTALL + install: $(PROGS:%=$(INSTALL_DIR)/bin/%) $(PROGS:%=$(INSTALL_DIR)/bin/%): $(INSTALL_DIR)/bin/%: % $(CP) $* $(INSTALL_DIR)/bin/$* +endif # BOOTCD_INSTALL + dist: $(PROGS:%=$(DIST_DIR)/apps/%) $(PROGS:%=$(DIST_DIR)/apps/%): $(DIST_DIR)/apps/%: % diff --git a/apps/tests/patblt/patblt.cpp b/apps/tests/patblt/patblt.cpp index 84c5d7b..f156fa5 100644 --- a/apps/tests/patblt/patblt.cpp +++ b/apps/tests/patblt/patblt.cpp @@ -230,7 +230,9 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, { PAINTSTRUCT ps; HDC Hdc = BeginPaint(HWnd, &ps); +#if 0 try +#endif { // // TODO: Add palette support... @@ -243,7 +245,9 @@ LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, HMemDC, 0, 0, SRCCOPY); } +#if 0 catch (...) +#endif { EndPaint(HWnd, &ps); } diff --git a/apps/tests/shaptest/makefile b/apps/tests/shaptest/makefile new file mode 100644 index 0000000..4b86249 --- /dev/null +++ b/apps/tests/shaptest/makefile @@ -0,0 +1,21 @@ +# $Id$ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = shaptest + +TARGET_SDKLIBS = kernel32.a gdi32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/apps/tests/shaptest/shaptest.c b/apps/tests/shaptest/shaptest.c new file mode 100644 index 0000000..3ef8e4d --- /dev/null +++ b/apps/tests/shaptest/shaptest.c @@ -0,0 +1,192 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * AUTHOR: See gditest-- (initial changes by Mark Tempel) + * shaptest + * + * This is a windowed application that should draw two polygons. One + * is drawn with ALTERNATE fill, the other is drawn with WINDING fill. + * This is used to test out the Polygon() implementation. + */ + +#include +#include + + +HFONT tf; +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); + +void __stdcall PolygonTest(HDC Desktop) +{ + HPEN BluePen; + HPEN OldPen; + HBRUSH RedBrush; + HBRUSH OldBrush; + POINT lpPointsAlternate[5]; + POINT lpPointsWinding[5]; + DWORD Mode; + + //create a pen to draw the shape + BluePen = CreatePen(PS_SOLID, 3, RGB(0, 0, 0xff)); + RedBrush = CreateSolidBrush(RGB(0xff, 0, 0)); + + //initialize a set of points for alternate. + lpPointsAlternate[0].x = 20; + lpPointsAlternate[0].y = 80; //{20,80}; + lpPointsAlternate[1].x = 60; + lpPointsAlternate[1].y = 20; //{60,20}; + lpPointsAlternate[2].x = 90; + lpPointsAlternate[2].y = 80; //{90,80}; + lpPointsAlternate[3].x = 20; + lpPointsAlternate[3].y = 40; //{20,40}; + lpPointsAlternate[4].x = 100; + lpPointsAlternate[4].y = 40; //{100,40}; + + //initialize a set of points for winding. + lpPointsWinding[0].x = 130; + lpPointsWinding[0].y = 80; //{130,80}; + lpPointsWinding[1].x = 170; + lpPointsWinding[1].y = 20; //{170,20}; + lpPointsWinding[2].x = 200; + lpPointsWinding[2].y = 80; //{200,80}; + lpPointsWinding[3].x = 130; + lpPointsWinding[3].y = 40; //{130,40}; + lpPointsWinding[4].x = 210; + lpPointsWinding[4].y = 40; //{210,40}; + + OldPen = (HPEN)SelectObject(Desktop, BluePen); + OldBrush = (HBRUSH)SelectObject(Desktop, RedBrush); + + Mode = GetPolyFillMode(Desktop); + + SetPolyFillMode(Desktop, ALTERNATE); + Polygon(Desktop,lpPointsAlternate,5); + + SetPolyFillMode(Desktop, WINDING); + Polygon(Desktop,lpPointsWinding,5); + + //cleanup + SetPolyFillMode(Desktop, Mode); + SelectObject(Desktop, OldPen); + SelectObject(Desktop, OldBrush); + DeleteObject(BluePen); + DeleteObject(RedBrush); + +} + + +void shaptest( HDC DevCtx ){ + HDC Desktop, MyDC, DC24; + HPEN RedPen, GreenPen, BluePen, WhitePen; + HBITMAP MyBitmap, DIB24; + HFONT hf, tf; + BITMAPINFOHEADER BitInf; + BITMAPINFO BitPalInf; + HRGN hRgn1, hRgn2, hRgn3; + HBRUSH BlueBrush, DefBrush; + int sec,Xmod,Ymod; + char tbuf[5]; + + + BlueBrush = CreateSolidBrush( RGB(0, 0, 0xff) ); + DefBrush = SelectObject( DevCtx, BlueBrush ); + + SelectObject( DevCtx, DefBrush ); + DeleteObject( BlueBrush ); + + // Create a blue pen and select it into the DC + BluePen = CreatePen(PS_SOLID, 8, RGB(0, 0, 0xff)); + SelectObject(DevCtx, BluePen); + + //Test the Polygon routine. + PolygonTest(DevCtx); +} + + +int WINAPI +WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + WNDCLASS wc; + MSG msg; + HWND hWnd; + + wc.lpszClassName = "ShapTestClass"; + wc.lpfnWndProc = MainWndProc; + wc.style = CS_VREDRAW | CS_HREDRAW; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + if (RegisterClass(&wc) == 0) + { + fprintf(stderr, "RegisterClass failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + hWnd = CreateWindow("ShapTestClass", + "Shaptest", + WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, + 0, + 0, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInstance, + NULL); + if (hWnd == NULL) + { + fprintf(stderr, "CreateWindow failed (last error 0x%X)\n", + GetLastError()); + return(1); + } + + tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons"); + + ShowWindow(hWnd, nCmdShow); + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + DeleteObject(tf); + + return msg.wParam; +} + +LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + HDC hDC; + RECT clr, wir; + char spr[100], sir[100]; + + switch(msg) + { + + case WM_PAINT: + hDC = BeginPaint(hWnd, &ps); + shaptest( hDC ); + EndPaint(hWnd, &ps); + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + return 0; +} + diff --git a/apps/tests/shm/makefile b/apps/tests/shm/makefile index 2bc060f..a069b10 100644 --- a/apps/tests/shm/makefile +++ b/apps/tests/shm/makefile @@ -26,11 +26,22 @@ clean: .phony: implib clean +ifneq ($(BOOTCD_INSTALL),) + +install: $(PROGS:%=$(INSTALL_DIR)/%) + +$(PROGS:%=$(INSTALL_DIR)/%): $(INSTALL_DIR)/%: % + $(CP) $* $(INSTALL_DIR)/$* + +else # BOOTCD_INSTALL + install: $(PROGS:%=$(INSTALL_DIR)/bin/%) $(PROGS:%=$(INSTALL_DIR)/bin/%): $(INSTALL_DIR)/bin/%: % $(CP) $* $(INSTALL_DIR)/bin/$* +endif # BOOTCD_INSTALL + dist: $(PROGS:%=$(DIST_DIR)/apps/%) $(PROGS:%=$(DIST_DIR)/apps/%): $(DIST_DIR)/apps/%: % diff --git a/apps/tests/tests/hello2/.cvsignore b/apps/tests/tests/hello2/.cvsignore deleted file mode 100644 index 0ec02ac..0000000 --- a/apps/tests/tests/hello2/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.exe -*.o -*.sym diff --git a/apps/tests/tests/hello2/Makefile b/apps/tests/tests/hello2/Makefile deleted file mode 100644 index 6929eaa..0000000 --- a/apps/tests/tests/hello2/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# -# -PATH_TO_TOP = ../../../.. - -PROGS = hello2 - -OBJECTS = hello2.o - -LIBS = # gdi32.a -CFLAGS = - -all: $(PROGS:%=%.exe) - -.phony: all - -clean: - - $(RM) *.o *.coff *.exe *.sym - -.phony: clean - -hello2.exe: $(OBJECTS) - $(CC) $(CFLAGS) -Wl,--subsystem,windows $(OBJECTS) $(LIBS) -o hello2.exe - $(NM) --numeric-sort hello2.exe > hello2.sym - -include $(PATH_TO_TOP)/rules.mak diff --git a/apps/tests/tests/hello2/hello2.c b/apps/tests/tests/hello2/hello2.c deleted file mode 100644 index 166eec4..0000000 --- a/apps/tests/tests/hello2/hello2.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "windows.h" - -int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) -{ - return MessageBox((HWND)0, - (LPSTR)"Hello, hello!", - (LPSTR)"Hello Wine Application", - (MB_OK | MB_ICONEXCLAMATION)); -} diff --git a/apps/tests/wm_erasebkgnd/BACKBITMAP.BMP b/apps/tests/wm_erasebkgnd/BACKBITMAP.BMP new file mode 100644 index 0000000000000000000000000000000000000000..38bc9716b64d087a7db51da3369be7766d930d30 GIT binary patch literal 26566 zcmXZF<(nK=mhQWQBLfp7l9@A$OQkBYO3Y}I*)q%6vYXW0YF4wlhdewU_OORNbI^zT z(7kaa^Tj?pcRHdxUh#hM$c-LC*+P!<>!xz-z>qA4SF+csvKmO5_yLeqa zt5n|q=+FPhEAr>P4?k3Q-?^{uzxS?spP%o&`;L15CqLo!5BUC}dguN3)SdhH)Vm*i zpx)!pyC1yId)`&|7N2=feZYI~^80uA{JVVS_Px96KG%5n{rCCo`&^sr@%lZ!zsvRC z<$CY&`g^Adq=&`&mVBj+jsA>uJ_bEUcWE*<>&YL{4L(|;o>^1jnCeF_dd_?p}Nmn z?!Nb)dUtW(yXqbO{SIrq%e_DNho7o@tmVUh_y^v1pY^}1Zr#4aweIp9teNj0^33nc zv)#YTbG)x^-nzx-KU6pG+-9xss9SvhfX{!(n%`kfw|LGELr?(-fpeTUa?@t(W)k)x~`IlL$LW9?UO z+)z8aXIbaFteL&Nb64HuK0je?Kl$(fUEO4zcaX>J+qcv%_rA$GuHL+%&fd7G&hqnZ z`8V&mednIK$9itd`nk_p-h1ob9o~CO-Q>MHySwbsKd9Zs{jRDt?s+guH(e>LR zGuHf5WciNBk!#%N`wp+&VxLZxB5jiEXUw*#FLkuCspTfQcB!OknyE$dU*zWVdH3O^ zeE#*Qo6&NSrtR?!D?40ujEdVIr5A?BEjy`J{gJn+veq{pt6~Ic5TtoGam`#S=f-Ya zGRtMXIxgwDR?1~UU2BIyW!+Yutt{pF+WCWC!}#a_@s0D^)tDyX_|UaX#`67shSrq zRt>Mv`1`wO{>dcQTJC2undM?Dr|~@(>88e7GsR5XENQu14w0E1Q)`<@s+?g-s#Qyo9WuNyu)wxLnM9hXrO@t-ZzZi{n;CYik;cmPcAzIb!*2d}NmQm!qnAD#w18 zHO;N5)xc~)MN3&6>lZV{HSGlQ${#iL zlJ1&Oj>VW7`!nfI_*N<%)L8zcSKBvG14C7YA~`m>*&OgSB=*@#&6MrBi_PsNL7<0W zDJ+%rs+O5N_F`Y_n0g$V<`O@crBYrmYnL*0&&NnuT6R|Pyg)f#C-d}mkzapp`K;FJ zwnMXB9X~T}6*V){?Q130*U`&4R1Uq&tjV+RL~TSWf4j=CrvAVh9(M+oGh}5>%~DgA zy4$R&2Uk~=ZCEJ29qe&=P(G!{?8Ff+k?Ciyx5Kb(b|?JFRq++NJM!nrJie+1R>iCP zeoYy9u~KA)IjxPgt`?rw?%eCQL)Nm!j+aa}Im)#01Z;ceh*qjb7zg5f1x<9_>4V#Y zxoXa~nhy@A!=cr56bk4MnrdGbd0Lji&Zj{yNZpa_Z#k@TyD^HJZ|&u2#v+UQnyHqf3bI2)o+Kpk7g~o9UK+FYFfi5H>QwQcz^9hvlLS z`^_qDtAoeF=a_2S%339RHqBbj6!Vx_E7za!pK!oA1It#c&Wf>WzZtW%xQ_hrsIis{ zGvy6jOcHSmb|EunqsEhdrmTBB(R8Jr)`HXzj6!M~L7{$djLxkJ4+=tS~n-YqXxmYvDtJGlx1ZdwRO8@UuAX8 z=00m`*-kU-2ks#^bYoqwnhQ5$R>L@Eh4tK#RouK)8om=!-tC7yjXF3?02}5 zDAhEKTE*?*g|#CYM53{laX*(?KC}1C1NY9br5FqAmshpck+Qj@qeUjhi`ko#P>+>i z_)n^Ac3@eKp{9nlH9UUOPy-y!@u@N@GZnZ!H;wfX25c^wqd45J$9hW?n4;00u+2U#`A7LD# zr2E}E;iOb5J&eD`XLnsgHHWLpD%6f=S>(_dG-}rN@vSX2m~rt{#MjBcFxyP{uTCc#4>3PQ;z%Ub)mN zvZeTIj6=IL>2~o38b%zIQEc=t)cX^5X(?}Ja+r>8vnA72uhR3aAvSDVD&3sV)jqXV zDAZ6vyP=11NX#XK<;`mBnyux`9{!C#8IQ{tZN54w2RCXy!8b@ZHw(1}pHeJ%MSc1z zQOT04{Ed!~&E*zftTOY!pXM^%%>JlKpu=8>YO?rTPP}$;$z9Kj32Rv0rF_DYY`ZdZ z1}v{)tUlk-wDf0G?Oi`e4Zr63U)4G>8#-b|=ta~m5)+BRVM*)u`{hh`y%FsXhcnBs zOtV=$voTYH3i8V;_E#xmux0tGk(d2j_z+-1=Cw!4ZM-}dHy&dp6C4-2o69^>B$9OW zd>){a>rMy-xLe#c`WpnqU672nGpgpjTBT;AnX|+jjjLwbOW0qX=r+;zo*$d}ZZ{;Z z5dga5$;7SafdZ$FQu5Pb5|i`(bPx<(hOeMQkIdbzeN2`OaBB zZbr*{*NA}8esPekdHx^{+OlSj zm!?KNth>ZFH&2*&tYoe&w~D6z;uwsim%Ed3zg#Sa>y=8a0eDf)@vV#5smiX{vPfqJ z+_D-g*y37i+&!ReZ(C}(a#|~C(pZKAjh%&A7Ew%;a6*n;Hu8qgJ z{b6|7v7B9H)e&_7C z4`vj{+>)j7$HbkOIfR8*?B}|~fN1Fz`E8~+?zXXN&`lW|El1_@p=w#Tjt{q{O0CxC zb`sc$8;{a?+Os9Txuqxym!fkCOjSbm)l>Ru;IWLGdz_$_Hu*-#rd$sTDje6W8erf zbj_Fue0bjg1Tt;((iJ~;ld@}gsq2Cp^*wpQk3N|o_Wjr(KmjPCyO@Ju9{Ye_@KmMA z&q>d#d6zn2Ugt)|;@aAo?|<^%wKZ-6;O6f#Ys(bR6Hjtcdw-4v^3U(R+|Nv^QN%SP z?G=ui*AltRz?m5|J9D!6>ii zdB99x+t5e0XZx0O&arELV9WCCnX%$j@oXA+nOHk6E?@cnr>~WfLuPF}DNoAXab^wu z03Yxkth$O8W(efk{#SCDmvj50sH;r?(PuMZyVd7+U69R&{#jQ~ddk`QK+mZ{c|mWrQl4ZPv^7v!yRf_7Ih|E&)ng8&^x+{bjJHKs=C2 z;Y}Y247VQK!ZHlPlhw#qR6`YlbvIZ~o|5(H0S+WBfoxnm2*`%2vB1588qSA~K_=%F zEaMXxk3iG!++h>@s4LGxMu|4|32(*!>G5m)LR3WC4>Cm5{VsNaD37t(Y`5(13uUZJ z11Jz8;&8(SB`aqzd(gm3OasJF%PLH=VS65loa+W3tFyYaQ3I@ip4is|b~3+y=>DeT z6>KHB0jg-&t@5tnf?359o;ibBu?kV~ZkLz1dtcUg@f*+?Ut;fmb%TImGCDbT&&S&vB z;8}WGf=sb^1jtgBbSR^ZGu$6YK%SoIqgIGl zeutPdvV5LKjGeVE!i`un0lpjowA>gW9zta9;N;1Z!{ZNTFIWW}TGDY;J*hVm<-3K( zjT?=pSd{`v%nWSS08aS_OMYSWiQZ_%P`Gqlr?>Mvr@e|NKu!e660|nr(X&3ev|1+wrz&7KzKcl-JUmm=)o*lW^*V(4qb8#-_P1B zhVPL4*s~iqZreVN7!eMK+h7VTf_3?acjC^R6|dN~s#Vme?j?dp`Kp$yC|DKo5pvAx z;!j7H5GxCizr@HED=d?v%S#`v4|ivhnUt1Lx_I411KDNQ&Q6CXhhM^77z4)#=@&4C znGtyP#A^`1E*O5JCgCM(-FzrJbehwfWLPWJ^sl4(Tsd}HAZy9q$_5?WkldGjYnQ8S zZdU5#L-|$)hyyrSA*<=`2MhFZCg3djl5b)h?6;t4NhS7-Fy7eByVN~Gc9_hS@C2Sw zqGZi|;LMfh@h+Pl*5WzhJiHVe75nCA2MaP9rBR0m@qPD6UU6=18{8j{Rc;fp!s7XsUSR3opV~PWO3(e|cy}bg`lT5Qh zEkQl`IZq{?*BBj4(!|Gui1Z3*najuUGAQZd4@>lY!$?xeK`h1gn&_MW<1SuBmT30( zQmA2hsT;4yW@m%s_aoK&NHxnC4;KHC0_G;=@Q|1+_}xX`abBk^R|3O;V|s<{>6E?m z@VNDU%|I$?QjfhG$_;$*I{BHU8mTw4rUS=rQeLteL4&;>P^L?~nlqcRBdkzXM?P8X zPrBOvwjOqnMcv&~NBusbArF!x)Q@rjzY1}8lhbBdOh%$vdxM=7x#=knl?R|iOJO_8 zl-c)}Q1X?bvqHcZc=hLZpYRfQ6NP)ypNY!VB)!0rvbYzi-q?eO@HprNw&8aQ=xqmU zr2r}SqTEu{_GhlMx%|&{lOW-TjT5Ene##DQFp)@U@i5wc1S+mYoMagCX6%USnR~jI zxJ#i)=3dr&^*AP4sN;mNo*G)Vzw^7l<&E6*$vN^o_k;urqd7eJ+%PK{hUF1+afGu0 zB_)E73cgewb(+o+C2q?&{DaE78~8WzLv%&6QJ zASzym+754fT@>)d`D5f1xXewrs*?+mz*2BV1N{Q-*>IfacXqm`aWj>K08;_5)YGH~ zjG^+Znfb;=%UR9Zb!+CY;xe&lYHPOd*b&ul;)c2RP>h>6B+fNY8Nzkz{KslooEdJ& zGFakB&%{_1Sv3xZID#hZ0TZ)q?jd?hN{fT07K!?%J$EV29v{tvicQE$l6nWHY#%7} zq@0+*QzkVK+sfNMPn6waznc>Oa71nu5Vya|l@|)etwhuL2g{Ra#p1&7 zC0WAaStFL*7XQ-4&n(oEwqdoP5p}t3t^Ko9#V^A0Q z$+|l@eO|{($+!?G(Rtx8QCf+C$QrxZU@_Qk98=8o5*~8x8`tA@%<8z66V7d;={R0u zcVAL|p2Q>U@ceal1&fo+|I(%koPw%YUX94B3KZD~YSoylX~jg%SrImiu4A7~LY|sg{Xa7XJ zs+%1+Qv)n&R9;Pj`sumvH}Xq|JQtbqd?-eQSHpp650@miH42hL37TP1PGxB9G(;7g%49tALV7MOQmXzS;knn7*PnCp}8W!f@ruDhUUR4IEcDB%R>*u z?7w{_6GfSEOvj-~jp+49?OL!I*S(6JlA5}`PD!d??2ukw*cl;Ae7h*R9;i*j zl_(zT%Y06B1*5^0lvxk&La zuQVPD!*;hd?w|jHWLR2j5-q<5h9A*i1$MkvJf!c536DWf>br%bWJz!3GCG0c<^( zPSpyAUm!(3s3$eaqp}owsk$XPJu(!IK((jTrkEqpQ~tt5ceHC~G6W9(Db9p=jWodz zK-!?wi}QeX-yUHt`Jh1?+oMn+|5?^*eNW(4Zd4LL6XnDg!H>(2FTYGhTk2y}PXyNC zvy&jjhr1z=+Tv0kojCP+(bsGEZR-h~0b!3FC6AK~1pDZ)5@e~HSa3bfA3O8n3#DpR zfFI>2Vg?3*>*28hCCS6ViZuWe8z7i^lvElETlD7heE|*xrG1!i+SZmNDHU}tE>mgJ zs`vzO$WopvHLwC(+taJy+JoNn`@jtYheUcXpv~afy{y%6LqVcEPQE0ML}bJDvA@W( zp5J>mW5ypja$Yv6nu-Yb(7JCw+6!VkJIKB@yfDbBLAFu>w7J;0K^_!mRso8c zu7n;<-zXo+y)5OODww;v(P@Y4JY_GSX>9DnrL6c#pa_qSF>^>$vW_t~K(j%*Czi-d zIPkSRS(s-T0d;cOM+0Tl!P z!>8B!JxRy9V;Tyy22aOn_(Jh)OOLge=^l|+5KlJrdMwZ!`UjqHJ< zvIZ;|I@WN-uLS9w4oK4NdXAgYK9-^g8EdtjS-#f7S8cS%FHl+zrHaEg;Kx|wB73(m zRMJfWt4={2wBc-9zT^1p+9LLf+SO4TceFu2Gz4;y6?+ng(L_lh2}c4?C4%Txd5)k_ z2Nx|0DlF2P&SpOGlTLl*Q=_I)SH!5|+F16s+iIQHTy!qf+XPCK3AoFS5I**7_Ih@W zWg)d;#cCp-$xvN-y&nynl#2cN!=7Yt#k?hw%dOkznCs z^7VS+rh*(wNUw1j;E1zmV;DT^o&fp9M=9O7Pc`ZR>j3$(N-3bALX@ahv0?VurkDWE z_X!tEc}@BXWr2{Oh2sy#MpU)vgX$*m7*fbs@3)hPFJ?4vOcbv zoWg7H8w$QwSdA+6%y{jYAAMs|s*38-mhWoqP8DP0Z_11>B9!*Sibe*!dc*q8gOhtd7 z!se=fxxiN2hBS3;Y?%6hHOnUJptZ7Ad}i;J&k^U^W9{ij?(BU8+gRccv49$<9`Gb^ z1uCTQv+S%ulhAKmRzpADVZ+chA_uA}w{&}#{Wo3sKl!MGhkAZSqW8{v4SaM!&s@DTF^zvxG z7(f3+gaECAwQuH9Xld`y;~?AuzoBXc52}W$q1Ip{p5J*jj@eM)8om0zvz%Jum+K*36F~kEfN7tO_tYG+Mf{*Fw_dMe+a{Eg7ZD4-d7tt{1A}IzS^3my zMN19rHq0VWlrT_%o-avynjwnxPmyKi>+a5#ci#9>M*MSNtqpu~LKi9@x=R|j$7+EFE(#_L2X-}_OD(ZkNr1wFaYP%CA601=wvVj_ z!>#QV1jQ9sFyt((4t9t?w5`gt3(X$lU?>9lwO!Arw?!{AYh1U!X*IS^PSv_z60Fzn{|SZS9C;OwAFZvOJ*xxI zc|i8lR}|eard7l19{cHbGh-9>u$K0(>;yLc$9`z0|U=X zJ9}MUah0YsSm(kUdj9AViwn)`?KlW&wKxWT4+h3L$OFQ@f>893Weuknttp8O>!$4V zQ9<_TQeHpoo>(RWF4d#|x(xbxQvwaop514C4ZFad?{u_-2d}G-7bsv_E9o5HK_GDJ zqxHB-6$+?@`@4L3At8cAte@XCcA?VI0Hs$IY3x3DZc*_V)q?rlXf^@7)^Gr!fhtc$ zoESmQ&JtD#o@f#R*G>SmOq`g(Cg|t88;2>6o$9$kgOtrv2j*bziYiFpS-mKs;+*Io z8BAlx_v=Sp_H)UM_t454wpd7fWeDO8M$B|Tl= zGr~m(*-Q8Aop|0`DL55$86p9&NY$LrR;2yG!;9asA>D8rb=8mo@qtLxP; zUtc1baY0Qmg_f4`4LbluLC2FS6KgPLejz!$LqI3H)Z8AFDe^4BxuN#eZdxdxQv4+T9%^ShMYBqdpTkb|pGO(YjHv-atgeDiLlnNJV8ZZl|iBSC{Nh@B{ z+4+D?z^&C?RDJ`_X}pw+mXHtutwD`~@&IzTXdY+DS=0e|k-!=lOHr7hY0a5{0IOzn zdWZlT%dAFrt?azPXAO+X^AIe?QBem5xNLwJE@WUhLxTAxPY0&OJL7`LJ{C{wtlD@e zh$={&BFqZ#k-aFnfv!JHWk_fi(4i5dPPIWQbLc6T;VRfLm2SgdN>&poB0KgBJWu8} zScD?p#zO20Tb>oTMLo}{e0tZw@3K@;Pt@1RQt@pl>w*e4>4psGBH>kx!s_A%fofRB zYPK@WI>%?ypD=u~qo9C@ub&C+n_2tKi;cW~Fly%y2fj~PzyTlu(zCmrcmi^^FK))J5AO$zDSwZGL zbZ0>+&8D=EE+Pa!2J6`NIpm3t;ohDxt!0f>>YXdEjn`7DoM7FLl}aJF5*849F|VsF z_|{tnI$#*a>QPar!iit}t(af)1~N)^9ab2!lU-sTNvBgR!wZtD5||C!mDuw1FaGwT z$Ux0VRnUL_hxUn#oVwp6$KZ>Ov9yhejt@zmBnZm@ppwfN!LiSGs?{DC(`kMzp5gf= z#?Q#Kt<@m`z;?cwT~J0~?H{s!is5vk>;BGvc*%DCn}iudovRbZ@J0q)EfPs%1thK1XjdSs z{QA$8t36ayR!)+*E%i24D9B?SkcTOZ4*d+>XR><3INIqLO#_!(!|Dh~A{1mtsHUMi zKl=7WK9$sWYfS@nG|maH`BSg4-DtC2n=60kkH7L;wdsIIbds4-w~%*bRjtA>q0YkX zK|M#2egio>s3xVl$#jIGB`gq?z~Ow<^6{Ppb@&Ir_ycqu1z!o0gJBPK zDzKuOy~|J1zf!4RBkR>WZ+HJWTbZR@Nrr@TAr9O2oMxdqQ1cCzR0)3n?k9hxW;J0X z!nVS7H4XdRAdB#>8f+F18;md?|0-|BFAY~zHaT{B)3^M&eSp$2PifSArXD+8M#%}2Oz1^fk{tU2}$^ovA$A-S^bv|)SLv^?@zvNO*r6A-MMKxN& zAg(Vd{@kaJok=}=hVI%D%piKtFnVZ&vZ-jDRIGd>JKe^eW)V0~N|BAYWJ7;cbQ>Wu z_yziDv`s27Dmq_(`jw+26unkR>BZxR9VJ)C+h;B8tcEDKzW7#p1!78+CCirZp1K9^ zCHeyuRCL8SNA~M9SOHFiLb5eH`OCKkJR8sRrC)sfoyW(XpA>v&RC5q5yzC(Hl9ZV6 zs>h?IJgrYK@!%CgN8+MS(BedockPtt;vwR4oE$=!wga0UF;nIgKf+B5X~S`5U;y}% zlC)0Yt~Fx+oPD5iuwtBJvt)zOM8lY_CTyW&uhNnO`SW?vlZX7Xzj^1NTe0n=U002U z?5w&NP+mih_3kE!47COf2-^3ty)x5^K=`D@u#P+;ozC$2N z*y4f(oT$fs?P(30p~z#h;V1>ZQJn*Z2>y4zddP2Pw{Iu7-K--2NYr6`FLpy@8;agp z7q}gsT|$lHpZ5C6x@S|mrQaJi&^9*pu(CTpm)NxxByX)q>vej8`aL{pJP+O<-2yPB zIM_6OvK_7jjk${+tbk5LG1S|SQYj(BDb<5Fg9J+=An;s#Q5nPYXNNQARauINjK^nh zjI@(r-cwi+uxCl02>!M=uQ}7kqk&xs=mybh=%Qc74SUr#R_ZE*!Nnsy|DT$}?1N&K zwEw+?MW(yn{3=cCxgVW&Qvmp@`~utZ1fT@3CcAzu4dK^)9$?)FysO^DdMY6fHK8~O zoF5v~?SF;$6bH&qZW31;r2d$?IM;1iHQ$ZV2-cMq-yb&`G`5$@IY^k`dhtkp!8maE z`XNA!u*jz;v*b(%D6?YJ0XatDzaC0yO$Fz}{3uB-I=nQ65s#VsiCy0*xZO#{ER*nr zc_>0`{tk*wEM==#(Km0!+O~~zSe=*wB0;UPw^u0SZAo@}&JZ}mj{EhLz*Y5Ulqv#U z>r)ieku9o06De@h!wb~Nw(KjAgE6Xx{-kjTQ$P8PhClV}kEQ-6|D|jb?!7_8a4@W- z09KQA7bU^OIun616 z4lA!A>LetThExGIXx?S2kO5dBnl=)TEXK>G#bE)&S_7v0>?bjcKo2*QCpYYm3tHMH z7O2mR_=!Nd!t9j3aZuYoqBH?YWG2Kd=~O5e6k-2=e&Nh_e~Oot7|)ypPd9vsP=`gZ zt8z!SmoUqZ^uPqU8^$_iz%b~PP57@S4>W^4z4Q8`Lbj1nzRn7ivlH2CeSGU0UK&wuzkKR#_F zJ>WSxk3_EQ7IuLu9>5Vw&_huf^;n@|&Gp$d8{>#+lF}N6x~#)UB+e zUM1Q{k}4vh6JL#OU^JyW3PVyF+F~S27}q0NEm1V9f*vR|_2TGEhNdui=8oH8Y6CX? z{?gGdv6U4b`|*!|_(g0M+Gje-GY3(hukgfNA&}++kcE})gO$w1JPHU0h1dJy@}*^H zlrJwAVRWeJi^*&?Onn!>2yU@_EQFei- zPvwo?oDg(*ZVbX^Zp!xcYIod6dh$Ugey|NzTYUO^k88`z87#kX@Wiq1j~SaPvp_q+ z3ggai{^sBQ+JE+Rtc1Xk1hbL9X|rQnH9 z7bumNtCCT7V&*4)mMN6dTMxl5YK>ve=S*+?B!orW@3Udj|Z+W8c>G%qp}YUB{beh zyiO+`_0&AEdnnC;orPM_-pO<)(lY14DIRNA+9h~)4E0hAHlwd!qTZN;rb_=xr*<~S z1MibKPtM|dZ~QNCM-~v(`4qiApvSp94WRWr1dcAe^(EmZjlb~t^4_y+dkK0=5>q6F-X07eyfrio94G3>mkeWf z@x&UYAa>#;RnrGbfw_Ds8O}NEF-wD?<);FfK;3)hZ{&xRYZd8aGi`GJd$04Eeng+n%QF@7u#DImZXHJ+pWr-A};Bt0b z{RggmA)*gR=lj%;A3-QFP8$`36wKTqWzxVpKAS23)BhT{3>mb>u9zBr6z2(@fms_F zrC~n1D7!x4>M}eJg?oIA5maJDL(Ix6I6mo+K{$gsM@U*RDgY8MNPB?0Kqiyvxj}G- zRE5Ss`gc2UC*Tt2a{VfOVVrAEufh`#nJblXnM@pyC$x98dSF~ojihrX>5(}|kTaRx zf-1lw7@p#rh*4&@axXBtG^W67?mxj!A7N5X$gu~Y`{6jLQmr)J*(9)8D?XJ-?*NrA z3dB7d`w1g$e^_ELG*cDzVC+hUIQS7RICN|b`w$Yuz1Cg!2i_)IpJU|hSj708E{{m! zO!luRVY)~RONR~0pp9ssj14g*EOLX5!`4b@L6}GQt=?fJ%H9@Yvv2>G*B_Kqt~)u1kx0l#{7zr+_Qy&w`HCqf(zB(xI1>OkgQxrJO^#NVz3gKRhXv5tu}yCE68T z7KqPkXS9;ZL}fpB=9A;H@S=EI{luX(1zDsp(}RRQIyIq9Iz%!&b8LBeje%vvH(|_& z*(oNg8O<(2077w!t>q%K)}rY+Krj)_LGqC75OmJBMROPlvh5;AQWbzJ9R)L9qQ6*W zyh;v&=#=p|NPs>dJEG~CE5-8<9DD2ynd!-J*hMbC`TQoMY3I+*twIIHBgN0T?dlsW z9o(|E_6v_d=tiH%*vVqJE7K>CM{A6yVbJ|n@dXsUB#7*sZ4B%rrNoq{cn`Nh_7~2* z0u=)7kRAED$IhTz%%z1L23q++ix^oGOEIAqnXlxEx#dUx&9jU&p3j&v4oPJ^@$R2F zA(;aMsDMe8>h%#_8th)oIFot#*|W&5|NZYWxhGb9$}GJ|j68w^#0$ZBI0a~wQ4YoI zV2_=}>04|j#YcPe>tHVB&!q%mD3~-*<};e`FeBvFj=sS@v$paP_9Oz2*V&HcN7@>( zVDDOn`OhPxG-&+O{-^)#RjG>;?;N8bTwA#eGyJSaYd!PEwSIB@G|{c95p~6U9*Y=r zFqx@>d=ugXy%mtRoiyrSDv(r3HExxRmPD98Y9$bi3Rxn@W?;T_%A}czg~CXvhMY)( zE#%r=4og{P+d#0Hy~VX(;IIDjvwO#<xLeg^i z49KJ^V?Hgy9JBKrJL=}~1=a3M^+QWJxnoM3s&U)Z}WW5UdBGSXT+kJjPTA)|9u=!bR4Wu4BU{0@Br z$-$9X@+dYk7>+inWU^wi5#AgL_J*&F>}6;i1`zYK1jz1JQ%1IWdK>FPkr zrCSX*ZxoDr3OzkH9hoKo?W)}N`t>(L-eP!eJ>A|q3# zg4qGAagmvHuo39!rD~^RLXH4#@6cykB-Gd%Skj&Mdhuw^Y$vU8cX{tMnIzr2eEzl8 zTILAg`#b3Ea*IZ_>A^OFx4_QoFzabQAJRvma{+C;|9Jn?cc1;r56@DXuz>mxouqc) z_K>5j@1p#TGEy+eW(?AkI7Dh6|-m^@cB6(N6;U4@VEYNsl&!CpGI$7td1WR}! z1T0X9e&&HQ4?K?GUgQ)44%}(|Ea!4)N4iXXnHms}CL**1`mpt&@w}9+>(Zl8fBwDi z{@~uP{<}~A>TgqG<@|~v70N-QS7+2N%5-xkgH3>$wjObYiOE0(T!t!~IiZ1rRu&C< z=r_>g;7(I43n;%zAV=+BtqdvpGRst}H})DRms0 z;CLd6S*5_P155+jAWD5=-~F@C{NR}%{^0KBK$s6ml%lE)&6OAdU4*g*IhJ;cXB2gu zFtgKU*&Nx!NhHXTxTk3)l0q1CBM3Zh9%0d8mI66+Xq0&%1v|K;NBW{`IYy68K=5yC zoN>a8D=_8+e!&%w)=L;UXXuR@`-=M{w5y+?oA|_QpMK_#Ui(n`LnSZPHz4Yok?w{QW@kZL3B6Sc zJUVrlMgNKMM9N~8RgWX^FZ!5A_m(r4mqtz3UUCkT=9!d;;KN#PBZleKOQ zpIel1E9AT1{=@Heb~=A~V*Z(A=lNumdhn5j_sbq=r5MqffW9gY54bP3Qr0Ig67@|s`5+}k z@DX<0FCGD2;Ze_;8=N%5R}v79L#-dC0ZIy0Fd-pAwF5j0H5V@}c$IHIW(oo^1dS7f zM9SFA=;ci2QcGhJgVLI5G6qqgl8Eio{(@%*pY^2m@m`M#gp|QoM#nhk>Z?zBPln~* zs06el`_;qTk(>-!pomqi#festNy6}jvy0;|fcO0zvx((gb#iIb_FI|j0aKCo(eNd@ z^2}h({j+D?SG~fh!A$G{OC3(x3#6APgw|9Cwkx@&$<#uXQx`nvz;DySl2(e5%;|hd zNk|wRq~pv)T&*2&KK`kt5FsY_$9`|PGg8Mm@J<&kXYPFS;*eUd&3 z9`V3AvX7YK3P?HXZU;yOm>A(o1XZ-b;b-<BMq6qJ zW*XEFimBqTafvv@juhQ-J+uV)mRno?8(g*&M)+!S%og$oCC+Vby;qRjv*0d@@q=pMNJ5cW=()1BQ)Aj@8afHjzI>#J5 zlhmqta`>&cp8M8we>W7u;-xRjv=fw{RNIk?mMzT%up@_lmB1N z)e~%NW3JTK&Pk(i0Eb~vKxHX?KDa&1J~SNQNIx|S`~#~@LAyP+3nOA0e+j-ZfwPml zL>YRLSu*S{zWWsjsz5^yS2T4f5>5lblq%F?C-~7X zy#6=8=Z+337&6ccgw94LDco*Y7_h0h?_sMpbY z<$o-{$+3!{tA&`e-~1-Kj$^De8fm@M&Sg+Hj<{s_g&#N`PBl7G-=^oq=onX~d%}}( z&d8%FZi|*H8V2Pg$meZi)Cn6@?vB3yx4-s3f~6|-TWXtFIV|0T?V+(q?nsr2b!4+m zfGA&6wa-WyRLmZqT1~w`7ncpjbodPo2g^9Vz5P~mdUE+0cPCY!`N>ay=`Vhpt!XrR9&TtC zJY2J(q+Ko4639nTTT^ zjUbfaZXpA4w&E7hmA&OC*MT83i|CS&61SXBjc!7X0E6tlz_K z0*ZCzjTmHYj^-9{URRs;zp^YD8VpajDanE9OL$R7_;B$3Z`hT~jS8ou?ej4yY`*S$ zvj?q*vIcx&VlUT1h%^~|=o(E3+7?ZH_V*(%0~?OwMDh|ov}RlTIEIwX+6^P%A5}%1 zU`)~C^SB{OU6n#ge5NkU;ZMLOk6}7!@^X5IsuUIni;}{SPeGX1mfK8HVK`fyU%;AR zrJ`b2ao|iEY$KlRVBj1lI^G=kg-W64JK5W?FRWo>fmjR96z(0SjZeofd90n97G>7L zfy6T!vSXh?f!s$dxlFsSHZ7fSk9~ zvt{NE-~ifZ)CB?7Xm#vjS>9E8PC`9^_%fwTO4#OfMoGuPF$)-o#~b}ML0#%?1fT|< zk+;Exrvpy%>~Ug6o1PMzHHK~B8wGTQVj=Z^EFQCfQZgq@5f6Aq)E@XmhAI`k94B|~ zeV`a^aP;oN-`jQQ?G)PJzGx6;hrRTL_q&Kp$q!DZCmF2e68J zq=Hi%lY&z$kdu;1`Stom3Zg_KpPG#f|BxKp(sVvpKGqMIVhq%PCM_M+!L0{R3Z=-q z2&YKSG(dR{?;QQam$5w(D0rox!n`0gh@?lm2$cWzfI`i{A(LPR*c+8nVjpHC6e2F= z7kbcY_z^d+DmBMbd`XVyI`vq-{;{VjHnX(;o{C=I!;!;acR^E?ah9{2;-$TSDMcBaKN#Pg#(~j6J&gIqxV1f_0@N4YUsJ9t-oH2`! zs-O%5XO^T-9zB!@@7s7%9tlUOteeoG*)2$35Png_fEotP=vJ=Hq`lsG7``@x+l&gj z!R7TBDghJ8g?&O^HCB3u4<35^acwR~9@27irs`(Uq}#z`BSmOq_^yi=!7AKs`y`#x z8BjrdHPFKFlNI43S2%W8=E31nJF}I=})@Hp?5mt3{`!99oID07EbAO~@qxHkZ}cdqjp6fo6k%<_ zP6oRpXHg?3*jR_;Te%F;XpeAJ8+7kLI8-4>7uuzzu&zfOhI(`fmU(s3-6)-k9$s$* zOg})vPCl`@@_NrV>?fE%U{4)Ctucrd;ENlaJ(Q}!Tf?EU9^&MeIRM=HCdQ5%v$Ct( zRwM1OrI;I)b5fZaI~_o~lxkPDP?2FjG~Kb|QvKq(eYtWm;IsrY-c?jH!PsO{n)U!n zXzE8vRyQ7w_Je@rDA{~;s_x>;@&A=4s(E!$k`h=wjE^^m^`pC(3g;DEfOJ$Rf|3hR zEjJpY^h*Wkzsdow4y_85Sfg=t(_kn^Tu-Hvkb)(ITZ;Vn2g|rv;|SVyy~ilvy1Nln zDo;^|rVic@%!m`0=|HePN)6g;r1kWAOC3(B)~@4k^5~-rH(I(I4uFzSOk^ly*fry7`znrKcK~0j2rUDQaF_^NVtnGRFdzv|~TKat#K@(G8AL z#A3``TjnO^JS&MqNq8tdv`N2-FNf2MRdVRo-{H-+oz+!VnO%ns!zMG&6jqtf)wKzu zikA@@{S~UMMhb1+$btbvd+75mRP) z3_6h9Dr&v)^H=V0!a4JJ^f0w(nd)X9x)t_Sn0xgTCTFNTAE=K}b$}D^+v!b?>lv_# zLJcDY67FIpdN?0(47`3=YvG^PnSF)&fRz)LNJ9%#R0F)ge2>r-NIYP(fSx$6kwQxa%PsynVdpLjmqtiwOU39c(fAkDTvhon}PfAa@rTkOwWvGp+))-Ygk1e<3 z#+NyZ6W|Z2C$8HD$cpJQVD$mUq8{c<_6B9EhnGwa_xZ#n_*6l;R2u0c7!{ncr!F_i zO&(&-Yym{;$)iW3$K<>`?iNw}D{)|q9zKjue(I?@y0tXo$oFNii=5L+x#KI zNTDhYp29Vq{8hV4b6y(DYpwo^ zFTQwIJ5nlLx$^8k(du~)Ou&4h9kjmiG>vC^;|Q8@BgD5ve|oXtewU+Z^-5N%1IcH# zd^mDAaUl7ye-;BFjhy;0@5ut2*;V-YL|miv@X_;l&Z;zGPU(r>rg>7;8O_PwG6u&n zriX@vG9kIGlDO6a&e4?eqcx8h4@_A1FVjsQ3hYug^9E?9ZI`PS;3F&HZ>-bxK5AHTV-MEp>K6F9O zuPrS}7lxgoCniV7U+I^1Sh~bC)DP+`gbc{y%w6O3;(GK7-O>qN=_9P~(xqtWF-<@E zolibHdBp^qE~tkSzDs`$cRi6lK5T|1_mspvUL*MF0aIZZgwMd<(W6nBxx3N6EvGs_{=x_FOZ!Z@a?jy}fVXqT&nX-D2F06D5lFq;X zyk@p8Mdl?r6+6mpn8Z^8ZSMQO5i$FlXCG)#X#Afyz?zW|3=fGYEcFmMHj8tgg)A28 zjp;VXp2L9ahx4D+{oCI>3GDOKU(Z!`*S1$zsTwk%OA!D}ORufEREFJz2=i-?EtQTv r!WsMWf4xE2%Bthcfm1eozTN*BH~25V`}kPe4W~+4vCAT&XzBk40w4U` literal 0 HcmV?d00001 diff --git a/apps/tests/wm_erasebkgnd/Demo_WM_ERASEBKGND.cpp b/apps/tests/wm_erasebkgnd/Demo_WM_ERASEBKGND.cpp new file mode 100644 index 0000000..582673f --- /dev/null +++ b/apps/tests/wm_erasebkgnd/Demo_WM_ERASEBKGND.cpp @@ -0,0 +1,175 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 2 - CD-ROM (WM_ERASEBKGND Demo) +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + +//*********************************************************// +// // +// SYNOPSIS: // +// This sample project demonstrates how to render // +// a background image in response to the WM_ERASEBKGND // +// message. It also shows how to create a transparent // +// static (text) control by handling the // +// WM_CTLCOLORSTATIC message. // +// // +//*********************************************************// + + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +HINSTANCE HInst; +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, + LPTSTR lpCmdLine, int nCmdShow) +{ + HInst = HInstance; + + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = HInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = + reinterpret_cast(COLOR_BTNFACE + 1); + wc.lpszClassName = WndClassName; + + if (RegisterClass(&wc)) + { + HWND HWnd = + CreateWindow(WndClassName, + TEXT("WM_ERASEBKGND Demo"), + WS_OVERLAPPEDWINDOW | WS_CAPTION | + WS_VISIBLE | WS_CLIPSIBLINGS, + CW_USEDEFAULT, CW_USEDEFAULT, 205, 85, + NULL, NULL, HInstance, NULL); + + if (HWnd) + { + ShowWindow(HWnd, nCmdShow); + UpdateWindow(HWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} +//------------------------------------------------------------------ + + +// static text and bitmap-related variables +HWND HStatic; +HDC HMemDC; +HBITMAP HBmp, HOldBmp; +const char* filename = "BACKBITMAP.BMP"; + +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam) +{ + switch (Msg) + { + case WM_CREATE: + { + HStatic = + CreateWindow(TEXT("STATIC"), TEXT("Static Text"), + WS_CHILD | WS_VISIBLE | SS_CENTER, + 10, 20, 175, 30, + HWnd, NULL, HInst, NULL); + + // create a memory DC compatible with the screen + HMemDC = CreateCompatibleDC(NULL); + if (HMemDC) + { + // load a DDB from file + HBmp = static_cast( + LoadImage(HInst, filename, IMAGE_BITMAP, + 0, 0, LR_LOADFROMFILE) + ); + if (HBmp) + { + // associate the DDB with the memory DC + HOldBmp = static_cast( + SelectObject(HMemDC, HBmp) + ); + } + } + } + case WM_CTLCOLORSTATIC: + { + if (reinterpret_cast(LParam) == HStatic) + { + HDC HStaticDC = reinterpret_cast(WParam); + SetBkMode(HStaticDC, TRANSPARENT); + + return reinterpret_cast( + GetStockObject(NULL_BRUSH) + ); + } + break; + } + case WM_ERASEBKGND: + { + BITMAP bmp; + if (GetObject(HBmp, sizeof(BITMAP), &bmp)) + { + RECT RClient; + GetClientRect(HWnd, &RClient); + + HDC Hdc = reinterpret_cast(WParam); + SetStretchBltMode(Hdc, COLORONCOLOR); + + // + // TODO: add palette handling code for + // palettized displays (see Chapter 9)... + // + + // render the background image + StretchBlt(Hdc, 0, 0, + RClient.right - RClient.left, + RClient.bottom - RClient.top, + HMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, + SRCCOPY); + return TRUE; + } + break; + } + case WM_DESTROY: + { + if (HBmp) + { + // free the bitmap + DeleteObject(SelectObject(HMemDC, HOldBmp)); + } + // free the memory DC + DeleteDC(HMemDC); + + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(HWnd, Msg, WParam, LParam); +} +//------------------------------------------------------------------ + + + diff --git a/apps/tests/wm_erasebkgnd/makefile b/apps/tests/wm_erasebkgnd/makefile new file mode 100644 index 0000000..5c6818c --- /dev/null +++ b/apps/tests/wm_erasebkgnd/makefile @@ -0,0 +1,66 @@ +# Makefile - Proj_Demo_WM_ERASEBKGND.dsp + +ifndef CFG +CFG=Proj_Demo_WM_ERASEBKGND - Win32 Debug +endif +CC=gcc +CFLAGS= +CXX=g++ +CXXFLAGS=$(CFLAGS) +RC=windres -O COFF +ifeq "$(CFG)" "Proj_Demo_WM_ERASEBKGND - Win32 Release" +CFLAGS+=-fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -W +LD=$(CXX) $(CXXFLAGS) +LDFLAGS= +LDFLAGS+=-Wl,--subsystem,windows +LIBS+=-lkernel32 -luser32 -lgdi32 +else +ifeq "$(CFG)" "Proj_Demo_WM_ERASEBKGND - Win32 Debug" +CFLAGS+=-fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W +LD=$(CXX) $(CXXFLAGS) +LDFLAGS= +LDFLAGS+=-Wl,--subsystem,windows +LIBS+=-lkernel32 -luser32 -lgdi32 +endif +endif + +ifndef TARGET +TARGET=WM_ERASEBKGND.exe +endif + +.PHONY: all +all: $(TARGET) + +%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< + +%.o: %.cpp + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $< + +%.res: %.rc + $(RC) $(CPPFLAGS) -o $@ -i $< + +SOURCE_FILES= \ + Demo_WM_ERASEBKGND.cpp + +HEADER_FILES= + +RESOURCE_FILES= + +SRCS=$(SOURCE_FILES) $(HEADER_FILES) $(RESOURCE_FILES) + +OBJS=$(patsubst %.rc,%.res,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(filter %.c %.cpp %.rc,$(SRCS))))) + +$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +.PHONY: clean +clean: + del $(OBJS) $(TARGET) Proj_Demo_WM_ERASEBKGND.dep + +.PHONY: depends +depends: + -$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $(filter %.c %.cpp,$(SRCS)) > Proj_Demo_WM_ERASEBKGND.dep + +-include Proj_Demo_WM_ERASEBKGND.dep + diff --git a/apps/tests/wm_paint/Listing1_1.cpp b/apps/tests/wm_paint/Listing1_1.cpp deleted file mode 100644 index 00bb7ad..0000000 --- a/apps/tests/wm_paint/Listing1_1.cpp +++ /dev/null @@ -1,129 +0,0 @@ - -// ------------------------------------------------------------------ -// Windows 2000 Graphics API Black Book -// Chapter 1 - Listing 1.1 (WM_PAINT Demo) -// -// Created by Damon Chandler -// Updates can be downloaded at: -// -// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu -// if you have any questions about this code. -// ------------------------------------------------------------------ - - -//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -#include -//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - - -const char* WndClassName = "GMainWnd"; -LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, - LPARAM LParam); - - -int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, - LPTSTR lpCmdLine, int nCmdShow) -{ - WNDCLASS wc; - memset(&wc, 0, sizeof(WNDCLASS)); - - wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; - wc.lpfnWndProc = MainWndProc; - wc.hInstance = HInstance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = - reinterpret_cast(COLOR_BTNFACE + 1); - wc.lpszClassName = WndClassName; - - if (RegisterClass(&wc)) - { - HWND HWnd = - CreateWindow(WndClassName, TEXT("WM_PAINT Demo"), - WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, 200, 150, - NULL, NULL, HInstance, NULL); - - if (HWnd) - { - ShowWindow(HWnd, nCmdShow); - UpdateWindow(HWnd); - - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } - return 0; -} -//------------------------------------------------------------------ - - -LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, - LPARAM LParam) -{ - switch (Msg) - { - case WM_PAINT: - { - // determine the invalidated area of the window - RECT RUpdate; - GetUpdateRect(HWnd, &RUpdate, false); - - // grab a handle to our window's - // common display device context - HDC Hdc = GetDC(HWnd); -#if 0 - try -#endif - { - RECT RClient; - GetClientRect(HWnd, &RClient); - - // set the clipping region - IntersectClipRect(Hdc, RUpdate.left, RUpdate.top, - RUpdate.right, RUpdate.bottom); - - // fill the client area with the background brush - HBRUSH HBrush = - reinterpret_cast( - GetClassLong(HWnd, GCL_HBRBACKGROUND) - ); - FillRect(Hdc, &RClient, HBrush); - - // render the persistent text - const char* text = "Persistent Text"; - SetTextColor(Hdc, PALETTERGB(0, 0, 255)); - DrawText(Hdc, text, strlen(text), &RClient, - DT_CENTER | DT_VCENTER | DT_SINGLELINE); - } -#if 0 - catch (...) -#endif - { - // release the device context - ReleaseDC(HWnd, Hdc); - - // validate the update area - ValidateRect(HWnd, &RUpdate); - } - // release the device context - ReleaseDC(HWnd, Hdc); - - // validate the update area - ValidateRect(HWnd, &RUpdate); - - break; - } - case WM_DESTROY: - { - PostQuitMessage(0); - return 0; - } - } - return DefWindowProc(HWnd, Msg, WParam, LParam); -} -//------------------------------------------------------------------ - diff --git a/apps/tests/wm_paint/makefile b/apps/tests/wm_paint/makefile index c606328..9fccf77 100644 --- a/apps/tests/wm_paint/makefile +++ b/apps/tests/wm_paint/makefile @@ -1,66 +1,20 @@ -# Makefile - Proj_Listing1_1.dsp -ifndef CFG -CFG=Proj_Listing1_1 - Win32 Debug -endif -CC=gcc -CFLAGS= -CXX=g++ -CXXFLAGS=$(CFLAGS) -RC=windres -O COFF -ifeq "$(CFG)" "Proj_Listing1_1 - Win32 Release" -CFLAGS+=-fexceptions -O2 -DWIN32 -DNDEBUG -D_WINDOWS -D_MBCS -W -LD=$(CXX) $(CXXFLAGS) -LDFLAGS= -LDFLAGS+=-Wl,--subsystem,windows -LIBS+=-lkernel32 -luser32 -lgdi32 -else -ifeq "$(CFG)" "Proj_Listing1_1 - Win32 Debug" -CFLAGS+=-fexceptions -g -O0 -DWIN32 -D_DEBUG -D_WINDOWS -D_MBCS -W -LD=$(CXX) $(CXXFLAGS) -LDFLAGS= -LDFLAGS+=-Wl,--subsystem,windows -LIBS+=-lkernel32 -luser32 -lgdi32 -endif -endif +PATH_TO_TOP = ../../.. -ifndef TARGET -TARGET=WM_PAINT.exe -endif +TARGET_NORC = yes -.PHONY: all -all: $(TARGET) +TARGET_TYPE = program -%.o: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< +TARGET_APPTYPE = windows -%.o: %.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ -c $< +TARGET_NAME = wm_paint -%.res: %.rc - $(RC) $(CPPFLAGS) -o $@ -i $< +TARGET_SDKLIBS = kernel32.a gdi32.a -SOURCE_FILES= \ - Listing1_1.cpp +TARGET_OBJECTS = $(TARGET_NAME).o -HEADER_FILES= +include $(PATH_TO_TOP)/rules.mak -RESOURCE_FILES= - -SRCS=$(SOURCE_FILES) $(HEADER_FILES) $(RESOURCE_FILES) - -OBJS=$(patsubst %.rc,%.res,$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(filter %.c %.cpp %.rc,$(SRCS))))) - -$(TARGET): $(OBJS) - $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) - -.PHONY: clean -clean: - -del $(OBJS) $(TARGET) - -.PHONY: depends -depends: - -$(CXX) $(CXXFLAGS) $(CPPFLAGS) -MM $(filter %.c %.cpp,$(SRCS)) > Proj_Listing1_1.dep - --include Proj_Listing1_1.dep +include $(TOOLS_PATH)/helper.mk +# EOF diff --git a/apps/tests/wm_paint/wm_paint.c b/apps/tests/wm_paint/wm_paint.c new file mode 100644 index 0000000..d0d035d --- /dev/null +++ b/apps/tests/wm_paint/wm_paint.c @@ -0,0 +1,128 @@ + +// ------------------------------------------------------------------ +// Windows 2000 Graphics API Black Book +// Chapter 1 - Listing 1.1 (WM_PAINT Demo) +// +// Created by Damon Chandler +// Updates can be downloaded at: +// +// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu +// if you have any questions about this code. +// ------------------------------------------------------------------ + + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#include +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + +const char* WndClassName = "GMainWnd"; +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam); + + +int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, + LPTSTR lpCmdLine, int nCmdShow) +{ + WNDCLASS wc; + memset(&wc, 0, sizeof(WNDCLASS)); + + wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = MainWndProc; + wc.hInstance = HInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszClassName = WndClassName; + + if (RegisterClass(&wc)) + { + HWND HWnd = + CreateWindow(WndClassName, TEXT("WM_PAINT Demo"), + WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, 200, 150, + NULL, NULL, HInstance, NULL); + + if (HWnd) + { + ShowWindow(HWnd, nCmdShow); + UpdateWindow(HWnd); + + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + return 0; +} +//------------------------------------------------------------------ + + +LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, + LPARAM LParam) +{ + switch (Msg) + { + case WM_PAINT: + { + // determine the invalidated area of the window + RECT RUpdate; + GetUpdateRect(HWnd, &RUpdate, NULL); + + // grab a handle to our window's + // common display device context + HDC Hdc = GetDC(HWnd); +#if 0 + try +#endif + { + RECT RClient; + GetClientRect(HWnd, &RClient); + + // set the clipping region + IntersectClipRect(Hdc, RUpdate.left, RUpdate.top, + RUpdate.right, RUpdate.bottom); + + // fill the client area with the background brush + //HBRUSH HBrush = + //reinterpret_cast + (HBRUSH)(GetClassLong(HWnd, GCL_HBRBACKGROUND) + ); + FillRect(Hdc, &RClient, NULL); + + // render the persistent text + const char* text = "Persistent Text"; + SetTextColor(Hdc, PALETTERGB(0, 0, 255)); + DrawText(Hdc, text, strlen(text), &RClient, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + } +#if 0 + catch (...) +#endif + { + // release the device context + ReleaseDC(HWnd, Hdc); + + // validate the update area + ValidateRect(HWnd, &RUpdate); + } + // release the device context + ReleaseDC(HWnd, Hdc); + + // validate the update area + ValidateRect(HWnd, &RUpdate); + + break; + } + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + } + return DefWindowProc(HWnd, Msg, WParam, LParam); +} +//------------------------------------------------------------------ + diff --git a/apps/testsets/Makefile b/apps/testsets/Makefile index 8aaf049..c8cdd48 100644 --- a/apps/testsets/Makefile +++ b/apps/testsets/Makefile @@ -59,19 +59,19 @@ dist: $(TEST_SETS:%=%_dist) \ # Testset Applications # $(TEST_SETS): %: - make -C $* + $(MAKE) -C $* $(TEST_SETS:%=%_implib): %_implib: - make -C $* implib + $(MAKE) -C $* implib $(TEST_SETS:%=%_clean): %_clean: - make -C $* clean + $(MAKE) -C $* clean $(TEST_SETS:%=%_dist): %_dist: - make -C $* dist + $(MAKE) -C $* dist $(TEST_SETS:%=%_install): %_install: - make -C $* install + $(MAKE) -C $* install .PHONY: $(TEST_SETS) $(TEST_SETS:%=%_implib) $(TEST_SETS:%=%_clean) $(TEST_SETS:%=%_install) $(TEST_SETS:%=%_dist) @@ -80,19 +80,19 @@ $(TEST_SETS:%=%_install): %_install: # Kernel32 Test Applications # $(TEST_KERNEL32): %: - make -C kernel32/$* + $(MAKE) -C kernel32/$* $(TEST_KERNEL32:%=%_implib): %_implib: - make -C kernel32/$* implib + $(MAKE) -C kernel32/$* implib $(TEST_KERNEL32:%=%_clean): %_clean: - make -C kernel32/$* clean + $(MAKE) -C kernel32/$* clean $(TEST_KERNEL32:%=%_dist): %_dist: - make -C kernel32/$* dist + $(MAKE) -C kernel32/$* dist $(TEST_KERNEL32:%=%_install): %_install: - make -C kernel32/$* install + $(MAKE) -C kernel32/$* install .PHONY: $(TEST_KERNEL32) $(TEST_KERNEL32:%=%_implib) $(TEST_KERNEL32:%=%_clean) $(TEST_KERNEL32:%=%_install) $(TEST_KERNEL32:%=%_dist) @@ -101,19 +101,19 @@ $(TEST_KERNEL32:%=%_install): %_install: # msvcrt Test Applications # $(TEST_MSVCRT): %: - make -C msvcrt/$* + $(MAKE) -C msvcrt/$* $(TEST_MSVCRT:%=%_implib): %_implib: - make -C msvcrt/$* implib + $(MAKE) -C msvcrt/$* implib $(TEST_MSVCRT:%=%_clean): %_clean: - make -C msvcrt/$* clean + $(MAKE) -C msvcrt/$* clean $(TEST_MSVCRT:%=%_dist): %_dist: - make -C msvcrt/$* dist + $(MAKE) -C msvcrt/$* dist $(TEST_MSVCRT:%=%_install): %_install: - make -C msvcrt/$* install + $(MAKE) -C msvcrt/$* install .PHONY: $(TEST_MSVCRT) $(TEST_MSVCRT:%=%_implib) $(TEST_MSVCRT:%=%_clean) $(TEST_MSVCRT:%=%_install) $(TEST_MSVCRT:%=%_dist) @@ -122,19 +122,19 @@ $(TEST_MSVCRT:%=%_install): %_install: # COM Test Applications # $(TEST_COM): %: - make -C com/$* + $(MAKE) -C com/$* $(TEST_COM:%=%_implib): %_implib: - make -C com/$* implib + $(MAKE) -C com/$* implib $(TEST_COM:%=%_clean): %_clean: - make -C com/$* clean + $(MAKE) -C com/$* clean $(TEST_COM:%=%_dist): %_dist: - make -C com/$* dist + $(MAKE) -C com/$* dist $(TEST_COM:%=%_install): %_install: - make -C com/$* install + $(MAKE) -C com/$* install .PHONY: $(TEST_COM) $(TEST_COM:%=%_implib) $(TEST_COM:%=%_clean) $(TEST_COM:%=%_install) $(TEST_COM:%=%_dist) @@ -143,19 +143,19 @@ $(TEST_COM:%=%_install): %_install: # SEH Test Applications # $(TEST_SEH): %: - make -C seh/$* + $(MAKE) -C seh/$* $(TEST_SEH:%=%_implib): %_implib: - make -C seh/$* implib + $(MAKE) -C seh/$* implib $(TEST_SEH:%=%_clean): %_clean: - make -C seh/$* clean + $(MAKE) -C seh/$* clean $(TEST_SEH:%=%_dist): %_dist: - make -C seh/$* dist + $(MAKE) -C seh/$* dist $(TEST_SEH:%=%_install): %_install: - make -C seh/$* install + $(MAKE) -C seh/$* install .PHONY: $(TEST_SEH) $(TEST_SEH:%=%_implib) $(TEST_SEH:%=%_clean) $(TEST_SEH:%=%_install) $(TEST_SEH:%=%_dist) @@ -164,19 +164,19 @@ $(TEST_SEH:%=%_install): %_install: # Regression Test Applications # $(TEST_REGRESSIONS): %: - make -C regres/$* + $(MAKE) -C regres/$* $(TEST_REGRESSIONS:%=%_implib): %_implib: - make -C regres/$* implib + $(MAKE) -C regres/$* implib $(TEST_REGRESSIONS:%=%_clean): %_clean: - make -C regres/$* clean + $(MAKE) -C regres/$* clean $(TEST_REGRESSIONS:%=%_dist): %_dist: - make -C regres/$* dist + $(MAKE) -C regres/$* dist $(TEST_REGRESSIONS:%=%_install): %_install: - make -C regres/$* install + $(MAKE) -C regres/$* install .PHONY: $(TEST_REGRESSIONS) $(TEST_REGRESSIONS:%=%_implib) $(TEST_REGRESSIONS:%=%_clean) $(TEST_REGRESSIONS:%=%_install) $(TEST_REGRESSIONS:%=%_dist) diff --git a/apps/utils/Makefile b/apps/utils/Makefile index a9b1033..6d83f56 100644 --- a/apps/utils/Makefile +++ b/apps/utils/Makefile @@ -37,19 +37,19 @@ dist: $(UTIL_APPS:%=%_dist) \ # Utility Applications # $(UTIL_APPS): %: - make -C $* + $(MAKE) -C $* $(UTIL_APPS:%=%_implib): %_implib: - make -C $* implib + $(MAKE) -C $* implib $(UTIL_APPS:%=%_clean): %_clean: - make -C $* clean + $(MAKE) -C $* clean $(UTIL_APPS:%=%_dist): %_dist: - make -C $* dist + $(MAKE) -C $* dist $(UTIL_APPS:%=%_install): %_install: - make -C $* install + $(MAKE) -C $* install .PHONY: $(UTIL_APPS) $(UTIL_APPS:%=%_implib) $(UTIL_APPS:%=%_clean) $(UTIL_APPS:%=%_install) $(UTIL_APPS:%=%_dist) @@ -58,19 +58,19 @@ $(UTIL_APPS:%=%_install): %_install: # GUI Utility Applications # $(UTIL_NET_APPS): %: - make -C net/$* + $(MAKE) -C net/$* $(UTIL_NET_APPS:%=%_implib): %_implib: - make -C net/$* implib + $(MAKE) -C net/$* implib $(UTIL_NET_APPS:%=%_clean): %_clean: - make -C net/$* clean + $(MAKE) -C net/$* clean $(UTIL_NET_APPS:%=%_dist): %_dist: - make -C net/$* dist + $(MAKE) -C net/$* dist $(UTIL_NET_APPS:%=%_install): %_install: - make -C net/$* install + $(MAKE) -C net/$* install .PHONY: $(UTIL_NET_APPS) $(UTIL_NET_APPS:%=%_implib) $(UTIL_NET_APPS:%=%_clean) $(UTIL_NET_APPS:%=%_install) $(UTIL_NET_APPS:%=%_dist) diff --git a/apps/utils/cabman/main.cpp b/apps/utils/cabman/main.cpp index d269f62..055926e 100644 --- a/apps/utils/cabman/main.cpp +++ b/apps/utils/cabman/main.cpp @@ -474,7 +474,7 @@ VOID CCABManager::OnAdd(PCFFILE File, } -INT main(INT argc, PCHAR argv[]) +int main(int argc, char * argv[]) /* * FUNCTION: Main entry point * ARGUMENTS: diff --git a/apps/utils/cabman/makefile b/apps/utils/cabman/makefile index eda0930..52284cb 100644 --- a/apps/utils/cabman/makefile +++ b/apps/utils/cabman/makefile @@ -1,64 +1,26 @@ -# -# Makefile for ReactOS Cabinet Manager -# -PATH_TO_TOP = ../../.. - -#FIXME: why doesn't this work? -#ZLIB_OBJECTS = $(PATH_TO_TOP)/drivers/lib/zlib/zlib.a -ZLIB_PATH = $(PATH_TO_TOP)/drivers/lib/zlib +# $Id$ -ZLIB_OBJECTS = $(ZLIB_PATH)/adler32.o $(ZLIB_PATH)/deflate.o \ - $(ZLIB_PATH)/infblock.o $(ZLIB_PATH)/infcodes.o \ - $(ZLIB_PATH)/inflate.o $(ZLIB_PATH)/inftrees.o \ - $(ZLIB_PATH)/infutil.o $(ZLIB_PATH)/inffast.o \ - $(ZLIB_PATH)/trees.o $(ZLIB_PATH)/zutil.o -ENGINE_OBJECTS = $(ZLIB_OBJECTS) cabinet.o mszip.o raw.o -TEST_OBJECTS = $(ENGINE_OBJECTS) test.o -OBJECTS = $(ENGINE_OBJECTS) main.o dfp.o -TARGET = cabman -PROGS = $(TARGET).exe test.exe - -#FIXME: zlib should be compiled and installed in the SDK by the master makefile -CFLAGS += -O3 -I$(ZLIB_PATH) +PATH_TO_TOP = ../../.. -CLEAN_FILES = *.o $(TARGET).exe $(TARGET).sym test.exe test.sym +TARGET_TYPE = program -all: $(PROGS) +TARGET_APPTYPE = console -clean: - - $(RM) $(CLEAN_FILES) +TARGET_NAME = cabman -.phony: clean +TARGET_OBJECTS = cabinet.o mszip.o raw.o main.o dfp.o -install: $(PROGS:%=$(FLOPPY_DIR)/apps/%) +TARGET_SDKLIBS = zlib.a -$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % -ifeq ($(DOSCLI),yes) - $(CP) $* $(FLOPPY_DIR)\apps\$* -else - $(CP) $* $(FLOPPY_DIR)/apps/$* -endif +TARGET_CFLAGS = -I$(PATH_TO_TOP)/lib/zlib -dist: $(PROGS:%=../../$(DIST_DIR)/apps/%) +TARGET_CPPFLAGS = $(TARGET_CFLAGS) -$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: % -ifeq ($(DOSCLI),yes) - $(CP) $* ..\..\$(DIST_DIR)\apps\$* -else - $(CP) $* ../../$(DIST_DIR)/apps/$* -endif +TARGET_GCCLIBS = stdc++ -#FIXME: zlib should be compiled and installed in the SDK by the master makefile -$(ZLIB_PATH)/zlib.a: - make -C $(ZLIB_PATH) -f makefile.reactos +TARGET_NORC = yes -$(TARGET).exe: $(OBJECTS) $(ZLIB_PATH)/zlib.a - $(CC) $(OBJECTS) -lstdc++ -o $(TARGET).exe - $(NM) --numeric-sort $(TARGET).exe > $(TARGET).sym - -test.exe: $(TEST_OBJECTS) - $(CC) $(TEST_OBJECTS) -lstdc++ -o test.exe - $(NM) --numeric-sort test.exe > test.sym +include $(PATH_TO_TOP)/rules.mak -include ../../../rules.mak +include $(TOOLS_PATH)/helper.mk diff --git a/apps/utils/pice/makefile b/apps/utils/pice/makefile index d46559d..f58ef6d 100644 --- a/apps/utils/pice/makefile +++ b/apps/utils/pice/makefile @@ -1,21 +1,21 @@ # $Id$ all: - make -C loader - make -C module + $(MAKE) -C loader + $(MAKE) -C module implib: - make -C loader implib - make -C module implib + $(MAKE) -C loader implib + $(MAKE) -C module implib clean: - make -C loader clean - make -C module clean + $(MAKE) -C loader clean + $(MAKE) -C module clean dist: - make -C loader dist - make -C module dist + $(MAKE) -C loader dist + $(MAKE) -C module dist install: - make -C loader install - make -C module install + $(MAKE) -C loader install + $(MAKE) -C module install diff --git a/baseaddress.cfg b/baseaddress.cfg index fa86ada..f862809 100644 --- a/baseaddress.cfg +++ b/baseaddress.cfg @@ -17,7 +17,9 @@ lib/secur32 TARGET_BASE=0x10000000 lib/shell32 TARGET_BASE=0x77260000 lib/user32 TARGET_BASE=0x77e70000 lib/version TARGET_BASE=0x77a90000 +lib/winspool TARGET_BASE=0x77800000 lib/ws2_32 TARGET_BASE=0x77780000 +lib/wsock32 TARGET_BASE=0x75050000 services/dd/vga/display TARGET_BASE=0x70000000 services/net/wshtcpip TARGET_BASE=0x777c0000 subsys/psx/lib/psxdll TARGET_BASE=0x68EB0000 @@ -34,6 +36,7 @@ dlls/ddraw TARGET_BASE=0x76240000 dlls/dinput TARGET_BASE=0x76280000 dlls/dplay TARGET_BASE=0x76320000 dlls/dplayx TARGET_BASE=0x76310000 +dlls/imm32 TARGET_BASE=0x75e60000 dlls/mapi32 TARGET_BASE=0x76430000 dlls/ole32 TARGET_BASE=0x76010000 dlls/oleaut32 TARGET_BASE=0x76040000 diff --git a/bootc.lst b/bootc.lst index 28ae66a..9ab90f2 100644 --- a/bootc.lst +++ b/bootc.lst @@ -3,5 +3,5 @@ system32\drivers\atapi.sys system32\drivers\class2.sys system32\drivers\disk.sys system32\drivers\vfatfs.sys -system32\config\system.hiv +system32\config\system * diff --git a/bootcd.bat b/bootcd.bat index 5a7a45d..b816a01 100755 --- a/bootcd.bat +++ b/bootcd.bat @@ -1,6 +1,7 @@ @echo off set BOOTCD_DIR=..\bootcd set FREELDR_DIR=..\freeldr +set ROSAPPS_DIR=..\rosapps md %BOOTCD_DIR% md %BOOTCD_DIR%\disk @@ -11,9 +12,10 @@ md %BOOTCD_DIR%\disk\reactos\system32 md %BOOTCD_DIR%\disk\loader rem copy FreeLoader files -copy /Y %FREELDR_DIR%\bootsect\isoboot.bin %BOOTCD_DIR% +copy /Y %FREELDR_DIR%\bootsect\isoboot.bin %BOOTCD_DIR% copy /Y %FREELDR_DIR%\freeldr\obj\i386\setupldr.sys %BOOTCD_DIR%\disk\reactos +copy /Y %FREELDR_DIR%\bootsect\dosmbr.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\ext2.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\fat.bin %BOOTCD_DIR%\disk\loader copy /Y %FREELDR_DIR%\bootsect\fat32.bin %BOOTCD_DIR%\disk\loader @@ -37,10 +39,18 @@ copy /Y drivers\storage\class2\class2.sys %BOOTCD_DIR%\disk\reactos copy /Y lib\ntdll\ntdll.dll %BOOTCD_DIR%\disk\reactos\system32 copy /Y subsys\system\usetup\usetup.exe %BOOTCD_DIR%\disk\reactos\system32\smss.exe -rem copy install files -copy /Y txtsetup.sif %BOOTCD_DIR%\disk\install -copy /Y system.hiv %BOOTCD_DIR%\disk\install +rem copy data files +copy /Y bootdata\autorun.inf %BOOTCD_DIR%\disk +copy /Y bootdata\readme.txt %BOOTCD_DIR%\disk + +copy /Y bootdata\hivecls.inf %BOOTCD_DIR%\disk\install +copy /Y bootdata\hivedef.inf %BOOTCD_DIR%\disk\install +copy /Y bootdata\hivesft.inf %BOOTCD_DIR%\disk\install +copy /Y bootdata\hivesys.inf %BOOTCD_DIR%\disk\install +copy /Y bootdata\txtsetup.sif %BOOTCD_DIR%\disk\install + +rem copy install files copy /Y ntoskrnl\ntoskrnl.exe %BOOTCD_DIR%\disk\install copy /Y hal\halx86\hal.dll %BOOTCD_DIR%\disk\install @@ -54,7 +64,7 @@ copy /Y drivers\dd\null\null.sys %BOOTCD_DIR%\disk\install copy /Y drivers\dd\serial\serial.sys %BOOTCD_DIR%\disk\install copy /Y drivers\dd\vga\display\vgaddi.dll %BOOTCD_DIR%\disk\install copy /Y drivers\dd\vga\miniport\vgamp.sys %BOOTCD_DIR%\disk\install -copy /Y drivers\dd\vidport\vidport.sys %BOOTCD_DIR%\disk\install +copy /Y drivers\dd\videoprt\videoprt.sys %BOOTCD_DIR%\disk\install copy /Y drivers\fs\cdfs\cdfs.sys %BOOTCD_DIR%\disk\install copy /Y drivers\fs\fs_rec\fs_rec.sys %BOOTCD_DIR%\disk\install @@ -87,6 +97,7 @@ copy /Y drivers\storage\scsiport\scsiport.sys %BOOTCD_DIR%\disk\install copy /Y lib\advapi32\advapi32.dll %BOOTCD_DIR%\disk\install copy /Y lib\crtdll\crtdll.dll %BOOTCD_DIR%\disk\install copy /Y lib\fmifs\fmifs.dll %BOOTCD_DIR%\disk\install +copy /Y lib\freetype\freetype.dll %BOOTCD_DIR%\disk\install copy /Y lib\gdi32\gdi32.dll %BOOTCD_DIR%\disk\install copy /Y lib\kernel32\kernel32.dll %BOOTCD_DIR%\disk\install copy /Y lib\msafd\msafd.dll %BOOTCD_DIR%\disk\install @@ -112,12 +123,22 @@ copy /Y subsys\csrss\csrss.exe %BOOTCD_DIR%\disk\install copy /Y subsys\ntvdm\ntvdm.exe %BOOTCD_DIR%\disk\install copy /Y subsys\smss\smss.exe %BOOTCD_DIR%\disk\install copy /Y subsys\system\autochk\autochk.exe %BOOTCD_DIR%\disk\install -copy /Y subsys\system\gstart\gstart.exe %BOOTCD_DIR%\disk\install copy /Y subsys\system\lsass\lsass.exe %BOOTCD_DIR%\disk\install copy /Y subsys\system\services\services.exe %BOOTCD_DIR%\disk\install -copy /Y subsys\system\shell\shell.exe %BOOTCD_DIR%\disk\install +copy /Y subsys\system\cmd\cmd.exe %BOOTCD_DIR%\disk\install copy /Y subsys\system\winlogon\winlogon.exe %BOOTCD_DIR%\disk\install copy /Y subsys\win32k\win32k.sys %BOOTCD_DIR%\disk\install copy /Y media\fonts\helb____.ttf %BOOTCD_DIR%\disk\install copy /Y media\fonts\timr____.ttf %BOOTCD_DIR%\disk\install + +rem copy test apps +copy /Y apps\tests\winhello\winhello.exe %BOOTCD_DIR%\disk\install + +rem copy rosapps files +copy /Y %ROSAPPS_DIR%\games\winemine\winemine.exe %BOOTCD_DIR%\disk\install +copy /Y %ROSAPPS_DIR%\hcalc\hcalc.exe %BOOTCD_DIR%\disk\install +copy /Y %ROSAPPS_DIR%\mc\mc.exe %BOOTCD_DIR%\disk\install + +rem create the reactos.iso image file +tools\cdmake\cdmake -m -b %BOOTCD_DIR%\isoboot.bin %BOOTCD_DIR%\disk REACTOS %BOOTCD_DIR%\reactos.iso diff --git a/bootdata/hivecls.inf b/bootdata/hivecls.inf new file mode 100644 index 0000000..18f7fe9 --- /dev/null +++ b/bootdata/hivecls.inf @@ -0,0 +1,15 @@ +[Version] +Signature="$ReactOS$ + +[AddReg] +HKLM,"SOFTWARE\Classes",,0x00000010 + +HKCR,"CLSID",,0x00000012 + +HKCR,"Interface",,0x00000012 + +HKCR,"NDS\Clsid","",0x00000002,"{323991f0-7bad-11cf-b03d-00aa006e0975}" + +HKCR,"WinNT\Clsid","",0x00000002,"{8b20cd60-0f29-11cf-abc4-02608c9e7553}" + +; EOF diff --git a/bootdata/hivedef.inf b/bootdata/hivedef.inf new file mode 100644 index 0000000..3c005d7 --- /dev/null +++ b/bootdata/hivedef.inf @@ -0,0 +1,12 @@ +[Version] +Signature="$ReactOS$ + +[AddReg] + +HKCU,"Control Panel",,0x00000012 + +HKCU,"Control Panel\Appearance",,0x00000012 + +HKCU,"Environment",,0x00000012 + +; EOF diff --git a/bootdata/hivesft.inf b/bootdata/hivesft.inf new file mode 100644 index 0000000..2eda1d5 --- /dev/null +++ b/bootdata/hivesft.inf @@ -0,0 +1,10 @@ +[Version] +Signature="$ReactOS$ + +[AddReg] + + +HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\WinLogon","Shell",0x00020000,"%SystemRoot%\System32\cmd.exe" +HKLM,"SOFTWARE\ReactOS\Windows NT\CurrentVersion\WinLogon","StartServices",0x00010001,0x00000001 + +; EOF diff --git a/bootdata/hivesys.inf b/bootdata/hivesys.inf new file mode 100644 index 0000000..9b5bb54 --- /dev/null +++ b/bootdata/hivesys.inf @@ -0,0 +1,324 @@ +[Version] +Signature = "$ReactOS$" + +[AddReg] + +; NLS Codepage settings +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","10000",0x00000000,"c_10000.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","1252",0x00000000,"c_1252.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","437",0x00000000,"c_437.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","850",0x00000000,"c_850.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","ACP",0x00000000,"1252" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","OEMCP",0x00000000,"437" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\CodePage","MACCP",0x00000000,"10000" + +; NLS Language settings +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0401",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0402",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0403",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0404",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0405",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0406",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0407",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0408",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0409",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040a",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040b",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040c",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040d",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040e",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","040f",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","0410",0x00000000,"l_intl.nls" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","Default",0x00000000,"0409" +HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","InstallLanguage",0x00000000,"0409" + +; Service groups +HKLM,"SYSTEM\CurrentControlSet\Control\ServiceGroupOrder","List",0x00010000, \ + "SCSI Port", \ + "SCSI Miniport", \ + "Primary Disk", \ + "SCSI Class Helper", \ + "SCSI Class", \ + "Boot File System", \ + "Base", \ + "Pointer Port", \ + "Keyboard Port", \ + "Pointer Class", \ + "Keyboard Class", \ + "Debug", \ + "Video Init", \ + "Video", \ + "File System", \ + "Event log", \ + "NDIS", \ + "PNP_TDI", \ + "TDI", \ + "Extended Base" + +; Session Manager stuff +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager","BootExecute", 0x00010000, \ + "autocheck autochk *" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager","ObjectDirectories",0x00010000, \ + "\Windows", \ + "\RPC Control" + +; DOS devices +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","AUX",0x00000000,"\DosDevices\COM1" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","MAILSLOT",0x00000000,"\Device\MailSlot" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","NUL",0x00000000,"\Device\Null" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","PIPE",0x00000000,"\Device\NamedPipe" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","PRN",0x00000000,"\DosDevices\LPT1" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices","UNC",0x00000000,"\Device\Mup" + +; System environment settings +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","ComSpec",0x00020000,"%SystemRoot%\system32\cmd.exe" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","OS",0x00020000,"ReactOS" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","Path",0x00020000,"%SystemRoot%\bin;%SystemRoot%\system32;%SystemRoot%" +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Environment","windir",0x00020000,"%SystemRoot%" + +; Pagefile settings +HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","PagingFiles",0x00010000, \ + "C:\reactos\pagefile.sys" + +; Afd driver +HKLM,"SYSTEM\CurrentControlSet\Services\Afd","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Afd","Group",0x00000000,"TDI" +HKLM,"SYSTEM\CurrentControlSet\Services\Afd","ImagePath",0x00020000,"system32\drivers\afd.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Afd","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\Afd","Type",0x00010001,0x00000001 + +; Atapi miniport driver +HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Group",0x00000000,"SCSI Miniport" +HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","ImagePath",0x00020000,"system32\drivers\atapi.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Type",0x00010001,0x00000001 + +; Beep device driver +HKLM,"SYSTEM\CurrentControlSet\Services\Beep","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Group",0x00000000,"Base" +HKLM,"SYSTEM\CurrentControlSet\Services\Beep","ImagePath",0x00020000,"system32\drivers\beep.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001 + +; BlueScreen device driver +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init" +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001 + +; Cdfs (ISO96660) filesystem driver +HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","ImagePath",0x00020000,"system32\drivers\cdfs.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\Cdfs","Type",0x00010001,0x00000002 + +; Cdrom class driver +HKLM,"SYSTEM\CurrentControlSet\Services\Cdrom","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Cdrom","Group",0x00000000,"SCSI Class" +HKLM,"SYSTEM\CurrentControlSet\Services\Cdrom","ImagePath",0x00020000,"system32\drivers\cdrom.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Cdrom","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Cdrom","Type",0x00010001,0x00000001 + +; Class2 driver +HKLM,"SYSTEM\CurrentControlSet\Services\Class2","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Class2","Group",0x00000000,"SCSI Class Helper" +HKLM,"SYSTEM\CurrentControlSet\Services\Class2","ImagePath",0x00020000,"system32\drivers\class2.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Class2","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Class2","Type",0x00010001,0x00000001 + +; Disk class driver +HKLM,"SYSTEM\CurrentControlSet\Services\Disk","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Disk","Group",0x00000000,"SCSI Class" +HKLM,"SYSTEM\CurrentControlSet\Services\Disk","ImagePath",0x00020000,"system32\drivers\disk.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Disk","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Disk","Type",0x00010001,0x00000001 + +; Event logging service +HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","Group",0x00000000,"Event log" +HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","ImagePath",0x00020000,"%SystemRoot%\system32\eventlog.exe" +HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","Type",0x00010001,0x00000010 + +; Floppy driver +HKLM,"SYSTEM\CurrentControlSet\Services\Floppy","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Floppy","Group",0x00000000,"Primary Disk" +HKLM,"SYSTEM\CurrentControlSet\Services\Floppy","ImagePath",0x00020000,"system32\drivers\floppy.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Floppy","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Floppy","Type",0x00010001,0x00000001 + +; Filesystem recognizer driver +HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Group",0x00000000,"Boot file system" +HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ImagePath",0x00020000,"system32\drivers\fs_rec.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 + +; IDE driver (deprecated) +;HKLM,"SYSTEM\CurrentControlSet\Services\Ide","ErrorControl",0x00010001,0x00000000 +;HKLM,"SYSTEM\CurrentControlSet\Services\Ide","Group",0x00000000,"Primary Disk" +;HKLM,"SYSTEM\CurrentControlSet\Services\Ide","ImagePath",0x00020000,"system32\drivers\ide.sys" +;HKLM,"SYSTEM\CurrentControlSet\Services\Ide","Start",0x00010001,0x00000004 +;HKLM,"SYSTEM\CurrentControlSet\Services\Ide","Type",0x00010001,0x00000001 + +; Keyboard driver +HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Group",0x00000000,"Keyboard Port" +HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","ImagePath",0x00020000,"system32\drivers\keyboard.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Keyboard","Type",0x00010001,0x00000001 + +; Mouse driver +HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","Group",0x00000000,"Pointer Class" +HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","ImagePath",0x00020000,"system32\drivers\mouclass.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Mouse","Type",0x00010001,0x00000001 + +; Mailslot filesystem driver +HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","ImagePath",0x00020000,"system32\drivers\msfs.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Type",0x00010001,0x00000002 + +; NDIS driver +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Group",0x00000000,"NDIS" +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","ImagePath",0x00020000,"system32\drivers\ndis.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Type",0x00010001,0x00000001 + +; NE2000 NIC driver +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Group",0x00000000,"NDIS" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ImagePath",0x00020000,"system32\drivers\ne2000.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Type",0x00010001,0x00000001 + +; Named Pipe filesystem driver +HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","ImagePath",0x00020000,"system32\drivers\npfs.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","Type",0x00010001,0x00000002 + +; NTFS filesystem driver +HKLM,"SYSTEM\CurrentControlSet\Services\Ntfs","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Ntfs","Group",0x00000000,"File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Ntfs","ImagePath",0x00020000,"system32\drivers\ntfs.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Ntfs","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\Ntfs","Type",0x00010001,0x00000002 + +; Null device driver +HKLM,"SYSTEM\CurrentControlSet\Services\Null","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Null","Group",0x00000000,"Base" +HKLM,"SYSTEM\CurrentControlSet\Services\Null","ImagePath",0x00020000,"system32\drivers\null.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Null","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Null","Type",0x00010001,0x00000001 + +; Serial device driver +HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Group",0x00000000,"Base" +HKLM,"SYSTEM\CurrentControlSet\Services\Serial","ImagePath",0x00020000,"system32\drivers\serial.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Serial","Type",0x00010001,0x00000001 + +; Packet driver +HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Group",0x00000000,"PNP_TDI" +HKLM,"SYSTEM\CurrentControlSet\Services\Packet","ImagePath",0x00020000,"system32\drivers\packet.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Packet","Type",0x00010001,0x00000001 +; NOTE: These settings should be added by the network setup +HKLM,"SYSTEM\CurrentControlSet\Services\Packet\Linkage","Bind",0x00020000,"\Device\ne2000" +HKLM,"SYSTEM\CurrentControlSet\Services\Packet\Linkage","Export",0x00020000,"\Device\packet" + +; Private ICE driver +HKLM,"SYSTEM\CurrentControlSet\Services\Pice","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Pice","Group",0x00000000,"Debug" +HKLM,"SYSTEM\CurrentControlSet\Services\Pice","ImagePath",0x00020000,"system32\drivers\pice.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Pice","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Pice","Type",0x00010001,0x00000001 + +; PS/2 mouse port driver +HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Group",0x00000000,"Pointer Port" +HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","ImagePath",0x00020000,"system32\drivers\psaux.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Psaux","Type",0x00010001,0x00000001 + +; RPC service +HKLM,"SYSTEM\CurrentControlSet\Services\Rpcss","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Rpcss","ImagePath",0x00020000,"%SystemRoot%\system32\rpcss.exe" +HKLM,"SYSTEM\CurrentControlSet\Services\Rpcss","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Rpcss","Type",0x00010001,0x00000010 + +; Scsiport driver +HKLM,"SYSTEM\CurrentControlSet\Services\Scsiport","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Scsiport","Group",0x00000000,"SCSI Port" +HKLM,"SYSTEM\CurrentControlSet\Services\Scsiport","ImagePath",0x00020000,"system32\drivers\scsiport.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Scsiport","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Scsiport","Type",0x00010001,0x00000001 + +; TCP/IP driver +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Group",0x00000000,"PNP_TDI" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","ImagePath",0x00020000,"system32\drivers\tcpip.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Start",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Type",0x00010001,0x00000001 +; NOTE: These settings should be added by the network setup +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Bind",0x00020000,"\Device\ne2000" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Export",0x00020000,"\Device\tcpip" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Route",0x00020000,"" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","DataBasePath",0x00000000,"DataBasePath" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Domain",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Hostname",0x00000000,"ROSHost" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","NameServer",0x00000000,"203.13.174.1" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","ForwardBroadcasts",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","IPEnableRouter",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","SearchList",0x00000000,"" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","EnableSecurityFilters",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\PersistentRoutes",,0x00000010 + +; Virtual FAT filesystem driver +HKLM,"SYSTEM\CurrentControlSet\Services\Vfatfs","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Vfatfs","Group",0x00000000,"Boot File System" +HKLM,"SYSTEM\CurrentControlSet\Services\Vfatfs","ImagePath",0x00020000,"system32\drivers\vfatfs.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Vfatfs","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Vfatfs","Type",0x00010001,0x00000002 + +; VGA miniport driver +HKLM,"SYSTEM\CurrentControlSet\Services\Vga","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Group",0x00000000,"Video" +HKLM,"SYSTEM\CurrentControlSet\Services\Vga","ImagePath",0x00020000,"system32\drivers\vgamp.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Vga","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Vga\Device0","InstalledDisplayDrivers",0x00010000,"vgaddi" + +; VMware SVGA driver +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Group",0x00000000,"Video" +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","ImagePath",0x00020000,"system32\drivers\vmx_svga.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\vmx_svga\Device0","InstalledDisplayDrivers",0x00010000,"vmx_fb" + + +; ControlSet selection settings +HKLM,"SYSTEM\Select","Current",0x00010001,0x00000001 +HKLM,"SYSTEM\Select","Default",0x00010001,0x00000001 +HKLM,"SYSTEM\Select","Failed",0x00010001,0x00000000 +HKLM,"SYSTEM\Select","LastKnownGood",0x00010001,0x00000000 + +; System setup settings +HKLM,"SYSTEM\Setup","CmdLine",0x00000000,"setup -newsetup" +HKLM,"SYSTEM\Setup","OsLoaderPath",0x00000000,"\" +HKLM,"SYSTEM\Setup","SetupType",0x00010001,0x00000000 +HKLM,"SYSTEM\Setup","SystemPartition",0x00000000,"\Device\Harddisk0\Partition1" +HKLM,"SYSTEM\Setup","SystemSetupInProgress",0x00010001,0x00000000 + +; EOF diff --git a/bootdata/readme.txt b/bootdata/readme.txt new file mode 100644 index 0000000..e291be8 --- /dev/null +++ b/bootdata/readme.txt @@ -0,0 +1,55 @@ +======================== +ReactOS Version 0.1.x +Updated March 27th, 2003 +======================== + +1. What is ReactOS? +------------------- + +ReactOS is an Open Source effort to develop a quality operating system that is +compatible with Windows NT applications and drivers. + +Website: http://www.reactos.com + + +2. Relationship with the WINE project +------------------------------------- + +ReactOS has always planned to work with the WINE project to share as much +programming effort as possible. This will mainly concern User Mode DLLs and +will happen once ReactOS's Kernel Mode areas are more complete, as those areas +form the underlying infrastructure. Other areas of cooperation lie in +applications and testing suites. + + +3. Future compatibility +----------------------- + +The ReactOS project, although currently focused on Windows NT 4.0 +compatibility, is always keeping an eye towards compatibility with future +Windows NT releases, that is, Windows 2000 (NT 5.0) and Windows XP (NT 5.1). + + +4. Supporting other System Applications +--------------------------------------- + +The Windows NT architecture allows for subsystems, as does the ReactOS +architecture. A subsystem is an implementation of the APIs of another +operating system, allowing ReactOS to run applications from other systems. We +are already looking at subsystems for: Java, OS/2 and DOS and possibly others +in the future. + + +5. Tutorials +------------ + +Developer and User Tutorials: http://reactos.com/index.php?tab=documents + +The tutorials contain more information on the project, compiling and testing +ReactOS - among other topics. Contributors to the project are always welcome. + +6. Author +--------- + +This document was written by Jason Filby (jasonfilby@yahoo.com). + diff --git a/bootdata/txtsetup.sif b/bootdata/txtsetup.sif new file mode 100644 index 0000000..dc3abf8 --- /dev/null +++ b/bootdata/txtsetup.sif @@ -0,0 +1,111 @@ +[Version] +Signature = "$ReactOS$" + +[Directories] +1 = "\" +2 = system32 +3 = system32\drivers +4 = system32\config +5 = media +6 = media\fonts +7 = bin + +[SourceFiles] +ntoskrnl.exe = 2 +hal.dll = 2 + +acpi.sys = 3 +isapnp.sys = 3 + +beep.sys = 3 +blue.sys = 3 +floppy.sys = 3 +null.sys = 3 +serial.sys = 3 +vgaddi.dll = 2 +vgamp.sys = 3 +videoprt.sys = 3 + +cdfs.sys = 3 +fs_rec.sys = 3 +msfs.sys = 3 +mup.sys = 3 +npfs.sys = 3 +ntfs.sys = 3 +vfatfs.sys = 3 + +keyboard.sys = 3 +mouclass.sys = 3 +psaux.sys = 3 + +unbzip2.sys = 3 + +afd.sys = 3 +ne2000.sys = 3 +ndis.sys = 3 +npf.sys = 3 +;packet.sys = 3 +tcpip.sys = 3 +tdi.sys = 3 + +atapi.sys = 3 +cdrom.sys = 3 +class2.sys = 3 +disk.sys = 3 +scsiport.sys = 3 + +advapi32.dll = 2 +crtdll.dll = 2 +fmifs.dll = 2 +freetype.dll = 2 +gdi32.dll = 2 +kernel32.dll = 2 +msafd.dll = 2 +msvcrt.dll = 2 +ntdll.dll = 2 +;ole32.dll = 2 +;oleaut32.dll = 2 +packet.dll = 2 +secur32.dll = 2 +;shell32.dll = 2 +user32.dll = 2 +version.dll = 2 +winedbgc.dll = 2 +winspool.drv = 2 +;winmm.dll = 2 +ws2_32.dll = 2 +ws2help.dll = 2 +wshirda.dll = 2 + +eventlog.exe = 2 +rpcss.exe = 2 +csrss.exe = 2 +ntvdm.exe = 2 +smss.exe = 2 +autochk.exe = 2 +;lsass.exe = 2 +services.exe = 2 +cmd.exe = 2 +winlogon.exe = 2 + +win32k.sys = 2 + +helb____.ttf = 6 +timr____.ttf = 6 + +winhello.exe = 2 + +hcalc.exe = 2 +mc.exe = 2 +winemine.exe = 2 + +[SetupData] +DefaultPath = \ReactOS + +[HiveInfs.Install] +AddReg=hivecls.inf,AddReg +AddReg=hivedef.inf,AddReg +AddReg=hivesft.inf,AddReg +AddReg=hivesys.inf,AddReg + +; EOF diff --git a/drivers/bus/pci/pci.c b/drivers/bus/pci/pci.c index 88f01c0..8610ae1 100644 --- a/drivers/bus/pci/pci.c +++ b/drivers/bus/pci/pci.c @@ -68,7 +68,7 @@ PciReadConfigUshort(UCHAR Bus, { case pbtType1: WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1)); + *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2)); return STATUS_SUCCESS; case pbtType2: @@ -150,7 +150,7 @@ PciWriteConfigUshort(UCHAR Bus, { case pbtType1: WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1), Value); + WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value); return STATUS_SUCCESS; case pbtType2: diff --git a/drivers/dd/blue/blue.c b/drivers/dd/blue/blue.c index 058d819..6269a0c 100644 --- a/drivers/dd/blue/blue.c +++ b/drivers/dd/blue/blue.c @@ -175,10 +175,12 @@ ScrWrite(PDEVICE_OBJECT DeviceObject, rows = DeviceExtension->Rows; columns = DeviceExtension->Columns; + __asm__ ("cli\n\t"); WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); offset = READ_PORT_UCHAR (CRTC_DATA)<<8; WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); offset += READ_PORT_UCHAR (CRTC_DATA); + __asm__ ("sti\n\t"); cursory = offset / columns; cursorx = offset % columns; @@ -268,11 +270,13 @@ ScrWrite(PDEVICE_OBJECT DeviceObject, /* Set the cursor position */ offset = (cursory * columns) + cursorx; } + __asm__ ("cli\n\t"); WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO); WRITE_PORT_UCHAR (CRTC_DATA, offset); WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI); offset >>= 8; WRITE_PORT_UCHAR (CRTC_DATA, offset); + __asm__ ("sti\n\t"); Status = STATUS_SUCCESS; @@ -450,7 +454,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject, offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + (Buf->dwCoord.X * 2) + 1; - for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pAttr++) + for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pAttr++) { (char) *pAttr = vidmem[offset + (dwCount * 2)]; } @@ -474,7 +478,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject, offset = (pCoord->Y * DeviceExtension->Columns * 2) + (pCoord->X * 2) + 1; - for (dwCount = 0; dwCount < (stk->Parameters.Write.Length - sizeof( COORD )); dwCount++, pAttr++) + for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pAttr++) { vidmem[offset + (dwCount * 2)] = *pAttr; } @@ -527,7 +531,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject, offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) + (Buf->dwCoord.X * 2); - for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pChar++) + for (dwCount = 0; dwCount < stk->Parameters.DeviceIoControl.OutputBufferLength; dwCount++, pChar++) { *pChar = vidmem[offset + (dwCount * 2)]; } @@ -552,7 +556,7 @@ ScrIoControl(PDEVICE_OBJECT DeviceObject, offset = (pCoord->Y * DeviceExtension->Columns * 2) + (pCoord->X * 2); - for (dwCount = 0; dwCount < (stk->Parameters.Write.Length - sizeof( COORD )); dwCount++, pChar++) + for (dwCount = 0; dwCount < (stk->Parameters.DeviceIoControl.InputBufferLength - sizeof( COORD )); dwCount++, pChar++) { vidmem[offset + (dwCount * 2)] = *pChar; } diff --git a/drivers/dd/blue/makefile b/drivers/dd/blue/makefile index ebc9e15..0d6a02d 100644 --- a/drivers/dd/blue/makefile +++ b/drivers/dd/blue/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = blue diff --git a/drivers/dd/floppy/Makefile b/drivers/dd/floppy/Makefile index ab1bd9a..d47bf83 100644 --- a/drivers/dd/floppy/Makefile +++ b/drivers/dd/floppy/Makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = floppy diff --git a/drivers/dd/floppy/floppy.c b/drivers/dd/floppy/floppy.c index d40c5f0..2504549 100644 --- a/drivers/dd/floppy/floppy.c +++ b/drivers/dd/floppy/floppy.c @@ -31,7 +31,6 @@ const FLOPPY_MEDIA_TYPE MediaTypes[] = { { 0x02, 80, 2, 18, 512 }, { 0, 0, 0, 0, 0 } }; - static BOOLEAN FloppyCreateController(PDRIVER_OBJECT DriverObject, PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters, @@ -179,7 +178,6 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, } // set for high speed mode // FloppyWriteCCNTL( ControllerExtension->PortBase, FLOPPY_CCNTL_1MBIT ); - // ok, so we have an FDC, now check for drives // aparently the sense drive status command does not work on any FDC I can find // so instead we will just have to assume a 1.44 meg 3.5 inch floppy. At some @@ -209,7 +207,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, if( ControllerExtension->St0 != FLOPPY_ST0_SEEKGD ) { DbgPrint( "Floppy: error recalibrating drive, ST0: %2x\n", (DWORD)ControllerExtension->St0 ); - goto interruptcleanup; + goto devicecleanup; } DeviceExtension->Cyl = 0; // drive is good, and it is now on track 0, turn off the motor @@ -231,7 +229,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, if( !NT_SUCCESS( Status ) ) { DPRINT1( "Error: IoAllocateAdapterChannel returned %x\n", Status ); - goto interruptcleanup; + goto devicecleanup; } CHECKPOINT; Status = KeWaitForSingleObject( &ControllerExtension->Event, @@ -243,7 +241,7 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, if( Status != STATUS_WAIT_0 ) { DPRINT1( "Error: KeWaitForSingleObject returned: %x\n", Status ); - goto interruptcleanup; + goto devicecleanup; } // Ok, we own the adapter object, from now on we can just IoMapTransfer, and not // bother releasing the adapter ever. @@ -259,7 +257,6 @@ FloppyCreateController(PDRIVER_OBJECT DriverObject, // turn off controller FloppyWriteDOR( ControllerExtension->PortBase, 0 ); IoDeleteController(ControllerObject); - for(;;); return FALSE; } @@ -324,16 +321,18 @@ FloppyExecuteReadWrite(PDEVICE_OBJECT DeviceObject, Timeout, &ControllerExtension->MotorSpindownDpc ); } - // verify media content +#if 0 + /* Handle disk change, doesn't work correctly */ if( FloppyReadDIR( ControllerExtension->PortBase ) & FLOPPY_DI_DSKCHNG ) { // No disk is in the drive DPRINT( "No disk is in the drive\n" ); - Irp->IoStatus.Status = STATUS_NO_MEDIA; + Irp->IoStatus.Status = STATUS_MEDIA_CHANGED; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, 0 ); return DeallocateObject; } +#endif if( DeviceExtension->MediaType == ~0 ) { // media is in disk, but we have not yet detected what kind it is, @@ -562,4 +561,3 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, } /* EOF */ - diff --git a/drivers/dd/floppy/floppy.h b/drivers/dd/floppy/floppy.h index 3ac15d3..b882d88 100644 --- a/drivers/dd/floppy/floppy.h +++ b/drivers/dd/floppy/floppy.h @@ -17,7 +17,7 @@ #define FLOPPY_MS_FDCBUSY 0x10 #define FLOPPY_MS_DMAMODE 0x20 #define FLOPPY_MS_DATADIR 0x40 -#define FLOPPY_MS_RDYMASK 0xF0 +#define FLOPPY_MS_RDYMASK 0xC0 #define FLOPPY_MS_DATARDYW 0x80 #define FLOPPY_MS_DATARDYR 0xC0 #define FLOPPY_REG_DATA 0x0005 diff --git a/drivers/dd/floppy/isr.c b/drivers/dd/floppy/isr.c index 615f97b..0a3fdba 100644 --- a/drivers/dd/floppy/isr.c +++ b/drivers/dd/floppy/isr.c @@ -23,6 +23,14 @@ BOOLEAN FloppyIsrDetect( PCONTROLLER_OBJECT Controller ) ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase ); KeStallExecutionProcessor( 100 ); DeviceExtension->Cyl = FloppyReadDATA( ControllerExtension->PortBase ); + KeStallExecutionProcessor( 100 ); + if (FLOPPY_MS_DATARDYR == + (FloppyReadMSTAT( ControllerExtension->PortBase ) & FLOPPY_MS_RDYMASK)) + { + /* There's something still to be read (what is it???? only happens on some + controllers). Ignore it. */ + (void) FloppyReadDATA( ControllerExtension->PortBase ); + } // now queue DPC to set the event IoRequestDpc( ControllerExtension->Device, 0, @@ -78,6 +86,13 @@ BOOLEAN FloppyIsrRecal( PCONTROLLER_OBJECT Controller ) ControllerExtension->St0 = FloppyReadDATA( ControllerExtension->PortBase ); KeStallExecutionProcessor( 1000 ); FloppyReadDATA( ControllerExtension->PortBase ); // ignore cyl number + if (FLOPPY_MS_DATARDYR == + (FloppyReadMSTAT( ControllerExtension->PortBase ) & FLOPPY_MS_RDYMASK)) + { + /* There's something still to be read (what is it???? only happens on some + controllers). Ignore it. */ + (void) FloppyReadDATA( ControllerExtension->PortBase ); + } DPRINT( "Recal St0: %2x\n", ControllerExtension->St0 ); // If recalibrate worked, issue read ID for each media type untill one works diff --git a/drivers/dd/mouse/.cvsignore b/drivers/dd/mouse/.cvsignore deleted file mode 100644 index ecc83ad..0000000 --- a/drivers/dd/mouse/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -base.tmp diff --git a/drivers/dd/mouse/makefile b/drivers/dd/mouse/makefile deleted file mode 100644 index 9beb9c9..0000000 --- a/drivers/dd/mouse/makefile +++ /dev/null @@ -1,13 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../../.. - -TARGET_TYPE = driver - -TARGET_NAME = mouse - -TARGET_OBJECTS = mouse.o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk diff --git a/drivers/dd/mouse/mouse.c b/drivers/dd/mouse/mouse.c deleted file mode 100644 index b9da7fb..0000000 --- a/drivers/dd/mouse/mouse.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - - ** Mouse driver 0.0.3 - ** Written by Jason Filby (jasonfilby@yahoo.com) - ** For ReactOS (www.sid-dis.com/reactos) - - ** Note: The serial.o driver must be loaded before loading this driver - - ** Known Limitations: - ** Only supports mice on COM port 1 - -*/ - -#include -#include -#include -/* #include */ -#include - -#define MOUSE_IRQ_COM1 4 -#define MOUSE_IRQ_COM2 3 - -#define COM1_PORT 0x3f8 -#define COM2_PORT 0x2f8 - -#define max_screen_x 79 -#define max_screen_y 24 - -static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1; -static unsigned int MOUSE_COM=COM1_PORT; - -static unsigned int bytepos=0, coordinate; -static unsigned char mpacket[3]; -static signed int mouse_x=40, mouse_y=12; -static unsigned char mouse_button1, mouse_button2; -static signed int horiz_sensitivity, vert_sensitivity; - -BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) -{ - unsigned int mbyte=inb(MOUSE_COM); - - // Synchronize - if((mbyte&64)==64) { bytepos=0; }; - - mpacket[bytepos]=mbyte; - bytepos++; - - // Process packet - if(bytepos==3) { - // Retrieve change in x and y from packet - int change_x=((mpacket[0] & 3) << 6) + mpacket[1]; - int change_y=((mpacket[0] & 12) << 4) + mpacket[2]; - - // Some mice need this - if(coordinate==1) { - change_x-=128; - change_y-=128; - }; - - // Change to signed - if(change_x>=128) { change_x=change_x-256; }; - if(change_y>=128) { change_y=change_y-256; }; - - // Adjust mouse position according to sensitivity - mouse_x+=change_x/horiz_sensitivity; - mouse_y+=change_y/vert_sensitivity; - - // Check that mouse is still in screen - if(mouse_x<0) { mouse_x=0; }; - if(mouse_x>max_screen_x) { mouse_x=max_screen_x; }; - if(mouse_y<0) { mouse_y=0; }; - if(mouse_y>max_screen_y) { mouse_y=max_screen_y; }; - - // Retrieve mouse button status from packet - mouse_button1=mpacket[0] & 32; - mouse_button2=mpacket[0] & 16; - - bytepos=0; - }; - -}; - -void InitializeMouseHardware(unsigned int mtype) -{ - char clear_error_bits; - - outb_p(MOUSE_COM+3, 0x80); // set DLAB on - outb_p(MOUSE_COM, 0x60); // speed LO byte - outb_p(MOUSE_COM+1, 0); // speed HI byte - outb_p(MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse - outb_p(MOUSE_COM+1, 0); // set comm and DLAB to 0 - outb_p(MOUSE_COM+4, 1); // DR int enable - - clear_error_bits=inb_p(MOUSE_COM+5); // clear error bits -}; - -int DetMicrosoft(void) -{ - char tmp, ind; - int buttons=0, i; - - outb_p(MOUSE_COM+4, 0x0b); - tmp=inb_p(MOUSE_COM); - - // Check the first for bytes for signs that this is an MS mouse - for(i=0; i<4; i++) { - while((inb_p(MOUSE_COM+5) & 1)==0) ; - ind=inb_p(MOUSE_COM); - if(ind==0x33) buttons=3; - if(ind==0x4d) buttons=2; - }; - - return buttons; -}; - -int CheckMouseType(unsigned int mtype) -{ - unsigned int retval=0; - - InitializeMouseHardware(mtype); - if(mtype==2) retval=DetMicrosoft(); - if(mtype==3) { - outb_p(MOUSE_COM+4, 11); - retval=3; - }; - outb_p(MOUSE_COM+1, 1); - - return retval; -}; - -void ClearMouse(void) -{ - // Waits until the mouse calms down but also quits out after a while - // in case some destructive user wants to keep moving the mouse - // before we're done - - unsigned int restarts=0, i; - for (i=0; i<60000; i++) - { - unsigned temp=inb(MOUSE_COM); - if(temp!=0) { - restarts++; - if(restarts<300000) { - i=0; - } else - { - i=60000; - }; - }; - }; -}; - -void InitializeMouse(void) -{ - int mbuttons=0, gotmouse=0; - ULONG MappedIrq; - KIRQL Dirql; - KAFFINITY Affinity; - PKINTERRUPT IrqObject; - - horiz_sensitivity=2; - vert_sensitivity=3; - - // Check for Microsoft mouse (2 buttons) - if(CheckMouseType(2)!=0) - { - gotmouse=1; - DbgPrint("Microsoft Mouse Detected\n"); - ClearMouse(); - coordinate=0; - }; - - // Check for Microsoft Systems mouse (3 buttons) - if(gotmouse==0) { - if(CheckMouseType(3)!=0) - { - gotmouse=1; - DbgPrint("Microsoft Mouse Detected\n"); - ClearMouse(); - coordinate=1; - }; - }; - - if(gotmouse==0) { - DbgPrint("No Mouse Detected!\n"); - } else { - MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ, - &Dirql, &Affinity); - - IoConnectInterrupt(&IrqObject, microsoft_mouse_handler, NULL, - NULL, MappedIrq, Dirql, Dirql, 0, FALSE, - Affinity, FALSE); - }; -}; - -// For test purposes only -unsigned char get_text_char(int x, int y) -{ - unsigned char getchar; - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - getchar=*vidmem; - return getchar; -}; - -// For test purposes only -unsigned char get_text_color(int x, int y) -{ - unsigned char getcolor; - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - vidmem++; - getcolor=*vidmem; - return getcolor; -}; - -// For test purposes only -void put_text_char(int x, int y, unsigned char putchar[2]) -{ - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - *vidmem=putchar[0]; - vidmem++; - *vidmem=putchar[1]; -}; - -// For test purposes only -void test_mouse(void) -{ - static int i=0, forcechange=0; - static int old_x=40, old_y=12; - static unsigned char old_cursor[2], new_cursor[2]; - - DbgPrint("Testing mouse..."); - - old_cursor[0]=' '; - old_cursor[1]=7; - new_cursor[0]='Û'; - new_cursor[1]=15; - - old_cursor[0]=get_text_char(mouse_x, mouse_y); - old_cursor[1]=get_text_color(mouse_x, mouse_y); - put_text_char(mouse_x, mouse_y, new_cursor); - - while(i!=1) - { - if(mouse_button1!=0) { new_cursor[1]=10; mouse_button1=0; forcechange=1; }; - if(mouse_button2!=0) { new_cursor[1]=12; mouse_button2=0; forcechange=1; }; - - if((mouse_x!=old_x) || (mouse_y!=old_y) || (forcechange==1)) { - forcechange=0; - - put_text_char(old_x, old_y, old_cursor); - old_cursor[0]=get_text_char(mouse_x, mouse_y); - old_cursor[1]=get_text_color(mouse_x, mouse_y); - put_text_char(mouse_x, mouse_y, new_cursor); - - old_x=mouse_x; - old_y=mouse_y; - }; - }; -}; - -NTSTATUS STDCALL -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) -{ - DbgPrint("Mouse Driver 0.0.3\n"); - InitializeMouse(); - test_mouse(); - - return(STATUS_SUCCESS); -}; - diff --git a/drivers/dd/vga/display/main/enable.c b/drivers/dd/vga/display/main/enable.c index 7d7e2d2..0a932a2 100644 --- a/drivers/dd/vga/display/main/enable.c +++ b/drivers/dd/vga/display/main/enable.c @@ -9,6 +9,7 @@ #include "gdiinfo.h" #include "../vgavideo/vgavideo.h" +#define NDEBUG #include #define DBG_PREFIX "VGADDI: " @@ -20,6 +21,7 @@ DRVFN FuncList[] = /* Required Display driver fuctions */ {INDEX_DrvAssertMode, (PFN) DrvAssertMode}, {INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV}, + {INDEX_DrvCopyBits, (PFN) DrvCopyBits}, {INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV}, {INDEX_DrvDisableSurface, (PFN) DrvDisableSurface}, {INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV}, @@ -208,7 +210,7 @@ DrvAssertMode(IN DHPDEV DPev, } VGAInitialized = FALSE; } - + return TRUE; } diff --git a/drivers/dd/vga/display/makefile b/drivers/dd/vga/display/makefile index 8babf88..e4ebc31 100644 --- a/drivers/dd/vga/display/makefile +++ b/drivers/dd/vga/display/makefile @@ -18,7 +18,8 @@ OTHER_OBJECTS = \ objects/paint.o \ objects/bitblt.o \ objects/transblt.o \ - objects/offscreen.o + objects/offscreen.o \ + objects/copybits.o VGAVIDEO_OBJECTS = \ vgavideo/vgavideo.o diff --git a/drivers/dd/vga/display/objects/bitblt.c b/drivers/dd/vga/display/objects/bitblt.c index 02fd0bc..30c7f8c 100644 --- a/drivers/dd/vga/display/objects/bitblt.c +++ b/drivers/dd/vga/display/objects/bitblt.c @@ -15,7 +15,7 @@ DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, LONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, c8; BYTE *GDIpos, *initial, *tMask, *lMask; - GDIpos = Source->pvBits; + GDIpos = Source->pvScan0; dx = DestRect->right - DestRect->left; dy = DestRect->bottom - DestRect->top; @@ -23,9 +23,10 @@ DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation, alterx = abs(SourcePoint->x - DestRect->left); altery = abs(SourcePoint->y - DestRect->top); - if (ColorTranslation == NULL) + if (NULL == ColorTranslation) { - DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, + DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, + Source->pvScan0 + SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1), Source->lDelta); } else @@ -369,8 +370,15 @@ DrvBitBlt(SURFOBJ *Dest, BrushPoint, rop4)); case SRCCOPY: - return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, - SourcePoint)); + if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat) + { + return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, + SourcePoint)); + } + else + { + return FALSE; + } case 0xAACC: return(VGADDI_BltMask(Dest, Mask, ColorTranslation, DestRect, diff --git a/drivers/dd/vga/display/objects/copybits.c b/drivers/dd/vga/display/objects/copybits.c new file mode 100644 index 0000000..242a9ef --- /dev/null +++ b/drivers/dd/vga/display/objects/copybits.c @@ -0,0 +1,39 @@ +#include "../vgaddi.h" +#include "../vgavideo/vgavideo.h" + +#define DBG +#include + +BOOL STDCALL +DrvCopyBits(OUT PSURFOBJ DestObj, + IN PSURFOBJ SourceObj, + IN PCLIPOBJ ClipObj, + IN PXLATEOBJ XLateObj, + IN PRECTL DestRectL, + IN PPOINTL SrcPointL) +{ + BOOL Done = FALSE; + + if (STYPE_BITMAP == DestObj->iType && BMF_4BPP == DestObj->iBitmapFormat && + STYPE_DEVICE == SourceObj->iType) + { + /* Screen to 4 BPP DIB */ + DIB_BltFromVGA(SrcPointL->x, SrcPointL->y, + DestRectL->right - DestRectL->left, + DestRectL->bottom - DestRectL->top, + DestObj->pvScan0, DestObj->lDelta); + Done = TRUE; + } + else if (STYPE_DEVICE == DestObj->iType && + STYPE_BITMAP == SourceObj->iType && BMF_4BPP == SourceObj->iBitmapFormat) + { + /* 4 BPP DIB to Screen */ + DIB_BltToVGA(DestRectL->left, DestRectL->top, + DestRectL->right - DestRectL->left, + DestRectL->bottom - DestRectL->top, + SourceObj->pvScan0, SourceObj->lDelta); + Done = TRUE; + } + + return Done; +} diff --git a/drivers/dd/vga/display/objects/lineto.c b/drivers/dd/vga/display/objects/lineto.c index 6345306..6fceab6 100644 --- a/drivers/dd/vga/display/objects/lineto.c +++ b/drivers/dd/vga/display/objects/lineto.c @@ -17,87 +17,84 @@ DrvLineTo(SURFOBJ *Surface, // FIXME: Use Mix to perform ROPs { - ULONG x, y, d, i, length, xchange, ychange, error, - iSolidColor, hx, vy; - LONG deltax, deltay; + LONG deltax, deltay, x, y, d, i, xchange, ychange, error, iSolidColor, hx, vy; - iSolidColor = Brush->iSolidColor; // FIXME: Brush Realization... + iSolidColor = Brush->iSolidColor; // FIXME: Brush Realization... - // FIXME: Implement clipping + // FIXME: Implement clipping - x=x1; - y=y1; - deltax=x2-x1; - deltay=y2-y1; + x = x1; + y = y1; + deltax = x2 - x1; + deltay = y2 - y1; - if(deltax<0) - { - xchange=-1; - deltax=-deltax; - hx = x2; - } else - { - xchange=1; - hx = x1; - } + if (deltax < 0) + { + xchange = -1; + deltax = - deltax; + hx = x2; + x--; + } + else + { + xchange = 1; + hx = x1; + } - if(deltay<0) - { - ychange=-1; - deltay=-deltay; - vy = y2; - } else - { - ychange=1; - vy = y1; - }; + if (deltay < 0) + { + ychange = -1; + deltay = - deltay; + vy = y2; + y--; + } + else + { + ychange = 1; + vy = y1; + }; - if(y1==y2) - { - return vgaHLine(hx, y1, deltax, iSolidColor); - } - if(x1==x2) - { - return vgaVLine(x1, vy, deltay, iSolidColor); - } + if (y1 == y2) + { + return vgaHLine(hx, y1, deltax, iSolidColor); + } + if (x1 == x2) + { + return vgaVLine(x1, vy, deltay, iSolidColor); + } // Using individual pixels to draw a line neither horizontal or vertical // Set up the VGA masking for individual pixels + error = 0; - error=0; - i=0; - - if(deltaxdeltay) + if (deltay <= error) { - x=x+xchange; - error=error-deltay; + x = x + xchange; + error = error - deltay; } - i=i+1; - } - } else - { - length=deltax+1; - while(ideltax) - { - y=y+ychange; - error=error-deltax; - } - i=i+1; + for (i = 0; i < deltax; i++) + { + vgaPutPixel(x, y, iSolidColor); + x = x + xchange; + error = error + deltay; + if (deltax <= error) + { + y = y + ychange; + error = error - deltax; + } } } diff --git a/drivers/dd/vga/display/objects/pointer.c b/drivers/dd/vga/display/objects/pointer.c index 8b6460a..724bfd6 100644 --- a/drivers/dd/vga/display/objects/pointer.c +++ b/drivers/dd/vga/display/objects/pointer.c @@ -76,9 +76,10 @@ VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, /* Write the mask. */ Video = (PUCHAR)vidmem + StartY * 80 + (StartX >> 3); - Src = MaskBits; - for (i = 0; i < SizeY; i++, Video+=80, Src+=MaskPitch) + Src = MaskBits + SizeY * MaskPitch; + for (i = 0; i < SizeY; i++, Video+=80) { + Src -= MaskPitch; SrcValue = (*Src) >> (StartX % 8); (VOID)READ_REGISTER_UCHAR(Video); WRITE_REGISTER_UCHAR(Video, SrcValue); @@ -101,7 +102,7 @@ VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, for (i = StartY; i < EndY; i++) { Video = (PUCHAR)vidmem + i * 80 + (Left >> 3); - Src = MaskBits + (i - StartY) * MaskPitch; + Src = MaskBits + (EndY - i - 1) * MaskPitch; for (j = 0; j < Length; j++, Video++, Src++) { if ((StartX % 8) != 0) @@ -127,9 +128,10 @@ VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); Video = (PUCHAR)vidmem + StartY * 80 + (EndX >> 3); - Src = MaskBits + (SizeX >> 3) - 1; - for (i = StartY; i < EndY; i++, Video+=80, Src+=MaskPitch) + Src = MaskBits + SizeY * MaskPitch + (SizeX >> 3) - 1; + for (i = StartY; i < EndY; i++, Video+=80) { + Src -= MaskPitch; SrcValue = (Src[0] << (8 - (StartX % 8))); (VOID)READ_REGISTER_UCHAR(Video); WRITE_REGISTER_UCHAR(Video, SrcValue); @@ -279,6 +281,8 @@ DrvSetPointerShape(PSURFOBJ pso, /* Show the cursor */ VGADDI_ShowCursor(ppdev); + + return SPS_ACCEPT_EXCLUDE; } VOID @@ -303,7 +307,7 @@ VOID VGADDI_ShowCursor(PPDEV ppdev) { ULONG i, j, cx, cy; - PUCHAR AndMask; + PUCHAR XorMask; ULONG SizeX; if (ppdev->pPointerAttributes->Enable != 0) @@ -326,20 +330,20 @@ VGADDI_ShowCursor(PPDEV ppdev) ppdev->pPointerAttributes->Height); /* Display the cursor. */ - AndMask = ppdev->pPointerAttributes->Pixels + + XorMask = ppdev->pPointerAttributes->Pixels + ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height; VGADDI_BltPointerToVGA(ppdev->xyCursor.x, ppdev->xyCursor.y, ppdev->pPointerAttributes->Width, ppdev->pPointerAttributes->Height, - AndMask, + ppdev->pPointerAttributes->Pixels, VGA_AND); VGADDI_BltPointerToVGA(ppdev->xyCursor.x, ppdev->xyCursor.y, ppdev->pPointerAttributes->Width, ppdev->pPointerAttributes->Height, - ppdev->pPointerAttributes->Pixels, + XorMask, VGA_XOR); /* Save the new cursor location. */ diff --git a/drivers/dd/vga/display/vgavideo/vgavideo.c b/drivers/dd/vga/display/vgavideo/vgavideo.c index ca644f1..7d9aa8d 100644 --- a/drivers/dd/vga/display/vgavideo/vgavideo.c +++ b/drivers/dd/vga/display/vgavideo/vgavideo.c @@ -266,49 +266,65 @@ BOOL vgaHLine(INT x, INT y, INT len, UCHAR c) { for (i=x; i0) - { - // Write left pixels - WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // set the mask - WRITE_PORT_UCHAR((PUCHAR)0x3cf,startmasks[ileftpix]); + if(ileftpix == 8) + { + ileftpix = 0; + imidpix++; + } - a = READ_REGISTER_UCHAR(vidmem + pre1); - WRITE_REGISTER_UCHAR(vidmem + pre1, c); + pre1=xconv[x-(8-ileftpix)]+y80[y]; + orgpre1=pre1; - // Prepare new x for the middle - x=orgx+8; - } + // Left + if(ileftpix>0) + { + // Write left pixels + WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); // set the mask + WRITE_PORT_UCHAR((PUCHAR)0x3cf,startmasks[ileftpix]); - if(imidpix>0) - { - midpre1=xconv[x]+y80[y]; + a = READ_REGISTER_UCHAR(vidmem + pre1); + WRITE_REGISTER_UCHAR(vidmem + pre1, c); - // Set mask to all pixels in byte - WRITE_PORT_UCHAR((PUCHAR)0x3ce, 0x08); - WRITE_PORT_UCHAR((PUCHAR)0x3cf, 0xff); - memset(vidmem+midpre1, c, imidpix); // write middle pixels, no need to read in latch because of the width - } + // Prepare new x for the middle + x=orgx+8; + } + if(imidpix>0) + { + midpre1=xconv[x]+y80[y]; + + // Set mask to all pixels in byte + WRITE_PORT_UCHAR((PUCHAR)0x3ce, 0x08); + WRITE_PORT_UCHAR((PUCHAR)0x3cf, 0xff); + memset(vidmem+midpre1, c, imidpix); // write middle pixels, no need to read in latch because of the width + } + + if(irightpix>0) + { x=orgx+len-irightpix; - pre1=xconv[x]+y80[y]; + + for(i=x; i +#include +#include + +#include "../../../ntoskrnl/include/internal/v86m.h" + +#define NDEBUG +#include + +#define VERSION "0.0.0" + +#define TAG_VIDEO_PORT TAG('V', 'I', 'D', 'P') + +typedef struct _VIDEO_PORT_ADDRESS_MAPPING +{ + LIST_ENTRY List; + + PVOID MappedAddress; + ULONG NumberOfUchars; + PHYSICAL_ADDRESS IoAddress; + ULONG SystemIoBusNumber; + UINT MappingCount; +} VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING; + +typedef struct _VIDEO_PORT_DEVICE_EXTENSTION +{ + PDEVICE_OBJECT DeviceObject; + PKINTERRUPT InterruptObject; + KSPIN_LOCK InterruptSpinLock; + ULONG InterruptLevel; + KIRQL IRQL; + KAFFINITY Affinity; + PVIDEO_HW_INITIALIZE HwInitialize; + LIST_ENTRY AddressMappingListHead; + INTERFACE_TYPE AdapterInterfaceType; + ULONG SystemIoBusNumber; + UNICODE_STRING RegistryPath; + + UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */ +} VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION; + + +static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp); +static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +static PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace); +static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PVOID MappedAddress); + +static BOOLEAN CsrssInitialized = FALSE; +static HANDLE CsrssHandle = 0; +static struct _EPROCESS* Csrss = NULL; + +PBYTE ReturnCsrssAddress(void) +{ + DPRINT("ReturnCsrssAddress()\n"); + return (PBYTE)Csrss; +} + +// ------------------------------------------------------- Public Interface + +// DriverEntry +// +// DESCRIPTION: +// This function initializes the driver. +// +// RUN LEVEL: +// PASSIVE_LEVEL +// +// ARGUMENTS: +// IN PDRIVER_OBJECT DriverObject System allocated Driver Object +// for this driver +// IN PUNICODE_STRING RegistryPath Name of registry driver service +// key +// +// RETURNS: +// NTSTATUS + +STDCALL NTSTATUS +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + DPRINT("DriverEntry()\n"); + return(STATUS_SUCCESS); +} + +VOID +VideoPortDebugPrint(IN ULONG DebugPrintLevel, + IN PCHAR DebugMessage, ...) +{ + char Buffer[256]; + va_list ap; + +/* + if (DebugPrintLevel > InternalDebugLevel) + return; +*/ + va_start (ap, DebugMessage); + vsprintf (Buffer, DebugMessage, ap); + va_end (ap); + + DbgPrint (Buffer); +} + +VP_STATUS +STDCALL +VideoPortDisableInterrupt(IN PVOID HwDeviceExtension) +{ + DPRINT("VideoPortDisableInterrupt\n"); + UNIMPLEMENTED; +} + +VP_STATUS +STDCALL +VideoPortEnableInterrupt(IN PVOID HwDeviceExtension) +{ + DPRINT("VideoPortEnableInterrupt\n"); + UNIMPLEMENTED; +} + +VOID +STDCALL +VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension, + IN PVOID MappedAddress) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortFreeDeviceBase\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + InternalUnmapMemory(DeviceExtension, MappedAddress); +} + +ULONG +STDCALL +VideoPortGetBusData(IN PVOID HwDeviceExtension, + IN BUS_DATA_TYPE BusDataType, + IN ULONG SlotNumber, + OUT PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetBusData\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + return HalGetBusDataByOffset(BusDataType, + DeviceExtension->SystemIoBusNumber, + SlotNumber, + Buffer, + Offset, + Length); +} + +UCHAR +STDCALL +VideoPortGetCurrentIrql(VOID) +{ + DPRINT("VideoPortGetCurrentIrql\n"); + return KeGetCurrentIrql(); +} + +PVOID +STDCALL +VideoPortGetDeviceBase(IN PVOID HwDeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetDeviceBase\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace); +} + +VP_STATUS +STDCALL +VideoPortGetDeviceData(IN PVOID HwDeviceExtension, + IN VIDEO_DEVICE_DATA_TYPE DeviceDataType, + IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine, + IN PVOID Context) +{ + DPRINT("VideoPortGetDeviceData\n"); + UNIMPLEMENTED; +} + +VP_STATUS +STDCALL +VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, + IN ULONG NumRequestedResources, + IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL, + IN ULONG NumAccessRanges, + IN PVIDEO_ACCESS_RANGE AccessRanges, + IN PVOID VendorId, + IN PVOID DeviceId, + IN PULONG Slot) +{ + PCI_SLOT_NUMBER PciSlotNumber; + BOOLEAN FoundDevice; + ULONG FunctionNumber; + PCI_COMMON_CONFIG Config; + PCM_RESOURCE_LIST AllocatedResources; + NTSTATUS Status; + UINT AssignedCount; + CM_FULL_RESOURCE_DESCRIPTOR *FullList; + CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortGetAccessRanges\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType) + { + DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId), + (int)*((USHORT *) DeviceId)); + FoundDevice = FALSE; + PciSlotNumber.u.AsULONG = *Slot; + for (FunctionNumber = 0; ! FoundDevice && FunctionNumber < 8; FunctionNumber++) + { + PciSlotNumber.u.bits.FunctionNumber = FunctionNumber; + if (sizeof(PCI_COMMON_CONFIG) == + HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber, + PciSlotNumber.u.AsULONG,&Config, 0, + sizeof(PCI_COMMON_CONFIG))) + { + DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n", + PciSlotNumber.u.AsULONG, PciSlotNumber.u.bits.DeviceNumber, + PciSlotNumber.u.bits.FunctionNumber, Config.VendorID, Config.DeviceID); + FoundDevice = (Config.VendorID == *((USHORT *) VendorId) && + Config.DeviceID == *((USHORT *) DeviceId)); + } + } + if (! FoundDevice) + { + return STATUS_UNSUCCESSFUL; + } + Status = HalAssignSlotResources(NULL, NULL, NULL, NULL, + DeviceExtension->AdapterInterfaceType, + DeviceExtension->SystemIoBusNumber, + PciSlotNumber.u.AsULONG, &AllocatedResources); + if (! NT_SUCCESS(Status)) + { + return Status; + } + AssignedCount = 0; + for (FullList = AllocatedResources->List; + FullList < AllocatedResources->List + AllocatedResources->Count && + AssignedCount < NumAccessRanges; + FullList++) + { + assert(FullList->InterfaceType == PCIBus && + FullList->BusNumber == DeviceExtension->SystemIoBusNumber && + 1 == FullList->PartialResourceList.Version && + 1 == FullList->PartialResourceList.Revision); + for (Descriptor = FullList->PartialResourceList.PartialDescriptors; + Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count && + AssignedCount < NumAccessRanges; + Descriptor++) + { + if (CmResourceTypeMemory == Descriptor->Type) + { + DPRINT("Memory range starting at 0x%08x length 0x%08x\n", + Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length); + AccessRanges[AssignedCount].RangeStart = Descriptor->u.Memory.Start; + AccessRanges[AssignedCount].RangeLength = Descriptor->u.Memory.Length; + AccessRanges[AssignedCount].RangeInIoSpace = 0; + AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ + AccessRanges[AssignedCount].RangeShareable = + (CmResourceShareShared == Descriptor->ShareDisposition); + } + else if (CmResourceTypePort == Descriptor->Type) + { + DPRINT("Port range starting at 0x%04x length %d\n", + Descriptor->u.Memory.Start.u.LowPart, Descriptor->u.Memory.Length); + AccessRanges[AssignedCount].RangeStart = Descriptor->u.Port.Start; + AccessRanges[AssignedCount].RangeLength = Descriptor->u.Port.Length; + AccessRanges[AssignedCount].RangeInIoSpace = 1; + AccessRanges[AssignedCount].RangeVisible = 0; /* FIXME: Just guessing */ + AccessRanges[AssignedCount].RangeShareable = 0; + } + else + { + ExFreePool(AllocatedResources); + return STATUS_UNSUCCESSFUL; + } + AssignedCount++; + } + } + ExFreePool(AllocatedResources); + } + else + { + UNIMPLEMENTED + } + + return STATUS_SUCCESS; +} + +VP_STATUS +STDCALL +VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension, + IN PWSTR ParameterName, + IN UCHAR IsParameterFileName, + IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine, + IN PVOID Context) +{ + DPRINT("VideoPortGetRegistryParameters\n"); + DPRINT("ParameterName %S\n", ParameterName); + return STATUS_OBJECT_NAME_NOT_FOUND; +/* + return NO_ERROR; +*/ +} + +ULONG STDCALL +VideoPortInitialize(IN PVOID Context1, + IN PVOID Context2, + IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, + IN PVOID HwContext) +{ + PUNICODE_STRING RegistryPath; + UCHAR Again; + WCHAR DeviceBuffer[20]; + WCHAR SymlinkBuffer[20]; + WCHAR DeviceVideoBuffer[20]; + NTSTATUS Status; + PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1; + PDEVICE_OBJECT MPDeviceObject; + VIDEO_PORT_CONFIG_INFO ConfigInfo; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + ULONG DeviceNumber = 0; + UNICODE_STRING DeviceName; + UNICODE_STRING SymlinkName; + ULONG MaxBus; + ULONG MaxLen; + + DPRINT("VideoPortInitialize\n"); + + RegistryPath = (PUNICODE_STRING) Context2; + + /* Build Dispatch table from passed data */ + MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO; + + /* Create a unicode device name */ + Again = FALSE; + do + { + swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber); + RtlInitUnicodeString(&DeviceName, DeviceBuffer); + + /* Create the device */ + Status = IoCreateDevice(MPDriverObject, + HwInitializationData->HwDeviceExtensionSize + + sizeof(VIDEO_PORT_DEVICE_EXTENSION), + &DeviceName, + FILE_DEVICE_VIDEO, + 0, + TRUE, + &MPDeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status); + return Status; + } + + MPDriverObject->DeviceObject = MPDeviceObject; + + /* Initialize the miniport drivers dispatch table */ + MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose; + MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose; + MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl; + + /* Initialize our device extension */ + DeviceExtension = + (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension; + DeviceExtension->DeviceObject = MPDeviceObject; + DeviceExtension->HwInitialize = HwInitializationData->HwInitialize; + DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType; + DeviceExtension->SystemIoBusNumber = 0; + MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR); + DeviceExtension->RegistryPath.MaximumLength = MaxLen; + DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, + MaxLen, + TAG_VIDEO_PORT); + swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device%d", + RegistryPath->Buffer, DeviceNumber); + DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) * + sizeof(WCHAR); + + MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1; + DPRINT("MaxBus: %lu\n", MaxBus); + InitializeListHead(&DeviceExtension->AddressMappingListHead); + + /* Set the buffering strategy here... */ + /* If you change this, remember to change VidDispatchDeviceControl too */ + MPDeviceObject->Flags |= DO_BUFFERED_IO; + + do + { + RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, + HwInitializationData->HwDeviceExtensionSize); + DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber); + /* Setup configuration info */ + RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO)); + ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO); + ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType; + ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; + ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ? + LevelSensitive : Latched; + + /* Call HwFindAdapter entry point */ + /* FIXME: Need to figure out what string to pass as param 3 */ + Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension, + Context2, + NULL, + &ConfigInfo, + &Again); + if (NO_ERROR != Status) + { + DPRINT("HwFindAdapter call failed with error %d\n", Status); + DeviceExtension->SystemIoBusNumber++; + } + } + while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus); + + if (NO_ERROR != Status) + { + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(MPDeviceObject); + + return Status; + } + DPRINT("Found adapter\n"); + + /* create symbolic link "\??\DISPLAYx" */ + swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1); + RtlInitUnicodeString (&SymlinkName, + SymlinkBuffer); + IoCreateSymbolicLink (&SymlinkName, + &DeviceName); + + /* Add entry to DEVICEMAP\VIDEO key in registry */ + swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber); + RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, + L"VIDEO", + DeviceVideoBuffer, + REG_SZ, + DeviceExtension->RegistryPath.Buffer, + DeviceExtension->RegistryPath.Length + sizeof(WCHAR)); + + /* FIXME: Allocate hardware resources for device */ + + /* Allocate interrupt for device */ + if (HwInitializationData->HwInterrupt != NULL && + !(ConfigInfo.BusInterruptLevel == 0 && + ConfigInfo.BusInterruptVector == 0)) + { +#if 0 + DeviceExtension->IRQL = ConfigInfo.BusInterruptLevel; + DeviceExtension->InterruptLevel = + HalGetInterruptVector(ConfigInfo.AdapterInterfaceType, + ConfigInfo.SystemIoBusNumber, + ConfigInfo.BusInterruptLevel, + ConfigInfo.BusInterruptVector, + &DeviceExtension->IRQL, + &DeviceExtension->Affinity); + KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock); + Status = IoConnectInterrupt(&DeviceExtension->InterruptObject, + (PKSERVICE_ROUTINE) + HwInitializationData->HwInterrupt, + &DeviceExtension->MiniPortDeviceExtension, + &DeviceExtension->InterruptSpinLock, + DeviceExtension->InterruptLevel, + DeviceExtension->IRQL, + DeviceExtension->IRQL, + ConfigInfo.InterruptMode, + FALSE, + DeviceExtension->Affinity, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoConnectInterrupt failed with status 0x%08x\n", Status); + IoDeleteDevice(MPDeviceObject); + + return Status; + } +#endif + } + DeviceNumber++; + } + while (Again); + + /* FIXME: initialize timer routine for MP Driver */ + if (HwInitializationData->HwTimer != NULL) + { + Status = IoInitializeTimer(MPDeviceObject, + (PIO_TIMER_ROUTINE) + HwInitializationData->HwTimer, + &DeviceExtension->MiniPortDeviceExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status); + + if (HwInitializationData->HwInterrupt != NULL) + { + IoDisconnectInterrupt(DeviceExtension->InterruptObject); + } + IoDeleteDevice(MPDeviceObject); + + return Status; + } + } + + return STATUS_SUCCESS; +} + +VP_STATUS STDCALL +VideoPortInt10(IN PVOID HwDeviceExtension, + IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments) +{ + KV86M_REGISTERS Regs; + NTSTATUS Status; + + DPRINT("VideoPortInt10\n"); + KeAttachProcess(Csrss); + + memset(&Regs, 0, sizeof(Regs)); + Regs.Eax = BiosArguments->Eax; + Regs.Ebx = BiosArguments->Ebx; + Regs.Ecx = BiosArguments->Ecx; + Regs.Edx = BiosArguments->Edx; + Regs.Esi = BiosArguments->Esi; + Regs.Edi = BiosArguments->Edi; + Regs.Ebp = BiosArguments->Ebp; + Status = Ke386CallBios(0x10, &Regs); + + KeDetachProcess(); + + return(Status); +} + +VOID +STDCALL +VideoPortLogError(IN PVOID HwDeviceExtension, + IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, + IN VP_STATUS ErrorCode, + IN ULONG UniqueId) +{ + DPRINT("VideoPortLogError\n"); + UNIMPLEMENTED; +} + +VP_STATUS +STDCALL +VideoPortMapBankedMemory(IN PVOID HwDeviceExtension, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN PULONG Length, + IN PULONG InIoSpace, + OUT PVOID *VirtualAddress, + IN ULONG BankLength, + IN UCHAR ReadWriteBank, + IN PBANKED_SECTION_ROUTINE BankRoutine, + IN PVOID Context) +{ + DPRINT("VideoPortMapBankedMemory\n"); + UNIMPLEMENTED; +} + +VP_STATUS +STDCALL +VideoPortMapMemory(IN PVOID HwDeviceExtension, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN PULONG Length, + IN PULONG InIoSpace, + OUT PVOID *VirtualAddress) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + PLIST_ENTRY Entry; + + DPRINT("VideoPortMapMemory\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress, + *Length, *InIoSpace); + + return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS; +} + +UCHAR +STDCALL +VideoPortReadPortUchar(IN PUCHAR Port) +{ + DPRINT("VideoPortReadPortUchar\n"); + return READ_PORT_UCHAR(Port); +} + +USHORT +STDCALL +VideoPortReadPortUshort(IN PUSHORT Port) +{ + DPRINT("VideoPortReadPortUshort\n"); + return READ_PORT_USHORT(Port); +} + +ULONG +STDCALL +VideoPortReadPortUlong(IN PULONG Port) +{ + DPRINT("VideoPortReadPortUlong\n"); + return READ_PORT_ULONG(Port); +} + +VOID +STDCALL +VideoPortReadPortBufferUchar(IN PUCHAR Port, + OUT PUCHAR Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortBufferUchar\n"); + READ_PORT_BUFFER_UCHAR(Port, Buffer, Count); +} + +VOID +STDCALL +VideoPortReadPortBufferUshort(IN PUSHORT Port, + OUT PUSHORT Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortBufferUshort\n"); + READ_PORT_BUFFER_USHORT(Port, Buffer, Count); +} + +VOID +STDCALL +VideoPortReadPortBufferUlong(IN PULONG Port, + OUT PULONG Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortBufferUlong\n"); + READ_PORT_BUFFER_ULONG(Port, Buffer, Count); +} + +UCHAR +STDCALL +VideoPortReadRegisterUchar(IN PUCHAR Register) +{ + DPRINT("VideoPortReadPortRegisterUchar\n"); + return READ_REGISTER_UCHAR(Register); +} + +USHORT +STDCALL +VideoPortReadRegisterUshort(IN PUSHORT Register) +{ + DPRINT("VideoPortReadPortRegisterUshort\n"); + return READ_REGISTER_USHORT(Register); +} + +ULONG +STDCALL +VideoPortReadRegisterUlong(IN PULONG Register) +{ + DPRINT("VideoPortReadPortRegisterUlong\n"); + return READ_REGISTER_ULONG(Register); +} + +VOID +STDCALL +VideoPortReadRegisterBufferUchar(IN PUCHAR Register, + OUT PUCHAR Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortRegisterBufferUchar\n"); + READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count); +} + +VOID +STDCALL +VideoPortReadRegisterBufferUshort(IN PUSHORT Register, + OUT PUSHORT Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortRegisterBufferUshort\n"); + READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count); +} + +VOID +STDCALL +VideoPortReadRegisterBufferUlong(IN PULONG Register, + OUT PULONG Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortReadPortRegisterBufferUlong\n"); + READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count); +} + +BOOLEAN +STDCALL +VideoPortScanRom(IN PVOID HwDeviceExtension, + IN PUCHAR RomBase, + IN ULONG RomLength, + IN PUCHAR String) +{ + DPRINT("VideoPortScanRom\n"); + UNIMPLEMENTED; +} + +ULONG +STDCALL +VideoPortSetBusData(IN PVOID HwDeviceExtension, + IN BUS_DATA_TYPE BusDataType, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length) +{ + DPRINT("VideoPortSetBusData\n"); + return HalSetBusDataByOffset(BusDataType, + 0, + SlotNumber, + Buffer, + Offset, + Length); +} + +VP_STATUS +STDCALL +VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, + IN PWSTR ValueName, + IN PVOID ValueData, + IN ULONG ValueLength) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoSetRegistryParameters\n"); + + assert_irql(PASSIVE_LEVEL); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, + DeviceExtension->RegistryPath.Buffer, + ValueName, + REG_BINARY, + ValueData, + ValueLength); +} + +VP_STATUS +STDCALL +VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension, + IN ULONG NumAccessRanges, + IN PVIDEO_ACCESS_RANGE AccessRange) +{ + DPRINT("VideoPortSetTrappedEmulatorPorts\n"); + UNIMPLEMENTED; +} + +VOID +STDCALL +VideoPortStartTimer(IN PVOID HwDeviceExtension) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortStartTimer\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + IoStartTimer(DeviceExtension->DeviceObject); +} + +VOID +STDCALL +VideoPortStopTimer(IN PVOID HwDeviceExtension) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortStopTimer\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + IoStopTimer(DeviceExtension->DeviceObject); +} + +BOOLEAN +STDCALL +VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension, + IN VIDEO_SYNCHRONIZE_PRIORITY Priority, + IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, + OUT PVOID Context) +{ + DPRINT("VideoPortSynchronizeExecution\n"); + UNIMPLEMENTED; +} + +VP_STATUS +STDCALL +VideoPortUnmapMemory(IN PVOID HwDeviceExtension, + IN PVOID VirtualAddress, + IN HANDLE ProcessHandle) +{ + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortFreeDeviceBase\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + InternalUnmapMemory(DeviceExtension, VirtualAddress); + + return STATUS_SUCCESS; +} + +VP_STATUS +STDCALL +VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension, + IN ULONG NumAccessRanges, + IN PVIDEO_ACCESS_RANGE AccessRanges) +{ + DPRINT1("VideoPortVerifyAccessRanges not implemented\n"); + return NO_ERROR; +} + +VOID +STDCALL +VideoPortWritePortUchar(IN PUCHAR Port, + IN UCHAR Value) +{ + DPRINT("VideoPortWritePortUchar\n"); + WRITE_PORT_UCHAR(Port, Value); +} + +VOID +STDCALL +VideoPortWritePortUshort(IN PUSHORT Port, + IN USHORT Value) +{ + DPRINT("VideoPortWritePortUshort\n"); + WRITE_PORT_USHORT(Port, Value); +} + +VOID +STDCALL +VideoPortWritePortUlong(IN PULONG Port, + IN ULONG Value) +{ + DPRINT("VideoPortWritePortUlong\n"); + WRITE_PORT_ULONG(Port, Value); +} + +VOID +STDCALL +VideoPortWritePortBufferUchar(IN PUCHAR Port, + IN PUCHAR Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWritePortBufferUchar\n"); + WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count); +} + +VOID +STDCALL +VideoPortWritePortBufferUshort(IN PUSHORT Port, + IN PUSHORT Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWritePortBufferUshort\n"); + WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count); +} + +VOID +STDCALL +VideoPortWritePortBufferUlong(IN PULONG Port, + IN PULONG Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWritePortBufferUlong\n"); + WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count); +} + +VOID +STDCALL +VideoPortWriteRegisterUchar(IN PUCHAR Register, + IN UCHAR Value) +{ + DPRINT("VideoPortWriteRegisterUchar\n"); + WRITE_REGISTER_UCHAR(Register, Value); +} + +VOID +STDCALL +VideoPortWriteRegisterUshort(IN PUSHORT Register, + IN USHORT Value) +{ + DPRINT("VideoPortWriteRegisterUshort\n"); + WRITE_REGISTER_USHORT(Register, Value); +} + +VOID +STDCALL +VideoPortWriteRegisterUlong(IN PULONG Register, + IN ULONG Value) +{ + DPRINT("VideoPortWriteRegisterUlong\n"); + WRITE_REGISTER_ULONG(Register, Value); +} + +VOID +STDCALL +VideoPortWriteRegisterBufferUchar(IN PUCHAR Register, + IN PUCHAR Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWriteRegisterBufferUchar\n"); + WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count); +} + +VOID STDCALL +VideoPortWriteRegisterBufferUshort(IN PUSHORT Register, + IN PUSHORT Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWriteRegisterBufferUshort\n"); + WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count); +} + +VOID STDCALL +VideoPortWriteRegisterBufferUlong(IN PULONG Register, + IN PULONG Buffer, + IN ULONG Count) +{ + DPRINT("VideoPortWriteRegisterBufferUlong\n"); + WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count); +} + +VOID STDCALL +VideoPortZeroDeviceMemory(OUT PVOID Destination, + IN ULONG Length) +{ + DPRINT("VideoPortZeroDeviceMemory\n"); + RtlZeroMemory(Destination, Length); +} + + +// ------------------------------------------- Nondiscardable statics + +// VidDispatchOpenClose +// +// DESCRIPTION: +// Answer requests for Open/Close calls: a null operation +// +// RUN LEVEL: +// PASSIVE_LEVEL +// +// ARGUMENTS: +// Standard dispatch arguments +// +// RETURNS: +// NTSTATUS +// + +static NTSTATUS STDCALL +VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpStack; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VidDispatchOpenClose() called\n"); + + IrpStack = IoGetCurrentIrpStackLocation(Irp); + + if (IrpStack->MajorFunction == IRP_MJ_CREATE && + CsrssInitialized == FALSE) + { + DPRINT("Referencing CSRSS\n"); + Csrss = PsGetCurrentProcess(); + CsrssInitialized = TRUE; + DPRINT("Csrss %p\n", Csrss); + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension; + if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension)) + { + Irp->IoStatus.Status = STATUS_SUCCESS; + } + else + { + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + } + } + else + { + Irp->IoStatus.Status = STATUS_SUCCESS; + } + + Irp->IoStatus.Information = FILE_OPENED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +// VidStartIo +// +// DESCRIPTION: +// Get the next requested I/O packet started +// +// RUN LEVEL: +// DISPATCH_LEVEL +// +// ARGUMENTS: +// Dispatch routine standard arguments +// +// RETURNS: +// NTSTATUS +// + +static VOID STDCALL +VidStartIo(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("VidStartIo\n"); + UNIMPLEMENTED; +} + +// VidDispatchDeviceControl +// +// DESCRIPTION: +// Answer requests for device control calls +// +// RUN LEVEL: +// PASSIVE_LEVEL +// +// ARGUMENTS: +// Standard dispatch arguments +// +// RETURNS: +// NTSTATUS +// + +static NTSTATUS STDCALL +VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpStack; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_REQUEST_PACKET vrp; + + DPRINT("VidDispatchDeviceControl\n"); + IrpStack = IoGetCurrentIrpStackLocation(Irp); + DeviceExtension = DeviceObject->DeviceExtension; + + /* Translate the IRP to a VRP */ + vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET)); + if (NULL == vrp) + { + return STATUS_NO_MEMORY; + } + vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus); + vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; + + /* We're assuming METHOD_BUFFERED */ + vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer; + vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; + vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer; + vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; + + /* Call the Miniport Driver with the VRP */ + DeviceObject->DriverObject->DriverStartIo((PVOID) &DeviceExtension->MiniPortDeviceExtension, (PIRP)vrp); + + /* Free the VRP */ + ExFreePool(vrp); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +static PVOID STDCALL +InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace) +{ + PHYSICAL_ADDRESS TranslatedAddress; + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + ULONG AddressSpace; + PVOID MappedAddress; + PLIST_ENTRY Entry; + + if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE)) + { + DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n"); + InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE; + } + if (! IsListEmpty(&DeviceExtension->AddressMappingListHead)) + { + Entry = DeviceExtension->AddressMappingListHead.Flink; + while (Entry != &DeviceExtension->AddressMappingListHead) + { + AddressMapping = CONTAINING_RECORD(Entry, + VIDEO_PORT_ADDRESS_MAPPING, + List); + if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart && + NumberOfUchars <= AddressMapping->NumberOfUchars) + { + AddressMapping->MappingCount++; + return AddressMapping->MappedAddress; + } + Entry = Entry->Flink; + } + } + + AddressSpace = (ULONG)InIoSpace; + if (HalTranslateBusAddress(DeviceExtension->AdapterInterfaceType, + DeviceExtension->SystemIoBusNumber, + IoAddress, + &AddressSpace, + &TranslatedAddress) == FALSE) + return NULL; + + /* i/o space */ + if (AddressSpace != 0) + { + assert(0 == TranslatedAddress.u.HighPart); + return (PVOID) TranslatedAddress.u.LowPart; + } + + MappedAddress = MmMapIoSpace(TranslatedAddress, + NumberOfUchars, + FALSE); + + AddressMapping = ExAllocatePoolWithTag(PagedPool, + sizeof(VIDEO_PORT_ADDRESS_MAPPING), + TAG_VIDEO_PORT); + if (AddressMapping == NULL) + return MappedAddress; + + AddressMapping->MappedAddress = MappedAddress; + AddressMapping->NumberOfUchars = NumberOfUchars; + AddressMapping->IoAddress = IoAddress; + AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; + AddressMapping->MappingCount = 1; + + InsertHeadList(&DeviceExtension->AddressMappingListHead, + &AddressMapping->List); + + return MappedAddress; +} + +static VOID STDCALL +InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PVOID MappedAddress) +{ + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + PLIST_ENTRY Entry; + + Entry = DeviceExtension->AddressMappingListHead.Flink; + while (Entry != &DeviceExtension->AddressMappingListHead) + { + AddressMapping = CONTAINING_RECORD(Entry, + VIDEO_PORT_ADDRESS_MAPPING, + List); + if (AddressMapping->MappedAddress == MappedAddress) + { + assert(0 <= AddressMapping->MappingCount); + AddressMapping->MappingCount--; + if (0 == AddressMapping->MappingCount) + { +#ifdef TODO + MmUnmapIoSpace(AddressMapping->MappedAddress, + AddressMapping->NumberOfUchars); +#else +DPRINT("MmUnmapIoSpace(0x%08x, 0x%08x)\n", AddressMapping->MappedAddress, AddressMapping->NumberOfUchars); +#endif + RemoveEntryList(Entry); + ExFreePool(AddressMapping); + + return; + } + } + + Entry = Entry->Flink; + } +} diff --git a/drivers/dd/vidport/vidport.def b/drivers/dd/videoprt/videoprt.def similarity index 100% rename from drivers/dd/vidport/vidport.def rename to drivers/dd/videoprt/videoprt.def diff --git a/drivers/dd/vidport/vidport.edf b/drivers/dd/videoprt/videoprt.edf similarity index 100% rename from drivers/dd/vidport/vidport.edf rename to drivers/dd/videoprt/videoprt.edf diff --git a/drivers/dd/vidport/vidport.rc b/drivers/dd/videoprt/videoprt.rc similarity index 100% rename from drivers/dd/vidport/vidport.rc rename to drivers/dd/videoprt/videoprt.rc diff --git a/drivers/dd/vidport/.cvsignore b/drivers/dd/vidport/.cvsignore deleted file mode 100644 index ed28e11..0000000 --- a/drivers/dd/vidport/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -vidport.coff -*.o -*.sym -*.sys diff --git a/drivers/dd/vidport/makefile b/drivers/dd/vidport/makefile deleted file mode 100644 index 224ef06..0000000 --- a/drivers/dd/vidport/makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../../.. - -TARGET_TYPE = export_driver - -TARGET_NAME = vidport - -TARGET_CFLAGS = - -TARGET_OBJECTS = vidport.o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk diff --git a/drivers/dd/vidport/vidport.c b/drivers/dd/vidport/vidport.c deleted file mode 100644 index eab93f2..0000000 --- a/drivers/dd/vidport/vidport.c +++ /dev/null @@ -1,806 +0,0 @@ -/* $Id$ - * - * VideoPort driver - * Written by Rex Jolliff - */ - -#include -#include - -#include "../../../ntoskrnl/include/internal/v86m.h" - -#include "vidport.h" - -#define NDEBUG -#include - -//#define UNIMPLEMENTED do {DbgPrint("%s:%d: Function not implemented", __FILE__, __LINE__); for(;;);} while (0) - -#define VERSION "0.0.0" - -static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); -static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp); -static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); - -static BOOLEAN CsrssInitialized = FALSE; -static HANDLE CsrssHandle = 0; -static struct _EPROCESS* Csrss = NULL; - -PBYTE ReturnCsrssAddress(void) -{ - return (PBYTE)Csrss; -} - -// ------------------------------------------------------- Public Interface - -// DriverEntry -// -// DESCRIPTION: -// This function initializes the driver. -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// IN PDRIVER_OBJECT DriverObject System allocated Driver Object -// for this driver -// IN PUNICODE_STRING RegistryPath Name of registry driver service -// key -// -// RETURNS: -// NTSTATUS - -STDCALL NTSTATUS -DriverEntry(IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegistryPath) -{ - return(STATUS_SUCCESS); -} - -VOID -VideoPortDebugPrint(IN ULONG DebugPrintLevel, - IN PCHAR DebugMessage, ...) -{ - char Buffer[256]; - va_list ap; - -/* - if (DebugPrintLevel > InternalDebugLevel) - return; -*/ - va_start (ap, DebugMessage); - vsprintf (Buffer, DebugMessage, ap); - va_end (ap); - - DbgPrint (Buffer); -} - -VP_STATUS -STDCALL -VideoPortDisableInterrupt(IN PVOID HwDeviceExtension) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortEnableInterrupt(IN PVOID HwDeviceExtension) -{ - UNIMPLEMENTED; -} - -VOID -STDCALL -VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension, - IN PVOID MappedAddress) -{ - UNIMPLEMENTED; -} - -ULONG -STDCALL -VideoPortGetBusData(IN PVOID HwDeviceExtension, - IN BUS_DATA_TYPE BusDataType, - IN ULONG SlotNumber, - OUT PVOID Buffer, - IN ULONG Offset, - IN ULONG Length) -{ - return HalGetBusDataByOffset(BusDataType, - 0, - SlotNumber, - Buffer, - Offset, - Length); -} - -UCHAR -STDCALL -VideoPortGetCurrentIrql(VOID) -{ - return KeGetCurrentIrql(); -} - -PVOID -STDCALL -VideoPortGetDeviceBase(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS IoAddress, - IN ULONG NumberOfUchars, - IN UCHAR InIoSpace) -{ - if (InIoSpace) - { - return MmMapIoSpace(IoAddress, NumberOfUchars, FALSE); - } - else - { - UNIMPLEMENTED; - return NULL; - } -} - -VP_STATUS -STDCALL -VideoPortGetDeviceData(IN PVOID HwDeviceExtension, - IN VIDEO_DEVICE_DATA_TYPE DeviceDataType, - IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine, - IN PVOID Context) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, - IN ULONG NumRequestedResources, - IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRanges, - IN PVOID VendorId, - IN PVOID DeviceId, - IN PULONG Slot) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension, - IN PWSTR ParameterName, - IN UCHAR IsParameterFileName, - IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine, - IN PVOID Context) -{ - UNIMPLEMENTED; -} - -ULONG STDCALL -VideoPortInitialize(IN PVOID Context1, - IN PVOID Context2, - IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, - IN PVOID HwContext) -{ - UCHAR Again; - WCHAR DeviceBuffer[20]; - WCHAR SymlinkBuffer[20]; - NTSTATUS Status; - PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1; - PDEVICE_OBJECT MPDeviceObject; - VIDEO_PORT_CONFIG_INFO ConfigInfo; - PVIDEOPORT_EXTENSION_DATA ExtensionData; - ULONG DeviceNumber = 0; - UNICODE_STRING DeviceName; - UNICODE_STRING SymlinkName; - CLIENT_ID Cid; - - /* Build Dispatch table from passed data */ - MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO; - - /* Create a unicode device name */ - Again = FALSE; - do - { - swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber); - RtlInitUnicodeString(&DeviceName, DeviceBuffer); - - /* Create the device */ - Status = IoCreateDevice(MPDriverObject, - HwInitializationData->HwDeviceExtensionSize + - sizeof(VIDEOPORT_EXTENSION_DATA), - &DeviceName, - FILE_DEVICE_VIDEO, - 0, - TRUE, - &MPDeviceObject); - if (!NT_SUCCESS(Status)) - { - DbgPrint("IoCreateDevice call failed\n",0); - return Status; - } - - MPDriverObject->DeviceObject = MPDeviceObject; - - /* initialize the miniport drivers dispatch table */ - MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose; - MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose; - MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl; - - /* create symbolic link "\??\DISPLAYx" */ - swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1); - RtlInitUnicodeString (&SymlinkName, - SymlinkBuffer); - IoCreateSymbolicLink (&SymlinkName, - &DeviceName); - - ExtensionData = - (PVIDEOPORT_EXTENSION_DATA) MPDeviceObject->DeviceExtension; - ExtensionData->DeviceObject = MPDeviceObject; - - /* Set the buffering strategy here... */ - /* If you change this, remember to change VidDispatchDeviceControl too */ - MPDeviceObject->Flags |= DO_BUFFERED_IO; - - /* Call HwFindAdapter entry point */ - /* FIXME: Need to figure out what string to pass as param 3 */ - Status = HwInitializationData->HwFindAdapter(VPExtensionToMPExtension(ExtensionData), - Context2, - L"", - &ConfigInfo, - &Again); - if (!NT_SUCCESS(Status)) - { - DbgPrint("HwFindAdapter call failed\n"); - IoDeleteDevice(MPDeviceObject); - - return Status; - } - - /* FIXME: Allocate hardware resources for device */ - - /* Allocate interrupt for device */ - if (HwInitializationData->HwInterrupt != NULL && - !(ConfigInfo.BusInterruptLevel == 0 && - ConfigInfo.BusInterruptVector == 0)) - { -#if 0 - ExtensionData->IRQL = ConfigInfo.BusInterruptLevel; - ExtensionData->InterruptLevel = - HalGetInterruptVector(ConfigInfo.AdapterInterfaceType, - ConfigInfo.SystemIoBusNumber, - ConfigInfo.BusInterruptLevel, - ConfigInfo.BusInterruptVector, - &ExtensionData->IRQL, - &ExtensionData->Affinity); - KeInitializeSpinLock(&ExtensionData->InterruptSpinLock); - Status = IoConnectInterrupt(&ExtensionData->InterruptObject, - (PKSERVICE_ROUTINE) - HwInitializationData->HwInterrupt, - VPExtensionToMPExtension(ExtensionData), - &ExtensionData->InterruptSpinLock, - ExtensionData->InterruptLevel, - ExtensionData->IRQL, - ExtensionData->IRQL, - ConfigInfo.InterruptMode, - FALSE, - ExtensionData->Affinity, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("IoConnectInterrupt failed\n"); - IoDeleteDevice(MPDeviceObject); - - return Status; - } -#endif - } - DeviceNumber++; - } - while (Again); - - /* FIXME: initialize timer routine for MP Driver */ - if (HwInitializationData->HwTimer != NULL) - { - Status = IoInitializeTimer(MPDeviceObject, - (PIO_TIMER_ROUTINE) - HwInitializationData->HwTimer, - VPExtensionToMPExtension(ExtensionData)); - if (!NT_SUCCESS(Status)) - { - DbgPrint("IoInitializeTimer failed\n"); - - if (HwInitializationData->HwInterrupt != NULL) - { - IoDisconnectInterrupt(ExtensionData->InterruptObject); - } - IoDeleteDevice(MPDeviceObject); - - return Status; - } - } - - return STATUS_SUCCESS; -} - -VP_STATUS STDCALL -VideoPortInt10(IN PVOID HwDeviceExtension, - IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments) -{ - KV86M_REGISTERS Regs; - NTSTATUS Status; - - KeAttachProcess(Csrss); - - memset(&Regs, 0, sizeof(Regs)); - Regs.Eax = BiosArguments->Eax; - Regs.Ebx = BiosArguments->Ebx; - Regs.Ecx = BiosArguments->Ecx; - Regs.Edx = BiosArguments->Edx; - Regs.Esi = BiosArguments->Esi; - Regs.Edi = BiosArguments->Edi; - Regs.Ebp = BiosArguments->Ebp; - Status = Ke386CallBios(0x10, &Regs); - - KeDetachProcess(); - - return(Status); -} - -VOID -STDCALL -VideoPortLogError(IN PVOID HwDeviceExtension, - IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL, - IN VP_STATUS ErrorCode, - IN ULONG UniqueId) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortMapBankedMemory(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN PULONG Length, - IN PULONG InIoSpace, - OUT PVOID *VirtualAddress, - IN ULONG BankLength, - IN UCHAR ReadWriteBank, - IN PBANKED_SECTION_ROUTINE BankRoutine, - IN PVOID Context) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortMapMemory(IN PVOID HwDeviceExtension, - IN PHYSICAL_ADDRESS PhysicalAddress, - IN PULONG Length, - IN PULONG InIoSpace, - OUT PVOID *VirtualAddress) -{ - if (*InIoSpace) - { - *VirtualAddress = MmMapIoSpace(PhysicalAddress, *Length, FALSE); - - return *VirtualAddress != NULL ? STATUS_SUCCESS : - STATUS_INSUFFICIENT_RESOURCES; - } - else - { - UNIMPLEMENTED; - } - - return STATUS_SUCCESS; -} - -UCHAR -STDCALL -VideoPortReadPortUchar(IN PUCHAR Port) -{ - return READ_PORT_UCHAR(Port); -} - -USHORT -STDCALL -VideoPortReadPortUshort(IN PUSHORT Port) -{ - return READ_PORT_USHORT(Port); -} - -ULONG -STDCALL -VideoPortReadPortUlong(IN PULONG Port) -{ - return READ_PORT_ULONG(Port); -} - -VOID -STDCALL -VideoPortReadPortBufferUchar(IN PUCHAR Port, - OUT PUCHAR Buffer, - IN ULONG Count) -{ - READ_PORT_BUFFER_UCHAR(Port, Buffer, Count); -} - -VOID -STDCALL -VideoPortReadPortBufferUshort(IN PUSHORT Port, - OUT PUSHORT Buffer, - IN ULONG Count) -{ - READ_PORT_BUFFER_USHORT(Port, Buffer, Count); -} - -VOID -STDCALL -VideoPortReadPortBufferUlong(IN PULONG Port, - OUT PULONG Buffer, - IN ULONG Count) -{ - READ_PORT_BUFFER_ULONG(Port, Buffer, Count); -} - -UCHAR -STDCALL -VideoPortReadRegisterUchar(IN PUCHAR Register) -{ - return READ_REGISTER_UCHAR(Register); -} - -USHORT -STDCALL -VideoPortReadRegisterUshort(IN PUSHORT Register) -{ - return READ_REGISTER_USHORT(Register); -} - -ULONG -STDCALL -VideoPortReadRegisterUlong(IN PULONG Register) -{ - return READ_REGISTER_ULONG(Register); -} - -VOID -STDCALL -VideoPortReadRegisterBufferUchar(IN PUCHAR Register, - OUT PUCHAR Buffer, - IN ULONG Count) -{ - READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count); -} - -VOID -STDCALL -VideoPortReadRegisterBufferUshort(IN PUSHORT Register, - OUT PUSHORT Buffer, - IN ULONG Count) -{ - READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count); -} - -VOID -STDCALL -VideoPortReadRegisterBufferUlong(IN PULONG Register, - OUT PULONG Buffer, - IN ULONG Count) -{ - READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count); -} - -BOOLEAN -STDCALL -VideoPortScanRom(IN PVOID HwDeviceExtension, - IN PUCHAR RomBase, - IN ULONG RomLength, - IN PUCHAR String) -{ - UNIMPLEMENTED; -} - -ULONG -STDCALL -VideoPortSetBusData(IN PVOID HwDeviceExtension, - IN BUS_DATA_TYPE BusDataType, - IN ULONG SlotNumber, - IN PVOID Buffer, - IN ULONG Offset, - IN ULONG Length) -{ - return HalSetBusDataByOffset(BusDataType, - 0, - SlotNumber, - Buffer, - Offset, - Length); -} - -VP_STATUS -STDCALL -VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, - IN PWSTR ValueName, - IN PVOID ValueData, - IN ULONG ValueLength) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRange) -{ - UNIMPLEMENTED; -} - -VOID -STDCALL -VideoPortStartTimer(IN PVOID HwDeviceExtension) -{ - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); - - IoStartTimer(ExtensionData->DeviceObject); -} - -VOID -STDCALL -VideoPortStopTimer(IN PVOID HwDeviceExtension) -{ - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); - - IoStopTimer(ExtensionData->DeviceObject); -} - -BOOLEAN -STDCALL -VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension, - IN VIDEO_SYNCHRONIZE_PRIORITY Priority, - IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine, - OUT PVOID Context) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortUnmapMemory(IN PVOID HwDeviceExtension, - IN PVOID VirtualAddress, - IN HANDLE ProcessHandle) -{ - UNIMPLEMENTED; -} - -VP_STATUS -STDCALL -VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension, - IN ULONG NumAccessRanges, - IN PVIDEO_ACCESS_RANGE AccessRanges) -{ - UNIMPLEMENTED; -} - -VOID -STDCALL -VideoPortWritePortUchar(IN PUCHAR Port, - IN UCHAR Value) -{ - WRITE_PORT_UCHAR(Port, Value); -} - -VOID -STDCALL -VideoPortWritePortUshort(IN PUSHORT Port, - IN USHORT Value) -{ - WRITE_PORT_USHORT(Port, Value); -} - -VOID -STDCALL -VideoPortWritePortUlong(IN PULONG Port, - IN ULONG Value) -{ - WRITE_PORT_ULONG(Port, Value); -} - -VOID -STDCALL -VideoPortWritePortBufferUchar(IN PUCHAR Port, - IN PUCHAR Buffer, - IN ULONG Count) -{ - WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count); -} - -VOID -STDCALL -VideoPortWritePortBufferUshort(IN PUSHORT Port, - IN PUSHORT Buffer, - IN ULONG Count) -{ - WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count); -} - -VOID -STDCALL -VideoPortWritePortBufferUlong(IN PULONG Port, - IN PULONG Buffer, - IN ULONG Count) -{ - WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count); -} - -VOID -STDCALL -VideoPortWriteRegisterUchar(IN PUCHAR Register, - IN UCHAR Value) -{ - WRITE_REGISTER_UCHAR(Register, Value); -} - -VOID -STDCALL -VideoPortWriteRegisterUshort(IN PUSHORT Register, - IN USHORT Value) -{ - WRITE_REGISTER_USHORT(Register, Value); -} - -VOID -STDCALL -VideoPortWriteRegisterUlong(IN PULONG Register, - IN ULONG Value) -{ - WRITE_REGISTER_ULONG(Register, Value); -} - -VOID -STDCALL -VideoPortWriteRegisterBufferUchar(IN PUCHAR Register, - IN PUCHAR Buffer, - IN ULONG Count) -{ - WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count); -} - -VOID STDCALL -VideoPortWriteRegisterBufferUshort(IN PUSHORT Register, - IN PUSHORT Buffer, - IN ULONG Count) -{ - WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count); -} - -VOID STDCALL -VideoPortWriteRegisterBufferUlong(IN PULONG Register, - IN PULONG Buffer, - IN ULONG Count) -{ - WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count); -} - -VOID STDCALL -VideoPortZeroDeviceMemory(OUT PVOID Destination, - IN ULONG Length) -{ - UNIMPLEMENTED; -} - - -// ------------------------------------------- Nondiscardable statics - -// VidDispatchOpenClose -// -// DESCRIPTION: -// Answer requests for Open/Close calls: a null operation -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// Standard dispatch arguments -// -// RETURNS: -// NTSTATUS -// - -static NTSTATUS STDCALL -VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpStack; - - DPRINT("VidDispatchOpenClose() called\n"); - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - - if (IrpStack->MajorFunction == IRP_MJ_CREATE && - CsrssInitialized == FALSE) - { - DPRINT("Referencing CSRSS\n"); - Csrss = PsGetCurrentProcess(); - CsrssInitialized = TRUE; - DPRINT("Csrss %p\n", Csrss); - } - - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -// VidStartIo -// -// DESCRIPTION: -// Get the next requested I/O packet started -// -// RUN LEVEL: -// DISPATCH_LEVEL -// -// ARGUMENTS: -// Dispatch routine standard arguments -// -// RETURNS: -// NTSTATUS -// - -static VOID STDCALL -VidStartIo(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - UNIMPLEMENTED; -} - -// VidDispatchDeviceControl -// -// DESCRIPTION: -// Answer requests for device control calls -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// Standard dispatch arguments -// -// RETURNS: -// NTSTATUS -// - -static NTSTATUS STDCALL -VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IrpStack; - PVIDEO_REQUEST_PACKET vrp; - - IrpStack = IoGetCurrentIrpStackLocation(Irp); - - // Translate the IRP to a VRP - vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET)); - vrp->StatusBlock = ExAllocatePool(PagedPool, sizeof(STATUS_BLOCK)); - vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; - - // We're assuming METHOD_BUFFERED - vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer; - vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; - vrp->OutputBuffer = Irp->UserBuffer; - vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; - - // Call the Miniport Driver with the VRP - DeviceObject->DriverObject->DriverStartIo(DeviceObject->DeviceExtension, (PIRP)vrp); - - // Translate the VRP back into the IRP for OutputBuffer - Irp->UserBuffer = vrp->OutputBuffer; - IrpStack->Parameters.DeviceIoControl.OutputBufferLength = vrp->OutputBufferLength; - - // Free the VRP - ExFreePool(vrp->StatusBlock); - ExFreePool(vrp); - - return STATUS_SUCCESS; -} diff --git a/drivers/dd/vidport/vidport.h b/drivers/dd/vidport/vidport.h deleted file mode 100644 index ed824e6..0000000 --- a/drivers/dd/vidport/vidport.h +++ /dev/null @@ -1,16 +0,0 @@ - -typedef struct _VIDEOPORT_EXTENSTION_DATA -{ - PDEVICE_OBJECT DeviceObject; - PKINTERRUPT InterruptObject; - KSPIN_LOCK InterruptSpinLock; - ULONG InterruptLevel; - KIRQL IRQL; - KAFFINITY Affinity; -} VIDEOPORT_EXTENSION_DATA, *PVIDEOPORT_EXTENSION_DATA; - -#define MPExtensionToVPExtension(MPX) \ - ((PVIDEOPORT_EXTENSION_DATA) ((DWORD) (MPX) - sizeof(VIDEOPORT_EXTENSION_DATA))) -#define VPExtensionToMPExtension(VPX) \ - ((PVOID) ((DWORD) (VPX) + sizeof(VIDEOPORT_EXTENSION_DATA))) - diff --git a/drivers/fs/cdfs/cdfs.h b/drivers/fs/cdfs/cdfs.h index ba50f23..b25d899 100644 --- a/drivers/fs/cdfs/cdfs.h +++ b/drivers/fs/cdfs/cdfs.h @@ -193,7 +193,6 @@ typedef struct _FCB typedef struct _CCB { - PFCB Fcb; LIST_ENTRY NextCCB; PFILE_OBJECT PtrFileObject; LARGE_INTEGER CurrentByteOffset; diff --git a/drivers/fs/cdfs/cleanup.c b/drivers/fs/cdfs/cleanup.c index 4f0a71a..a2eec26 100644 --- a/drivers/fs/cdfs/cleanup.c +++ b/drivers/fs/cdfs/cleanup.c @@ -45,23 +45,16 @@ CdfsCleanupFile(PDEVICE_EXTENSION DeviceExt, * FUNCTION: Cleans up after a file has been closed. */ { - PCCB Ccb; DPRINT("CdfsCleanupFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); - Ccb = (PCCB) (FileObject->FsContext2); - if (Ccb == NULL) - { - return STATUS_SUCCESS; - } - /* Uninitialize file cache if initialized for this file object. */ - if (Ccb->Fcb->RFCB.Bcb != NULL) + if (FileObject->SectionObjectPointers && FileObject->SectionObjectPointers->SharedCacheMap) { - CcRosReleaseFileCache (FileObject, Ccb->Fcb->RFCB.Bcb); + CcRosReleaseFileCache (FileObject); } return STATUS_SUCCESS; diff --git a/drivers/fs/cdfs/close.c b/drivers/fs/cdfs/close.c index ec17966..2915b88 100644 --- a/drivers/fs/cdfs/close.c +++ b/drivers/fs/cdfs/close.c @@ -46,7 +46,7 @@ CdfsCloseFile(PDEVICE_EXTENSION DeviceExt, */ { PCCB Ccb; - + DPRINT("CdfsCloseFile(DeviceExt %x, FileObject %x)\n", DeviceExt, FileObject); @@ -66,8 +66,7 @@ CdfsCloseFile(PDEVICE_EXTENSION DeviceExt, // This a FO, that was created outside from FSD. // Some FO's are created with IoCreateStreamFileObject() insid from FSD. // This FO's don't have a FileName. - CdfsReleaseFCB(DeviceExt, - Ccb->Fcb); + CdfsReleaseFCB(DeviceExt, FileObject->FsContext); } if (Ccb->DirectorySearchPattern) diff --git a/drivers/fs/cdfs/create.c b/drivers/fs/cdfs/create.c index 28c4b1e..e01b791 100644 --- a/drivers/fs/cdfs/create.c +++ b/drivers/fs/cdfs/create.c @@ -45,12 +45,9 @@ CdfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject, { PWSTR rcName; PFCB Fcb; - PCCB Ccb; DPRINT("try related for %S\n", pRelativeFileName); - Ccb = pFileObject->FsContext2; - assert(Ccb); - Fcb = Ccb->Fcb; + Fcb = pFileObject->FsContext; assert(Fcb); /* verify related object is a directory and target name @@ -169,7 +166,6 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject, ULONG RequestedDisposition; ULONG RequestedOptions; PFCB Fcb; - PCCB Ccb; // PWSTR FileName; NTSTATUS Status; @@ -200,8 +196,7 @@ CdfsCreateFile(PDEVICE_OBJECT DeviceObject, if (NT_SUCCESS(Status)) { - Ccb = FileObject->FsContext2; - Fcb = Ccb->Fcb; + Fcb = FileObject->FsContext; /* * Check the file has the requested attributes */ diff --git a/drivers/fs/cdfs/dirctl.c b/drivers/fs/cdfs/dirctl.c index ce58ca2..59fa071 100644 --- a/drivers/fs/cdfs/dirctl.c +++ b/drivers/fs/cdfs/dirctl.c @@ -555,7 +555,7 @@ CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject, FileObject = Stack->FileObject; Ccb = (PCCB)FileObject->FsContext2; - Fcb = Ccb->Fcb; + Fcb = (PFCB)FileObject->FsContext; /* Obtain the callers parameters */ BufferLength = Stack->Parameters.QueryDirectory.Length; diff --git a/drivers/fs/cdfs/fcb.c b/drivers/fs/cdfs/fcb.c index fa54c38..c5295b9 100644 --- a/drivers/fs/cdfs/fcb.c +++ b/drivers/fs/cdfs/fcb.c @@ -187,7 +187,7 @@ CdfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb, if (FileName == NULL || *FileName == 0) { DPRINT("Return FCB for stream file object\n"); - Fcb = ((PCCB)Vcb->StreamFileObject->FsContext2)->Fcb; + Fcb = Vcb->StreamFileObject->FsContext; Fcb->RefCount++; KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); return(Fcb); @@ -237,15 +237,13 @@ CdfsFCBInitializeCache(PVCB Vcb, FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; - FileObject->FsContext = (PVOID) &Fcb->RFCB; + FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; - newCCB->Fcb = Fcb; newCCB->PtrFileObject = FileObject; Fcb->FileObject = FileObject; Fcb->DevExt = Vcb; Status = CcRosInitializeFileCache(FileObject, - &Fcb->RFCB.Bcb, PAGE_SIZE); if (!NT_SUCCESS(Status)) { @@ -417,16 +415,14 @@ CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb, FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; - FileObject->FsContext = (PVOID)&Fcb->RFCB; + FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; - newCCB->Fcb = Fcb; newCCB->PtrFileObject = FileObject; Fcb->DevExt = Vcb; if (CdfsFCBIsDirectory(Fcb)) { Status = CcRosInitializeFileCache(FileObject, - &Fcb->RFCB.Bcb, PAGE_SIZE); if (!NT_SUCCESS(Status)) { diff --git a/drivers/fs/cdfs/fsctl.c b/drivers/fs/cdfs/fsctl.c index 2a777f9..b209836 100644 --- a/drivers/fs/cdfs/fsctl.c +++ b/drivers/fs/cdfs/fsctl.c @@ -379,12 +379,11 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject, sizeof(CCB)); DeviceExt->StreamFileObject->Flags = DeviceExt->StreamFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; - DeviceExt->StreamFileObject->FsContext = (PVOID)&Fcb->RFCB; + DeviceExt->StreamFileObject->FsContext = Fcb; DeviceExt->StreamFileObject->FsContext2 = Ccb; DeviceExt->StreamFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; DeviceExt->StreamFileObject->PrivateCacheMap = NULL; DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb; - Ccb->Fcb = Fcb; Ccb->PtrFileObject = DeviceExt->StreamFileObject; Fcb->FileObject = DeviceExt->StreamFileObject; Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; @@ -398,7 +397,6 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject, Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE; Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject, - &Fcb->RFCB.Bcb, PAGE_SIZE); if (!NT_SUCCESS (Status)) { diff --git a/drivers/fs/cdfs/makefile b/drivers/fs/cdfs/makefile index 57a17ef..15b2644 100644 --- a/drivers/fs/cdfs/makefile +++ b/drivers/fs/cdfs/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = cdfs diff --git a/drivers/fs/cdfs/rw.c b/drivers/fs/cdfs/rw.c index 82ae382..e7d669c 100644 --- a/drivers/fs/cdfs/rw.c +++ b/drivers/fs/cdfs/rw.c @@ -71,7 +71,7 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, return(STATUS_SUCCESS); Ccb = (PCCB)FileObject->FsContext2; - Fcb = Ccb->Fcb; + Fcb = (PFCB)FileObject->FsContext; if (ReadOffset >= Fcb->Entry.DataLengthL) return(STATUS_END_OF_FILE); @@ -87,7 +87,7 @@ CdfsReadFile(PDEVICE_EXTENSION DeviceExt, Length = Fcb->Entry.DataLengthL - ReadOffset; if (FileObject->PrivateCacheMap == NULL) { - CcRosInitializeFileCache(FileObject, &Fcb->RFCB.Bcb, PAGE_SIZE); + CcRosInitializeFileCache(FileObject, PAGE_SIZE); } FileOffset.QuadPart = (LONGLONG)ReadOffset; diff --git a/drivers/fs/ntfs/create.c b/drivers/fs/ntfs/create.c index ade3d61..46cb24e 100644 --- a/drivers/fs/ntfs/create.c +++ b/drivers/fs/ntfs/create.c @@ -44,12 +44,9 @@ NtfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject, { PWSTR rcName; PFCB Fcb; - PCCB Ccb; DPRINT("try related for %S\n", pRelativeFileName); - Ccb = pFileObject->FsContext2; - assert(Ccb); - Fcb = Ccb->Fcb; + Fcb = pFileObject->FsContext; assert(Fcb); /* verify related object is a directory and target name diff --git a/drivers/fs/ntfs/dirctl.c b/drivers/fs/ntfs/dirctl.c index aa89ee7..1e714d0 100644 --- a/drivers/fs/ntfs/dirctl.c +++ b/drivers/fs/ntfs/dirctl.c @@ -505,7 +505,7 @@ NtfsQueryDirectory(PDEVICE_OBJECT DeviceObject, FileObject = Stack->FileObject; Ccb = (PCCB)FileObject->FsContext2; - Fcb = Ccb->Fcb; + Fcb = (PFCB)FileObject->FsContext; /* Obtain the callers parameters */ BufferLength = Stack->Parameters.QueryDirectory.Length; diff --git a/drivers/fs/ntfs/fcb.c b/drivers/fs/ntfs/fcb.c index 45f8861..6c6f46a 100644 --- a/drivers/fs/ntfs/fcb.c +++ b/drivers/fs/ntfs/fcb.c @@ -153,7 +153,7 @@ NtfsReleaseFCB(PDEVICE_EXTENSION Vcb, if (Fcb->RefCount <= 0 && !NtfsFCBIsDirectory(Fcb)) { RemoveEntryList(&Fcb->FcbListEntry); - CcRosReleaseFileCache(NULL, Fcb->RFCB.Bcb); + CcRosReleaseFileCache(Fcb->FileObject); NtfsDestroyFCB(Fcb); } KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); @@ -186,7 +186,7 @@ NtfsGrabFCBFromTable(PDEVICE_EXTENSION Vcb, if (FileName == NULL || *FileName == 0) { DPRINT("Return FCB for stream file object\n"); - Fcb = ((PCCB)Vcb->StreamFileObject->FsContext2)->Fcb; + Fcb = Vcb->StreamFileObject->FsContext; Fcb->RefCount++; KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql); return(Fcb); @@ -236,15 +236,13 @@ NtfsFCBInitializeCache(PVCB Vcb, FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; - FileObject->FsContext = (PVOID) &Fcb->RFCB; + FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; - newCCB->Fcb = Fcb; newCCB->PtrFileObject = FileObject; Fcb->FileObject = FileObject; Fcb->DevExt = Vcb; Status = CcRosInitializeFileCache(FileObject, - &Fcb->RFCB.Bcb, CACHEPAGESIZE(Vcb)); if (!NT_SUCCESS(Status)) { @@ -409,16 +407,14 @@ NtfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb, FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; - FileObject->FsContext = (PVOID)&Fcb->RFCB; + FileObject->FsContext = Fcb; FileObject->FsContext2 = newCCB; - newCCB->Fcb = Fcb; newCCB->PtrFileObject = FileObject; Fcb->DevExt = Vcb; if (!(Fcb->Flags & FCB_CACHE_INITIALIZED)) { Status = CcRosInitializeFileCache(FileObject, - &Fcb->RFCB.Bcb, CACHEPAGESIZE(Vcb)); if (!NT_SUCCESS(Status)) { diff --git a/drivers/fs/ntfs/fsctl.c b/drivers/fs/ntfs/fsctl.c index 98554d9..4cdc428 100644 --- a/drivers/fs/ntfs/fsctl.c +++ b/drivers/fs/ntfs/fsctl.c @@ -275,12 +275,11 @@ NtfsMountVolume(PDEVICE_OBJECT DeviceObject, sizeof(CCB)); DeviceExt->StreamFileObject->Flags = DeviceExt->StreamFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; - DeviceExt->StreamFileObject->FsContext = (PVOID)&Fcb->RFCB; + DeviceExt->StreamFileObject->FsContext = Fcb; DeviceExt->StreamFileObject->FsContext2 = Ccb; DeviceExt->StreamFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; DeviceExt->StreamFileObject->PrivateCacheMap = NULL; DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb; - Ccb->Fcb = Fcb; Ccb->PtrFileObject = DeviceExt->StreamFileObject; Fcb->FileObject = DeviceExt->StreamFileObject; Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; @@ -295,7 +294,6 @@ NtfsMountVolume(PDEVICE_OBJECT DeviceObject, // Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE; Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject, - &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt)); if (!NT_SUCCESS (Status)) { diff --git a/drivers/fs/ntfs/makefile b/drivers/fs/ntfs/makefile index 28c1929..2170104 100644 --- a/drivers/fs/ntfs/makefile +++ b/drivers/fs/ntfs/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = ntfs diff --git a/drivers/fs/ntfs/ntfs.h b/drivers/fs/ntfs/ntfs.h index b700ddd..c1fbf65 100644 --- a/drivers/fs/ntfs/ntfs.h +++ b/drivers/fs/ntfs/ntfs.h @@ -106,7 +106,6 @@ typedef struct _FCB typedef struct _CCB { - PFCB Fcb; LIST_ENTRY NextCCB; PFILE_OBJECT PtrFileObject; LARGE_INTEGER CurrentByteOffset; diff --git a/drivers/fs/vfat/cleanup.c b/drivers/fs/vfat/cleanup.c index 8ab965b..23b45e6 100644 --- a/drivers/fs/vfat/cleanup.c +++ b/drivers/fs/vfat/cleanup.c @@ -24,7 +24,6 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext) * FUNCTION: Cleans up after a file has been closed. */ { - PVFATCCB pCcb; PVFATFCB pFcb; PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt; PFILE_OBJECT FileObject = IrpContext->FileObject; @@ -33,30 +32,25 @@ VfatCleanupFile(PVFAT_IRP_CONTEXT IrpContext) DeviceExt, FileObject); /* FIXME: handle file/directory deletion here */ - pCcb = (PVFATCCB) (FileObject->FsContext2); - if (pCcb == NULL) - { - return STATUS_SUCCESS; - } - pFcb = pCcb->pFcb; - - if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && - FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) + pFcb = (PVFATFCB) FileObject->FsContext; + if (pFcb) { - /* remove all locks this process have on this file */ - FsRtlFastUnlockAll(&pFcb->FileLock, - FileObject, - IoGetRequestorProcess(IrpContext->Irp), - NULL - ); + if (!(pFcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY) && + FsRtlAreThereCurrentFileLocks(&pFcb->FileLock)) + { + /* remove all locks this process have on this file */ + FsRtlFastUnlockAll(&pFcb->FileLock, + FileObject, + IoGetRequestorProcess(IrpContext->Irp), + NULL); + } + + /* Uninitialize file cache if initialized for this file object. */ + if (FileObject->PrivateCacheMap) + { + CcRosReleaseFileCache (FileObject); + } } - - /* Uninitialize file cache if initialized for this file object. */ - if (pFcb->RFCB.Bcb != NULL) - { - CcRosReleaseFileCache (FileObject, pFcb->RFCB.Bcb); - } - return STATUS_SUCCESS; } diff --git a/drivers/fs/vfat/close.c b/drivers/fs/vfat/close.c index 7fae9a7..c3dd065 100644 --- a/drivers/fs/vfat/close.c +++ b/drivers/fs/vfat/close.c @@ -33,13 +33,13 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) /* FIXME : update entry in directory? */ pCcb = (PVFATCCB) (FileObject->FsContext2); + pFcb = (PVFATFCB) (FileObject->FsContext); - DPRINT ("pCcb %x\n", pCcb); - if (pCcb == NULL) + if (pFcb == NULL) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - pFcb = pCcb->pFcb; + if (pFcb->Flags & FCB_IS_VOLUME) { DPRINT1("Volume\n"); @@ -58,15 +58,21 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject) delEntry (DeviceExt, FileObject); } else - Status = STATUS_DELETE_PENDING; + { + Status = STATUS_DELETE_PENDING; + } } - FileObject->FsContext2 = NULL; vfatReleaseFCB (DeviceExt, pFcb); } - else - FileObject->FsContext2 = NULL; + + FileObject->FsContext2 = NULL; + FileObject->FsContext = NULL; + FileObject->SectionObjectPointers = NULL; - vfatDestroyCCB(pCcb); + if (pCcb) + { + vfatDestroyCCB(pCcb); + } return Status; } diff --git a/drivers/fs/vfat/create.c b/drivers/fs/vfat/create.c index 3aa7ac1..74666e1 100644 --- a/drivers/fs/vfat/create.c +++ b/drivers/fs/vfat/create.c @@ -238,12 +238,14 @@ FindFile (PDEVICE_EXTENSION DeviceExt, CHECKPOINT; Fcb->PathName[0]='\\'; Fcb->ObjectName = &Fcb->PathName[1]; - Fcb->entry.FileSize = DeviceExt->FatInfo.rootDirectorySectors * DeviceExt->FatInfo.BytesPerSector; Fcb->entry.Attrib = FILE_ATTRIBUTE_DIRECTORY; + Fcb->entry.CreationDate = 0x0021; /* 1.1.1980 */ + Fcb->entry.AccessDate = 0x0021; + Fcb->entry.UpdateDate = 0x0021; if (DeviceExt->FatInfo.FatType == FAT32) { - Fcb->entry.FirstCluster = ((PUSHORT)FirstCluster)[0]; - Fcb->entry.FirstClusterHigh = ((PUSHORT)FirstCluster)[1]; + Fcb->entry.FirstCluster = ((PUSHORT)&FirstCluster)[0]; + Fcb->entry.FirstClusterHigh = ((PUSHORT)&FirstCluster)[1]; } else Fcb->entry.FirstCluster = 1; @@ -364,12 +366,9 @@ vfatMakeAbsoluteFilename (PFILE_OBJECT pFileObject, { PWSTR rcName; PVFATFCB fcb; - PVFATCCB ccb; DPRINT ("try related for %S\n", pRelativeFileName); - ccb = pFileObject->FsContext2; - assert (ccb); - fcb = ccb->pFcb; + fcb = pFileObject->FsContext; assert (fcb); /* verify related object is a directory and target name @@ -600,11 +599,8 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) memset(pCcb, 0, sizeof(VFATCCB)); FileObject->Flags |= FO_FCB_IS_VALID; FileObject->SectionObjectPointers = &pFcb->SectionObjectPointers; - FileObject->FsContext = (PVOID) &pFcb->RFCB; + FileObject->FsContext = pFcb; FileObject->FsContext2 = pCcb; - pCcb->pFcb = pFcb; - pCcb->PtrFileObject = FileObject; - pFcb->pDevExt = DeviceExt; pFcb->RefCount++; Irp->IoStatus.Information = FILE_OPENED; @@ -654,8 +650,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) Attributes & FILE_ATTRIBUTE_VALID_FLAGS); if (NT_SUCCESS (Status)) { - pCcb = FileObject->FsContext2; - pFcb = pCcb->pFcb; + pFcb = FileObject->FsContext; Irp->IoStatus.Information = FILE_CREATED; VfatSetAllocationSizeInformation(FileObject, pFcb, @@ -689,8 +684,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) return(STATUS_OBJECT_NAME_COLLISION); } - pCcb = FileObject->FsContext2; - pFcb = pCcb->pFcb; + pFcb = FileObject->FsContext; /* * Check the file has the requested attributes diff --git a/drivers/fs/vfat/dir.c b/drivers/fs/vfat/dir.c index e9c1a67..362fde8 100644 --- a/drivers/fs/vfat/dir.c +++ b/drivers/fs/vfat/dir.c @@ -209,7 +209,7 @@ NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext) BOOLEAN First = FALSE; pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2; - pFcb = pCcb->pFcb; + pFcb = (PVFATFCB) IrpContext->FileObject->FsContext; if (!ExAcquireResourceSharedLite(&pFcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT)) { diff --git a/drivers/fs/vfat/dirwr.c b/drivers/fs/vfat/dirwr.c index 2f5e54d..7f828f4 100644 --- a/drivers/fs/vfat/dirwr.c +++ b/drivers/fs/vfat/dirwr.c @@ -45,7 +45,7 @@ VfatUpdateEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) DPRINT ("updEntry PathFileName \'%S\'\n", ((PVFATCCB)(pFileObject->FsContext2))->pFcb->PathName); - pFcb = ((PVFATCCB)(pFileObject->FsContext2))->pFcb; + pFcb = (PVFATFCB)pFileObject->FsContext; assert (pFcb); pDirFcb = pFcb->parentFcb; assert (pDirFcb); @@ -559,7 +559,7 @@ VfatAddEntry (PDEVICE_EXTENSION DeviceExt, CcSetDirtyPinnedData(Context, NULL); CcUnpinData(Context); - // FEXME: check status + // FIXME: check status vfatMakeFCBFromDirEntry (DeviceExt, pDirFcb, FileName, pEntry, start, start + nbSlots - 1, &newFCB); vfatAttachFCBToFileObject (DeviceExt, newFCB, pFileObject); @@ -635,7 +635,7 @@ delEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject) } return status; } - pName = ((PVFATCCB)(pFileObject->FsContext2))->pFcb->ObjectName; + pName = ((PVFATFCB)pFileObject->FsContext)->ObjectName; if (*pName == L'\\') { pName ++; diff --git a/drivers/fs/vfat/fcb.c b/drivers/fs/vfat/fcb.c index 2c7adbe..6f1a375 100644 --- a/drivers/fs/vfat/fcb.c +++ b/drivers/fs/vfat/fcb.c @@ -156,12 +156,13 @@ vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) if (vfatFCBIsDirectory(pFCB)) { /* Uninitialize file cache if initialized for this file object. */ - if (pFCB->RFCB.Bcb != NULL) + if (pFCB->FileObject->SectionObjectPointers->SharedCacheMap) { - CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb); + CcRosReleaseFileCache(pFCB->FileObject); } vfatDestroyCCB(pFCB->FileObject->FsContext2); pFCB->FileObject->FsContext2 = NULL; + pFCB->FileObject->FsContext = NULL; ObDereferenceObject(pFCB->FileObject); } vfatDestroyFCB (pFCB); @@ -185,7 +186,6 @@ vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB) Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE; KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql); - pFCB->pDevExt = pVCB; InsertTailList (&pVCB->FcbListHead, &pFCB->FcbListEntry); pFCB->Hash.next = pVCB->FcbHashTable[Index]; @@ -287,19 +287,15 @@ vfatFCBInitializeCacheFromVolume (PVCB vcb, PVFATFCB fcb) fileObject->Flags |= FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; fileObject->SectionObjectPointers = &fcb->SectionObjectPointers; - fileObject->FsContext = (PVOID) &fcb->RFCB; + fileObject->FsContext = fcb; fileObject->FsContext2 = newCCB; - newCCB->pFcb = fcb; - newCCB->PtrFileObject = fileObject; fcb->FileObject = fileObject; - fcb->pDevExt = vcb; fileCacheQuantum = (vcb->FatInfo.BytesPerCluster >= PAGE_SIZE) ? vcb->FatInfo.BytesPerCluster : PAGE_SIZE; status = CcRosInitializeFileCache (fileObject, - &fcb->RFCB.Bcb, fileCacheQuantum); if (!NT_SUCCESS (status)) { @@ -331,7 +327,6 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) CurrentCluster = FirstCluster = pVCB->FatInfo.RootCluster; FCB->entry.FirstCluster = FirstCluster & 0xffff; FCB->entry.FirstClusterHigh = FirstCluster >> 16; - CurrentCluster = FirstCluster; while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) { @@ -469,11 +464,8 @@ vfatAttachFCBToFileObject (PDEVICE_EXTENSION vcb, fileObject->Flags = fileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; fileObject->SectionObjectPointers = &fcb->SectionObjectPointers; - fileObject->FsContext = (PVOID) &fcb->RFCB; + fileObject->FsContext = fcb; fileObject->FsContext2 = newCCB; - newCCB->pFcb = fcb; - newCCB->PtrFileObject = fileObject; - fcb->pDevExt = vcb; DPRINT ("file open: fcb:%x file size: %d\n", fcb, fcb->entry.FileSize); return STATUS_SUCCESS; diff --git a/drivers/fs/vfat/finfo.c b/drivers/fs/vfat/finfo.c index cccbfd6..d8f48ac 100644 --- a/drivers/fs/vfat/finfo.c +++ b/drivers/fs/vfat/finfo.c @@ -553,7 +553,7 @@ NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext) /* INITIALIZATION */ FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass; - FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb; + FCB = (PVFATFCB) IrpContext->FileObject->FsContext; SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; BufferLength = IrpContext->Stack->Parameters.QueryFile.Length; @@ -654,7 +654,7 @@ NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext) /* INITIALIZATION */ FileInformationClass = IrpContext->Stack->Parameters.SetFile.FileInformationClass; - FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb; + FCB = (PVFATFCB) IrpContext->FileObject->FsContext; SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer; DPRINT("FileInformationClass %d\n", FileInformationClass); diff --git a/drivers/fs/vfat/flush.c b/drivers/fs/vfat/flush.c index 7262598..3203199 100644 --- a/drivers/fs/vfat/flush.c +++ b/drivers/fs/vfat/flush.c @@ -36,7 +36,6 @@ NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) { PLIST_ENTRY ListEntry; PVFATFCB Fcb; - PVFATCCB Ccb; NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; DPRINT("VfatFlushVolume(DeviceExt %x, FatFcb %x)\n", DeviceExt, VolumeFcb); @@ -54,11 +53,10 @@ NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) DPRINT1("VfatFlushFile failed, status = %x\n", Status); ReturnStatus = Status; } - /* FIXME: Stop flushing if this a removable media and the media was removed */ + /* FIXME: Stop flushing if this is a removable media and the media was removed */ } - Ccb = (PVFATCCB) DeviceExt->FATFileObject->FsContext2; - Fcb = Ccb->pFcb; + Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext; ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); Status = VfatFlushFile(DeviceExt, Fcb); @@ -79,7 +77,6 @@ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext) { NTSTATUS Status; PVFATFCB Fcb; - PVFATCCB Ccb; /* * This request is not allowed on the main device object. */ @@ -89,9 +86,7 @@ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext) goto ByeBye; } - Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; - assert(Ccb); - Fcb = Ccb->pFcb; + Fcb = (PVFATFCB)IrpContext->FileObject->FsContext; assert(Fcb); if (Fcb->Flags & FCB_IS_VOLUME) diff --git a/drivers/fs/vfat/fsctl.c b/drivers/fs/vfat/fsctl.c index 5d84d45..b66a377 100644 --- a/drivers/fs/vfat/fsctl.c +++ b/drivers/fs/vfat/fsctl.c @@ -301,15 +301,12 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) wcscpy(Fcb->PathName, L"$$Fat$$"); Fcb->ObjectName = Fcb->PathName; DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; - DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB; + DeviceExt->FATFileObject->FsContext = Fcb; DeviceExt->FATFileObject->FsContext2 = Ccb; DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers; DeviceExt->FATFileObject->PrivateCacheMap = NULL; DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb; - Ccb->pFcb = Fcb; - Ccb->PtrFileObject = DeviceExt->FATFileObject; Fcb->FileObject = DeviceExt->FATFileObject; - Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; Fcb->Flags = FCB_IS_FAT; @@ -319,11 +316,11 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) if (DeviceExt->FatInfo.FatType != FAT12) { - Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt)); + Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, CACHEPAGESIZE(DeviceExt)); } else { - Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGE_SIZE); + Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, 2 * PAGE_SIZE); } if (!NT_SUCCESS (Status)) { @@ -349,7 +346,6 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext) VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.Sectors * DeviceExt->FatInfo.BytesPerSector; VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize; VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize; - VolumeFcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice; DeviceExt->VolumeFcb = VolumeFcb; ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); diff --git a/drivers/fs/vfat/makefile b/drivers/fs/vfat/makefile index 0cf3999..21bb030 100644 --- a/drivers/fs/vfat/makefile +++ b/drivers/fs/vfat/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = vfatfs diff --git a/drivers/fs/vfat/misc.c b/drivers/fs/vfat/misc.c index b2bd621..ec26c9d 100644 --- a/drivers/fs/vfat/misc.c +++ b/drivers/fs/vfat/misc.c @@ -71,15 +71,13 @@ NTSTATUS VfatLockControl( ) { PVFATFCB Fcb; - PVFATCCB Ccb; NTSTATUS Status; DPRINT("VfatLockControl(IrpContext %x)\n", IrpContext); assert(IrpContext); - Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; - Fcb = Ccb->pFcb; + Fcb = (PVFATFCB)IrpContext->FileObject->FsContext; if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) { @@ -119,8 +117,6 @@ NTSTATUS STDCALL VfatBuildRequest ( assert (DeviceObject); assert (Irp); - - FsRtlEnterFileSystem(); IrpContext = VfatAllocateIrpContext(DeviceObject, Irp); if (IrpContext == NULL) { @@ -130,9 +126,20 @@ NTSTATUS STDCALL VfatBuildRequest ( } else { + if (KeGetCurrentIrql() <= PASSIVE_LEVEL) + { + FsRtlEnterFileSystem(); + } + else + { + DPRINT1("Vfat is entered at irql = %d\n", KeGetCurrentIrql()); + } Status = VfatDispatchRequest (IrpContext); + if (KeGetCurrentIrql() <= PASSIVE_LEVEL) + { + FsRtlExitFileSystem(); + } } - FsRtlExitFileSystem(); return Status; } diff --git a/drivers/fs/vfat/rw.c b/drivers/fs/vfat/rw.c index cce9f96..a28ca12 100644 --- a/drivers/fs/vfat/rw.c +++ b/drivers/fs/vfat/rw.c @@ -290,7 +290,7 @@ VfatReadFileData (PVFAT_IRP_CONTEXT IrpContext, PVOID Buffer, *LengthRead = 0; Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; - Fcb = Ccb->pFcb; + Fcb = IrpContext->FileObject->FsContext; BytesPerSector = DeviceExt->FatInfo.BytesPerSector; BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster; @@ -451,7 +451,7 @@ NTSTATUS VfatWriteFileData(PVFAT_IRP_CONTEXT IrpContext, assert (IrpContext->FileObject->FsContext2 != NULL); Ccb = (PVFATCCB)IrpContext->FileObject->FsContext2; - Fcb = Ccb->pFcb; + Fcb = IrpContext->FileObject->FsContext; BytesPerCluster = DeviceExt->FatInfo.BytesPerCluster; BytesPerSector = DeviceExt->FatInfo.BytesPerSector; @@ -580,7 +580,6 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext) { NTSTATUS Status; PVFATFCB Fcb; - PVFATCCB Ccb; ULONG Length; ULONG ReturnedLength = 0; PERESOURCE Resource = NULL; @@ -605,9 +604,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext) assert(IrpContext->DeviceExt); assert(IrpContext->FileObject); - Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; - assert(Ccb); - Fcb = Ccb->pFcb; + Fcb = IrpContext->FileObject->FsContext; assert(Fcb); DPRINT("<%S>\n", Fcb->PathName); @@ -711,7 +708,7 @@ VfatRead(PVFAT_IRP_CONTEXT IrpContext) { CacheSize = PAGE_SIZE; } - CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize); + CcRosInitializeFileCache(IrpContext->FileObject, CacheSize); } if (!CcCopyRead(IrpContext->FileObject, &ByteOffset, Length, IrpContext->Flags & IRPCONTEXT_CANWAIT, Buffer, @@ -805,7 +802,6 @@ ByeBye: NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) { - PVFATCCB Ccb; PVFATFCB Fcb; PERESOURCE Resource = NULL; LARGE_INTEGER ByteOffset; @@ -832,9 +828,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) assert(IrpContext->DeviceExt); assert(IrpContext->FileObject); - Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2; - assert(Ccb); - Fcb = Ccb->pFcb; + Fcb = IrpContext->FileObject->FsContext; assert(Fcb); DPRINT("<%S>\n", Fcb->PathName); @@ -988,7 +982,7 @@ NTSTATUS VfatWrite (PVFAT_IRP_CONTEXT IrpContext) { CacheSize = PAGE_SIZE; } - CcRosInitializeFileCache(IrpContext->FileObject, &Fcb->RFCB.Bcb, CacheSize); + CcRosInitializeFileCache(IrpContext->FileObject, CacheSize); } if (ByteOffset.QuadPart > OldFileSize.QuadPart) { diff --git a/drivers/fs/vfat/vfat.h b/drivers/fs/vfat/vfat.h index ac55a1b..f481d6c 100644 --- a/drivers/fs/vfat/vfat.h +++ b/drivers/fs/vfat/vfat.h @@ -181,28 +181,56 @@ extern PVFAT_GLOBAL_DATA VfatGlobalData; typedef struct _VFATFCB { + /* FCB header required by ROS/NT */ REACTOS_COMMON_FCB_HEADER RFCB; SECTION_OBJECT_POINTERS SectionObjectPointers; + ERESOURCE MainResource; + ERESOURCE PagingIoResource; + /* end FCB header required by ROS/NT */ + + /* */ FATDirEntry entry; + /* point on filename (250 chars max) in PathName */ WCHAR *ObjectName; + /* path+filename 260 max */ WCHAR PathName[MAX_PATH]; + + /* short file name */ WCHAR ShortName[14]; + + /* */ LONG RefCount; - PDEVICE_EXTENSION pDevExt; + + /* List of FCB's for this volume */ LIST_ENTRY FcbListEntry; + + /* pointer to the parent fcb */ struct _VFATFCB* parentFcb; + + /* Flags for the fcb */ ULONG Flags; + + /* pointer to the file object which has initialized the fcb */ PFILE_OBJECT FileObject; + + /* Directory index for the short name entry */ ULONG dirIndex; + + /* Directory index where the long name starts */ ULONG startIndex; - ERESOURCE PagingIoResource; - ERESOURCE MainResource; - ULONG TimerCount; + + /* Share access for the file object */ SHARE_ACCESS FCBShareAccess; + + /* Entry into the hash table for the path + long name */ HASHENTRY Hash; + + /* Entry into the hash table for the path + short name */ HASHENTRY ShortHash; + + /* List of byte-range locks for this file */ FILE_LOCK FileLock; /* Structure members used only for paging files. */ @@ -212,9 +240,6 @@ typedef struct _VFATFCB typedef struct _VFATCCB { - VFATFCB * pFcb; - LIST_ENTRY NextCCB; - PFILE_OBJECT PtrFileObject; LARGE_INTEGER CurrentByteOffset; /* for DirectoryControl */ ULONG Entry; diff --git a/drivers/input/include/mouse.h b/drivers/input/include/mouse.h deleted file mode 100644 index 99440c0..0000000 --- a/drivers/input/include/mouse.h +++ /dev/null @@ -1,50 +0,0 @@ -// Mouse definitions common to both mouse class and port drivers - -#define IO_MOUSE_INCREMENT 6 -#define MOUSE_BUFFER_SIZE 32 - -#define IOCTL_INTERNAL_MOUSE_CONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_INTERNAL_MOUSE_DISCONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_INTERNAL_MOUSE_ENABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS) -#define IOCTL_INTERNAL_MOUSE_DISABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS) - -typedef struct _MOUSE_INPUT_DATA { - USHORT UnitId; - USHORT Flags; - union { - ULONG Buttons; - struct { - USHORT ButtonFlags; - USHORT ButtonData; - }; - }; - ULONG RawButtons; - LONG LastX; - LONG LastY; - ULONG ExtraInformation; -} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA; - -typedef struct _CLASS_INFORMATION { - PDEVICE_OBJECT DeviceObject; - PVOID CallBack; -} CLASS_INFORMATION, *PCLASS_INFORMATION; - -typedef struct _GDI_INFORMATION { - PVOID CallBack; -} GDI_INFORMATION, *PGDI_INFORMATION; - -typedef -VOID -(*PSERVICE_CALLBACK_ROUTINE) ( - IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2, - IN OUT PVOID SystemArgument3 - ); - -typedef -VOID -(*PGDI_SERVICE_CALLBACK_ROUTINE) ( - IN PVOID SystemArgument1, - IN ULONG SystemArgument2 - ); diff --git a/drivers/input/keyboard/makefile b/drivers/input/keyboard/makefile index f56c974..602814f 100644 --- a/drivers/input/keyboard/makefile +++ b/drivers/input/keyboard/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = keyboard diff --git a/drivers/input/mouclass/mouclass.c b/drivers/input/mouclass/mouclass.c index 8f5d431..849bb99 100644 --- a/drivers/input/mouclass/mouclass.c +++ b/drivers/input/mouclass/mouclass.c @@ -12,7 +12,7 @@ */ #include -#include "../include/mouse.h" +#include #include "mouclass.h" #define NDEBUG @@ -20,6 +20,40 @@ BOOLEAN AlreadyOpened = FALSE; +VOID MouseClassPassiveCallback(PDEVICE_OBJECT ClassDeviceObject, PVOID Context) +{ + PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension; + MOUSE_INPUT_DATA PortData[MOUSE_BUFFER_SIZE]; + ULONG InputCount; + KIRQL OldIrql; + + assert(NULL != ClassDeviceExtension->GDIInformation.CallBack); + KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql); + DPRINT("Entering MouseClassPassiveCallback\n"); + while (0 != ClassDeviceExtension->InputCount) { + ClassDeviceExtension->PortData -= ClassDeviceExtension->InputCount; + RtlMoveMemory(PortData, ClassDeviceExtension->PortData, + ClassDeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA)); + InputCount = ClassDeviceExtension->InputCount; + ClassDeviceExtension->InputCount = 0; + KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql); + + DPRINT("MouseClassPassiveCallBack() Calling GDI callback at %p\n", + ClassDeviceExtension->GDIInformation.CallBack); + /* We're jumping through hoops to get to run at PASSIVE_LEVEL, let's make + sure we succeeded */ + ASSERT_IRQL(PASSIVE_LEVEL); + (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack) + (PortData, InputCount); + + KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql); + } + + ClassDeviceExtension->PassiveCallbackQueued = FALSE; + DPRINT("Leaving MouseClassPassiveCallback\n"); + KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql); +} + BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart, PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount) { @@ -27,11 +61,13 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M PIRP Irp; ULONG ReadSize; PIO_STACK_LOCATION Stack; + KIRQL OldIrql; // In classical NT, you would take the input data and pipe it through the IO system, for the GDI to read. // In ReactOS, however, we use a GDI callback for increased mouse responsiveness. The reason we don't // simply call from the port driver is so that our mouse class driver can support NT mouse port drivers. + DPRINT("Entering MouseClassCallBack\n"); /* if(ClassDeviceExtension->ReadIsPending == TRUE) { Irp = ClassDeviceObject->CurrentIrp; @@ -56,6 +92,8 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M // If we have data from the port driver and a higher service to send the data to if((*InputCount>0) && (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL)) { + KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql); + if(ClassDeviceExtension->InputCount + *InputCount > MOUSE_BUFFER_SIZE) { ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount; @@ -74,22 +112,26 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M ClassDeviceExtension->PortData += ReadSize; ClassDeviceExtension->InputCount += ReadSize; - // Throw data up to GDI callback if(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL) { - DPRINT("MouseClassCallBack() Calling GDI callback at %p\n", ClassDeviceExtension->GDIInformation.CallBack); - (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack) - (ClassDeviceExtension->PortData - ReadSize, ReadSize); - } else { - DPRINT("MouseClassCallBack() NO GDI callback installed\n"); + if (! ClassDeviceExtension->PassiveCallbackQueued) { + if (NULL == ClassDeviceExtension->WorkItem) { + ClassDeviceExtension->WorkItem = IoAllocateWorkItem(ClassDeviceObject); } - - ClassDeviceExtension->PortData -= ReadSize; - ClassDeviceExtension->InputCount -= ReadSize; - ClassDeviceExtension->ReadIsPending = FALSE; + if (NULL != ClassDeviceExtension->WorkItem) { + DPRINT("Queueing workitem\n"); + IoQueueWorkItem(ClassDeviceExtension->WorkItem, MouseClassPassiveCallback, CriticalWorkQueue, NULL); + ClassDeviceExtension->PassiveCallbackQueued = TRUE; + } + } + } else { + DPRINT("MouseClassCallBack() NO GDI callback installed\n"); + } + KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql); } else { DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount); } + DPRINT("Leaving MouseClassCallBack\n"); return TRUE; } @@ -122,6 +164,9 @@ NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject) DeviceExtension->PortData = ExAllocatePool(NonPagedPool, MOUSE_BUFFER_SIZE * sizeof(MOUSE_INPUT_DATA)); DeviceExtension->InputCount = 0; DeviceExtension->ReadIsPending = FALSE; + DeviceExtension->WorkItem = NULL; + KeInitializeSpinLock(&(DeviceExtension->SpinLock)); + DeviceExtension->PassiveCallbackQueued = FALSE; // Connect our callback to the port driver diff --git a/drivers/input/mouclass/mouclass.h b/drivers/input/mouclass/mouclass.h index cf77cb7..eebba4a 100644 --- a/drivers/input/mouclass/mouclass.h +++ b/drivers/input/mouclass/mouclass.h @@ -1,4 +1,7 @@ typedef struct _DEVICE_EXTENSION { + PIO_WORKITEM WorkItem; + KSPIN_LOCK SpinLock; + BOOLEAN PassiveCallbackQueued; BOOLEAN ReadIsPending; ULONG InputCount; PMOUSE_INPUT_DATA PortData; diff --git a/drivers/input/psaux/mouse.c b/drivers/input/psaux/mouse.c index 6a6fec0..76b4935 100644 --- a/drivers/input/psaux/mouse.c +++ b/drivers/input/psaux/mouse.c @@ -1,18 +1,21 @@ #include -#include "../include/mouse.h" +#include #include "controller.h" #include "mouse.h" #include "psaux.h" // Have we got a PS/2 mouse port? -BOOLEAN has_mouse = FALSE; +static BOOLEAN has_mouse = FALSE; // This buffer holds the mouse scan codes. The PS/2 protocol sends three characters for each event. -unsigned mouse_buffer[3]; -int mouse_buffer_position = 0; +static unsigned mouse_buffer[3]; +static int mouse_buffer_position = 0; // The number of mouse replies expected -int mouse_replies_expected = 0; +static int mouse_replies_expected = 0; + +// Previous button state +static ULONG PreviousButtons = 0; // Handle a mouse event @@ -21,112 +24,138 @@ ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) { PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; - int state_dx, state_dy, state_buttons; + PMOUSE_INPUT_DATA Input; + ULONG Queue, ButtonsDiff; + int state_dx, state_dy; unsigned scancode; unsigned status = controller_read_status(); scancode = controller_read_input(); - /* - * Don't handle the mouse event if we aren't connected to the mouse class - * driver - */ - if (DeviceExtension->ClassInformation.CallBack == NULL) - { - return FALSE; - } + /* Don't handle the mouse event if we aren't connected to the mouse class driver */ + if (DeviceExtension->ClassInformation.CallBack == NULL) + { + return FALSE; + } if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0) - { - // mouse_handle_event(scancode); proceed to handle it - } + { + // mouse_handle_event(scancode); proceed to handle it + } else - { - return FALSE; // keyboard_handle_event(scancode); - } + { + return FALSE; // keyboard_handle_event(scancode); + } - if (mouse_replies_expected > 0) + if (mouse_replies_expected > 0) + { + if (scancode == MOUSE_ACK) { - if (scancode == MOUSE_ACK) - { - mouse_replies_expected--; - return; - } - - mouse_replies_expected = 0; + mouse_replies_expected--; + return; } - + + mouse_replies_expected = 0; + } + /* Add this scancode to the mouse event queue. */ mouse_buffer[mouse_buffer_position] = scancode; mouse_buffer_position++; - + /* If the buffer is full, parse this event */ if (mouse_buffer_position == 3) + { + /* Set local variables for DeviceObject and DeviceExtension */ + DeviceObject = (PDEVICE_OBJECT)ServiceContext; + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + Queue = DeviceExtension->ActiveQueue % 2; + + /* Prevent buffer overflow */ + if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE) + { + return TRUE; + } + + Input = &DeviceExtension->MouseInputData[Queue] + [DeviceExtension->InputDataCount[Queue]]; + + mouse_buffer_position = 0; + + /* Determine the current state of the buttons */ + Input->RawButtons = (mouse_buffer[0] & 1) /* * GPM_B_LEFT */ + + (mouse_buffer[0] & 2) /* * GPM_B_RIGHT */ + + (mouse_buffer[0] & 4) /* * GPM_B_MIDDLE */; + + /* Determine ButtonFlags */ + Input->ButtonFlags = 0; + ButtonsDiff = PreviousButtons ^ Input->RawButtons; + + if (ButtonsDiff & GPM_B_LEFT) + { + if (Input->RawButtons & GPM_B_LEFT) + { + Input->ButtonFlags |= MOUSE_BUTTON_1_DOWN; + } else { + Input->ButtonFlags |= MOUSE_BUTTON_1_UP; + } + } + + if (ButtonsDiff & GPM_B_RIGHT) + { + if (Input->RawButtons & GPM_B_RIGHT) + { + Input->ButtonFlags |= MOUSE_BUTTON_2_DOWN; + } else { + Input->ButtonFlags |= MOUSE_BUTTON_2_UP; + } + } + + if (ButtonsDiff & GPM_B_MIDDLE) { - mouse_buffer_position = 0; - - state_buttons = (mouse_buffer[0] & 1) * GPM_B_LEFT + - (mouse_buffer[0] & 2) * GPM_B_RIGHT + - (mouse_buffer[0] & 4) * GPM_B_MIDDLE; - - /* - * Some PS/2 mice send reports with negative bit set in data[0] and zero - * for movement. I think this is a bug in the mouse, but working around - * it only causes artifacts when the actual report is -256; they'll - * be treated as zero. This should be rare if the mouse sampling rate is - * set to a reasonable value; the default of 100 Hz is plenty. - * (Stephen Tell) - */ - if (mouse_buffer[1] == 0) - { - state_dx = 0; - } - else - { - state_dx = (mouse_buffer[0] & 0x10) ? - mouse_buffer[1] - 256 : - mouse_buffer[1]; - } - - if (mouse_buffer[2] == 0) - { - state_dy = 0; - } - else - { - state_dy = -((mouse_buffer[0] & 0x20) ? - mouse_buffer[2] - 256 : - mouse_buffer[2]); - } - - if (((state_dx!=0) || (state_dy!=0) || (state_buttons!=0))) - { - ULONG Queue; - PMOUSE_INPUT_DATA Input; - - /* FIXME: Implement button state, see /include/ntddmous.h */ - - DeviceObject = (PDEVICE_OBJECT)ServiceContext; - DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; - Queue = DeviceExtension->ActiveQueue % 2; - - if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE) - { - return TRUE; - } - - Input = &DeviceExtension->MouseInputData[Queue] - [DeviceExtension->InputDataCount[Queue]]; - Input->RawButtons = state_buttons; - Input->ButtonData = state_buttons; - Input->LastX = state_dx; - Input->LastY = state_dy; - DeviceExtension->InputDataCount[Queue]++; - - KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, - NULL); - return TRUE; + if (Input->RawButtons & GPM_B_MIDDLE) + { + Input->ButtonFlags |= MOUSE_BUTTON_3_DOWN; + } else { + Input->ButtonFlags |= MOUSE_BUTTON_3_UP; } - } + } + + /* Some PS/2 mice send reports with negative bit set in data[0] and zero for + * movement. I think this is a bug in the mouse, but working around it only + * causes artifacts when the actual report is -256; they'll be treated as zero. + * This should be rare if the mouse sampling rate is set to a reasonable value; + * the default of 100 Hz is plenty. (Stephen Tell) */ + + /* Determine LastX */ + if (mouse_buffer[1] == 0) + { + Input->LastX = 0; + } + else + { + Input->LastX = (mouse_buffer[0] & 0x10) ? mouse_buffer[1] - 256 + : mouse_buffer[1]; + } + + /* Determine LastY */ + if (mouse_buffer[2] == 0) + { + Input->LastY = 0; + } + else + { + Input->LastY = -((mouse_buffer[0] & 0x20) ? mouse_buffer[2] - 256 + : mouse_buffer[2]); + } + + /* Send the Input data to the Mouse Class driver */ + DeviceExtension->InputDataCount[Queue]++; + KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL); + + /* Copy RawButtons to Previous Buttons for Input */ + PreviousButtons = Input->RawButtons; + + return TRUE; + } } /* Write a PS/2 mouse command. */ diff --git a/drivers/input/psaux/mouse.h b/drivers/input/psaux/mouse.h index 5ab0f5f..ed568d7 100644 --- a/drivers/input/psaux/mouse.h +++ b/drivers/input/psaux/mouse.h @@ -1,47 +1,19 @@ // All or parts of this file are from CHAOS (http://www.se.chaosdev.org/). // CHAOS is also under the GNU General Public License. -/* Mouse commands. */ -/* Set resolution. */ - -#define MOUSE_SET_RESOLUTION 0xE8 - -/* Set 1:1 scaling. */ - -#define MOUSE_SET_SCALE11 0xE6 - -/* Set 2:1 scaling. */ - -#define MOUSE_SET_SCALE21 0xE7 - -/* Get scaling factor. */ - -#define MOUSE_GET_SCALE 0xE9 - -/* Set stream mode. */ - -#define MOUSE_SET_STREAM 0xEA - -/* Set sample rate (number of times the controller will poll the port - per second). */ - -#define MOUSE_SET_SAMPLE_RATE 0xF3 - -/* Enable mouse device. */ - -#define MOUSE_ENABLE_DEVICE 0xF4 - -/* Disable mouse device. */ - -#define MOUSE_DISABLE_DEVICE 0xF5 - -/* Reset aux device. */ - -#define MOUSE_RESET 0xFF - -/* Command byte ACK. */ - -#define MOUSE_ACK 0xFA +// Mouse commands +#define MOUSE_SET_RESOLUTION 0xE8 // Set resolution +#define MOUSE_SET_SCALE11 0xE6 // Set 1:1 scaling +#define MOUSE_SET_SCALE21 0xE7 // Set 2:1 scaling +#define MOUSE_GET_SCALE 0xE9 // Get scaling factor +#define MOUSE_SET_STREAM 0xEA // Set stream mode +#define MOUSE_SET_SAMPLE_RATE 0xF3 /* Set sample rate (number of times + * the controller will poll the port + * per second */ +#define MOUSE_ENABLE_DEVICE 0xF4 // Enable mouse device +#define MOUSE_DISABLE_DEVICE 0xF5 // Disable mouse device +#define MOUSE_RESET 0xFF // Reset aux device +#define MOUSE_ACK 0xFA // Command byte ACK #define MOUSE_INTERRUPTS_OFF (CONTROLLER_MODE_KCC | \ CONTROLLER_MODE_DISABLE_MOUSE | \ @@ -53,18 +25,15 @@ CONTROLLER_MODE_MOUSE_INTERRUPT | \ CONTROLLER_MODE_KEYBOARD_INTERRUPT) -/* Used with mouse buttons */ - -#define GPM_B_LEFT 4 -#define GPM_B_MIDDLE 2 -#define GPM_B_RIGHT 1 - -/* Some aux operations take long time. */ +// Used with mouse buttons +#define GPM_B_LEFT 1 +#define GPM_B_RIGHT 2 +#define GPM_B_MIDDLE 4 +// Some aux operations take long time #define MAX_RETRIES 60 -/* Hardware defines. */ - +// Hardware defines #define MOUSE_IRQ 12 #define MOUSE_WRAP_MASK 0x1F @@ -78,3 +47,4 @@ static VOID MouseDpcRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2); + diff --git a/drivers/input/psaux/psaux.c b/drivers/input/psaux/psaux.c index 3393801..5428586 100644 --- a/drivers/input/psaux/psaux.c +++ b/drivers/input/psaux/psaux.c @@ -1,18 +1,15 @@ /* - - ** PS/2 driver 0.0.1 + ** PS/2 driver 0.0.2 ** Written by Jason Filby (jasonfilby@yahoo.com) ** For ReactOS (www.reactos.com) ** Handles the keyboard and mouse on the PS/2 ports ** TODO: Fix detect_ps2_port(void) so that it works under BOCHs - Implement mouse button support - */ #include -#include "../include/mouse.h" +#include #include "mouse.h" #include "psaux.h" @@ -159,7 +156,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) PDEVICE_EXTENSION DeviceExtension; if (detect_ps2_port() == TRUE) { - DbgPrint("PS2 Port Driver version 0.0.1\n"); + DbgPrint("PS2 Port Driver version 0.0.2\n"); } else { DbgPrint("PS2 port not found.\n"); return STATUS_UNSUCCESSFUL; diff --git a/drivers/input/psaux/psaux.h b/drivers/input/psaux/psaux.h index 22eb2b2..590d6ba 100644 --- a/drivers/input/psaux/psaux.h +++ b/drivers/input/psaux/psaux.h @@ -9,5 +9,6 @@ typedef struct _DEVICE_EXTENSION { CLASS_INFORMATION ClassInformation; PKINTERRUPT MouseInterrupt; - KDPC IsrDpc; + KDPC IsrDpc; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; + diff --git a/drivers/input/sermouse/mouse.c b/drivers/input/sermouse/mouse.c deleted file mode 100644 index d402062..0000000 --- a/drivers/input/sermouse/mouse.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - - ** Mouse driver 0.0.3 - ** Written by Jason Filby (jasonfilby@yahoo.com) - ** For ReactOS (www.sid-dis.com/reactos) - - ** Note: The serial.o driver must be loaded before loading this driver - - ** Known Limitations: - ** Only supports mice on COM port 1 - - ** Old Driver, We done build it. Just keep for History. (S.E.) - -*/ - -#include -#include -#include -/* #include */ -#include - -#define MOUSE_IRQ_COM1 4 -#define MOUSE_IRQ_COM2 3 - -#define COM1_PORT 0x3f8 -#define COM2_PORT 0x2f8 - -#define max_screen_x 79 -#define max_screen_y 24 - -static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1; -static unsigned int MOUSE_COM=COM1_PORT; - -static unsigned int bytepos=0, coordinate; -static unsigned char mpacket[3]; -static signed int mouse_x=40, mouse_y=12; -static unsigned char mouse_button1, mouse_button2; -static signed int horiz_sensitivity, vert_sensitivity; - -BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) -{ - unsigned int mbyte=inb(MOUSE_COM); - - // Synchronize - if((mbyte&64)==64) { bytepos=0; }; - - mpacket[bytepos]=mbyte; - bytepos++; - - // Process packet - if(bytepos==3) { - // Retrieve change in x and y from packet - int change_x=((mpacket[0] & 3) << 6) + mpacket[1]; - int change_y=((mpacket[0] & 12) << 4) + mpacket[2]; - - // Some mice need this - if(coordinate==1) { - change_x-=128; - change_y-=128; - }; - - // Change to signed - if(change_x>=128) { change_x=change_x-256; }; - if(change_y>=128) { change_y=change_y-256; }; - - // Adjust mouse position according to sensitivity - mouse_x+=change_x/horiz_sensitivity; - mouse_y+=change_y/vert_sensitivity; - - // Check that mouse is still in screen - if(mouse_x<0) { mouse_x=0; }; - if(mouse_x>max_screen_x) { mouse_x=max_screen_x; }; - if(mouse_y<0) { mouse_y=0; }; - if(mouse_y>max_screen_y) { mouse_y=max_screen_y; }; - - // Retrieve mouse button status from packet - mouse_button1=mpacket[0] & 32; - mouse_button2=mpacket[0] & 16; - - bytepos=0; - }; - -}; - -void InitializeMouseHardware(unsigned int mtype) -{ - char clear_error_bits; - - outb_p(MOUSE_COM+3, 0x80); // set DLAB on - outb_p(MOUSE_COM, 0x60); // speed LO byte - outb_p(MOUSE_COM+1, 0); // speed HI byte - outb_p(MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse - outb_p(MOUSE_COM+1, 0); // set comm and DLAB to 0 - outb_p(MOUSE_COM+4, 1); // DR int enable - - clear_error_bits=inb_p(MOUSE_COM+5); // clear error bits -}; - -int DetMicrosoft(void) -{ - char tmp, ind; - int buttons=0, i; - - outb_p(MOUSE_COM+4, 0x0b); - tmp=inb_p(MOUSE_COM); - - // Check the first for bytes for signs that this is an MS mouse - for(i=0; i<4; i++) { - while((inb_p(MOUSE_COM+5) & 1)==0) ; - ind=inb_p(MOUSE_COM); - if(ind==0x33) buttons=3; - if(ind==0x4d) buttons=2; - }; - - return buttons; -}; - -int CheckMouseType(unsigned int mtype) -{ - unsigned int retval=0; - - InitializeMouseHardware(mtype); - if(mtype==2) retval=DetMicrosoft(); - if(mtype==3) { - outb_p(MOUSE_COM+4, 11); - retval=3; - }; - outb_p(MOUSE_COM+1, 1); - - return retval; -}; - -void ClearMouse(void) -{ - // Waits until the mouse calms down but also quits out after a while - // in case some destructive user wants to keep moving the mouse - // before we're done - - unsigned int restarts=0, i; - for (i=0; i<60000; i++) - { - unsigned temp=inb(MOUSE_COM); - if(temp!=0) { - restarts++; - if(restarts<300000) { - i=0; - } else - { - i=60000; - }; - }; - }; -}; - -void InitializeMouse(void) -{ - int mbuttons=0, gotmouse=0; - ULONG MappedIrq; - KIRQL Dirql; - KAFFINITY Affinity; - PKINTERRUPT IrqObject; - - horiz_sensitivity=2; - vert_sensitivity=3; - - // Check for Microsoft mouse (2 buttons) - if(CheckMouseType(2)!=0) - { - gotmouse=1; - DbgPrint("Microsoft Mouse Detected\n"); - ClearMouse(); - coordinate=0; - }; - - // Check for Microsoft Systems mouse (3 buttons) - if(gotmouse==0) { - if(CheckMouseType(3)!=0) - { - gotmouse=1; - DbgPrint("Microsoft Mouse Detected\n"); - ClearMouse(); - coordinate=1; - }; - }; - - if(gotmouse==0) { - DbgPrint("No Mouse Detected!\n"); - } else { - MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ, - &Dirql, &Affinity); - - IoConnectInterrupt(&IrqObject, microsoft_mouse_handler, NULL, - NULL, MappedIrq, Dirql, Dirql, 0, FALSE, - Affinity, FALSE); - }; -}; - -// For test purposes only -unsigned char get_text_char(int x, int y) -{ - unsigned char getchar; - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - getchar=*vidmem; - return getchar; -}; - -// For test purposes only -unsigned char get_text_color(int x, int y) -{ - unsigned char getcolor; - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - vidmem++; - getcolor=*vidmem; - return getcolor; -}; - -// For test purposes only -void put_text_char(int x, int y, unsigned char putchar[2]) -{ - char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2))); - *vidmem=putchar[0]; - vidmem++; - *vidmem=putchar[1]; -}; - -// For test purposes only -void test_mouse(void) -{ - static int i=0, forcechange=0; - static int old_x=40, old_y=12; - static unsigned char old_cursor[2], new_cursor[2]; - - DbgPrint("Testing mouse..."); - - old_cursor[0]=' '; - old_cursor[1]=7; - new_cursor[0]='Û'; - new_cursor[1]=15; - - old_cursor[0]=get_text_char(mouse_x, mouse_y); - old_cursor[1]=get_text_color(mouse_x, mouse_y); - put_text_char(mouse_x, mouse_y, new_cursor); - - while(i!=1) - { - if(mouse_button1!=0) { new_cursor[1]=10; mouse_button1=0; forcechange=1; }; - if(mouse_button2!=0) { new_cursor[1]=12; mouse_button2=0; forcechange=1; }; - - if((mouse_x!=old_x) || (mouse_y!=old_y) || (forcechange==1)) { - forcechange=0; - - put_text_char(old_x, old_y, old_cursor); - old_cursor[0]=get_text_char(mouse_x, mouse_y); - old_cursor[1]=get_text_color(mouse_x, mouse_y); - put_text_char(mouse_x, mouse_y, new_cursor); - - old_x=mouse_x; - old_y=mouse_y; - }; - }; -}; - -NTSTATUS STDCALL -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) -{ - DbgPrint("Mouse Driver 0.0.3\n"); - InitializeMouse(); - test_mouse(); - - return(STATUS_SUCCESS); -}; - diff --git a/drivers/input/sermouse/mouse.h b/drivers/input/sermouse/mouse.h deleted file mode 100644 index 0532f48..0000000 --- a/drivers/input/sermouse/mouse.h +++ /dev/null @@ -1,12 +0,0 @@ -typedef struct _DEVICE_EXTENSION { - - PDEVICE_OBJECT DeviceObject; - ULONG InputDataCount; - PMOUSE_INPUT_DATA MouseInputData; - CLASS_INFORMATION ClassInformation; - - PKINTERRUPT MouseInterrupt; - KDPC IsrDpc; - KDPC IsrDpcRetry; - -} DEVICE_EXTENSION, *PDEVICE_EXTENSION; \ No newline at end of file diff --git a/drivers/input/sermouse/sermouse.c b/drivers/input/sermouse/sermouse.c index d625924..2772b5d 100644 --- a/drivers/input/sermouse/sermouse.c +++ b/drivers/input/sermouse/sermouse.c @@ -1,111 +1,283 @@ /* - - ** Mouse driver 0.0.4 - ** Written by Jason Filby (jasonfilby@yahoo.com) - ** For ReactOS (www.sid-dis.com/reactos) - - ** Note: The serial.o driver must be loaded before loading this driver - - ** Known Limitations: - ** Only supports mice on COM port 1 - -*/ + * Mouse driver 0.0.6 + * Written by Jason Filby (jasonfilby@yahoo.com) + * For ReactOS (www.reactos.com) + * + * Note: The serial.o driver must be loaded before loading this driver + * + * Known Limitations: + * Only supports Microsoft mice on COM port 1 + * + * Following information obtained from Tomi Engdahl (then@delta.hut.fi), + * http://www.hut.fi/~then/mytexts/mouse.html + * + * Microsoft serial mouse + * + * Serial data parameters: + * 1200bps, 7 databits, 1 stop-bit + * + * Data packet format: + * Data packet is 3 byte packet. It is send to the computer every time mouse + * state changes (mouse moves or keys are pressed/released). + * D7 D6 D5 D4 D3 D2 D1 D0 + * 1. X 1 LB RB Y7 Y6 X7 X6 + * 2. X 0 X5 X4 X3 X2 X1 X0 + * 3. X 0 Y5 Y4 Y3 Y2 Y1 Y0 + * + * Note: The bit marked with X is 0 if the mouse received with 7 databits + * and 2 stop bits format. It is also possible to use 8 databits and 1 stop + * bit format for receiving. In this case X gets value 1. The safest thing + * to get everything working is to use 7 databits and 1 stopbit when + * receiving mouse information (and if you are making mouse then send out + * 7 databits and 2 stop bits). + * The byte marked with 1. is send first, then the others. The bit D6 in + * the first byte is used for syncronizing the software to mouse packets + * if it goes out of sync. + * + * LB is the state of the left button (1 means pressed down) + * RB is the state of the right button (1 means pressed down) + * X7-X0 movement in X direction since last packet (signed byte) + * Y7-Y0 movement in Y direction since last packet (signed byte) + * + * Mouse identification + * When DTR line is toggled, mouse should send one data byte containing + * letter 'M' (ascii 77). + * + * + * Logitech serial mouse + * + * Logitech uses the Microsoft serial mouse protocol in their mouses (for + * example Logitech Pilot mouse and others). The origianal protocol supports + * only two buttons, but logitech as added third button to some of their + * mouse models. To make this possible logitech has made one extension to + * the protocol. + * I have not seen any documentation about the exact documents, but here is + * what I have found out: The information of the third button state is sent + * using one extra byte which is send after the normal packet when needed. + * Value 32 (dec) is sent every time when the center button is pressed down. + * It is also sent every time with the data packet when center button is kept + * down and the mouse data packet is sent for other reasons. When center + * button is released, the mouse sends the normal data packet followed by + * data bythe which has value 0 (dec). As you can see the extra data byte + * is sent only when you mess with the center button. + * + * + * Mouse systems mouse + * + * Serial data parameters: + * 1200bps, 8 databits, 1 stop-bit + * + * Data packet format: + * D7 D6 D5 D4 D3 D2 D1 D0 + * 1. 1 0 0 0 0 LB CB RB + * 2. X7 X6 X5 X4 X3 X2 X1 X0 + * 3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0 + * 4. X7' X6' X5' X4' X3' X2' X1' X0' + * 5. Y7' Y6' Y5' Y4' Y3' Y4' Y1' Y0' + * + * LB is left button state (0 = pressed, 1 = released) + * CB is center button state (0 = pressed, 1 = released) + * RB is right button state (0 = pressed, 1 = released) + * X7-X0 movement in X direction since last packet in signed byte + * format (-128..+127), positive direction right + * Y7-Y0 movement in Y direction since last packet in signed byte + * format (-128..+127), positive direction up + * X7'-X0' movement in X direction since sending of X7-X0 packet in + * signed byte format (-128..+127), positive direction right + * Y7'-Y0' movement in Y direction since sending of Y7-Y0 packet in + * signed byte format (-128..+127), positive direction up + * + * The last two bytes in the packet (bytes 4 and 5) contains information + * about movement data changes which have occured after data bytes 2 and 3 + * have been sent. + * + */ #include -#include "../include/mouse.h" -#include "sermouse.h" -#include "mouse.h" +#include #define MOUSE_IRQ_COM1 4 #define MOUSE_IRQ_COM2 3 -#define COM1_PORT 0x3f8 -#define COM2_PORT 0x2f8 +#define MOUSE_PORT_COM1 0x3f8 +#define MOUSE_PORT_COM2 0x2f8 + +typedef struct _DEVICE_EXTENSION { + PDEVICE_OBJECT DeviceObject; + ULONG ActiveQueue; + ULONG InputDataCount[2]; + MOUSE_INPUT_DATA MouseInputData[2][MOUSE_BUFFER_SIZE]; + CLASS_INFORMATION ClassInformation; -#define max_screen_x 79 -#define max_screen_y 24 + PKINTERRUPT MouseInterrupt; + KDPC IsrDpc; +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; -//static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1; -static unsigned int MOUSE_COM=COM1_PORT; +static unsigned int MOUSE_IRQ = MOUSE_IRQ_COM1; +static unsigned int MOUSE_COM = MOUSE_PORT_COM1; static unsigned int bytepos=0, coordinate; static unsigned char mpacket[3]; -static signed int mouse_x=40, mouse_y=12; static unsigned char mouse_button1, mouse_button2; -static signed int horiz_sensitivity, vert_sensitivity; -BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) +// Previous button state +static ULONG PreviousButtons = 0; + +BOOLEAN STDCALL +microsoft_mouse_handler(IN PKINTERRUPT Interrupt, PVOID ServiceContext) { - unsigned int mbyte=READ_PORT_UCHAR((PUCHAR)MOUSE_COM); + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext; + PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + PMOUSE_INPUT_DATA Input; + ULONG Queue, ButtonsDiff; + unsigned int mbyte; + int change_x; + int change_y; + UCHAR InterruptId = READ_PORT_UCHAR((PUCHAR)MOUSE_COM + 2); + + /* Is the interrupt for us? */ + if (0 != (InterruptId & 0x01)) + { + return FALSE; + } + + /* Not a Receive Data Available interrupt? */ + if (0 == (InterruptId & 0x04)) + { + return TRUE; + } - // Synchronize - if((mbyte&64)==64) { bytepos=0; } + /* Read all available data and process */ + while (0 != (READ_PORT_UCHAR((PUCHAR)MOUSE_COM + 5) & 0x01)) + { + mbyte = READ_PORT_UCHAR((PUCHAR)MOUSE_COM); - mpacket[bytepos]=mbyte; - bytepos++; + /* Synchronize */ + if (0x40 == (mbyte & 0x40)) + bytepos=0; - // Process packet - if(bytepos==3) { - // Retrieve change in x and y from packet - int change_x=((mpacket[0] & 3) << 6) + mpacket[1]; - int change_y=((mpacket[0] & 12) << 4) + mpacket[2]; + mpacket[bytepos] = (mbyte & 0x7f); + bytepos++; - // Some mice need this - if(coordinate==1) { - change_x-=128; - change_y-=128; - } + /* Process packet if complete */ + if (3 == bytepos) + { + /* Set local variables for DeviceObject and DeviceExtension */ + DeviceObject = (PDEVICE_OBJECT)ServiceContext; + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + Queue = DeviceExtension->ActiveQueue % 2; + + /* Prevent buffer overflow */ + if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE) + { + continue; + } + + Input = &DeviceExtension->MouseInputData[Queue] + [DeviceExtension->InputDataCount[Queue]]; + + /* Retrieve change in x and y from packet */ + change_x = (int)(signed char)((mpacket[0] & 0x03) << 6) + mpacket[1]; + change_y = (int)(signed char)((mpacket[0] & 0x0c) << 4) + mpacket[2]; - // Change to signed - if(change_x>=128) { change_x=change_x-256; } - if(change_y>=128) { change_y=change_y-256; } + /* Some mice need this */ + if (1 == coordinate) + { + change_x-=128; + change_y-=128; + } - // Adjust mouse position according to sensitivity - mouse_x+=change_x/horiz_sensitivity; - mouse_y+=change_y/vert_sensitivity; +#if 0 + /* Change to signed */ + if (128 <= change_x) + { + change_x = change_x - 256; + } + if (128 <= change_y) + { + change_y = change_y - 256; + } +#endif + + Input->LastX = 2 * change_x; + Input->LastY = - 3 * change_y; + + /* Retrieve mouse button status from packet */ + mouse_button1 = mpacket[0] & 0x20; + mouse_button2 = mpacket[0] & 0x10; + + /* Determine the current state of the buttons */ + Input->RawButtons = mouse_button1 + mouse_button2; + + /* Determine ButtonFlags */ + Input->ButtonFlags = 0; + ButtonsDiff = PreviousButtons ^ Input->RawButtons; + + if (0 != (ButtonsDiff & 0x20)) + { + if (0 != (Input->RawButtons & 0x20)) + { + Input->ButtonFlags |= MOUSE_BUTTON_1_DOWN; + } + else + { + Input->ButtonFlags |= MOUSE_BUTTON_1_UP; + } + } - // Check that mouse is still in screen - if(mouse_x<0) { mouse_x=0; } - if(mouse_x>max_screen_x) { mouse_x=max_screen_x; } - if(mouse_y<0) { mouse_y=0; } - if(mouse_y>max_screen_y) { mouse_y=max_screen_y; } + if (0 != (ButtonsDiff & 0x10)) + { + if (0 != (Input->RawButtons & 0x10)) + { + Input->ButtonFlags |= MOUSE_BUTTON_2_DOWN; + } + else + { + Input->ButtonFlags |= MOUSE_BUTTON_2_UP; + } + } - // Retrieve mouse button status from packet - mouse_button1=mpacket[0] & 32; - mouse_button2=mpacket[0] & 16; + bytepos=0; + + /* Send the Input data to the Mouse Class driver */ + DeviceExtension->InputDataCount[Queue]++; + KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL); - bytepos=0; + /* Copy RawButtons to Previous Buttons for Input */ + PreviousButtons = Input->RawButtons; + } } + return TRUE; } void InitializeMouseHardware(unsigned int mtype) { - char clear_error_bits; - - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+3, 0x80); // set DLAB on - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM, 0x60); // speed LO byte - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+1, 0); // speed HI byte - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+1, 0); // set comm and DLAB to 0 - WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+4, 1); // DR int enable - - clear_error_bits=READ_PORT_UCHAR((PUCHAR)MOUSE_COM+5); // clear error bits + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM + 3, 0x80); /* set DLAB on */ + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM, 0x60); /* speed LO byte */ + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM + 1, 0); /* speed HI byte */ + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM + 3, mtype); /* 2=MS Mouse; 3=Mouse systems mouse */ + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM + 1, 0); /* set comm and DLAB to 0 */ + WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM + 4, 0x09); /* DR int enable */ + + (void) READ_PORT_UCHAR((PUCHAR)MOUSE_COM+5); /* clear error bits */ } int DetMicrosoft(void) { char tmp, ind; int buttons=0, i, timeout=250; + LARGE_INTEGER Timeout; WRITE_PORT_UCHAR((PUCHAR)MOUSE_COM+4, 0x0b); tmp=READ_PORT_UCHAR((PUCHAR)MOUSE_COM); - // Check the first four bytes for signs that this is an MS mouse + /* Check the first four bytes for signs that this is an MS mouse */ for(i=0; i<4; i++) { while(((READ_PORT_UCHAR((PUCHAR)MOUSE_COM+5) & 1)==0) && (timeout>0)) { - KeDelayExecutionThread (KernelMode, FALSE, 1); + Timeout.QuadPart = 1; + KeDelayExecutionThread (KernelMode, FALSE, &Timeout); timeout--; } ind=READ_PORT_UCHAR((PUCHAR)MOUSE_COM); @@ -133,9 +305,9 @@ int CheckMouseType(unsigned int mtype) void ClearMouse(void) { - // Waits until the mouse calms down but also quits out after a while - // in case some destructive user wants to keep moving the mouse - // before we're done + /* Waits until the mouse calms down but also quits out after a while + * in case some destructive user wants to keep moving the mouse + * before we're done */ unsigned int restarts=0, i; for (i=0; i<60000; i++) @@ -161,10 +333,7 @@ BOOLEAN InitializeMouse(PDEVICE_OBJECT DeviceObject) KIRQL Dirql; KAFFINITY Affinity; - horiz_sensitivity=2; - vert_sensitivity=3; - - // Check for Microsoft mouse (2 buttons) + /* Check for Microsoft mouse (2 buttons) */ if(CheckMouseType(2)!=0) { gotmouse=1; @@ -173,12 +342,12 @@ BOOLEAN InitializeMouse(PDEVICE_OBJECT DeviceObject) coordinate=0; } - // Check for Microsoft Systems mouse (3 buttons) + /* Check for Microsoft Systems mouse (3 buttons) */ if(gotmouse==0) { if(CheckMouseType(3)!=0) { gotmouse=1; - DbgPrint("Microsoft Mouse Detected\n"); + DbgPrint("Mouse Systems Mouse Detected\n"); ClearMouse(); coordinate=1; } @@ -186,29 +355,22 @@ BOOLEAN InitializeMouse(PDEVICE_OBJECT DeviceObject) if(gotmouse==0) return FALSE; - DeviceExtension->InputDataCount = 0; - DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); + DeviceExtension->ActiveQueue = 0; + MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ, &Dirql, &Affinity); - MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ, - &Dirql, &Affinity); - - IoConnectInterrupt(&DeviceExtension->MouseInterrupt, microsoft_mouse_handler, NULL, - NULL, MappedIrq, Dirql, Dirql, 0, FALSE, - Affinity, FALSE); + IoConnectInterrupt(&DeviceExtension->MouseInterrupt, microsoft_mouse_handler, + DeviceObject, NULL, MappedIrq, Dirql, Dirql, 0, FALSE, + Affinity, FALSE); return TRUE; } VOID SerialMouseInitializeDataQueue(PVOID Context) { - ; -/* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension; - - DeviceExtension->InputDataCount = 0; - DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */ } -BOOLEAN MouseSynchronizeRoutine(PVOID Context) +BOOLEAN STDCALL +MouseSynchronizeRoutine(PVOID Context) { PIRP Irp = (PIRP)Context; PMOUSE_INPUT_DATA rec = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer; @@ -221,14 +383,11 @@ BOOLEAN MouseSynchronizeRoutine(PVOID Context) return(TRUE); } - MouseDataRequired=stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA); - MouseDataRead=NrToRead; - CurrentIrp=Irp; - return(FALSE); } -VOID SerialMouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) +VOID STDCALL +SerialMouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; @@ -241,7 +400,8 @@ VOID SerialMouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp) } } -NTSTATUS SerialMouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +NTSTATUS STDCALL +SerialMouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); @@ -254,7 +414,7 @@ NTSTATUS SerialMouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIR DeviceExtension->ClassInformation = *((PCLASS_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - // Reinitialize the port input data queue synchronously + /* Reinitialize the port input data queue synchronously */ KeSynchronizeExecution(DeviceExtension->MouseInterrupt, (PKSYNCHRONIZE_ROUTINE)SerialMouseInitializeDataQueue, DeviceExtension); @@ -277,10 +437,12 @@ NTSTATUS SerialMouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIR return status; } -NTSTATUS SerialMouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) +NTSTATUS STDCALL +SerialMouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp); NTSTATUS Status; + static BOOLEAN AlreadyOpened = FALSE; switch (stk->MajorFunction) { @@ -322,14 +484,17 @@ NTSTATUS SerialMouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) VOID SerialMouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + ULONG Queue; + Queue = DeviceExtension->ActiveQueue % 2; + InterlockedIncrement(&DeviceExtension->ActiveQueue); (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)( DeviceExtension->ClassInformation.DeviceObject, - DeviceExtension->MouseInputData, + DeviceExtension->MouseInputData[Queue], NULL, - &DeviceExtension->InputDataCount); + &DeviceExtension->InputDataCount[Queue]); - DeviceExtension->InputDataCount = 0; + DeviceExtension->InputDataCount[Queue] = 0; } NTSTATUS STDCALL @@ -340,18 +505,13 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) UNICODE_STRING SymlinkName; PDEVICE_EXTENSION DeviceExtension; - DbgPrint("Serial Mouse Driver 0.0.4\n"); - - if(InitializeMouse(DeviceObject) == FALSE) - return STATUS_UNSUCCESSFUL; - DriverObject->MajorFunction[IRP_MJ_CREATE] = SerialMouseDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = SerialMouseDispatch; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = SerialMouseInternalDeviceControl; DriverObject->DriverStartIo = SerialMouseStartIo; RtlInitUnicodeStringFromLiteral(&DeviceName, - L"\\Device\\Mouse"); // FIXME: find correct device name + L"\\Device\\Mouse"); /* FIXME: find correct device name */ IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DeviceName, @@ -361,13 +521,21 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) &DeviceObject); DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO; + if(InitializeMouse(DeviceObject) == TRUE) + { + DbgPrint("Serial Mouse Driver 0.0.5\n"); + } else { + IoDeleteDevice(DeviceObject); + DbgPrint("Serial mouse not found.\n"); + return STATUS_UNSUCCESSFUL; + } + RtlInitUnicodeStringFromLiteral(&SymlinkName, - L"\\??\\Mouse"); // FIXME: find correct device name + L"\\??\\Mouse"); /* FIXME: find correct device name */ IoCreateSymbolicLink(&SymlinkName, &DeviceName); DeviceExtension = DeviceObject->DeviceExtension; KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)SerialMouseIsrDpc, DeviceObject); - KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)SerialMouseIsrDpc, DeviceObject); return(STATUS_SUCCESS); } diff --git a/drivers/input/sermouse/sermouse.h b/drivers/input/sermouse/sermouse.h deleted file mode 100644 index 5ab0f5f..0000000 --- a/drivers/input/sermouse/sermouse.h +++ /dev/null @@ -1,80 +0,0 @@ -// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/). -// CHAOS is also under the GNU General Public License. - -/* Mouse commands. */ -/* Set resolution. */ - -#define MOUSE_SET_RESOLUTION 0xE8 - -/* Set 1:1 scaling. */ - -#define MOUSE_SET_SCALE11 0xE6 - -/* Set 2:1 scaling. */ - -#define MOUSE_SET_SCALE21 0xE7 - -/* Get scaling factor. */ - -#define MOUSE_GET_SCALE 0xE9 - -/* Set stream mode. */ - -#define MOUSE_SET_STREAM 0xEA - -/* Set sample rate (number of times the controller will poll the port - per second). */ - -#define MOUSE_SET_SAMPLE_RATE 0xF3 - -/* Enable mouse device. */ - -#define MOUSE_ENABLE_DEVICE 0xF4 - -/* Disable mouse device. */ - -#define MOUSE_DISABLE_DEVICE 0xF5 - -/* Reset aux device. */ - -#define MOUSE_RESET 0xFF - -/* Command byte ACK. */ - -#define MOUSE_ACK 0xFA - -#define MOUSE_INTERRUPTS_OFF (CONTROLLER_MODE_KCC | \ - CONTROLLER_MODE_DISABLE_MOUSE | \ - CONTROLLER_MODE_SYS | \ - CONTROLLER_MODE_KEYBOARD_INTERRUPT) - -#define MOUSE_INTERRUPTS_ON (CONTROLLER_MODE_KCC | \ - CONTROLLER_MODE_SYS | \ - CONTROLLER_MODE_MOUSE_INTERRUPT | \ - CONTROLLER_MODE_KEYBOARD_INTERRUPT) - -/* Used with mouse buttons */ - -#define GPM_B_LEFT 4 -#define GPM_B_MIDDLE 2 -#define GPM_B_RIGHT 1 - -/* Some aux operations take long time. */ - -#define MAX_RETRIES 60 - -/* Hardware defines. */ - -#define MOUSE_IRQ 12 -#define MOUSE_WRAP_MASK 0x1F - -static PIRP CurrentIrp; -static ULONG MouseDataRead; -static ULONG MouseDataRequired; -static BOOLEAN AlreadyOpened = FALSE; -static KDPC MouseDpc; - -static VOID MouseDpcRoutine(PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2); diff --git a/drivers/lib/zlib/Make_vms.com b/drivers/lib/zlib/Make_vms.com deleted file mode 100644 index 1c57e8f..0000000 --- a/drivers/lib/zlib/Make_vms.com +++ /dev/null @@ -1,115 +0,0 @@ -$! make libz under VMS -$! written by Martin P.J. Zinser -$! -$! Look for the compiler used -$! -$ ccopt = "" -$ if f$getsyi("HW_MODEL").ge.1024 -$ then -$ ccopt = "/prefix=all"+ccopt -$ comp = "__decc__=1" -$ if f$trnlnm("SYS").eqs."" then define sys sys$library: -$ else -$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" -$ then -$ comp = "__vaxc__=1" -$ if f$trnlnm("SYS").eqs."" then define sys sys$library: -$ else -$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: -$ ccopt = "/decc/prefix=all"+ccopt -$ comp = "__decc__=1" -$ endif -$ endif -$! -$! Build the thing plain or with mms -$! -$ write sys$output "Compiling Zlib sources ..." -$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" -$ then -$ dele example.obj;*,minigzip.obj;* -$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - - adler32.c zlib.h zconf.h -$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - - compress.c zlib.h zconf.h -$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - - crc32.c zlib.h zconf.h -$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - - deflate.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - - gzio.c zutil.h zlib.h zconf.h -$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - - infblock.c zutil.h zlib.h zconf.h infblock.h -$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - - infcodes.c zutil.h zlib.h zconf.h inftrees.h -$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - - inffast.c zutil.h zlib.h zconf.h inffast.h -$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - - inflate.c zutil.h zlib.h zconf.h infblock.h -$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - - inftrees.c zutil.h zlib.h zconf.h inftrees.h -$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" - - infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h -$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - - trees.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - - uncompr.c zlib.h zconf.h -$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - - zutil.c zutil.h zlib.h zconf.h -$ write sys$output "Building Zlib ..." -$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ -$ write sys$output "Building example..." -$ CALL MAKE example.OBJ "CC ''CCOPT' example" - - example.c zlib.h zconf.h -$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb -$ write sys$output "Building minigzip..." -$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - - minigzip.c zlib.h zconf.h -$ call make minigzip.exe - - "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - - minigzip.obj libz.olb -$ else -$ mms/macro=('comp') -$ endif -$ write sys$output "Zlib build completed" -$ exit -$! -$! -$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES -$ V = 'F$Verify(0) -$! P1 = What we are trying to make -$! P2 = Command to make it -$! P3 - P8 What it depends on -$ -$ If F$Search(P1) .Eqs. "" Then Goto Makeit -$ Time = F$CvTime(F$File(P1,"RDT")) -$arg=3 -$Loop: -$ Argument = P'arg -$ If Argument .Eqs. "" Then Goto Exit -$ El=0 -$Loop2: -$ File = F$Element(El," ",Argument) -$ If File .Eqs. " " Then Goto Endl -$ AFile = "" -$Loop3: -$ OFile = AFile -$ AFile = F$Search(File) -$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl -$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit -$ Goto Loop3 -$NextEL: -$ El = El + 1 -$ Goto Loop2 -$EndL: -$ arg=arg+1 -$ If arg .Le. 8 Then Goto Loop -$ Goto Exit -$ -$Makeit: -$ VV=F$VERIFY(0) -$ write sys$output P2 -$ 'P2 -$ VV='F$Verify(VV) -$Exit: -$ If V Then Set Verify -$ENDSUBROUTINE diff --git a/drivers/lib/zlib/Makefile b/drivers/lib/zlib/Makefile deleted file mode 100644 index 98244e8..0000000 --- a/drivers/lib/zlib/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../../.. - -TARGET_TYPE = library - -TARGET_NAME = zlib - -TARGET_NORC = yes - -TARGET_CFLAGS = \ - -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -TARGET_OBJECTS = \ - adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o \ - inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - -zlib.sym: - @echo FIXME!>$@ - -# FIXME: this rule should be defined in helper.mk -$(TARGET_NAME).nostrip.a: - @echo FIXME! - @echo FIXME!>$@ - -# EOF diff --git a/drivers/lib/zlib/contrib/asm386/zlibvc.dsp b/drivers/lib/zlib/contrib/asm386/zlibvc.dsp deleted file mode 100644 index a70d4d4..0000000 --- a/drivers/lib/zlib/contrib/asm386/zlibvc.dsp +++ /dev/null @@ -1,651 +0,0 @@ -# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 5.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 -# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 - -CFG=zlibvc - Win32 Release -!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 "zlibvc.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 "zlibvc.mak" CFG="zlibvc - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ - "Win32 (ALPHA) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" - -!IF "$(CFG)" == "zlibvc - 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 Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - 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 "" -CPP=cl.exe -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc__" -# PROP BASE Intermediate_Dir "zlibvc__" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc__" -# PROP Intermediate_Dir "zlibvc__" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -CPP=cl.exe -# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc_0" -# PROP BASE Intermediate_Dir "zlibvc_0" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc_0" -# PROP Intermediate_Dir "zlibvc_0" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc_1" -# PROP BASE Intermediate_Dir "zlibvc_1" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc_1" -# PROP Intermediate_Dir "zlibvc_1" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "zlibvc - Win32 Release" -# Name "zlibvc - Win32 Debug" -# Name "zlibvc - Win32 ReleaseAxp" -# Name "zlibvc - Win32 ReleaseWithoutAsm" -# Name "zlibvc - Win32 ReleaseWithoutCrtdll" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\adler32.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_ADLER=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\compress.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_COMPR=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\crc32.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_CRC32=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\deflate.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_DEFLA=\ - ".\deflate.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\gvmat32c.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\gzio.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_GZIO_=\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infblock.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFBL=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infcodes.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFCO=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inffast.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inffast.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFFA=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inffast.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inflate.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFLA=\ - ".\infblock.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inftrees.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFTR=\ - ".\inftrees.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infutil.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFUT=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\trees.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_TREES=\ - ".\deflate.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\uncompr.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_UNCOM=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\unzip.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\zip.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\zlib.rc -# End Source File -# Begin Source File - -SOURCE=.\zlibvc.def -# End Source File -# Begin Source File - -SOURCE=.\zutil.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_ZUTIL=\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\deflate.h -# End Source File -# Begin Source File - -SOURCE=.\infblock.h -# End Source File -# Begin Source File - -SOURCE=.\infcodes.h -# End Source File -# Begin Source File - -SOURCE=.\inffast.h -# End Source File -# Begin Source File - -SOURCE=.\inftrees.h -# End Source File -# Begin Source File - -SOURCE=.\infutil.h -# End Source File -# Begin Source File - -SOURCE=.\zconf.h -# End Source File -# Begin Source File - -SOURCE=.\zlib.h -# End Source File -# Begin Source File - -SOURCE=.\zutil.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" -# End Group -# End Target -# End Project diff --git a/drivers/lib/zlib/contrib/asm386/zlibvc.dsw b/drivers/lib/zlib/contrib/asm386/zlibvc.dsw deleted file mode 100644 index 493cd87..0000000 --- a/drivers/lib/zlib/contrib/asm386/zlibvc.dsw +++ /dev/null @@ -1,41 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 5.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/drivers/lib/zlib/contrib/minizip/zlibvc.dsp b/drivers/lib/zlib/contrib/minizip/zlibvc.dsp deleted file mode 100644 index a70d4d4..0000000 --- a/drivers/lib/zlib/contrib/minizip/zlibvc.dsp +++ /dev/null @@ -1,651 +0,0 @@ -# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 5.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 -# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 - -CFG=zlibvc - Win32 Release -!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 "zlibvc.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 "zlibvc.mak" CFG="zlibvc - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ - "Win32 (ALPHA) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ - "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" - -!IF "$(CFG)" == "zlibvc - 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 Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - 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 "" -CPP=cl.exe -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc__" -# PROP BASE Intermediate_Dir "zlibvc__" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc__" -# PROP Intermediate_Dir "zlibvc__" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -CPP=cl.exe -# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc_0" -# PROP BASE Intermediate_Dir "zlibvc_0" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc_0" -# PROP Intermediate_Dir "zlibvc_0" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "zlibvc_1" -# PROP BASE Intermediate_Dir "zlibvc_1" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "zlibvc_1" -# PROP Intermediate_Dir "zlibvc_1" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -CPP=cl.exe -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c -# SUBTRACT CPP /YX -MTL=midl.exe -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "zlibvc - Win32 Release" -# Name "zlibvc - Win32 Debug" -# Name "zlibvc - Win32 ReleaseAxp" -# Name "zlibvc - Win32 ReleaseWithoutAsm" -# Name "zlibvc - Win32 ReleaseWithoutCrtdll" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\adler32.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_ADLER=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\compress.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_COMPR=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\crc32.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_CRC32=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\deflate.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_DEFLA=\ - ".\deflate.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\gvmat32c.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\gzio.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_GZIO_=\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infblock.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFBL=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infcodes.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFCO=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inffast.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inffast.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFFA=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inffast.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inflate.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFLA=\ - ".\infblock.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\inftrees.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFTR=\ - ".\inftrees.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\infutil.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_INFUT=\ - ".\infblock.h"\ - ".\infcodes.h"\ - ".\inftrees.h"\ - ".\infutil.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\trees.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_TREES=\ - ".\deflate.h"\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\uncompr.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_UNCOM=\ - ".\zconf.h"\ - ".\zlib.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\unzip.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\zip.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\zlib.rc -# End Source File -# Begin Source File - -SOURCE=.\zlibvc.def -# End Source File -# Begin Source File - -SOURCE=.\zutil.c - -!IF "$(CFG)" == "zlibvc - Win32 Release" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" - -DEP_CPP_ZUTIL=\ - ".\zconf.h"\ - ".\zlib.h"\ - ".\zutil.h"\ - - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" - -!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" - -!ENDIF - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\deflate.h -# End Source File -# Begin Source File - -SOURCE=.\infblock.h -# End Source File -# Begin Source File - -SOURCE=.\infcodes.h -# End Source File -# Begin Source File - -SOURCE=.\inffast.h -# End Source File -# Begin Source File - -SOURCE=.\inftrees.h -# End Source File -# Begin Source File - -SOURCE=.\infutil.h -# End Source File -# Begin Source File - -SOURCE=.\zconf.h -# End Source File -# Begin Source File - -SOURCE=.\zlib.h -# End Source File -# Begin Source File - -SOURCE=.\zutil.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" -# End Group -# End Target -# End Project diff --git a/drivers/lib/zlib/contrib/minizip/zlibvc.dsw b/drivers/lib/zlib/contrib/minizip/zlibvc.dsw deleted file mode 100644 index 493cd87..0000000 --- a/drivers/lib/zlib/contrib/minizip/zlibvc.dsw +++ /dev/null @@ -1,41 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 5.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/drivers/lib/zlib/makefile.reactos b/drivers/lib/zlib/makefile.reactos deleted file mode 100644 index 0dd73db..0000000 --- a/drivers/lib/zlib/makefile.reactos +++ /dev/null @@ -1,26 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../../.. - -TARGET_TYPE = library - -TARGET_NAME = zlib - -TARGET_CFLAGS = \ - -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -TARGET_OBJECTS = \ - adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o \ - inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - -# FIXME: this rule should be defined in helper.mk -$(TARGET_NAME).nostrip.a: - @echo FIXME! - @echo FIXME!>$@ - -# EOF diff --git a/drivers/net/ndis/ndis.def b/drivers/net/ndis/ndis.def index f2dbdad..28373c0 100644 --- a/drivers/net/ndis/ndis.def +++ b/drivers/net/ndis/ndis.def @@ -296,7 +296,7 @@ NdisUpcaseUnicodeString@8 NdisUpdateSharedMemory@20 NdisWaitEvent@8 NdisWriteConfiguration@16 -;NdisWriteErrorLogEntry ? +NdisWriteErrorLogEntry@16 NdisWriteEventLogEntry@28 NdisWritePciSlotInformation@20 NdisWritePcmciaAttributeMemory@16 diff --git a/drivers/net/ndis/ndis.edf b/drivers/net/ndis/ndis.edf index 11ee1f9..c89a025 100644 --- a/drivers/net/ndis/ndis.edf +++ b/drivers/net/ndis/ndis.edf @@ -296,7 +296,7 @@ NdisUpcaseUnicodeString=NdisUpcaseUnicodeString@8 NdisUpdateSharedMemory=NdisUpdateSharedMemory@20 NdisWaitEvent=NdisWaitEvent@8 NdisWriteConfiguration=NdisWriteConfiguration@16 -;NdisWriteErrorLogEntry ? +NdisWriteErrorLogEntry=NdisWriteErrorLogEntry@16 NdisWriteEventLogEntry=NdisWriteEventLogEntry@28 NdisWritePciSlotInformation=NdisWritePciSlotInformation@20 NdisWritePcmciaAttributeMemory=NdisWritePcmciaAttributeMemory@16 diff --git a/drivers/net/ndis/ndis/miniport.c b/drivers/net/ndis/ndis/miniport.c index cd1d3e7..6382a11 100644 --- a/drivers/net/ndis/ndis/miniport.c +++ b/drivers/net/ndis/ndis/miniport.c @@ -16,8 +16,8 @@ #ifdef DBG /* See debug.h for debug/trace constants */ -ULONG DebugTraceLevel = MIN_TRACE; -//ULONG DebugTraceLevel = (MAX_TRACE + DEBUG_MINIPORT); +//ULONG DebugTraceLevel = MIN_TRACE; +ULONG DebugTraceLevel = (MAX_TRACE + DEBUG_MINIPORT); #endif /* DBG */ @@ -1275,7 +1275,17 @@ NdisMSetAttributesEx( * AdapterType = Specifies the I/O bus interface of the caller's NIC */ { - UNIMPLEMENTED + // Currently just like NdisMSetAttributesEx + // TODO: Take CheckForHandTimeInSeconds into account! + PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle); + + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); + NDIS_DbgPrint(MIN_TRACE, ("NdisMSetAttributesEx() is partly-implemented.")); + + Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext; + Adapter->Attributes = AttributeFlags & NDIS_ATTRIBUTE_BUS_MASTER; + Adapter->NdisMiniportBlock.AdapterType = AdapterType; + Adapter->AttributesSet = TRUE; } diff --git a/drivers/net/ndis/ndis/stubs.c b/drivers/net/ndis/ndis/stubs.c index 76c2eb2..1360d9e 100644 --- a/drivers/net/ndis/ndis/stubs.c +++ b/drivers/net/ndis/ndis/stubs.c @@ -153,7 +153,10 @@ NdisWriteErrorLogEntry( IN NDIS_HANDLE NdisAdapterHandle, IN NDIS_ERROR_CODE ErrorCode, IN ULONG NumberOfErrorValues, - /* IN ULONG */ ...) + IN ULONG ERROR_LOG_MAXIMUM_SIZE) +/* IN ULONG ...) + * ERROR_LOG_MAXIMUM_SIZE = ... in MSDN + */ { UNIMPLEMENTED } diff --git a/drivers/net/packet/Makefile b/drivers/net/packet/Makefile index 24b4fe2..68cf2e7 100644 --- a/drivers/net/packet/Makefile +++ b/drivers/net/packet/Makefile @@ -11,6 +11,8 @@ TARGET_NAME = packet TARGET_CFLAGS = -DDBG -DWIN_NT_DRIVER -DKQPC_TS -DUSE_KLOCKS -I$(PATH_TO_TOP)/ntoskrnl/include +TARGET_DDKLIBS = ndis.a + TARGET_OBJECTS = \ packet.o \ openclos.o \ @@ -29,15 +31,6 @@ TARGET_OBJECTS = \ bucket_lookup.o \ normal_lookup.o - -TARGET_DDKLIBS = ndis.a - -TARGET_CLEAN = \ - *.o \ - *.coff - -TARGET_PATH = . - include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk diff --git a/drivers/storage/atapi/atapi.c b/drivers/storage/atapi/atapi.c index d85ba3a..e540426 100644 --- a/drivers/storage/atapi/atapi.c +++ b/drivers/storage/atapi/atapi.c @@ -2174,6 +2174,9 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow); IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead); + /* Indicate expecting an interrupt. */ + DeviceExtension->ExpectingInterrupt = TRUE; + /* Issue command to drive */ IDEWriteCommand(DeviceExtension->CommandPortBase, Command); @@ -2224,8 +2227,6 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, TransferSize); } } - /* Indicate expecting an interrupt. */ - DeviceExtension->ExpectingInterrupt = TRUE; DPRINT("AtapiReadWrite() done!\n"); diff --git a/drivers/storage/atapi/makefile b/drivers/storage/atapi/makefile index b24da0d..0748db1 100644 --- a/drivers/storage/atapi/makefile +++ b/drivers/storage/atapi/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = atapi diff --git a/drivers/storage/cdrom/makefile b/drivers/storage/cdrom/makefile index 3e3ad3a..805d00d 100644 --- a/drivers/storage/cdrom/makefile +++ b/drivers/storage/cdrom/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = cdrom diff --git a/drivers/storage/class2/class2.c b/drivers/storage/class2/class2.c index c36b07e..76bb8d9 100644 --- a/drivers/storage/class2/class2.c +++ b/drivers/storage/class2/class2.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2001, 2002 ReactOS Team + * Copyright (C) 2001, 2002, 2003 ReactOS Team * * 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 @@ -1245,12 +1245,12 @@ ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, { if (WriteToDevice == TRUE) { - RequestType = IOCTL_SCSI_EXECUTE_OUT; - Srb->SrbFlags = SRB_FLAGS_DATA_OUT; + RequestType = IOCTL_SCSI_EXECUTE_IN; // needs _in_ to the device + Srb->SrbFlags = SRB_FLAGS_DATA_OUT; // needs _out_ from the caller } else { - RequestType = IOCTL_SCSI_EXECUTE_IN; + RequestType = IOCTL_SCSI_EXECUTE_OUT; Srb->SrbFlags = SRB_FLAGS_DATA_IN; } } @@ -1528,7 +1528,8 @@ ScsiClassReadWrite(IN PDEVICE_OBJECT DeviceObject, } /* Adjust partition-relative starting offset to absolute offset */ - IrpStack->Parameters.Read.ByteOffset.QuadPart += DeviceExtension->StartingOffset.QuadPart; + IrpStack->Parameters.Read.ByteOffset.QuadPart += + (DeviceExtension->StartingOffset.QuadPart + DeviceExtension->DMByteSkew); /* Calculate number of pages in this transfer */ CurrentTransferPages = diff --git a/drivers/storage/class2/makefile b/drivers/storage/class2/makefile index bdfe08f..7785537 100644 --- a/drivers/storage/class2/makefile +++ b/drivers/storage/class2/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = export_driver TARGET_NAME = class2 diff --git a/drivers/storage/disk/disk.c b/drivers/storage/disk/disk.c index 2e54035..354be2b 100644 --- a/drivers/storage/disk/disk.c +++ b/drivers/storage/disk/disk.c @@ -1,6 +1,6 @@ /* * ReactOS kernel - * Copyright (C) 2001, 2002 ReactOS Team + * Copyright (C) 2001, 2002, 2003 ReactOS Team * * 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 @@ -40,6 +40,9 @@ typedef struct _DISK_DATA { + PDEVICE_EXTENSION NextPartition; + ULONG Signature; + ULONG MbrCheckSum; ULONG HiddenSectors; ULONG PartitionNumber; ULONG PartitionOrdinal; @@ -82,28 +85,47 @@ NTSTATUS STDCALL DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +static BOOLEAN +ScsiDiskSearchForDisk(IN PDEVICE_EXTENSION DeviceExtension, + IN HANDLE BusKey, + OUT PULONG DetectedDiskNumber); + +static VOID +DiskClassUpdatePartitionDeviceObjects (IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +static VOID +ScsiDiskUpdateFixedDiskGeometry(IN PDEVICE_EXTENSION DeviceExtension); + +static BOOLEAN +ScsiDiskCalcMbrCheckSum(IN PDEVICE_EXTENSION DeviceExtension, + OUT PULONG Checksum); /* FUNCTIONS ****************************************************************/ -// DriverEntry -// -// DESCRIPTION: -// This function initializes the driver, locates and claims -// hardware resources, and creates various NT objects needed -// to process I/O requests. -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// IN PDRIVER_OBJECT DriverObject System allocated Driver Object -// for this driver -// IN PUNICODE_STRING RegistryPath Name of registry driver service -// key -// -// RETURNS: -// NTSTATUS +/********************************************************************** + * NAME EXPORTED + * DriverEntry + * + * DESCRIPTION + * This function initializes the driver, locates and claims + * hardware resources, and creates various NT objects needed + * to process I/O requests. + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DriverObject + * System allocated Driver Object for this driver + * + * RegistryPath + * Name of registry driver service key + * + * RETURN VALUE + * Status + */ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject, @@ -353,7 +375,7 @@ DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject, /********************************************************************** - * NAME EXPORTED + * NAME INTERNAL * DiskClassCreateDeviceObject * * DESCRIPTION @@ -401,6 +423,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, PPARTITION_INFORMATION PartitionEntry; PDISK_DATA DiskData; ULONG PartitionNumber; + PVOID MbrBuffer; NTSTATUS Status; DPRINT("DiskClassCreateDeviceObject() called\n"); @@ -482,6 +505,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, DiskDeviceExtension = DiskDeviceObject->DeviceExtension; DiskDeviceExtension->LockCount = 0; DiskDeviceExtension->DeviceNumber = DiskNumber; + DiskDeviceExtension->DeviceObject = DiskDeviceObject; DiskDeviceExtension->PortDeviceObject = PortDeviceObject; DiskDeviceExtension->PhysicalDevice = DiskDeviceObject; DiskDeviceExtension->PortCapabilities = Capabilities; @@ -540,6 +564,25 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, DPRINT("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector); + /* Check disk for presence of a disk manager */ + HalExamineMBR(DiskDeviceObject, + DiskDeviceExtension->DiskGeometry->BytesPerSector, + 0x54, + &MbrBuffer); + if (MbrBuffer != NULL) + { + /* Start disk at sector 63 if the Ontrack Disk Manager was found */ + DPRINT("Found 'Ontrack Disk Manager'!\n"); + + DiskDeviceExtension->DMSkew = 63; + DiskDeviceExtension->DMByteSkew = + 63 * DiskDeviceExtension->DiskGeometry->BytesPerSector; + DiskDeviceExtension->DMActive = TRUE; + + ExFreePool(MbrBuffer); + MbrBuffer = NULL; + } + if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) && (DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia)) { @@ -597,9 +640,37 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, if (NT_SUCCESS(Status)) { DPRINT("Read partition table!\n"); - DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount); + /* Set disk signature */ + DiskData->Signature = PartitionList->Signature; + + /* Calculate MBR checksum if disk got no signature */ + if (DiskData->Signature == 0) + { + if (!ScsiDiskCalcMbrCheckSum(DiskDeviceExtension, + &DiskData->MbrCheckSum)) + { + DPRINT("MBR checksum calculation failed for disk %lu\n", + DiskDeviceExtension->DeviceNumber); + } + else + { + DPRINT("MBR checksum for disk %lu is %lx\n", + DiskDeviceExtension->DeviceNumber, + DiskData->MbrCheckSum); + } + } + else + { + DPRINT("Signature on disk %lu is %lx\n", + DiskDeviceExtension->DeviceNumber, + DiskData->Signature); + } + + /* Update disk geometry if disk is visible to the BIOS */ + ScsiDiskUpdateFixedDiskGeometry(DiskDeviceExtension); + for (PartitionNumber = 0; PartitionNumber < PartitionList->PartitionCount; PartitionNumber++) { PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber]; @@ -634,6 +705,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, PartitionDeviceExtension = PartitionDeviceObject->DeviceExtension; PartitionDeviceExtension->LockCount = 0; PartitionDeviceExtension->DeviceNumber = DiskNumber; + PartitionDeviceExtension->DeviceObject = PartitionDeviceObject; PartitionDeviceExtension->PortDeviceObject = PortDeviceObject; PartitionDeviceExtension->DiskGeometry = DiskDeviceExtension->DiskGeometry; PartitionDeviceExtension->PhysicalDevice = DiskDeviceExtension->PhysicalDevice; @@ -642,6 +714,9 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, PartitionEntry->StartingOffset.QuadPart; PartitionDeviceExtension->PartitionLength.QuadPart = PartitionEntry->PartitionLength.QuadPart; + PartitionDeviceExtension->DMSkew = DiskDeviceExtension->DMSkew; + PartitionDeviceExtension->DMByteSkew = DiskDeviceExtension->DMByteSkew; + PartitionDeviceExtension->DMActive = DiskDeviceExtension->DMActive; PartitionDeviceExtension->PortNumber = (UCHAR)PortNumber; PartitionDeviceExtension->PathId = InquiryData->PathId; PartitionDeviceExtension->TargetId = InquiryData->TargetId; @@ -652,7 +727,12 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, ScsiClassInitializeSrbLookasideList(PartitionDeviceExtension, 8); + /* Link current partition device extension to previous disk data */ + DiskData->NextPartition = PartitionDeviceExtension; + + /* Initialize current disk data */ DiskData = (PDISK_DATA)(PartitionDeviceExtension + 1); + DiskData->NextPartition = NULL; DiskData->PartitionType = PartitionEntry->PartitionType; DiskData->PartitionNumber = PartitionNumber + 1; DiskData->PartitionOrdinal = PartitionNumber + 1; @@ -873,15 +953,18 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, } else { - Status = IoWritePartitionTable(DeviceExtension->DeviceObject, + /* Update partition device objects */ + DiskClassUpdatePartitionDeviceObjects (DeviceObject, + Irp); + + /* Write partition table */ + Status = IoWritePartitionTable(DeviceExtension->PhysicalDevice, DeviceExtension->DiskGeometry->BytesPerSector, DeviceExtension->DiskGeometry->SectorsPerTrack, DeviceExtension->DiskGeometry->TracksPerCylinder, PartitionList); if (NT_SUCCESS(Status)) { - /* FIXME: Update partition device objects */ - Information = TableSize; } } @@ -1024,4 +1107,779 @@ DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, return(IoCallDriver(DeviceExtension->PortDeviceObject, Irp)); } + +/********************************************************************** + * NAME INTERNAL + * DiskClassUpdatePartitionDeviceObjects + * + * DESCRIPTION + * Deletes, modifies or creates partition device objects. + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DeviceObject + * Pointer to the device. + * + * Irp + * Pointer to the IRP + * + * RETURN VALUE + * None + */ + +static VOID +DiskClassUpdatePartitionDeviceObjects(IN PDEVICE_OBJECT DiskDeviceObject, + IN PIRP Irp) +{ + PDRIVE_LAYOUT_INFORMATION PartitionList; + PPARTITION_INFORMATION PartitionEntry; + PDEVICE_EXTENSION DeviceExtension; + PDEVICE_EXTENSION DiskDeviceExtension; + PDISK_DATA DiskData; + ULONG PartitionCount; + ULONG PartitionOrdinal; + ULONG PartitionNumber; + ULONG LastPartitionNumber; + ULONG i; + BOOLEAN Found; + WCHAR NameBuffer[MAX_PATH]; + UNICODE_STRING DeviceName; + PDEVICE_OBJECT DeviceObject; + NTSTATUS Status; + + DPRINT("ScsiDiskUpdatePartitionDeviceObjects() called\n"); + + /* Get partition list */ + PartitionList = Irp->AssociatedIrp.SystemBuffer; + + /* Round partition count up by 4 */ + PartitionCount = ((PartitionList->PartitionCount + 3) / 4) * 4; + + /* Remove the partition numbers from the partition list */ + for (i = 0; i < PartitionCount; i++) + { + PartitionList->PartitionEntry[i].PartitionNumber = 0; + } + + DiskDeviceExtension = DiskDeviceObject->DeviceExtension; + + /* Traverse on-disk partition list */ + LastPartitionNumber = 0; + DeviceExtension = DiskDeviceExtension; + DiskData = (PDISK_DATA)(DeviceExtension + 1); + while (TRUE) + { + DeviceExtension = DiskData->NextPartition; + if (DeviceExtension == NULL) + break; + + /* Get disk data */ + DiskData = (PDISK_DATA)(DeviceExtension + 1); + + /* Update last partition number */ + if (DiskData->PartitionNumber > LastPartitionNumber) + LastPartitionNumber = DiskData->PartitionNumber; + + /* Ignore unused on-disk partitions */ + if (DeviceExtension->PartitionLength.QuadPart == 0ULL) + continue; + + Found = FALSE; + PartitionOrdinal = 0; + for (i = 0; i < PartitionCount; i++) + { + /* Get current partition entry */ + PartitionEntry = &PartitionList->PartitionEntry[i]; + + /* Ignore empty (aka unused) or extended partitions */ + if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED || + IsContainerPartition (PartitionEntry->PartitionType)) + continue; + + PartitionOrdinal++; + + /* Check for matching partition start offset and length */ + if ((PartitionEntry->StartingOffset.QuadPart != + DeviceExtension->StartingOffset.QuadPart) || + (PartitionEntry->PartitionLength.QuadPart != + DeviceExtension->PartitionLength.QuadPart)) + continue; + + DPRINT1("Found matching partition entry for partition %lu\n", + DiskData->PartitionNumber); + + /* Found matching partition */ + Found = TRUE; + + /* Update partition number in partition list */ + PartitionEntry->PartitionNumber = DiskData->PartitionNumber; + break; + } + + if (Found == TRUE) + { + /* Get disk data for current partition */ + DiskData = (PDISK_DATA)(DeviceExtension + 1); + + /* Update partition type if partiton will be rewritten */ + if (PartitionEntry->RewritePartition == TRUE) + DiskData->PartitionType = PartitionEntry->PartitionType; + + /* Assign new partiton ordinal */ + DiskData->PartitionOrdinal = PartitionOrdinal; + + DPRINT("Partition ordinal %lu was assigned to partition %lu\n", + DiskData->PartitionOrdinal, + DiskData->PartitionNumber); + } + else + { + /* Delete this partition */ + DeviceExtension->PartitionLength.QuadPart = 0ULL; + + DPRINT("Deleting partition %lu\n", + DiskData->PartitionNumber); + } + } + + /* Traverse partiton list and create new partiton devices */ + PartitionOrdinal = 0; + for (i = 0; i < PartitionCount; i++) + { + /* Get current partition entry */ + PartitionEntry = &PartitionList->PartitionEntry[i]; + + /* Ignore empty (aka unused) or extended partitions */ + if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED || + IsContainerPartition (PartitionEntry->PartitionType)) + continue; + + PartitionOrdinal++; + + /* Ignore unchanged partition entries */ + if (PartitionEntry->RewritePartition == FALSE) + continue; + + /* Check for an unused device object */ + PartitionNumber = 0; + DeviceExtension = DiskDeviceExtension; + DiskData = (PDISK_DATA)(DeviceExtension + 1); + while (TRUE) + { + DeviceExtension = DiskData->NextPartition; + if (DeviceExtension == NULL) + break; + + /* Get partition disk data */ + DiskData = (PDISK_DATA)(DeviceExtension + 1); + + /* Found a free (unused) partition (device object) */ + if (DeviceExtension->PartitionLength.QuadPart == 0ULL) + { + PartitionNumber = DiskData->PartitionNumber; + break; + } + } + + if (PartitionNumber == 0) + { + /* Create a new partition device object */ + DPRINT("Create new partition device object\n"); + + /* Get new partiton number */ + LastPartitionNumber++; + PartitionNumber = LastPartitionNumber; + + /* Create partition device object */ + swprintf(NameBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + DiskDeviceExtension->DeviceNumber, + PartitionNumber); + RtlInitUnicodeString(&DeviceName, + NameBuffer); + + Status = IoCreateDevice(DiskDeviceObject->DriverObject, + sizeof(DEVICE_EXTENSION) + sizeof(DISK_DATA), + &DeviceName, + FILE_DEVICE_DISK, + 0, + FALSE, + &DeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoCreateDevice() failed (Status %lx)\n", Status); + continue; + } + + DeviceObject->Flags |= DO_DIRECT_IO; + DeviceObject->StackSize = DiskDeviceObject->StackSize; + DeviceObject->Characteristics = DiskDeviceObject->Characteristics; + DeviceObject->AlignmentRequirement = DiskDeviceObject->AlignmentRequirement; + + /* Initialize device extension */ + DeviceExtension = DeviceObject->DeviceExtension; + RtlCopyMemory(DeviceExtension, + DiskDeviceObject->DeviceExtension, + sizeof(DEVICE_EXTENSION)); + DeviceExtension->DeviceObject = DeviceObject; + + /* Initialize lookaside list for SRBs */ + ScsiClassInitializeSrbLookasideList(DeviceExtension, + 8); + + /* Link current partition device extension to previous disk data */ + DiskData->NextPartition = DeviceExtension; + DiskData = (PDISK_DATA)(DeviceExtension + 1); + DiskData->NextPartition = NULL; + } + else + { + /* Reuse an existing partition device object */ + DPRINT("Reuse an exisiting partition device object\n"); + DiskData = (PDISK_DATA)(DeviceExtension + 1); + } + + /* Update partition data and device extension */ + DiskData->PartitionNumber = PartitionNumber; + DiskData->PartitionOrdinal = PartitionOrdinal; + DiskData->PartitionType = PartitionEntry->PartitionType; + DiskData->BootIndicator = PartitionEntry->BootIndicator; + DiskData->HiddenSectors = PartitionEntry->HiddenSectors; + DeviceExtension->StartingOffset = PartitionEntry->StartingOffset; + DeviceExtension->PartitionLength = PartitionEntry->PartitionLength; + + /* Update partition number in the partition list */ + PartitionEntry->PartitionNumber = PartitionNumber; + + DPRINT("Partition ordinal %lu was assigned to partition %lu\n", + DiskData->PartitionOrdinal, + DiskData->PartitionNumber); + } + + DPRINT("ScsiDiskUpdatePartitionDeviceObjects() done\n"); +} + + +/********************************************************************** + * NAME INTERNAL + * ScsiDiskSearchForDisk + * + * DESCRIPTION + * Searches the hardware tree for the given disk. + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DeviceExtension + * Disk device extension. + * + * BusKey + * Handle to the hardware bus key. + * + * DetectedDiskNumber + * Returned disk number. + * + * RETURN VALUE + * TRUE: Disk was found. + * FALSE: Search failed. + */ + +static BOOLEAN +ScsiDiskSearchForDisk(IN PDEVICE_EXTENSION DeviceExtension, + IN HANDLE BusKey, + OUT PULONG DetectedDiskNumber) +{ + PKEY_VALUE_FULL_INFORMATION ValueData; + OBJECT_ATTRIBUTES ObjectAttributes; + PDISK_DATA DiskData; + UNICODE_STRING IdentifierString; + UNICODE_STRING NameString; + HANDLE BusInstanceKey; + HANDLE ControllerKey; + HANDLE DiskKey; + HANDLE DiskInstanceKey; + ULONG BusNumber; + ULONG ControllerNumber; + ULONG DiskNumber; + ULONG Length; + WCHAR Buffer[32]; + BOOLEAN DiskFound; + NTSTATUS Status; + + DPRINT("ScsiDiskSearchForDiskData() called\n"); + + DiskFound = FALSE; + + /* Enumerate buses */ + for (BusNumber = 0; ; BusNumber++) + { + /* Open bus instance subkey */ + swprintf(Buffer, + L"%lu", + BusNumber); + + RtlInitUnicodeString(&NameString, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &NameString, + OBJ_CASE_INSENSITIVE, + BusKey, + NULL); + + Status = ZwOpenKey(&BusInstanceKey, + KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + break; + } + + /* Open 'DiskController' subkey */ + RtlInitUnicodeString(&NameString, + L"DiskController"); + + InitializeObjectAttributes(&ObjectAttributes, + &NameString, + OBJ_CASE_INSENSITIVE, + BusInstanceKey, + NULL); + + Status = ZwOpenKey(&ControllerKey, + KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + ZwClose(BusInstanceKey); + continue; + } + + /* Enumerate controllers */ + for (ControllerNumber = 0; ; ControllerNumber++) + { + /* Open 'DiskPeripheral' subkey */ + swprintf(Buffer, + L"%lu\\DiskPeripheral", + ControllerNumber); + + RtlInitUnicodeString(&NameString, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &NameString, + OBJ_CASE_INSENSITIVE, + ControllerKey, + NULL); + + Status = ZwOpenKey(&DiskKey, + KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + break; + } + + /* Enumerate disks */ + for (DiskNumber = 0; ; DiskNumber++) + { + /* Open disk instance subkey */ + swprintf(Buffer, + L"%lu", + DiskNumber); + + RtlInitUnicodeString(&NameString, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &NameString, + OBJ_CASE_INSENSITIVE, + DiskKey, + NULL); + + Status = ZwOpenKey(&DiskInstanceKey, + KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + break; + } + + DPRINT("Found disk key: bus %lu controller %lu disk %lu\n", + BusNumber, + ControllerNumber, + DiskNumber); + + /* Allocate data buffer */ + ValueData = ExAllocatePool(PagedPool, + 2048); + if (ValueData == NULL) + { + ZwClose(DiskInstanceKey); + continue; + } + + /* Get the 'Identifier' value */ + RtlInitUnicodeString(&NameString, + L"Identifier"); + Status = ZwQueryValueKey(DiskInstanceKey, + &NameString, + KeyValueFullInformation, + ValueData, + 2048, + &Length); + + ZwClose(DiskInstanceKey); + if (!NT_SUCCESS(Status)) + { + ExFreePool(ValueData); + continue; + } + + IdentifierString.Buffer = + (PWSTR)((PUCHAR)ValueData + ValueData->DataOffset); + IdentifierString.Length = (USHORT)ValueData->DataLength - 2; + IdentifierString.MaximumLength = (USHORT)ValueData->DataLength; + + DPRINT("DiskIdentifier: %wZ\n", + &IdentifierString); + + DiskData = (PDISK_DATA)(DeviceExtension + 1); + if (DiskData->Signature != 0) + { + /* Comapre disk signature */ + swprintf(Buffer, + L"%08lx", + DiskData->Signature); + if (!_wcsnicmp(Buffer, &IdentifierString.Buffer[9], 8)) + { + DPRINT("Found disk %lu\n", DiskNumber); + DiskFound = TRUE; + *DetectedDiskNumber = DiskNumber; + } + } + else + { + /* Comapre mbr checksum */ + swprintf(Buffer, + L"%08lx", + DiskData->MbrCheckSum); + if (!_wcsnicmp(Buffer, &IdentifierString.Buffer[0], 8)) + { + DPRINT("Found disk %lu\n", DiskNumber); + DiskFound = TRUE; + *DetectedDiskNumber = DiskNumber; + } + } + + ExFreePool(ValueData); + + ZwClose(DiskInstanceKey); + + if (DiskFound == TRUE) + break; + } + + ZwClose(DiskKey); + } + + ZwClose(ControllerKey); + ZwClose(BusInstanceKey); + } + + DPRINT("ScsiDiskSearchForDisk() done\n"); + + return DiskFound; +} + + +/********************************************************************** + * NAME INTERNAL + * DiskClassUpdateFixedDiskGeometry + * + * DESCRIPTION + * Updated the geometry of a disk if the disk can be accessed + * by the BIOS. + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DeviceExtension + * Disk device extension. + * + * RETURN VALUE + * None + */ + +static VOID +ScsiDiskUpdateFixedDiskGeometry(IN PDEVICE_EXTENSION DeviceExtension) +{ + PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor; + PCM_INT13_DRIVE_PARAMETER DriveParameters; + PKEY_VALUE_FULL_INFORMATION ValueBuffer; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE SystemKey; + HANDLE BusKey; + ULONG DiskNumber; + ULONG Length; + ULONG i; + ULONG Cylinders; + ULONG Sectors; + ULONG SectorsPerTrack; + ULONG TracksPerCylinder; + NTSTATUS Status; + + DPRINT("ScsiDiskUpdateFixedDiskGeometry() called\n"); + + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\Hardware\\Description\\System"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the adapter key */ + Status = ZwOpenKey(&SystemKey, + KEY_READ, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwOpenKey() failed (Status %lx)\n", Status); + return; + } + + /* Allocate value buffer */ + ValueBuffer = ExAllocatePool(PagedPool, + 1024); + if (ValueBuffer == NULL) + { + DPRINT1("Failed to allocate value buffer\n"); + ZwClose(SystemKey); + return; + } + + RtlInitUnicodeString(&ValueName, + L"Configuration Data"); + + /* Query 'Configuration Data' value */ + Status = ZwQueryValueKey(SystemKey, + &ValueName, + KeyValueFullInformation, + ValueBuffer, + 1024, + &Length); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed (Status %lx)\n", Status); + ExFreePool(ValueBuffer); + ZwClose(SystemKey); + return; + } + + /* Open the 'MultifunctionAdapter' subkey */ + RtlInitUnicodeString(&KeyName, + L"MultifunctionAdapter"); + + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + SystemKey, + NULL); + + Status = ZwOpenKey(&BusKey, + KEY_READ, + &ObjectAttributes); + ZwClose(SystemKey); + if (!NT_SUCCESS(Status)) + { + DPRINT("ZwQueryValueKey() failed (Status %lx)\n", Status); + ExFreePool(ValueBuffer); + return; + } + + if (!ScsiDiskSearchForDisk(DeviceExtension, BusKey, &DiskNumber)) + { + DPRINT("ScsiDiskSearchForDisk() failed\n"); + ZwClose(BusKey); + ExFreePool(ValueBuffer); + return; + } + + ZwClose(BusKey); + + ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) + ((PUCHAR)ValueBuffer + ValueBuffer->DataOffset); + + DriveParameters = (PCM_INT13_DRIVE_PARAMETER) + ((PUCHAR)ResourceDescriptor + sizeof(CM_FULL_RESOURCE_DESCRIPTOR)); + +#if 0 + for (i = 0; i< DriveParameters[0].NumberDrives; i++) + { + DPRINT1("Drive %lu: %lu Cylinders %hu Heads %hu Sectors\n", + i, + DriveParameters[i].MaxCylinders, + DriveParameters[i].MaxHeads, + DriveParameters[i].SectorsPerTrack); + } +#endif + + Cylinders = DriveParameters[DiskNumber].MaxCylinders + 1; + TracksPerCylinder = DriveParameters[DiskNumber].MaxHeads +1; + SectorsPerTrack = DriveParameters[DiskNumber].SectorsPerTrack; + + DPRINT("BIOS geometry: %lu Cylinders %hu Heads %hu Sectors\n", + Cylinders, + TracksPerCylinder, + SectorsPerTrack); + + Sectors = (ULONG) + (DeviceExtension->PartitionLength.QuadPart >> DeviceExtension->SectorShift); + + DPRINT("Physical sectors: %lu\n", + Sectors); + + Length = TracksPerCylinder * SectorsPerTrack; + if (Length == 0) + { + DPRINT1("Invalid track length 0\n"); + ExFreePool(ValueBuffer); + return; + } + + Cylinders = Sectors / Length; + + DPRINT("Logical geometry: %lu Cylinders %hu Heads %hu Sectors\n", + Cylinders, + TracksPerCylinder, + SectorsPerTrack); + + /* Update the disk geometry */ + DeviceExtension->DiskGeometry->SectorsPerTrack = SectorsPerTrack; + DeviceExtension->DiskGeometry->TracksPerCylinder = TracksPerCylinder; + DeviceExtension->DiskGeometry->Cylinders.QuadPart = (ULONGLONG)Cylinders; + + if (DeviceExtension->DMActive) + { + DPRINT1("FIXME: Update geometry with respect to the installed disk manager!\n"); + + /* FIXME: Update geometry for disk managers */ + + } + + ExFreePool(ValueBuffer); + + DPRINT("ScsiDiskUpdateFixedDiskGeometry() done\n"); +} + + +/********************************************************************** + * NAME INTERNAL + * ScsiDiskCalcMbrCheckSum + * + * DESCRIPTION + * Calculates the Checksum from drives MBR. + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DeviceExtension + * Disk device extension. + * + * Checksum + * Pointer to the caller supplied cecksum variable. + * + * RETURN VALUE + * TRUE: Checksum was calculated. + * FALSE: Calculation failed. + */ + +static BOOLEAN +ScsiDiskCalcMbrCheckSum(IN PDEVICE_EXTENSION DeviceExtension, + OUT PULONG Checksum) +{ + IO_STATUS_BLOCK IoStatusBlock; + LARGE_INTEGER SectorOffset; + ULONG SectorSize; + PULONG MbrBuffer; + KEVENT Event; + PIRP Irp; + ULONG i; + ULONG Sum; + NTSTATUS Status; + + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); + + /* Get the disk sector size */ + SectorSize = DeviceExtension->DiskGeometry->BytesPerSector; + if (SectorSize < 512) + { + SectorSize = 512; + } + + /* Allocate MBR buffer */ + MbrBuffer = ExAllocatePool(NonPagedPool, + SectorSize); + if (MbrBuffer == NULL) + { + return FALSE; + } + + /* Allocate an IRP */ + SectorOffset.QuadPart = 0ULL; + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, + DeviceExtension->DeviceObject, + MbrBuffer, + SectorSize, + &SectorOffset, + &Event, + &IoStatusBlock); + if (Irp == NULL) + { + ExFreePool(MbrBuffer); + return FALSE; + } + + /* Call the miniport driver */ + Status = IoCallDriver(DeviceExtension->DeviceObject, + Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, + Suspended, + KernelMode, + FALSE, + NULL); + Status = IoStatusBlock.Status; + } + + if (!NT_SUCCESS(Status)) + { + ExFreePool(MbrBuffer); + return FALSE; + } + + /* Calculate MBR checksum */ + Sum = 0; + for (i = 0; i < 128; i++) + { + Sum += MbrBuffer[i]; + } + *Checksum = ~Sum + 1; + + ExFreePool(MbrBuffer); + + return TRUE; +} + /* EOF */ diff --git a/drivers/storage/disk/disk.h b/drivers/storage/disk/disk.h deleted file mode 100644 index eb34864..0000000 --- a/drivers/storage/disk/disk.h +++ /dev/null @@ -1,250 +0,0 @@ -// -// IDE.H - defines and typedefs for the IDE Driver module. -// - -#ifndef __IDE_H -#define __IDE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define IDE_MAXIMUM_DEVICES 8 - -#define IDE_MAX_NAME_LENGTH 50 - -#define IDE_SECTOR_BUF_SZ 512 -#define IDE_MAX_SECTORS_PER_XFER 256 -#define IDE_MAX_RESET_RETRIES 10000 -#define IDE_MAX_POLL_RETRIES 100000 -#define IDE_MAX_WRITE_RETRIES 1000 -#define IDE_MAX_BUSY_RETRIES 100 -//#define IDE_MAX_BUSY_RETRIES 100000 -#define IDE_MAX_DRQ_RETRIES 10000 -//#define IDE_MAX_CMD_RETRIES 1 -#define IDE_MAX_CMD_RETRIES 0 -#define IDE_CMD_TIMEOUT 5 -#define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */ -#define IDE_RESET_BUSY_TIMEOUT 31 -#define IDE_RESET_DRDY_TIMEOUT 120 - -// Control Block offsets and masks -#define IDE_REG_ALT_STATUS 0x0000 -#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */ -#define IDE_DC_SRST 0x04 /* drive reset (both drives) */ -#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */ -#define IDE_REG_DRV_ADDR 0x0001 - -// Command Block offsets and masks -#define IDE_REG_DATA_PORT 0x0000 -#define IDE_REG_ERROR 0x0001 /* error register */ -#define IDE_ER_AMNF 0x01 /* addr mark not found */ -#define IDE_ER_TK0NF 0x02 /* track 0 not found */ -#define IDE_ER_ABRT 0x04 /* command aborted */ -#define IDE_ER_MCR 0x08 /* media change requested */ -#define IDE_ER_IDNF 0x10 /* ID not found */ -#define IDE_ER_MC 0x20 /* Media changed */ -#define IDE_ER_UNC 0x40 /* Uncorrectable data error */ -#define IDE_REG_PRECOMP 0x0001 -#define IDE_REG_SECTOR_CNT 0x0002 -#define IDE_REG_SECTOR_NUM 0x0003 -#define IDE_REG_CYL_LOW 0x0004 -#define IDE_REG_CYL_HIGH 0x0005 -#define IDE_REG_DRV_HEAD 0x0006 -#define IDE_DH_FIXED 0xA0 -#define IDE_DH_LBA 0x40 -#define IDE_DH_HDMASK 0x0F -#define IDE_DH_DRV0 0x00 -#define IDE_DH_DRV1 0x10 -#define IDE_REG_STATUS 0x0007 -#define IDE_SR_BUSY 0x80 -#define IDE_SR_DRDY 0x40 -#define IDE_SR_DRQ 0x08 -#define IDE_SR_ERR 0x01 -#define IDE_REG_COMMAND 0x0007 -#define IDE_CMD_READ 0x20 -#define IDE_CMD_READ_RETRY 0x21 -#define IDE_CMD_WRITE 0x30 -#define IDE_CMD_WRITE_RETRY 0x31 -#define IDE_CMD_IDENT_DRV 0xEC - -// -// Access macros for command registers -// Each macro takes an address of the command port block, and data -// -#define IDEReadError(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR))) -#define IDEWritePrecomp(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data))) -#define IDEReadSectorCount(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT))) -#define IDEWriteSectorCount(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data))) -#define IDEReadSectorNum(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM))) -#define IDEWriteSectorNum(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data))) -#define IDEReadCylinderLow(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW))) -#define IDEWriteCylinderLow(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data))) -#define IDEReadCylinderHigh(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH))) -#define IDEWriteCylinderHigh(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data))) -#define IDEReadDriveHead(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD))) -#define IDEWriteDriveHead(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data))) -#define IDEReadStatus(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS))) -#define IDEWriteCommand(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data))) - - -// -// Data block read and write commands -// -#define IDEReadBlock(Address, Buffer, Count) \ - (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) -#define IDEWriteBlock(Address, Buffer, Count) \ - (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) - -// -// Access macros for control registers -// Each macro takes an address of the control port blank and data -// -#define IDEWriteDriveControl(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data))) - -// IDE_DEVICE_EXTENSION -// -// DESCRIPTION: -// Extension to be placed in each device object -// -// ACCESS: -// Allocated from NON-PAGED POOL -// Available at any IRQL -// - -typedef struct _IDE_DEVICE_EXTENSION { - PDEVICE_OBJECT DeviceObject; - PCONTROLLER_OBJECT ControllerObject; - struct _IDE_DEVICE_EXTESION *DiskExtension; - int UnitNumber; - BOOLEAN LBASupported; - BOOLEAN DMASupported; - int BytesPerSector; - int LogicalHeads; - int SectorsPerLogCyl; - int SectorsPerLogTrk; - int Offset; - int Size; - - int Operation; - ULONG BytesRequested; - ULONG BytesToTransfer; - ULONG BytesRemaining; - ULONG StartingSector; - int SectorsTransferred; - BYTE *TargetAddress; - -} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION; - -// IDE_TIMER_STATES -// -// DESCRIPTION: -// An enumeration containing the states in the timer DFA -// - -typedef enum _IDE_TIMER_STATES { - IDETimerIdle, - IDETimerCmdWait, - IDETimerResetWaitForBusyNegate, - IDETimerResetWaitForDrdyAssert -} IDE_TIMER_STATES; - -// IDE_CONTROLLER_EXTENSION -// -// DESCRIPTION: -// Driver-defined structure used to hold miscellaneous controller information. -// -// ACCESS: -// Allocated from NON-PAGED POOL -// Available at any IRQL -// - -typedef struct _IDE_CONTROLLER_EXTENSION { - KSPIN_LOCK SpinLock; - int Number; - int Vector; - int CommandPortBase; - int ControlPortBase; - BOOLEAN DMASupported; - BOOLEAN ControllerInterruptBug; - PKINTERRUPT Interrupt; - - BOOLEAN OperationInProgress; - BYTE DeviceStatus; - PIDE_DEVICE_EXTENSION DeviceForOperation; - PIRP CurrentIrp; - int Retries; - - IDE_TIMER_STATES TimerState; - LONG TimerCount; - PDEVICE_OBJECT TimerDevice; - -} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION; - -// IDE_DRIVE_IDENTIFY - -typedef struct _IDE_DRIVE_IDENTIFY { - WORD ConfigBits; /*00*/ - WORD LogicalCyls; /*01*/ - WORD Reserved02; /*02*/ - WORD LogicalHeads; /*03*/ - WORD BytesPerTrack; /*04*/ - WORD BytesPerSector; /*05*/ - WORD SectorsPerTrack; /*06*/ - BYTE InterSectorGap; /*07*/ - BYTE InterSectorGapSize; - BYTE Reserved08H; /*08*/ - BYTE BytesInPLO; - WORD VendorUniqueCnt; /*09*/ - char SerialNumber[20]; /*10*/ - WORD ControllerType; /*20*/ - WORD BufferSize; /*21*/ - WORD ECCByteCnt; /*22*/ - char FirmwareRev[8]; /*23*/ - char ModelNumber[40]; /*27*/ - WORD RWMultImplemented; /*47*/ - WORD Reserved48; /*48*/ - WORD Capabilities; /*49*/ -#define IDE_DRID_STBY_SUPPORTED 0x2000 -#define IDE_DRID_IORDY_SUPPORTED 0x0800 -#define IDE_DRID_IORDY_DISABLE 0x0400 -#define IDE_DRID_LBA_SUPPORTED 0x0200 -#define IDE_DRID_DMA_SUPPORTED 0x0100 - WORD Reserved50; /*50*/ - WORD MinPIOTransTime; /*51*/ - WORD MinDMATransTime; /*52*/ - WORD TMFieldsValid; /*53*/ - WORD TMCylinders; /*54*/ - WORD TMHeads; /*55*/ - WORD TMSectorsPerTrk; /*56*/ - WORD TMCapacityLo; /*57*/ - WORD TMCapacityHi; /*58*/ - WORD Reserved59; /*59*/ - WORD TMSectorCountLo; /*60*/ - WORD TMSectorCountHi; /*61*/ - WORD Reserved62[194]; /*62*/ -} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY; - - -#ifdef __cplusplus -} -#endif - -#endif /* __IDE_H */ - - diff --git a/drivers/storage/disk/makefile b/drivers/storage/disk/makefile index 92a8f45..4bb5cae 100644 --- a/drivers/storage/disk/makefile +++ b/drivers/storage/disk/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = driver TARGET_NAME = disk diff --git a/drivers/storage/disk/partitio.h b/drivers/storage/disk/partitio.h deleted file mode 100644 index 06841ee..0000000 --- a/drivers/storage/disk/partitio.h +++ /dev/null @@ -1,41 +0,0 @@ -/** -*** Partition.h - defines and structs for harddrive partition info -*** -*** 05/30/98 RJJ Created -**/ - -#ifndef __PARTITION_H -#define __PARTITION_H - -#define PARTITION_MAGIC 0xaa55 -#define PART_MAGIC_OFFSET 0x01fe -#define PARTITION_OFFSET 0x01be -#define PARTITION_TBL_SIZE 4 -#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \ - (scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2))) -#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \ - (s) = (lba) % (scnt) + 1, \ - (lba) /= (scnt), \ - (h) = (lba) % (hcnt), \ - (lba) /= (heads), \ - (c) = (lba) & 0xff, \ - (s) |= ((lba) >> 2) & 0xc0) - - -typedef struct Partition { - unsigned char BootFlags; - unsigned char StartingHead; - unsigned char StartingSector; - unsigned char StartingCylinder; - unsigned char PartitionType; - unsigned char EndingHead; - unsigned char EndingSector; - unsigned char EndingCylinder; - unsigned int StartingBlock; - unsigned int SectorCount; - -} PARTITION; - -#endif // PARTITION_H - - diff --git a/drivers/storage/scsiport/makefile b/drivers/storage/scsiport/makefile index 1f50c8f..86fcc2e 100644 --- a/drivers/storage/scsiport/makefile +++ b/drivers/storage/scsiport/makefile @@ -2,6 +2,8 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = export_driver TARGET_NAME = scsiport diff --git a/drivers/storage/scsiport/scsiport.c b/drivers/storage/scsiport/scsiport.c index 3592b24..524201c 100644 --- a/drivers/storage/scsiport/scsiport.c +++ b/drivers/storage/scsiport/scsiport.c @@ -634,8 +634,16 @@ ScsiPortLogError(IN PVOID HwDeviceExtension, IN ULONG ErrorCode, IN ULONG UniqueId) { - DPRINT("ScsiPortLogError()\n"); - UNIMPLEMENTED; + PSCSI_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("ScsiPortLogError() called\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + SCSI_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + + DPRINT("ScsiPortLogError() done\n"); } @@ -1727,7 +1735,6 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, /* Set 'Driver' (REG_SZ) value */ DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1; - DPRINT(" Driver = '%S'\n", DriverName); RtlInitUnicodeString(&ValueName, L"Driver"); Status = ZwSetValueKey(ScsiPortKey, @@ -1735,7 +1742,7 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 0, REG_SZ, DriverName, - wcslen(DriverName) * sizeof(WCHAR)); + (wcslen(DriverName) + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status); @@ -1939,7 +1946,7 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 0, REG_SZ, NameBuffer, - wcslen(NameBuffer) * sizeof(WCHAR)); + (wcslen(NameBuffer) + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status); @@ -1992,7 +1999,7 @@ ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 0, REG_SZ, TypeName, - wcslen(TypeName) * sizeof(WCHAR)); + (wcslen(TypeName) + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status); diff --git a/hal/halx86/Makefile b/hal/halx86/Makefile index edd134c..3c9001c 100644 --- a/hal/halx86/Makefile +++ b/hal/halx86/Makefile @@ -14,6 +14,8 @@ include $(PATH_TO_TOP)/rules.mak # include $(TOOLS_PATH)/config.mk +TARGET_BOOTSTRAP = yes + TARGET_TYPE = hal TARGET_BASENAME = hal @@ -40,7 +42,6 @@ endif HAL_OBJECTS = \ adapter.o \ beep.o \ - bios32.o \ bus.o \ display.o \ dma.o \ @@ -50,7 +51,6 @@ HAL_OBJECTS = \ halinit.o \ isa.o \ kdbg.o \ - mbr.o \ mca.o \ misc.o \ mp.o \ diff --git a/hal/halx86/bios32.c b/hal/halx86/bios32.c deleted file mode 100644 index 4668367..0000000 --- a/hal/halx86/bios32.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/pci - * PURPOSE: Interfaces to BIOS32 interface - * PROGRAMMER: David Welch (welch@mcmail.com) - * UPDATE HISTORY: - * 05/06/98: Created - */ - -/* - * NOTES: Sections copied from the Linux pci support - */ - -/* INCLUDES ***************************************************************/ - -#include -#include -#include - - -/* TYPES ******************************************************************/ - -typedef struct -{ - /* - * "_32_" if present - */ - unsigned int signature; - - /* - * Entry point (physical address) - */ - unsigned long int entry; - - /* - * Revision level - */ - unsigned char revision; - - /* - * Length in paragraphs - */ - unsigned char length; - - /* - * Checksum (so all bytes add up to zero) - */ - unsigned char checksum; - - unsigned char reserved[5]; -} bios32; - -BOOLEAN bios32_detected = FALSE; - -static struct -{ - unsigned long address; - unsigned short segment; -} bios32_indirect = {0,KERNEL_CS}; - -/* FUNCTIONS **************************************************************/ - -#define BIOS32_SIGNATURE (('_' << 0)+('3'<<8)+('2'<<16)+('_'<<24)) - -#if 0 -BOOL static checksum(bios32* service_entry) -/* - * FUNCTION: Checks the checksum of a bios32 service entry - * ARGUMENTS: - * service_entry = Pointer to the service entry - * RETURNS: True if the sum of the bytes in the entry was zero - * False otherwise - */ -{ - unsigned char* p = (unsigned char *)service_entry; - int i; - unsigned char sum=0; - - for (i=0; i<(service_entry->length*16); i++) - { - sum=sum+p[i]; - } -// DbgPrint("sum = %d\n",sum); - if (sum==0) - { - return(TRUE); - } - return(FALSE); -} -#endif - -BOOLEAN Hal_bios32_is_service_present(ULONG service) -{ - unsigned char return_code; - unsigned int address; - unsigned int length; - unsigned int entry; - - __asm__("lcall *(%%edi)" - : "=a" (return_code), - "=b" (address), - "=c" (length), - "=d" (entry) - : "0" (service), - "1" (0), - "D" (&bios32_indirect)); - if (return_code==0) - { - return(address+entry); - } - return(0); -} - -VOID Hal_bios32_probe() -/* - * FUNCTION: Probes for an BIOS32 extension - * RETURNS: True if detected - */ -{ - DbgPrint ("Hal_bios32_probe()\n"); - - return; -#if 0 - int i; - - for (i=0xe0000;i<=0xffff0;i++) - { - bios32* service_entry = (bios32 *)physical_to_linear(i); - if ( service_entry->signature != BIOS32_SIGNATURE ) - { - continue; - } - DbgPrint("Signature detected at %x\n",i); - if (!checksum(service_entry)) - { - continue; - } - DbgPrint("ReactOS: BIOS32 detected at %x\n",i); - bios32_indirect.address = service_entry->entry; - bios32_detected=TRUE; - } -#endif -} diff --git a/hal/halx86/bus.c b/hal/halx86/bus.c index 8c2dec6..8c14722 100644 --- a/hal/halx86/bus.c +++ b/hal/halx86/bus.c @@ -16,7 +16,7 @@ /* INCLUDES *****************************************************************/ #include -#include +#include #include #define NDEBUG @@ -40,6 +40,7 @@ HalpNoAdjustResourceList(PBUS_HANDLER BusHandler, return STATUS_UNSUCCESSFUL; } + static NTSTATUS STDCALL HalpNoAssignSlotResources(PBUS_HANDLER BusHandler, ULONG BusNumber, @@ -53,6 +54,7 @@ HalpNoAssignSlotResources(PBUS_HANDLER BusHandler, return STATUS_NOT_SUPPORTED; } + static ULONG STDCALL HalpNoBusData(PBUS_HANDLER BusHandler, ULONG BusNumber, @@ -64,6 +66,7 @@ HalpNoBusData(PBUS_HANDLER BusHandler, return 0; } + static ULONG STDCALL HalpNoGetInterruptVector(PBUS_HANDLER BusHandler, ULONG BusNumber, @@ -75,6 +78,7 @@ HalpNoGetInterruptVector(PBUS_HANDLER BusHandler, return 0; } + static ULONG STDCALL HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler, ULONG BusNumber, @@ -130,58 +134,59 @@ HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType, VOID HalpInitBusHandlers(VOID) { - PBUS_HANDLER BusHandler; + PBUS_HANDLER BusHandler; - /* general preparations */ - KeInitializeSpinLock(&HalpBusHandlerSpinLock); - InitializeListHead(&HalpBusHandlerList); + /* General preparations */ + KeInitializeSpinLock(&HalpBusHandlerSpinLock); + InitializeListHead(&HalpBusHandlerList); - /* initialize hal dispatch tables */ -#if 0 + /* Initialize hal dispatch tables */ + HalQuerySystemInformation = HalpQuerySystemInformation; +#if 0 + HalSetSystemInformation = HalpSetSystemInformation; - HalDispatchTable->HalQueryBusSlots = HaliQueryBusSlots; + HalQueryBusSlots = HalpQueryBusSlots; #endif - /* add system bus handler */ - BusHandler = HalpAllocateBusHandler(Internal, - ConfigurationSpaceUndefined, - 0); - if (BusHandler == NULL) - return; - BusHandler->GetInterruptVector = - (pGetInterruptVector)HalpGetSystemInterruptVector; - BusHandler->TranslateBusAddress = - (pTranslateBusAddress)HalpTranslateSystemBusAddress; - - /* add cmos bus handler */ - BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined, - Cmos, - 0); - if (BusHandler == NULL) - return; - BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData; - BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData; - - /* add isa bus handler */ - BusHandler = HalpAllocateBusHandler(Isa, - ConfigurationSpaceUndefined, - 0); - if (BusHandler == NULL) - return; - - BusHandler->GetInterruptVector = - (pGetInterruptVector)HalpGetIsaInterruptVector; - BusHandler->TranslateBusAddress = - (pTranslateBusAddress)HalpTranslateIsaBusAddress; + /* Add system bus handler */ + BusHandler = HalpAllocateBusHandler(Internal, + ConfigurationSpaceUndefined, + 0); + if (BusHandler == NULL) + return; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetSystemInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslateSystemBusAddress; + + /* Add cmos bus handler */ + BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined, + Cmos, + 0); + if (BusHandler == NULL) + return; + BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData; + BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData; + + /* Add isa bus handler */ + BusHandler = HalpAllocateBusHandler(Isa, + ConfigurationSpaceUndefined, + 0); + if (BusHandler == NULL) + return; + BusHandler->GetInterruptVector = + (pGetInterruptVector)HalpGetIsaInterruptVector; + BusHandler->TranslateBusAddress = + (pTranslateBusAddress)HalpTranslateIsaBusAddress; - /* add MicroChannel bus handler */ + /* Add MicroChannel bus handler */ BusHandler = HalpAllocateBusHandler(MicroChannel, Pos, 0); - if (BusHandler == NULL) - return; + if (BusHandler == NULL) + return; BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData; } diff --git a/hal/halx86/drive.c b/hal/halx86/drive.c index cc04fbe..8b24779 100644 --- a/hal/halx86/drive.c +++ b/hal/halx86/drive.c @@ -22,10 +22,10 @@ IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock, OUT PUCHAR NtSystemPath, OUT PSTRING NtSystemPathString) { - HalDispatchTable.HalIoAssignDriveLetters(LoaderBlock, - NtDeviceName, - NtSystemPath, - NtSystemPathString); + HalIoAssignDriveLetters(LoaderBlock, + NtDeviceName, + NtSystemPath, + NtSystemPathString); } /* EOF */ diff --git a/hal/halx86/halinit.c b/hal/halx86/halinit.c index 287aa2f..5830314 100644 --- a/hal/halx86/halinit.c +++ b/hal/halx86/halinit.c @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef MP #include @@ -58,8 +57,8 @@ HalInitSystem (ULONG BootPhase, } else if (BootPhase == 1) { - HalpInitBusHandlers (); - HalpCalibrateStallExecution (); + HalpInitBusHandlers(); + HalpCalibrateStallExecution(); /* Enumerate the devices on the motherboard */ HalpStartEnumerator(); diff --git a/hal/halx86/include/hal.h b/hal/halx86/include/hal.h index 704c2b3..87939c1 100644 --- a/hal/halx86/include/hal.h +++ b/hal/halx86/include/hal.h @@ -45,4 +45,12 @@ struct _ADAPTER_OBJECT { BOOLEAN Inuse; }; +/* sysinfo.c */ +NTSTATUS STDCALL +HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength); + + #endif /* __INTERNAL_HAL_HAL_H */ diff --git a/hal/halx86/include/mps.h b/hal/halx86/include/mps.h index 6fc8e47..0311bca 100644 --- a/hal/halx86/include/mps.h +++ b/hal/halx86/include/mps.h @@ -1,6 +1,16 @@ #ifndef __INCLUDE_HAL_MPS #define __INCLUDE_HAL_MPS +/* + * FIXME: This does not work if we have more than 24 IRQs (ie. more than one + * I/O APIC) + */ +#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8) +#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR) +#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector)) +#define IRQL2VECTOR(irql) (IRQ2VECTOR(irql - DISPATCH_LEVEL /* 2 */ - 1)) + + #define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */ #define IOAPIC_DEFAULT_BASE 0xFEC00000 /* Default I/O APIC Base Register Address */ diff --git a/hal/halx86/isa.c b/hal/halx86/isa.c index d97e342..12449f6 100644 --- a/hal/halx86/isa.c +++ b/hal/halx86/isa.c @@ -11,8 +11,12 @@ /* INCLUDES ***************************************************************/ +#include #include #include +#ifdef MP +#include +#endif /* FUNCTIONS *****************************************************************/ @@ -67,8 +71,14 @@ HalpGetIsaInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; +#endif } /* EOF */ diff --git a/hal/halx86/mbr.c b/hal/halx86/mbr.c deleted file mode 100644 index 5dc30a9..0000000 --- a/hal/halx86/mbr.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/x86/mbr.c - * PURPOSE: Functions for reading the master boot record (MBR) - * PROGRAMMER: David Welch (welch@cwcom.net) - * UPDATE HISTORY: - * Created 22/05/98 - */ - -/* INCLUDES *****************************************************************/ - -#include - -#include - -/* FUNCTIONS *****************************************************************/ - -VOID HalExamineMBR(PDEVICE_OBJECT DeviceObject, - ULONG SectorSize, - ULONG MBRTypeIdentifier, - PVOID Buffer) -{ - UNIMPLEMENTED; -} diff --git a/hal/halx86/mp.c b/hal/halx86/mp.c index 01e026e..b1941d4 100644 --- a/hal/halx86/mp.c +++ b/hal/halx86/mp.c @@ -82,7 +82,8 @@ extern VOID MpsSpuriousInterrupt(VOID); WRITE_PORT_UCHAR((PUCHAR)0x71, value); \ }) -BOOLEAN MPSInitialized = FALSE; /* Is the MP system initialized? */ +static BOOLEAN MPSInitialized = FALSE; /* Is the MP system initialized? */ +static KDPC RescheduleDpc; VOID APICDisable(VOID); static VOID APICSyncArbIDs(VOID); @@ -96,8 +97,7 @@ ULONG lastvalw = 0; #endif /* MP */ -BOOLEAN BSPInitialized = FALSE; /* Is the BSP initialized? */ - +static BOOLEAN BSPInitialized = FALSE; /* Is the BSP initialized? */ /* FUNCTIONS *****************************************************************/ @@ -148,12 +148,10 @@ volatile ULONG IOAPICRead( PULONG Base; Base = (PULONG)IOAPICMap[Apic].ApicAddress; - - *Base = Offset; - return *((PULONG)((ULONG)Base + IOAPIC_IOWIN)); + *Base = Offset; + return *((PULONG)((ULONG)Base + IOAPIC_IOWIN)); } - VOID IOAPICWrite( ULONG Apic, ULONG Offset, @@ -162,9 +160,8 @@ VOID IOAPICWrite( PULONG Base; Base = (PULONG)IOAPICMap[Apic].ApicAddress; - *Base = Offset; - *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value; + *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value; } @@ -179,6 +176,7 @@ VOID IOAPICClearPin( */ memset(&Entry, 0, sizeof(Entry)); Entry.mask = 1; + IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0)); IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1)); } @@ -210,6 +208,7 @@ VOID IOAPICMaskIrq( *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq); Entry.mask = 1; + IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry)); } @@ -223,6 +222,7 @@ VOID IOAPICUnmaskIrq( *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq); Entry.mask = 0; + IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry)); } @@ -268,7 +268,7 @@ IOAPICSetupIds(VOID) tmp &= ~IOAPIC_ID_MASK; tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId); - + IOAPICWrite(apic, IOAPIC_ID, tmp); /* @@ -582,25 +582,26 @@ static ULONG IOAPICGetIrqEntry( static ULONG AssignIrqVector( ULONG irq) { - static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0; + static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0; ULONG vector; /* There may already have been assigned a vector for this IRQ */ vector = IRQVectorMap[irq]; - if (vector > 0) - return vector; + if (vector > 0) + return vector; - current_vector += 8; if (current_vector > FIRST_SYSTEM_VECTOR) { - vector_offset++; + vector_offset++; current_vector = FIRST_DEVICE_VECTOR + vector_offset; } else if (current_vector == FIRST_SYSTEM_VECTOR) { DPRINT1("Ran out of interrupt sources!"); KeBugCheck(0); } - IRQVectorMap[irq] = current_vector; - return current_vector; + vector = current_vector; + IRQVectorMap[irq] = vector; + current_vector += 8; + return vector; } @@ -651,6 +652,8 @@ VOID IOAPICSetupIrqs( vector = AssignIrqVector(irq); entry.vector = vector; + DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq); + if (irq == 0) { /* Mask timer IRQ */ @@ -1167,7 +1170,6 @@ VOID WaitFor8254Wraparound(VOID) LONG Delta; CurCount = Read8254Timer(); - do { PrevCount = CurCount; CurCount = Read8254Timer(); @@ -1235,8 +1237,8 @@ VOID APICCalibrateTimer( /* Setup timer for normal operation */ //APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns - APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 15000); // 15ms - //APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms +// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 15000); // 15ms + APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms DPRINT("CPU clock speed is %ld.%04ld MHz.\n", CPUMap[CPU].CoreSpeed/1000000, @@ -1374,37 +1376,52 @@ VOID MpsTimerHandler( { #if 0 KIRQL OldIrql; -#endif - DPRINT("T1"); + DPRINT("T:\n"); /* - * Acknowledge the interrupt + * Notify the rest of the kernel of the raised irq level */ - APICSendEOI(); -#if 0 + //OldIrql = KeRaiseIrqlToSynchLevel(); + KeRaiseIrql(PROFILE_LEVEL, &OldIrql); + /* - * Notify the rest of the kernel of the raised irq level + * Enable interrupts + * NOTE: Only higher priority interrupts will get through */ - OldIrql = KeRaiseIrqlToSynchLevel(); -#endif __asm__("sti\n\t"); + if (KeGetCurrentProcessorNumber() == 0) + { + //KIRQL OldIrql2; + //KeLowerIrql(PROFILE_LEVEL); + KiInterruptDispatch2(OldIrql, 0); + //KeRaiseIrql(CLOCK2_LEVEL, &OldIrql2); + } + + DbgPrint("MpsTimerHandler() called at IRQL 0x%.08x\n", OldIrql); + //(BOOLEAN) KeInsertQueueDpc(&RescheduleDpc, NULL, NULL); + + DbgPrint("MpsTimerHandler() -1 IRQL 0x%.08x\n", OldIrql); + /* - * Call the dispatcher + * Disable interrupts */ - // TODO FIXME - What happened to definition for PsDispatchThread ??? - //PsDispatchThread(THREAD_STATE_READY); + __asm__("cli\n\t"); - // KeGetCurrentThread is linked into hal from ntoskrnl, so can - // PsDispatchThread be exported from ntoskrnl also ??? + DbgPrint("MpsTimerHandler() 0 IRQL 0x%.08x\n", OldIrql); + /* + * Acknowledge the interrupt + */ + APICSendEOI(); -#if 0 /* * Lower irq level */ + DbgPrint("MpsTimerHandler() 1 IRQL 0x%.08x\n", OldIrql); KeLowerIrql(OldIrql); + DbgPrint("MpsTimerHandler() 2 IRQL 0x%.08x\n", OldIrql); #endif } @@ -1445,10 +1462,8 @@ VOID MpsSpuriousHandler( { DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU()); - /* - * Acknowledge the interrupt - */ - APICSendEOI(); + /* No need to send EOI here */ + APICDump(); for (;;); } @@ -1494,7 +1509,7 @@ VOID APICSetup( APICWrite(APIC_SIVR, tmp); /* - * Only the BP should see the LINT1 NMI signal, obviously. + * Only the BSP should see the LINT1 NMI signal, obviously. */ if (CPU == 0) tmp = APIC_DM_NMI; @@ -1744,7 +1759,8 @@ HalAllProcessorsStarted ( #ifdef MP - return (NextCPU >= CPUCount); + //return (NextCPU >= CPUCount); + return (NextCPU >= 1); #else /* MP */ @@ -2214,6 +2230,7 @@ static VOID HaliConstructDefaultISAMPTable( } } + BOOLEAN HaliScanForMPConfigTable( ULONG Base, @@ -2301,6 +2318,22 @@ HaliScanForMPConfigTable( } +static VOID STDCALL +RescheduleDpcRoutine(PKDPC Dpc, PVOID DeferredContext, + PVOID SystemArgument1, PVOID SystemArgument2) +{ + KIRQL OldIrql; + KIRQL NewIrql; + + DbgPrint("RDR()"); + NewIrql = KeGetCurrentIrql(); + KeLowerIrql(APC_LEVEL); + KeRescheduleThread(); + KeRaiseIrql(NewIrql, &OldIrql); + DbgPrint("...\n"); +} + + VOID HalpInitMPS( VOID) @@ -2328,6 +2361,8 @@ HalpInitMPS( MPSInitialized = TRUE; + KeInitializeDpc(&RescheduleDpc, RescheduleDpcRoutine, NULL); + /* Scan the system memory for an MP configuration table 1) Scan the first KB of system base memory @@ -2350,7 +2385,7 @@ HalpInitMPS( } /* Setup IRQ to vector translation map */ - memset(&IRQVectorMap, sizeof(IRQVectorMap), 0); + memset(&IRQVectorMap, 0, sizeof(IRQVectorMap)); /* Initialize the bootstrap processor */ HaliInitBSP(); diff --git a/hal/halx86/mpsirql.c b/hal/halx86/mpsirql.c index fbb47d7..b1c0780 100644 --- a/hal/halx86/mpsirql.c +++ b/hal/halx86/mpsirql.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #define NDEBUG @@ -21,117 +22,131 @@ /* GLOBALS ******************************************************************/; +#define IRQ_BASE (0x30) +#define NR_VECTORS (0x100 - IRQ_BASE) + extern IMPORTED ULONG DpcQueueSize; -static VOID KeSetCurrentIrql(KIRQL newlvl); +static ULONG HalpPendingInterruptCount[NR_VECTORS]; -/* FUNCTIONS ****************************************************************/ +static VOID KeSetCurrentIrql (KIRQL newlvl); -#define IRQL2TPR(irql) (APIC_TPR_MIN + ((irql - DISPATCH_LEVEL - 1) * 8)) +VOID STDCALL +KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); -static VOID HiSetCurrentPriority( - ULONG Priority) -{ - //DbgPrint(" P(0x%X)\n", Priority); - APICWrite(APIC_TPR, Priority & APIC_TPR_PRI); -} +#define IRQL2TPR(irql) (FIRST_DEVICE_VECTOR + ((irql - DISPATCH_LEVEL /* 2 */ - 1) * 8)) +/* FUNCTIONS ****************************************************************/ -static VOID HiSwitchIrql(KIRQL OldIrql, ULONG Flags) +KIRQL STDCALL KeGetCurrentIrql (VOID) /* - * FUNCTION: Switches to the current irql - * NOTE: Must be called with interrupt disabled + * PURPOSE: Returns the current irq level + * RETURNS: The current irq level */ { - PKTHREAD CurrentThread; - KIRQL CurrentIrql; - - //DbgPrint("HiSwitchIrql(OldIrql %d)\n", OldIrql); - - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (CurrentIrql >= IPI_LEVEL) - { - /* Block all interrupts */ - HiSetCurrentPriority(APIC_TPR_MAX); - return; - } - - if (CurrentIrql == CLOCK2_LEVEL) - { - HiSetCurrentPriority(APIC_TPR_MAX - 16); - popfl(Flags); - return; - } - - if (CurrentIrql > DISPATCH_LEVEL) - { - HiSetCurrentPriority(IRQL2TPR(CurrentIrql)); - popfl(Flags); - return; - } - - /* Pass all interrupts */ - HiSetCurrentPriority(0); - - if (CurrentIrql == DISPATCH_LEVEL) - { - popfl(Flags); - return; - } - - if (CurrentIrql == APC_LEVEL) - { - if (DpcQueueSize > 0 ) - { - KeSetCurrentIrql(DISPATCH_LEVEL); - __asm__("sti\n\t"); - KiDispatchInterrupt(); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - } - popfl(Flags); - return; - } - - CurrentThread = KeGetCurrentThread(); - - if (CurrentIrql == PASSIVE_LEVEL && - CurrentThread != NULL && - CurrentThread->ApcState.KernelApcPending) - { - KeSetCurrentIrql(APC_LEVEL); - __asm__("sti\n\t"); - KiDeliverApc(0, 0, 0); - __asm__("cli\n\t"); - KeSetCurrentIrql(PASSIVE_LEVEL); - popfl(Flags); - } - else - { - popfl(Flags); - } + if (KeGetCurrentKPCR ()->Irql > HIGH_LEVEL) + { + DPRINT1 ("CurrentIrql %x\n", KeGetCurrentKPCR ()->Irql); + KeBugCheck (0); + for(;;); + } + + return(KeGetCurrentKPCR ()->Irql); } -KIRQL STDCALL KeGetCurrentIrql (VOID) +static VOID KeSetCurrentIrql (KIRQL NewIrql) /* - * PURPOSE: Returns the current irq level - * RETURNS: The current irq level + * PURPOSE: Sets the current irq level without taking any action */ { - return(KeGetCurrentKPCR()->Irql); + if (NewIrql > HIGH_LEVEL) + { + DPRINT1 ("NewIrql %x\n", NewIrql); + KeBugCheck (0); + for(;;); + } + + KeGetCurrentKPCR ()->Irql = NewIrql; } -static VOID KeSetCurrentIrql(KIRQL newlvl) +VOID HalpEndSystemInterrupt (KIRQL Irql) /* - * PURPOSE: Sets the current irq level without taking any action + * FUNCTION: Enable all irqs with higher priority. */ { -// DPRINT("KeSetCurrentIrql(newlvl %x)\n",newlvl); + /* Interrupts should be disabled while enabling irqs */ + __asm__("pushf\n\t"); + __asm__("cli\n\t"); + APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI); + __asm__("popf\n\t"); +} + + +VOID STATIC +HalpExecuteIrqs(KIRQL NewIrql) +{ + ULONG VectorLimit, i; + + VectorLimit = min(IRQL2VECTOR (NewIrql), NR_VECTORS); + + /* + * For each vector if there have been any deferred interrupts then now + * dispatch them. + */ + for (i = 0; i < VectorLimit; i++) + { + if (HalpPendingInterruptCount[i] > 0) + { + KeSetCurrentIrql (VECTOR2IRQL (i)); + + while (HalpPendingInterruptCount[i] > 0) + { + /* + * For each deferred interrupt execute all the handlers at DIRQL. + */ + KiInterruptDispatch2 (i, NewIrql); + HalpPendingInterruptCount[i]--; + } + KeSetCurrentIrql (KeGetCurrentIrql () - 1); + HalpEndSystemInterrupt (KeGetCurrentIrql ()); + } + } + +} - KeGetCurrentKPCR()->Irql = newlvl; + +VOID STATIC +HalpLowerIrql(KIRQL NewIrql) +{ + if (NewIrql >= PROFILE_LEVEL) + { + KeSetCurrentIrql (NewIrql); + return; + } + HalpExecuteIrqs (NewIrql); + if (NewIrql >= DISPATCH_LEVEL) + { + KeSetCurrentIrql (NewIrql); + return; + } + KeSetCurrentIrql (DISPATCH_LEVEL); + if (DpcQueueSize > 0) + { + KiDispatchInterrupt (); + } + KeSetCurrentIrql (APC_LEVEL); + if (NewIrql == APC_LEVEL) + { + return; + } + if (KeGetCurrentThread () != NULL && + KeGetCurrentThread ()->ApcState.KernelApcPending) + { + KiDeliverApc (0, 0, 0); + } + KeSetCurrentIrql (PASSIVE_LEVEL); } @@ -151,34 +166,19 @@ static VOID KeSetCurrentIrql(KIRQL newlvl) * NOTES * Uses fastcall convention */ - VOID FASTCALL -KfLowerIrql ( - KIRQL NewIrql - ) +KfLowerIrql (KIRQL NewIrql) { - KIRQL CurrentIrql; KIRQL OldIrql; - ULONG Flags; - - //DbgPrint("KfLowerIrql(NewIrql %d)\n", NewIrql); - - pushfl(Flags); - __asm__ ("\n\tcli\n\t"); - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (NewIrql > CurrentIrql) + if (NewIrql > KeGetCurrentIrql ()) { - DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n", - __FILE__, __LINE__, NewIrql, CurrentIrql); - KeBugCheck(0); + DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, KeGetCurrentIrql ()); + KeBugCheck (0); for(;;); } - OldIrql = CurrentIrql; - KeGetCurrentKPCR()->Irql = NewIrql; - HiSwitchIrql(OldIrql, Flags); + HalpLowerIrql (NewIrql); } @@ -198,13 +198,10 @@ KfLowerIrql ( * NOTES */ -VOID -STDCALL -KeLowerIrql ( - KIRQL NewIrql - ) +VOID STDCALL +KeLowerIrql (KIRQL NewIrql) { - KfLowerIrql (NewIrql); + KfLowerIrql (NewIrql); } @@ -225,37 +222,21 @@ KeLowerIrql ( * Uses fastcall convention */ -KIRQL -FASTCALL -KfRaiseIrql ( - KIRQL NewIrql - ) +KIRQL FASTCALL +KfRaiseIrql (KIRQL NewIrql) { - KIRQL CurrentIrql; KIRQL OldIrql; - ULONG Flags; - - //DbgPrint("KfRaiseIrql(NewIrql %d)\n", NewIrql); - - pushfl(Flags); - __asm__ ("\n\tcli\n\t"); - - CurrentIrql = KeGetCurrentKPCR()->Irql; - - if (NewIrql < CurrentIrql) - { - DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n", - __FILE__,__LINE__,CurrentIrql,NewIrql); - KeBugCheck (0); - for(;;); - } - - OldIrql = CurrentIrql; - KeGetCurrentKPCR()->Irql = NewIrql; - - //DPRINT("NewIrql %x OldIrql %x\n", NewIrql, OldIrql); - HiSwitchIrql(OldIrql, Flags); - return OldIrql; + + if (NewIrql < KeGetCurrentIrql ()) + { + DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql); + KeBugCheck (0); + for(;;); + } + + OldIrql = KeGetCurrentIrql (); + KeSetCurrentIrql (NewIrql); + return OldIrql; } @@ -276,15 +257,11 @@ KfRaiseIrql ( * NOTES * Calls KfRaiseIrql */ - -VOID -STDCALL -KeRaiseIrql ( - KIRQL NewIrql, - PKIRQL OldIrql - ) +VOID STDCALL +KeRaiseIrql (KIRQL NewIrql, + PKIRQL OldIrql) { - *OldIrql = KfRaiseIrql (NewIrql); + *OldIrql = KfRaiseIrql (NewIrql); } @@ -305,11 +282,10 @@ KeRaiseIrql ( * Calls KfRaiseIrql */ -KIRQL -STDCALL +KIRQL STDCALL KeRaiseIrqlToDpcLevel (VOID) { - return KfRaiseIrql (DISPATCH_LEVEL); + return KfRaiseIrql (DISPATCH_LEVEL); } @@ -330,88 +306,91 @@ KeRaiseIrqlToDpcLevel (VOID) * Calls KfRaiseIrql */ -KIRQL -STDCALL +KIRQL STDCALL KeRaiseIrqlToSynchLevel (VOID) { - return KfRaiseIrql (CLOCK2_LEVEL); + return KfRaiseIrql (CLOCK2_LEVEL); } -BOOLEAN STDCALL HalBeginSystemInterrupt (ULONG Vector, - KIRQL Irql, - PKIRQL OldIrql) +BOOLEAN STDCALL +HalBeginSystemInterrupt (ULONG Vector, + KIRQL Irql, + PKIRQL OldIrql) { - DPRINT("Vector (0x%X) Irql (0x%X)\n", - Vector, Irql); + DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql); if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT("Not a device interrupt\n"); return FALSE; } - /* - * Acknowledge the interrupt - */ - APICSendEOI(); + HalDisableSystemInterrupt (Vector, 0); - *OldIrql = KeGetCurrentIrql(); + APICSendEOI(); - KeSetCurrentIrql(Irql); + if (KeGetCurrentIrql () >= Irql) + { + HalpPendingInterruptCount[Vector]++; + return(FALSE); + } + *OldIrql = KeGetCurrentIrql (); + KeSetCurrentIrql (Irql); - return TRUE; + return(TRUE); } -VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, - ULONG Unknown2) +VOID STDCALL +HalEndSystemInterrupt (KIRQL Irql, + ULONG Unknown2) +/* + * FUNCTION: Finish a system interrupt and restore the specified irq level. + */ { - KeSetCurrentIrql(Irql); + HalpLowerIrql (Irql); + HalpEndSystemInterrupt (Irql); } - - -BOOLEAN STDCALL HalDisableSystemInterrupt (ULONG Vector, - ULONG Unknown2) + +BOOLEAN STDCALL +HalDisableSystemInterrupt (ULONG Vector, + ULONG Unknown2) { ULONG irq; - DPRINT("Vector (0x%X)\n", Vector); + DPRINT ("Vector (0x%X)\n", Vector); if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT("Not a device interrupt\n"); return FALSE; } - // TODO FIXME - What happened to definition for VECTOR2IRQ ??? - //irq = VECTOR2IRQ(Vector); - IOAPICMaskIrq(0, irq); + irq = VECTOR2IRQ (Vector); + IOAPICMaskIrq (ThisCPU (), irq); - return TRUE; + return TRUE; } -BOOLEAN STDCALL HalEnableSystemInterrupt (ULONG Vector, - ULONG Unknown2, - ULONG Unknown3) +BOOLEAN STDCALL +HalEnableSystemInterrupt (ULONG Vector, + ULONG Unknown2, + ULONG Unknown3) { ULONG irq; - DPRINT("Vector (0x%X)\n", Vector); + DPRINT ("Vector (0x%X)\n", Vector); if (Vector < FIRST_DEVICE_VECTOR || - Vector > FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { + Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT("Not a device interrupt\n"); return FALSE; } - // TODO FIXME - What happened to definition for VECTOR2IRQ ??? - //irq = VECTOR2IRQ(Vector); - - IOAPICUnmaskIrq(0, irq); + irq = VECTOR2IRQ (Vector); + IOAPICUnmaskIrq (ThisCPU (), irq); return TRUE; } - -/* EOF */ diff --git a/hal/halx86/pci.c b/hal/halx86/pci.c index b5493c5..820ecbb 100644 --- a/hal/halx86/pci.c +++ b/hal/halx86/pci.c @@ -18,8 +18,13 @@ /* INCLUDES *****************************************************************/ +#include #include #include +#ifdef MP +#include +#endif + #define NDEBUG #include @@ -27,6 +32,9 @@ /* MACROS ******************************************************************/ +/* FIXME These are also defined in drivers/bus/pci/pcidef.h. + Maybe put PCI definitions in a central include file??? */ + /* access type 1 macros */ #define CONFIG_CMD(bus, dev_fn, where) \ (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3)) @@ -37,9 +45,23 @@ #define FUNC(dev_fn) \ ((((dev_fn) & 0xE0) >> 4) | 0xf0) +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +/* bit 1 is reserved if address_space = 1 */ + /* GLOBALS ******************************************************************/ +#define TAG_PCI TAG('P', 'C', 'I', 'H') + static ULONG BusConfigType = 0; /* undetermined config type */ static KSPIN_LOCK PciLock; @@ -93,7 +115,7 @@ ReadPciConfigUshort(UCHAR Bus, case 1: KeAcquireSpinLock(&PciLock, &oldIrql); WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1)); + *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2)); KeReleaseSpinLock(&PciLock, oldIrql); return STATUS_SUCCESS; @@ -193,7 +215,7 @@ WritePciConfigUshort(UCHAR Bus, case 1: KeAcquireSpinLock(&PciLock, &oldIrql); WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset)); - WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1), Value); + WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value); KeReleaseSpinLock(&PciLock, oldIrql); return STATUS_SUCCESS; @@ -529,9 +551,15 @@ HalpGetPciInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else *Irql = PROFILE_LEVEL - BusInterruptVector; *Affinity = 0xFFFFFFFF; return BusInterruptVector; +#endif } static BOOLEAN STDCALL @@ -562,6 +590,134 @@ HalpTranslatePciAddress(PBUS_HANDLER BusHandler, return TRUE; } +/* + * Find the extent of a PCI decode.. + */ +static ULONG STDCALL +PciSize(ULONG Base, ULONG Mask) +{ + ULONG Size = Mask & Base; /* Find the significant bits */ + Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */ + return Size; +} + +static NTSTATUS STDCALL +HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler, + IN ULONG BusNumber, + IN PUNICODE_STRING RegistryPath, + IN PUNICODE_STRING DriverClassName, + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT DeviceObject, + IN ULONG SlotNumber, + IN OUT PCM_RESOURCE_LIST *AllocatedResources) +{ + UINT Address; + UINT NoAddresses; + ULONG BaseAddresses[PCI_TYPE0_ADDRESSES]; + ULONG Size[PCI_TYPE0_ADDRESSES]; + NTSTATUS Status = STATUS_SUCCESS; + UCHAR Offset; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + + /* FIXME: Should handle 64-bit addresses */ + + /* Read the PCI configuration space for the device and store base address and + size information in temporary storage. Count the number of valid base addresses */ + NoAddresses = 0; + for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++) + { + Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]); + Status = ReadPciConfigUlong(BusNumber, SlotNumber, + Offset, BaseAddresses + Address); + if (! NT_SUCCESS(Status)) + { + return Status; + } + if (0xffffffff == BaseAddresses[Address]) + { + BaseAddresses[Address] = 0; + } + if (0 != BaseAddresses[Address]) + { + NoAddresses++; + Status = WritePciConfigUlong(BusNumber, SlotNumber, Offset, 0xffffffff); + if (! NT_SUCCESS(Status)) + { + WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]); + return Status; + } + Status = ReadPciConfigUlong(BusNumber, SlotNumber, + Offset, Size + Address); + if (! NT_SUCCESS(Status)) + { + WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]); + return Status; + } + Status = WritePciConfigUlong(BusNumber, SlotNumber, Offset, BaseAddresses[Address]); + if (! NT_SUCCESS(Status)) + { + return Status; + } + + } + } + + /* Allocate output buffer and initialize */ + *AllocatedResources = ExAllocatePoolWithTag(PagedPool, + sizeof(CM_RESOURCE_LIST) + + (NoAddresses - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR), + TAG_PCI); + if (NULL == *AllocatedResources) + { + return STATUS_NO_MEMORY; + } + (*AllocatedResources)->Count = 1; + (*AllocatedResources)->List[0].InterfaceType = PCIBus; + (*AllocatedResources)->List[0].BusNumber = BusNumber; + (*AllocatedResources)->List[0].PartialResourceList.Version = 1; + (*AllocatedResources)->List[0].PartialResourceList.Revision = 1; + (*AllocatedResources)->List[0].PartialResourceList.Count = NoAddresses; + Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors; + + /* Store configuration information */ + for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++) + { + if (0 != BaseAddresses[Address]) + { + if (PCI_BASE_ADDRESS_SPACE_MEMORY == + (BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE)) + { + Descriptor->Type = CmResourceTypeMemory; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */ + Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */ + Descriptor->u.Memory.Start.QuadPart = (BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK); + Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK); + } + else if (PCI_BASE_ADDRESS_SPACE_IO == + (BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE)) + { + Descriptor->Type = CmResourceTypePort; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */ + Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */ + Descriptor->u.Port.Start.QuadPart = BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK; + Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff); + } + else + { + assert(FALSE); + return STATUS_UNSUCCESSFUL; + } + Descriptor++; + } + } + + assert(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + NoAddresses); + + /* FIXME: Should store the resources in the registry resource map */ + + return Status; +} + VOID HalpInitPciBus(VOID) @@ -590,8 +746,8 @@ HalpInitPciBus(VOID) (pTranslateBusAddress)HalpTranslatePciAddress; // BusHandler->AdjustResourceList = // (pGetSetBusData)HalpAdjustPciResourceList; -// BusHandler->AssignSlotResources = -// (pGetSetBusData)HalpAssignPciSlotResources; + BusHandler->AssignSlotResources = + (pAssignSlotResources)HalpAssignPciSlotResources; /* agp bus (bus 1) handler */ @@ -606,8 +762,8 @@ HalpInitPciBus(VOID) (pTranslateBusAddress)HalpTranslatePciAddress; // BusHandler->AdjustResourceList = // (pGetSetBusData)HalpAdjustPciResourceList; -// BusHandler->AssignSlotResources = -// (pGetSetBusData)HalpAssignPciSlotResources; + BusHandler->AssignSlotResources = + (pAssignSlotResources)HalpAssignPciSlotResources; DPRINT("HalpInitPciBus() finished.\n"); } diff --git a/hal/halx86/sysbus.c b/hal/halx86/sysbus.c index 5b1b95f..53c021d 100644 --- a/hal/halx86/sysbus.c +++ b/hal/halx86/sysbus.c @@ -11,8 +11,12 @@ /* INCLUDES *****************************************************************/ +#include #include #include +#ifdef MP +#include +#endif /* FUNCTIONS ****************************************************************/ @@ -25,9 +29,15 @@ HalpGetSystemInterruptVector(PVOID BusHandler, PKIRQL Irql, PKAFFINITY Affinity) { - *Irql = PROFILE_LEVEL - BusInterruptVector; - *Affinity = 0xFFFFFFFF; - return BusInterruptVector; +#ifdef MP + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return IRQ2VECTOR(BusInterruptVector); +#else + *Irql = PROFILE_LEVEL - BusInterruptVector; + *Affinity = 0xFFFFFFFF; + return BusInterruptVector; +#endif } diff --git a/hal/halx86/sysinfo.c b/hal/halx86/sysinfo.c index 5d04be8..fb17cbc 100644 --- a/hal/halx86/sysinfo.c +++ b/hal/halx86/sysinfo.c @@ -11,13 +11,66 @@ /* INCLUDES *****************************************************************/ #include +#include +#include +#define NDEBUG #include -/* FUNCTIONS *****************************************************************/ -VOID HalQuerySystemInformation() +/* FUNCTIONS ****************************************************************/ + +NTSTATUS STDCALL +HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass, + IN ULONG BufferSize, + IN OUT PVOID Buffer, + OUT PULONG ReturnedLength) +{ + ULONG DataLength; + NTSTATUS Status; + + DPRINT1("HalpQuerySystemInformation() called\n"); + + *ReturnedLength = 0; + + DataLength = 0; + + switch(InformationClass) + { +#if 0 + case HalInstalledBusInformation: + Status = HalpQueryBusInformation(BufferSize, + Buffer, + ReturnedLength); + break; +#endif + + default: + DataLength = 0; + Status = STATUS_INVALID_LEVEL; + break; + } + + if (DataLength != 0) + { + if (DataLength > BufferSize) + DataLength = BufferSize; + +// RtlCopyMemory(); + + *ReturnedLength = DataLength; + } + + return(Status); +} + + +#if 0 +NTSTATUS +HalpSetSystemInformation(VOID) { UNIMPLEMENTED; } - +#endif + +/* EOF */ diff --git a/iface/addsys/w32ksvc.db b/iface/addsys/w32ksvc.db index b1190ea..b7ccd61 100644 --- a/iface/addsys/w32ksvc.db +++ b/iface/addsys/w32ksvc.db @@ -359,6 +359,7 @@ NtUserGetClassInfo 5 NtUserGetClassLong 2 NtUserGetClassName 3 NtUserGetClientOrigin 2 +NtUserGetClientRect 2 NtUserGetClipboardData 2 NtUserGetClipboardFormatName 3 NtUserGetClipboardOwner 0 @@ -528,6 +529,7 @@ NtUserUnregisterClass 3 NtUserUnregisterHotKey 2 NtUserUpdateInputContext 3 NtUserUpdateInstance 3 +NtUserUpdateWindow 1 NtUserUpdateLayeredWindow 9 NtUserUpdatePerUserSystemParameters 2 NtUserUserHandleGrantAccess 3 diff --git a/include/ascii.h b/include/ascii.h index be57851..82f91ef 100644 --- a/include/ascii.h +++ b/include/ascii.h @@ -1857,7 +1857,7 @@ CopyMetaFileA(HMETAFILE, LPCSTR); HFONT STDCALL -CreateFontIndirectA(CONST LOGFONT *); +CreateFontIndirectA(CONST LOGFONTA *); HDC STDCALL @@ -1878,7 +1878,7 @@ DeviceCapabilitiesA(LPCSTR, LPCSTR, WORD, int STDCALL -EnumFontFamiliesExA(HDC, LPLOGFONT, FONTENUMEXPROC, LPARAM,DWORD); +EnumFontFamiliesExA(HDC, LPLOGFONTA, FONTENUMEXPROC, LPARAM,DWORD); int STDCALL @@ -1917,7 +1917,7 @@ GetMetaFileA(LPCSTR); UINT STDCALL -GetOutlineTextMetricsA(HDC, UINT, LPOUTLINETEXTMETRIC); +GetOutlineTextMetricsA(HDC, UINT, LPOUTLINETEXTMETRICA); WINBOOL STDCALL @@ -1979,7 +1979,7 @@ GetEnhMetaFileDescriptionA(HENHMETAFILE, UINT, LPSTR ); WINBOOL STDCALL -GetTextMetricsA(HDC, LPTEXTMETRIC); +GetTextMetricsA(HDC, LPTEXTMETRICA); int STDCALL diff --git a/include/base.h b/include/base.h index e8b39f4..e37c0e7 100644 --- a/include/base.h +++ b/include/base.h @@ -323,7 +323,10 @@ typedef enum _SID_NAME_USE { #define INDEXTOSTATEIMAGEMASK(i) ((i) << 12) #define MAKEINTATOM(i) (LPTSTR) ((DWORD) ((WORD) (i))) -#define MAKEINTRESOURCE(i) (LPTSTR) ((DWORD) ((WORD) (i))) +#define MAKEINTRESOURCE(i) (LPTSTR) ((ULONG_PTR) ((WORD) (i))) +#define MAKEINTRESOURCEA(i) (LPSTR) ((ULONG_PTR) ((WORD) (i))) +#define MAKEINTRESOURCEW(i) (LPWSTR) ((ULONG_PTR) ((WORD) (i))) +#define IS_INTRESOURCE(n) ((((ULONG_PTR) (n)) >> 16) == 0) #define MAKELANGID(p, s) ((((WORD) (s)) << 10) | (WORD) (p)) #define PRIMARYLANGID(lgid) ((WORD )(lgid) & 0x3ff) diff --git a/include/basetsd.h b/include/basetsd.h index d9c375d..65eec25 100644 --- a/include/basetsd.h +++ b/include/basetsd.h @@ -51,7 +51,7 @@ typedef int LONG32, *PLONG32; #ifndef XFree86Server typedef int INT32, *PINT32; #endif /* ndef XFree86Server */ -typedef unsigned int ULONG32, *PULONG32; +typedef unsigned long ULONG32, *PULONG32; typedef unsigned int DWORD32, *PDWORD32; typedef unsigned int UINT32, *PUINT32; diff --git a/include/csrss/csrss.h b/include/csrss/csrss.h index d13ece7..c1e59c7 100644 --- a/include/csrss/csrss.h +++ b/include/csrss/csrss.h @@ -337,6 +337,37 @@ typedef struct DWORD Length; } CSRSS_WRITE_CONSOLE_INPUT_REPLY, *PCSRSS_WRITE_CONSOLE_INPUT_REPLY; +typedef struct +{ + HANDLE InputHandle; +} CSRSS_GET_INPUT_HANDLE_REPLY, *PCSRSS_GET_INPUT_HANDLE_REPLY; + +typedef struct +{ + HANDLE OutputHandle; +} CSRSS_GET_OUTPUT_HANDLE_REPLY, *PCSRSS_GET_OUTPUT_HANDLE_REPLY; + +typedef struct +{ + HANDLE Handle; +} CSRSS_CLOSE_HANDLE_REQUEST, *PCSRSS_CLOSE_HANDLE_REQUEST; + +typedef struct +{ + HANDLE Handle; +} CSRSS_VERIFY_HANDLE_REQUEST, *PCSRSS_VERIFY_HANDLE_REQUEST; + +typedef struct +{ + HANDLE Handle; + DWORD ProcessId; +} CSRSS_DUPLICATE_HANDLE_REQUEST, *PCSRSS_DUPLICATE_HANDLE_REQUEST; + +typedef struct +{ + HANDLE Handle; +} CSRSS_DUPLICATE_HANDLE_REPLY, *PCSRSS_DUPLICATE_HANDLE_REPLY; + #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \ (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST)) @@ -352,8 +383,8 @@ typedef struct #define CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(HANDLE) - sizeof(DWORD) - sizeof(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB_REQUEST)) -// FIXME: it should be 80. Is this a limit due to LPC msg size? -#define CSRSS_MAX_TITLE_LENGTH 50 +// WCHARs, not bytes! +#define CSRSS_MAX_TITLE_LENGTH 80 #define CSRSS_CREATE_PROCESS (0x0) #define CSRSS_TERMINATE_PROCESS (0x1) @@ -391,6 +422,11 @@ typedef struct #define CSRSS_PEEK_CONSOLE_INPUT (0x21) #define CSRSS_READ_CONSOLE_OUTPUT (0x22) #define CSRSS_WRITE_CONSOLE_INPUT (0x23) +#define CSRSS_GET_INPUT_HANDLE (0x24) +#define CSRSS_GET_OUTPUT_HANDLE (0x25) +#define CSRSS_CLOSE_HANDLE (0x26) +#define CSRSS_VERIFY_HANDLE (0x27) +#define CSRSS_DUPLICATE_HANDLE (0x28) /* Keep in sync with definition below. */ #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE) + sizeof(ULONG)) @@ -434,6 +470,9 @@ typedef struct CSRSS_PEEK_CONSOLE_INPUT_REQUEST PeekConsoleInputRequest; CSRSS_READ_CONSOLE_OUTPUT_REQUEST ReadConsoleOutputRequest; CSRSS_WRITE_CONSOLE_INPUT_REQUEST WriteConsoleInputRequest; + CSRSS_CLOSE_HANDLE_REQUEST CloseHandleRequest; + CSRSS_VERIFY_HANDLE_REQUEST VerifyHandleRequest; + CSRSS_DUPLICATE_HANDLE_REQUEST DuplicateHandleRequest; } Data; } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST; @@ -464,6 +503,9 @@ typedef struct CSRSS_PEEK_CONSOLE_INPUT_REPLY PeekConsoleInputReply; CSRSS_READ_CONSOLE_OUTPUT_REPLY ReadConsoleOutputReply; CSRSS_WRITE_CONSOLE_INPUT_REPLY WriteConsoleInputReply; + CSRSS_GET_INPUT_HANDLE_REPLY GetInputHandleReply; + CSRSS_GET_OUTPUT_HANDLE_REPLY GetOutputHandleReply; + CSRSS_DUPLICATE_HANDLE_REPLY DuplicateHandleReply; } Data; } CSRSS_API_REPLY, *PCSRSS_API_REPLY; diff --git a/include/ddk/cctypes.h b/include/ddk/cctypes.h index 4d61ef8..dce1748 100644 --- a/include/ddk/cctypes.h +++ b/include/ddk/cctypes.h @@ -77,7 +77,6 @@ typedef struct _REACTOS_COMMON_FCB_HEADER { CSHORT NodeTypeCode; CSHORT NodeByteSize; - struct _BCB* Bcb; LARGE_INTEGER AllocationSize; LARGE_INTEGER FileSize; LARGE_INTEGER ValidDataLength; diff --git a/include/ddk/class2.h b/include/ddk/class2.h index 941b35a..6e1e939 100644 --- a/include/ddk/class2.h +++ b/include/ddk/class2.h @@ -213,4 +213,4 @@ ScsiClassSplitRequest(PDEVICE_OBJECT DeviceObject, #endif /* __STORAGE_INCLUDE_CLASS2_H */ -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/include/ddk/cmtypes.h b/include/ddk/cmtypes.h index e1c1ac4..3334610 100644 --- a/include/ddk/cmtypes.h +++ b/include/ddk/cmtypes.h @@ -1,7 +1,7 @@ #ifndef __INCLUDE_DDK_CMTYPES_H #define __INCLUDE_DDK_CMTYPES_H /* - * Object Manager structures and typedefs + * Configuration Manager structures and typedefs */ /* @@ -99,4 +99,5 @@ typedef struct _KEY_VALUE_ENTRY ULONG Type; } KEY_VALUE_ENTRY, *PKEY_VALUE_ENTRY; + #endif /* __INCLUDE_DDK_CMTYPES_H */ diff --git a/include/ddk/defines.h b/include/ddk/defines.h index 392afe0..de9e186 100644 --- a/include/ddk/defines.h +++ b/include/ddk/defines.h @@ -34,11 +34,11 @@ enum enum { NonPagedPool, - NonPagedPoolMustSucceed, - NonPagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS, PagedPool, + NonPagedPoolMustSucceed, + NonPagedPoolCacheAligned = 4, PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, }; diff --git a/include/ddk/exfuncs.h b/include/ddk/exfuncs.h index fc13a68..026f90c 100644 --- a/include/ddk/exfuncs.h +++ b/include/ddk/exfuncs.h @@ -185,7 +185,7 @@ ExFreePool ( * ); */ #define ExGetCurrentResourceThread() \ - ((ERESOURCE_THREAD)PsGetCurrentThread()) + ((ERESOURCE_THREAD)KeGetCurrentThread()) ULONG STDCALL @@ -801,6 +801,9 @@ InterlockedIncrement ( PLONG Addend ); +#define InterlockedExchangePointer(__T__, __V__) \ + (PVOID)InterlockedExchange((PLONG)(__T__), (LONG)(__V__)) + /*---*/ typedef diff --git a/include/ddk/extypes.h b/include/ddk/extypes.h index 6093fc5..2d44910 100644 --- a/include/ddk/extypes.h +++ b/include/ddk/extypes.h @@ -7,16 +7,18 @@ extern POBJECT_TYPE EXPORTED ExDesktopObjectType; extern POBJECT_TYPE EXPORTED ExEventObjectType; extern POBJECT_TYPE EXPORTED ExWindowStationObjectType; +extern POBJECT_TYPE EXPORTED ExIoCompletionType; #else extern POBJECT_TYPE IMPORTED ExDesktopObjectType; extern POBJECT_TYPE IMPORTED ExEventObjectType; extern POBJECT_TYPE IMPORTED ExWindowStationObjectType; +extern POBJECT_TYPE IMPORTED ExIoCompletionType; #endif typedef ULONG INTERLOCKED_RESULT; typedef ULONG WORK_QUEUE_TYPE; -typedef ULONG ERESOURCE_THREAD, *PERESOURCE_THREAD; +typedef ULONG_PTR ERESOURCE_THREAD, *PERESOURCE_THREAD; typedef struct _OWNER_ENTRY { diff --git a/include/ddk/fsfuncs.h b/include/ddk/fsfuncs.h index 06ce05f..e443aa7 100644 --- a/include/ddk/fsfuncs.h +++ b/include/ddk/fsfuncs.h @@ -24,13 +24,11 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Lbn, IN LONGLONG SectorCount); -VOID STDCALL -FsRtlAddMcbEntry( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ); +BOOLEAN STDCALL +FsRtlAddMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + IN LBN Lbn, + IN ULONG SectorCount); VOID STDCALL FsRtlAddToTunnelCache ( @@ -204,7 +202,7 @@ FsRtlFastUnlockAllByKey ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, - IN DWORD Key, + IN ULONG Key, IN PVOID Context OPTIONAL ); NTSTATUS @@ -250,15 +248,12 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount); -VOID -STDCALL -FsRtlGetNextMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ); +BOOLEAN STDCALL +FsRtlGetNextMcbEntry (IN PMCB Mcb, + IN ULONG RunIndex, + OUT PVBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount); #define FsRtlEnterFileSystem KeEnterCriticalRegion #define FsRtlExitFileSystem KeLeaveCriticalRegion VOID @@ -273,12 +268,9 @@ VOID STDCALL FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType); -VOID -STDCALL -FsRtlInitializeMcb ( - DWORD Unknown0, - DWORD Unknown1 - ); +VOID STDCALL +FsRtlInitializeMcb (IN PMCB Mcb, + IN POOL_TYPE PoolType); VOID STDCALL FsRtlInitializeOplock(IN OUT POPLOCK Oplock); @@ -347,22 +339,17 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn); -VOID -STDCALL -FsRtlLookupLastMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ); -VOID -STDCALL -FsRtlLookupMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ); +BOOLEAN STDCALL +FsRtlLookupLastMcbEntry (IN PMCB Mcb, + OUT PVBN Vbn, + OUT PLBN Lbn); +BOOLEAN STDCALL +FsRtlLookupMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount OPTIONAL, + OUT PULONG Index); + BOOLEAN STDCALL FsRtlMdlRead ( @@ -522,11 +509,9 @@ FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize, ULONG STDCALL FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb); -VOID -STDCALL -FsRtlNumberOfRunsInMcb ( - DWORD Unknown0 - ); +ULONG STDCALL +FsRtlNumberOfRunsInMcb (IN PMCB Mcb); + VOID STDCALL FsRtlPostPagingFileStackOverflow ( @@ -575,13 +560,10 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount); -VOID -STDCALL -FsRtlRemoveMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ); +VOID STDCALL +FsRtlRemoveMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + IN ULONG SectorCount); BOOLEAN STDCALL FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, @@ -600,26 +582,18 @@ VOID STDCALL FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, IN LONGLONG Vbn); -VOID -STDCALL -FsRtlTruncateMcb ( - DWORD Unknown0, - DWORD Unknown1 - ); -VOID -STDCALL -FsRtlUninitializeFileLock ( - IN PFILE_LOCK FileLock - ); +VOID STDCALL +FsRtlTruncateMcb (IN PMCB Mcb, + IN VBN Vbn); + +VOID STDCALL +FsRtlUninitializeFileLock (IN PFILE_LOCK FileLock); VOID STDCALL FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb); -VOID -STDCALL -FsRtlUninitializeMcb ( - DWORD Unknown0 - ); +VOID STDCALL +FsRtlUninitializeMcb (IN PMCB Mcb); VOID STDCALL FsRtlUninitializeOplock(IN POPLOCK Oplock); diff --git a/include/ddk/fstypes.h b/include/ddk/fstypes.h index f782424..4d27259 100644 --- a/include/ddk/fstypes.h +++ b/include/ddk/fstypes.h @@ -4,6 +4,12 @@ #define FSRTL_TAG TAG('F','S','r','t') +typedef ULONG LBN; +typedef LBN *PLBN; + +typedef ULONG VBN; +typedef VBN *PVBN; + typedef struct _FILE_LOCK_INFO { LARGE_INTEGER StartingByte; LARGE_INTEGER Length; @@ -80,6 +86,9 @@ typedef struct _LARGE_MCB PVOID Mapping; } LARGE_MCB, *PLARGE_MCB; +typedef struct _MCB { + LARGE_MCB LargeMcb; +} MCB, *PMCB; typedef VOID (*POPLOCK_WAIT_COMPLETE_ROUTINE)(PVOID Context, diff --git a/include/ddk/halfuncs.h b/include/ddk/halfuncs.h index fd2be9d..d54b9cf 100644 --- a/include/ddk/halfuncs.h +++ b/include/ddk/halfuncs.h @@ -70,12 +70,16 @@ HalEndSystemInterrupt(KIRQL Irql, ULONG Unknown2); -/* Is this function really exported ?? */ -VOID -HalExamineMBR(PDEVICE_OBJECT DeviceObject, - ULONG SectorSize, - ULONG MBRTypeIdentifier, - PVOID Buffer); +/* + * HalExamineMBR() is not exported explicitly. + * It is exported by the HalDispatchTable. + * + * VOID + * HalExamineMBR(PDEVICE_OBJECT DeviceObject, + * ULONG SectorSize, + * ULONG MBRTypeIdentifier, + * PVOID Buffer); + */ BOOLEAN STDCALL HalFlushCommonBuffer(ULONG Unknown1, @@ -150,9 +154,13 @@ HalQueryDisplayParameters(PULONG DispSizeX, VOID STDCALL HalQueryRealTimeClock(PTIME_FIELDS Time); -/* Is this function really exported ?? */ -VOID -HalQuerySystemInformation(VOID); +/* + * HalQuerySystemInformation() is not exported explicitly. + * It is exported by the HalDispatchTable. + * + * VOID + * HalQuerySystemInformation(VOID); + */ ULONG STDCALL HalReadDmaCounter(PADAPTER_OBJECT AdapterObject); diff --git a/include/ddk/haltypes.h b/include/ddk/haltypes.h index 2256e25..ff34edf 100644 --- a/include/ddk/haltypes.h +++ b/include/ddk/haltypes.h @@ -260,18 +260,6 @@ typedef struct _PCI_SLOT_NUMBER } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER; -/* MicroChannel bus data */ - -typedef struct _CM_MCA_POS_DATA -{ - USHORT AdapterId; - UCHAR PosData1; - UCHAR PosData2; - UCHAR PosData3; - UCHAR PosData4; -} CM_MCA_POS_DATA, *PCM_MCA_POS_DATA; - - /* Hal dispatch table */ typedef enum _HAL_QUERY_INFORMATION_CLASS @@ -430,14 +418,29 @@ typedef struct _HAL_DISPATCH pHalReferenceBusHandler HalDereferenceBusHandler; } HAL_DISPATCH, *PHAL_DISPATCH; -#define HAL_DISPATCH_VERSION 1 - #ifdef __NTOSKRNL__ extern HAL_DISPATCH EXPORTED HalDispatchTable; +#define HALDISPATCH (&HalDispatchTable) #else -extern HAL_DISPATCH IMPORTED HalDispatchTable; +extern PHAL_DISPATCH IMPORTED HalDispatchTable; +#define HALDISPATCH ((PHAL_DISPATCH)&HalDispatchTable) #endif +#define HAL_DISPATCH_VERSION 1 +#define HalDispatchTableVersion HALDISPATCH->Version +#define HalQuerySystemInformation HALDISPATCH->HalQuerySystemInformation +#define HalSetSystemInformation HALDISPATCH->HalSetSystemInformation +#define HalQueryBusSlots HALDISPATCH->HalQueryBusSlots +#define HalDeviceControl HALDISPATCH->HalDeviceControl +#define HalExamineMBR HALDISPATCH->HalExamineMBR +#define HalIoAssignDriveLetters HALDISPATCH->HalIoAssignDriveLetters +#define HalIoReadPartitionTable HALDISPATCH->HalIoReadPartitionTable +#define HalIoSetPartitionInformation HALDISPATCH->HalIoSetPartitionInformation +#define HalIoWritePartitionTable HALDISPATCH->HalIoWritePartitionTable +#define HalReferenceHandlerForBus HALDISPATCH->HalReferenceHandlerForBus +#define HalReferenceBusHandler HALDISPATCH->HalReferenceBusHandler +#define HalDereferenceBusHandler HALDISPATCH->HalDereferenceBusHandler + /* Hal private dispatch table */ @@ -446,15 +449,15 @@ typedef struct _HAL_PRIVATE_DISPATCH ULONG Version; } HAL_PRIVATE_DISPATCH, *PHAL_PRIVATE_DISPATCH; -#define HAL_PRIVATE_DISPATCH_VERSION 1 - #ifdef __NTOSKRNL__ extern HAL_PRIVATE_DISPATCH EXPORTED HalPrivateDispatchTable; #else -extern HAL_PRIVATE_DISPATCH IMPORTED HalPrivateDispatchTable; +extern PHAL_PRIVATE_DISPATCH IMPORTED HalPrivateDispatchTable; #endif +#define HAL_PRIVATE_DISPATCH_VERSION 1 + /* diff --git a/include/ddk/iodef.h b/include/ddk/iodef.h index 4d0b4e9..c133f6c 100644 --- a/include/ddk/iodef.h +++ b/include/ddk/iodef.h @@ -42,6 +42,17 @@ enum enum { + CM_RESOURCE_MEMORY_READ_WRITE = 0x0000, + CM_RESOURCE_MEMORY_READ_ONLY = 0x0001, + CM_RESOURCE_MEMORY_WRITE_ONLY = 0x0002, + CM_RESOURCE_MEMORY_PREFETCHABLE = 0x0004, + CM_RESOURCE_MEMORY_COMBINEDWRITE = 0x0008, + CM_RESOURCE_MEMORY_24 = 0x0010 +}; + + +enum +{ CM_RESOURCE_PORT_MEMORY, CM_RESOURCE_PORT_IO, }; diff --git a/include/ddk/iofuncs.h b/include/ddk/iofuncs.h index 595b33e..572b26b 100644 --- a/include/ddk/iofuncs.h +++ b/include/ddk/iofuncs.h @@ -936,8 +936,8 @@ IoReportResourceUsage ( (KeInsertQueueDpc(&(DeviceObject)->Dpc,(Irp),(Context))) #define IoSetCancelRoutine(Irp,NewCancelRoutine) \ - ((PDRIVER_CANCEL)InterlockedExchange((PULONG)&(Irp)->CancelRoutine, \ - (ULONG)(NewCancelRoutine))) + ((PDRIVER_CANCEL)InterlockedExchangePointer(&(Irp)->CancelRoutine, \ + NewCancelRoutine)) #define IoSetCompletionRoutine(Irp,Routine,Context,Success,Error,Cancel) \ { \ diff --git a/include/ddk/iotypes.h b/include/ddk/iotypes.h index e6f6fa7..81dbf8e 100644 --- a/include/ddk/iotypes.h +++ b/include/ddk/iotypes.h @@ -194,6 +194,42 @@ typedef struct _IO_RESOURCE_REQUIREMENTS_LIST IO_RESOURCE_LIST List[1]; } IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST; + +/* MicroChannel bus data */ + +typedef struct _CM_MCA_POS_DATA +{ + USHORT AdapterId; + UCHAR PosData1; + UCHAR PosData2; + UCHAR PosData3; + UCHAR PosData4; +} CM_MCA_POS_DATA, *PCM_MCA_POS_DATA; + + +/* Int13 drive geometry data */ + +typedef struct _CM_INT13_DRIVE_PARAMETER +{ + USHORT DriveSelect; + ULONG MaxCylinders; + USHORT SectorsPerTrack; + USHORT MaxHeads; + USHORT NumberDrives; +} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER; + + +/* Extended drive geometry data */ + +typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA +{ + ULONG BytesPerSector; + ULONG NumberOfCylinders; + ULONG SectorsPerTrack; + ULONG NumberOfHeads; +} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA; + + typedef struct { UCHAR Type; @@ -245,7 +281,7 @@ typedef struct INTERFACE_TYPE InterfaceType; ULONG BusNumber; CM_PARTIAL_RESOURCE_LIST PartialResourceList; -} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR; +} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; typedef struct { @@ -465,6 +501,12 @@ typedef struct _IO_STATUS_BLOCK ULONG Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; +typedef struct _IO_COMPLETION_PACKET{ + ULONG Key; + ULONG Overlapped; + IO_STATUS_BLOCK IoStatus; + LIST_ENTRY ListEntry; +} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET; typedef struct _IO_PIPE_CREATE_BUFFER { diff --git a/include/ddk/kefuncs.h b/include/ddk/kefuncs.h index b99a1be..6322bf2 100644 --- a/include/ddk/kefuncs.h +++ b/include/ddk/kefuncs.h @@ -135,6 +135,9 @@ VOID STDCALL KeInitializeQueue(IN PKQUEUE Queue, IN ULONG Count); +PLIST_ENTRY STDCALL +KeRundownQueue(IN PKQUEUE Queue); + VOID STDCALL KeInitializeSemaphore (PKSEMAPHORE Semaphore, LONG Count, LONG Limit); diff --git a/include/ddk/ketypes.h b/include/ddk/ketypes.h index be4b6e4..7851386 100644 --- a/include/ddk/ketypes.h +++ b/include/ddk/ketypes.h @@ -122,9 +122,9 @@ typedef struct _KQUEUE { DISPATCHER_HEADER Header; LIST_ENTRY EntryListHead; - ULONG CurrentCount; - ULONG MaximumCount; - LIST_ENTRY ThreadListEntry; + ULONG RunningThreads; + ULONG MaximumThreads; + LIST_ENTRY ThreadListHead; } KQUEUE, *PKQUEUE; struct _KDPC; diff --git a/include/ddk/ntddblue.h b/include/ddk/ntddblue.h index ed29427..dd13642 100644 --- a/include/ddk/ntddblue.h +++ b/include/ddk/ntddblue.h @@ -12,17 +12,17 @@ #define IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x810, METHOD_BUFFERED, FILE_WRITE_ACCESS) -#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x811, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x812, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x811, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x812, METHOD_IN_DIRECT, FILE_ANY_ACCESS) #define IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE CTL_CODE(FILE_DEVICE_SCREEN, 0x813, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x820, METHOD_BUFFERED, FILE_WRITE_ACCESS) -#define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x821, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x822, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_CONSOLE_READ_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x821, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER CTL_CODE(FILE_DEVICE_SCREEN, 0x822, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_CONSOLE_DRAW CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_CONSOLE_DRAW CTL_CODE(FILE_DEVICE_SCREEN, 0x830, METHOD_IN_DIRECT, FILE_ANY_ACCESS) /* TYPEDEFS **************************************************************/ diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h index 11610af..b2e0e19 100644 --- a/include/ddk/ntddk.h +++ b/include/ddk/ntddk.h @@ -37,6 +37,7 @@ extern "C" #include #include #include +#include #include #include @@ -48,8 +49,8 @@ extern "C" #include #include #include -#include #include +#include #include #include #include diff --git a/include/ddk/ntddmou.h b/include/ddk/ntddmou.h new file mode 100644 index 0000000..f64067e --- /dev/null +++ b/include/ddk/ntddmou.h @@ -0,0 +1,71 @@ +// Mouse definitions common to both mouse class and port drivers + +#define IO_MOUSE_INCREMENT 6 +#define MOUSE_BUFFER_SIZE 32 + +#define IOCTL_INTERNAL_MOUSE_CONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_INTERNAL_MOUSE_DISCONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_INTERNAL_MOUSE_ENABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS) +#define IOCTL_INTERNAL_MOUSE_DISABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS) + +#define MOUSE_BUTTON_1_DOWN 0x0001 +#define MOUSE_BUTTON_1_UP 0x0002 +#define MOUSE_BUTTON_2_DOWN 0x0004 +#define MOUSE_BUTTON_2_UP 0x0008 +#define MOUSE_BUTTON_3_DOWN 0x0010 +#define MOUSE_BUTTON_3_UP 0x0020 +#define MOUSE_BUTTON_4_DOWN 0x0040 +#define MOUSE_BUTTON_4_UP 0x0080 +#define MOUSE_BUTTON_5_DOWN 0x0100 +#define MOUSE_BUTTON_5_UP 0x0200 +#define MOUSE_WHEEL 0x0400 + +#define MOUSE_LEFT_BUTTON_DOWN MOUSE_BUTTON_1_DOWN +#define MOUSE_LEFT_BUTTON_UP MOUSE_BUTTON_1_UP +#define MOUSE_RIGHT_BUTTON_DOWN MOUSE_BUTTON_2_DOWN +#define MOUSE_RIGHT_BUTTON_UP MOUSE_BUTTON_2_UP +#define MOUSE_MIDDLE_BUTTON_DOWN MOUSE_BUTTON_3_DOWN +#define MOUSE_MIDDLE_BUTTON_UP MOUSE_BUTTON_3_UP + +/* Mouse input data structure */ +typedef struct _MOUSE_INPUT_DATA { + USHORT UnitId; + USHORT Flags; + union { + ULONG Buttons; + struct { + USHORT ButtonFlags; + USHORT ButtonData; + }; + }; + ULONG RawButtons; + LONG LastX; + LONG LastY; + ULONG ExtraInformation; +} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA; + +typedef struct _CLASS_INFORMATION { + PDEVICE_OBJECT DeviceObject; + PVOID CallBack; +} CLASS_INFORMATION, *PCLASS_INFORMATION; + +typedef struct _GDI_INFORMATION { + PVOID CallBack; +} GDI_INFORMATION, *PGDI_INFORMATION; + +typedef +VOID +(*PSERVICE_CALLBACK_ROUTINE) ( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2, + IN OUT PVOID SystemArgument3 + ); + +typedef +VOID +(*PGDI_SERVICE_CALLBACK_ROUTINE) ( + IN PVOID SystemArgument1, + IN ULONG SystemArgument2 + ); + diff --git a/include/ddk/ntddvid.h b/include/ddk/ntddvid.h index 3240396..5705546 100644 --- a/include/ddk/ntddvid.h +++ b/include/ddk/ntddvid.h @@ -209,6 +209,16 @@ typedef struct _VIDEO_PORT_CONFIG_INFO ULONG DmaPort; UCHAR DmaShareable; UCHAR InterruptShareable; + BOOLEAN Master; + DMA_WIDTH DmaWidth; + DMA_SPEED DmaSpeed; + BOOLEAN bMapBuffers; + BOOLEAN NeedPhysicalAddresses; + BOOLEAN DemandMode; + ULONG MaximumTransferLength; + ULONG NumberOfPhysicalBreaks; + BOOLEAN ScatterGather; + ULONG MaximumScatterGatherChunkSize; } VIDEO_PORT_CONFIG_INFO, *PVIDEO_PORT_CONFIG_INFO; typedef VP_STATUS STDCALL diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index e5b8290..82632f7 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -1,15 +1,11 @@ #ifndef __INCLUDE_DDK_NTIFS_H #define __INCLUDE_DDK_NTIFS_H -struct _BCB; - NTSTATUS STDCALL CcRosInitializeFileCache (PFILE_OBJECT FileObject, - struct _BCB** Bcb, ULONG CacheSegmentSize); NTSTATUS STDCALL -CcRosReleaseFileCache (PFILE_OBJECT FileObject, - struct _BCB* Bcb); +CcRosReleaseFileCache (PFILE_OBJECT FileObject); #include diff --git a/include/ddk/obtypes.h b/include/ddk/obtypes.h index 5e5480d..623b4f7 100644 --- a/include/ddk/obtypes.h +++ b/include/ddk/obtypes.h @@ -94,13 +94,18 @@ typedef struct _OBJECT_TYPE PUNICODE_STRING FullPath, PWSTR *Path, ULONG Attributes); - - /* - */ - NTSTATUS STDCALL_FUNC (*Security)(PVOID Object, - ULONG InfoClass, - PVOID Info, - PULONG InfoLength); + + /* + * PURPOSE: Called to set, query, delete or assign a security-descriptor + * to the object + * RETURNS + * STATUS_SUCCESS NextObject was found + */ + NTSTATUS STDCALL_FUNC (*Security)(PVOID ObjectBody, + SECURITY_OPERATION_CODE OperationCode, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR SecurityDescriptor, + PULONG BufferLength); /* */ diff --git a/include/ddk/psfuncs.h b/include/ddk/psfuncs.h index 780ca7c..cac2810 100644 --- a/include/ddk/psfuncs.h +++ b/include/ddk/psfuncs.h @@ -48,8 +48,9 @@ VOID STDCALL PsEstablishWin32Callouts(PVOID Param1, ULONG W32ThreadSize, ULONG W32ProcessSize); -struct _ETHREAD* STDCALL PsGetCurrentThread(VOID); -struct _EPROCESS* STDCALL PsGetCurrentProcess(VOID); +#define PsGetCurrentProcess() IoGetCurrentProcess() +#define PsGetCurrentThread() ((struct _ETHREAD*) (KeGetCurrentThread())) + PACCESS_TOKEN STDCALL PsReferenceImpersonationToken(struct _ETHREAD* Thread, PULONG Unknown1, PULONG Unknown2, diff --git a/include/ddk/pstypes.h b/include/ddk/pstypes.h index 25113b8..9925904 100644 --- a/include/ddk/pstypes.h +++ b/include/ddk/pstypes.h @@ -9,6 +9,9 @@ #ifndef TLS_MINIMUM_AVAILABLE #define TLS_MINIMUM_AVAILABLE (64) #endif +#ifndef TLS_OUT_OF_INDEXES +#define TLS_OUT_OF_INDEXES 0xFFFFFFFF +#endif #ifndef MAX_PATH #define MAX_PATH (260) #endif diff --git a/include/ddk/sefuncs.h b/include/ddk/sefuncs.h index 004359b..bc8d3cc 100644 --- a/include/ddk/sefuncs.h +++ b/include/ddk/sefuncs.h @@ -2,6 +2,14 @@ #define _INCLUDE_DDK_SEFUNCS_H /* $Id$ */ +#ifdef __NTOSKRNL__ +extern PACL EXPORTED SePublicDefaultDacl; +extern PACL EXPORTED SeSystemDefaultDacl; +#else +extern PACL IMPORTED SePublicDefaultDacl; +extern PACL IMPORTED SeSystemDefaultDacl; +#endif + BOOLEAN STDCALL SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, diff --git a/include/ddk/setypes.h b/include/ddk/setypes.h index cd4eaa5..cf1ab5d 100644 --- a/include/ddk/setypes.h +++ b/include/ddk/setypes.h @@ -159,6 +159,15 @@ typedef struct _SE_EXPORTS typedef NTSTATUS STDCALL_FUNC (*PSE_LOGON_SESSION_TERMINATED_ROUTINE)(IN PLUID LogonId); + +typedef enum _SECURITY_OPERATION_CODE +{ + SetSecurityDescriptor, + QuerySecurityDescriptor, + DeleteSecurityDescriptor, + AssignSecurityDescriptor +} SECURITY_OPERATION_CODE, *PSECURITY_OPERATION_CODE; + #endif /* EOF */ diff --git a/include/ddk/winddi.h b/include/ddk/winddi.h index 7c69738..9d18363 100644 --- a/include/ddk/winddi.h +++ b/include/ddk/winddi.h @@ -1085,7 +1085,7 @@ EngCreateEvent HPALETTE STDCALL EngCreatePalette(IN ULONG Mode, IN ULONG NumColors, - IN PULONG *Colors, + IN ULONG *Colors, IN ULONG Red, IN ULONG Green, IN ULONG Blue); diff --git a/include/debug.h b/include/debug.h index 38c9223..acc6db0 100644 --- a/include/debug.h +++ b/include/debug.h @@ -34,26 +34,12 @@ #define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0); -extern unsigned int old_idt[256][2]; -//extern unsigned int idt; -extern unsigned int old_idt_valid; - -#ifdef __NTOSKRNL__ -//#define DPRINT_CHECKS ExAllocatePool(NonPagedPool,0); assert(old_idt_valid || (!memcmp(old_idt,KiIdt,256*2))); -//#define DPRINT_CHECKS ExAllocatePool(NonPagedPool,0); -#define DPRINT_CHECKS -#else -#define DPRINT_CHECKS -#endif #ifndef NDEBUG -#define OLD_DPRINT(fmt,args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(fmt,args); } while(0); -#define DPRINT(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); DPRINT_CHECKS } while(0); +#define DPRINT(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0); #else -//#define DPRINT(args...) do { DPRINT_CHECKS } while (0); #define DPRINT(args...) -#define OLD_DPRINT(args...) #define CHECKPOINT #endif /* NDEBUG */ @@ -65,36 +51,15 @@ extern unsigned int old_idt_valid; #define ASSERT_IRQL(x) assert(KeGetCurrentIrql()<=(x)) #define assert_irql(x) assert(KeGetCurrentIrql()<=(x)) -#define HBP_EXECUTE (0) -#define HBP_WRITE (1) -#define HBP_READWRITE (3) - -#define HBP_BYTE (0) -#define HBP_WORD (1) -#define HBP_DWORD (3) - -/* - * FUNCTION: Sets a hardware breakpoint - * ARGUMENTS: - * i = breakpoint to set (0 to 3) - * addr = linear address to break on - * type = Type of access to break on - * len = length of the variable to watch - * NOTES: - * The variable to watch must be aligned to its length (i.e. a dword - * breakpoint must be aligned to a dword boundary) - * - * A fatal exception will be generated on the access to the variable. - * It is (at the moment) only really useful for catching undefined - * pointers if you know the variable effected but not the buggy - * routine. - * - * FIXME: Extend to call out to kernel debugger on breakpoint - * Add support for I/O breakpoints - * REFERENCES: See the i386 programmer manual for more details - */ -void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, - unsigned int len); - +/* Macros expanding to the appropriate inline assembly to raise a breakpoint */ +#if defined(_M_IX86) +#define ASM_BREAKPOINT "\nint $3\n" +#elif defined(_M_ALPHA) +#define ASM_BREAKPOINT "\ncall_pal bpt\n" +#elif defined(_M_MIPS) +#define ASM_BREAKPOINT "\nbreak\n" +#else +#error Unsupported architecture. +#endif #endif /* __INTERNAL_DEBUG */ diff --git a/include/defines.h b/include/defines.h index 30cca02..e191776 100644 --- a/include/defines.h +++ b/include/defines.h @@ -882,6 +882,7 @@ extern "C" { /* DrawFrameControl */ #define DFC_BUTTON (4) +#define DFC_POPUPMENU (5) #define DFC_CAPTION (1) #define DFC_MENU (2) #define DFC_SCROLL (3) @@ -956,6 +957,7 @@ extern "C" { #define DT_TOP (0) #define DT_VCENTER (4) #define DT_WORDBREAK (16) +#define DT_WORD_ELLIPSIS (262144) #define DT_INTERNAL (4096) @@ -1435,9 +1437,10 @@ extern "C" { #define EXCEPTION_INVALID_HANDLE (0xc0000008L) #define EXCEPTION_PRIV_INSTRUCTION (0xc0000096L) #define EXCEPTION_NONCONTINUABLE_EXCEPTION (0xc0000025L) -#define EXCEPTION_NONCONTINUABLE (0x1) #define EXCEPTION_STACK_OVERFLOW (0xc00000fdL) #define EXCEPTION_INVALID_DISPOSITION (0xc0000026L) +#define EXCEPTION_CONTINUABLE (0x0) +#define EXCEPTION_NONCONTINUABLE (0x1) /* GetFileType */ #define FILE_TYPE_UNKNOWN (0) @@ -1922,23 +1925,6 @@ extern "C" { /* InitializeSecurityDescriptor */ #define SECURITY_DESCRIPTOR_REVISION (1) -/* IsTextUnicode */ -#define IS_TEXT_UNICODE_ASCII16 (1) -#define IS_TEXT_UNICODE_REVERSE_ASCII16 (16) -#define IS_TEXT_UNICODE_STATISTICS (2) -#define IS_TEXT_UNICODE_REVERSE_STATISTICS (32) -#define IS_TEXT_UNICODE_CONTROLS (4) -#define IS_TEXT_UNICODE_REVERSE_CONTROLS (64) -#define IS_TEXT_UNICODE_SIGNATURE (8) -#define IS_TEXT_UNICODE_REVERSE_SIGNATURE (128) -#define IS_TEXT_UNICODE_ILLEGAL_CHARS (256) -#define IS_TEXT_UNICODE_ODD_LENGTH (512) -#define IS_TEXT_UNICODE_NULL_BYTES (4096) -#define IS_TEXT_UNICODE_UNICODE_MASK (15) -#define IS_TEXT_UNICODE_REVERSE_MASK (240) -#define IS_TEXT_UNICODE_NOT_UNICODE_MASK (3840) -#define IS_TEXT_UNICODE_NOT_ASCII_MASK (61440) - /* JournalPlaybackProc, KeyboardProc */ #define HC_GETNEXT (1) #define HC_SKIP (2) @@ -2891,6 +2877,8 @@ extern "C" { #define VS_FF_PRERELEASE (0x2L) #define VS_FF_PRIVATEBUILD (0x8L) #define VS_FF_SPECIALBUILD (0x20L) +#define VS_FFI_SIGNATURE (0xfeef04bd) +#define VS_FFI_STRUCVERSION (0x00010000) #define VOS_UNKNOWN (0L) #define VOS_DOS (0x10000L) #define VOS_OS216 (0x20000L) @@ -4788,6 +4776,17 @@ typedef enum _SystemState { STATE_SYSTEM_VALID = 0x1FFFFFFF } SystemState; +/* + * From OS/2 2.0 exception handling + * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD + */ + +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/include/epsapi.h b/include/epsapi.h new file mode 100644 index 0000000..cb067a2 --- /dev/null +++ b/include/epsapi.h @@ -0,0 +1,227 @@ +/* $Id$ +*/ +/* + * epsapi.h + * + * Process Status Helper API, native interface + * + * This file is part of the ReactOS Operating System. + * + * Contributors: + * Created by KJK::Hyperion + * + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __INTERNAL_PSAPI_H_INCLUDED__ +#define __INTERNAL_PSAPI_H_INCLUDED__ + +/* INCLUDES */ +#include +#include + +/* OBJECTS */ + +/* TYPES */ +typedef NTSTATUS NTAPI (*PPROC_ENUM_ROUTINE) +( + IN PSYSTEM_PROCESSES CurrentProcess, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PTHREAD_ENUM_ROUTINE) +( + IN PSYSTEM_THREADS CurrentThread, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PSYSMOD_ENUM_ROUTINE) +( + IN PSYSTEM_MODULE_INFORMATION CurrentModule, + IN OUT PVOID CallbackContext +); + +typedef NTSTATUS NTAPI (*PPROCMOD_ENUM_ROUTINE) +( + IN HANDLE ProcessHandle, + IN PLDR_MODULE CurrentModule, + IN OUT PVOID CallbackContext +); + +/* CONSTANTS */ +#define FAILED_WITH_STATUS DEFINE_DBG_MSG("%s() failed, status 0x%08X") + +/* PROTOTYPES */ +/* Processes and threads */ +/* enumeration */ +NTSTATUS +NTAPI +PsaEnumerateProcessesAndThreads +( + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +); + +NTSTATUS +NTAPI +PsaEnumerateProcesses +( + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +NTSTATUS +NTAPI +PsaEnumerateThreads +( + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* capturing & walking */ +NTSTATUS +NTAPI +PsaCaptureProcessesAndThreads +( + OUT PSYSTEM_PROCESSES * ProcessesAndThreads +); + +NTSTATUS +NTAPI +PsaWalkProcessesAndThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +); + +NTSTATUS +NTAPI +PsaWalkProcesses +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +NTSTATUS +NTAPI +PsaWalkThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkFirstProcess +( + IN PSYSTEM_PROCESSES ProcessesAndThreads +); + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkNextProcess +( + IN PSYSTEM_PROCESSES CurrentProcess +); + +PSYSTEM_THREADS +FASTCALL +PsaWalkFirstThread +( + IN PSYSTEM_PROCESSES CurrentProcess +); + +PSYSTEM_THREADS +FASTCALL +PsaWalkNextThread +( + IN PSYSTEM_THREADS CurrentThread +); + +/* System modules */ +/* enumeration */ +NTSTATUS +NTAPI +PsaEnumerateSystemModules +( + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* capturing & walking */ +NTSTATUS +NTAPI +PsaCaptureSystemModules +( + OUT PSYSTEM_MODULES * SystemModules +); + +NTSTATUS +NTAPI +PsaWalkSystemModules +( + IN PSYSTEM_MODULES SystemModules, + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +PSYSTEM_MODULE_INFORMATION +FASTCALL +PsaWalkFirstSystemModule +( + IN PSYSTEM_MODULES SystemModules +); + +PSYSTEM_MODULE_INFORMATION +FASTCALL +PsaWalkNextSystemModule +( + IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule +); + +/* Process modules */ +NTSTATUS +NTAPI +PsaEnumerateProcessModules +( + IN HANDLE ProcessHandle, + IN PPROCMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +); + +/* Miscellaneous */ +VOID +NTAPI +PsaFreeCapture +( + IN PVOID Capture +); + +/* The user must define these functions. They are called by PSAPI to allocate + memory. This allows PSAPI to be called from any environment */ +void *PsaiMalloc(SIZE_T size); +void *PsaiRealloc(void *ptr, SIZE_T size); +void PsaiFree(void *ptr); + +/* MACROS */ +#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n" + +#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */ + +/* EOF */ diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h deleted file mode 100644 index 338e22c..0000000 --- a/include/freetype/config/ftconfig.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftconfig.h */ -/* */ -/* ANSI-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2000 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 header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `freetype/builds/', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ - /* */ - /* This ANSI version should stay in `include/freetype/config'. */ - /* */ - /*************************************************************************/ - - -#ifndef FTCONFIG_H -#define FTCONFIG_H - - - /* Include the header file containing all developer build options */ -#include - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - - /* We use values to know the sizes of the types. */ -#include - - /* The number of bytes in an `int' type. */ -#if UINT_MAX == 0xFFFFFFFF -#define FT_SIZEOF_INT 4 -#elif UINT_MAX == 0xFFFF -#define FT_SIZEOF_INT 2 -#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF -#define FT_SIZEOF_INT 8 -#else -#error "Unsupported number of bytes in `int' type!" -#endif - - /* The number of bytes in a `long' type. */ -#if ULONG_MAX == 0xFFFFFFFF -#define FT_SIZEOF_LONG 4 -#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF -#define FT_SIZEOF_LONG 8 -#else -#error "Unsupported number of bytes in `long' type!" -#endif - - - /* Preferred alignment of data */ -#define FT_ALIGNMENT 8 - - - /* UNUSED is a macro used to indicate that a given parameter is not used */ - /* -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* IntN types */ - /* */ - /* Used to guarantee the size of some specific integers. */ - /* */ - typedef signed short FT_Int16; - typedef unsigned short FT_UInt16; - -#if FT_SIZEOF_INT == 4 - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == 4 - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - -#if FT_SIZEOF_LONG == 8 - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long - -#else - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ - /* `ftoption.h'. */ - /* */ - /* Note that this will produce many -ansi warnings during library */ - /* compilation, and that in many cases, the generated code will be */ - /* neither smaller nor faster! */ - /* */ -#ifdef FTCALC_USE_LONG_LONG - -#define FT_LONG64 -#define FT_INT64 long long - -#endif /* FTCALC_USE_LONG_LONG */ -#endif /* FT_SIZEOF_LONG == 8 */ - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT -#define LOCAL_DEF static -#define LOCAL_FUNC static -#else -#define LOCAL_DEF extern -#define LOCAL_FUNC /* nothing */ -#endif - -#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT -#define BASE_DEF( x ) static x -#define BASE_FUNC( x ) static x -#else -#define BASE_DEF( x ) extern x -#define BASE_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_DEF -#define FT_EXPORT_DEF( x ) extern x -#endif - -#ifndef FT_EXPORT_FUNC -#define FT_EXPORT_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* FTCONFIG_H */ - - -/* END */ diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h deleted file mode 100644 index 50cc46b..0000000 --- a/include/freetype/config/ftmodule.h +++ /dev/null @@ -1,10 +0,0 @@ -FT_USE_MODULE(autohint_module_class) -FT_USE_MODULE(cff_driver_class) -FT_USE_MODULE(t1cid_driver_class) -FT_USE_MODULE(psnames_module_class) -FT_USE_MODULE(ft_raster1_renderer_class) -FT_USE_MODULE(sfnt_module_class) -FT_USE_MODULE(ft_smooth_renderer_class) -FT_USE_MODULE(tt_driver_class) -FT_USE_MODULE(t1_driver_class) -FT_USE_MODULE(winfnt_driver_class) diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h deleted file mode 100644 index a7e1f40..0000000 --- a/include/freetype/config/ftoption.h +++ /dev/null @@ -1,395 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2000 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 FTOPTION_H -#define FTOPTION_H - - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled by developers to enable or disable */ - /* certain aspects of FreeType. This is a default file, where all major */ - /* options are enabled. */ - /* */ - /* Note that if some modifications are required for your build, we */ - /* advise you to put a modified copy of this file in your build */ - /* directory, rather than modifying it in-place. */ - /* */ - /* The build directory is normally `freetype/builds/' and */ - /* contains build or system-specific files that are included in */ - /* priority when building the library. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Convenience functions support */ - /* */ - /* Some functions of the FreeType 2 API are provided as a convenience */ - /* for client applications and developers. However, they are not */ - /* required to build and run the library itself. */ - /* */ - /* By defining this configuration macro, you'll disable the */ - /* compilation of these functions at build time. This can be useful */ - /* to reduce the library's code size when you don't need any of */ - /* these functions. */ - /* */ - /* All convenience functions are declared as such in their */ - /* documentation. */ - /* */ -#undef FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS - - - /*************************************************************************/ - /* */ - /* Alternate Glyph Image Format support */ - /* */ - /* By default, the glyph images returned by the FreeType glyph loader */ - /* can either be a pixmap or a vectorial outline defined through */ - /* Bezier control points. When defining the following configuration */ - /* macro, some font drivers will be able to register alternate */ - /* glyph image formats. */ - /* */ - /* Unset this macro if you are sure that you will never use a font */ - /* driver with an alternate glyph format; this will reduce the size of */ - /* the base layer code. */ - /* */ - /* Note that a few Type 1 fonts, as well as Windows `vector' fonts */ - /* use a vector `plotter' format that isn't supported when this */ - /* macro is undefined. */ - /* */ -#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ - /* This module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro. Note that */ - /* this will produce many -ansi warnings during library compilation, and */ - /* that in many cases the generated code will not be smaller or faster! */ - /* */ -#undef FTCALC_USE_LONG_LONG - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT_DEF and FT_EXPORT_FUNC. */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_FUNC( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_FUNC( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT_DEF and */ - /* FT_EXPORT_FUNC here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ -#undef FT_EXPORT_DEF -#undef FT_EXPORT_FUNC - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ -#define FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* Computation Algorithms */ - /* */ - /* Used for debugging, this configuration macro should disappear */ - /* soon. */ - /* */ -#define FT_CONFIG_OPTION_OLD_CALCS - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4kByte. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384 - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 16 is the default. */ - /* */ -#define FT_MAX_MODULES 16 - - - /*************************************************************************/ - /* */ - /* FT_MAX_EXTENSIONS */ - /* */ - /* The maximum number of extensions that can be registered in a single */ - /* font driver. 8 is the default. */ - /* */ - /* If you don't know what this means, you certainly do not need to */ - /* change this value. */ - /* */ -#define FT_MAX_EXTENSIONS 8 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. Note that there are */ - /* important patent issues related to the use of the interpreter. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ -#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_STACK_DEPTH is the maximal depth of the token stack used by */ - /* the Type 1 parser (see t1load.c). A minimum of 16 is required. */ - /* */ -#define T1_MAX_STACK_DEPTH 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 8 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 32 - - - /*************************************************************************/ - /* */ - /* Define T1_CONFIG_OPTION_DISABLE_HINTER if you want to generate a */ - /* driver with no hinter. This can be useful to debug the parser. */ - /* */ -#undef T1_CONFIG_OPTION_DISABLE_HINTER - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - -#endif /* FTOPTION_H */ - - -/* END */ diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h deleted file mode 100644 index 29316c6..0000000 --- a/include/freetype/freetype.h +++ /dev/null @@ -1,2286 +0,0 @@ -/***************************************************************************/ -/* */ -/* freetype.h */ -/* */ -/* FreeType high-level API and common types (specification only). */ -/* */ -/* Copyright 1996-2000 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 -#define FREETYPE_H - - - /*************************************************************************/ - /* */ - /* The `raster' component duplicates some of the declarations in */ - /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ - /* */ -#define _FREETYPE_ - - - /*************************************************************************/ - /* */ - /* The FREETYPE_MAJOR and FREETYPE_MINOR macros are used to version the */ - /* new FreeType design, which is able to host several kinds of font */ - /* drivers. It starts at 2.0. */ - /* */ -#define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 0 - - -#include /* read configuration information */ -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S I C T Y P E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Metrics */ - /* */ - /* */ - /* A structure used to model the metrics of a single glyph. Note */ - /* that values are expressed in 26.6 fractional pixel format or in */ - /* font units, depending on context. */ - /* */ - /* */ - /* width :: The glyph's width. */ - /* */ - /* height :: The glyph's height. */ - /* */ - /* horiBearingX :: Horizontal left side bearing. */ - /* */ - /* horiBearingY :: Horizontal top side bearing. */ - /* */ - /* horiAdvance :: Horizontal advance width. */ - /* */ - /* vertBearingX :: Vertical left side bearing. */ - /* */ - /* vertBearingY :: Vertical top side bearing. */ - /* */ - /* vertAdvance :: Vertical advance height. */ - /* */ - typedef struct FT_Glyph_Metrics_ - { - FT_Pos width; /* glyph width */ - FT_Pos height; /* glyph height */ - - FT_Pos horiBearingX; /* left side bearing in horizontal layouts */ - FT_Pos horiBearingY; /* top side bearing in horizontal layouts */ - FT_Pos horiAdvance; /* advance width for horizontal layout */ - - FT_Pos vertBearingX; /* left side bearing in vertical layouts */ - FT_Pos vertBearingY; /* top side bearing in vertical layouts */ - FT_Pos vertAdvance; /* advance height for vertical layout */ - - } FT_Glyph_Metrics; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Generic_Finalizer */ - /* */ - /* */ - /* Describes a function used to destroy the `client' data of any */ - /* FreeType object. See the description of the FT_Generic type for */ - /* details of usage. */ - /* */ - /* */ - /* The address of the FreeType object which is under finalization. */ - /* Its client data is accessed through its `generic' field. */ - /* */ - typedef void (*FT_Generic_Finalizer)(void* object); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Generic */ - /* */ - /* */ - /* Client applications often need to associate their own data to a */ - /* variety of FreeType core objects. For example, a text layout API */ - /* might want to associate a glyph cache to a given size object. */ - /* */ - /* Most FreeType object contains a `generic' field, of type */ - /* FT_Generic, which usage is left to client applications and font */ - /* servers. */ - /* */ - /* It can be used to store a pointer to client-specific data, as well */ - /* as the address of a `finalizer' function, which will be called by */ - /* FreeType when the object is destroyed (for example, the previous */ - /* client example would put the address of the glyph cache destructor */ - /* in the `finalizer' field). */ - /* */ - /* */ - /* data :: A typeless pointer to any client-specified data. This */ - /* field is completely ignored by the FreeType library. */ - /* */ - /* finalizer :: A pointer to a `generic finalizer' function, which */ - /* will be called when the object is destroyed. If this */ - /* field is set to NULL, no code will be called. */ - /* */ - typedef struct FT_Generic_ - { - void* data; - FT_Generic_Finalizer finalizer; - - } FT_Generic; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bitmap_Size */ - /* */ - /* */ - /* An extremely simple structure used to model the size of a bitmap */ - /* strike (i.e., a bitmap instance of the font for a given */ - /* resolution) in a fixed-size font face. This is used for the */ - /* `available_sizes' field of the FT_Face_Properties structure. */ - /* */ - /* */ - /* height :: The character height in pixels. */ - /* */ - /* width :: The character width in pixels. */ - /* */ - typedef struct FT_Bitmap_Size_ - { - FT_Short height; - FT_Short width; - - } FT_Bitmap_Size; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* FT_Library */ - /* */ - /* */ - /* A handle to a FreeType library instance. Each `library' is */ - /* completely independent from the others; it is the `root' of a set */ - /* of objects like fonts, faces, sizes, etc. */ - /* */ - /* It also embeds a system object (see FT_System), as well as a */ - /* scan-line converter object (see FT_Raster). */ - /* */ - /* */ - /* Library objects are created through FT_Init_FreeType(). */ - /* */ - typedef struct FT_LibraryRec_ *FT_Library; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Module */ - /* */ - /* */ - /* A handle to a given FreeType module object. Each module can be a */ - /* font driver, a renderer, or anything else that provides services */ - /* to the formers. */ - /* */ - typedef struct FT_ModuleRec_* FT_Module; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Driver */ - /* */ - /* */ - /* A handle to a given FreeType font driver object. Each font driver */ - /* is able to create faces, sizes, glyph slots, and charmaps from the */ - /* resources whose format it supports. */ - /* */ - /* A driver can support either bitmap, graymap, or scalable font */ - /* formats. */ - /* */ - typedef struct FT_DriverRec_* FT_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Renderer */ - /* */ - /* */ - /* A handle to a given FreeType renderer. A renderer is in charge of */ - /* converting a glyph image to a bitmap, when necessary. Each */ - /* supports a given glyph image format, and one or more target */ - /* surface depths. */ - /* */ - typedef struct FT_RendererRec_* FT_Renderer; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Face */ - /* */ - /* */ - /* A handle to a given driver face object. A face object contains */ - /* all the instance and glyph independent data of a font file */ - /* typeface. */ - /* */ - /* A face object is created from a resource object through the */ - /* new_face() method of a given driver. */ - /* */ - typedef struct FT_FaceRec_* FT_Face; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Size */ - /* */ - /* */ - /* A handle to a given driver size object. Such an object models the */ - /* _resolution_ AND _size_ dependent state of a given driver face */ - /* size. */ - /* */ - /* A size object is always created from a given face object. It is */ - /* discarded automatically by its parent face. */ - /* */ - typedef struct FT_SizeRec_* FT_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphSlot */ - /* */ - /* */ - /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any of the glyphs contained within its parent */ - /* face. */ - /* */ - /* A glyph slot is created from a given face object. It is discarded */ - /* automatically by its parent face. */ - /* */ - typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_CharMap */ - /* */ - /* */ - /* A handle to a given character map. A charmap is used to translate */ - /* character codes in a given encoding into glyph indexes for its */ - /* parent's face. Some font formats may provide several charmaps per */ - /* font. */ - /* */ - /* A charmap is created from a given face object. It is discarded */ - /* automatically by its parent face. */ - /* */ - typedef struct FT_CharMapRec_* FT_CharMap; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Encoding */ - /* */ - /* */ - /* An enumeration used to specify encodings supported by charmaps. */ - /* Used in the FT_Select_CharMap() API function. */ - /* */ - /* */ - /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ - /* all character codes must be expressed as FT_Longs. */ - /* */ - typedef enum FT_Encoding_ - { - ft_encoding_none = 0, - ft_encoding_symbol = FT_MAKE_TAG( 's', 'y', 'm', 'b' ), - ft_encoding_unicode = FT_MAKE_TAG( 'u', 'n', 'i', 'c' ), - ft_encoding_latin_2 = FT_MAKE_TAG( 'l', 'a', 't', '2' ), - ft_encoding_sjis = FT_MAKE_TAG( 's', 'j', 'i', 's' ), - ft_encoding_gb2312 = FT_MAKE_TAG( 'g', 'b', ' ', ' ' ), - ft_encoding_big5 = FT_MAKE_TAG( 'b', 'i', 'g', '5' ), - ft_encoding_wansung = FT_MAKE_TAG( 'w', 'a', 'n', 's' ), - ft_encoding_johab = FT_MAKE_TAG( 'j', 'o', 'h', 'a' ), - - ft_encoding_adobe_standard = FT_MAKE_TAG( 'A', 'D', 'O', 'B' ), - ft_encoding_adobe_expert = FT_MAKE_TAG( 'A', 'D', 'B', 'E' ), - ft_encoding_adobe_custom = FT_MAKE_TAG( 'A', 'D', 'B', 'C' ), - - ft_encoding_apple_roman = FT_MAKE_TAG( 'a', 'r', 'm', 'n' ) - - /* other encodings might be defined in the future */ - - } FT_Encoding; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_CharMapRec */ - /* */ - /* */ - /* The base charmap class. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* flags :: A set of bit flags used to describe the charmap. */ - /* Each bit indicates that a given encoding is */ - /* supported. */ - /* */ - /* platform_id :: An ID number describing the platform for the */ - /* following encoding ID. This comes directly from */ - /* the TrueType specification and should be emulated */ - /* for other formats. */ - /* */ - /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and should be */ - /* emulated similarly. */ - /* */ - /* */ - /* We STRONGLY recommmend emulating a Unicode charmap for drivers */ - /* that do not support TrueType or OpenType. */ - /* */ - typedef struct FT_CharMapRec_ - { - FT_Face face; - FT_Encoding encoding; - FT_UShort platform_id; - FT_UShort encoding_id; - - } FT_CharMapRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S E O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* FreeType base face class */ - /* */ - /* */ - /* FT_FaceRec */ - /* */ - /* */ - /* FreeType root face class structure. A face object models the */ - /* resolution and point-size independent data found in a font file. */ - /* */ - /* */ - /* num_faces :: In the case where the face is located in a */ - /* collection (i.e., a resource which embeds */ - /* several faces), this is the total number of */ - /* faces found in the resource. 1 by default. */ - /* */ - /* face_index :: The index of the face in its resource. */ - /* Usually, this is 0 for all normal font */ - /* formats. It can be more in the case of */ - /* collections (which embed several fonts in a */ - /* single resource/file). */ - /* */ - /* face_flags :: A set of bit flags that give important */ - /* information about the face; see the */ - /* FT_FACE_FLAG_XXX macros for details. */ - /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face (i.e., italic, bold, underline, */ - /* etc). */ - /* */ - /* num_glyphs :: The total number of glyphs in the face. */ - /* */ - /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's family (like `Times New */ - /* Roman', `Bodoni', `Garamond', etc). This */ - /* is a least common denominator used to list */ - /* fonts. Some formats (TrueType & OpenType) */ - /* provide localized and Unicode versions of */ - /* this string. Applications should use the */ - /* format specific interface to access them. */ - /* */ - /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's style (like `Italic', */ - /* `Bold', `Condensed', etc). Not all font */ - /* formats provide a style name, so this field */ - /* is optional, and can be set to NULL. As */ - /* for `family_name', some formats provide */ - /* localized/Unicode versions of this string. */ - /* Applications should use the format specific */ - /* interface to access them. */ - /* */ - /* num_fixed_sizes :: The number of fixed sizes available in this */ - /* face. This should be set to 0 for scalable */ - /* fonts, unless its resource includes a */ - /* complete set of glyphs (called a `strike') */ - /* for the specified size. */ - /* */ - /* available_sizes :: An array of sizes specifying the available */ - /* bitmap/graymap sizes that are contained in */ - /* in the font resource. Should be set to */ - /* NULL if the field `num_fixed_sizes' is set */ - /* to 0. */ - /* */ - /* num_charmaps :: The total number of character maps in the */ - /* face. */ - /* */ - /* charmaps :: A table of pointers to the face's charmaps */ - /* Used to scan the list of available charmaps */ - /* this table might change after a call to */ - /* FT_Attach_File/Stream (e.g. when it used */ - /* to hook and additional encoding/CMap to */ - /* the face object). */ - /* */ - /* generic :: A field reserved for client uses. See the */ - /* FT_Generic type description. */ - /* */ - /* bbox :: The font bounding box. Coordinates are */ - /* expressed in font units (see units_per_EM). */ - /* The box is large enough to contain any */ - /* glyph from the font. Thus, bbox.yMax can */ - /* be seen as the `maximal ascender', */ - /* bbox.yMin as the `minimal descender', and */ - /* the maximal glyph width is given by */ - /* `bbox.xMax-bbox.xMin' (not to be confused */ - /* with the maximal _advance_width_). Only */ - /* relevant for scalable formats. */ - /* */ - /* units_per_EM :: The number of font units per EM square for */ - /* this face. This is typically 2048 for */ - /* TrueType fonts, 1000 for Type1 fonts, and */ - /* should be set to the (unrealistic) value 1 */ - /* for fixed-sizes fonts. Only relevant for */ - /* scalable formats. */ - /* */ - /* ascender :: The face's ascender is the vertical */ - /* distance from the baseline to the topmost */ - /* point of any glyph in the face. This */ - /* field's value is positive, expressed in */ - /* font units. Some font designs use a value */ - /* different from `bbox.yMax'. Only relevant */ - /* for scalable formats. */ - /* */ - /* descender :: The face's descender is the vertical */ - /* distance from the baseline to the */ - /* bottommost point of any glyph in the face. */ - /* This field's value is positive, expressed */ - /* in font units. Some font designs use a */ - /* value different from `-bbox.yMin'. Only */ - /* relevant for scalable formats. */ - /* */ - /* height :: The face's height is the vertical distance */ - /* from one baseline to the next when writing */ - /* several lines of text. Its value is always */ - /* positive, expressed in font units. The */ - /* value can be computed as */ - /* `ascender+descender+line_gap' where the */ - /* value of `line_gap' is also called */ - /* `external leading'. Only relevant for */ - /* scalable formats. */ - /* */ - /* max_advance_width :: The maximal advance width, in font units, */ - /* for all glyphs in this face. This can be */ - /* used to make word wrapping computations */ - /* faster. Only relevant for scalable */ - /* formats. */ - /* */ - /* max_advance_height :: The maximal advance height, in font units, */ - /* for all glyphs in this face. This is only */ - /* relevant for vertical layouts, and should */ - /* be set to the `height' for fonts that do */ - /* not provide vertical metrics. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It's the */ - /* center of the underlining stem. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_thickness :: The thickness, in font units, of the */ - /* underline for this face. Only relevant for */ - /* scalable formats. */ - /* */ - /* driver :: A handle to the face's parent driver */ - /* object. */ - /* */ - /* memory :: A handle to the face's parent memory */ - /* object. Used for the allocation of */ - /* subsequent objects. */ - /* */ - /* stream :: A handle to the face's stream. */ - /* */ - /* glyph :: The face's associated glyph slot(s). This */ - /* object is created automatically with a new */ - /* face object. However, certain kinds of */ - /* applications (mainly tools like converters) */ - /* can need more than one slot to ease their */ - /* task. */ - /* */ - /* sizes_list :: The list of child sizes for this face. */ - /* */ - /* max_points :: The maximal number of points used to store */ - /* the vectorial outline of any glyph in this */ - /* face. If this value cannot be known in */ - /* advance, or if the face isn't scalable, */ - /* this should be set to 0. Only relevant for */ - /* scalable formats. */ - /* */ - /* max_contours :: The maximal number of contours used to */ - /* store the vectorial outline of any glyph in */ - /* this face. If this value cannot be known */ - /* in advance, or if the face isn't scalable, */ - /* this should be set to 0. Only relevant for */ - /* scalable formats. */ - /* */ - /* transform_matrix :: A 2x2 matrix of 16.16 coefficients used */ - /* to transform glyph outlines after they are */ - /* loaded from the font. Only used by the */ - /* convenience functions. */ - /* */ - /* transform_delta :: A translation vector used to transform */ - /* glyph outlines after they are loaded from */ - /* the font. Only used by the convenience */ - /* functions. */ - /* */ - /* transform_flags :: Some flags used to classify the transform. */ - /* Only used by the convenience functions. */ - /* */ - typedef struct FT_FaceRec_ - { - FT_Long num_faces; - FT_Long face_index; - - FT_Long face_flags; - FT_Long style_flags; - - FT_Long num_glyphs; - - FT_String* family_name; - FT_String* style_name; - - FT_Int num_fixed_sizes; - FT_Bitmap_Size* available_sizes; - - /* the face's table of available charmaps */ - FT_Int num_charmaps; - FT_CharMap* charmaps; - - FT_Generic generic; - - /* the following are only relevant for scalable outlines */ - FT_BBox bbox; - - FT_UShort units_per_EM; - FT_Short ascender; - FT_Short descender; - FT_Short height; - - FT_Short max_advance_width; - FT_Short max_advance_height; - - FT_Short underline_position; - FT_Short underline_thickness; - - FT_GlyphSlot glyph; - FT_Size size; - - /************************************************************/ - /* The following fields should be considered private and */ - /* rarely, if ever, used directly by client applications. */ - - FT_Driver driver; - FT_Memory memory; - FT_Stream stream; - - FT_CharMap charmap; - FT_ListRec sizes_list; - - FT_Generic autohint; - void* extensions; - - FT_UShort max_points; - FT_Short max_contours; - - FT_Matrix transform_matrix; - FT_Vector transform_delta; - FT_Int transform_flags; - - } FT_FaceRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_SCALABLE */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face provides */ - /* vectorial outlines (i.e., TrueType or Type1). This doesn't */ - /* prevent embedding of bitmap strikes though, i.e., a given face can */ - /* have both this bit set, and a `num_fixed_sizes' property > 0. */ - /* */ -#define FT_FACE_FLAG_SCALABLE 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FIXED_SIZES */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* `fixed sizes', i.e., bitmap strikes for some given pixel sizes. */ - /* See the `num_fixed_sizes' and `available_sizes' face properties */ - /* for more information. */ - /* */ -#define FT_FACE_FLAG_FIXED_SIZES 2 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FIXED_WIDTH */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* fixed-width characters (like Courier, Lucida, MonoType, etc.). */ - /* */ -#define FT_FACE_FLAG_FIXED_WIDTH 4 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_SFNT */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face uses the */ - /* `sfnt' storage fomat. For now, this means TrueType or OpenType. */ - /* */ -#define FT_FACE_FLAG_SFNT 8 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_HORIZONTAL */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* horizontal glyph metrics. This should be set for all common */ - /* formats, but who knows. */ - /* */ -#define FT_FACE_FLAG_HORIZONTAL 0x10 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_VERTICAL */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* vertical glyph metrics. If not set, the glyph loader will */ - /* synthetize vertical metrics itself to help display vertical text */ - /* correctly. */ - /* */ -#define FT_FACE_FLAG_VERTICAL 0x20 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_KERNING */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* kerning information. When set, this information can be retrieved */ - /* through the function FT_Get_Kerning(). Note that when unset, this */ - /* function will always return the kerning vector (0,0). */ - /* */ -#define FT_FACE_FLAG_KERNING 0x40 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FAST_GLYPHS */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the glyphs in a given */ - /* font can be retrieved very quickly, and that a glyph cache is thus */ - /* not necessary for any of its child size objects. */ - /* */ - /* This flag should really be set for fixed-size formats like FNT, */ - /* where each glyph bitmap is available directly in binary form */ - /* without any kind of compression. */ - /* */ -#define FT_FACE_FLAG_FAST_GLYPHS 0x80 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the font contains */ - /* multiple masters and is capable of interpolating between them. */ - /* */ -#define FT_FACE_FLAG_MULTIPLE_MASTERS 0x100 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_GLYPH_NAMES */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the font contains */ - /* glyph names that can be retrieved through FT_Get_Glyph_Name(). */ - /* */ -#define FT_FACE_FLAG_GLYPH_NAMES 0x200 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* */ - /* */ - /* This bit field is used internally by FreeType to indicate that */ - /* a face's stream was provided by the client application and should */ - /* not be destroyed by FT_Done_Face(). */ - /* */ -#define FT_FACE_FLAG_EXTERNAL_STREAM 0x4000 - - -#define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) -#define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) -#define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) -#define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) -#define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) -#define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) -#define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) -#define FT_HAS_FAST_GLYPHS( face ) \ - ( face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) -#define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) - -#define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_STYLE_FLAG_ITALIC */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face is */ - /* italicized. */ - /* */ -#define FT_STYLE_FLAG_ITALIC 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_STYLE_FLAG_BOLD */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face is */ - /* emboldened. */ - /* */ -#define FT_STYLE_FLAG_BOLD 2 - - - /*************************************************************************/ - /* */ - /* FreeType base size metrics */ - /* */ - /* */ - /* FT_Size_Metrics */ - /* */ - /* */ - /* The size metrics structure returned scaled important distances for */ - /* a given size object. */ - /* */ - /* */ - /* x_ppem :: The character width, expressed in integer pixels. */ - /* This is the width of the EM square expressed in */ - /* pixels, hence the term `ppem' (pixels per EM). */ - /* */ - /* y_ppem :: The character height, expressed in integer pixels. */ - /* This is the height of the EM square expressed in */ - /* pixels, hence the term `ppem' (pixels per EM). */ - /* */ - /* x_scale :: A simple 16.16 fixed point format coefficient used */ - /* to scale horizontal distances expressed in font */ - /* units to fractional (26.6) pixel coordinates. */ - /* */ - /* y_scale :: A simple 16.16 fixed point format coefficient used */ - /* to scale vertical distances expressed in font */ - /* units to fractional (26.6) pixel coordinates. */ - /* */ - /* x_resolution :: The horizontal device resolution for this size */ - /* object, expressed in integer dots per inches */ - /* (dpi). As a convention, fixed font formats set */ - /* this value to 72. */ - /* */ - /* y_resolution :: The vertical device resolution for this size */ - /* object, expressed in integer dots per inches */ - /* (dpi). As a convention, fixed font formats set */ - /* this value to 72. */ - /* */ - /* ascender :: The ascender, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* descender :: The descender, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* height :: The text height, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* max_advance :: Maximum horizontal advance, expressed in 26.6 */ - /* fixed point pixels. Always positive. */ - /* */ - /* */ - /* The values of `ascender', `descender', and `height' are only the */ - /* scaled versions of `face->ascender', `face->descender', and */ - /* `face->height'. */ - /* */ - /* Unfortunately, due to glyph hinting, these values might not be */ - /* exact for certain fonts, they thus must be treated as unreliable */ - /* with an error margin of at least one pixel! */ - /* */ - /* Indeed, the only way to get the exact pixel ascender and descender */ - /* is to render _all_ glyphs. As this would be a definite */ - /* performance hit, it is up to client applications to perform such */ - /* computations. */ - /* */ - typedef struct FT_Size_Metrics_ - { - FT_UShort x_ppem; /* horizontal pixels per EM */ - FT_UShort y_ppem; /* vertical pixels per EM */ - - FT_Fixed x_scale; /* two scales used to convert font units */ - FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates.. */ - - FT_Pos ascender; /* ascender in 26.6 frac. pixels */ - FT_Pos descender; /* descender in 26.6 frac. pixels */ - FT_Pos height; /* text height in 26.6 frac. pixels */ - FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ - - } FT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* FreeType base size class */ - /* */ - /* */ - /* FT_SizeRec */ - /* */ - /* */ - /* FreeType root size class structure. A size object models the */ - /* resolution and pointsize dependent data of a given face. */ - /* */ - /* */ - /* face :: Handle to the parent face object. */ - /* */ - /* generic :: A typeless pointer, which is unused by the FreeType */ - /* library or any of its drivers. It can be used by */ - /* client applications to link their own data to each size */ - /* object. */ - /* */ - /* metrics :: Metrics for this size object. This field is read-only. */ - /* */ - typedef struct FT_SizeRec_ - { - FT_Face face; /* parent face object */ - FT_Generic generic; /* generic pointer for client uses */ - FT_Size_Metrics metrics; /* size metrics */ - - } FT_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_SubGlyph */ - /* */ - /* */ - /* The subglyph structure is an internal object used to describe */ - /* subglyphs (for example, in the case of composites). */ - /* */ - /* */ - /* The subglyph implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_SubGlyph_ FT_SubGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphLoader */ - /* */ - /* */ - /* The glyph loader is an internal object used to load several glyphs */ - /* together (for example, in the case of composites). */ - /* */ - /* */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoader_ FT_GlyphLoader; - - - /*************************************************************************/ - /* */ - /* FreeType Glyph Slot base class */ - /* */ - /* */ - /* FT_GlyphSlotRec */ - /* */ - /* */ - /* FreeType root glyph slot class structure. A glyph slot is a */ - /* container where individual glyphs can be loaded, be they */ - /* vectorial or bitmap/graymaps. */ - /* */ - /* */ - /* library :: A handle to the FreeType library instance */ - /* this slot belongs to. */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* next :: In some cases (like some font tools), several */ - /* glyph slots per face object can be a good */ - /* thing. As this is rare, the glyph slots are */ - /* listed through a direct, single-linked list */ - /* using its `next' field. */ - /* */ - /* generic :: A typeless pointer which is unused by the */ - /* FreeType library or any of its drivers. It */ - /* can be used by client applications to link */ - /* their own data to each size object. */ - /* */ - /* metrics :: The metrics of the last loaded glyph in the */ - /* slot. The returned values depend on the last */ - /* load flags (see the FT_Load_Glyph() API */ - /* function) and can be expressed either in 26.6 */ - /* fractional pixels or font units. */ - /* */ - /* Note that even when the glyph image is */ - /* transformed, the metrics are not. */ - /* */ - /* linearHoriAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled horizontal advance width */ - /* for the glyph (i.e. the scaled and unhinted */ - /* value of the hori advance). This can be */ - /* important to perform correct WYSIWYG layout */ - /* */ - /* Note that this value is expressed by default */ - /* in 16.16 pixels. However, when the glyph is */ - /* loaded with the FT_LOAD_UNSCALED_LINEAR flag, */ - /* this field contains simply the value of the */ - /* advance in original font units. */ - /* */ - /* linearVertAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled vertical advance height */ - /* for the glyph. See linearHoriAdvance for */ - /* comments. */ - /* */ - /* advance :: This is the transformed advance width for the */ - /* glyph. */ - /* */ - /* format :: This field indicates the format of the image */ - /* contained in the glyph slot. Typically */ - /* ft_glyph_format_bitmap, */ - /* ft_glyph_format_outline, and */ - /* ft_glyph_format_composite, but others are */ - /* possible. */ - /* */ - /* bitmap :: This field is used as a bitmap descriptor */ - /* when the slot format is */ - /* ft_glyph_format_bitmap. Note that the */ - /* address and content of the bitmap buffer can */ - /* change between calls of FT_Load_Glyph() and a */ - /* few other functions. */ - /* */ - /* bitmap_left :: This is the bitmap's left bearing expressed */ - /* in integer pixels. Of course, this is only */ - /* valid if the format is */ - /* ft_glyph_format_bitmap. */ - /* */ - /* bitmap_top :: This is the bitmap's top bearing expressed in */ - /* integer pixels. Remember that this is the */ - /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y-coordinates being */ - /* *positive*. */ - /* */ - /* outline :: The outline descriptor for the current glyph */ - /* image if its format is */ - /* ft_glyph_bitmap_outline. */ - /* */ - /* num_subglyphs :: The number of subglyphs in a composite glyph. */ - /* This format is only valid for the composite */ - /* glyph format, that should normally only be */ - /* loaded with the FT_LOAD_NO_RECURSE flag. */ - /* */ - /* subglyphs :: An array of subglyph descriptors for */ - /* composite glyphs. There are `num_subglyphs' */ - /* elements in there. */ - /* */ - /* control_data :: Certain font drivers can also return the */ - /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type 1 charstrings, etc.). */ - /* This field is a pointer to such data. */ - /* */ - /* control_len :: This is the length in bytes of the control */ - /* data. */ - /* */ - /* other :: Really wicked formats can use this pointer to */ - /* present their own glyph image to client apps. */ - /* Note that the app will need to know about the */ - /* image format. */ - /* */ - /* loader :: This is a private object for the glyph slot. */ - /* Do not touch this. */ - /* */ - /* */ - /* If FT_Load_Glyph() is called with default flags (FT_LOAD_DEFAULT), */ - /* the glyph image is loaded in the glyph slot in its native format */ - /* (e.g. a vectorial outline for TrueType and Type 1 formats). */ - /* */ - /* This image can later be converted into a bitmap by calling */ - /* FT_Render_Glyph(). This function finds the current renderer for */ - /* the native image's format then invokes it. */ - /* */ - /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then convert it into a */ - /* bitmap that is returned in `slot->bitmap'. */ - /* */ - /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ - /* to specify the position of the bitmap relative to the current pen */ - /* position (e.g. coordinates [0,0] on the baseline). Of course, */ - /* `slot->format' is also changed to `ft_glyph_format_bitmap' . */ - /* */ - typedef struct FT_GlyphSlotRec_ - { - FT_Library library; - FT_Face face; - FT_GlyphSlot next; - FT_UInt flags; - FT_Generic generic; - - FT_Glyph_Metrics metrics; - FT_Fixed linearHoriAdvance; - FT_Fixed linearVertAdvance; - FT_Vector advance; - - FT_Glyph_Format format; - - FT_Bitmap bitmap; - FT_Int bitmap_left; - FT_Int bitmap_top; - - FT_Outline outline; - - FT_UInt num_subglyphs; - FT_SubGlyph* subglyphs; - - void* control_data; - long control_len; - - void* other; - - /* private fields */ - FT_GlyphLoader* loader; - - } FT_GlyphSlotRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* F U N C T I O N S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Init_FreeType */ - /* */ - /* */ - /* Initializes a new FreeType library object. The set of drivers */ - /* that are registered by this function is determined at build time. */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Init_FreeType( FT_Library* library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_FreeType */ - /* */ - /* */ - /* Destroys a given FreeType library object and all of its childs, */ - /* including resources, drivers, faces, sizes, etc. */ - /* */ - /* */ - /* library :: A handle to the target library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_FreeType( FT_Library library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Flags */ - /* */ - /* */ - /* An enumeration used to list the bit flags used within */ - /* FT_Open_Args(). */ - /* */ - /* */ - /* ft_open_memory :: This is a memory-based stream. */ - /* */ - /* ft_open_stream :: Copy the stream from the `stream' field. */ - /* */ - /* ft_open_pathname :: Create a new input stream from a C pathname. */ - /* */ - /* ft_open_driver :: Use the `driver' field. */ - /* */ - /* ft_open_params :: Use the `num_params' & `params' field. */ - /* */ - typedef enum - { - ft_open_memory = 1, - ft_open_stream = 2, - ft_open_pathname = 4, - ft_open_driver = 8, - ft_open_params = 16 - - } FT_Open_Flags; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Parameter */ - /* */ - /* */ - /* A simple structure used to pass more or less generic parameters */ - /* to FT_Open_Face(). */ - /* */ - /* */ - /* tag :: A 4-byte identification tag. */ - /* */ - /* data :: A pointer to the parameter data. */ - /* */ - /* */ - /* The id and function of parameters are driver-specific. */ - /* */ - typedef struct FT_Parameter_ - { - FT_ULong tag; - FT_Pointer data; - - } FT_Parameter; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Args */ - /* */ - /* */ - /* A structure used to indicate how to open a new font file/stream. */ - /* A pointer to such a structure can be used as a parameter for the */ - /* functions FT_Open_Face() & FT_Attach_Stream(). */ - /* */ - /* */ - /* flags :: A set of bit flags indicating how to use the */ - /* structure. */ - /* */ - /* memory_base :: The first byte of the file in memory. */ - /* */ - /* memory_size :: The size in bytes of the file in memory. */ - /* */ - /* pathname :: A pointer to an 8-bit file pathname. */ - /* */ - /* stream :: A handle to a source stream object. */ - /* */ - /* driver :: This field is exclusively used by FT_Open_Face(); */ - /* it simply specifies the font driver to use to open */ - /* the face. If set to 0, FreeType will try to load */ - /* the face with each one of the drivers in its list. */ - /* */ - /* num_params :: The number of extra parameters. */ - /* */ - /* params :: Extra parameters passed to the font driver when */ - /* opening a new face. */ - /* */ - /* */ - /* `stream_type' determines which fields are used to create a new */ - /* input stream. */ - /* */ - /* If it is `ft_stream_memory', a new memory-based stream will be */ - /* created using the memory block specified by `memory_base' and */ - /* `memory_size'. */ - /* */ - /* If it is `ft_stream_pathname', a new stream will be created with */ - /* the `pathname' field, calling the system-specific FT_New_Stream() */ - /* function. */ - /* */ - /* If is is `ft_stream_copy', then the content of `stream' will be */ - /* copied to a new input stream object. The object will be closed */ - /* and destroyed when the face is destroyed itself. Note that this */ - /* means that you should not close the stream before the library */ - /* does! */ - /* */ - typedef struct FT_Open_Args_ - { - FT_Open_Flags flags; - FT_Byte* memory_base; - FT_Long memory_size; - FT_String* pathname; - FT_Stream stream; - FT_Module driver; - FT_Int num_params; - FT_Parameter* params; - - } FT_Open_Args; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a pathname to the font file. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* pathname :: A path to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Face( FT_Library library, - const char* filepathname, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a font file already loaded into memory. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* file_base :: A pointer to the beginning of the font data. */ - /* */ - /* file_size :: The size of the memory chunk used by the font data. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* face :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Memory_Face() can be used to determine and/or check the */ - /* font format of a given font resource. If the `face_index' field */ - /* is negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Memory_Face( FT_Library library, - FT_Byte* file_base, - FT_Long file_size, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Face */ - /* */ - /* */ - /* Opens a face object from a given resource and typeface index using */ - /* an `FT_Open_Args' structure. If the face object doesn't exist, it */ - /* will be created. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ - /* be filled by the caller. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_Open_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Open_Face( FT_Library library, - FT_Open_Args* args, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_File */ - /* */ - /* */ - /* `Attaches' a given font file to an existing face. This is usually */ - /* to read additional information for a single face object. For */ - /* example, it is used to read the AFM files that come with Type 1 */ - /* fonts in order to add kerning data and other metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* */ - /* filepathname :: An 8-bit pathname naming the `metrics' file. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If your font file is in memory, or if you want to provide your */ - /* own input stream object, use FT_Attach_Stream(). */ - /* */ - /* The meaning of the `attach' action (i.e., what really happens when */ - /* the new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Attach_File( FT_Face face, - const char* filepathname ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_Stream */ - /* */ - /* */ - /* This function is similar to FT_Attach_File() with the exception */ - /* that it reads the attachment from an arbitrary stream. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* parameters :: A pointer to an FT_Open_Args structure used to */ - /* describe the input stream to FreeType. */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The meaning of the `attach' (i.e. what really happens when the */ - /* new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Face */ - /* */ - /* */ - /* Discards a given face object, as well as all of its child slots */ - /* and sizes. */ - /* */ - /* */ - /* face :: A handle to a target face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_Face( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Char_Size */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The */ - /* `char_width' and `char_height' values are used for the width and */ - /* height, respectively, expressed in 26.6 fractional points. */ - /* */ - /* If the horizontal or vertical resolution values are zero, a */ - /* default value of 72dpi is used. Similarly, if one of the */ - /* character dimensions is zero, its value is set equal to the other. */ - /* */ - /* */ - /* size :: A handle to a target size object. */ - /* */ - /* */ - /* char_width :: The character width, in 26.6 fractional points. */ - /* */ - /* char_height :: The character height, in 26.6 fractional */ - /* points. */ - /* */ - /* horz_resolution :: The horizontal resolution. */ - /* */ - /* vert_resolution :: The vertical resolution. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* When dealing with fixed-size faces (i.e., non-scalable formats), */ - /* use the function FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Pixel_Sizes */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The width */ - /* and height are expressed in integer pixels. */ - /* */ - /* If one of the character dimensions is zero, its value is set equal */ - /* to the other. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* pixel_width :: The character width, in integer pixels. */ - /* */ - /* pixel_height :: The character height, in integer pixels. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* face :: A handle to the target face object where the glyph */ - /* will be loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform. */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Char */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size, according to its character code. */ - /* */ - /* */ - /* face :: A handle to a target face object where the glyph */ - /* will be loaded. */ - /* */ - /* char_code :: The glyph's character code, according to the */ - /* current charmap used in the face. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the face has no current charmap, or if the character code */ - /* is not defined in the charmap, this function will return an */ - /* error. */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform(). */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_SCALE */ - /* */ - /* */ - /* A bit field constant, used with FT_Load_Glyph() to indicate that */ - /* the vector outline being loaded should not be scaled to 26.6 */ - /* fractional pixels, but kept in notional units. */ - /* */ -#define FT_LOAD_NO_SCALE 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_HINTING */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the vector outline being loaded should not be fitted to the pixel */ - /* grid but simply scaled to 26.6 fractional pixels. */ - /* */ - /* This flag is ignored if FT_LOAD_NO_SCALE is set. */ - /* */ -#define FT_LOAD_NO_HINTING 2 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_RENDER */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should load the glyph and immediately convert it into */ - /* a bitmap, if necessary, by calling FT_Render_Glyph(). */ - /* */ - /* Note that by default, FT_Load_Glyph() loads the glyph image in its */ - /* native format. */ - /* */ -#define FT_LOAD_RENDER 4 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_BITMAP */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should not load the bitmap or pixmap of a given */ - /* glyph. This is useful when you do not want to load the embedded */ - /* bitmaps of scalable formats, as the native glyph image will be */ - /* loaded, and can then be rendered through FT_Render_Glyph(). */ - /* */ -#define FT_LOAD_NO_BITMAP 8 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_VERTICAL_LAYOUT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph image should be prepared for vertical layout. This */ - /* basically means that `face.glyph.advance' will correspond to the */ - /* vertical advance height (instead of the default horizontal */ - /* advance width), and that the glyph image will translated to match */ - /* the vertical bearings positions. */ - /* */ -#define FT_LOAD_VERTICAL_LAYOUT 16 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_FORCE_AUTOHINT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should try to auto-hint the glyphs, even if a driver */ - /* specific hinter is available. */ - /* */ -#define FT_LOAD_FORCE_AUTOHINT 32 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_CROP_BITMAP */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the font driver should try to crop the bitmap (i.e. remove all */ - /* space around its black bits) when loading it. For now, this */ - /* really only works with embedded bitmaps in TrueType fonts. */ - /* */ -#define FT_LOAD_CROP_BITMAP 64 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_PEDANTIC */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should perform a pedantic bytecode */ - /* interpretation. Many popular fonts come with broken glyph */ - /* programs. When this flag is set, loading them will return an */ - /* error. Otherwise, errors are ignored by the loader, sometimes */ - /* resulting in ugly glyphs. */ - /* */ -#define FT_LOAD_PEDANTIC 128 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should ignore the global advance width defined */ - /* in the font. As far as we know, this is only used by the */ - /* X-TrueType font server, in order to deal correctly with the */ - /* incorrect metrics contained in DynaLab's TrueType CJK fonts. */ - /* */ -#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 512 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_RECURSE */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should not load composite glyph recursively. */ - /* Rather, when a composite glyph is encountered, it should set */ - /* the values of `num_subglyphs' and `subglyphs', as well as set */ - /* `face->glyph.format' to ft_glyph_format_composite. */ - /* */ - /* This is for use by the auto-hinter and possibly other tools. */ - /* For nearly all applications, this flags should be left unset */ - /* when invoking FT_Load_Glyph(). */ - /* */ - /* Note that the flag forces the load of unscaled glyphs. */ - /* */ -#define FT_LOAD_NO_RECURSE 1024 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_IGNORE_TRANSFORM */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should not try to transform the loaded glyph */ - /* image. */ - /* */ -#define FT_LOAD_IGNORE_TRANSFORM 2048 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_MONOCHROME */ - /* */ - /* */ - /* Only used with FT_LOAD_RENDER set, it indicates that the returned */ - /* glyph image should be 1-bit monochrome. This really tells the */ - /* glyph loader to use `ft_render_mode_mono' when calling */ - /* FT_Render_Glyph(). */ - /* */ -#define FT_LOAD_MONOCHROME 4096 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_LINEAR_DESIGN */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should return the linearly scaled metrics expressed */ - /* in original font units, instead of the default 16.16 pixel values. */ - /* */ -#define FT_LOAD_LINEAR_DESIGN 8192 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_DEFAULT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should try to load the glyph normally, i.e., */ - /* embedded bitmaps are favored over outlines, vectors are always */ - /* scaled and grid-fitted. */ - /* */ -#define FT_LOAD_DEFAULT 0 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Transform */ - /* */ - /* */ - /* A function used to set the transformation that is applied to glyph */ - /* images just before they are converted to bitmaps in a glyph slot */ - /* when FT_Render_Glyph() is called. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ - /* vector. */ - /* */ - /* */ - /* The transformation is only applied to scalable image formats after */ - /* the glyph has been loaded. It means that hinting is unaltered by */ - /* the transformation and is performed on the character size given in */ - /* the last call to FT_Set_Char_Sizes() or FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_DEF( void ) FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Render_Mode */ - /* */ - /* */ - /* An enumeration type that lists the render modes supported by the */ - /* FreeType 2 renderer(s). A renderer is in charge of converting a */ - /* glyph image into a bitmap. */ - /* */ - /* */ - /* ft_render_mode_normal :: This is the default render mode; it */ - /* corresponds to 8-bit anti-aliased */ - /* bitmaps, using 256 levels of gray. */ - /* */ - /* ft_render_mode_mono :: This render mode is used to produce 1-bit */ - /* monochrome bitmaps. */ - /* */ - /* */ - /* There is no render mode to produce 8-bit `monochrome' bitmaps -- */ - /* you have to make the conversion yourself if you need such things */ - /* (besides, FreeType is not a graphics library). */ - /* */ - /* More modes might appear later for specific display modes (e.g. TV, */ - /* LCDs, etc.). They will be supported through the simple addition */ - /* of a renderer module, with no changes to the rest of the engine. */ - /* */ - typedef enum FT_Render_Mode_ - { - ft_render_mode_normal = 0, - ft_render_mode_mono = 1 - - } FT_Render_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Render_Glyph */ - /* */ - /* */ - /* Converts a given glyph image to a bitmap. It does so by */ - /* inspecting the glyph image format, find the relevant renderer, and */ - /* invoke it. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot containing the image to */ - /* convert. */ - /* */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See FT_Render_Mode for a list */ - /* of possible values. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, - FT_UInt render_mode ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Kerning_Mode */ - /* */ - /* */ - /* An enumeration used to specify which kerning values to return in */ - /* FT_Get_Kerning(). */ - /* */ - /* */ - /* ft_kerning_default :: Return scaled and grid-fitted kerning */ - /* distances (value is 0). */ - /* */ - /* ft_kerning_unfitted :: Return scaled but un-grid-fitted kerning */ - /* distances. */ - /* */ - /* ft_kerning_unscaled :: Return the kerning vector in original font */ - /* units. */ - /* */ - typedef enum FT_Kerning_Mode_ - { - ft_kerning_default = 0, - ft_kerning_unfitted, - ft_kerning_unscaled - - } FT_Kerning_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Kerning */ - /* */ - /* */ - /* Returns the kerning vector between two glyphs of a same face. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* kern_mode :: See FT_Kerning_Mode() for more information. */ - /* Determines the scale/dimension of the returned */ - /* kerning vector. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings, are out of the scope of this API function -- they can be */ - /* implemented through format-specific interfaces. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector* kerning ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph_Name */ - /* */ - /* */ - /* Retrieves the ASCII name of a given glyph in a face. This only */ - /* works for those faces where FT_HAS_GLYPH_NAME(face) returns true. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* buffer :: A pointer to a target buffer where the name will be */ - /* copied to. */ - /* */ - /* buffer_max :: The maximal number of bytes available in the */ - /* buffer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error is returned if the face doesn't provide glyph names or if */ - /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' will be set to 0 to indicate an empty name. */ - /* */ - /* The glyph name is truncated to fit within the buffer if it is too */ - /* long. The returned string is always zero-terminated. */ - /* */ - /* This function is not compiled within the library if the config */ - /* macro FT_CONFIG_OPTION_NO_GLYPH_NAMES is defined in */ - /* `include/freetype/config/ftoptions.h' */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Select_Charmap */ - /* */ - /* */ - /* Selects a given charmap by its encoding tag (as listed in */ - /* `freetype.h'). */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* encoding :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if no charmap in the face */ - /* corresponds to the encoding queried here. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Charmap */ - /* */ - /* */ - /* Selects a given charmap for character code to glyph index */ - /* decoding. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* charmap :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if the charmap is not part of */ - /* the face (i.e., if it is not listed in the face->charmaps[] */ - /* table). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Char_Index */ - /* */ - /* */ - /* Returns the glyph index of a given character code. This function */ - /* uses a charmap object to do the translation. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* */ - /* The glyph index. 0 means `undefined character code'. */ - /* */ - FT_EXPORT_DEF( FT_UInt ) FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulDiv */ - /* */ - /* */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximal accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* */ - /* This function has been optimized for the case where the absolute */ - /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ - /* As this happens mainly when scaling from notional units to */ - /* fractional pixels in FreeType, it resulted in noticeable speed */ - /* improvements between versions 2.x and 1.x. */ - /* */ - /* As a conclusion, always try to place a 16.16 factor as the */ - /* _second_ argument of this function; this can make a great */ - /* difference. */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_MulFix( FT_Long a, - FT_Long b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DivFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*0x10000)/b'. */ - /* */ - /* */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ - /* 32 bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of the old FT_MulDiv64(). */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_DivFix( FT_Long a, - FT_Long b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vec, - FT_Matrix* matrix ); - - - -#ifdef __cplusplus - } -#endif - - -#endif /* FREETYPE_H */ - - -/* END */ diff --git a/include/freetype/ftbbox.h b/include/freetype/ftbbox.h deleted file mode 100644 index e144664..0000000 --- a/include/freetype/ftbbox.h +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbbox.h */ -/* */ -/* FreeType bbox computation (specification). */ -/* */ -/* Copyright 1996-2000 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 has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /* It is separated from the rest of the engine for various technical */ - /* reasons. It may well be integrated in `ftoutln' later. */ - /* */ - /*************************************************************************/ - - -#ifndef FTBBOX_H -#define FTBBOX_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_GetBBox */ - /* */ - /* */ - /* Computes the exact bounding box of an outline. This is slower */ - /* than computing the control box. However, it uses an advanced */ - /* algorithm which returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bezier arcs are walked over to */ - /* extract their extrema. */ - /* */ - /* */ - /* outline :: A pointer to the source outline. */ - /* */ - /* */ - /* bbox :: The outline's exact bounding box. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - FT_EXPORT_DEF(FT_Error) FT_Raster_GetBBox( FT_Outline* outline, - FT_BBox* abbox ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTBBOX_H */ - - -/* END */ diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h deleted file mode 100644 index 9fb8099..0000000 --- a/include/freetype/fterrors.h +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 1996-2000 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 define the FreeType error enumeration constants */ - /* It can also be used to create an error message table easily with */ - /* something like: */ - /* */ - /* { */ - /* #undef FTERRORS_H */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, 0 } }; */ - /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg */ - /* } ft_errors[] = */ - /* */ - /* #include */ - /* } */ - /* */ - /*************************************************************************/ - - -#ifndef FTERRORS_H -#define FTERRORS_H - - -#ifndef FT_ERRORDEF - -#define FT_ERRORDEF( e, v, s ) e = v, -#define FT_ERROR_START_LIST enum { -#define FT_ERROR_END_LIST FT_Err_Max }; - -#endif /* !FT_ERRORDEF */ - - -#ifdef FT_ERROR_START_LIST - FT_ERROR_START_LIST -#endif - - FT_ERRORDEF( FT_Err_Ok, 0x0000, \ - "no error" ) - FT_ERRORDEF( FT_Err_Cannot_Open_Resource, 0x0001, \ - "can't open stream" ) - FT_ERRORDEF( FT_Err_Unknown_File_Format, 0x0002, \ - "unknown file format" ) - FT_ERRORDEF( FT_Err_Invalid_File_Format, 0x0003, \ - "broken file" ) - - FT_ERRORDEF( FT_Err_Invalid_Argument, 0x0010, \ - "invalid argument" ) - FT_ERRORDEF( FT_Err_Invalid_Handle, 0x0011, \ - "invalid object handle" ) - FT_ERRORDEF( FT_Err_Invalid_Glyph_Index, 0x0012, \ - "invalid glyph index" ) - FT_ERRORDEF( FT_Err_Invalid_Character_Code, 0x0013, \ - "invalid character code" ) - - FT_ERRORDEF( FT_Err_Unimplemented_Feature, 0x0020, \ - "unimplemented feature" ) - FT_ERRORDEF( FT_Err_Invalid_Glyph_Format, 0x0021, \ - "unsupported glyph image format" ) - FT_ERRORDEF( FT_Err_Cannot_Render_Glyph, 0x0022, \ - "cannot render this glyph format" ) - - FT_ERRORDEF( FT_Err_Invalid_Library_Handle, 0x0030, \ - "invalid library handle" ) - FT_ERRORDEF( FT_Err_Invalid_Driver_Handle, 0x0031, \ - "invalid module handle" ) - FT_ERRORDEF( FT_Err_Invalid_Face_Handle, 0x0032, \ - "invalid face handle" ) - FT_ERRORDEF( FT_Err_Invalid_Size_Handle, 0x0033, \ - "invalid size handle" ) - FT_ERRORDEF( FT_Err_Invalid_Slot_Handle, 0x0034, \ - "invalid glyph slot handle" ) - FT_ERRORDEF( FT_Err_Invalid_CharMap_Handle, 0x0035, \ - "invalid charmap handle" ) - FT_ERRORDEF( FT_Err_Invalid_Outline, 0x0036, \ - "invalid outline" ) - FT_ERRORDEF( FT_Err_Invalid_Version, 0x0037, \ - "invalid FreeType version" ) - FT_ERRORDEF( FT_Err_Lower_Module_Version, 0x0038, \ - "module version is too low" ) - - FT_ERRORDEF( FT_Err_Too_Many_Drivers, 0x0040, \ - "too many modules" ) - FT_ERRORDEF( FT_Err_Too_Many_Extensions, 0x0041, \ - "too many extensions" ) - - FT_ERRORDEF( FT_Err_Out_Of_Memory, 0x0050, \ - "out of memory" ) - FT_ERRORDEF( FT_Err_Unlisted_Object, 0x0051, \ - "unlisted object" ) - - FT_ERRORDEF( FT_Err_Invalid_Stream_Handle, 0x0060, \ - "invalid stream handle" ) - FT_ERRORDEF( FT_Err_Cannot_Open_Stream, 0x0061, \ - "cannot open stream" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Seek, 0x0062, \ - "invalid stream seek" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Skip, 0x0063, \ - "invalid stream skip" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Read, 0x0064, \ - "invalid stream read" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Operation, 0x0065, \ - "invalid stream operation" ) - FT_ERRORDEF( FT_Err_Invalid_Frame_Operation, 0x0066, \ - "invalid frame operation" ) - FT_ERRORDEF( FT_Err_Nested_Frame_Access, 0x0067, \ - "nested frame access" ) - FT_ERRORDEF( FT_Err_Invalid_Frame_Read, 0x0068, \ - "invalid frame read" ) - - FT_ERRORDEF( FT_Err_Invalid_Composite, 0x0070, \ - "invalid composite glyph" ) - FT_ERRORDEF( FT_Err_Too_Many_Hints, 0x0071, \ - "too many hints" ) - - FT_ERRORDEF( FT_Err_Raster_Uninitialized, 0x0080, \ - "raster uninitialized" ) - FT_ERRORDEF( FT_Err_Raster_Corrupted, 0x0081, \ - "raster corrupted" ) - FT_ERRORDEF( FT_Err_Raster_Overflow, 0x0082, \ - "raster overflow" ) - FT_ERRORDEF( FT_Err_Raster_Negative_Height, 0x0083, \ - "negative height while rastering" ) - - /* range 0x400 - 0x4FF is reserved for TrueType specific stuff */ - - /* range 0x500 - 0x5FF is reserved for CFF specific stuff */ - - /* range 0x600 - 0x6FF is reserved for Type1 specific stuff */ - -#ifdef FT_ERROR_END_LIST - FT_ERROR_END_LIST -#endif - - -#undef FT_ERROR_START_LIST -#undef FT_ERROR_END_LIST -#undef FT_ERRORDEF - - -#endif /* FTERRORS_H */ - - -/* END */ diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h deleted file mode 100644 index 0647c88..0000000 --- a/include/freetype/ftglyph.h +++ /dev/null @@ -1,422 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.h */ -/* */ -/* FreeType convenience functions to handle glyphs (specification). */ -/* */ -/* Copyright 1996-2000 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 contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#ifndef FTGLYPH_H -#define FTGLYPH_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - /* forward declaration to a private type */ - typedef struct FT_Glyph_Class_ FT_Glyph_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphRec */ - /* */ - /* */ - /* The root glyph structure contains a given glyph image plus its */ - /* advance width in 16.16 fixed float format. */ - /* */ - /* */ - /* library :: A handle to the FreeType library object. */ - /* */ - /* clazz :: A pointer to the glyph's class. Private. */ - /* */ - /* format :: The format of the glyph's image. */ - /* */ - /* advance :: A 16.16 vector that gives the glyph's advance width. */ - /* */ - typedef struct FT_GlyphRec_ - { - FT_Library library; - const FT_Glyph_Class* clazz; - FT_Glyph_Format format; - FT_Vector advance; - - } FT_GlyphRec, *FT_Glyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_BitmapGlyphRec */ - /* */ - /* */ - /* A structure used for bitmap glyph images. This really is a */ - /* `sub-class' of `FT_GlyphRec'. */ - /* */ - /* */ - /* root :: The root FT_Glyph fields. */ - /* */ - /* left :: The left-side bearing, i.e., the horizontal distance */ - /* from the current pen position to the left border of the */ - /* glyph bitmap. */ - /* */ - /* top :: The top-side bearing, i.e., the vertical distance from */ - /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards-y! */ - /* */ - /* bitmap :: A descriptor for the bitmap. */ - /* */ - /* */ - /* You can typecast FT_Glyph to FT_BitmapGlyph if you have */ - /* glyph->format == ft_glyph_format_bitmap. This lets you access */ - /* the bitmap's contents easily. */ - /* */ - /* The corresponding pixel buffer is always owned by the BitmapGlyph */ - /* and is thus created and destroyed with it. */ - /* */ - typedef struct FT_BitmapGlyphRec_ - { - FT_GlyphRec root; - FT_Int left; - FT_Int top; - FT_Bitmap bitmap; - - } FT_BitmapGlyphRec, *FT_BitmapGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_OutlineGlyphRec */ - /* */ - /* */ - /* A structure used for outline (vectorial) glyph images. This */ - /* really is a `sub-class' of `FT_GlyphRec'. */ - /* */ - /* */ - /* root :: The root FT_Glyph fields. */ - /* */ - /* outline :: A descriptor for the outline. */ - /* */ - /* */ - /* You can typecast FT_Glyph to FT_OutlineGlyph if you have */ - /* glyph->format == ft_glyph_format_outline. This lets you access */ - /* the outline's content easily. */ - /* */ - /* As the outline is extracted from a glyph slot, its coordinates are */ - /* expressed normally in 26.6 pixels, unless the flag */ - /* FT_LOAD_NO_SCALE was used in FT_Load_Glyph() or FT_Load_Char(). */ - /* */ - /* The outline's tables are always owned by the object and are */ - /* destroyed with it. */ - /* */ - typedef struct FT_OutlineGlyphRec_ - { - FT_GlyphRec root; - FT_Outline outline; - - } FT_OutlineGlyphRec, *FT_OutlineGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph */ - /* */ - /* */ - /* A function used to extract a glyph image from a slot. */ - /* */ - /* */ - /* slot :: A handle to the source glyph slot. */ - /* */ - /* */ - /* aglyph :: A handle to the glyph object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph* aglyph ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Copy */ - /* */ - /* */ - /* A function used to copy a glyph image. */ - /* */ - /* */ - /* source :: A handle to the source glyph object. */ - /* */ - /* */ - /* target :: A handle to the target glyph object. 0 in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_Copy( FT_Glyph source, - FT_Glyph* target ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Transform */ - /* */ - /* */ - /* Transforms a glyph image if its format is scalable. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - /* matrix :: A pointer to a 2x2 matrix to apply. */ - /* */ - /* delta :: A pointer to a 2d vector to apply. Coordinates are */ - /* expressed in 1/64th of a pixel. */ - /* */ - /* */ - /* FreeType error code (the glyph format is not scalable if it is */ - /* not zero). */ - /* */ - /* */ - /* The 2x2 transformation matrix is also applied to the glyph's */ - /* advance vector. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); - - - enum - { - ft_glyph_bbox_pixels = 0, - ft_glyph_bbox_subpixels = 1, - ft_glyph_bbox_gridfit = 2 - }; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Get_CBox */ - /* */ - /* */ - /* Returns the glyph image's bounding box. */ - /* */ - /* */ - /* glyph :: A handle to the source glyph object. */ - /* */ - /* mode :: A set of bit flags that indicate how to interpret the */ - /* returned bounding box values. */ - /* */ - /* */ - /* box :: The glyph bounding box. Coordinates are expressed in */ - /* 1/64th of pixels if it is grid-fitted. */ - /* */ - /* */ - /* Coordinates are relative to the glyph origin, using the Y-upwards */ - /* convention. */ - /* */ - /* If `ft_glyph_bbox_subpixels' is set in `mode', the bbox */ - /* coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). */ - /* Otherwise, coordinates are expressed in integer pixels. */ - /* */ - /* Note that the maximum coordinates are exclusive, which means that */ - /* one can compute the width and height of the glyph image (be it in */ - /* integer or 26.6 pixels) as: */ - /* */ - /* width = bbox.xMax - bbox.xMin; */ - /* height = bbox.yMax - bbox.yMin; */ - /* */ - /* Note also that for 26.6 coordinates, if the */ - /* `ft_glyph_bbox_gridfit' flag is set in `mode;, the coordinates */ - /* will also be grid-fitted, which corresponds to: */ - /* */ - /* bbox.xMin = FLOOR(bbox.xMin); */ - /* bbox.yMin = FLOOR(bbox.yMin); */ - /* bbox.xMax = CEILING(bbox.xMax); */ - /* bbox.yMax = CEILING(bbox.yMax); */ - /* */ - /* The default value (0) for `bbox_mode' is `ft_glyph_bbox_pixels'. */ - /* */ - FT_EXPORT_DEF( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox* cbox ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_To_Bitmap */ - /* */ - /* */ - /* Converts a given glyph object to a bitmap glyph object. */ - /* */ - /* */ - /* glyph :: A pointer to a handle to the target glyph. */ - /* */ - /* */ - /* render_mode :: A set of bit flags that describe how the data is */ - /* */ - /* */ - /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be 0 (if no */ - /* translation). The origin is expressed in */ - /* 26.6 pixels. */ - /* */ - /* destroy :: A boolean that indicates that the original glyph */ - /* image should be destroyed by this function. It is */ - /* never destroyed in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The glyph image is translated with the `origin' vector before */ - /* rendering. In case of error, it it translated back to its */ - /* original position and the glyph is left untouched. */ - /* */ - /* The first parameter is a pointer to a FT_Glyph handle, that will */ - /* be replaced by this function. Typically, you would use (omitting */ - /* error handling): */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyph; */ - /* FT_BitmapGlyph glyph_bitmap; */ - /* */ - /* */ - /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ - /* */ - /* // extract glyph image */ - /* error = FT_Get_Glyph( face->glyph, &glyph ); */ - /* */ - /* // convert to a bitmap (default render mode + destroy old) */ - /* if ( glyph->format != ft_glyph_format_bitmap ) */ - /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_default, */ - /* 0, 1 ); */ - /* if ( error ) // glyph unchanged */ - /* ... */ - /* } */ - /* */ - /* // access bitmap content by typecasting */ - /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ - /* */ - /* // do funny stuff with it, like blitting/drawing */ - /* ... */ - /* */ - /* // discard glyph image (bitmap or not) */ - /* FT_Done_Glyph( glyph ); */ - /* } */ - /* */ - /* */ - /* This function will always fail if the glyph's format isn't */ - /* scalable. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_ULong render_mode, - FT_Vector* origin, - FT_Bool destroy ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Glyph */ - /* */ - /* */ - /* Destroys a given glyph. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - FT_EXPORT_DEF( void ) FT_Done_Glyph( FT_Glyph glyph ); - - - /* other helpful functions */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Multiply */ - /* */ - /* */ - /* Performs the matrix operation `b = a*b'. */ - /* */ - /* */ - /* a :: A pointer to matrix `a'. */ - /* */ - /* */ - /* b :: A pointer to matrix `b'. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `a' or `b' is zero. */ - /* */ - FT_EXPORT_DEF( void ) FT_Matrix_Multiply( FT_Matrix* a, - FT_Matrix* b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Invert */ - /* */ - /* */ - /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ - /* */ - /* */ - /* matrix :: A pointer to the target matrix. Remains untouched in */ - /* case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTGLYPH_H */ - - -/* END */ diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h deleted file mode 100644 index 4dd1c3d..0000000 --- a/include/freetype/ftimage.h +++ /dev/null @@ -1,1003 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2000 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: A `raster' is simply a scan-line converter, used to render */ - /* FT_Outlines into FT_Bitmaps. */ - /* */ - /*************************************************************************/ - - -#ifndef FTIMAGE_H -#define FTIMAGE_H - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pos */ - /* */ - /* */ - /* The type FT_Pos is a 32-bit integer used to store vectorial */ - /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 26.6 fixed float pixel */ - /* coordinates. */ - /* */ - typedef signed long FT_Pos; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector */ - /* */ - /* */ - /* A simple structure used to store a 2D vector; coordinates are of */ - /* the FT_Pos type. */ - /* */ - /* */ - /* x :: The horizontal coordinate. */ - /* y :: The vertical coordinate. */ - /* */ - typedef struct FT_Vector_ - { - FT_Pos x; - FT_Pos y; - - } FT_Vector; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pixel_Mode */ - /* */ - /* */ - /* An enumeration type used to describe the format of pixels in a */ - /* given bitmap. Note that additional formats may be added in the */ - /* future. */ - /* */ - /* */ - /* ft_pixel_mode_mono :: A monochrome bitmap (1 bit/pixel). */ - /* */ - /* ft_pixel_mode_grays :: An 8-bit gray-levels bitmap. Note that the */ - /* total number of gray levels is given in the */ - /* `num_grays' field of the FT_Bitmap */ - /* structure. */ - /* */ - /* ft_pixel_mode_pal2 :: A 2-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_pal4 :: A 4-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_pal8 :: An 8-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb15 :: A 15-bit RGB bitmap. Uses 5:5:5 encoding. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb16 :: A 16-bit RGB bitmap. Uses 5:6:5 encoding. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb24 :: A 24-bit RGB bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb32 :: A 32-bit RGB bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* */ - /* Some anti-aliased bitmaps might be embedded in TrueType fonts */ - /* using formats pal2 or pal4, though no fonts presenting those have */ - /* been found to date. */ - /* */ - typedef enum FT_Pixel_Mode_ - { - ft_pixel_mode_none = 0, - ft_pixel_mode_mono, - ft_pixel_mode_grays, - ft_pixel_mode_pal2, - ft_pixel_mode_pal4, - ft_pixel_mode_pal8, - ft_pixel_mode_rgb15, - ft_pixel_mode_rgb16, - ft_pixel_mode_rgb24, - ft_pixel_mode_rgb32, - - ft_pixel_mode_max /* do not remove */ - - } FT_Pixel_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Palette_Mode */ - /* */ - /* */ - /* An enumeration type used to describe the format of a bitmap */ - /* palette, used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ - /* */ - /* */ - /* ft_palette_mode_rgb :: The palette is an array of 3-bytes RGB */ - /* records. */ - /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-bytes RGBA */ - /* records. */ - /* */ - /* */ - /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ - /* FreeType, these types are not handled by the library itself. */ - /* */ - typedef enum FT_Palette_Mode_ - { - ft_palette_mode_rgb = 0, - ft_palette_mode_rgba, - - ft_palettte_mode_max /* do not remove */ - - } FT_Palette_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bitmap */ - /* */ - /* */ - /* A structure used to describe a bitmap or pixmap to the raster. */ - /* Note that we now manage pixmaps of various depths through the */ - /* `pixel_mode' field. */ - /* */ - /* */ - /* rows :: The number of bitmap rows. */ - /* */ - /* width :: The number of pixels in bitmap row. */ - /* */ - /* pitch :: The pitch's absolute value is the number of bytes */ - /* taken by one bitmap row, including padding. */ - /* However, the pitch is positive when the bitmap has */ - /* a `down' flow, and negative when it has an `up' */ - /* flow. In all cases, the pitch is an offset to add */ - /* to a bitmap pointer in order to go down one row. */ - /* */ - /* buffer :: A typeless pointer to the bitmap buffer. This */ - /* value should be aligned on 32-bit boundaries in */ - /* most cases. */ - /* */ - /* num_grays :: This field is only used with */ - /* `ft_pixel_mode_grays'; it gives the number of gray */ - /* levels used in the bitmap. */ - /* */ - /* pixel_mode :: The pixel_mode, i.e., how pixel bits are stored. */ - /* */ - /* palette_mode :: This field is only used with paletted pixel modes; */ - /* it indicates how the palette is stored. */ - /* */ - /* palette :: A typeless pointer to the bitmap palette; only */ - /* used for paletted pixel modes. */ - /* */ - /* */ - /* For now, the only pixel mode supported by FreeType are mono and */ - /* grays. However, drivers might be added in the future to support */ - /* more `colorful' options. */ - /* */ - /* When using pixel modes pal2, pal4 and pal8 with a void `palette' */ - /* field, a gray pixmap with respectively 4, 16, and 256 levels of */ - /* gray is assumed. This, in order to be compatible with some */ - /* embedded bitmap formats defined in the TrueType specification. */ - /* */ - /* Note that no font was found presenting such embedded bitmaps, so */ - /* this is currently completely unhandled by the library. */ - /* */ - typedef struct FT_Bitmap_ - { - int rows; - int width; - int pitch; - unsigned char* buffer; - short num_grays; - char pixel_mode; - char palette_mode; - void* palette; - - } FT_Bitmap; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline */ - /* */ - /* */ - /* This structure is used to describe an outline to the scan-line */ - /* converter. */ - /* */ - /* */ - /* n_contours :: The number of contours in the outline. */ - /* */ - /* n_points :: The number of points in the outline. */ - /* */ - /* points :: A pointer to an array of `n_points' FT_Vector */ - /* elements, giving the outline's point coordinates. */ - /* */ - /* tags :: A pointer to an array of `n_points' chars, giving */ - /* giving each outline point's type. If bit 0 is */ - /* unset, the point is 'off' the curve, i.e. a Bezier */ - /* control point, while it is `on' when unset. */ - /* */ - /* Bit 1 is meaningful for `off' points only. If set, */ - /* it indicates a third-order Bezier arc control point; */ - /* and a second-order control point if unset. */ - /* */ - /* contours :: An array of `n_contours' shorts, giving the end */ - /* point of each contour within the outline. For */ - /* example, the first contour is defined by the points */ - /* `0' to `contours[0]', the second one is defined by */ - /* the points `contours[0]+1' to `contours[1]', etc. */ - /* */ - /* flags :: A set of bit flags used to characterize the outline */ - /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See FT_Outline_Flags. */ - /* */ - typedef struct FT_Outline_ - { - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ - - FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ - - int flags; /* outline masks */ - - } FT_Outline; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Flags */ - /* */ - /* */ - /* A simple type used to enumerates the flags in an outline's */ - /* `outline_flags' field. */ - /* */ - /* */ - /* ft_outline_owner :: If set, this flag indicates that the */ - /* outline's field arrays (i.e. */ - /* `points', `flags' & `contours') are */ - /* `owned' by the outline object, and */ - /* should thus be freed when it is */ - /* destroyed. */ - /* */ - /* ft_outline_even_odd_fill :: By default, outlines are filled using */ - /* the non-zero winding rule. If set to */ - /* 1, the outline will be filled using */ - /* the even-odd fill rule (only works */ - /* with the smooth raster). */ - /* */ - /* ft_outline_reverse_fill :: By default, outside contours of an */ - /* outline are oriented in clock-wise */ - /* direction, as defined in the TrueType */ - /* specification. This flag is set if */ - /* the outline uses the opposite */ - /* direction (typically for Type 1 */ - /* fonts). This flag is ignored by the */ - /* scan-converter. However, it is very */ - /* important for the auto-hinter. */ - /* */ - /* ft_outline_ignore_dropouts :: By default, the scan converter will */ - /* try to detect drop-outs in an outline */ - /* and correct the glyph bitmap to */ - /* ensure consistent shape continuity. */ - /* If set, this flag hints the scan-line */ - /* converter to ignore such cases. */ - /* */ - /* ft_outline_high_precision :: This flag indicates that the */ - /* scan-line converter should try to */ - /* convert this outline to bitmaps with */ - /* the highest possible quality. It is */ - /* typically set for small character */ - /* sizes. Note that this is only a */ - /* hint, that might be completely */ - /* ignored by a given scan-converter. */ - /* */ - /* ft_outline_single_pass :: This flag is set to force a given */ - /* scan-converter to only use a single */ - /* pass over the outline to render a */ - /* bitmap glyph image. Normally, it is */ - /* set for very large character sizes. */ - /* It is only a hint, that might be */ - /* completely ignored by a given */ - /* scan-converter. */ - /* */ - typedef enum FT_Outline_Flags_ - { - ft_outline_none = 0, - ft_outline_owner = 1, - ft_outline_even_odd_fill = 2, - ft_outline_reverse_fill = 4, - ft_outline_ignore_dropouts = 8, - ft_outline_high_precision = 256, - ft_outline_single_pass = 512 - - } FT_Outline_Flags; - - -#define FT_CURVE_TAG( flag ) ( flag & 3 ) - -#define FT_Curve_Tag_On 1 -#define FT_Curve_Tag_Conic 0 -#define FT_Curve_Tag_Cubic 2 - -#define FT_Curve_Tag_Touch_X 8 /* reserved for the TrueType hinter */ -#define FT_Curve_Tag_Touch_Y 16 /* reserved for the TrueType hinter */ - -#define FT_Curve_Tag_Touch_Both ( FT_Curve_Tag_Touch_X | \ - FT_Curve_Tag_Touch_Y ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_MoveTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `move */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `move to' is emitted to start a new contour in an outline. */ - /* */ - /* */ - /* to :: A pointer to the target point of the `move to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_MoveTo_Func)( FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_LineTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `line */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `line to' is emitted to indicate a segment in the outline. */ - /* */ - /* */ - /* to :: A pointer to the target point of the `line to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_LineTo_Func)( FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_ConicTo_Func */ - /* */ - /* */ - /* A function pointer type use to describe the signature of a `conic */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `conic to' is emitted to indicate a second-order Bezier arc in */ - /* the outline. */ - /* */ - /* */ - /* control :: An intermediate control point between the last position */ - /* and the new target in `to'. */ - /* */ - /* to :: A pointer to the target end point of the conic arc. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_ConicTo_Func)( FT_Vector* control, - FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_CubicTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ - /* */ - /* */ - /* control1 :: A pointer to the first Bezier control point. */ - /* */ - /* control2 :: A pointer to the second Bezier control point. */ - /* */ - /* to :: A pointer to the target end point. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_CubicTo_Func)( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Funcs */ - /* */ - /* */ - /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Beziers, */ - /* as well as `move to' and `close to' operations. */ - /* */ - /* */ - /* move_to :: The `move to' emitter. */ - /* */ - /* line_to :: The segment emitter. */ - /* */ - /* conic_to :: The second-order Bezier arc emitter. */ - /* */ - /* cubic_to :: The third-order Bezier arc emitter. */ - /* */ - /* shift :: The shift that is applied to coordinates before they */ - /* are sent to the emitter. */ - /* */ - /* delta :: The delta that is applied to coordinates before they */ - /* are sent to the emitter, but after the shift. */ - /* */ - /* */ - /* The point coordinates sent to the emitters are the transformed */ - /* version of the original coordinates (this is important for high */ - /* accuracy during scan-conversion). The transformation is simple: */ - /* */ - /* x' = (x << shift) - delta */ - /* y' = (x << shift) - delta */ - /* */ - /* Set the value of `shift' and `delta' to 0 to get the original */ - /* point coordinates. */ - /* */ - typedef struct FT_Outline_Funcs_ - { - FT_Outline_MoveTo_Func move_to; - FT_Outline_LineTo_Func line_to; - FT_Outline_ConicTo_Func conic_to; - FT_Outline_CubicTo_Func cubic_to; - - int shift; - FT_Pos delta; - - } FT_Outline_Funcs; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_IMAGE_TAG */ - /* */ - /* */ - /* This macro converts four letter tags into an unsigned long. */ - /* */ -#define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (unsigned long)_x1 << 24 ) | \ - ( (unsigned long)_x2 << 16 ) | \ - ( (unsigned long)_x3 << 8 ) | \ - (unsigned long)_x4 ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Format */ - /* */ - /* */ - /* An enumeration type used to describe the format of a given glyph */ - /* image. Note that this version of FreeType only supports two image */ - /* formats, even though future font drivers will be able to register */ - /* their own format. */ - /* */ - /* */ - /* ft_glyph_format_composite :: The glyph image is a composite of */ - /* several other images. This glyph */ - /* format is _only_ used with the */ - /* FT_LOAD_FLAG_NO_RECURSE flag (XXX: */ - /* Which is currently unimplemented). */ - /* */ - /* ft_glyph_format_bitmap :: The glyph image is a bitmap, and can */ - /* be described as a FT_Bitmap. */ - /* */ - /* ft_glyph_format_outline :: The glyph image is a vectorial image */ - /* made of bezier control points, and */ - /* can be described as a FT_Outline. */ - /* */ - /* ft_glyph_format_plotter :: The glyph image is a vectorial image */ - /* made of plotter lines (some T1 fonts */ - /* like Hershey contain glyph in this */ - /* format). */ - /* */ - typedef enum FT_Glyph_Format_ - { - ft_glyph_format_none = 0, - ft_glyph_format_composite = FT_IMAGE_TAG( 'c', 'o', 'm', 'p' ), - ft_glyph_format_bitmap = FT_IMAGE_TAG( 'b', 'i', 't', 's' ), - ft_glyph_format_outline = FT_IMAGE_TAG( 'o', 'u', 't', 'l' ), - ft_glyph_format_plotter = FT_IMAGE_TAG( 'p', 'l', 'o', 't' ) - - } FT_Glyph_Format; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** R A S T E R D E F I N I T I O N S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ - /* */ - /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `freetype/ftrender.h' for */ - /* more details on renderers. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster */ - /* */ - /* */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ - /* */ - typedef struct FT_RasterRec_* FT_Raster; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Span */ - /* */ - /* */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ - /* */ - /* */ - /* x :: The span's horizontal start position. */ - /* */ - /* len :: The span's length in pixels. */ - /* */ - /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ - /* */ - /* */ - /* This structure is used by the span drawing callback type named */ - /* FT_Raster_Span_Func(), which takes the y-coordinate of the span as */ - /* a parameter. */ - /* */ - /* The coverage value is always between 0 and 255, even if the number */ - /* of gray levels have been set through FT_Set_Gray_Levels(). */ - /* */ - typedef struct FT_Span_ - { - short x; - unsigned short len; - unsigned char coverage; - - } FT_Span; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Span_Func */ - /* */ - /* */ - /* A function used as a call-back by the anti-aliased renderer in */ - /* order to let client applications draw themselves the gray pixel */ - /* spans on each scan line. */ - /* */ - /* */ - /* y :: The scanline's y-coordinate. */ - /* */ - /* count :: The number of spans to draw on this scanline. */ - /* */ - /* spans :: A table of `count' spans to draw on the scanline. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* This callback allows client applications to directly render the */ - /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ - /* */ - /* This can be used to write anti-aliased outlines directly to a */ - /* given background bitmap, and even perform translucency. */ - /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the FT_MAX_GRAY_SPANS configuration macro in */ - /* ftoption.h. By default, this value is set to 32, which means that */ - /* if there are more than 32 spans on a given scanline, the callback */ - /* will be called several times with the same `y' parameter in order */ - /* to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ - typedef void (*FT_Raster_Span_Func)( int y, - int count, - FT_Span* spans, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_BitTest_Func */ - /* */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to test whether a given target pixel is already set to the drawing */ - /* `color'. These tests are crucial to implement drop-out control */ - /* per-se the TrueType spec. */ - /* */ - /* */ - /* y :: The pixel's y-coordinate. */ - /* */ - /* x :: The pixel's x-coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* 1 if the pixel is `set', 0 otherwise. */ - /* */ - typedef int (*FT_Raster_BitTest_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_BitSet_Func */ - /* */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to set an individual target pixel. This is crucial to implement */ - /* drop-out control according to the TrueType specification. */ - /* */ - /* */ - /* y :: The pixel's y-coordinate. */ - /* */ - /* x :: The pixel's x-coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* 1 if the pixel is `set', 0 otherwise. */ - /* */ - typedef void (*FT_Raster_BitSet_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Flag */ - /* */ - /* */ - /* An enumeration to list the bit flags as used in the `flags' field */ - /* of a FT_Raster_Params structure. */ - /* */ - /* */ - /* ft_raster_flag_default :: This value is 0. */ - /* */ - /* ft_raster_flag_aa :: Requests the rendering of an */ - /* anti-aliased glyph bitmap. If unset, a */ - /* monchrome bitmap will be rendered. */ - /* */ - /* ft_raster_flag_direct :: Requests direct rendering over the */ - /* target bitmap. Direct rendering uses */ - /* user-provided callbacks in order to */ - /* perform direct drawing or composition */ - /* over an existing bitmap. If this bit is */ - /* unset, the content of the target bitmap */ - /* *must be zeroed*! */ - /* */ - typedef enum - { - ft_raster_flag_default = 0, - ft_raster_flag_aa = 1, - ft_raster_flag_direct = 2 - - } FT_Raster_Flag; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Params */ - /* */ - /* */ - /* A structure to hold the arguments used by a raster's render */ - /* function. */ - /* */ - /* */ - /* target :: The target bitmap. */ - /* */ - /* source :: A pointer to the source glyph image (e.g. an */ - /* FT_Outline). */ - /* */ - /* flags :: The rendering flags. */ - /* */ - /* gray_spans :: The gray span drawing callback. */ - /* */ - /* black_spans :: The black span drawing callback. */ - /* */ - /* bit_test :: The bit test callback. */ - /* */ - /* bit_set :: The bit set callback. */ - /* */ - /* user :: User-supplied data that is passed to each drawing */ - /* callback. */ - /* */ - /* */ - /* An anti-aliased glyph bitmap is drawn if the ft_raster_flag_aa bit */ - /* flag is set in the `flags' field, otherwise a monochrome bitmap */ - /* will be generated. */ - /* */ - /* If the ft_raster_flag_direct bit flag is set in `flags', the */ - /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ - /* */ - typedef struct FT_Raster_Params_ - { - FT_Bitmap* target; - void* source; - int flags; - FT_Raster_Span_Func gray_spans; - FT_Raster_Span_Func black_spans; - FT_Raster_BitTest_Func bit_test; - FT_Raster_BitSet_Func bit_set; - void* user; - - } FT_Raster_Params; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_New_Func */ - /* */ - /* */ - /* A function used to create a new raster object. */ - /* */ - /* */ - /* memory :: A handle to the memory allocator. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - /* */ - /* The `memory' parameter is a typeless pointer in order to avoid */ - /* un-wanted dependencies on the rest of the FreeType code. In */ - /* practice, it is a FT_Memory, i.e., a handle to the standard */ - /* FreeType memory allocator. However, this field can be completely */ - /* ignored by a given raster implementation. */ - /* */ - typedef int (*FT_Raster_New_Func)( void* memory, - FT_Raster* raster ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Done_Func */ - /* */ - /* */ - /* A function used to destroy a given raster object. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - typedef void (*FT_Raster_Done_Func)( FT_Raster raster ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Reset_Func */ - /* */ - /* */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ - /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* pool_base :: The address in memory of the render pool. */ - /* */ - /* pool_size :: The size in bytes of the render pool. */ - /* */ - /* */ - /* Rasters can ignore the render pool and rely on dynamic memory */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ - /* */ - typedef void (*FT_Raster_Reset_Func)( FT_Raster raster, - unsigned char* pool_base, - unsigned long pool_size ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Set_Mode_Func */ - /* */ - /* */ - /* This function is a generic facility to change modes or attributes */ - /* in a given raster. This can be used for debugging purposes, or */ - /* simply to allow implementation-specific `features' in a given */ - /* raster module. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* mode :: A 4-byte tag used to name the mode or property. */ - /* */ - /* args :: A pointer to the new mode/property to use. */ - /* */ - typedef int (*FT_Raster_Set_Mode_Func)( FT_Raster raster, - unsigned long mode, - void* args ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Render_Func */ - /* */ - /* */ - /* Invokes a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - /* params :: A pointer to a FT_Raster_Params structure used to store */ - /* the rendering parameters. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - /* */ - /* The exact format of the source image depends on the raster's glyph */ - /* format defined in its FT_Raster_Funcs structure. It can be an */ - /* FT_Outline or anything else in order to support a large array of */ - /* glyph formats. */ - /* */ - /* Note also that the render function can fail and return a */ - /* FT_Err_Unimplemented_Feature error code if the raster used does */ - /* not support direct composition. */ - /* */ - /* XXX: For now, the standard raster doesn't support direct */ - /* composition but this should change for the final release (see */ - /* the files demos/src/ftgrays.c and demos/src/ftgrays2.c for */ - /* examples of distinct implementations which support direct */ - /* composition). */ - /* */ - typedef int (*FT_Raster_Render_Func)( FT_Raster raster, - FT_Raster_Params* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Funcs */ - /* */ - /* */ - /* A structure used to describe a given raster class to the library. */ - /* */ - /* */ - /* glyph_format :: The supported glyph format for this raster. */ - /* */ - /* raster_new :: The raster constructor. */ - /* */ - /* raster_reset :: Used to reset the render pool within the raster. */ - /* */ - /* raster_render :: A function to render a glyph into a given bitmap. */ - /* */ - /* raster_done :: The raster destructor. */ - /* */ - typedef struct FT_Raster_Funcs_ - { - FT_Glyph_Format glyph_format; - FT_Raster_New_Func raster_new; - FT_Raster_Reset_Func raster_reset; - FT_Raster_Set_Mode_Func raster_set_mode; - FT_Raster_Render_Func raster_render; - FT_Raster_Done_Func raster_done; - - } FT_Raster_Funcs; - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTIMAGE_H */ - - -/* END */ diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h deleted file mode 100644 index db5db04..0000000 --- a/include/freetype/ftmm.h +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.h */ -/* */ -/* FreeType Multiple Master font interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMM_H -#define FTMM_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MM_Axis */ - /* */ - /* */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters fonts. */ - /* */ - /* */ - /* name :: The axis's name. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ - typedef struct FT_MM_Axis_ - { - FT_String* name; - FT_Long minimum; - FT_Long maximum; - - } FT_MM_Axis; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Multi_Master */ - /* */ - /* */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* font. */ - /* */ - /* */ - /* num_axis :: Number of axes. Cannot exceed 4. */ - /* */ - /* num_designs :: Number of designs; should ne normally 2^num_axis */ - /* even though the Type 1 specification strangely */ - /* allows for intermediate designs to be present. This */ - /* number cannot exceed 16. */ - /* */ - /* axis :: A table of axis descriptors. */ - /* */ - typedef struct FT_Multi_Master_ - { - FT_UInt num_axis; - FT_UInt num_designs; - FT_MM_Axis axis[T1_MAX_MM_AXIS]; - - } FT_Multi_Master; - - - typedef FT_Error (*FT_Get_MM_Func)( FT_Face face, - FT_Multi_Master* master ); - - typedef FT_Error (*FT_Set_MM_Design_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - typedef FT_Error (*FT_Set_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Multi_Master */ - /* */ - /* */ - /* Retrieves the Multiple Master descriptor of a given font. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* */ - /* master :: The Multiple Masters descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master* master ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Design_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_MM_Design_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Blend_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through normalized blend coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates (each one must be between 0 */ - /* and 1.0). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_MM_Blend_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTMM_H */ - - -/* END */ diff --git a/include/freetype/ftmodule.h b/include/freetype/ftmodule.h deleted file mode 100644 index 3c09aa2..0000000 --- a/include/freetype/ftmodule.h +++ /dev/null @@ -1,274 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmodule.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMODULE_H -#define FTMODULE_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* module bit flags */ - typedef enum FT_Module_Flags_ - { - ft_module_font_driver = 1, /* this module is a font driver */ - ft_module_renderer = 2, /* this module is a renderer */ - ft_module_hinter = 4, /* this module is a glyph hinter */ - ft_module_styler = 8, /* this module is a styler */ - - ft_module_driver_scalable = 0x100, /* the driver supports scalable */ - /* fonts */ - ft_module_driver_no_outlines = 0x200, /* the driver does not support */ - /* vector outlines */ - ft_module_driver_has_hinter = 0x400 /* the driver provides its own */ - /* hinter */ - - } FT_Module_Flags; - - - typedef void (*FT_Module_Interface)( void ); - - typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); - - typedef void (*FT_Module_Destructor)( FT_Module module ); - - typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, - const char* name ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Module_Class */ - /* */ - /* */ - /* The module class descriptor. */ - /* */ - /* */ - /* module_flags :: Bit flags describing the module. */ - /* */ - /* module_size :: The size of one module object/instance in */ - /* bytes. */ - /* */ - /* module_name :: The name of the module. */ - /* */ - /* module_version :: The version, as a 16.16 fixed number */ - /* (major.minor). */ - /* */ - /* module_requires :: The version of FreeType this module requires */ - /* (starts at version 2.0, i.e 0x20000) */ - /* */ - /* module_init :: A function used to initialize (not create) a */ - /* new module object. */ - /* */ - /* module_done :: A function used to finalize (not destroy) a */ - /* given module object */ - /* */ - /* get_interface :: Queries a given module for a specific */ - /* interface by name. */ - /* */ - typedef struct FT_Module_Class_ - { - FT_ULong module_flags; - FT_Int module_size; - const FT_String* module_name; - FT_Fixed module_version; - FT_Fixed module_requires; - - const void* module_interface; - - FT_Module_Constructor module_init; - FT_Module_Destructor module_done; - FT_Module_Requester get_interface; - - } FT_Module_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Module */ - /* */ - /* */ - /* Adds a new module to a given library instance. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* clazz :: A pointer to class descriptor for the module. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module */ - /* */ - /* */ - /* Finds a module by its name. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module handle. 0 if none was found. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for :-) */ - /* */ - FT_EXPORT_DEF( FT_Module ) FT_Get_Module( FT_Library library, - const char* module_name ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Remove_Module */ - /* */ - /* */ - /* Removes a given module from a library instance. */ - /* */ - /* */ - /* library :: A handle to a library object. */ - /* */ - /* module :: A handle to a module object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The module object is destroyed by the function in case of success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Remove_Module( FT_Library library, - FT_Module module ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Library */ - /* */ - /* */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ - /* */ - /* */ - /* memory :: A handle to the original memory object. */ - /* */ - /* */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Library( FT_Memory memory, - FT_Library* library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Library */ - /* */ - /* */ - /* Discards a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* */ - /* library :: A handle to the target library. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_Library( FT_Library library ); - - - - typedef void (*FT_DebugHook_Func)( void* arg ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Debug_Hook */ - /* */ - /* */ - /* Sets a debug hook function for debugging the interpreter of a font */ - /* format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in ftobjs.h, e.g. */ - /* FT_DEBUG_HOOK_TRUETYPE */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ - /* */ - FT_EXPORT_DEF( void ) FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ); - - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Default_Modules */ - /* */ - /* */ - /* Adds the set of default drivers to a given library object. */ - /* This is only useful when you create a library object with */ - /* FT_New_Library() (usually to plug a custom memory manager). */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - FT_EXPORT_DEF( void ) FT_Add_Default_Modules( FT_Library library ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTMODULE_H */ - - -/* END */ diff --git a/include/freetype/ftnames.h b/include/freetype/ftnames.h deleted file mode 100644 index 2969214..0000000 --- a/include/freetype/ftnames.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftnames.h */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2000 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 FTNAMES_H -#define FTNAMES_H - - -#include - - - typedef struct FT_SfntName_ - { - FT_UShort platform_id; - FT_UShort encoding_id; - FT_UShort language_id; - FT_UShort name_id; - - FT_Byte* string; - FT_UInt string_len; /* in bytes */ - - } FT_SfntName; - - - FT_EXPORT_DEF( FT_UInt ) FT_Get_Sfnt_Name_Count( FT_Face face ); - - FT_EXPORT_DEF( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, - FT_UInt index, - FT_SfntName* aname ); - - -#endif /* FTNAMES_H */ - - -/* END */ diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h deleted file mode 100644 index 1e448bd..0000000 --- a/include/freetype/ftoutln.h +++ /dev/null @@ -1,344 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.h */ -/* */ -/* Support for the FT_Outline type used to store glyph shapes of */ -/* most scalable font formats (specification). */ -/* */ -/* Copyright 1996-2000 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 FTOUTLN_H -#define FTOUTLN_H - - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Decompose */ - /* */ - /* */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* */ - /* outline :: A pointer to the source target. */ - /* */ - /* interface :: A table of `emitters', i.e,. function pointers called */ - /* during decomposition to indicate path operations. */ - /* */ - /* user :: A typeless pointer which is passed to each emitter */ - /* during the decomposition. It can be used to store */ - /* the state during the decomposition. */ - /* */ - /* */ - /* FreeType error code. 0 means sucess. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Decompose( - FT_Outline* outline, - FT_Outline_Funcs* interface, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_New */ - /* */ - /* */ - /* Creates a new outline of a given size. */ - /* */ - /* */ - /* library :: A handle to the library object from where the */ - /* outline is allocated. Note however that the new */ - /* outline will NOT necessarily be FREED, when */ - /* destroying the library, by FT_Done_FreeType(). */ - /* */ - /* numPoints :: The maximal number of points within the outline. */ - /* */ - /* numContours :: The maximal number of contours within the outline. */ - /* */ - /* */ - /* outline :: A handle to the new outline. NULL in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* The reason why this function takes a `library' parameter is simply */ - /* to use the library's memory allocator. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ); - - - FT_EXPORT_DEF( FT_Error ) FT_Outline_New_Internal( - FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Done */ - /* */ - /* */ - /* Destroys an outline created with FT_Outline_New(). */ - /* */ - /* */ - /* library :: A handle of the library object used to allocate the */ - /* outline. */ - /* */ - /* outline :: A pointer to the outline object to be discarded. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* If the outline's `owner' field is not set, only the outline */ - /* descriptor will be released. */ - /* */ - /* The reason why this function takes an `outline' parameter is */ - /* simply to use FT_Free(). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Done( FT_Library library, - FT_Outline* outline ); - - - FT_EXPORT_DEF( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_CBox */ - /* */ - /* */ - /* Returns an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bezier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bezier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ - /* */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* */ - /* cbox :: The outline's control box. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Get_CBox( FT_Outline* outline, - FT_BBox* cbox ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Translate */ - /* */ - /* */ - /* Applies a simple translation to the points of an outline. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* xOffset :: The horizontal offset. */ - /* */ - /* yOffset :: The vertical offset. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Translate( FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Copy */ - /* */ - /* */ - /* Copies an outline into another one. Both objects must have the */ - /* same sizes (number of points & number of contours) when this */ - /* function is called. */ - /* */ - /* */ - /* source :: A handle to the source outline. */ - /* */ - /* */ - /* target :: A handle to the target outline. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Copy( FT_Outline* source, - FT_Outline* target ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Transform( FT_Outline* outline, - FT_Matrix* matrix ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Reverse */ - /* */ - /* */ - /* Reverses the drawing direction of an outline. This is used to */ - /* ensure consistent fill conventions for mirrored glyphs. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* */ - /* This functions toggles the bit flag `ft_outline_reverse_fill' in */ - /* the outline's `flags' field. */ - /* */ - /* It shouldn't be used by a normal client application, unless it */ - /* knows what it is doing. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Reverse( FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* */ - /* Renders an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* map :: A pointer to the target bitmap descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ - /* */ - /* It will use the raster correponding to the default glyph format. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - FT_Bitmap* bitmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Render */ - /* */ - /* */ - /* Renders an outline within a bitmap using the current scan-convert. */ - /* This functions uses an FT_Raster_Params structure as an argument, */ - /* allowing advanced features like direct composition, translucency, */ - /* etc. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* params :: A pointer to a FT_Raster_Params structure used to */ - /* describe the rendering operation. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* You should know what you are doing and how FT_Raster_Params works */ - /* to use this function. */ - /* */ - /* The field `params.source' will be set to `outline' before the scan */ - /* converter is called, which means that the value you give to it is */ - /* actually ignored. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTOUTLN_H */ - - -/* END */ diff --git a/include/freetype/ftrender.h b/include/freetype/ftrender.h deleted file mode 100644 index fe5acd2..0000000 --- a/include/freetype/ftrender.h +++ /dev/null @@ -1,191 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrender.h */ -/* */ -/* FreeType renderer modules public interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTRENDER_H -#define FTRENDER_H - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* create a new glyph object */ - typedef FT_Error (*FT_Glyph_Init_Func)( FT_Glyph glyph, - FT_GlyphSlot slot ); - - /* destroys a given glyph object */ - typedef void (*FT_Glyph_Done_Func)( FT_Glyph glyph ); - - typedef void (*FT_Glyph_Transform_Func)( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); - - typedef void (*FT_Glyph_BBox_Func)( FT_Glyph glyph, - FT_BBox* abbox ); - - typedef FT_Error (*FT_Glyph_Copy_Func)( FT_Glyph source, - FT_Glyph target ); - - typedef FT_Error (*FT_Glyph_Prepare_Func)( FT_Glyph glyph, - FT_GlyphSlot slot ); - - struct FT_Glyph_Class_ - { - FT_UInt glyph_size; - FT_Glyph_Format glyph_format; - FT_Glyph_Init_Func glyph_init; - FT_Glyph_Done_Func glyph_done; - FT_Glyph_Copy_Func glyph_copy; - FT_Glyph_Transform_Func glyph_transform; - FT_Glyph_BBox_Func glyph_bbox; - FT_Glyph_Prepare_Func glyph_prepare; - }; - - - typedef FT_Error (*FTRenderer_render)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ); - - typedef FT_Error (*FTRenderer_transform)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ); - - typedef void (*FTRenderer_getCBox)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_BBox* cbox ); - - typedef FT_Error (*FTRenderer_setMode)( FT_Renderer renderer, - FT_ULong mode_tag, - FT_Pointer mode_ptr ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Renderer_Class */ - /* */ - /* */ - /* The renderer module class descriptor. */ - /* */ - /* */ - /* root :: The root FT_Module_Class fields. */ - /* */ - /* glyph_format :: The glyph image format this renderer handles. */ - /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ - /* */ - /* set_mode :: A method used to pass additional parameters. */ - /* */ - /* raster_class :: For `ft_glyph_format_outline' renderers only, this */ - /* is a pointer to its raster's class. */ - /* */ - /* raster :: For `ft_glyph_format_outline' renderers only. this */ - /* is a pointer to the corresponding raster object, */ - /* if any. */ - /* */ - typedef struct FT_Renderer_Class_ - { - FT_Module_Class root; - - FT_Glyph_Format glyph_format; - - FTRenderer_render render_glyph; - FTRenderer_transform transform_glyph; - FTRenderer_getCBox get_glyph_cbox; - FTRenderer_setMode set_mode; - - FT_Raster_Funcs* raster_class; - - } FT_Renderer_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Renderer */ - /* */ - /* */ - /* Retrieves the current renderer for a given glyph format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* format :: The glyph format. */ - /* */ - /* */ - /* A renderer handle. 0 if none found. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - /* To add a new renderer, simply use FT_Add_Module(). To retrieve a */ - /* renderer by its name, use FT_Get_Module(). */ - /* */ - FT_EXPORT_DEF( FT_Renderer ) FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Renderer */ - /* */ - /* */ - /* Sets the current renderer to use, and set additional mode. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* renderer :: A handle to the renderer object. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* parameters :: Additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* In case of success, the renderer will be used to convert glyph */ - /* images in the renderer's known format into bitmaps. */ - /* */ - /* This doesn't change the current renderer for other formats. */ - /* */ - FT_EXPORT_DEF(FT_Error) FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTRENDER_H */ - - -/* END */ diff --git a/include/freetype/ftsystem.h b/include/freetype/ftsystem.h deleted file mode 100644 index bc74bce..0000000 --- a/include/freetype/ftsystem.h +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.h */ -/* */ -/* FreeType low-level system interface definition (specification). */ -/* */ -/* Copyright 1996-2000 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 FTSYSTEM_H -#define FTSYSTEM_H - - - /*************************************************************************/ - /* */ - /* M E M O R Y M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - typedef struct FT_MemoryRec_* FT_Memory; - - - typedef void* (*FT_Alloc_Func)( FT_Memory memory, - long size ); - - typedef void (*FT_Free_Func)( FT_Memory memory, - void* block ); - - typedef void* (*FT_Realloc_Func)( FT_Memory memory, - long cur_size, - long new_size, - void* block ); - - - struct FT_MemoryRec_ - { - void* user; - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - }; - - - /*************************************************************************/ - /* */ - /* I / O M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - typedef union FT_StreamDesc_ - { - long value; - void* pointer; - - } FT_StreamDesc; - - - typedef struct FT_StreamRec_* FT_Stream; - - - typedef unsigned long (*FT_Stream_IO)( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ); - - typedef void (*FT_Stream_Close)( FT_Stream stream ); - - - struct FT_StreamRec_ - { - unsigned char* base; - unsigned long size; - unsigned long pos; - - FT_StreamDesc descriptor; - FT_StreamDesc pathname; /* ignored by FreeType -- */ - /* useful for debugging */ - FT_Stream_IO read; - FT_Stream_Close close; - - FT_Memory memory; - unsigned char* cursor; - unsigned char* limit; - }; - - -#endif /* FTSYSTEM_H */ - - -/* END */ diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h deleted file mode 100644 index ec90906..0000000 --- a/include/freetype/fttypes.h +++ /dev/null @@ -1,400 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttypes.h */ -/* */ -/* FreeType simple types definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 FTTYPES_H -#define FTTYPES_H - - -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bool */ - /* */ - /* */ - /* A typedef of unsigned char, used for simple booleans. */ - /* */ - typedef unsigned char FT_Bool; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FWord */ - /* */ - /* */ - /* A signed 16-bit integer used to store a distance in original font */ - /* units. */ - /* */ - typedef signed short FT_FWord; /* distance in FUnits */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UFWord */ - /* */ - /* */ - /* An unsigned 16-bit integer used to store a distance in original */ - /* font units. */ - /* */ - typedef unsigned short FT_UFWord; /* unsigned distance */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Char */ - /* */ - /* */ - /* A simple typedef for the _signed_ char type. */ - /* */ - typedef signed char FT_Char; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Byte */ - /* */ - /* */ - /* A simple typedef for the _unsigned_ char type. */ - /* */ - typedef unsigned char FT_Byte; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_String */ - /* */ - /* */ - /* A simple typedef for the char type, usually used for strings. */ - /* */ - typedef char FT_String; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Short */ - /* */ - /* */ - /* A typedef for signed short. */ - /* */ - typedef signed short FT_Short; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UShort */ - /* */ - /* */ - /* A typedef for unsigned short. */ - /* */ - typedef unsigned short FT_UShort; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int */ - /* */ - /* */ - /* A typedef for the int type. */ - /* */ - typedef int FT_Int; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt */ - /* */ - /* */ - /* A typedef for the unsigned int type. */ - /* */ - typedef unsigned int FT_UInt; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Long */ - /* */ - /* */ - /* A typedef for signed long. */ - /* */ - typedef signed long FT_Long; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ULong */ - /* */ - /* */ - /* A typedef for unsigned long. */ - /* */ - typedef unsigned long FT_ULong; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_F2Dot14 */ - /* */ - /* */ - /* A signed 2.14 fixed float type used for unit vectors. */ - /* */ - typedef signed short FT_F2Dot14; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_F26Dot6 */ - /* */ - /* */ - /* A signed 26.6 fixed float type used for vectorial pixel */ - /* coordinates. */ - /* */ - typedef signed long FT_F26Dot6; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Fixed */ - /* */ - /* */ - /* This type is used to store 16.16 fixed float values, like scales */ - /* or matrix coefficients. */ - /* */ - typedef signed long FT_Fixed; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Error */ - /* */ - /* */ - /* The FreeType error code type. A value of 0 is always interpreted */ - /* as a successful operation. */ - /* */ - typedef int FT_Error; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pointer */ - /* */ - /* */ - /* A simple typedef for a typeless pointer. */ - /* */ - typedef void* FT_Pointer; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UnitVector */ - /* */ - /* */ - /* A simple structure used to store a 2D vector unit vector. Uses */ - /* FT_F2Dot14 types. */ - /* */ - /* */ - /* x :: Horizontal coordinate. */ - /* */ - /* y :: Vertical coordinate. */ - /* */ - typedef struct FT_UnitVector_ - { - FT_F2Dot14 x; - FT_F2Dot14 y; - - } FT_UnitVector; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix */ - /* */ - /* */ - /* A simple structure used to store a 2x2 matrix. Coefficients are */ - /* in 16.16 fixed float format. The computation performed is: */ - /* */ - /* { */ - /* x' = x*xx + y*xy */ - /* y' = x*yx + y*yy */ - /* } */ - /* */ - /* */ - /* xx :: Matrix coefficient. */ - /* */ - /* xy :: Matrix coefficient. */ - /* */ - /* yx :: Matrix coefficient. */ - /* */ - /* yy :: Matrix coefficient. */ - /* */ - typedef struct FT_Matrix_ - { - FT_Fixed xx, xy; - FT_Fixed yx, yy; - - } FT_Matrix; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_BBox */ - /* */ - /* */ - /* A structure used to hold an outline's bounding box, i.e., the */ - /* coordinates of its extrema in the horizontal and vertical */ - /* directions. */ - /* */ - /* */ - /* xMin :: The horizontal minimum (left-most). */ - /* */ - /* yMin :: The vertical minimum (bottom-most). */ - /* */ - /* xMax :: The horizontal maximum (right-most). */ - /* */ - /* yMax :: The vertical maximum (top-most). */ - /* */ - typedef struct FT_BBox_ - { - FT_Pos xMin, yMin; - FT_Pos xMax, yMax; - - } FT_BBox; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MAKE_TAG */ - /* */ - /* */ - /* This macro converts four letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ - /* */ -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* L I S T M A N A G E M E N T */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListNode */ - /* */ - /* */ - /* Many elements and objects in FreeType are listed through a */ - /* FT_List record (see FT_ListRec). As its name suggests, a */ - /* FT_ListNode is a handle to a single list element. */ - /* */ - typedef struct FT_ListNodeRec_* FT_ListNode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List */ - /* */ - /* */ - /* A handle to a list record (see FT_ListRec). */ - /* */ - typedef struct FT_ListRec_* FT_List; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListNodeRec */ - /* */ - /* */ - /* A structure used to hold a single list element. */ - /* */ - /* */ - /* prev :: The previous element in the list. NULL if first. */ - /* */ - /* next :: The next element in the list. NULL if last. */ - /* */ - /* data :: A typeless pointer to the listed object. */ - /* */ - typedef struct FT_ListNodeRec_ - { - FT_ListNode prev; - FT_ListNode next; - void* data; - - } FT_ListNodeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListRec */ - /* */ - /* */ - /* A structure used to hold a simple doubly-linked list. These are */ - /* used in many parts of FreeType. */ - /* */ - /* */ - /* head :: The head (first element) of doubly-linked list. */ - /* */ - /* tail :: The tail (last element) of doubly-linked list. */ - /* */ - typedef struct FT_ListRec_ - { - FT_ListNode head; - FT_ListNode tail; - - } FT_ListRec; - - -#define FT_IS_EMPTY( list ) ( (list).head == 0 ) - - -#endif /* FTTYPES_H */ - - -/* END */ diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h deleted file mode 100644 index 5d35a5d..0000000 --- a/include/freetype/internal/autohint.h +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************/ -/* */ -/* autohint.h */ -/* */ -/* High-level `autohint' module-specific interface (specification). */ -/* */ -/* Copyright 1996-2000 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 auto-hinter is used to load and automatically hint glyphs if a */ - /* format-specific hinter isn't available. */ - /* */ - /*************************************************************************/ - - -#ifndef AUTOHINT_H -#define AUTOHINT_H - - - /*************************************************************************/ - /* */ - /* A small technical note regarding automatic hinting in order to */ - /* clarify this module interface. */ - /* */ - /* An automatic hinter might compute two kinds of data for a given face: */ - /* */ - /* - global hints: Usually some metrics that describe global properties */ - /* of the face. It is computed by scanning more or less */ - /* agressively the glyphs in the face, and thus can be */ - /* very slow to compute (even if the size of global */ - /* hints is really small). */ - /* */ - /* - glyph hints: These describe some important features of the glyph */ - /* outline, as well as how to align them. They are */ - /* generally much faster to compute than global hints. */ - /* */ - /* The current FreeType auto-hinter does a pretty good job while */ - /* performing fast computations for both global and glyph hints. */ - /* However, we might be interested in introducing more complex and */ - /* powerful algorithms in the future, like the one described in the John */ - /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ - /* */ - /* Because a sufficiently sophisticated font management system would */ - /* typically implement an LRU cache of opened face objects to reduce */ - /* memory usage, it is a good idea to be able to avoid recomputing */ - /* global hints every time the same face is re-opened. */ - /* */ - /* We thus provide the ability to cache global hints outside of the face */ - /* object, in order to speed up font re-opening time. Of course, this */ - /* feature is purely optional, so most client programs won't even notice */ - /* it. */ - /* */ - /* I initially thought that it would be a good idea to cache the glyph */ - /* hints too. However, my general idea now is that if you really need */ - /* to cache these too, you are simply in need of a new font format, */ - /* where all this information could be stored within the font file and */ - /* decoded on the fly. */ - /* */ - /*************************************************************************/ - - -#include - - - typedef struct FT_AutoHinterRec_ *FT_AutoHinter; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Get_Global_Func */ - /* */ - /* */ - /* Retrieves the global hints computed for a given face object the */ - /* resulting data is dissociated from the face and will survive a */ - /* call to FT_Done_Face(). It must be discarded through the API */ - /* FT_AutoHinter_Done_Global_Func(). */ - /* */ - /* */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* global_hints :: A typeless pointer to the global hints. */ - /* */ - /* global_len :: The size in bytes of the global hints. */ - /* */ - typedef void (*FT_AutoHinter_Get_Global_Func)( - FT_AutoHinter hinter, - FT_Face face, - void** global_hints, - long* global_len ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Done_Global_Func */ - /* */ - /* */ - /* Discards the global hints retrieved through */ - /* FT_AutoHinter_Get_Global_Func(). This is the only way these hints */ - /* are freed from memory. */ - /* */ - /* */ - /* hinter :: A handle to the auto-hinter module. */ - /* */ - /* global :: A pointer to retrieved global hints to discard. */ - /* */ - typedef void (*FT_AutoHinter_Done_Global_Func)( FT_AutoHinter hinter, - void* global ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Reset_Func */ - /* */ - /* */ - /* This function is used to recompute the global metrics in a given */ - /* font. This is useful when global font data changes (e.g. Multiple */ - /* Masters fonts where blend coordinates change). */ - /* */ - /* */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the face. */ - /* */ - typedef void (*FT_AutoHinter_Reset_Func)( FT_AutoHinter hinter, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Load_Func */ - /* */ - /* */ - /* This function is used to load, scale, and automatically hint a */ - /* glyph from a given face. */ - /* */ - /* */ - /* face :: A handle to the face. */ - /* glyph_index :: The glyph index. */ - /* load_flags :: The load flags. */ - /* */ - /* */ - /* This function is capable of loading composite glyphs by hinting */ - /* each sub-glyph independently (which improves quality). */ - /* */ - /* It will call the font driver with FT_Load_Glyph(), with */ - /* FT_LOAD_NO_SCALE set. */ - /* */ - typedef FT_Error (*FT_AutoHinter_Load_Func)( FT_AutoHinter hinter, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_ULong load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Interface */ - /* */ - /* */ - /* The auto-hinter module's interface. */ - /* */ - typedef struct FT_AutoHinter_Interface - { - FT_AutoHinter_Reset_Func reset_face; - FT_AutoHinter_Load_Func load_glyph; - - FT_AutoHinter_Get_Global_Func get_global_hints; - FT_AutoHinter_Done_Global_Func done_global_hints; - - } FT_AutoHinter_Interface; - - -#endif /* AUTOHINT_H */ - - -/* END */ diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h deleted file mode 100644 index 99b6cfa..0000000 --- a/include/freetype/internal/ftcalc.h +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.h */ -/* */ -/* Arithmetic computations (specification). */ -/* */ -/* Copyright 1996-2000 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 FTCALC_H -#define FTCALC_H - -#include -#include /* for LONG64 */ - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifdef LONG64 - - - typedef INT64 FT_Int64; - -#define ADD_64( x, y, z ) z = (x) + (y) -#define MUL_64( x, y, z ) z = (FT_Int64)(x) * (y) - -#define DIV_64( x, y ) ( (x) / (y) ) - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_64( z ) FT_Sqrt64( z ) - - FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt64( FT_Int64 l ); - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#else /* LONG64 */ - - - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - - } FT_Int64; - - -#define ADD_64( x, y, z ) FT_Add64( &x, &y, &z ) -#define MUL_64( x, y, z ) FT_MulTo64( x, y, &z ) -#define DIV_64( x, y ) FT_Div64by32( &x, y ) - - - FT_EXPORT_DEF( void ) FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64* z ); - - FT_EXPORT_DEF( void ) FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64* z ); - - FT_EXPORT_DEF( FT_Int32 ) FT_Div64by32( FT_Int64* x, - FT_Int32 y ); - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_64( z ) FT_Sqrt64( &z ) - - FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt64( FT_Int64* x ); - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#endif /* LONG64 */ - - -#ifndef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_32( x ) FT_Sqrt32( x ) - - BASE_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ); - -#endif /* !FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) -#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) -#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) -#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) -#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) - -#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ - : ( -( ( 32 - (x) ) & -64 ) ) ) - - -#ifdef __cplusplus - } -#endif - -#endif /* FTCALC_H */ - - -/* END */ diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h deleted file mode 100644 index 530c067..0000000 --- a/include/freetype/internal/ftdebug.h +++ /dev/null @@ -1,232 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.h */ -/* */ -/* Debugging and logging component (specification). */ -/* */ -/* Copyright 1996-2000 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 FTDEBUG_H -#define FTDEBUG_H - -#include /* for FT_DEBUG_LEVEL_TRACE, */ - /* FT_DEBUG_LEVEL_ERROR */ - -#ifdef __cplusplus - extern "C" { -#endif - - - /* A very stupid pre-processor trick. See K&R version 2 */ - /* section A12.3 for details... */ - /* */ - /* It is also described in the section `Separate */ - /* Expansion of Macro Arguments' in the info file */ - /* `cpp.info', describing GNU cpp. */ - /* */ -#define FT_CAT( x, y ) x ## y -#define FT_XCAT( x, y ) FT_CAT( x, y ) - - -#ifdef FT_DEBUG_LEVEL_TRACE - - - /* note that not all levels are used currently */ - - typedef enum FT_Trace_ - { - /* the first level must always be `trace_any' */ - trace_any = 0, - - /* base components */ - trace_aaraster, /* anti-aliasing raster (ftgrays.c) */ - trace_calc, /* calculations (ftcalc.c) */ - trace_extend, /* extension manager (ftextend.c) */ - trace_glyph, /* glyph manager (ftglyph.c) */ - trace_io, /* i/o monitoring (ftsystem.c) */ - trace_init, /* initialization (ftinit.c) */ - trace_list, /* list manager (ftlist.c) */ - trace_memory, /* memory manager (ftobjs.c) */ - trace_mm, /* MM interface (ftmm.c) */ - trace_objs, /* base objects (ftobjs.c) */ - trace_outline, /* outline management (ftoutln.c) */ - trace_raster, /* rasterizer (ftraster.c) */ - trace_stream, /* stream manager (ftstream.c) */ - - /* SFNT driver components */ - trace_sfobjs, /* SFNT object handler (sfobjs.c) */ - trace_ttcmap, /* charmap handler (ttcmap.c) */ - trace_ttload, /* basic TrueType tables (ttload.c) */ - trace_ttpost, /* PS table processing (ttpost.c) */ - trace_ttsbit, /* TrueType sbit handling (ttsbit.c) */ - - /* TrueType driver components */ - trace_ttdriver, /* TT font driver (ttdriver.c) */ - trace_ttgload, /* TT glyph loader (ttgload.c) */ - trace_ttinterp, /* bytecode interpreter (ttinterp.c) */ - trace_ttobjs, /* TT objects manager (ttobjs.c) */ - trace_ttpload, /* TT data/program loader (ttpload.c) */ - - /* Type 1 driver components */ - trace_t1driver, - trace_t1gload, - trace_t1hint, - trace_t1load, - trace_t1objs, - - /* experimental Type 1 driver components */ - trace_z1driver, - trace_z1gload, - trace_z1hint, - trace_z1load, - trace_z1objs, - trace_z1parse, - - /* Type 2 driver components */ - trace_t2driver, - trace_t2gload, - trace_t2load, - trace_t2objs, - trace_t2parse, - - /* CID driver components */ - trace_cidafm, - trace_ciddriver, - trace_cidgload, - trace_cidload, - trace_cidobjs, - trace_cidparse, - - /* Windows fonts component */ - trace_winfnt, - - /* the last level must always be `trace_max' */ - trace_max - - } FT_Trace; - - - /* declared in ftdebug.c */ - extern char ft_trace_levels[trace_max]; - - - /*************************************************************************/ - /* */ - /* IMPORTANT! */ - /* */ - /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ - /* value before using any TRACE macro. */ - /* */ - /*************************************************************************/ - - -#if __GNUC__ >= 3 -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ -#else -#define FT_TRACE( level, varformat ) \ - do \ - { \ - if ( ft_trace_levels[FT_COMPONENT] >= level ) \ - FT_XCAT( FT_Message, varformat ); \ - } while ( 0 ) -#endif - - - FT_EXPORT_DEF( void ) FT_SetTraceLevel( FT_Trace component, - char level ); - - -#elif defined( FT_DEBUG_LEVEL_ERROR ) - - -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ - - -#else /* release mode */ - - -#define FT_Assert( condition ) do ; while ( 0 ) /* nothing */ - -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ -#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ - - -#endif /* FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* Define macros and functions that are common to the debug and trace */ - /* modes. */ - /* */ - /* You need vprintf() to be able to compile ftdebug.c. */ - /* */ - /*************************************************************************/ - - -#if defined( FT_DEBUG_LEVEL_TRACE ) || defined( FT_DEBUG_LEVEL_ERROR ) - - -#include "stdio.h" /* for vprintf() */ - - -#define FT_Assert( condition ) \ - do \ - { \ - if ( !( condition ) ) \ - FT_Panic( "assertion failed on line %d of file %s\n", \ - __LINE__, __FILE__ ); \ - } while ( 0 ) - - /* print a message */ - FT_EXPORT_DEF( void ) FT_Message( const char* fmt, ... ); - - /* print a message and exit */ - FT_EXPORT_DEF( void ) FT_Panic( const char* fmt, ... ); - -#if __GNUC__ >= 3 -#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ -#else -#define FT_ERROR( varformat ) FT_XCAT( FT_Message, varformat ) -#endif - -#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* You need two opening resp. closing parentheses! */ - /* */ - /* Example: FT_TRACE0(( "Value is %i", foo )) */ - /* */ - /*************************************************************************/ - -#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) -#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) -#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) -#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) -#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) -#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) -#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) -#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTDEBUG_H */ - - -/* END */ diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h deleted file mode 100644 index 592de49..0000000 --- a/include/freetype/internal/ftdriver.h +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdriver.h */ -/* */ -/* FreeType font driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTDRIVER_H -#define FTDRIVER_H - - -#include -#include - - - typedef FT_Error (*FTDriver_initFace)( FT_Stream stream, - FT_Face face, - FT_Int typeface_index, - FT_Int num_params, - FT_Parameter* parameters ); - - typedef void (*FTDriver_doneFace)( FT_Face face ); - - - typedef FT_Error (*FTDriver_initSize)( FT_Size size ); - - typedef void (*FTDriver_doneSize)( FT_Size size ); - - - typedef FT_Error (*FTDriver_initGlyphSlot)( FT_GlyphSlot slot ); - - typedef void (*FTDriver_doneGlyphSlot)( FT_GlyphSlot slot ); - - - typedef FT_Error (*FTDriver_setCharSizes)( FT_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ); - - typedef FT_Error (*FTDriver_setPixelSizes)( FT_Size size, - FT_UInt pixel_width, - FT_UInt pixel_height ); - - typedef FT_Error (*FTDriver_loadGlyph)( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ); - - - typedef FT_UInt (*FTDriver_getCharIndex)( FT_CharMap charmap, - FT_Long charcode ); - - typedef FT_Error (*FTDriver_getKerning)( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ); - - - typedef FT_Error (*FTDriver_attachFile)( FT_Face face, - FT_Stream stream ); - - - typedef FT_Error (*FTDriver_getAdvances)( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Bool vertical, - FT_UShort* advances ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Driver_Class */ - /* */ - /* */ - /* The font driver class. This structure mostly contains pointers to */ - /* driver methods. */ - /* */ - /* */ - /* root :: The parent module. */ - /* */ - /* face_object_size :: The size of a face object in bytes. */ - /* */ - /* size_object_size :: The size of a size object in bytes. */ - /* */ - /* slot_object_size :: The size of a glyph object in bytes. */ - /* */ - /* init_face :: The format-specific face constructor. */ - /* */ - /* done_face :: The format-specific face destructor. */ - /* */ - /* init_size :: The format-specific size constructor. */ - /* */ - /* done_size :: The format-specific size destructor. */ - /* */ - /* init_slot :: The format-specific slot constructor. */ - /* */ - /* done_slot :: The format-specific slot destructor. */ - /* */ - /* set_char_sizes :: A handle to a function used to set the new */ - /* character size in points + resolution. Can be */ - /* set to 0 to indicate default behaviour. */ - /* */ - /* set_pixel_sizes :: A handle to a function used to set the new */ - /* character size in pixels. Can be set to 0 to */ - /* indicate default behaviour. */ - /* */ - /* load_glyph :: A function handle to load a given glyph image */ - /* in a slot. This field is mandatory! */ - /* */ - /* get_char_index :: A function handle to return the glyph index of */ - /* a given character for a given charmap. This */ - /* field is mandatory! */ - /* */ - /* get_kerning :: A function handle to return the unscaled */ - /* kerning for a given pair of glyphs. Can be */ - /* set to 0 if the format doesn't support */ - /* kerning. */ - /* */ - /* attach_file :: This function handle is used to read */ - /* additional data for a face from another */ - /* file/stream. For example, this can be used to */ - /* add data from AFM or PFM files on a Type 1 */ - /* face, or a CIDMap on a CID-keyed face. */ - /* */ - /* get_advances :: A function handle used to return the advances */ - /* of 'count' glyphs, starting at `index'. the */ - /* `vertical' flags must be set when vertical */ - /* advances are queried. The advances buffer is */ - /* caller-allocated. */ - /* */ - /* */ - /* Most function pointers, with the exception of `load_glyph' and */ - /* `get_char_index' can be set to 0 to indicate a default behaviour. */ - /* */ - typedef struct FT_Driver_Class_ - { - FT_Module_Class root; - - FT_Int face_object_size; - FT_Int size_object_size; - FT_Int slot_object_size; - - FTDriver_initFace init_face; - FTDriver_doneFace done_face; - - FTDriver_initSize init_size; - FTDriver_doneSize done_size; - - FTDriver_initGlyphSlot init_slot; - FTDriver_doneGlyphSlot done_slot; - - FTDriver_setCharSizes set_char_sizes; - FTDriver_setPixelSizes set_pixel_sizes; - - FTDriver_loadGlyph load_glyph; - FTDriver_getCharIndex get_char_index; - - FTDriver_getKerning get_kerning; - FTDriver_attachFile attach_file; - - FTDriver_getAdvances get_advances; - - } FT_Driver_Class; - - -#endif /* FTDRIVER_H */ - - -/* END */ diff --git a/include/freetype/internal/ftextend.h b/include/freetype/internal/ftextend.h deleted file mode 100644 index fdd2c6e..0000000 --- a/include/freetype/internal/ftextend.h +++ /dev/null @@ -1,178 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftextend.h */ -/* */ -/* FreeType extensions implementation (specification). */ -/* */ -/* Copyright 1996-2000 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 FTEXTEND_H -#define FTEXTEND_H - - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* The extensions don't need to be integrated at compile time into the */ - /* engine, only at link time. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Initializer */ - /* */ - /* */ - /* Each new face object can have several extensions associated with */ - /* it at creation time. This function is used to initialize given */ - /* extension data for a given face. */ - /* */ - /* */ - /* ext :: A typeless pointer to the extension data. */ - /* */ - /* face :: A handle to the source face object the extension is */ - /* associated with. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* In case of error, the initializer should not destroy the extension */ - /* data, as the finalizer will get called later by the function's */ - /* caller. */ - /* */ - typedef FT_Error (*FT_Extension_Initializer)( void* ext, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Finalizer */ - /* */ - /* */ - /* Each new face object can have several extensions associated with */ - /* it at creation time. This function is used to finalize given */ - /* extension data for a given face; it occurs before the face object */ - /* itself is finalized. */ - /* */ - /* */ - /* ext :: A typeless pointer to the extension data. */ - /* */ - /* face :: A handle to the source face object the extension is */ - /* associated with. */ - /* */ - typedef void (*FT_Extension_Finalizer)( void* ext, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Class */ - /* */ - /* */ - /* A simple structure used to describe a given extension to the */ - /* FreeType base layer. An FT_Extension_Class is used as a parameter */ - /* for FT_Register_Extension(). */ - /* */ - /* */ - /* id :: The extension's ID. This is a normal C string that */ - /* is used to uniquely reference the extension's */ - /* interface. */ - /* */ - /* size :: The size in bytes of the extension data that must be */ - /* associated with each face object. */ - /* */ - /* init :: A pointer to the extension data's initializer. */ - /* */ - /* finalize :: A pointer to the extension data's finalizer. */ - /* */ - /* interface :: This pointer can be anything, but should usually */ - /* point to a table of function pointers which implement */ - /* the extension's interface. */ - /* */ - /* offset :: This field is set and used within the base layer and */ - /* should be set to 0 when registering an extension */ - /* through FT_Register_Extension(). It contains an */ - /* offset within the face's extension block for the */ - /* current extension's data. */ - /* */ - typedef struct FT_Extension_Class_ - { - const char* id; - FT_ULong size; - FT_Extension_Initializer init; - FT_Extension_Finalizer finalize; - void* interface; - - FT_ULong offset; - - } FT_Extension_Class; - - - FT_EXPORT_DEF( FT_Error ) FT_Register_Extension( - FT_Driver driver, - FT_Extension_Class* clazz ); - - -#ifdef FT_CONFIG_OPTION_EXTEND_ENGINE - - - /* Initialize the extension component */ - LOCAL_DEF - FT_Error FT_Init_Extensions( FT_Library library ); - - /* Finalize the extension component */ - LOCAL_DEF - FT_Error FT_Done_Extensions( FT_Library library ); - - /* Create an extension within a face object. Called by the */ - /* face object constructor. */ - LOCAL_DEF - FT_Error FT_Create_Extensions( FT_Face face ); - - /* Destroy all extensions within a face object. Called by the */ - /* face object destructor. */ - LOCAL_DEF - FT_Error FT_Destroy_Extensions( FT_Face face ); - - -#endif - - - /* return an extension's data & interface according to its ID */ - FT_EXPORT_DEF( void* ) FT_Get_Extension( - FT_Face face, - const char* extension_id, - void** extension_interface ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTEXTEND_H */ - - -/* END */ diff --git a/include/freetype/internal/ftlist.h b/include/freetype/internal/ftlist.h deleted file mode 100644 index 7c6d8ed..0000000 --- a/include/freetype/internal/ftlist.h +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlist.c */ -/* */ -/* Generic list support for FreeType (specification). */ -/* */ -/* Copyright 1996-2000 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 implements functions relative to list processing. Its */ - /* data structures are defined in `freetype.h'. */ - /* */ - /*************************************************************************/ - - -#ifndef FTLIST_H -#define FTLIST_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - FT_EXPORT_DEF( FT_ListNode ) FT_List_Find( FT_List list, - void* data ); - - FT_EXPORT_DEF( void ) FT_List_Add( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Insert( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Remove( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Up( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Iterator */ - /* */ - /* */ - /* An FT_List iterator function which is called during a list parse */ - /* by FT_List_Iterate(). */ - /* */ - /* */ - /* node :: The current iteration list node. */ - /* */ - /* user :: A typeless pointer passed to FT_List_Iterate(). */ - /* Can be used to point to the iteration's state. */ - /* */ - typedef FT_Error (*FT_List_Iterator)( FT_ListNode node, - void* user ); - - - FT_EXPORT_DEF( FT_Error ) FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Destructor */ - /* */ - /* */ - /* An FT_List iterator function which is called during a list */ - /* finalization by FT_List_Finalize() to destroy all elements in a */ - /* given list. */ - /* */ - /* */ - /* system :: The current system object. */ - /* */ - /* data :: The current object to destroy. */ - /* */ - /* user :: A typeless pointer passed to FT_List_Iterate(). It can */ - /* be used to point to the iteration's state. */ - /* */ - typedef void (*FT_List_Destructor)( FT_Memory memory, - void* data, - void* user ); - - - FT_EXPORT_DEF( void ) FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTLIST_H */ - - -/* END */ diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h deleted file mode 100644 index da8d3a4..0000000 --- a/include/freetype/internal/ftmemory.h +++ /dev/null @@ -1,127 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmemory.h */ -/* */ -/* The FreeType memory management macros (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMEMORY_H -#define FTMEMORY_H - - -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* FT_SET_ERROR */ - /* */ - /* */ - /* This macro is used to set an implicit `error' variable to a given */ - /* expression's value (usually a function call), and convert it to a */ - /* boolean which is set whenever the value is != 0. */ - /* */ -#undef FT_SET_ERROR -#define FT_SET_ERROR( expression ) \ - ( ( error = (expression) ) != 0 ) - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M E M O R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - BASE_DEF( FT_Error ) FT_Alloc( FT_Memory memory, - FT_Long size, - void** P ); - - BASE_DEF( FT_Error ) FT_Realloc( FT_Memory memory, - FT_Long current, - FT_Long size, - void** P ); - - BASE_DEF( void ) FT_Free( FT_Memory memory, - void** P ); - - - - /* This `#include' is needed by the MEM_xxx() macros; it should be */ - /* available on all platforms we know of. */ -#include - -#define MEM_Set( dest, byte, count ) memset( dest, byte, count ) - -#define MEM_Copy( dest, source, count ) memcpy( dest, source, count ) - -#define MEM_Move( dest, source, count ) memmove( dest, source, count ) - - - /*************************************************************************/ - /* */ - /* We now support closures to produce completely reentrant code. This */ - /* means the allocation functions now takes an additional argument */ - /* (`memory'). It is a handle to a given memory object, responsible for */ - /* all low-level operations, including memory management and */ - /* synchronisation. */ - /* */ - /* In order to keep our code readable and use the same macros in the */ - /* font drivers and the rest of the library, MEM_Alloc(), ALLOC(), and */ - /* ALLOC_ARRAY() now use an implicit variable, `memory'. It must be */ - /* defined at all locations where a memory operation is queried. */ - /* */ -#define MEM_Alloc( _pointer_, _size_ ) \ - FT_Alloc( memory, _size_, (void**)&(_pointer_) ) - -#define MEM_Alloc_Array( _pointer_, _count_, _type_ ) \ - FT_Alloc( memory, (_count_)*sizeof ( _type_ ), \ - (void**)&(_pointer_) ) - -#define MEM_Realloc( _pointer_, _current_, _size_ ) \ - FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) ) - -#define MEM_Realloc_Array( _pointer_, _current_, _new_, _type_ ) \ - FT_Realloc( memory, (_current_)*sizeof ( _type_ ), \ - (_new_)*sizeof ( _type_ ), (void**)&(_pointer_) ) - -#define ALLOC( _pointer_, _size_ ) \ - FT_SET_ERROR( MEM_Alloc( _pointer_, _size_ ) ) - -#define REALLOC( _pointer_, _current_, _size_ ) \ - FT_SET_ERROR( MEM_Realloc( _pointer_, _current_, _size_ ) ) - -#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ - FT_SET_ERROR( MEM_Alloc( _pointer_, \ - (_count_)*sizeof ( _type_ ) ) ) - -#define REALLOC_ARRAY( _pointer_, _current_, _count_, _type_ ) \ - FT_SET_ERROR( MEM_Realloc( _pointer_, \ - (_current_)*sizeof ( _type_ ), \ - (_count_)*sizeof ( _type_ ) ) ) - -#define FREE( _pointer_ ) FT_Free( memory, (void**)&(_pointer_) ) - - -#endif /* FTMEMORY_H */ - - -/* END */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h deleted file mode 100644 index 0d0f5d8..0000000 --- a/include/freetype/internal/ftobjs.h +++ /dev/null @@ -1,532 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.h */ -/* */ -/* The FreeType private base classes (specification). */ -/* */ -/* Copyright 1996-2000 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 contains the definition of all internal FreeType classes. */ - /* */ - /*************************************************************************/ - - -#ifndef FTOBJS_H -#define FTOBJS_H - -#include -#include -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* Some generic definitions. */ - /* */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL (void*)0 -#endif - -#ifndef UNUSED -#define UNUSED( arg ) ( (arg)=(arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* 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 - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ModuleRec */ - /* */ - /* */ - /* A module object instance. */ - /* */ - /* */ - /* clazz :: A pointer to the module's class. */ - /* */ - /* library :: A handle to the parent library object. */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ - /* generic :: A generic structure for user-level extensibility (?). */ - /* */ - typedef struct FT_ModuleRec_ - { - FT_Module_Class* clazz; - FT_Library library; - FT_Memory memory; - FT_Generic generic; - - } FT_ModuleRec; - - - /* typecast an object to a FT_Module */ -#define FT_MODULE( x ) ((FT_Module)(x)) -#define FT_MODULE_CLASS( x ) FT_MODULE(x)->clazz -#define FT_MODULE_LIBRARY( x ) FT_MODULE(x)->library -#define FT_MODULE_MEMORY( x ) FT_MODULE(x)->memory - -#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_font_driver ) - -#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_renderer ) - -#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_hinter ) - -#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_styler ) - -#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_scalable ) - -#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_no_outlines ) - -#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_has_hinter ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module_Interface */ - /* */ - /* */ - /* Finds a module and returns its specific interface as a typeless */ - /* pointer. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module-specific interface if available, 0 otherwise. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for, and what its interface is :-) */ - /* */ - BASE_DEF( const void* ) FT_Get_Module_Interface( FT_Library library, - const char* mod_name ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* a few macros used to perform easy typecasts with minimal brain damage */ - -#define FT_FACE( x ) ((FT_Face)(x)) -#define FT_SIZE( x ) ((FT_Size)(x)) -#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) - -#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver -#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library -#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory - -#define FT_SIZE_FACE( x ) FT_SIZE( x )->face -#define FT_SLOT_FACE( x ) FT_SLOT( x )->face - -#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph -#define FT_FACE_SIZE( x ) FT_FACE( x )->size - - - /* this must be kept exported -- tt will be used later in our own */ - /* high-level caching font manager called SemTex (way after the */ - /* 2.0 release though */ - FT_EXPORT_DEF( FT_Error ) FT_New_Size( FT_Face face, - FT_Size* size ); - - FT_EXPORT_DEF( FT_Error ) FT_Done_Size( FT_Size size ); - - - FT_EXPORT_DEF( FT_Error ) FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot* aslot ); - - FT_EXPORT_DEF( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** G L Y P H L O A D E R ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 - - - enum - { - ft_glyph_own_bitmap = 1 - }; - - - struct FT_SubGlyph_ - { - FT_Int index; - FT_UShort flags; - FT_Int arg1; - FT_Int arg2; - FT_Matrix transform; - }; - - - typedef struct FT_GlyphLoad_ - { - FT_Outline outline; /* outline */ - FT_UInt num_subglyphs; /* number of subglyphs */ - FT_SubGlyph* subglyphs; /* subglyphs */ - FT_Vector* extra_points; /* extra points table */ - - } FT_GlyphLoad; - - - struct FT_GlyphLoader_ - { - FT_Memory memory; - FT_UInt max_points; - FT_UInt max_contours; - FT_UInt max_subglyphs; - FT_Bool use_extra; - - FT_GlyphLoad base; - FT_GlyphLoad current; - - void* other; /* for possible future extension? */ - - }; - - - BASE_DEF( FT_Error ) FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader** aloader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Create_Extra( - FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Done( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Points( - FT_GlyphLoader* loader, - FT_UInt n_points, - FT_UInt n_contours ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Subglyphs( - FT_GlyphLoader* loader, - FT_UInt n_subs ); - - BASE_DEF( void ) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Add( FT_GlyphLoader* loader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, - FT_GlyphLoader* source ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_RENDERER( x ) ((FT_Renderer)( x )) -#define FT_GLYPH( x ) ((FT_Glyph)( x )) -#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) -#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) - - - typedef struct FT_RendererRec_ - { - FT_ModuleRec root; - FT_Renderer_Class* clazz; - FT_Glyph_Format glyph_format; - const FT_Glyph_Class glyph_class; - - FT_Raster raster; - FT_Raster_Render_Func raster_render; - FTRenderer_render render; - - } FT_RendererRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F O N T D R I V E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* typecast a module into a driver easily */ -#define FT_DRIVER( x ) ((FT_Driver)(x)) - - /* typecast a module as a driver, and get its driver class */ -#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DriverRec */ - /* */ - /* */ - /* The root font driver class. A font driver is responsible for */ - /* managing and loading font files of a given format. */ - /* */ - /* */ - /* root :: Contains the fields of the root module class. */ - /* */ - /* clazz :: A pointer to the font driver's class. Note that */ - /* this is NOT root.clazz. `class' wasn't used */ - /* as it is a reserved word in C++. */ - /* */ - /* faces_list :: The list of faces currently opened by this */ - /* driver. */ - /* */ - /* extensions :: A typeless pointer to the driver's extensions */ - /* registry, if they are supported through the */ - /* configuration macro FT_CONFIG_OPTION_EXTENSIONS. */ - /* */ - /* glyph_loader :: The glyph loader for all faces managed by this */ - /* driver. This object isn't defined for unscalable */ - /* formats. */ - /* */ - typedef struct FT_DriverRec_ - { - FT_ModuleRec root; - FT_Driver_Class* clazz; - - FT_ListRec faces_list; - void* extensions; - - FT_GlyphLoader* glyph_loader; - - } FT_DriverRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R I E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_DEBUG_HOOK_TRUETYPE 0 -#define FT_DEBUG_HOOK_TYPE1 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LibraryRec */ - /* */ - /* */ - /* The FreeType library class. This is the root of all FreeType */ - /* data. Use FT_New_Library() to create a library object, and */ - /* FT_Done_Library() to discard it and all child objects. */ - /* */ - /* */ - /* memory :: The library's memory object. Manages memory */ - /* allocation. */ - /* */ - /* generic :: Client data variable. Used to extend the */ - /* Library class by higher levels and clients. */ - /* */ - /* num_modules :: The number of modules currently registered */ - /* within this library. This is set to 0 for new */ - /* libraries. New modules are added through the */ - /* FT_Add_Module() API function. */ - /* */ - /* modules :: A table used to store handles to the currently */ - /* registered modules. Note that each font driver */ - /* contains a list of its opened faces. */ - /* */ - /* renderers :: The list of renderers currently registered */ - /* within the library. */ - /* */ - /* cur_renderer :: The current outline renderer. This is a */ - /* shortcut used to avoid parsing the list on */ - /* each call to FT_Outline_Render(). It is a */ - /* handle to the current renderer for the */ - /* ft_glyph_format_outline format. */ - /* */ - /* auto_hinter :: XXX */ - /* */ - /* raster_pool :: The raster object's render pool. This can */ - /* ideally be changed dynamically at run-time. */ - /* */ - /* raster_pool_size :: The size of the render pool in bytes. */ - /* */ - /* debug_hooks :: XXX */ - /* */ - typedef struct FT_LibraryRec_ - { - FT_Memory memory; /* library's memory manager */ - - FT_Generic generic; - - FT_UInt num_modules; - FT_Module modules[FT_MAX_MODULES]; /* module objects */ - - FT_ListRec renderers; /* list of renderers */ - FT_Renderer cur_renderer; /* current outline renderer */ - FT_Module auto_hinter; - - FT_Byte* raster_pool; /* scan-line conversion */ - /* render pool */ - FT_ULong raster_pool_size; /* size of render pool in bytes */ - - FT_DebugHook_Func debug_hooks[4]; - - } FT_LibraryRec; - - - BASE_DEF( FT_Renderer ) FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ); - - BASE_DEF( FT_Error ) FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_UInt render_mode ); - - typedef FT_Error (*FT_Glyph_Name_Requester)( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - -#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM - - - FT_EXPORT_DEF( FT_Error ) FT_New_Stream( const char* filepathname, - FT_Stream astream ); - - FT_EXPORT_DEF( void ) FT_Done_Stream( FT_Stream stream ); - - FT_EXPORT_DEF( FT_Memory ) FT_New_Memory( void ); - - -#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ - - - /* Define default raster's interface. The default raster is located in */ - /* `src/base/ftraster.c' */ - /* */ - /* Client applications can register new rasters through the */ - /* FT_Set_Raster() API. */ - -#ifndef FT_NO_DEFAULT_RASTER - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; -#endif - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTOBJS_H */ - - -/* END */ diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h deleted file mode 100644 index 365f479..0000000 --- a/include/freetype/internal/ftstream.h +++ /dev/null @@ -1,361 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.h */ -/* */ -/* Stream handling(specification). */ -/* */ -/* Copyright 1996-2000 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 FTSTREAM_H -#define FTSTREAM_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* format of an 8-bit frame_op value = [ xxxxx | e | s ] */ - /* s is set to 1 if the value is signed, */ - /* e is set to 1 if the value is little-endian */ - /* xxxxx is a command */ - -#define FT_FRAME_OP_SHIFT 2 -#define FT_FRAME_OP_SIGNED 1 -#define FT_FRAME_OP_LITTLE 2 -#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) - -#define FT_MAKE_FRAME_OP( command, little, sign ) \ - ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) - -#define FT_FRAME_OP_END 0 -#define FT_FRAME_OP_START 1 /* start a new frame */ -#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ -#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ -#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ -#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ -#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ - - - typedef enum FT_Frame_Op_ - { - ft_frame_end = 0, - ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), - - ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), - ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), - - ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), - ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), - ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), - ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), - - ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), - ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), - ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), - ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), - - ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), - ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), - ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), - ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), - - ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), - ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) - - } FT_Frame_Op; - - - typedef struct FT_Frame_Field_ - { - FT_Frame_Op value; - char size; - FT_UShort offset; - - } FT_Frame_Field; - - - /* make-up a FT_Frame_Field out of a structure type and a field name */ -#define FT_FIELD_REF( s, f ) (((s*)0)->f) - -#define FT_FRAME_FIELD( frame_op, struct_type, field ) \ - { \ - frame_op, \ - sizeof ( FT_FIELD_REF( struct_type,field ) ), \ - (FT_UShort)(char*)&FT_FIELD_REF( struct_type, field ) \ - } - -#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } - -#define FT_FRAME_START( s ) { ft_frame_start, 0, s } -#define FT_FRAME_END { ft_frame_end, 0, 0 } - -#define FT_FRAME_LONG( s, f ) FT_FRAME_FIELD( ft_frame_long_be, s, f ) -#define FT_FRAME_ULONG( s, f ) FT_FRAME_FIELD( ft_frame_ulong_be, s, f ) -#define FT_FRAME_SHORT( s, f ) FT_FRAME_FIELD( ft_frame_short_be, s, f ) -#define FT_FRAME_USHORT( s, f ) FT_FRAME_FIELD( ft_frame_ushort_be, s, f ) -#define FT_FRAME_BYTE( s, f ) FT_FRAME_FIELD( ft_frame_byte, s, f ) -#define FT_FRAME_CHAR( s, f ) FT_FRAME_FIELD( ft_frame_schar, s, f ) - -#define FT_FRAME_LONG_LE( s, f ) FT_FRAME_FIELD( ft_frame_long_le, s, f ) -#define FT_FRAME_ULONG_LE( s, f ) FT_FRAME_FIELD( ft_frame_ulong_le, s, f ) -#define FT_FRAME_SHORT_LE( s, f ) FT_FRAME_FIELD( ft_frame_short_le, s, f ) -#define FT_FRAME_USHORT_LE( s, f ) FT_FRAME_FIELD( ft_frame_ushort_le, s, f ) - -#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } -#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } -#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } - -#define FT_FRAME_BYTES( struct_type, field, count ) \ - { \ - ft_frame_bytes, \ - count, \ - (FT_UShort)(char*)&FT_FIELD_REF( struct_type, field ) \ - } -#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } - - - - /*************************************************************************/ - /* */ - /* integer extraction macros -- the `buffer' parameter must ALWAYS be of */ - /* type `char*' or equivalent (1-byte elements). */ - /* */ -#define NEXT_Char( buffer ) \ - ( (signed char)*buffer++ ) -#define NEXT_Byte( buffer ) \ - ( (unsigned char)*buffer++ ) - -#define NEXT_Short( buffer ) \ - ( buffer += 2, \ - ( (short)( (signed char)buffer[-2] << 8 ) | \ - (unsigned char)buffer[-1] ) ) - -#define NEXT_UShort( buffer ) \ - ( (unsigned short)NEXT_Short( buffer ) ) - -#define NEXT_Offset( buffer ) \ - ( buffer += 3, \ - ( ( (long)(signed char)buffer[-3] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-1] ) ) - -#define NEXT_UOffset( buffer ) \ - ( (unsigned long)NEXT_Offset( buffer ) ) - -#define NEXT_Long( buffer ) \ - ( buffer += 4, \ - ( ( (long)(signed char)buffer[-4] << 24 ) | \ - ( (long)(unsigned char)buffer[-3] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-1] ) ) - -#define NEXT_ULong( buffer ) \ - ( (unsigned long)NEXT_Long( buffer ) ) - - -#define NEXT_ShortLE( buffer ) \ - ( buffer += 2, \ - ( (short)( (signed char)buffer[-1] << 8 ) | \ - (unsigned char)buffer[-2] ) ) - -#define NEXT_UShortLE( buffer ) \ - ( (unsigned short)NEXT_ShortLE( buffer ) ) - -#define NEXT_OffsetLE( buffer ) \ - ( buffer += 3, \ - ( ( (long)(signed char)buffer[-1] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-3] ) ) - -#define NEXT_UOffsetLE( buffer ) \ - ( (unsigned long)NEXT_OffsetLE( buffer ) ) - - -#define NEXT_LongLE( buffer ) \ - ( buffer += 4, \ - ( ( (long)(signed char)buffer[-1] << 24 ) | \ - ( (long)(unsigned char)buffer[-2] << 16 ) | \ - ( (long)(unsigned char)buffer[-3] << 8 ) | \ - (long)(unsigned char)buffer[-4] ) ) - -#define NEXT_ULongLE( buffer ) \ - ( (unsigned long)NEXT_LongLE( buffer ) ) - - - /*************************************************************************/ - /* */ - /* Each GET_xxxx() macro uses an implicit `stream' variable. */ - /* */ -#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) - -#define GET_Char() FT_GET_MACRO( FT_Get_Char, FT_Char ) -#define GET_Byte() FT_GET_MACRO( FT_Get_Char, FT_Byte ) -#define GET_Short() FT_GET_MACRO( FT_Get_Short, FT_Short ) -#define GET_UShort() FT_GET_MACRO( FT_Get_Short, FT_UShort ) -#define GET_Offset() FT_GET_MACRO( FT_Get_Offset, FT_Long ) -#define GET_UOffset() FT_GET_MACRO( FT_Get_Offset, FT_ULong ) -#define GET_Long() FT_GET_MACRO( FT_Get_Long, FT_Long ) -#define GET_ULong() FT_GET_MACRO( FT_Get_Long, FT_ULong ) -#define GET_Tag4() FT_GET_MACRO( FT_Get_Long, FT_ULong ) - -#define GET_ShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_Short ) -#define GET_UShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_UShort ) -#define GET_LongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) -#define GET_ULongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) - -#define FT_READ_MACRO( func, type, var ) \ - ( var = (type)func( stream, &error ), \ - error != FT_Err_Ok ) - -#define READ_Byte( var ) FT_READ_MACRO( FT_Read_Char, FT_Byte, var ) -#define READ_Char( var ) FT_READ_MACRO( FT_Read_Char, FT_Char, var ) -#define READ_Short( var ) FT_READ_MACRO( FT_Read_Short, FT_Short, var ) -#define READ_UShort( var ) FT_READ_MACRO( FT_Read_Short, FT_UShort, var ) -#define READ_Offset( var ) FT_READ_MACRO( FT_Read_Offset, FT_Long, var ) -#define READ_UOffset( var ) FT_READ_MACRO( FT_Read_Offset, FT_ULong, var ) -#define READ_Long( var ) FT_READ_MACRO( FT_Read_Long, FT_Long, var ) -#define READ_ULong( var ) FT_READ_MACRO( FT_Read_Long, FT_ULong, var ) - -#define READ_ShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_Short, var ) -#define READ_UShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_UShort, var ) -#define READ_LongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_Long, var ) -#define READ_ULongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_ULong, var ) - - - BASE_DEF( void ) FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ); - - BASE_DEF( FT_Error ) FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ); - - BASE_DEF( FT_Error ) FT_Skip_Stream( FT_Stream stream, - FT_Long distance ); - - BASE_DEF( FT_Long ) FT_Stream_Pos( FT_Stream stream ); - - - BASE_DEF( FT_Error ) FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ); - - BASE_DEF( FT_Error ) FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ); - - BASE_DEF( FT_Error ) FT_Access_Frame( FT_Stream stream, - FT_ULong count ); - - BASE_DEF( void ) FT_Forget_Frame( FT_Stream stream ); - - BASE_DEF( FT_Error ) FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ); - - BASE_DEF( void ) FT_Release_Frame( FT_Stream stream, - FT_Byte** pbytes ); - - BASE_DEF( FT_Char ) FT_Get_Char( FT_Stream stream ); - - BASE_DEF( FT_Short ) FT_Get_Short( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_Offset( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_Long( FT_Stream stream ); - - BASE_DEF( FT_Short ) FT_Get_ShortLE( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_LongLE( FT_Stream stream ); - - - BASE_DEF( FT_Char ) FT_Read_Char( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Short ) FT_Read_Short( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_Offset( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_Long( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Short ) FT_Read_ShortLE( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_LongLE( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Error ) FT_Read_Fields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ); - - -#define USE_Stream( resource, stream ) \ - FT_SET_ERROR( FT_Open_Stream( resource, stream ) ) - -#define DONE_Stream( stream ) \ - FT_Done_Stream( stream ) - - -#define ACCESS_Frame( size ) \ - FT_SET_ERROR( FT_Access_Frame( stream, size ) ) - -#define FORGET_Frame() \ - FT_Forget_Frame( stream ) - -#define EXTRACT_Frame( size, bytes ) \ - FT_SET_ERROR( FT_Extract_Frame( stream, size, \ - (FT_Byte**)&(bytes) ) ) - -#define RELEASE_Frame( bytes ) \ - FT_Release_Frame( stream, (FT_Byte**)&(bytes) ) - -#define FILE_Seek( position ) \ - FT_SET_ERROR( FT_Seek_Stream( stream, position ) ) - -#define FILE_Skip( distance ) \ - FT_SET_ERROR( FT_Skip_Stream( stream, distance ) ) - -#define FILE_Pos() \ - FT_Stream_Pos( stream ) - -#define FILE_Read( buffer, count ) \ - FT_SET_ERROR( FT_Read_Stream( stream, \ - (FT_Byte*)buffer, \ - count ) ) - -#define FILE_Read_At( position, buffer, count ) \ - FT_SET_ERROR( FT_Read_Stream_At( stream, \ - position, \ - (FT_Byte*)buffer, \ - count ) ) - -#define READ_Fields( fields, object ) \ - ( ( error = FT_Read_Fields( stream, fields, object ) ) != FT_Err_Ok ) - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTSTREAM_H */ - - -/* END */ diff --git a/include/freetype/internal/psnames.h b/include/freetype/internal/psnames.h deleted file mode 100644 index ed86235..0000000 --- a/include/freetype/internal/psnames.h +++ /dev/null @@ -1,220 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.h */ -/* */ -/* High-level interface for the `PSNames' module (in charge of */ -/* various functions related to Postscript glyph names conversion). */ -/* */ -/* Copyright 1996-2000 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 PSNAMES_H -#define PSNAMES_H - - -#include - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicode_Value_Func */ - /* */ - /* */ - /* A function used to return the Unicode index corresponding to a */ - /* given glyph name. */ - /* */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* */ - /* The Unicode character index resp. the non-Unicode value 0xFFFF if */ - /* the glyph name has no known Unicode meaning. */ - /* */ - /* */ - /* This function is able to map several different glyph names to the */ - /* same Unicode value, according to the rules defined in the Adobe */ - /* Glyph List table. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_ULong (*PS_Unicode_Value_Func)( const char* glyph_name ); - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicode_Index_Func */ - /* */ - /* */ - /* A function used to return the glyph index corresponding to a given */ - /* Unicode value. */ - /* */ - /* */ - /* num_glyphs :: The number of glyphs in the face. */ - /* */ - /* glyph_names :: An array of glyph name pointers. */ - /* */ - /* unicode :: The Unicode value. */ - /* */ - /* */ - /* The glyph index resp. 0xFFFF if no glyph corresponds to this */ - /* Unicode value. */ - /* */ - /* */ - /* This function is able to recognize several glyph names per Unicode */ - /* value, according to the Adobe Glyph List. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_UInt (*PS_Unicode_Index_Func)( FT_UInt num_glyphs, - const char** glyph_names, - FT_ULong unicode ); - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Macintosh_Name_Func */ - /* */ - /* */ - /* A function used to return the glyph name corresponding to an Apple */ - /* glyph name index. */ - /* */ - /* */ - /* name_index :: The index of the Mac name. */ - /* */ - /* */ - /* The glyph name, or 0 if the index is invalid. */ - /* */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef const char* (*PS_Macintosh_Name_Func)( FT_UInt name_index ); - - - typedef const char* (*PS_Adobe_Std_Strings_Func)( FT_UInt string_index ); - - - typedef struct PS_UniMap_ - { - FT_UInt unicode; - FT_UInt glyph_index; - - } PS_UniMap; - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicodes */ - /* */ - /* */ - /* A simple table used to map Unicode values to glyph indices. It is */ - /* built by the PS_Build_Unicodes table according to the glyphs */ - /* present in a font file. */ - /* */ - /* */ - /* num_codes :: The number of glyphs in the font that match a given */ - /* Unicode value. */ - /* */ - /* unicodes :: An array of unicode values, sorted in increasing */ - /* order. */ - /* */ - /* gindex :: An array of glyph indices, corresponding to each */ - /* Unicode value. */ - /* */ - /* */ - /* Use the function PS_Lookup_Unicode() to retrieve the glyph index */ - /* corresponding to a given Unicode character code. */ - /* */ - typedef struct PS_Unicodes_ - { - FT_UInt num_maps; - PS_UniMap* maps; - - } PS_Unicodes; - - - typedef FT_Error (*PS_Build_Unicodes_Func)( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* unicodes ); - - typedef FT_UInt (*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes, - FT_UInt unicode ); - - - /*************************************************************************/ - /* */ - /* */ - /* PSNames_Interface */ - /* */ - /* */ - /* This structure defines the PSNames interface. */ - /* */ - /* */ - /* unicode_value :: A function used to convert a glyph name */ - /* into a Unicode character code. */ - /* */ - /* build_unicodes :: A function which builds up the Unicode */ - /* mapping table. */ - /* */ - /* lookup_unicode :: A function used to return the glyph index */ - /* corresponding to a given Unicode */ - /* character. */ - /* */ - /* macintosh_name :: A function used to return the standard */ - /* Apple glyph Postscript name corresponding */ - /* to a given string index (used by the */ - /* TrueType `post' table). */ - /* */ - /* adobe_std_strings :: A function that returns a pointer to a */ - /* Adobe Standard String for a given SID. */ - /* */ - /* adobe_std_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Standard */ - /* Encoding to SIDs. */ - /* */ - /* adobe_expert_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Expert */ - /* Encoding to SIDs. */ - /* */ - /* */ - /* `unicode_value' and `unicode_index' will be set to 0 if the */ - /* configuration macro FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is */ - /* undefined. */ - /* */ - /* `macintosh_name' will be set to 0 if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef struct PSNames_Interface_ - { - PS_Unicode_Value_Func unicode_value; - PS_Build_Unicodes_Func build_unicodes; - PS_Lookup_Unicode_Func lookup_unicode; - PS_Macintosh_Name_Func macintosh_name; - - PS_Adobe_Std_Strings_Func adobe_std_strings; - const unsigned short* adobe_std_encoding; - const unsigned short* adobe_expert_encoding; - - } PSNames_Interface; - - -#endif /* PSNAMES_H */ - - -/* END */ diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h deleted file mode 100644 index 380ee93..0000000 --- a/include/freetype/internal/sfnt.h +++ /dev/null @@ -1,492 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.h */ -/* */ -/* High-level `sfnt' driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 SFNT_H -#define SFNT_H - - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Face_Func */ - /* */ - /* */ - /* First part of the SFNT face object initialization. This will find */ - /* the face in a SFNT file or collection, and load its format tag in */ - /* face->format_tag. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* Once the format tag has been validated by the font driver, it */ - /* should then call the TT_Load_Face_Func() callback to read the rest */ - /* of the SFNT tables in the object. */ - /* */ - typedef - FT_Error (*TT_Init_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Face_Func */ - /* */ - /* */ - /* Second part of the SFNT face object initialization. This will */ - /* load the common SFNT tables (head, OS/2, maxp, metrics, etc.) in */ - /* the face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function must be called after TT_Init_Face_Func(). */ - /* */ - typedef - FT_Error (*TT_Load_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Face_Func */ - /* */ - /* */ - /* A callback used to delete the common SFNT data from a face. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* This function does NOT destroy the face object. */ - /* */ - typedef - void (*TT_Done_Face_Func)( TT_Face face ); - - - typedef - FT_Module_Interface (*SFNT_Get_Interface_Func)( FT_Module module, - const char* interface ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SFNT_Header_Func */ - /* */ - /* */ - /* Loads the header of a SFNT font file. Supports collections. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* This function checks that the header is valid by looking at the */ - /* values of `search_range', `entry_selector', and `range_shift'. */ - /* */ - typedef - FT_Error (*TT_Load_SFNT_Header_Func)( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Directory_Func */ - /* */ - /* */ - /* Loads the table directory into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be on the first byte after the 4-byte font */ - /* format tag. This is the case just after a call to */ - /* TT_Load_Format_Tag(). */ - /* */ - typedef - FT_Error (*TT_Load_Directory_Func)( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Any_Func */ - /* */ - /* */ - /* Loads any font table into client memory. */ - /* */ - /* */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The 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 :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* */ - /* buffer :: The address of target buffer. */ - /* */ - /* */ - /* TrueType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Any_Func)( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Image_Func */ - /* */ - /* */ - /* Loads a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* glyph_index :: The current glyph index. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* map :: The target pixmap. */ - /* */ - /* metrics :: A big sbit metrics structure for the glyph image. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ - typedef - FT_Error (*TT_Load_SBit_Image_Func)( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_PS_Name_Func */ - /* */ - /* */ - /* Gets the PostScript glyph name of a glyph. */ - /* */ - /* */ - /* index :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Get_PS_Name_Func)( TT_Face face, - FT_UInt index, - FT_String** PSname ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics_Func */ - /* */ - /* */ - /* Loads the horizontal or vertical header in a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Metrics_Func)( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Load_Func */ - /* */ - /* */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* stream :: A handle to the current stream object. */ - /* */ - /* */ - /* cmap :: A pointer to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - typedef - FT_Error (*TT_CharMap_Load_Func)( TT_Face face, - TT_CMapTable* cmap, - FT_Stream input ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Free_Func */ - /* */ - /* */ - /* Destroys a character mapping table. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_CharMap_Free_Func)( TT_Face face, - TT_CMapTable* cmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Table_Func */ - /* */ - /* */ - /* Loads a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function will use `face->goto_table' to seek the stream to */ - /* the start of the table. */ - /* */ - typedef - FT_Error (*TT_Load_Table_Func)( TT_Face face, - FT_Stream stream ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Table_Func */ - /* */ - /* */ - /* Frees a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - typedef - void (*TT_Free_Table_Func)( TT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* SFNT_Interface */ - /* */ - /* */ - /* This structure holds pointers to the functions used to load and */ - /* free the basic tables that are required in a `sfnt' font file. */ - /* */ - /* */ - /* Check the various xxx_Func() descriptions for details. */ - /* */ - typedef struct SFNT_Interface_ - { - TT_Goto_Table_Func goto_table; - - TT_Init_Face_Func init_face; - TT_Load_Face_Func load_face; - TT_Done_Face_Func done_face; - SFNT_Get_Interface_Func get_interface; - - TT_Load_Any_Func load_any; - TT_Load_SFNT_Header_Func load_sfnt_header; - TT_Load_Directory_Func load_directory; - - /* these functions are called by `load_face' but they can also */ - /* be called from external modules, if there is a need to do so */ - TT_Load_Table_Func load_header; - TT_Load_Metrics_Func load_metrics; - TT_Load_Table_Func load_charmaps; - TT_Load_Table_Func load_max_profile; - TT_Load_Table_Func load_os2; - TT_Load_Table_Func load_psnames; - - TT_Load_Table_Func load_names; - TT_Free_Table_Func free_names; - - /* optional tables */ - TT_Load_Table_Func load_hdmx; - TT_Free_Table_Func free_hdmx; - - TT_Load_Table_Func load_kerning; - TT_Load_Table_Func load_gasp; - TT_Load_Table_Func load_pclt; - - /* see `ttsbit.h' */ - TT_Load_Table_Func load_sbits; - TT_Load_SBit_Image_Func load_sbit_image; - TT_Free_Table_Func free_sbits; - - /* see `ttpost.h' */ - TT_Get_PS_Name_Func get_psname; - TT_Free_Table_Func free_psnames; - - /* see `ttcmap.h' */ - TT_CharMap_Load_Func load_charmap; - TT_CharMap_Free_Func free_charmap; - - } SFNT_Interface; - - -#endif /* SFNT_H */ - - -/* END */ diff --git a/include/freetype/internal/t1errors.h b/include/freetype/internal/t1errors.h deleted file mode 100644 index 58566d8..0000000 --- a/include/freetype/internal/t1errors.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1errors.h */ -/* */ -/* Type 1 error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 T1ERRORS_H -#define T1ERRORS_H - - - /************************ error codes declaration **************/ - - /* The error codes are grouped into `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 T1_Err_Ok FT_Err_Ok - - /* ----------- high level API errors -------- */ - -#define T1_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define T1_Err_Invalid_Argument FT_Err_Invalid_Argument -#define T1_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define T1_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define T1_Err_Invalid_Size_Handle FT_Err_Invalid_Size_Handle -#define T1_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define T1_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define T1_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define T1_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define T1_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* ------------- internal errors ------------ */ - -#define T1_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define T1_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* ------------ general glyph outline errors ------ */ - -#define T1_Err_Invalid_Composite FT_Err_Invalid_Composite - -#define T1_Err_Syntax_Error FT_Err_Invalid_File_Format -#define T1_Err_Stack_Underflow FT_Err_Invalid_File_Format -#define T1_Err_Stack_Overflow FT_Err_Invalid_File_Format - - -#endif /* T1ERRORS_H */ - - -/* END */ diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h deleted file mode 100644 index 4d41a6b..0000000 --- a/include/freetype/internal/t1types.h +++ /dev/null @@ -1,188 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1types.h */ -/* */ -/* Basic Type1/Type2 type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T1TYPES_H -#define T1TYPES_H - - -#include -#include - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Encoding */ - /* */ - /* */ - /* A structure modeling a custom encoding */ - /* */ - /* */ - /* num_chars :: The number of character codes in the encoding. */ - /* Usually 256. */ - /* */ - /* code_first :: The lowest valid character code in the encoding. */ - /* */ - /* code_last :: The highest valid character code in the encoding. */ - /* */ - /* char_index :: An array of corresponding glyph indices. */ - /* */ - /* char_name :: An array of corresponding glyph names. */ - /* */ - typedef struct T1_Encoding_ - { - FT_Int num_chars; - FT_Int code_first; - FT_Int code_last; - - FT_UShort* char_index; - FT_String** char_name; - - } T1_Encoding; - - - typedef enum T1_EncodingType_ - { - t1_encoding_none = 0, - t1_encoding_array, - t1_encoding_standard, - t1_encoding_expert - - } T1_EncodingType; - - - typedef struct T1_Font_ - { - - /* font info dictionary */ - T1_FontInfo font_info; - - /* private dictionary */ - T1_Private private_dict; - - /* top-level dictionary */ - FT_String* font_name; - - T1_EncodingType encoding_type; - T1_Encoding encoding; - - FT_Byte* subrs_block; - FT_Byte* charstrings_block; - FT_Byte* glyph_names_block; - - FT_Int num_subrs; - FT_Byte** subrs; - FT_Int* subrs_len; - - FT_Int num_glyphs; - FT_String** glyph_names; /* array of glyph names */ - FT_Byte** charstrings; /* array of glyph charstrings */ - FT_Int* charstrings_len; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - FT_BBox font_bbox; - FT_Long font_id; - - FT_Int stroke_width; - - } T1_Font; - - - typedef struct CID_Subrs_ - { - FT_UInt num_subrs; - FT_Byte** code; - - } CID_Subrs; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined normally in */ - /* `ttobjs.h'. */ - /* */ - /*************************************************************************/ - - typedef struct T1_FaceRec_* T1_Face; - typedef struct CID_FaceRec_* CID_Face; - - - typedef struct T1_FaceRec_ - { - FT_FaceRec root; - T1_Font type1; - void* psnames; - void* afm_data; - FT_CharMapRec charmaprecs[2]; - FT_CharMap charmaps[2]; - PS_Unicodes unicode_map; - - /* support for Multiple Masters fonts */ - T1_Blend* blend; - - } T1_FaceRec; - - - typedef struct CID_FaceRec_ - { - FT_FaceRec root; - void* psnames; - CID_Info cid; - void* afm_data; - CID_Subrs* subrs; - - } CID_FaceRec; - - -#endif /* T1TYPES_H */ - - -/* END */ diff --git a/include/freetype/internal/t2errors.h b/include/freetype/internal/t2errors.h deleted file mode 100644 index d685220..0000000 --- a/include/freetype/internal/t2errors.h +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2errors.h */ -/* */ -/* OpenType error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 T2ERRORS_H -#define T2ERRORS_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 T2_Err_Ok FT_Err_Ok - - /* High level API errors. */ - -#define T2_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define T2_Err_Invalid_Argument FT_Err_Invalid_Argument -#define T2_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define T2_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define T2_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle -#define T2_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define T2_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define T2_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define T2_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define T2_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* Internal errors. */ - -#define T2_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define T2_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* General glyph outline errors. */ - -#define T2_Err_Invalid_Composite FT_Err_Invalid_Composite - - /* 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 T2_Err_Invalid_Opcode 0x500 -#define T2_Err_Too_Few_Arguments 0x501 -#define T2_Err_Stack_Overflow 0x502 -#define T2_Err_Code_Overflow 0x503 -#define T2_Err_Bad_Argument 0x504 -#define T2_Err_Divide_By_Zero 0x505 -#define T2_Err_Storage_Overflow 0x506 -#define T2_Err_Cvt_Overflow 0x507 -#define T2_Err_Invalid_Reference 0x508 -#define T2_Err_Invalid_Distance 0x509 -#define T2_Err_Interpolate_Twilight 0x50A -#define T2_Err_Debug_OpCode 0x50B -#define T2_Err_ENDF_In_Exec_Stream 0x50C -#define T2_Err_Out_Of_CodeRanges 0x50D -#define T2_Err_Nested_DEFS 0x50E -#define T2_Err_Invalid_CodeRange 0x50F -#define T2_Err_Invalid_Displacement 0x510 -#define T2_Err_Execution_Too_Long 0x511 - -#define T2_Err_Too_Many_Instruction_Defs 0x512 -#define T2_Err_Too_Many_Function_Defs 0x513 - - /* Other TrueType specific error codes. */ - -#define T2_Err_Table_Missing 0x520 -#define T2_Err_Too_Many_Extensions 0x521 -#define T2_Err_Extensions_Unsupported 0x522 -#define T2_Err_Invalid_Extension_Id 0x523 - -#define T2_Err_No_Vertical_Data 0x524 - -#define T2_Err_Max_Profile_Missing 0x530 -#define T2_Err_Header_Table_Missing 0x531 -#define T2_Err_Horiz_Header_Missing 0x532 -#define T2_Err_Locations_Missing 0x533 -#define T2_Err_Name_Table_Missing 0x534 -#define T2_Err_CMap_Table_Missing 0x535 -#define T2_Err_Hmtx_Table_Missing 0x536 -#define T2_Err_OS2_Table_Missing 0x537 -#define T2_Err_Post_Table_Missing 0x538 - -#define T2_Err_Invalid_Horiz_Metrics 0x540 -#define T2_Err_Invalid_CharMap_Format 0x541 -#define T2_Err_Invalid_PPem 0x542 -#define T2_Err_Invalid_Vert_Metrics 0x543 - -#define T2_Err_Could_Not_Find_Context 0x550 - - -#endif /* T2ERRORS_H */ - - -/* END */ diff --git a/include/freetype/internal/t2types.h b/include/freetype/internal/t2types.h deleted file mode 100644 index 033f315..0000000 --- a/include/freetype/internal/t2types.h +++ /dev/null @@ -1,218 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2types.h */ -/* */ -/* Basic OpenType/CFF type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T2TYPES_H -#define T2TYPES_H - - -#include - - - /*************************************************************************/ - /* */ - /* */ - /* CFF_Index */ - /* */ - /* */ - /* A structure used to model a CFF Index table. */ - /* */ - /* */ - /* stream :: XXX */ - /* */ - /* count :: The number of elements in the index. */ - /* */ - /* off_size :: The size in bytes of object offsets in index. */ - /* */ - /* data_offset :: The position of first data byte in the index's */ - /* bytes. */ - /* */ - /* offsets :: XXX */ - /* */ - /* bytes :: If the index is loaded in memory, its bytes. */ - /* */ - typedef struct CFF_Index_ - { - FT_Stream stream; - FT_UInt count; - FT_Byte off_size; - FT_ULong data_offset; - - FT_ULong* offsets; - FT_Byte* bytes; - - } CFF_Index; - - - typedef struct CFF_Font_Dict_ - { - FT_UInt version; - FT_UInt notice; - FT_UInt copyright; - FT_UInt full_name; - FT_UInt family_name; - FT_UInt weight; - FT_Bool is_fixed_pitch; - FT_Fixed italic_angle; - FT_Pos underline_position; - FT_Pos underline_thickness; - FT_Int paint_type; - FT_Int charstring_type; - FT_Matrix font_matrix; - FT_ULong unique_id; - FT_BBox font_bbox; - FT_Pos stroke_width; - FT_ULong charset_offset; - FT_ULong encoding_offset; - FT_ULong charstrings_offset; - FT_ULong private_offset; - FT_ULong private_size; - FT_Long synthetic_base; - FT_UInt embedded_postscript; - FT_UInt base_font_name; - FT_UInt postscript; - - /* these should only be used for the top-level font dictionary */ - FT_UInt cid_registry; - FT_UInt cid_ordering; - FT_ULong cid_supplement; - - FT_Long cid_font_version; - FT_Long cid_font_revision; - FT_Long cid_font_type; - FT_Long cid_count; - FT_ULong cid_uid_base; - FT_ULong cid_fd_array_offset; - FT_ULong cid_fd_select_offset; - FT_UInt cid_font_name; - - } CFF_Font_Dict; - - - typedef struct CFF_Private_ - { - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Pos blue_values[14]; - FT_Pos other_blues[10]; - FT_Pos family_blues[14]; - FT_Pos family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Pos blue_shift; - FT_Pos blue_fuzz; - FT_Pos standard_width; - FT_Pos standard_height; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Pos snap_widths[13]; - FT_Pos snap_heights[13]; - FT_Bool force_bold; - FT_Fixed force_bold_threshold; - FT_Int lenIV; - FT_Int language_group; - FT_Fixed expansion_factor; - FT_Long initial_random_seed; - FT_ULong local_subrs_offset; - FT_Pos default_width; - FT_Pos nominal_width; - - } CFF_Private; - - - typedef struct CFF_FD_Select_ - { - FT_Byte format; - FT_UInt range_count; - - /* that's the table, taken from the file `as is' */ - FT_Byte* data; - FT_UInt data_size; - - /* small cache for format 3 only */ - FT_UInt cache_first; - FT_UInt cache_count; - FT_Byte cache_fd; - - } CFF_FD_Select; - - - /* A SubFont packs a font dict and a private dict together. They are */ - /* needed to support CID-keyed CFF fonts. */ - typedef struct CFF_SubFont_ - { - CFF_Font_Dict font_dict; - CFF_Private private_dict; - - CFF_Index local_subrs_index; - FT_UInt num_local_subrs; - FT_Byte** local_subrs; - - } CFF_SubFont; - - - /* maximum number of sub-fonts in a CID-keyed file */ -#define CFF_MAX_CID_FONTS 16 - - - typedef struct CFF_Font_ - { - FT_Stream stream; - FT_Memory memory; - FT_UInt num_faces; - FT_UInt num_glyphs; - - FT_Byte version_major; - FT_Byte version_minor; - FT_Byte header_size; - FT_Byte absolute_offsize; - - - CFF_Index name_index; - CFF_Index top_dict_index; - CFF_Index string_index; - CFF_Index global_subrs_index; - - /* we don't load the Encoding and CharSet tables */ - - CFF_Index charstrings_index; - CFF_Index font_dict_index; - CFF_Index private_index; - CFF_Index local_subrs_index; - - FT_String* font_name; - FT_UInt num_global_subrs; - FT_Byte** global_subrs; - - CFF_SubFont top_font; - FT_UInt num_subfonts; - CFF_SubFont* subfonts[CFF_MAX_CID_FONTS]; - - CFF_FD_Select fd_select; - - } CFF_Font; - - -#endif /* T2TYPES_H */ - - -/* END */ diff --git a/include/freetype/internal/tterrors.h b/include/freetype/internal/tterrors.h deleted file mode 100644 index b53e9f3..0000000 --- a/include/freetype/internal/tterrors.h +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* tterrors.h */ -/* */ -/* TrueType error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 TTERRORS_H -#define TTERRORS_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 FT_Err_Ok - - /* High level API errors. */ - -#define TT_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument -#define TT_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define TT_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle -#define TT_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define TT_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define TT_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define TT_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define TT_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* Internal errors. */ - -#define TT_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define TT_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* General glyph outline errors. */ - -#define TT_Err_Too_Many_Ins FT_Err_Too_Many_Hints -#define TT_Err_Invalid_Composite FT_Err_Invalid_Composite - - /* 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 -#define TT_Err_Too_Many_Function_Defs 0x412 -#define TT_Err_Too_Many_Instruction_Defs 0x413 - - /* Other TrueType specific error codes. */ - -#define TT_Err_Table_Missing 0x420 -#define TT_Err_Too_Many_Extensions 0x421 -#define TT_Err_Extensions_Unsupported 0x422 -#define TT_Err_Invalid_Extension_Id 0x423 - -#define TT_Err_No_Vertical_Data 0x424 - -#define TT_Err_Max_Profile_Missing 0x430 -#define TT_Err_Header_Table_Missing 0x431 -#define TT_Err_Horiz_Header_Missing 0x432 -#define TT_Err_Locations_Missing 0x433 -#define TT_Err_Name_Table_Missing 0x434 -#define TT_Err_CMap_Table_Missing 0x435 -#define TT_Err_Hmtx_Table_Missing 0x436 -#define TT_Err_OS2_Table_Missing 0x437 -#define TT_Err_Post_Table_Missing 0x438 - -#define TT_Err_Invalid_Horiz_Metrics 0x440 -#define TT_Err_Invalid_CharMap_Format 0x441 -#define TT_Err_Invalid_PPem 0x442 -#define TT_Err_Invalid_Vert_Metrics 0x443 - -#define TT_Err_Could_Not_Find_Context 0x450 - - -#endif /* TTERRORS_H */ - - -/* END */ diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h deleted file mode 100644 index 1fd43ce..0000000 --- a/include/freetype/internal/tttypes.h +++ /dev/null @@ -1,1582 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttypes.h */ -/* */ -/* Basic SFNT/TrueType type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 TTTYPES_H -#define TTTYPES_H - - -#include - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TTC_Header */ - /* */ - /* */ - /* TrueType collection header. This table contains the offsets of */ - /* the font headers of each distinct TrueType face in the file. */ - /* */ - /* */ - /* tag :: Must be `ttc ' to indicate a TrueType collection. */ - /* */ - /* version :: The version number. */ - /* */ - /* count :: The number of faces in the collection. The */ - /* specification says this should be an unsigned long, but */ - /* we use a signed long since we need the value -1 for */ - /* specific purposes. */ - /* */ - /* offsets :: The offsets of the font headers, one per face. */ - /* */ - typedef struct TTC_Header_ - { - FT_ULong tag; - FT_Fixed version; - FT_Long count; - FT_ULong* offsets; - - } TTC_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* SFNT_Header */ - /* */ - /* */ - /* SFNT file format header. */ - /* */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of tables in file. */ - /* */ - /* search_range :: Must be 16*(max power of 2 <= num_tables). */ - /* */ - /* entry_selector :: Must be log2 of search_range/16. */ - /* */ - /* range_shift :: Must be num_tables*16 - search_range. */ - /* */ - typedef struct SFNT_Header_ - { - FT_ULong format_tag; - FT_UShort num_tables; - FT_UShort search_range; - FT_UShort entry_selector; - FT_UShort range_shift; - - } SFNT_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_TableDir */ - /* */ - /* */ - /* This structure models a TrueType table directory. It is used to */ - /* access the various tables of the font face. */ - /* */ - /* */ - /* version :: The version number; starts with 0x00010000. */ - /* */ - /* numTables :: The number of tables. */ - /* */ - /* searchRange :: Unused. */ - /* */ - /* entrySelector :: Unused. */ - /* */ - /* rangeShift :: Unused. */ - /* */ - /* */ - /* This structure is only used during font opening. */ - /* */ - typedef struct TT_TableDir_ - { - FT_Fixed version; /* should be 0x10000 */ - FT_UShort numTables; /* number of tables */ - - FT_UShort searchRange; /* These parameters are only used */ - FT_UShort entrySelector; /* for a dichotomy search in the */ - FT_UShort rangeShift; /* directory. We ignore them. */ - - } TT_TableDir; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Table */ - /* */ - /* */ - /* This structure describes a given table of a TrueType font. */ - /* */ - /* */ - /* Tag :: A four-bytes tag describing the table. */ - /* */ - /* CheckSum :: The table checksum. This value can be ignored. */ - /* */ - /* Offset :: The offset of the table from the start of the TrueType */ - /* font in its resource. */ - /* */ - /* Length :: The table length (in bytes). */ - /* */ - typedef struct TT_Table_ - { - FT_ULong Tag; /* table type */ - FT_ULong CheckSum; /* table checksum */ - FT_ULong Offset; /* table file offset */ - FT_ULong Length; /* table length */ - - } TT_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CMapDir */ - /* */ - /* */ - /* This structure describes the directory of the `cmap' table, */ - /* containing the font's character mappings table. */ - /* */ - /* */ - /* tableVersionNumber :: The version number. */ - /* */ - /* numCMaps :: The number of charmaps in the font. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDir_ - { - FT_UShort tableVersionNumber; - FT_UShort numCMaps; - - } TT_CMapDir; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CMapDirEntry */ - /* */ - /* */ - /* This structure describes a charmap in a TrueType font. */ - /* */ - /* */ - /* platformID :: An ID used to specify for which platform this */ - /* charmap is defined (FreeType manages all platforms). */ - /* */ - /* encodingID :: A platform-specific ID used to indicate which source */ - /* encoding is used in this charmap. */ - /* */ - /* offset :: The offset of the charmap relative to the start of */ - /* the `cmap' table. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDirEntry_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_Long offset; - - } TT_CMapDirEntry; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_LongMetrics */ - /* */ - /* */ - /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ - /* TrueType tables. The values are expressed in font units. */ - /* */ - /* */ - /* advance :: The advance width or height for the glyph. */ - /* */ - /* bearing :: The left-side or top-side bearing for the glyph. */ - /* */ - typedef struct TT_LongMetrics_ - { - FT_UShort advance; - FT_Short bearing; - - } TT_LongMetrics; - - - /*************************************************************************/ - /* */ - /* TT_ShortMetrics */ - /* */ - /* */ - /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ - /* tables. */ - /* */ - typedef FT_Short TT_ShortMetrics; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_NameRec */ - /* */ - /* */ - /* A structure modeling TrueType name records. Name records are used */ - /* to store important strings like family name, style name, */ - /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ - /* etc). */ - /* */ - /* */ - /* platformID :: The ID of the name's encoding platform. */ - /* */ - /* encodingID :: The platform-specific ID for the name's encoding. */ - /* */ - /* languageID :: The platform-specific ID for the name's language. */ - /* */ - /* nameID :: The ID specifying what kind of name this is. */ - /* */ - /* stringLength :: The length of the string in bytes. */ - /* */ - /* stringOffset :: The offset to the string in the `name' table. */ - /* */ - /* string :: A pointer to the string's bytes. Note that these */ - /* are usually UTF-16 encoded characters. */ - /* */ - typedef struct TT_NameRec_ - { - FT_UShort platformID; - FT_UShort encodingID; - FT_UShort languageID; - FT_UShort nameID; - FT_UShort stringLength; - FT_UShort stringOffset; - - /* this last field is not defined in the spec */ - /* but used by the FreeType engine */ - - FT_Byte* string; - - } TT_NameRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_NameTable */ - /* */ - /* */ - /* A structure modeling the TrueType name table. */ - /* */ - /* */ - /* format :: The format of the name table. */ - /* */ - /* numNameRecords :: The number of names in table. */ - /* */ - /* storageOffset :: The offset of the name table in the `name' */ - /* TrueType table. */ - /* */ - /* names :: An array of name records. */ - /* */ - /* storage :: The names storage area. */ - /* */ - typedef struct TT_NameTable_ - { - FT_UShort format; - FT_UShort numNameRecords; - FT_UShort storageOffset; - TT_NameRec* names; - FT_Byte* storage; - - } TT_NameTable; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GaspRange */ - /* */ - /* */ - /* A tiny structure used to model a gasp range according to the */ - /* TrueType specification. */ - /* */ - /* */ - /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ - /* */ - /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ - /* modes to be used. */ - /* */ - typedef struct TT_GaspRange_ - { - FT_UShort maxPPEM; - FT_UShort gaspFlag; - - } TT_GaspRange; - - -#define TT_GASP_GRIDFIT 0x01 -#define TT_GASP_DOGRAY 0x02 - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Gasp */ - /* */ - /* */ - /* A structure modeling the TrueType `gasp' table used to specify */ - /* grid-fitting and anti-aliasing behaviour. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* numRanges :: The number of gasp ranges in table. */ - /* */ - /* gaspRanges :: An array of gasp ranges. */ - /* */ - typedef struct TT_Gasp_ - { - FT_UShort version; - FT_UShort numRanges; - TT_GaspRange* gaspRanges; - - } TT_Gasp; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_HdmxRec */ - /* */ - /* */ - /* A small structure used to model the pre-computed widths of a given */ - /* size. They are found in the `hdmx' table. */ - /* */ - /* */ - /* ppem :: The pixels per EM value at which these metrics apply. */ - /* */ - /* max_width :: The maximum advance width for this metric. */ - /* */ - /* widths :: An array of widths. Note: These are 8-bit bytes. */ - /* */ - typedef struct TT_HdmxRec_ - { - FT_Byte ppem; - FT_Byte max_width; - FT_Byte* widths; - - } TT_HdmxRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Hdmx */ - /* */ - /* */ - /* A structure used to model the `hdmx' table, which contains */ - /* pre-computed widths for a set of given sizes/dimensions. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* num_records :: The number of hdmx records. */ - /* */ - /* records :: An array of hdmx records. */ - /* */ - typedef struct TT_Hdmx_ - { - FT_UShort version; - FT_Short num_records; - TT_HdmxRec* records; - - } TT_Hdmx; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Kern_0_Pair */ - /* */ - /* */ - /* A structure used to model a kerning pair for the kerning table */ - /* format 0. The engine now loads this table if it finds one in the */ - /* font file. */ - /* */ - /* */ - /* left :: The index of the left glyph in pair. */ - /* */ - /* right :: The index of the right glyph in pair. */ - /* */ - /* value :: The kerning distance. A positive value spaces the */ - /* glyphs, a negative one makes them closer. */ - /* */ - typedef struct TT_Kern_0_Pair_ - { - FT_UShort left; /* index of left glyph in pair */ - FT_UShort right; /* index of right glyph in pair */ - FT_FWord value; /* kerning value */ - - } TT_Kern_0_Pair; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** EMBEDDED BITMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* 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' (Microsoft) or `bdat' (Apple) table. */ - /* */ - /* */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* horiBearingX :: The horizontal left bearing. */ - /* */ - /* horiBearingY :: The horizontal top bearing. */ - /* */ - /* horiAdvance :: The horizontal advance. */ - /* */ - /* vertBearingX :: The vertical left bearing. */ - /* */ - /* vertBearingY :: The vertical top bearing. */ - /* */ - /* vertAdvance :: The vertical advance. */ - /* */ - typedef struct TT_SBit_Metrics_ - { - FT_Byte height; - FT_Byte width; - - FT_Char horiBearingX; - FT_Char horiBearingY; - FT_Byte horiAdvance; - - FT_Char vertBearingX; - FT_Char vertBearingY; - FT_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' (Microsoft) or the `bdat' (Apple) table. */ - /* */ - /* */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* bearingX :: The left-side bearing. */ - /* */ - /* bearingY :: The top-side bearing. */ - /* */ - /* advance :: The advance width or height. */ - /* */ - typedef struct TT_SBit_Small_Metrics_ - { - FT_Byte height; - FT_Byte width; - - FT_Char bearingX; - FT_Char bearingY; - FT_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 a horizontal or vertical layout. */ - /* */ - /* */ - /* ascender :: The ascender in pixels. */ - /* */ - /* descender :: The descender in pixels. */ - /* */ - /* max_width :: The 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 */ - /* */ - /* horizontal advance - */ - /* ( horiBearingX + width ) */ - /* */ - /* resp. */ - /* */ - /* vertical advance - */ - /* ( vertBearingY + height ) */ - /* */ - /* max_before_BL :: Maximum of horiBearingY (resp. */ - /* vertBearingY). */ - /* */ - /* min_after_BL :: Minimum of */ - /* */ - /* horiBearingY - height */ - /* */ - /* resp. */ - /* */ - /* vertBearingX - width */ - /* */ - /* pads :: Unused (to make the size of the record */ - /* a multiple of 32 bits. */ - /* */ - typedef struct TT_SBit_Line_Metrics_ - { - FT_Char ascender; - FT_Char descender; - FT_Byte max_width; - FT_Char caret_slope_numerator; - FT_Char caret_slope_denominator; - FT_Char caret_offset; - FT_Char min_origin_SB; - FT_Char min_advance_SB; - FT_Char max_before_BL; - FT_Char min_after_BL; - FT_Char pads[2]; - - } TT_SBit_Line_Metrics; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Range */ - /* */ - /* */ - /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* */ - /* first_glyph :: The first glyph index in the range. */ - /* */ - /* last_glyph :: The last glyph index in the range. */ - /* */ - /* index_format :: The format of index table. Valid values are 1 */ - /* to 5. */ - /* */ - /* image_format :: The format of `EBDT' image data. */ - /* */ - /* image_offset :: The offset to image data in `EBDT'. */ - /* */ - /* image_size :: For index formats 2 and 5. This is the size in */ - /* bytes of each 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 :: The offset of the index table in the `EBLC' */ - /* table. Only used during strike loading. */ - /* */ - typedef struct TT_SBit_Range - { - FT_UShort first_glyph; - FT_UShort last_glyph; - - FT_UShort index_format; - FT_UShort image_format; - FT_ULong image_offset; - - FT_ULong image_size; - TT_SBit_Metrics metrics; - FT_ULong num_glyphs; - - FT_ULong* glyph_offsets; - FT_UShort* glyph_codes; - - FT_ULong table_offset; - - } TT_SBit_Range; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Strike */ - /* */ - /* */ - /* A structure used describe a given bitmap strike in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* */ - /* num_index_ranges :: The number of index ranges. */ - /* */ - /* index_ranges :: An array of glyph index ranges. */ - /* */ - /* color_ref :: Unused. A color reference? */ - /* */ - /* hori :: The line metrics for horizontal layouts. */ - /* */ - /* vert :: The line metrics for vertical layouts. */ - /* */ - /* start_glyph :: The lowest glyph index for this strike. */ - /* */ - /* end_glyph :: The highest glyph index for this strike. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ - /* and 8. */ - /* */ - /* flags :: Is this a vertical or horizontal strike? */ - /* */ - typedef struct TT_SBit_Strike_ - { - FT_Int num_ranges; - TT_SBit_Range* sbit_ranges; - FT_ULong ranges_offset; - - FT_ULong color_ref; - - TT_SBit_Line_Metrics hori; - TT_SBit_Line_Metrics vert; - - FT_UShort start_glyph; - FT_UShort end_glyph; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte bit_depth; - FT_Char flags; - - } TT_SBit_Strike; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Component */ - /* */ - /* */ - /* A simple structure to describe a compound sbit element. */ - /* */ - /* */ - /* glyph_code :: The element's glyph index. */ - /* */ - /* x_offset :: The element's left bearing. */ - /* */ - /* y_offset :: The element's top bearing. */ - /* */ - typedef struct TT_SBit_Component_ - { - FT_UShort glyph_code; - - FT_Char x_offset; - FT_Char y_offset; - - } TT_SBit_Component; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Scale */ - /* */ - /* */ - /* A structure used describe a given bitmap scaling table, as defined */ - /* in the `EBSC' table. */ - /* */ - /* */ - /* hori :: The horizontal line metrics. */ - /* */ - /* vert :: The vertical line metrics. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* x_ppem_substitute :: Substitution x_ppem value. */ - /* */ - /* y_ppem_substitute :: Substitution y_ppem value. */ - /* */ - typedef struct TT_SBit_Scale_ - { - TT_SBit_Line_Metrics hori; - TT_SBit_Line_Metrics vert; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte x_ppem_substitute; - FT_Byte y_ppem_substitute; - - } TT_SBit_Scale; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_20 */ - /* */ - /* */ - /* Postscript names sub-table, format 2.0. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* */ - /* num_glyphs :: The number of named glyphs in the table. */ - /* */ - /* num_names :: The number of PS names stored in the table. */ - /* */ - /* glyph_indices :: The indices of the glyphs in the names arrays. */ - /* */ - /* glyph_names :: The PS names not in Mac Encoding. */ - /* */ - typedef struct TT_Post_20_ - { - FT_UShort num_glyphs; - FT_UShort num_names; - FT_UShort* glyph_indices; - FT_Char** glyph_names; - - } TT_Post_20; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_25 */ - /* */ - /* */ - /* Postscript names sub-table, format 2.5. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* */ - /* num_glyphs :: The number of glyphs in the table. */ - /* */ - /* offsets :: An array of signed offsets in a normal Mac */ - /* Postscript name encoding. */ - /* */ - typedef struct TT_Post_25_ - { - FT_UShort num_glyphs; - FT_Char* offsets; - - } TT_Post_25; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_Names */ - /* */ - /* */ - /* Postscript names table, either format 2.0 or 2.5. */ - /* */ - /* */ - /* loaded :: A flag to indicate whether the PS names are loaded. */ - /* */ - /* format_20 :: The sub-table used for format 2.0. */ - /* */ - /* format_25 :: The sub-table used for format 2.5. */ - /* */ - typedef struct TT_Post_Names_ - { - FT_Bool loaded; - - union - { - TT_Post_20 format_20; - TT_Post_25 format_25; - - } names; - - } TT_Post_Names; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** TRUETYPE CHARMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* format 0 */ - - typedef struct TT_CMap0_ - { - FT_Byte* glyphIdArray; - - } TT_CMap0; - - - /* format 2 */ - - typedef struct TT_CMap2SubHeader_ - { - FT_UShort firstCode; /* first valid low byte */ - FT_UShort entryCount; /* number of valid low bytes */ - FT_Short idDelta; /* delta value to glyphIndex */ - FT_UShort idRangeOffset; /* offset from here to 1st code */ - - } TT_CMap2SubHeader; - - - typedef struct TT_CMap2_ - { - FT_UShort* subHeaderKeys; - /* high byte mapping table */ - /* value = subHeader index * 8 */ - - TT_CMap2SubHeader* subHeaders; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - } TT_CMap2; - - - /* format 4 */ - - typedef struct TT_CMap4Segment_ - { - FT_UShort endCount; - FT_UShort startCount; - FT_Short idDelta; - FT_UShort idRangeOffset; - - } TT_CMap4Segment; - - - typedef struct TT_CMap4_ - { - FT_UShort segCountX2; /* number of segments * 2 */ - FT_UShort searchRange; /* these parameters can be used */ - FT_UShort entrySelector; /* for a binary search */ - FT_UShort rangeShift; - - TT_CMap4Segment* segments; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - TT_CMap4Segment* last_segment; /* last used segment; this is a small */ - /* cache to potentially increase speed */ - } TT_CMap4; - - - /* format 6 */ - - typedef struct TT_CMap6_ - { - FT_UShort firstCode; /* first character code of subrange */ - FT_UShort entryCount; /* number of character codes in subrange */ - - FT_UShort* glyphIdArray; - - } TT_CMap6; - - - typedef struct TT_CMapTable_ TT_CMapTable; - - - typedef - FT_UInt (*TT_CharMap_Func)( TT_CMapTable* charmap, - FT_ULong char_code ); - - - /* charmap table */ - struct TT_CMapTable_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_UShort format; - FT_UShort length; - FT_UShort version; - - FT_Bool loaded; - FT_ULong offset; - - union - { - TT_CMap0 cmap0; - TT_CMap2 cmap2; - TT_CMap4 cmap4; - TT_CMap6 cmap6; - } c; - - TT_CharMap_Func get_index; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMapRec */ - /* */ - /* */ - /* The TrueType character map object type. */ - /* */ - /* */ - /* root :: The parent character map structure. */ - /* */ - /* cmap :: The used character map. */ - /* */ - typedef struct TT_CharMapRec_ - { - FT_CharMapRec root; - TT_CMapTable cmap; - - } TT_CharMapRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined normally in */ - /* `ttobjs.h'. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Face */ - /* */ - /* */ - /* A handle to a TrueType face/font object. A TT_Face encapsulates */ - /* the resolution and scaling independent parts of a TrueType font */ - /* resource. */ - /* */ - /* */ - /* The TT_Face structure is also used as a `parent class' for the */ - /* OpenType-CFF class (T2_Face). */ - /* */ - typedef struct TT_FaceRec_* TT_Face; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap */ - /* */ - /* */ - /* A handle to a TrueType character mapping object. */ - /* */ - typedef struct TT_CharMapRec_* TT_CharMap; - - - /* a function type used for the truetype bytecode interpreter hooks */ - typedef FT_Error (*TT_Interpreter)( void* exec_context ); - - /* forward declaration */ - typedef struct TT_Loader_ TT_Loader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_Table_Func */ - /* */ - /* */ - /* Seeks a stream to the start of a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* tag :: A 4-byte tag used to name the table. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* length :: The length of the table in bytes. Set to 0 if not */ - /* needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - typedef - FT_Error (*TT_Goto_Table_Func)( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Access_Glyph_Frame_Func */ - /* */ - /* */ - /* Seeks a stream to the start of a given glyph element, and opens a */ - /* frame for it. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* glyph index :: The index of the glyph to access. */ - /* */ - /* offset :: The offset of the glyph according to the */ - /* `locations' table. */ - /* */ - /* byte_count :: The size of the frame in bytes. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function is normally equivalent to FILE_Seek(offset) */ - /* followed by ACCESS_Frame(byte_count) with the loader's stream, but */ - /* alternative formats (e.g. compressed ones) might use something */ - /* different. */ - /* */ - typedef - FT_Error (*TT_Access_Glyph_Frame_Func)( TT_Loader* loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Glyph_Element_Func */ - /* */ - /* */ - /* Reads one glyph element (its header, a simple glyph, or a */ - /* composite) from the loader's current stream frame. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Glyph_Element_Func)( TT_Loader* loader ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Forget_Glyph_Frame_Func */ - /* */ - /* */ - /* Closes the current loader stream frame for the glyph. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - typedef - void (*TT_Forget_Glyph_Frame_Func)( TT_Loader* loader ); - - - - /*************************************************************************/ - /* */ - /* TrueType Face Type */ - /* */ - /* */ - /* TT_Face */ - /* */ - /* */ - /* The TrueType face class. These objects model the resolution and */ - /* point-size independent data found in a TrueType font file. */ - /* */ - /* */ - /* root :: The base FT_Face structure, managed by the */ - /* base layer. */ - /* */ - /* ttc_header :: The TrueType collection header, used when */ - /* the file is a `ttc' rather than a `ttf'. */ - /* For ordinary font files, the field */ - /* `ttc_header.count' is set to 0. */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of TrueType tables in this font */ - /* file. */ - /* */ - /* dir_tables :: The directory of TrueType tables for this */ - /* font file. */ - /* */ - /* header :: The font's font header (`head' table). */ - /* Read on font opening. */ - /* */ - /* horizontal :: The font's horizontal header (`hhea' */ - /* table). This field also contains the */ - /* associated horizontal metrics table */ - /* (`hmtx'). */ - /* */ - /* max_profile :: The font's maximum profile table. Read on */ - /* font opening. Note that some maximum */ - /* values cannot be taken directly from this */ - /* table. We thus define additional fields */ - /* below to hold the computed maxima. */ - /* */ - /* max_components :: The maximum number of glyph components */ - /* required to load any composite glyph from */ - /* this font. Used to size the load stack. */ - /* */ - /* vertical_info :: A boolean which is set when the font file */ - /* contains vertical metrics. If not, the */ - /* value of the `vertical' field is */ - /* undefined. */ - /* */ - /* vertical :: The font's vertical header (`vhea' table). */ - /* This field also contains the associated */ - /* vertical metrics table (`vmtx'), if found. */ - /* IMPORTANT: The contents of this field is */ - /* undefined if the `verticalInfo' field is */ - /* unset. */ - /* */ - /* num_names :: The number of name records within this */ - /* TrueType font. */ - /* */ - /* name_table :: The table of name records (`name'). */ - /* */ - /* os2 :: The font's OS/2 table (`OS/2'). */ - /* */ - /* postscript :: The font's PostScript table (`post' */ - /* table). The PostScript glyph names are */ - /* not loaded by the driver on face opening. */ - /* See the `ttpost' module for more details. */ - /* */ - /* num_charmaps :: The number of character mappings in the */ - /* font. */ - /* */ - /* charmaps :: The array of charmap objects for this font */ - /* file. Note that this field is a typeless */ - /* pointer. The Reason is that the format of */ - /* charmaps varies with the underlying font */ - /* format and cannot be determined here. */ - /* */ - /* goto_table :: A function called by each TrueType table */ - /* loader to position a stream's cursor to */ - /* the start of a given table according to */ - /* its tag. It defaults to TT_Goto_Face but */ - /* can be different for strange formats (e.g. */ - /* Type 42). */ - /* */ - /* access_glyph_frame :: XXX */ - /* */ - /* read_glyph_header :: XXX */ - /* */ - /* read_simple_glyph :: XXX */ - /* */ - /* read_composite_glyph :: XXX */ - /* */ - /* forget_glyph_frame :: XXX */ - /* */ - /* sfnt :: A pointer to the SFNT `driver' interface. */ - /* */ - /* psnames :: A pointer to the `PSNames' module */ - /* interface. */ - /* */ - /* hdmx :: The face's horizontal device metrics */ - /* (`hdmx' table). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* gasp :: The grid-fitting and scaling properties */ - /* table (`gasp'). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* pclt :: XXX */ - /* */ - /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ - /* sizes, embedded in this font. */ - /* */ - /* sbit_strikes :: An array of sbit strikes embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* num_sbit_scales :: The number of sbit scales for this font. */ - /* */ - /* sbit_scales :: Array of sbit scales embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* postscript_names :: A table used to store the Postscript names */ - /* of the glyphs for this font. See the */ - /* file `ttconfig.h' for comments on the */ - /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ - /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* font_program_size :: Size in bytecodes of the face's font */ - /* program. 0 if none defined. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* font_program :: The face's font program (bytecode stream) */ - /* executed at load time, also used during */ - /* glyph rendering. Comes from the `fpgm' */ - /* table. Ignored for Type 2 font fonts. */ - /* */ - /* cvt_program_size :: The size in bytecodes of the face's cvt */ - /* program. Ignored for Type 2 fonts. */ - /* */ - /* cvt_program :: The face's cvt program (bytecode stream) */ - /* executed each time an instance/size is */ - /* changed/reset. Comes from the `prep' */ - /* table. Ignored for Type 2 fonts. */ - /* */ - /* cvt_size :: Size of the control value table (in */ - /* entries). Ignored for Type 2 fonts. */ - /* */ - /* cvt :: The face's original control value table. */ - /* Coordinates are expressed in unscaled font */ - /* units. Comes from the `cvt ' table. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. You should use */ - /* the `ttxkern' structures if you want to */ - /* access other kerning tables. Ignored */ - /* for Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Only used by the */ - /* ttxkern extension to avoid data */ - /* duplication. Ignored for Type 2 fonts. */ - /* */ - /* interpreter :: A pointer to the TrueType bytecode */ - /* interpreters field is also used to hook */ - /* the debugger in `ttdebug'. */ - /* */ - /* extra :: XXX */ - /* */ - typedef struct TT_FaceRec_ - { - FT_FaceRec root; - - TTC_Header ttc_header; - - FT_ULong format_tag; - FT_UShort num_tables; - TT_Table* dir_tables; - - TT_Header header; /* TrueType header table */ - TT_HoriHeader horizontal; /* TrueType horizontal header */ - - TT_MaxProfile max_profile; - FT_ULong max_components; - - FT_Bool vertical_info; - TT_VertHeader vertical; /* TT Vertical header, if present */ - - FT_Int num_names; /* number of name records */ - TT_NameTable name_table; /* name table */ - - TT_OS2 os2; /* TrueType OS/2 table */ - TT_Postscript postscript; /* TrueType Postscript table */ - - FT_Int num_charmaps; - TT_CharMap charmaps; /* array of TT_CharMapRec */ - - TT_Goto_Table_Func goto_table; - - TT_Access_Glyph_Frame_Func access_glyph_frame; - TT_Load_Glyph_Element_Func read_glyph_header; - TT_Load_Glyph_Element_Func read_simple_glyph; - TT_Load_Glyph_Element_Func read_composite_glyph; - TT_Forget_Glyph_Frame_Func forget_glyph_frame; - - /* a typeless pointer to the SFNT_Interface table used to load */ - /* the basic TrueType tables in the face object */ - void* sfnt; - - /* a typeless pointer to the PSNames_Interface table used to */ - /* handle glyph names <-> unicode & Mac values */ - void* psnames; - - /***********************************************************************/ - /* */ - /* Optional TrueType/OpenType tables */ - /* */ - /***********************************************************************/ - - /* horizontal device metrics */ - TT_Hdmx hdmx; - - /* grid-fitting and scaling table */ - TT_Gasp gasp; /* the `gasp' table */ - - /* PCL 5 table */ - TT_PCLT pclt; - - /* embedded bitmaps support */ - FT_Int num_sbit_strikes; - TT_SBit_Strike* sbit_strikes; - - FT_Int num_sbit_scales; - TT_SBit_Scale* sbit_scales; - - /* postscript names table */ - TT_Post_Names postscript_names; - - - /***********************************************************************/ - /* */ - /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ - /* */ - /***********************************************************************/ - - /* the glyph locations */ - FT_UShort num_locations; - FT_Long* glyph_locations; - - /* the font program, if any */ - FT_ULong font_program_size; - FT_Byte* font_program; - - /* the cvt program, if any */ - FT_ULong cvt_program_size; - FT_Byte* cvt_program; - - /* the original, unscaled, control value table */ - FT_ULong cvt_size; - FT_Short* cvt; - - /* the format 0 kerning table, if any */ - FT_Int num_kern_pairs; - FT_Int kern_table_index; - TT_Kern_0_Pair* kern_pairs; - - /* A pointer to the bytecode interpreter to use. This is also */ - /* used to hook the debugger for the `ttdebug' utility. */ - TT_Interpreter interpreter; - - - /***********************************************************************/ - /* */ - /* Other tables or fields. This is used by derivative formats like */ - /* OpenType. */ - /* */ - /***********************************************************************/ - - FT_Generic extra; - - } TT_FaceRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GlyphZone */ - /* */ - /* */ - /* A glyph zone is used to load, scale and hint glyph outline */ - /* coordinates. */ - /* */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ - /* max_points :: The maximal size in points of the zone. */ - /* */ - /* max_contours :: Max size in links contours of thez one. */ - /* */ - /* n_points :: The current number of points in the zone. */ - /* */ - /* n_contours :: The current number of contours in the zone. */ - /* */ - /* org :: The original glyph coordinates (font */ - /* units/scaled). */ - /* */ - /* cur :: The current glyph coordinates (scaled/hinted). */ - /* */ - /* tags :: The point control tags. */ - /* */ - /* contours :: The contours end points. */ - /* */ - typedef struct TT_GlyphZone_ - { - FT_Memory memory; - FT_UShort max_points; - FT_UShort max_contours; - FT_UShort n_points; /* number of points in zone */ - FT_Short n_contours; /* number of contours */ - - FT_Vector* org; /* original point coordinates */ - FT_Vector* cur; /* current point coordinates */ - - FT_Byte* tags; /* current touch flags */ - FT_UShort* contours; /* contour end points */ - - } TT_GlyphZone; - - - /* handle to execution context */ - typedef struct TT_ExecContextRec_* TT_ExecContext; - - /* glyph loader structure */ - struct TT_Loader_ - { - FT_Face face; - FT_Size size; - FT_GlyphSlot glyph; - FT_GlyphLoader* gloader; - - FT_ULong load_flags; - FT_UInt glyph_index; - - FT_Stream stream; - FT_Int byte_len; - - FT_Short n_contours; - FT_BBox bbox; - FT_Int left_bearing; - FT_Int advance; - FT_Bool preserve_pps; - FT_Vector pp1; - FT_Vector pp2; - - FT_ULong glyf_offset; - - /* the zone where we load our glyphs */ - TT_GlyphZone base; - TT_GlyphZone zone; - - TT_ExecContext exec; - FT_Byte* instructions; - FT_ULong ins_pos; - - /* for possible extensibility in other formats */ - void* other; - - }; - - -#endif /* TTTYPES_H */ - - -/* END */ diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h deleted file mode 100644 index 323e013..0000000 --- a/include/freetype/t1tables.h +++ /dev/null @@ -1,235 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tables.h */ -/* */ -/* Basic Type 1/Type 2 tables definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T1TABLES_H -#define T1TABLES_H - - -#include - - - /* Note that we separate font data in T1_FontInfo and T1_Private */ - /* structures in order to support Multiple Master fonts. */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_FontInfo */ - /* */ - /* */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own */ - /* FontInfo. */ - /* */ - typedef struct T1_FontInfo - { - FT_String* version; - FT_String* notice; - FT_String* full_name; - FT_String* family_name; - FT_String* weight; - FT_Long italic_angle; - FT_Bool is_fixed_pitch; - FT_Short underline_position; - FT_UShort underline_thickness; - - } T1_FontInfo; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Private */ - /* */ - /* */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own Private */ - /* dict. */ - /* */ - typedef struct T1_Private - { - FT_Int unique_id; - FT_Int lenIV; - - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Short blue_values[14]; - FT_Short other_blues[10]; - - FT_Short family_blues [14]; - FT_Short family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Int blue_shift; - FT_Int blue_fuzz; - - FT_UShort standard_width[1]; - FT_UShort standard_height[1]; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Bool force_bold; - FT_Bool round_stem_up; - - FT_Short snap_widths [13]; /* reserve one place for the std */ - FT_Short snap_heights[13]; /* reserve one place for the std */ - - FT_Long language_group; - FT_Long password; - - FT_Short min_feature[2]; - - } T1_Private; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Blend_Flags */ - /* */ - /* */ - /* A set of flags used to indicate which fields are present in a */ - /* given blen dictionary (font info or private). Used to support */ - /* Multiple Masters fonts. */ - /* */ - typedef enum - { - /* required fields in a FontInfo blend dictionary */ - t1_blend_underline_position = 0, - t1_blend_underline_thickness, - t1_blend_italic_angle, - - /* required fields in a Private blend dictionary */ - t1_blend_blue_values, - t1_blend_other_blues, - t1_blend_standard_width, - t1_blend_standard_height, - t1_blend_stem_snap_widths, - t1_blend_stem_snap_heights, - t1_blend_blue_scale, - t1_blend_blue_shift, - t1_blend_family_blues, - t1_blend_family_other_blues, - t1_blend_force_bold, - - /* never remove */ - t1_blend_max - - } T1_Blend_Flags; - - - /* maximum number of Multiple Masters designs, as defined in the spec */ -#define T1_MAX_MM_DESIGNS 16 - - /* maximum number of Multiple Masters axes, as defined in the spec */ -#define T1_MAX_MM_AXIS 4 - - /* maximum number of elements in a design map */ -#define T1_MAX_MM_MAP_POINTS 20 - - - /* this structure is used to store the BlendDesignMap entry for an axis */ - typedef struct T1_DesignMap_ - { - FT_Byte num_points; - FT_Fixed* design_points; - FT_Fixed* blend_points; - - } T1_DesignMap; - - - typedef struct T1_Blend_ - { - FT_UInt num_designs; - FT_UInt num_axis; - - FT_String* axis_names[T1_MAX_MM_AXIS]; - FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - T1_DesignMap design_map[T1_MAX_MM_AXIS]; - - FT_Fixed* weight_vector; - FT_Fixed* default_weight_vector; - - T1_FontInfo* font_infos[T1_MAX_MM_DESIGNS + 1]; - T1_Private* privates [T1_MAX_MM_DESIGNS + 1]; - - FT_ULong blend_bitflags; - - } T1_Blend; - - - typedef struct CID_FontDict_ - { - T1_Private private_dict; - - FT_UInt len_buildchar; - FT_Fixed forcebold_threshold; - FT_Pos stroke_width; - FT_Fixed expansion_factor; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - - FT_UInt num_subrs; - FT_ULong subrmap_offset; - FT_Int sd_bytes; - - } CID_FontDict; - - - typedef struct CID_Info_ - { - FT_String* cid_font_name; - FT_Fixed cid_version; - FT_Int cid_font_type; - - FT_String* registry; - FT_String* ordering; - FT_Int supplement; - - T1_FontInfo font_info; - FT_BBox font_bbox; - FT_ULong uid_base; - - FT_Int num_xuid; - FT_ULong xuid[16]; - - - FT_ULong cidmap_offset; - FT_Int fd_bytes; - FT_Int gd_bytes; - FT_ULong cid_count; - - FT_Int num_dicts; - CID_FontDict* font_dicts; - - FT_ULong data_offset; - - } CID_Info; - - -#endif /* T1TABLES_H */ - - -/* END */ diff --git a/include/freetype/ttnameid.h b/include/freetype/ttnameid.h deleted file mode 100644 index 4890242..0000000 --- a/include/freetype/ttnameid.h +++ /dev/null @@ -1,698 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttmakeid.h */ -/* */ -/* TrueType name ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 TTNAMEID_H -#define TTNAMEID_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 /* deprecated */ -#define TT_PLATFORM_MICROSOFT 3 - - - /*************************************************************************/ - /* */ - /* Possible values of the platform specific encoding identifier field in */ - /* the name records of the TTF `name' table if the `platform' identifier */ - /* code is TT_PLATFORM_APPLE_UNICODE. */ - /* */ -#define TT_APPLE_ID_DEFAULT 0 -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ - - - /*************************************************************************/ - /* */ - /* Possible values of the platform specific encoding identifier field in */ - /* the name records of the TTF `name' table if 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 if the `platform' identifier */ - /* code is TT_PLATFORM_ISO. */ - /* */ - /* This use is now deprecated. */ - /* */ -#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 if 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 if 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_CYRILLIC_SCRIPT 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_MONGOLIAN_SCRIPT 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 - - -#if 0 /* these seem to be errors that have been dropped */ - -#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 -#define TT_MAC_LANGID_IRISH_GAELIC 141 - -#endif - - - /* The following codes are new as of 2000-03-10 */ -#define TT_MAC_LANGID_GALICIAN 140 -#define TT_MAC_LANGID_AFRIKAANS 141 -#define TT_MAC_LANGID_BRETON 142 -#define TT_MAC_LANGID_INUKTITUT 143 -#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 -#define TT_MAC_LANGID_MANX_GAELIC 145 -#define TT_MAC_LANGID_IRISH_GAELIC 146 -#define TT_MAC_LANGID_TONGAN 147 -#define TT_MAC_LANGID_GREEK_POLYTONIC 148 -#define TT_MAC_LANGID_GREELANDIC 149 -#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 - - - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if 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 - -/* The following code is new as of 2000-01-21 */ -#define TT_NAME_ID_SAMPLE_TEXT 19 - - - /*************************************************************************/ - /* */ - /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ - /* */ - /* Updated 02-Jul-2000. */ - /* */ - - /* General Scripts Area */ - - /* Bit 0 C0 Controls and Basic Latin */ -#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ - /* Bit 1 C1 Controls and Latin-1 Supplement */ -#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+00A0-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 + Extended Bopomofo */ -#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ - /* U+31A0-U+31BF */ - /* 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 + */ - /* CJK Radical Supplement + */ - /* Kangxi Radicals + */ - /* Ideographic Description + */ - /* CJK Unified Ideographs Extension A */ -#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ - /* U+2E80-U+2EFF */ - /* U+2F00-U+2FDF */ - /* U+2FF0-U+2FFF */ - /* U+34E0-U+4DB5 */ - - /* 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+FDFF */ - /* 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+FEFE */ - /* 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+FFF0-U+FFFD */ - /* Bit 70 Tibetan */ -#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FCF */ - /* Bit 71 Syriac */ -#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ - /* Bit 72 Thaana */ -#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ - /* Bit 73 Sinhala */ -#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ - /* Bit 74 Myanmar */ -#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ - /* Bit 75 Ethiopic */ -#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+12BF */ - /* Bit 76 Cherokee */ -#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ - /* Bit 77 Canadian Aboriginal Syllabics */ -#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+14DF */ - /* Bit 78 Ogham */ -#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ - /* Bit 79 Runic */ -#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ - /* Bit 80 Khmer */ -#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ - /* Bit 81 Mongolian */ -#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ - /* Bit 82 Braille */ -#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ - /* Bit 83 Yi + Yi Radicals */ -#define TT_UCR_YI (1L << 19) /* U+A000-U+A48C */ - /* U+A490-U+A4CF */ - - - /*************************************************************************/ - /* */ - /* 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 /* !HAVE_LIMIT_ON_IDENTS */ - - -#endif /* TTNAMEID_H */ - - -/* END */ diff --git a/include/freetype/tttables.h b/include/freetype/tttables.h deleted file mode 100644 index 27c46f3..0000000 --- a/include/freetype/tttables.h +++ /dev/null @@ -1,583 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttables.h */ -/* */ -/* Basic SFNT/TrueType tables definitions and interface */ -/* (specification only). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Header */ - /* */ - /* */ - /* A structure used to model a TrueType font header table. All */ - /* fields follow the TrueType specification. */ - /* */ - typedef struct TT_Header_ - { - FT_Fixed Table_Version; - FT_Fixed Font_Revision; - - FT_Long CheckSum_Adjust; - FT_Long Magic_Number; - - FT_UShort Flags; - FT_UShort Units_Per_EM; - - FT_Long Created [2]; - FT_Long Modified[2]; - - FT_Short xMin; - FT_Short yMin; - FT_Short xMax; - FT_Short yMax; - - FT_UShort Mac_Style; - FT_UShort Lowest_Rec_PPEM; - - FT_Short Font_Direction; - FT_Short Index_To_Loc_Format; - FT_Short Glyph_Data_Format; - - } TT_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_HoriHeader */ - /* */ - /* */ - /* A structure used to model a TrueType horizontal header, the `hhea' */ - /* table, as well as the corresponding horizontal metrics table, */ - /* i.e., the `hmtx' table. */ - /* */ - /* */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of all */ - /* glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoAscender' field */ - /* of the OS/2 table instead if you want */ - /* the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the distance */ - /* from the baseline to the bottom-most of */ - /* all glyph points found in the font. It */ - /* is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Width_Max :: This field is the maximum of all advance */ - /* widths found in the font. It can be */ - /* used to compute the maximum width of an */ - /* arbitrary string of text. */ - /* */ - /* min_Left_Side_Bearing :: The minimum left side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Right_Side_Bearing :: The minimum right side bearing of all */ - /* glyphs within the font. */ - /* */ - /* xMax_Extent :: The maximum horizontal extent (i.e., the */ - /* `width' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* Reserved :: 10 reserved bytes. */ - /* */ - /* metric_Data_Format :: Always 0. */ - /* */ - /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ - /* table -- this value can be smaller than */ - /* the total number of glyphs in the font. */ - /* */ - /* long_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_HoriHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Width_Max; /* advance width maximum */ - - FT_Short min_Left_Side_Bearing; /* minimum left-sb */ - FT_Short min_Right_Side_Bearing; /* minimum right-sb */ - FT_Short xMax_Extent; /* xmax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_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' table. */ - - void* long_metrics; - void* short_metrics; - - } TT_HoriHeader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_VertHeader */ - /* */ - /* */ - /* A structure used to model a TrueType vertical header, the `vhea' */ - /* table, as well as the corresponding vertical metrics table, i.e., */ - /* the `vmtx' table. */ - /* */ - /* */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of */ - /* all glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoAscender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the */ - /* distance from the baseline to the */ - /* bottom-most of all glyph points found */ - /* in the font. It is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Height_Max :: This field is the maximum of all */ - /* advance heights found in the font. It */ - /* can be used to compute the maximum */ - /* height of an arbitrary string of text. */ - /* */ - /* min_Top_Side_Bearing :: The minimum top side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ - /* glyphs within the font. */ - /* */ - /* yMax_Extent :: The maximum vertical extent (i.e., the */ - /* `height' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* Reserved :: 10 reserved bytes. */ - /* */ - /* metric_Data_Format :: Always 0. */ - /* */ - /* number_Of_HMetrics :: Number of VMetrics entries in the */ - /* `vmtx' table -- this value can be */ - /* smaller than the total number of glyphs */ - /* in the font. */ - /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_VertHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Height_Max; /* advance height maximum */ - - FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ - FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ - FT_Short yMax_Extent; /* xmax or ymax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_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; - - } TT_VertHeader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_OS2 */ - /* */ - /* */ - /* A structure used to model a TrueType OS/2 table. This is the long */ - /* table version. All fields comply to the TrueType specification. */ - /* */ - /* Note that we now support old Mac fonts which do not include an */ - /* OS/2 table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ - /* */ - typedef struct TT_OS2_ - { - FT_UShort version; /* 0x0001 - more or 0xFFFF */ - FT_Short xAvgCharWidth; - FT_UShort usWeightClass; - FT_UShort usWidthClass; - FT_Short fsType; - FT_Short ySubscriptXSize; - FT_Short ySubscriptYSize; - FT_Short ySubscriptXOffset; - FT_Short ySubscriptYOffset; - FT_Short ySuperscriptXSize; - FT_Short ySuperscriptYSize; - FT_Short ySuperscriptXOffset; - FT_Short ySuperscriptYOffset; - FT_Short yStrikeoutSize; - FT_Short yStrikeoutPosition; - FT_Short sFamilyClass; - - FT_Byte panose[10]; - - FT_ULong ulUnicodeRange1; /* Bits 0-31 */ - FT_ULong ulUnicodeRange2; /* Bits 32-63 */ - FT_ULong ulUnicodeRange3; /* Bits 64-95 */ - FT_ULong ulUnicodeRange4; /* Bits 96-127 */ - - FT_Char achVendID[4]; - - FT_UShort fsSelection; - FT_UShort usFirstCharIndex; - FT_UShort usLastCharIndex; - FT_Short sTypoAscender; - FT_Short sTypoDescender; - FT_Short sTypoLineGap; - FT_UShort usWinAscent; - FT_UShort usWinDescent; - - /* only version 1 tables: */ - - FT_ULong ulCodePageRange1; /* Bits 0-31 */ - FT_ULong ulCodePageRange2; /* Bits 32-63 */ - - /* only version 2 tables: */ - - FT_Short sxHeight; - FT_Short sCapHeight; - FT_UShort usDefaultChar; - FT_UShort usBreakChar; - FT_UShort usMaxContext; - - } TT_OS2; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Postscript */ - /* */ - /* */ - /* A structure used to model a TrueType Postscript table. All fields */ - /* comply to the TrueType table. This structure does not reference */ - /* the Postscript glyph names, which can be nevertheless accessed */ - /* with the `ttpost' module. */ - /* */ - typedef struct TT_Postscript_ - { - FT_Fixed FormatType; - FT_Fixed italicAngle; - FT_Short underlinePosition; - FT_Short underlineThickness; - FT_ULong isFixedPitch; - FT_ULong minMemType42; - FT_ULong maxMemType42; - FT_ULong minMemType1; - FT_ULong maxMemType1; - - /* Glyph names follow in the file, but we don't */ - /* load them by default. See the ttpost.c file. */ - - } TT_Postscript; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_PCLT */ - /* */ - /* */ - /* A structure used to model a TrueType PCLT table. All fields */ - /* comply to the TrueType table. */ - /* */ - typedef struct TT_PCLT_ - { - FT_Fixed Version; - FT_ULong FontNumber; - FT_UShort Pitch; - FT_UShort xHeight; - FT_UShort Style; - FT_UShort TypeFamily; - FT_UShort CapHeight; - FT_UShort SymbolSet; - FT_Char TypeFace[16]; - FT_Char CharacterComplement[8]; - FT_Char FileName[6]; - FT_Char StrokeWeight; - FT_Char WidthType; - FT_Byte SerifStyle; - FT_Byte Reserved; - - } TT_PCLT; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_MaxProfile */ - /* */ - /* */ - /* The maximum profile is a table containing many max values which */ - /* can be used to pre-allocate arrays. This ensures that no memory */ - /* allocation occurs during a glyph load. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* numGlyphs :: The number of glyphs in this TrueType */ - /* font. */ - /* */ - /* maxPoints :: The maximum number of points in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositePoints'. */ - /* */ - /* maxContours :: The maximum number of contours in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositeContours'. */ - /* */ - /* maxCompositePoints :: The maximum number of points in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxPoints'. */ - /* */ - /* maxCompositeContours :: The maximum number of contours in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxContours'. */ - /* */ - /* maxZones :: The maximum number of zones used for */ - /* glyph hinting. */ - /* */ - /* maxTwilightPoints :: The maximum number of points in the */ - /* twilight zone used for glyph hinting. */ - /* */ - /* maxStorage :: The maximum number of elements in the */ - /* storage area used for glyph hinting. */ - /* */ - /* maxFunctionDefs :: The maximum number of function */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxInstructionDefs :: The maximum number of instruction */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxStackElements :: The maximum number of stack elements used */ - /* during bytecode interpretation. */ - /* */ - /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ - /* used for glyph hinting. */ - /* */ - /* maxComponentElements :: An obscure value related to composite */ - /* glyphs definitions. */ - /* */ - /* maxComponentDepth :: An obscure value related to composite */ - /* glyphs definitions. Probably the maximum */ - /* number of simple glyphs in a composite. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_MaxProfile_ - { - FT_Fixed version; - FT_UShort numGlyphs; - FT_UShort maxPoints; - FT_UShort maxContours; - FT_UShort maxCompositePoints; - FT_UShort maxCompositeContours; - FT_UShort maxZones; - FT_UShort maxTwilightPoints; - FT_UShort maxStorage; - FT_UShort maxFunctionDefs; - FT_UShort maxInstructionDefs; - FT_UShort maxStackElements; - FT_UShort maxSizeOfInstructions; - FT_UShort maxComponentElements; - FT_UShort maxComponentDepth; - - } TT_MaxProfile; - - - typedef enum - { - ft_sfnt_head = 0, - ft_sfnt_maxp = 1, - ft_sfnt_os2 = 2, - ft_sfnt_hhea = 3, - ft_sfnt_vhea = 4, - ft_sfnt_post = 5, - ft_sfnt_pclt = 6, - - sfnt_max /* don't remove */ - - } FT_Sfnt_Tag; - - - /* internal use only */ - typedef void* (*FT_Get_Sfnt_Table_Func)( FT_Face face, - FT_Sfnt_Tag tag ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Sfnt_Table */ - /* */ - /* */ - /* Returns a pointer to a given SFNT table within a face. */ - /* */ - /* */ - /* face :: A handle to the source. */ - /* */ - /* tag :: The index of the SFNT table. */ - /* */ - /* */ - /* A type-less pointer to the table. This will be 0 in case of */ - /* error, or if the corresponding table was not found *OR* loaded */ - /* from the file. */ - /* */ - /* */ - /* The table is owned by the face object and disappears with it. */ - /* */ - /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt/truetype/opentype drivers. See FT_Sfnt_tag for a */ - /* list. */ - /* */ - /* You can load any table using the (internal) SFNT_Interface */ - /* structure -- this is available via FT_Get_Module_Interface(). */ - /* */ - FT_EXPORT_DEF( void* ) FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ); - -#ifdef __cplusplus - } -#endif - - -#endif /* TTTABLES_H */ - - -/* END */ diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h deleted file mode 100644 index 9de9810..0000000 --- a/include/freetype/tttags.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttags.h */ -/* */ -/* Tags for TrueType tables (specification only). */ -/* */ -/* Copyright 1996-2000 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 /* for MAKE_TT_TAG() */ - - -#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) -#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) -#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) -#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) -#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) -#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) -#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) -#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) -#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) -#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) -#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) -#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) -#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) -#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) -#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) -#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) -#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) -#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) -#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) -#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) -#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) -#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) -#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) -#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) -#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) -#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) -#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) -#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) -#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) -#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) -#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) -#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) -#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) -#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) -#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) -#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) - -#endif /* TTAGS_H */ - - -/* END */ diff --git a/include/fslib/vfatlib.h b/include/fslib/vfatlib.h new file mode 100755 index 0000000..c824638 --- /dev/null +++ b/include/fslib/vfatlib.h @@ -0,0 +1,28 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VFAT filesystem library + * FILE: include/fslib/vfatlib.h + * PURPOSE: Public definitions for vfat filesystem library + */ +#ifndef __VFATLIB_H +#define __VFATLIB_H + +#include + + +NTSTATUS +VfatInitialize(); + +NTSTATUS +VfatCleanup(); + +NTSTATUS +VfatFormat( + PUNICODE_STRING DriveRoot, + DWORD MediaFlag, + PUNICODE_STRING Label, + BOOL QuickFormat, + DWORD ClusterSize, + PFMIFSCALLBACK Callback); + +#endif /*__VFATLIB_H */ diff --git a/include/funcs.h b/include/funcs.h index 3c1798b..d4ce50b 100644 --- a/include/funcs.h +++ b/include/funcs.h @@ -7297,6 +7297,12 @@ SetConsoleOutputCP( UINT wCodePageID ); +BOOL +STDCALL +VerifyConsoleIoHandle( + HANDLE Handle + ); + DWORD STDCALL WNetConnectionDialog( HWND hwnd, diff --git a/include/getopt.h b/include/getopt.h index 43dc804..33c5e19 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -1,53 +1,3 @@ -/* temporary header for getopt. Please remove this file when MingW ships with - its own */ - -#ifndef __GETOPT_H_INCLUDED -#define __GETOPT_H_INCLUDED - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern char *optarg; -extern int optind, opterr, optopt; - -#define no_argument (0) -#define required_argument (1) -#define optional_argument (2) - -struct option -{ - const char *name; - int has_arg; - int *flag; - int val; -}; - -extern int getopt(int, char * const [], const char *); - -extern int getopt_long -( - int, - char * const [], - const char *, - const struct option *, - int * -); - -extern int getopt_long_only -( - int, - char * const [], - const char *, - const struct option *, - int * -); - -#ifdef __cplusplus -} -#endif - -#endif /* __GETOPT_H_INCLUDED */ +#include /* EOF */ diff --git a/include/kernel32/error.h b/include/kernel32/error.h index 384a280..7ad2d3c 100644 --- a/include/kernel32/error.h +++ b/include/kernel32/error.h @@ -4,9 +4,8 @@ #include #define NTOS_MODE_USER #include -DWORD -STDCALL -SetLastErrorByStatus ( - NTSTATUS Status - ); + +#define SetLastErrorByStatus(__S__) \ + ((void)SetLastError(RtlNtStatusToDosError(__S__))) + #endif /* _INCLUDE_KERNEL32_H */ diff --git a/include/kernel32/kernel32.h b/include/kernel32/kernel32.h index 1db3e0f..7c4befd 100644 --- a/include/kernel32/kernel32.h +++ b/include/kernel32/kernel32.h @@ -8,9 +8,17 @@ #ifdef NDEBUG #define DPRINT(args...) #define CHECKPOINT +#ifdef assert +#undef assert +#endif +#define assert(x) #else #define DPRINT(args...) do { DbgPrint("(KERNEL32:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT do { DbgPrint("(KERNEL32:%s:%d) Checkpoint\n",__FILE__,__LINE__); } while(0); +#ifdef assert +#undef assert +#endif +#define assert(x) do { if(!x) RtlAssert(x, __FILE__,__LINE__, ""); } while(0); #endif #define DPRINT1(args...) do { DbgPrint("(KERNEL32:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); diff --git a/include/msvcrt/ctype.h b/include/msvcrt/ctype.h index 877b993..09fa609 100644 --- a/include/msvcrt/ctype.h +++ b/include/msvcrt/ctype.h @@ -120,9 +120,9 @@ int iswupper(wint_t); int iswxdigit(wint_t); //wchar_t towlower(wchar_t); -wchar_t towupper(wchar_t); +//wchar_t towupper(wchar_t); int towlower(wint_t); -//int towupper(wint_t); +int towupper(wint_t); int isleadbyte(int); diff --git a/include/msvcrt/internal/tls.h b/include/msvcrt/internal/tls.h index b1ec17d..0b25f9e 100644 --- a/include/msvcrt/internal/tls.h +++ b/include/msvcrt/internal/tls.h @@ -5,6 +5,7 @@ #include #include +#include typedef struct _ThreadData { @@ -24,6 +25,8 @@ typedef struct _ThreadData int thresh; /* THRESHold in chars */ int mthresh; /* MTHRESHold in chars */ + EXCEPTION_RECORD *exc_record; /* Head of exception record list */ + } THREADDATA, *PTHREADDATA; diff --git a/include/msvcrt/sys/stat.h b/include/msvcrt/sys/stat.h index ab7dfed..888f902 100644 --- a/include/msvcrt/sys/stat.h +++ b/include/msvcrt/sys/stat.h @@ -85,34 +85,29 @@ typedef __WCHAR_TYPE__ wchar_t; */ struct stat { -#ifdef _MSVCRT_LIB_ - long st_dev; /* Equivalent to drive number 0=A 1=B ... */ -#else - short st_dev; /* Equivalent to drive number 0=A 1=B ... */ - short st_padding; /* Pad structure to equal msvcrt version req */ -#endif - short st_ino; /* Always zero ? */ - short st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - int st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - short st_rdev; /* Seems useless (not even filled in) */ - long st_size; /* File size in bytes */ - time_t st_atime; /* Accessed date (always 00:00 hrs local on FAT) */ - time_t st_mtime; /* Modified time */ - time_t st_ctime; /* Creation time */ + unsigned st_dev; /* Equivalent to drive number 0=A 1=B ... */ + short st_ino; /* Always zero ? */ + short st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + unsigned st_rdev; /* Seems useless (not even filled in) */ + long st_size; /* File size in bytes */ + time_t st_atime; /* Accessed date (always 00:00 hrs local on FAT) */ + time_t st_mtime; /* Modified time */ + time_t st_ctime; /* Creation time */ }; struct _stati64 { - short st_dev; /* Equivalent to drive number 0=A 1=B ... */ - short st_ino; /* Always zero ? */ - short st_mode; /* See above constants */ - short st_nlink; /* Number of links. */ - int st_uid; /* User: Maybe significant on NT ? */ - short st_gid; /* Group: Ditto */ - short st_rdev; /* Seems useless (not even filled in) */ + unsigned st_dev; /* Equivalent to drive number 0=A 1=B ... */ + short st_ino; /* Always zero ? */ + short st_mode; /* See above constants */ + short st_nlink; /* Number of links. */ + short st_uid; /* User: Maybe significant on NT ? */ + short st_gid; /* Group: Ditto */ + unsigned st_rdev; /* Seems useless (not even filled in) */ __int64 st_size; /* File size in bytes */ time_t st_atime; /* Accessed date (always 00:00 hrs local on FAT) */ time_t st_mtime; /* Modified time */ diff --git a/include/napi/i386/floatsave.h b/include/napi/i386/floatsave.h new file mode 100644 index 0000000..1785143 --- /dev/null +++ b/include/napi/i386/floatsave.h @@ -0,0 +1,11 @@ +#ifndef __NAPI_I386_FLOATSAVE_H__ +#define __NAPI_I386_FLOATSAVE_H__ + +#define FLOAT_SAVE_CONTROL (0xFFFF037F) +#define FLOAT_SAVE_STATUS (0xFFFF0000) +#define FLOAT_SAVE_TAG (0xFFFFFFFF) +#define FLOAT_SAVE_DATA (0xFFFF0000) + +#endif /* __NAPI_I386_FLOATSAVE_H__ */ + +/* EOF */ diff --git a/include/napi/i386/segment.h b/include/napi/i386/segment.h index 6034b60..a4dce78 100644 --- a/include/napi/i386/segment.h +++ b/include/napi/i386/segment.h @@ -9,345 +9,4 @@ #define PCR_SELECTOR (0x30) #define TEB_SELECTOR (0x38 + 0x3) -//#define USER_CS (0x8+0x3) -//#define USER_DS (0x10+0x3) -//#define ZERO_DS 0x18 -//#define KERNEL_CS 0x20 -//#define KERNEL_DS 0x28 - -#ifndef __ASSEMBLY__ - -/* - * Uh, these should become the main single-value transfer routines.. - * They automatically use the right size if we just have the right - * pointer type.. - */ -#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))) -#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))) - -/* - * This is a silly but good way to make sure that - * the __put_user function is indeed always optimized, - * and that we use the correct sizes.. - */ -extern int bad_user_access_length(void); - -/* - * dummy pointer type structure.. gcc won't try to do something strange - * this way.. - */ -struct __segment_dummy { unsigned long a[100]; }; -#define __sd(x) ((struct __segment_dummy *) (x)) -#define __const_sd(x) ((const struct __segment_dummy *) (x)) - -static inline void __put_user(unsigned long x, void * y, int size) -{ - switch (size) { - case 1: - __asm__ ("movb %b1,%%fs:%0" \ - :"=m" (*__sd(y)) \ - :"iq" ((unsigned char) x), "m" (*__sd(y))); - break; - case 2: - __asm__ ("movw %w1,%%fs:%0" \ - :"=m" (*__sd(y)) \ - :"ir" ((unsigned short) x), "m" (*__sd(y))); - break; - case 4: - __asm__ ("movl %1,%%fs:%0" \ - :"=m" (*__sd(y)) \ - :"ir" (x), "m" (*__sd(y))); - break; - default: - bad_user_access_length(); - } -} - -static inline unsigned long __get_user(const void * y, int size) -{ - unsigned long result; - - switch (size) { - case 1: - __asm__ ("movb %%fs:%1,%b0" \ - :"=q" (result) \ - :"m" (*__const_sd(y))); - return (unsigned char) result; - case 2: - __asm__ ("movw %%fs:%1,%w0" \ - :"=r" (result) \ - :"m" (*__const_sd(y))); - return (unsigned short) result; - case 4: - __asm__ ("movl %%fs:%1,%0" \ - :"=r" (result) \ - :"m" (*__const_sd(y))); - return result; - default: - return bad_user_access_length(); - } -} - -static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - __asm__ volatile - (" cld \ - push %%es \ - push %%fs \ - cmpl $3,%0 \ - pop %%es \ - jbe 1f \ - movl %%edi,%%ecx \ - negl %%ecx \ - andl $3,%%ecx \ - subl %%ecx,%0 \ - rep; movsb \ - movl %0,%%ecx \ - shrl $2,%%ecx \ - rep; movsl \ - andl $3,%0 \ - 1: movl %0,%%ecx \ - rep; movsb \ - pop %%es" \ - :"=abd" (n) \ - :"0" (n),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si"); -} - -static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - __put_user(*(const char *) from, (char *) to, 1); - return; - case 2: - __put_user(*(const short *) from, (short *) to, 2); - return; - case 3: - __put_user(*(const short *) from, (short *) to, 2); - __put_user(*(2+(const char *) from), 2+(char *) to, 1); - return; - case 4: - __put_user(*(const int *) from, (int *) to, 4); - return; - case 8: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - return; - case 12: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - __put_user(*(2+(const int *) from), 2+(int *) to, 4); - return; - case 16: - __put_user(*(const int *) from, (int *) to, 4); - __put_user(*(1+(const int *) from), 1+(int *) to, 4); - __put_user(*(2+(const int *) from), 2+(int *) to, 4); - __put_user(*(3+(const int *) from), 3+(int *) to, 4); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "push %%es\n\t" \ - "push %%fs\n\t" \ - "pop %%es\n\t" \ - "rep ; movsl\n\t" \ - x \ - "pop %%es" \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("movsb\n\t"); - return; - case 2: - COMMON("movsw\n\t"); - return; - case 3: - COMMON("movsw\n\tmovsb\n\t"); - return; - } -#undef COMMON -} - -static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - __asm__ volatile - (" cld \ - cmpl $3,%0 \ - jbe 1f \ - movl %%edi,%%ecx \ - negl %%ecx \ - andl $3,%%ecx \ - subl %%ecx,%0 \ - fs; rep; movsb \ - movl %0,%%ecx \ - shrl $2,%%ecx \ - fs; rep; movsl \ - andl $3,%0 \ - 1: movl %0,%%ecx \ - fs; rep; movsb" - :"=abd" (n) - :"0" (n),"D" ((long) to),"S" ((long) from) - :"cx","di","si", "memory"); -} - -static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) -{ - switch (n) { - case 0: - return; - case 1: - *(char *)to = __get_user((const char *) from, 1); - return; - case 2: - *(short *)to = __get_user((const short *) from, 2); - return; - case 3: - *(short *) to = __get_user((const short *) from, 2); - *((char *) to + 2) = __get_user(2+(const char *) from, 1); - return; - case 4: - *(int *) to = __get_user((const int *) from, 4); - return; - case 8: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - return; - case 12: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - *(2+(int *) to) = __get_user(2+(const int *) from, 4); - return; - case 16: - *(int *) to = __get_user((const int *) from, 4); - *(1+(int *) to) = __get_user(1+(const int *) from, 4); - *(2+(int *) to) = __get_user(2+(const int *) from, 4); - *(3+(int *) to) = __get_user(3+(const int *) from, 4); - return; - } -#define COMMON(x) \ -__asm__("cld\n\t" \ - "rep ; fs ; movsl\n\t" \ - x \ - : /* no outputs */ \ - :"c" (n/4),"D" ((long) to),"S" ((long) from) \ - :"cx","di","si","memory") - - switch (n % 4) { - case 0: - COMMON(""); - return; - case 1: - COMMON("fs ; movsb"); - return; - case 2: - COMMON("fs ; movsw"); - return; - case 3: - COMMON("fs ; movsw\n\tfs ; movsb"); - return; - } -#undef COMMON -} - -#define memcpy_fromfs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_fromfs((to),(from),(n)) : \ - __generic_memcpy_fromfs((to),(from),(n))) - -#define memcpy_tofs(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_memcpy_tofs((to),(from),(n)) : \ - __generic_memcpy_tofs((to),(from),(n))) - -/* - * These are deprecated.. - * - * Use "put_user()" and "get_user()" with the proper pointer types instead. - */ - -#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1) -#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2) -#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4) - -#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1) -#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2) -#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4) - -#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE - -static inline unsigned short get_user_word(const short *addr) -{ - return __get_user(addr, 2); -} - -static inline unsigned char get_user_byte(const char * addr) -{ - return __get_user(addr,1); -} - -static inline unsigned long get_user_long(const int *addr) -{ - return __get_user(addr, 4); -} - -static inline void put_user_byte(char val,char *addr) -{ - __put_user(val, addr, 1); -} - -static inline void put_user_word(short val,short * addr) -{ - __put_user(val, addr, 2); -} - -static inline void put_user_long(unsigned long val,int * addr) -{ - __put_user(val, addr, 4); -} - -#endif - -/* - * Someone who knows GNU asm better than I should double check the following. - * It seems to work, but I don't know if I'm doing something subtly wrong. - * --- TYT, 11/24/91 - * [ nothing wrong here, Linus: I just changed the ax to be any reg ] - */ - -static inline unsigned long get_fs(void) -{ - unsigned long _v; - __asm__("mov %%fs,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline unsigned long get_ds(void) -{ - unsigned long _v; - __asm__("mov %%ds,%w0":"=r" (_v):"0" (0)); - return _v; -} - -static inline void set_fs(unsigned long val) -{ - __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val)); -} - -static inline void set_ds(unsigned long val) -{ - __asm__ __volatile__("mov %w0,%%ds": /* no output */ :"r" (val)); -} - - -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_SEGMENT_H */ diff --git a/include/napi/teb.h b/include/napi/teb.h index b570639..0cf8beb 100644 --- a/include/napi/teb.h +++ b/include/napi/teb.h @@ -187,9 +187,9 @@ typedef struct _TEB PVOID SystemReserved1[0x36]; // CCh PVOID Spare1; // 1A4h LONG ExceptionCode; // 1A8h - ULONG SpareBytes1[0x28]; // 1ACh + UCHAR SpareBytes1[0x28]; // 1ACh PVOID SystemReserved2[0xA]; // 1D4h -// GDI_TEB_BATCH GdiTebBatch; // 1FCh + GDI_TEB_BATCH GdiTebBatch; // 1FCh ULONG gdiRgn; // 6DCh ULONG gdiPen; // 6E0h ULONG gdiBrush; // 6E4h @@ -220,7 +220,7 @@ typedef struct _TEB PVOID Instrumentation[0x10]; // F2Ch PVOID WinSockData; // F6Ch ULONG GdiBatchCount; // F70h - ULONG Spare2; // F74h + ULONG Spare2; // F74h // NOTE: RtlExitUserThread writes something here ULONG Spare3; // F78h ULONG Spare4; // F7Ch PVOID ReservedForOle; // F80h @@ -228,19 +228,78 @@ typedef struct _TEB PVOID WineDebugInfo; // Needed for WINE DLL's } TEB, *PTEB; +/* FIXME: at least NtCurrentTeb should be defined in winnt.h */ -#define NtCurrentPeb() (NtCurrentTeb()->Peb) +#ifndef NtCurrentTeb -static inline PTEB NtCurrentTeb(VOID) +#if defined(_M_IX86) +/* on the x86, the TEB is contained in the FS segment */ +/* + FIXME: GCC should allow defining a variable that directly maps to a register. + It could make for even faster code +*/ +static inline struct _TEB * NtCurrentTeb(void) { - int x; - - __asm__ __volatile__("movl %%fs:0x18, %0\n\t" - : "=r" (x) /* can't have two memory operands */ - : /* no inputs */ - ); - - return((PTEB)x); + struct _TEB * pTeb; + + /* FIXME: instead of hardcoded offsets, use offsetof() - if possible */ + __asm__ __volatile__ + ( + "movl %%fs:0x18, %0\n" /* fs:18h == Teb->Tib.Self */ + : "=r" (pTeb) /* can't have two memory operands */ + : /* no inputs */ + ); + + return pTeb; } +#define NtCurrentTeb NtCurrentTeb + +#elif defined(_M_ALPHA) + +void * __rdteb(void); +#pragma intrinsic(__rdteb) + +/* on the Alpha AXP, we call the rdteb PAL to retrieve the address of the TEB */ +#define NtCurrentTeb() ((struct _TEB *)__rdteb()) + +#elif defined(_M_MIPS) + +/* on the MIPS R4000, the TEB is loaded at a fixed address */ +#define NtCurrentTeb() ((struct _TEB *)0x7FFFF4A8) + +#elif defined(_M_PPC) + +unsigned __gregister_get(unsigned const regnum); +#pragma intrinsic(__gregister_get) + +/* on the PowerPC, the TEB is pointed to by GPR 13 */ +#define NtCurrentTeb() ((struct _TEB *)__gregister_get(13)) + +#else +#error Unsupported architecture or no architecture specified. +#endif + +#endif + +#ifdef _M_IX86 + +static inline struct _PEB * NtCurrentPeb(void) +{ + struct _PEB * pPeb; + + __asm__ __volatile__ + ( + "movl %%fs:0x30, %0\n" /* fs:30h == Teb->Peb */ + : "=r" (pPeb) /* can't have two memory operands */ + : /* no inputs */ + ); + + return pPeb; +} + +#else +/* generic NtCurrentPeb() */ +#define NtCurrentPeb() (NtCurrentTeb()->Peb) +#endif #endif /* __INCLUDE_INTERNAL_TEB */ diff --git a/include/net/ndis.h b/include/net/ndis.h index 168ff97..b88a48a 100644 --- a/include/net/ndis.h +++ b/include/net/ndis.h @@ -2625,17 +2625,17 @@ NdisWriteConfiguration( IN PNDIS_STRING Keyword, IN PNDIS_CONFIGURATION_PARAMETER *ParameterValue); -/* + VOID EXPIMP NdisWriteErrorLogEntry( IN NDIS_HANDLE NdisAdapterHandle, IN NDIS_ERROR_CODE ErrorCode, IN ULONG NumberOfErrorValues, - IN ULONG ...); -*/ - - + IN ULONG ERROR_LOG_MAXIMUM_SIZE); +/* IN ULONG ...); + * ERROR_LOG_MAXIMUM_SIZE = ... in MSDN + */ /* * VOID NdisStallExecution( diff --git a/include/ntdll/dbg.h b/include/ntdll/dbg.h index 3ac7a75..d905f2e 100644 --- a/include/ntdll/dbg.h +++ b/include/ntdll/dbg.h @@ -34,6 +34,10 @@ DbgUiWaitStateChange ( ULONG Unknown2 ); +NTSTATUS STDCALL DbgUiRemoteBreakin(VOID); + +NTSTATUS STDCALL DbgUiIssueRemoteBreakin(HANDLE Process); + #endif /* __INCLUDE_NTDLL_DBG_H */ /* EOF */ diff --git a/include/ntdll/rtl.h b/include/ntdll/rtl.h index b42877f..be0fad9 100644 --- a/include/ntdll/rtl.h +++ b/include/ntdll/rtl.h @@ -339,6 +339,8 @@ RtlCreateUserThread ( IN OUT PCLIENT_ID ClientId ); +NTSTATUS STDCALL RtlExitUserThread(NTSTATUS Status); + NTSTATUS STDCALL RtlFreeUserThreadStack ( @@ -576,6 +578,19 @@ RtlpNtSetValueKey ( IN ULONG DataLength ); + +VOID NTAPI RtlRunDecodeUnicodeString +( + IN UCHAR hash, + IN OUT PUNICODE_STRING uString +); + +VOID NTAPI RtlRunEncodeUnicodeString +( + IN OUT PUCHAR hash, + IN OUT PUNICODE_STRING uString +); + #ifndef __NTDRIVER__ #ifndef __INTERLOCKED_DECLARED diff --git a/include/ntos/rtl.h b/include/ntos/rtl.h index a1f0f2e..8d6baa0 100755 --- a/include/ntos/rtl.h +++ b/include/ntos/rtl.h @@ -28,6 +28,26 @@ #define RTL_QUERY_REGISTRY_DIRECT (0x00000020) #define RTL_QUERY_REGISTRY_DELETE (0x00000040) + +/* + * PURPOSE: Flags used by RtlIsTextUnicode and IsTextUnicode + */ +#define IS_TEXT_UNICODE_ASCII16 (0x00000001) +#define IS_TEXT_UNICODE_REVERSE_ASCII16 (0x00000010) +#define IS_TEXT_UNICODE_STATISTICS (0x00000002) +#define IS_TEXT_UNICODE_REVERSE_STATISTICS (0x00000020) +#define IS_TEXT_UNICODE_CONTROLS (0x00000004) +#define IS_TEXT_UNICODE_REVERSE_CONTROLS (0x00000040) +#define IS_TEXT_UNICODE_SIGNATURE (0x00000008) +#define IS_TEXT_UNICODE_REVERSE_SIGNATURE (0x00000080) +#define IS_TEXT_UNICODE_ILLEGAL_CHARS (0x00000100) +#define IS_TEXT_UNICODE_ODD_LENGTH (0x00000200) +#define IS_TEXT_UNICODE_NULL_BYTES (0x00001000) +#define IS_TEXT_UNICODE_UNICODE_MASK (0x0000000F) +#define IS_TEXT_UNICODE_REVERSE_MASK (0x000000F0) +#define IS_TEXT_UNICODE_NOT_UNICODE_MASK (0x00000F00) +#define IS_TEXT_UNICODE_NOT_ASCII_MASK (0x0000F000) + /* * VOID * InitializeObjectAttributes ( @@ -1217,7 +1237,7 @@ RtlInitializeContext ( IN PCONTEXT Context, IN PVOID Parameter, IN PTHREAD_START_ROUTINE StartAddress, - IN OUT PINITIAL_TEB InitialTeb + IN OUT PUSER_STACK UserStack ); VOID @@ -1267,6 +1287,11 @@ RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName, IN PANSI_STRING AnsiName, OUT PBOOLEAN SpacesFound); +ULONG STDCALL +RtlIsTextUnicode (PVOID Buffer, + ULONG Length, + ULONG *Flags); + LARGE_INTEGER STDCALL RtlLargeIntegerAdd ( diff --git a/include/ntos/rtltypes.h b/include/ntos/rtltypes.h index 7532839..dbe9b71 100755 --- a/include/ntos/rtltypes.h +++ b/include/ntos/rtltypes.h @@ -129,14 +129,14 @@ typedef struct _RTL_SPLAY_LINKS #endif /* __USE_W32API */ -typedef struct _INITIAL_TEB +typedef struct _USER_STACK { - ULONG StackCommit; - ULONG StackReserve; - PVOID StackBase; - PVOID StackLimit; - PVOID StackAllocate; -} INITIAL_TEB, *PINITIAL_TEB; + PVOID FixedStackBase; + PVOID FixedStackLimit; + PVOID ExpandableStackBase; + PVOID ExpandableStackLimit; + PVOID ExpandableStackBottom; +} USER_STACK, *PUSER_STACK; typedef struct _RTL_HEAP_DEFINITION { @@ -220,4 +220,8 @@ typedef struct _RTL_MESSAGE_RESOURCE_DATA RTL_MESSAGE_RESOURCE_BLOCK Blocks[1]; } RTL_MESSAGE_RESOURCE_DATA, *PRTL_MESSAGE_RESOURCE_DATA; +typedef VOID STDCALL +(*PRTL_BASE_PROCESS_START_ROUTINE)(PTHREAD_START_ROUTINE StartAddress, + PVOID Parameter); + #endif /* __DDK_RTLTYPES_H */ diff --git a/include/ntos/synch.h b/include/ntos/synch.h index be138d4..a77a880 100644 --- a/include/ntos/synch.h +++ b/include/ntos/synch.h @@ -27,6 +27,9 @@ #define TIMER_ALL_ACCESS (0x1f0003L) #define TIMER_QUERY_STATE (1) #define TIMER_MODIFY_STATE (2) +#define IO_COMPLETION_QUERY_STATE (0x0001) +#define IO_COMPLETION_MODIFY_STATE (0x0002) +#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) #endif /* !__USE_W32API */ diff --git a/include/ntos/types.h b/include/ntos/types.h index 3efeef3..e7739af 100644 --- a/include/ntos/types.h +++ b/include/ntos/types.h @@ -61,28 +61,12 @@ typedef short SHORT; #endif /*i386*/ -#ifdef _WIN64 - -/* 64-bit architecture */ - -typedef INT64 INT, *PINT; -typedef LONG64 LONG, *PLONG; -typedef DWORD64 DWORD, *PDWORD; -typedef UINT64 UINT, *PUINT; -typedef ULONG64 ULONG, *PULONG; - -#else /* _WIN64 */ - -/* 32-bit architecture */ - typedef INT32 INT, *PINT; typedef LONG32 LONG, *PLONG; -typedef DWORD32 DWORD, *PDWORD; +typedef ULONG32 DWORD, *PDWORD; typedef UINT32 UINT, *PUINT; typedef ULONG32 ULONG, *PULONG; -#endif /* _WIN64 */ - #ifndef _WCHAR_T_ #define _WCHAR_T_ #define _WCHAR_T @@ -231,8 +215,12 @@ typedef unsigned short *PRTL_ATOM; #endif /* __USE_W32API */ +#ifndef FALSE #define FALSE 0 +#endif +#ifndef TRUE #define TRUE 1 +#endif #ifndef NULL #ifdef __cplusplus diff --git a/include/ntos/zw.h b/include/ntos/zw.h index 0799a2b..b5fd42b 100755 --- a/include/ntos/zw.h +++ b/include/ntos/zw.h @@ -497,21 +497,20 @@ ZwCreateFile( NTSTATUS STDCALL NtCreateIoCompletion( - OUT PHANDLE CompletionPort, - IN ACCESS_MASK DesiredAccess, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfConcurrentThreads - ); + OUT PHANDLE IoCompletionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG NumberOfConcurrentThreads + ); NTSTATUS STDCALL ZwCreateIoCompletion( - OUT PHANDLE CompletionPort, - IN ACCESS_MASK DesiredAccess, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfConcurrentThreads - ); - + OUT PHANDLE IoCompletionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG NumberOfConcurrentThreads + ); /* * FUNCTION: Creates a registry key @@ -2357,20 +2356,22 @@ ZwQueryInformationToken( NTSTATUS STDCALL NtQueryIoCompletion( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG NumberOfBytesTransferred - ); + IN HANDLE IoCompletionHandle, + IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, + OUT PVOID IoCompletionInformation, + IN ULONG IoCompletionInformationLength, + OUT PULONG ResultLength OPTIONAL + ); + NTSTATUS STDCALL ZwQueryIoCompletion( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG NumberOfBytesTransferred - ); - + IN HANDLE IoCompletionHandle, + IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, + OUT PVOID IoCompletionInformation, + IN ULONG IoCompletionInformationLength, + OUT PULONG ResultLength OPTIONAL + ); /* * FUNCTION: Queries the information of a registry key object. @@ -2990,22 +2991,23 @@ ZwReleaseSemaphore( NTSTATUS STDCALL NtRemoveIoCompletion( - IN HANDLE CompletionPort, - OUT PULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG CompletionStatus, - IN PLARGE_INTEGER WaitTime - ); + IN HANDLE IoCompletionHandle, + OUT PULONG CompletionKey, + OUT PULONG CompletionValue, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER Timeout OPTIONAL + ); NTSTATUS STDCALL ZwRemoveIoCompletion( - IN HANDLE CompletionPort, - OUT PULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG CompletionStatus, - IN PLARGE_INTEGER WaitTime - ); + IN HANDLE IoCompletionHandle, + OUT PULONG CompletionKey, + OUT PULONG CompletionValue, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER Timeout OPTIONAL + ); + /* * FUNCTION: Replaces one registry key with another * ARGUMENTS: @@ -3392,21 +3394,22 @@ ZwSetInformationToken( NTSTATUS STDCALL NtSetIoCompletion( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfBytesToTransfer, - OUT PULONG NumberOfBytesTransferred - ); + IN HANDLE IoCompletionPortHandle, + IN ULONG CompletionKey, + IN ULONG CompletionValue, + IN NTSTATUS CompletionStatus, + IN ULONG CompletionInformation + ); + NTSTATUS STDCALL ZwSetIoCompletion( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfBytesToTransfer, - OUT PULONG NumberOfBytesTransferred - ); + IN HANDLE IoCompletionPortHandle, + IN ULONG CompletionKey, + IN ULONG CompletionValue, + IN NTSTATUS CompletionStatus, + IN ULONG CompletionInformation + ); /* * FUNCTION: Set properties for profiling @@ -4311,31 +4314,6 @@ ZwQuerySystemTime ( ); /* - * FUNCTION: Loads a registry key. - * ARGUMENTS: - * KeyHandle = Handle to the registry key - * ObjectAttributes = ??? - * Unknown3 = ??? - * REMARK: - * This procedure maps to the win32 procedure RegLoadKey - * RETURNS: Status - */ -NTSTATUS -STDCALL -NtLoadKey2 ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG Unknown3 - ); -NTSTATUS -STDCALL -ZwLoadKey2 ( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - ULONG Unknown3 - ); - -/* * FUNCTION: Copies a handle from one process space to another * ARGUMENTS: * SourceProcessHandle = The source process owning the handle. The source process should have opened @@ -4536,7 +4514,7 @@ NtCreateThread( IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, + IN PUSER_STACK UserStack, IN BOOLEAN CreateSuspended ); @@ -4549,7 +4527,7 @@ ZwCreateThread( IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, + IN PUSER_STACK UserStack, IN BOOLEAN CreateSuspended ); @@ -4674,39 +4652,64 @@ ZwGetTickCount( /* * FUNCTION: Loads a registry key. * ARGUMENTS: - * KeyHandle = Handle to the registry key - * ObjectAttributes = ??? + * KeyObjectAttributes = Key to be loaded + * FileObjectAttributes = File to load the key from * REMARK: * This procedure maps to the win32 procedure RegLoadKey * RETURNS: Status */ NTSTATUS -STDCALL +STDCALL NtLoadKey( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes + IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes ); NTSTATUS -STDCALL +STDCALL ZwLoadKey( - PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes + IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes ); /* - * FUNCTION: Locks a range of virtual memory. + * FUNCTION: Loads a registry key. + * ARGUMENTS: + * KeyObjectAttributes = Key to be loaded + * FileObjectAttributes = File to load the key from + * Flags = ??? + * REMARK: + * This procedure maps to the win32 procedure RegLoadKey + * RETURNS: Status + */ +NTSTATUS +STDCALL +NtLoadKey2( + IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes, + IN ULONG Flags + ); +NTSTATUS +STDCALL +ZwLoadKey2( + IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes, + IN ULONG Flags + ); + +/* + * FUNCTION: Locks a range of virtual memory. * ARGUMENTS: * ProcessHandle = Handle to the process - * BaseAddress = Lower boundary of the range of bytes to lock. + * BaseAddress = Lower boundary of the range of bytes to lock. * NumberOfBytesLock = Offset to the upper boundary. * NumberOfBytesLocked (OUT) = Number of bytes actually locked. * REMARK: - This procedure maps to the win32 procedure VirtualLock + This procedure maps to the win32 procedure VirtualLock. * RETURNS: Status [STATUS_SUCCESS | STATUS_WAS_LOCKED ] */ NTSTATUS -STDCALL +STDCALL NtLockVirtualMemory( HANDLE ProcessHandle, PVOID BaseAddress, @@ -4715,7 +4718,7 @@ NtLockVirtualMemory( ); NTSTATUS -STDCALL +STDCALL ZwLockVirtualMemory( HANDLE ProcessHandle, PVOID BaseAddress, @@ -4966,21 +4969,21 @@ ZwQueryObject( NTSTATUS STDCALL NtQuerySecurityObject( - IN HANDLE Object, - IN CINT SecurityObjectInformationClass, - OUT PVOID SecurityObjectInformation, + IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Length, - OUT PULONG ReturnLength + OUT PULONG ResultLength ); NTSTATUS STDCALL ZwQuerySecurityObject( - IN HANDLE Object, - IN CINT SecurityObjectInformationClass, - OUT PVOID SecurityObjectInformation, + IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Length, - OUT PULONG ReturnLength + OUT PULONG ResultLength ); /* @@ -5210,13 +5213,13 @@ ZwSetTimer( NTSTATUS STDCALL NtUnloadKey( - HANDLE KeyHandle + IN POBJECT_ATTRIBUTES KeyObjectAttributes ); NTSTATUS STDCALL ZwUnloadKey( - HANDLE KeyHandle + IN POBJECT_ATTRIBUTES KeyObjectAttributes ); /* @@ -5265,7 +5268,7 @@ STDCALL NtWaitForMultipleObjects ( IN ULONG Count, IN HANDLE Object[], - IN CINT WaitType, + IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER Time ); @@ -5275,7 +5278,7 @@ STDCALL ZwWaitForMultipleObjects ( IN ULONG Count, IN HANDLE Object[], - IN CINT WaitType, + IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER Time ); diff --git a/include/ntos/zwtypes.h b/include/ntos/zwtypes.h index cc1fe02..9bd7d74 100755 --- a/include/ntos/zwtypes.h +++ b/include/ntos/zwtypes.h @@ -301,8 +301,18 @@ struct _SYSTEM_PERFORMANCE_INFORMATION // SystemModuleInformation (11) typedef -struct _SYSTEM_MODULE_ENTRY +struct _SYSTEM_MODULE_INFORMATION { + ULONG Reserved[2]; + PVOID Base; + SIZE_T Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; +#if 0 ULONG Unknown1; ULONG Unknown2; PVOID BaseAddress; @@ -312,14 +322,15 @@ struct _SYSTEM_MODULE_ENTRY USHORT NameLength; /* Length of module name not including the path, this field contains valid value only for NTOSKRNL module*/ USHORT PathLength; /* Length of 'directory path' part of modulename*/ CHAR Name [256]; -} SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY; +#endif +} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION; typedef -struct _SYSTEM_MODULE_INFORMATION +struct _SYSTEM_MODULES { - ULONG Count; - SYSTEM_MODULE_ENTRY Module [1]; -} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + SIZE_T Count; + SYSTEM_MODULE_INFORMATION Modules[ANYSIZE_ARRAY]; +} SYSTEM_MODULES, *PSYSTEM_MODULES; // SystemHandleInformation (16) // (see ontypes.h) @@ -608,9 +619,9 @@ typedef struct _QUOTA_LIMITS // Information class 2 typedef struct _IO_COUNTERS { - ULONG ReadOperationCount; - ULONG WriteOperationCount; - ULONG OtherOperationCount; + LARGE_INTEGER ReadOperationCount; + LARGE_INTEGER WriteOperationCount; + LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; @@ -721,10 +732,10 @@ typedef struct _OBJECT_NAME_INFORMATION typedef struct _FILE_BASIC_INFORMATION { - TIME CreationTime; - TIME LastAccessTime; - TIME LastWriteTime; - TIME ChangeTime; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; ULONG FileAttributes; } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; @@ -881,6 +892,11 @@ typedef struct _FILE_COMPRESSION_INFORMATION { UCHAR Reserved[3]; } FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION; +typedef struct _FILE_COMPLETION_INFORMATION { // Information Class 30 + HANDLE IoCompletionHandle; + ULONG CompletionKey; +} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION; + typedef struct _FILE_ALL_INFORMATION { FILE_BASIC_INFORMATION BasicInformation; FILE_STANDARD_INFORMATION StandardInformation; @@ -1069,6 +1085,14 @@ typedef enum SHUTDOWN_ACTION_TAG { ShutdownPowerOff } SHUTDOWN_ACTION; +typedef enum _IO_COMPLETION_INFORMATION_CLASS { + IoCompletionBasicInformation +} IO_COMPLETION_INFORMATION_CLASS; + +typedef struct _IO_COMPLETION_BASIC_INFORMATION { + LONG SignalState; +} IO_COMPLETION_BASIC_INFORMATION, *PIO_COMPLETION_BASIC_INFORMATION; + #else /* __USE_W32API */ #define DebugDbgLoadSymbols ((DEBUG_CONTROL_CODE)0xffffffff) @@ -1200,53 +1224,61 @@ struct _SYSTEM_PATH_INFORMATION } SYSTEM_PATH_INFORMATION, * PSYSTEM_PATH_INFORMATION; // SystemProcessInformation (5) -typedef -struct _SYSTEM_THREAD_INFORMATION -{ - TIME KernelTime; - TIME UserTime; - TIME CreateTime; - ULONG TickCount; - ULONG StartEIP; - CLIENT_ID ClientId; - ULONG DynamicPriority; - ULONG BasePriority; - ULONG nSwitches; - DWORD State; - KWAIT_REASON WaitReason; - -} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; -typedef -struct SYSTEM_PROCESS_INFORMATION -{ - ULONG RelativeOffset; - ULONG ThreadCount; - ULONG Unused1 [6]; - TIME CreateTime; - TIME UserTime; - TIME KernelTime; - UNICODE_STRING Name; - ULONG BasePriority; - ULONG ProcessId; - ULONG ParentProcessId; - ULONG HandleCount; - ULONG Unused2[2]; - ULONG PeakVirtualSizeBytes; - ULONG TotalVirtualSizeBytes; - ULONG PageFaultCount; - ULONG PeakWorkingSetSizeBytes; - ULONG TotalWorkingSetSizeBytes; - ULONG PeakPagedPoolUsagePages; - ULONG TotalPagedPoolUsagePages; - ULONG PeakNonPagedPoolUsagePages; - ULONG TotalNonPagedPoolUsagePages; - ULONG TotalPageFileUsageBytes; - ULONG PeakPageFileUsageBytes; - ULONG TotalPrivateBytes; - SYSTEM_THREAD_INFORMATION ThreadSysInfo [1]; - -} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; +typedef struct _SYSTEM_THREADS +{ + TIME KernelTime; + TIME UserTime; + TIME CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + KPRIORITY BasePriority; + ULONG ContextSwitchCount; + ULONG State; + KWAIT_REASON WaitReason; +} SYSTEM_THREADS, *PSYSTEM_THREADS; + +typedef struct _SYSTEM_PROCESSES_NT4 +{ + SIZE_T NextEntryDelta; + ULONG ThreadCount; + ULONG Reserved1[6]; + TIME CreateTime; + TIME UserTime; + TIME KernelTime; + UNICODE_STRING ProcessName; + KPRIORITY BasePriority; + ULONG ProcessId; + ULONG InheritedFromProcessId; + ULONG HandleCount; + ULONG Reserved2[2]; + VM_COUNTERS VmCounters; + SYSTEM_THREADS Threads[ANYSIZE_ARRAY]; +} SYSTEM_PROCESSES_NT4, *PSYSTEM_PROCESSES_NT4; + +typedef struct _SYSTEM_PROCESSES_NT5 +{ + SIZE_T NextEntryDelta; + ULONG ThreadCount; + ULONG Reserved1[6]; + TIME CreateTime; + TIME UserTime; + TIME KernelTime; + UNICODE_STRING ProcessName; + KPRIORITY BasePriority; + ULONG ProcessId; + ULONG InheritedFromProcessId; + ULONG HandleCount; + ULONG Reserved2[2]; + VM_COUNTERS VmCounters; + IO_COUNTERS IoCounters; + SYSTEM_THREADS Threads[ANYSIZE_ARRAY]; +} SYSTEM_PROCESSES_NT5, *PSYSTEM_PROCESSES_NT5; + +/* Not sure. What version are we emulating? */ +typedef SYSTEM_PROCESSES_NT5 SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; // SystemCallCountInformation (6) typedef diff --git a/include/reactos/version.h b/include/reactos/version.h index 2580f07..7b9d253 100644 --- a/include/reactos/version.h +++ b/include/reactos/version.h @@ -19,9 +19,9 @@ #define KERNEL_VERSION_MAJOR 0 #define KERNEL_VERSION_MINOR 1 -#define KERNEL_VERSION_PATCH_LEVEL 0 +#define KERNEL_VERSION_PATCH_LEVEL 1 /* Edit each time a new release is out: format is YYYYMMDD (UTC) */ -#define KERNEL_RELEASE_DATE 20030201L +#define KERNEL_RELEASE_DATE 20030329L #endif diff --git a/include/rosrtl/thread.h b/include/rosrtl/thread.h new file mode 100644 index 0000000..7dc9deb --- /dev/null +++ b/include/rosrtl/thread.h @@ -0,0 +1,53 @@ +/* $Id$ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +NTSTATUS STDCALL RtlRosCreateUserThreadEx +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +); + +NTSTATUS CDECL RtlRosCreateUserThreadVa +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + ... +); + +NTSTATUS NTAPI RtlRosInitializeContextEx +( + IN HANDLE ProcessHandle, + IN PCONTEXT Context, + IN PTHREAD_START_ROUTINE StartAddress, + IN PUSER_STACK UserStack, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +); + +#ifdef __cplusplus +} +#endif + +/* EOF */ diff --git a/include/structs.h b/include/structs.h index 5cae0a4..4e8ad7f 100644 --- a/include/structs.h +++ b/include/structs.h @@ -472,7 +472,7 @@ typedef struct { LPCTSTR lpTemplateName; } CHOOSECOLOR, *LPCHOOSECOLOR; -typedef struct tagLOGFONT { +typedef struct tagLOGFONTA { LONG lfHeight; LONG lfWidth; LONG lfEscapement; @@ -486,8 +486,8 @@ typedef struct tagLOGFONT { BYTE lfClipPrecision; BYTE lfQuality; BYTE lfPitchAndFamily; - TCHAR lfFaceName[LF_FACESIZE]; -} LOGFONT, *LPLOGFONT, *PLOGFONT; + CHAR lfFaceName[LF_FACESIZE]; +} LOGFONTA, *LPLOGFONTA, *PLOGFONTA; typedef struct tagLOGFONTW { LONG lfHeight; @@ -506,24 +506,61 @@ typedef struct tagLOGFONTW { WCHAR lfFaceName[LF_FACESIZE]; } LOGFONTW, *LPLOGFONTW, *PLOGFONTW; -typedef struct { +#ifdef UNICODE +typedef LOGFONTW LOGFONT; +typedef LPLOGFONTW LPLOGFONT; +typedef PLOGFONTW PLOGFONT; +#else +typedef LOGFONTA LOGFONT; +typedef LPLOGFONTA LPLOGFONT; +typedef PLOGFONTA PLOGFONT; +#endif + +typedef struct tagCHOOSEFONTA { DWORD lStructSize; HWND hwndOwner; HDC hDC; - LPLOGFONT lpLogFont; + LPLOGFONTA lpLogFont; INT iPointSize; DWORD Flags; DWORD rgbColors; LPARAM lCustData; LPCFHOOKPROC lpfnHook; - LPCTSTR lpTemplateName; + LPCSTR lpTemplateName; + HINSTANCE hInstance; + LPSTR lpszStyle; + WORD nFontType; + WORD ___MISSING_ALIGNMENT__; + INT nSizeMin; + INT nSizeMax; +} CHOOSEFONTA, *LPCHOOSEFONTA; + +typedef struct tagCHOOSEFONTW { + DWORD lStructSize; + HWND hwndOwner; + HDC hDC; + LPLOGFONTW lpLogFont; + INT iPointSize; + DWORD Flags; + DWORD rgbColors; + LPARAM lCustData; + LPCFHOOKPROC lpfnHook; + LPCWSTR lpTemplateName; HINSTANCE hInstance; - LPTSTR lpszStyle; + LPWSTR lpszStyle; WORD nFontType; WORD ___MISSING_ALIGNMENT__; INT nSizeMin; INT nSizeMax; -} CHOOSEFONT, *LPCHOOSEFONT; +} CHOOSEFONTW, *LPCHOOSEFONTW; + +#ifdef UNICODE +typedef CHOOSEFONTW CHOOSEFONT; +typedef LPCHOOSEFONTW LPCHOOSEFONT; +#else +typedef CHOOSEFONTA CHOOSEFONT; +typedef LPCHOOSEFONTA LPCHOOSEFONT; +#endif typedef struct _IDA { UINT cidl; @@ -1283,24 +1320,45 @@ typedef struct tagPANOSE { BYTE bXHeight; } PANOSE; -typedef struct tagEXTLOGFONT { - LOGFONT elfLogFont; +typedef struct tagEXTLOGFONTA { + LOGFONTA elfLogFont; BCHAR elfFullName[LF_FULLFACESIZE]; BCHAR elfStyle[LF_FACESIZE]; - DWORD elfVersion; - DWORD elfStyleSize; - DWORD elfMatch; - DWORD elfReserved; - BYTE elfVendorId[ELF_VENDOR_SIZE]; - DWORD elfCulture; - PANOSE elfPanose; -} EXTLOGFONT; + DWORD elfVersion; + DWORD elfStyleSize; + DWORD elfMatch; + DWORD elfReserved; + BYTE elfVendorId[ELF_VENDOR_SIZE]; + DWORD elfCulture; + PANOSE elfPanose; +} EXTLOGFONTA, *LPEXTLOGFONTA; + +typedef struct tagEXTLOGFONTW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; + DWORD elfVersion; + DWORD elfStyleSize; + DWORD elfMatch; + DWORD elfReserved; + BYTE elfVendorId[ELF_VENDOR_SIZE]; + DWORD elfCulture; + PANOSE elfPanose; +} EXTLOGFONTW, *LPEXTLOGFONTW; + +#ifdef UNICODE +typedef EXTLOGFONTW EXTLOGFONT; +typedef LPEXTLOGFONTW LPEXTLOGFONT; +#else +typedef EXTLOGFONTA EXTLOGFONT; +typedef LPEXTLOGFONTA LPEXTLOGFONT; +#endif typedef struct tagEMREXTCREATEFONTINDIRECTW { EMR emr; DWORD ihFont; - EXTLOGFONT elfw; + EXTLOGFONTW elfw; } EMREXTCREATEFONTINDIRECTW, PEMREXTCREATEFONTINDIRECTW; @@ -1864,18 +1922,47 @@ typedef struct _ENUM_SERVICE_STATUSW { #define LPENUM_SERVICE_STATUS LPENUM_SERVICE_STATUSA #endif -typedef struct tagENUMLOGFONT { - LOGFONT elfLogFont; +typedef struct tagENUMLOGFONTA { + LOGFONTA elfLogFont; BCHAR elfFullName[LF_FULLFACESIZE]; BCHAR elfStyle[LF_FACESIZE]; -} ENUMLOGFONT; +} ENUMLOGFONTA, *LPENUMLOGFONTA; -typedef struct tagENUMLOGFONTEX { - LOGFONT elfLogFont; - BCHAR elfFullName[LF_FULLFACESIZE]; - BCHAR elfStyle[LF_FACESIZE]; - BCHAR elfScript[LF_FACESIZE]; -} ENUMLOGFONTEX; +typedef struct tagENUMLOGFONTW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; +} ENUMLOGFONTW, *LPENUMLOGFONTW; + +#ifdef UNICODE +typedef ENUMLOGFONTW ENUMLOGFONT; +typedef LPENUMLOGFONTW LPENUMLOGFONT; +#else +typedef ENUMLOGFONTA ENUMLOGFONT; +typedef LPENUMLOGFONTA LPENUMLOGFONT; +#endif + +typedef struct tagENUMLOGFONTEXA { + LOGFONTA elfLogFont; + BCHAR elfFullName[LF_FULLFACESIZE]; + BCHAR elfStyle[LF_FACESIZE]; + BCHAR elfScript[LF_FACESIZE]; +} ENUMLOGFONTEXA, *LPENUMLOGFONTEXA; + +typedef struct tagENUMLOGFONTEXW { + LOGFONTW elfLogFont; + WCHAR elfFullName[LF_FULLFACESIZE]; + WCHAR elfStyle[LF_FACESIZE]; + WCHAR elfScript[LF_FACESIZE]; +} ENUMLOGFONTEXW, *LPENUMLOGFONTEXW; + +#ifdef UNICODE +typedef ENUMLOGFONTEXW ENUMLOGFONTEX; +typedef LPENUMLOGFONTEXW LPENUMLOGFONTEX; +#else +typedef ENUMLOGFONTEXA ENUMLOGFONTEX; +typedef LPENUMLOGFONTEXA LPENUMLOGFONTEX; +#endif typedef struct _EVENTLOGRECORD { DWORD Length; @@ -2180,13 +2267,29 @@ typedef struct _ICONINFO { HBITMAP hbmColor; } ICONINFO, *PICONINFO; -typedef struct tagICONMETRICS { - UINT cbSize; - int iHorzSpacing; - int iVertSpacing; - int iTitleWrap; - LOGFONT lfFont; -} ICONMETRICS, *LPICONMETRICS; +typedef struct tagICONMETRICSA { + UINT cbSize; + int iHorzSpacing; + int iVertSpacing; + int iTitleWrap; + LOGFONTA lfFont; +} ICONMETRICSA, *LPICONMETRICSA; + +typedef struct tagICONMETRICSW { + UINT cbSize; + int iHorzSpacing; + int iVertSpacing; + int iTitleWrap; + LOGFONTW lfFont; +} ICONMETRICSW, *LPICONMETRICSW; + +#ifdef UNICODE +typedef ICONMETRICSW ICONMETRICS; +typedef LPICONMETRICSW LPICONMETRICS; +#else +typedef ICONMETRICSA ICONMETRICS; +typedef LPICONMETRICSA LPICONMETRICS; +#endif typedef struct _IMAGEINFO { HBITMAP hbmImage; @@ -2715,7 +2818,7 @@ typedef struct tagNEWCPLINFO { TCHAR szHelpFile[128]; } NEWCPLINFO; -typedef struct tagNEWTEXTMETRIC { +typedef struct tagNEWTEXTMETRICA { LONG tmHeight; LONG tmAscent; LONG tmDescent; @@ -2740,13 +2843,56 @@ typedef struct tagNEWTEXTMETRIC { UINT ntmSizeEM; UINT ntmCellHeight; UINT ntmAvgWidth; -} NEWTEXTMETRIC; +} NEWTEXTMETRICA; +typedef struct tagNEWTEXTMETRICW { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + WCHAR tmFirstChar; + WCHAR tmLastChar; + WCHAR tmDefaultChar; + WCHAR tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; + DWORD ntmFlags; + UINT ntmSizeEM; + UINT ntmCellHeight; + UINT ntmAvgWidth; +} NEWTEXTMETRICW; -typedef struct tagNEWTEXTMETRICEX { - NEWTEXTMETRIC ntmentm; +#ifdef UNICODE +typedef NEWTEXTMETRICA NEWTEXTMETRIC; +#else +typedef NEWTEXTMETRICW NEWTEXTMETRIC; +#endif + +typedef struct tagNEWTEXTMETRICEXA { + NEWTEXTMETRICA ntmentm; + FONTSIGNATURE ntmeFontSignature; +} NEWTEXTMETRICEXA; + +typedef struct tagNEWTEXTMETRICEXW { + NEWTEXTMETRICW ntmentm; FONTSIGNATURE ntmeFontSignature; -} NEWTEXTMETRICEX; +} NEWTEXTMETRICEXW; + +#ifdef UNICODE +typedef NEWTEXTMETRICEXA NEWTEXTMETRICEX; +#else +typedef NEWTEXTMETRICEXW NEWTEXTMETRICEX; +#endif typedef struct tagNM_LISTVIEW { NMHDR hdr; @@ -2789,23 +2935,49 @@ typedef struct _NM_UPDOWN { int iDelta; } NM_UPDOWNW; -typedef struct tagNONCLIENTMETRICS { - UINT cbSize; - int iBorderWidth; - int iScrollWidth; - int iScrollHeight; - int iCaptionWidth; - int iCaptionHeight; - LOGFONT lfCaptionFont; - int iSmCaptionWidth; - int iSmCaptionHeight; - LOGFONT lfSmCaptionFont; - int iMenuWidth; - int iMenuHeight; - LOGFONT lfMenuFont; - LOGFONT lfStatusFont; - LOGFONT lfMessageFont; -} NONCLIENTMETRICS, * LPNONCLIENTMETRICS; +typedef struct tagNONCLIENTMETRICSA { + UINT cbSize; + int iBorderWidth; + int iScrollWidth; + int iScrollHeight; + int iCaptionWidth; + int iCaptionHeight; + LOGFONTA lfCaptionFont; + int iSmCaptionWidth; + int iSmCaptionHeight; + LOGFONTA lfSmCaptionFont; + int iMenuWidth; + int iMenuHeight; + LOGFONTA lfMenuFont; + LOGFONTA lfStatusFont; + LOGFONTA lfMessageFont; +} NONCLIENTMETRICSA, *LPNONCLIENTMETRICSA; + +typedef struct tagNONCLIENTMETRICSW { + UINT cbSize; + int iBorderWidth; + int iScrollWidth; + int iScrollHeight; + int iCaptionWidth; + int iCaptionHeight; + LOGFONTW lfCaptionFont; + int iSmCaptionWidth; + int iSmCaptionHeight; + LOGFONTW lfSmCaptionFont; + int iMenuWidth; + int iMenuHeight; + LOGFONTW lfMenuFont; + LOGFONTW lfStatusFont; + LOGFONTW lfMessageFont; +} NONCLIENTMETRICSW, *LPNONCLIENTMETRICSW; + +#ifdef UNICODE +typedef NONCLIENTMETRICSW NONCLIENTMETRICS; +typedef LPNONCLIENTMETRICSW LPNONCLIENTMETRICS; +#else +typedef NONCLIENTMETRICSA NONCLIENTMETRICS; +typedef LPNONCLIENTMETRICSA LPNONCLIENTMETRICS; +#endif typedef struct _SERVICE_ADDRESS { DWORD dwAddressType; @@ -2974,7 +3146,7 @@ typedef OSVERSIONINFOEXA OSVERSIONINFOEX; typedef OSVERSIONINFOEXW OSVERSIONINFOEX; #endif -typedef struct tagTEXTMETRIC { +typedef struct tagTEXTMETRICA { LONG tmHeight; LONG tmAscent; LONG tmDescent; @@ -2995,11 +3167,42 @@ typedef struct tagTEXTMETRIC { BYTE tmStruckOut; BYTE tmPitchAndFamily; BYTE tmCharSet; -} TEXTMETRIC, *LPTEXTMETRIC; +} TEXTMETRICA, *LPTEXTMETRICA; -typedef struct _OUTLINETEXTMETRIC { +typedef struct tagTEXTMETRICW { + LONG tmHeight; + LONG tmAscent; + LONG tmDescent; + LONG tmInternalLeading; + LONG tmExternalLeading; + LONG tmAveCharWidth; + LONG tmMaxCharWidth; + LONG tmWeight; + LONG tmOverhang; + LONG tmDigitizedAspectX; + LONG tmDigitizedAspectY; + WCHAR tmFirstChar; + WCHAR tmLastChar; + WCHAR tmDefaultChar; + BCHAR tmBreakChar; + BYTE tmItalic; + BYTE tmUnderlined; + BYTE tmStruckOut; + BYTE tmPitchAndFamily; + BYTE tmCharSet; +} TEXTMETRICW, *LPTEXTMETRICW; + +#ifdef UNICODE +typedef TEXTMETRICA TEXTMETRIC; +typedef LPTEXTMETRICA LPTEXTMETRIC; +#else +typedef TEXTMETRICW TEXTMETRIC; +typedef LPTEXTMETRICA LPTEXTMETRIC; +#endif + +typedef struct _OUTLINETEXTMETRICA { UINT otmSize; - TEXTMETRIC otmTextMetrics; + TEXTMETRICA otmTextMetrics; BYTE otmFiller; PANOSE otmPanoseNumber; UINT otmfsSelection; @@ -3030,7 +3233,50 @@ typedef struct _OUTLINETEXTMETRIC { PSTR otmpFaceName; PSTR otmpStyleName; PSTR otmpFullName; -} OUTLINETEXTMETRIC, *LPOUTLINETEXTMETRIC; +} OUTLINETEXTMETRICA, *LPOUTLINETEXTMETRICA; + +typedef struct _OUTLINETEXTMETRICW { + UINT otmSize; + TEXTMETRICW otmTextMetrics; + BYTE otmFiller; + PANOSE otmPanoseNumber; + UINT otmfsSelection; + UINT otmfsType; + int otmsCharSlopeRise; + int otmsCharSlopeRun; + int otmItalicAngle; + UINT otmEMSquare; + int otmAscent; + int otmDescent; + UINT otmLineGap; + UINT otmsCapEmHeight; + UINT otmsXHeight; + RECT otmrcFontBox; + int otmMacAscent; + int otmMacDescent; + UINT otmMacLineGap; + UINT otmusMinimumPPEM; + POINT otmptSubscriptSize; + POINT otmptSubscriptOffset; + POINT otmptSuperscriptSize; + POINT otmptSuperscriptOffset; + UINT otmsStrikeoutSize; + int otmsStrikeoutPosition; + int otmsUnderscoreSize; + int otmsUnderscorePosition; + PSTR otmpFamilyName; + PSTR otmpFaceName; + PSTR otmpStyleName; + PSTR otmpFullName; +} OUTLINETEXTMETRICW, *LPOUTLINETEXTMETRICW; + +#ifdef UNICODE +typedef OUTLINETEXTMETRICA OUTLINETEXTMETRIC; +typedef LPOUTLINETEXTMETRICA LPOUTLINETEXTMETRIC; +#else +typedef OUTLINETEXTMETRICW OUTLINETEXTMETRIC; +typedef LPOUTLINETEXTMETRICA LPOUTLINETEXTMETRIC; +#endif typedef struct _OVERLAPPED { DWORD Internal; @@ -3775,11 +4021,70 @@ typedef struct tagSTYLESTRUCT { DWORD styleNew; } STYLESTRUCT, * LPSTYLESTRUCT; +typedef struct _ACCESS_ALLOWED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} ACCESS_ALLOWED_ACE; + +typedef ACCESS_ALLOWED_ACE *PACCESS_ALLOWED_ACE; + +typedef struct _ACCESS_DENIED_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} ACCESS_DENIED_ACE; +typedef ACCESS_DENIED_ACE *PACCESS_DENIED_ACE; + typedef struct _SYSTEM_AUDIT_ACE { - ACE_HEADER Header; - ACCESS_MASK Mask; - DWORD SidStart; + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; } SYSTEM_AUDIT_ACE; +typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE; + +typedef struct _SYSTEM_ALARM_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +} SYSTEM_ALARM_ACE; +typedef SYSTEM_ALARM_ACE *PSYSTEM_ALARM_ACE; + +typedef struct _ACCESS_ALLOWED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE; + +typedef struct _ACCESS_DENIED_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE; + +typedef struct _SYSTEM_AUDIT_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} SYSTEM_AUDIT_OBJECT_ACE, *PSYSTEM_AUDIT_OBJECT_ACE; + +typedef struct _SYSTEM_ALARM_OBJECT_ACE { + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD Flags; + GUID ObjectType; + GUID InheritedObjectType; + DWORD SidStart; +} SYSTEM_ALARM_OBJECT_ACE, *PSYSTEM_ALARM_OBJECT_ACE; typedef struct _SYSTEM_INFO { @@ -4181,11 +4486,31 @@ typedef int CALLBACK (*ENUMMETAFILEPROC) (HDC, HANDLETABLE, typedef int CALLBACK (*ENHMETAFILEPROC) (HDC, HANDLETABLE, ENHMETARECORD, int, LPARAM); -typedef int CALLBACK (*ENUMFONTSPROC) (LPLOGFONT, LPTEXTMETRIC, DWORD, LPARAM); -typedef int CALLBACK (*FONTENUMPROC) (ENUMLOGFONT *, NEWTEXTMETRIC *, - int, LPARAM); -typedef int CALLBACK (*FONTENUMEXPROC) (ENUMLOGFONTEX *, NEWTEXTMETRICEX *, - int, LPARAM); +typedef int CALLBACK (*ENUMFONTSPROCA) (LPLOGFONTA, LPTEXTMETRICA, DWORD, LPARAM); +typedef int CALLBACK (*ENUMFONTSPROCW) (LPLOGFONTW, LPTEXTMETRICW, DWORD, LPARAM); +#ifdef UNICODE +typedef ENUMFONTSPROCW ENUMFONTSPROC; +#else +typedef ENUMFONTSPROCA ENUMFONTSPROC; +#endif +typedef int CALLBACK (*FONTENUMPROCA) (ENUMLOGFONTA *, NEWTEXTMETRICA *, + int, LPARAM); +typedef int CALLBACK (*FONTENUMPROCW) (ENUMLOGFONTW *, NEWTEXTMETRICW *, + int, LPARAM); +#ifdef UNICODE +typedef FONTENUMPROCW FONTENUMPROC; +#else +typedef FONTENUMPROCA FONTENUMPROC; +#endif +typedef int CALLBACK (*FONTENUMEXPROCA) (ENUMLOGFONTEXA *, NEWTEXTMETRICEXA *, + int, LPARAM); +typedef int CALLBACK (*FONTENUMEXPROCW) (ENUMLOGFONTEXW *, NEWTEXTMETRICEXW *, + int, LPARAM); +#ifdef UNICODE +typedef FONTENUMEXPROCW FONTENUMEXPROC; +#else +typedef FONTENUMEXPROCA FONTENUMEXPROC; +#endif typedef VOID CALLBACK (*LPOVERLAPPED_COMPLETION_ROUTINE) (DWORD, DWORD, LPOVERLAPPED); diff --git a/include/tchar.h b/include/tchar.h index 922f7f5..fbc98c7 100644 --- a/include/tchar.h +++ b/include/tchar.h @@ -52,8 +52,8 @@ #ifndef _TCHAR_DEFINED #ifndef RC_INVOKED typedef wchar_t _TCHAR; -typedef signed wchar_t _TSCHAR; -typedef unsigned wchar_t _TUCHAR; +typedef wchar_t _TSCHAR; +typedef wchar_t _TUCHAR; typedef wchar_t _TXCHAR; /* #if !__STDC__ */ typedef wchar_t TCHAR; diff --git a/include/unicode.h b/include/unicode.h index dcf22bb..a37474d 100644 --- a/include/unicode.h +++ b/include/unicode.h @@ -1858,7 +1858,7 @@ CopyMetaFileW(HMETAFILE, LPCWSTR); HFONT STDCALL -CreateFontIndirectW(CONST LOGFONT *); +CreateFontIndirectW(CONST LOGFONTW *); HFONT STDCALL @@ -1885,7 +1885,7 @@ DeviceCapabilitiesW(LPCWSTR, LPCWSTR, WORD, int STDCALL -EnumFontFamiliesExW(HDC, LPLOGFONT, FONTENUMEXPROC, LPARAM, DWORD); +EnumFontFamiliesExW(HDC, LPLOGFONTW, FONTENUMEXPROC, LPARAM, DWORD); int STDCALL @@ -1925,7 +1925,7 @@ GetMetaFileW(LPCWSTR); UINT STDCALL -GetOutlineTextMetricsW(HDC, UINT, LPOUTLINETEXTMETRIC); +GetOutlineTextMetricsW(HDC, UINT, LPOUTLINETEXTMETRICW); WINBOOL STDCALL GetTextExtentPointW( @@ -1986,7 +1986,7 @@ GetEnhMetaFileDescriptionW(HENHMETAFILE, UINT, LPWSTR ); WINBOOL STDCALL -GetTextMetricsW(HDC, LPTEXTMETRIC); +GetTextMetricsW(HDC, LPTEXTMETRICW); int STDCALL diff --git a/include/win32k/bitmaps.h b/include/win32k/bitmaps.h index e504a02..8196f14 100644 --- a/include/win32k/bitmaps.h +++ b/include/win32k/bitmaps.h @@ -48,6 +48,7 @@ int DIB_GetDIBImageBytes (int width, int height, int depth); int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse); INT BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer); BOOL Bitmap_InternalDelete( PBITMAPOBJ pBmp ); +HBITMAP BitmapToSurf(PBITMAPOBJ BitmapObj); /* User Entry Points */ BOOL diff --git a/include/win32k/debug1.h b/include/win32k/debug1.h index 7618cb8..c1a75a6 100644 --- a/include/win32k/debug1.h +++ b/include/win32k/debug1.h @@ -34,26 +34,18 @@ #define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); ExAllocatePool(NonPagedPool,0); } while(0); #define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); ExAllocatePool(NonPagedPool,0); } while(0); -extern unsigned int old_idt[256][2]; -//extern unsigned int idt; -extern unsigned int old_idt_valid; #ifdef __NTOSKRNL__ -//#define DPRINT_CHECKS ExAllocatePool(NonPagedPool,0); assert(old_idt_valid || (!memcmp(old_idt,KiIdt,256*2))); -//#define DPRINT_CHECKS ExAllocatePool(NonPagedPool,0); #define DPRINT_CHECKS #else #define DPRINT_CHECKS #endif #ifndef NDEBUG -#define OLD_DPRINT(fmt,args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(fmt,args); } while(0); -#define DPRINT(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); DPRINT_CHECKS } while(0); +#define DPRINT(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT do { DbgPrint("%s:%d\n",__FILE__,__LINE__); ExAllocatePool(NonPagedPool,0); } while(0); #else -//#define DPRINT(args...) do { DPRINT_CHECKS } while (0); #define DPRINT(args...) -#define OLD_DPRINT(args...) #define CHECKPOINT #endif /* NDEBUG */ @@ -65,36 +57,4 @@ extern unsigned int old_idt_valid; #define ASSERT_IRQL(x) assert(KeGetCurrentIrql()<=(x)) #define assert_irql(x) assert(KeGetCurrentIrql()<=(x)) -#define HBP_EXECUTE (0) -#define HBP_WRITE (1) -#define HBP_READWRITE (3) - -#define HBP_BYTE (0) -#define HBP_WORD (1) -#define HBP_DWORD (3) - -/* - * FUNCTION: Sets a hardware breakpoint - * ARGUMENTS: - * i = breakpoint to set (0 to 3) - * addr = linear address to break on - * type = Type of access to break on - * len = length of the variable to watch - * NOTES: - * The variable to watch must be aligned to its length (i.e. a dword - * breakpoint must be aligned to a dword boundary) - * - * A fatal exception will be generated on the access to the variable. - * It is (at the moment) only really useful for catching undefined - * pointers if you know the variable effected but not the buggy - * routine. - * - * FIXME: Extend to call out to kernel debugger on breakpoint - * Add support for I/O breakpoints - * REFERENCES: See the i386 programmer manual for more details - */ -void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, - unsigned int len); - - #endif /* __INTERNAL_DEBUG */ diff --git a/include/win32k/misc.h b/include/win32k/misc.h index 93945f6..e732ce6 100644 --- a/include/win32k/misc.h +++ b/include/win32k/misc.h @@ -1,6 +1,9 @@ #ifndef __WIN32K_MISC_H #define __WIN32K_MISC_H +/* Process context in which miniport driver is opened/used */ +extern PEPROCESS W32kDeviceProcess; + BOOLEAN STDCALL W32kInitialize (VOID); diff --git a/include/win32k/ntuser.h b/include/win32k/ntuser.h index c515fb7..06f48b9 100644 --- a/include/win32k/ntuser.h +++ b/include/win32k/ntuser.h @@ -11,6 +11,8 @@ INT STDCALL NtUserReleaseDC(HWND hWnd, HDC hDc); BOOL STDCALL NtUserGetWindowRect(HWND hWnd, LPRECT Rect); +BOOL STDCALL +NtUserGetClientRect(HWND hWnd, LPRECT Rect); HANDLE STDCALL NtUserGetProp(HWND hWnd, ATOM Atom); BOOL STDCALL @@ -814,7 +816,7 @@ NtUserGetUpdateRgn( DWORD STDCALL NtUserGetWindowDC( - DWORD Unknown0); + HWND hWnd); DWORD STDCALL @@ -880,27 +882,28 @@ NtUserInternalGetWindowText( DWORD STDCALL NtUserInvalidateRect( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2); +HWND hWnd, +CONST RECT *lpRect, +WINBOOL bErase); DWORD STDCALL -NtUserInvalidateRgn( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2); + NtUserInvalidateRgn( + HWND hWnd, + HRGN hRgn, + WINBOOL bErase); + DWORD STDCALL NtUserIsClipboardFormatAvailable( DWORD Unknown0); -DWORD +NTSTATUS STDCALL NtUserKillTimer( - DWORD Unknown0, - DWORD Unknown1); + HWND hWnd, + UINT_PTR IDEvent); DWORD STDCALL @@ -976,15 +979,16 @@ NtUserModifyUserStartupInfoFlags( DWORD Unknown0, DWORD Unknown1); -DWORD +BOOL STDCALL -NtUserMoveWindow( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5); +NtUserMoveWindow( + HWND hWnd, + int X, + int Y, + int nWidth, + int nHeight, + BOOL bRepaint +); DWORD STDCALL @@ -1084,13 +1088,9 @@ NtUserRealChildWindowFromPoint( DWORD Unknown1, DWORD Unknown2); -DWORD -STDCALL -NtUserRedrawWindow( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3); +NTSTATUS STDCALL +NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags); + RTL_ATOM STDCALL @@ -1415,13 +1415,13 @@ NtUserSetThreadState( DWORD Unknown0, DWORD Unknown1); -DWORD +NTSTATUS STDCALL NtUserSetTimer( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3); + HWND hWnd, + UINT_PTR * IDEvent, + UINT Period, + TIMERPROC TimerFunc); DWORD STDCALL @@ -1443,16 +1443,16 @@ NtUserSetWindowPlacement( DWORD Unknown0, DWORD Unknown1); -DWORD -STDCALL -NtUserSetWindowPos( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6); +BOOL +STDCALL NtUserSetWindowPos( + HWND hWnd, + HWND hWndInsertAfter, + int X, + int Y, + int cx, + int cy, + UINT uFlags +); DWORD STDCALL @@ -1641,6 +1641,9 @@ NtUserUpdateInstance( DWORD Unknown1, DWORD Unknown2); +BOOL STDCALL +NtUserUpdateWindow( HWND hWnd ); + DWORD STDCALL NtUserUpdateLayeredWindow( diff --git a/include/win32k/region.h b/include/win32k/region.h index 6650718..4c7783a 100644 --- a/include/win32k/region.h +++ b/include/win32k/region.h @@ -130,6 +130,11 @@ STDCALL W32kRectInRegion(HRGN hRgn, CONST LPRECT rc); +INT +STDCALL +W32kSelectVisRgn(HDC hdc, + HRGN hrgn); + BOOL STDCALL W32kSetRectRgn(HRGN hRgn, diff --git a/include/win32k/text.h b/include/win32k/text.h index fc1be70..96e6507 100644 --- a/include/win32k/text.h +++ b/include/win32k/text.h @@ -5,7 +5,8 @@ /* GDI logical font object */ typedef struct { - LOGFONT logfont; + LOGFONTW logfont; + HFONT GDIFontHandle; } TEXTOBJ, *PTEXTOBJ; /* Internal interface */ @@ -13,15 +14,12 @@ typedef struct #define TEXTOBJ_AllocText() \ ((HFONT) GDIOBJ_AllocObj (sizeof (TEXTOBJ), GO_FONT_MAGIC)) #define TEXTOBJ_FreeText(hBMObj) GDIOBJ_FreeObj((HGDIOBJ) hBMObj, GO_FONT_MAGIC, GDIOBJFLAG_DEFAULT) -/* -#define TEXTOBJ_HandleToPtr(hBMObj) \ - ((PTEXTOBJ) GDIOBJ_HandleToPtr ((HGDIOBJ) hBMObj, GO_FONT_MAGIC)) -#define TEXTOBJ_PtrToHandle(hBMObj) \ - ((HFONT) GDIOBJ_PtrToHandle ((PGDIOBJ) hBMObj, GO_FONT_MAGIC)) -*/ #define TEXTOBJ_LockText(hBMObj) ((PTEXTOBJ) GDIOBJ_LockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC)) #define TEXTOBJ_UnlockText(hBMObj) GDIOBJ_UnlockObj ((HGDIOBJ) hBMObj, GO_FONT_MAGIC) +NTSTATUS TextIntRealizeFont(HFONT FontHandle); +NTSTATUS TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont); + int STDCALL W32kAddFontResource(LPCWSTR Filename); @@ -45,7 +43,7 @@ W32kCreateFont(int Height, HFONT STDCALL -W32kCreateFontIndirect(CONST LPLOGFONT lf); +W32kCreateFontIndirect(CONST LPLOGFONTW lf); BOOL STDCALL @@ -64,7 +62,7 @@ W32kEnumFontFamilies(HDC hDC, int STDCALL W32kEnumFontFamiliesEx(HDC hDC, - LPLOGFONT Logfont, + LPLOGFONTW Logfont, FONTENUMPROC EnumFontFamExProc, LPARAM lParam, DWORD Flags); @@ -160,7 +158,7 @@ UINT STDCALL W32kGetOutlineTextMetrics(HDC hDC, UINT Data, - LPOUTLINETEXTMETRIC otm); + LPOUTLINETEXTMETRICW otm); BOOL STDCALL @@ -210,7 +208,7 @@ W32kGetTextFace(HDC hDC, BOOL STDCALL W32kGetTextMetrics(HDC hDC, - LPTEXTMETRIC tm); + LPTEXTMETRICW tm); BOOL STDCALL diff --git a/install.bat b/install.bat index 55be918..e1f2763 100644 --- a/install.bat +++ b/install.bat @@ -40,7 +40,6 @@ copy drivers\bus\isapnp\isapnp.sys %ROS_INSTALL%\system32\drivers copy drivers\bus\pci\pci.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\floppy\floppy.sys %ROS_INSTALL%\system32\drivers copy drivers\lib\bzip2\unbzip2.sys %ROS_INSTALL%\system32\drivers -copy drivers\lib\zlib\zlib.a %ROS_INSTALL%\system32 copy drivers\input\keyboard\keyboard.sys %ROS_INSTALL%\system32\drivers copy drivers\input\mouclass\mouclass.sys %ROS_INSTALL%\system32\drivers copy drivers\input\psaux\psaux.sys %ROS_INSTALL%\system32\drivers @@ -50,8 +49,8 @@ copy drivers\dd\null\null.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\serial\serial.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\serenum\serenum.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\vga\miniport\vgamp.sys %ROS_INSTALL%\system32\drivers -copy drivers\dd\vga\display\vgaddi.dll %ROS_INSTALL%\system32\drivers -copy drivers\dd\vidport\vidport.sys %ROS_INSTALL%\system32\drivers +copy drivers\dd\vga\display\vgaddi.dll %ROS_INSTALL%\system32 +copy drivers\dd\videoprt\videoprt.sys %ROS_INSTALL%\system32\drivers copy drivers\net\afd\afd.sys %ROS_INSTALL%\system32\drivers copy drivers\net\dd\ne2000\ne2000.sys %ROS_INSTALL%\system32\drivers copy drivers\net\dd\miniport\nscirda\nscirda.sys %ROS_INSTALL%\system32\drivers @@ -66,8 +65,7 @@ copy drivers\storage\cdrom\cdrom.sys %ROS_INSTALL%\system32\drivers copy drivers\storage\disk\disk.sys %ROS_INSTALL%\system32\drivers copy drivers\storage\class2\class2.sys %ROS_INSTALL%\system32\drivers copy subsys\system\autochk\autochk.exe %ROS_INSTALL%\system32 -copy subsys\system\gstart\gstart.exe %ROS_INSTALL%\system32 -copy subsys\system\shell\shell.exe %ROS_INSTALL%\system32 +copy subsys\system\cmd\cmd.exe %ROS_INSTALL%\system32 copy subsys\system\winlogon\winlogon.exe %ROS_INSTALL%\system32 copy subsys\system\services\services.exe %ROS_INSTALL%\system32 copy services\eventlog\eventlog.exe %ROS_INSTALL%\system32 @@ -75,6 +73,7 @@ copy services\rpcss\rpcss.exe %ROS_INSTALL%\system32 copy lib\advapi32\advapi32.dll %ROS_INSTALL%\system32 copy lib\crtdll\crtdll.dll %ROS_INSTALL%\system32 copy lib\fmifs\fmifs.dll %ROS_INSTALL%\system32 +copy lib\freetype\freetype.dll %ROS_INSTALL%\system32 copy lib\gdi32\gdi32.dll %ROS_INSTALL%\system32 copy lib\iphlpapi\iphlpapi.dll %ROS_INSTALL%\system32 copy lib\kernel32\kernel32.dll %ROS_INSTALL%\system32 @@ -90,6 +89,7 @@ copy lib\user32\user32.dll %ROS_INSTALL%\system32 copy lib\version\version.dll %ROS_INSTALL%\system32 copy lib\winedbgc\winedbgc.dll %ROS_INSTALL%\system32 copy lib\winmm\winmm.dll %ROS_INSTALL%\system32 +copy lib\winspool\winspool.drv %ROS_INSTALL%\system32 copy lib\ws2_32\ws2_32.dll %ROS_INSTALL%\system32 copy lib\ws2help\ws2help.dll %ROS_INSTALL%\system32 copy lib\wshirda\wshirda.dll %ROS_INSTALL%\system32 @@ -97,7 +97,7 @@ copy lib\wsock32\wsock32.dll %ROS_INSTALL%\system32 copy subsys\smss\smss.exe %ROS_INSTALL%\system32 copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32 copy subsys\ntvdm\ntvdm.exe %ROS_INSTALL%\system32 -copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32\drivers +copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32 copy subsys\system\usetup\usetup.exe %ROS_INSTALL%\system32 copy apps\utils\cat\cat.exe %ROS_INSTALL%\bin copy apps\utils\partinfo\partinfo.exe %ROS_INSTALL%\bin @@ -120,6 +120,7 @@ copy apps\tests\pteb\pteb.exe %ROS_INSTALL%\bin copy apps\tests\consume\consume.exe %ROS_INSTALL%\bin copy apps\tests\vmtest\vmtest.exe %ROS_INSTALL_TESTS% copy apps\tests\gditest\gditest.exe %ROS_INSTALL_TESTS% +copy apps\tests\shaptest\shaptest.exe %ROS_INSTALL_TESTS% copy apps\tests\dibtest\dibtest.exe %ROS_INSTALL_TESTS% copy apps\tests\mstest\msserver.exe %ROS_INSTALL_TESTS% copy apps\tests\mstest\msclient.exe %ROS_INSTALL_TESTS% @@ -143,6 +144,8 @@ copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts rem copy media\nls\*.nls %ROS_INSTALL%\system32 copy ntoskrnl\ntoskrnl.map %ROS_INSTALL%\symbols +tools\mkhive\mkhive bootdata %ROS_INSTALL%\system32\config + if "%ROS_BUILD_EXT%" == "" goto Finish echo Installing extra programs from rosapps directory... diff --git a/lib/advapi32/advapi32.def b/lib/advapi32/advapi32.def index 30127ce..5349efd 100644 --- a/lib/advapi32/advapi32.def +++ b/lib/advapi32/advapi32.def @@ -1,11 +1,11 @@ - $Id$ - - advapi32.def - - ReactOS Operating System - - Some stack sizes are taken from Ander Norlander's .DEFs. - +; $Id$ +; +; advapi32.def +; +; ReactOS Operating System +; +; Some stack sizes are taken from Ander Norlander's .DEFs. +; LIBRARY advapi32.dll EXPORTS AbortSystemShutdownA@4 @@ -409,3 +409,4 @@ UnlockServiceDatabase@4 WinLoadTrustProvider@4 WinSubmitCertificate@4 WinVerifyTrust@12 +; EOF diff --git a/lib/advapi32/makefile b/lib/advapi32/makefile index dd3d4d1..9f2b6fb 100644 --- a/lib/advapi32/makefile +++ b/lib/advapi32/makefile @@ -50,13 +50,11 @@ TARGET_OBJECTS = \ $(SERVICE_OBJECTS) \ $(TOKEN_OBJECTS) -TARGET_CLEAN = \ - misc/*.o \ - reg/*.o \ - sec/*.o \ - service/*.o \ - token/*.o +DEP_OBJECTS = $(TARGET_OBJECTS) include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + diff --git a/lib/advapi32/misc/.cvsignore b/lib/advapi32/misc/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/advapi32/misc/.cvsignore +++ b/lib/advapi32/misc/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/advapi32/reg/.cvsignore b/lib/advapi32/reg/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/advapi32/reg/.cvsignore +++ b/lib/advapi32/reg/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/advapi32/reg/reg.c b/lib/advapi32/reg/reg.c index 2957c5e..45a0c72 100644 --- a/lib/advapi32/reg/reg.c +++ b/lib/advapi32/reg/reg.c @@ -9,7 +9,8 @@ * Created 01/11/98 * 19990309 EA Stubs */ -#ifndef WIN32_REGDBG + +/* INCLUDES *****************************************************************/ #define NTOS_MODE_USER #include @@ -21,70 +22,8 @@ #define NDEBUG #include -#else /*WIN32_REGDBG*/ -#include "cm_win32.h" -#ifdef __GNUC__ -#define WINAPI __stdcall -#define WINAPIV __cdecl -#define APIENTRY __stdcall -#define DECLSPEC_IMPORT __declspec(dllimport) -#define DECLSPEC_EXPORT __declspec(dllexport) -#define DECLARE_HANDLE(n) typedef HANDLE n -#define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004) -#define ERROR_SUCCESS 0L -#define ERROR_INVALID_HANDLE 6L -#define ERROR_OUTOFMEMORY 14L -#define ERROR_INVALID_PARAMETER 87L -#define ERROR_CALL_NOT_IMPLEMENTED 120L -#define ERROR_MORE_DATA 234L - -void WINAPI SetLastError(DWORD); -BOOLEAN STDCALL RtlDosPathNameToNtPathName_U(PWSTR dosname, PUNICODE_STRING ntname, PWSTR* shortname, PCURDIR nah); -NTSTATUS STDCALL RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs); -NTSTATUS STDCALL RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs); -NTSTATUS STDCALL RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs); -NTSTATUS STDCALL RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs); - -DECLARE_HANDLE(HKEY); -typedef HKEY *PHKEY; -typedef ACCESS_MASK REGSAM; - -typedef struct value_entA { - LPSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} VALENTA,*PVALENTA; -typedef struct value_entW { - LPWSTR ve_valuename; - DWORD ve_valuelen; - DWORD ve_valueptr; - DWORD ve_type; -} VALENTW,*PVALENTW; -#endif -#undef STDCALL -#define STDCALL _stdcall -#undef RegSetValueEx -#undef RegCreateKeyEx -#undef RegQueryInfoKey -#undef RegDeleteKey -#undef RegOpenKey -#undef RegOpenKeyEx -#undef RegEnumKeyEx -#undef RegEnumValue -#endif /*WIN32_REGDBG*/ - -#define CHECK_STATUS \ -{ \ - if (!NT_SUCCESS(Status)) \ - { \ - LONG _ErrorCode = RtlNtStatusToDosError(Status); \ - SetLastError(_ErrorCode); \ - return _ErrorCode; \ - } \ -} -/* GLOBALS *******************************************************************/ +/* GLOBALS ******************************************************************/ #define MAX_DEFAULT_HANDLES 6 @@ -92,7 +31,7 @@ static CRITICAL_SECTION HandleTableCS; static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES]; -/* PROTOTYPES ****************************************************************/ +/* PROTOTYPES ***************************************************************/ static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key); static VOID CloseDefaultKeys(VOID); @@ -103,27 +42,20 @@ static NTSTATUS OpenUsersKey (PHANDLE KeyHandle); static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle); -/* FUNCTIONS *****************************************************************/ - -inline void RegiTerminateWideString(LPWSTR String, DWORD Length) -{ - LPWSTR AfterString = String + Length; - *AfterString = 0; -} +/* FUNCTIONS ****************************************************************/ /************************************************************************ * RegInitDefaultHandles */ - BOOL RegInitialize(VOID) { - DPRINT("RegInitialize()\n"); + DPRINT("RegInitialize()\n"); - RtlZeroMemory (DefaultHandleTable, - MAX_DEFAULT_HANDLES * sizeof(HANDLE)); - RtlInitializeCriticalSection(&HandleTableCS); - return TRUE; + RtlZeroMemory(DefaultHandleTable, + MAX_DEFAULT_HANDLES * sizeof(HANDLE)); + RtlInitializeCriticalSection(&HandleTableCS); + return TRUE; } @@ -133,83 +65,101 @@ RegInitialize(VOID) BOOL RegCleanup(VOID) { - DPRINT("RegCleanup()\n"); + DPRINT("RegCleanup()\n"); - CloseDefaultKeys(); - RtlDeleteCriticalSection(&HandleTableCS); - return TRUE; + CloseDefaultKeys(); + RtlDeleteCriticalSection(&HandleTableCS); + return(TRUE); } static NTSTATUS MapDefaultKey(PHKEY RealKey, - HKEY Key) + HKEY Key) { - PHANDLE Handle; - ULONG Index; - NTSTATUS Status = STATUS_SUCCESS; - - DPRINT("MapDefaultKey (Key %x)\n", Key); - - if (((ULONG)Key & 0xF0000000) != 0x80000000) { - *RealKey = Key; - return STATUS_SUCCESS; - } - /* Handle special cases here */ - Index = (ULONG)Key & 0x0FFFFFFF; - if (Index >= MAX_DEFAULT_HANDLES) - return STATUS_INVALID_PARAMETER; - RtlEnterCriticalSection(&HandleTableCS); - Handle = &DefaultHandleTable[Index]; - if (*Handle == NULL) { - /* create/open the default handle */ - switch (Index) { - case 0: /* HKEY_CLASSES_ROOT */ - Status = OpenClassesRootKey(Handle); - break; - case 1: /* HKEY_CURRENT_USER */ - Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle); - break; - case 2: /* HKEY_LOCAL_MACHINE */ - Status = OpenLocalMachineKey(Handle); - break; - case 3: /* HKEY_USERS */ - Status = OpenUsersKey(Handle); - break; + PHANDLE Handle; + ULONG Index; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("MapDefaultKey (Key %x)\n", Key); + + if (((ULONG)Key & 0xF0000000) != 0x80000000) + { + *RealKey = Key; + return(STATUS_SUCCESS); + } + + /* Handle special cases here */ + Index = (ULONG)Key & 0x0FFFFFFF; + if (Index >= MAX_DEFAULT_HANDLES) + return(STATUS_INVALID_PARAMETER); + + RtlEnterCriticalSection(&HandleTableCS); + Handle = &DefaultHandleTable[Index]; + if (*Handle == NULL) + { + /* create/open the default handle */ + switch (Index) + { + case 0: /* HKEY_CLASSES_ROOT */ + Status = OpenClassesRootKey(Handle); + break; + + case 1: /* HKEY_CURRENT_USER */ + Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle); + break; + + case 2: /* HKEY_LOCAL_MACHINE */ + Status = OpenLocalMachineKey(Handle); + break; + + case 3: /* HKEY_USERS */ + Status = OpenUsersKey(Handle); + break; #if 0 - case 4: /* HKEY_PERFORMANCE_DATA */ - Status = OpenPerformanceDataKey(Handle); - break; + case 4: /* HKEY_PERFORMANCE_DATA */ + Status = OpenPerformanceDataKey(Handle); + break; #endif - case 5: /* HKEY_CURRENT_CONFIG */ - Status = OpenCurrentConfigKey(Handle); - break; - default: - DPRINT("MapDefaultHandle() no handle creator\n"); - Status = STATUS_INVALID_PARAMETER; - } - } - RtlLeaveCriticalSection(&HandleTableCS); - if (NT_SUCCESS(Status)) { - *RealKey = (HKEY)*Handle; - } - return Status; + case 5: /* HKEY_CURRENT_CONFIG */ + Status = OpenCurrentConfigKey(Handle); + break; + + case 6: /* HKEY_DYN_DATA */ + Status = STATUS_NOT_IMPLEMENTED; + break; + + default: + DPRINT("MapDefaultHandle() no handle creator\n"); + Status = STATUS_INVALID_PARAMETER; + } + } + RtlLeaveCriticalSection(&HandleTableCS); + + if (NT_SUCCESS(Status)) + { + *RealKey = (HKEY)*Handle; + } + + return(Status); } static VOID CloseDefaultKeys(VOID) { - ULONG i; - - RtlEnterCriticalSection(&HandleTableCS); - for (i = 0; i < MAX_DEFAULT_HANDLES; i++) { - if (DefaultHandleTable[i] != NULL) { - NtClose (DefaultHandleTable[i]); - DefaultHandleTable[i] = NULL; - } - } - RtlLeaveCriticalSection(&HandleTableCS); + ULONG i; + + RtlEnterCriticalSection(&HandleTableCS); + for (i = 0; i < MAX_DEFAULT_HANDLES; i++) + { + if (DefaultHandleTable[i] != NULL) + { + NtClose(DefaultHandleTable[i]); + DefaultHandleTable[i] = NULL; + } + } + RtlLeaveCriticalSection(&HandleTableCS); } @@ -222,13 +172,13 @@ OpenClassesRootKey(PHANDLE KeyHandle) DPRINT("OpenClassesRootKey()\n"); InitializeObjectAttributes(&Attributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); return(NtOpenKey(KeyHandle, - KEY_ALL_ACCESS, - &Attributes)); + KEY_ALL_ACCESS, + &Attributes)); } @@ -299,14 +249,16 @@ RegCloseKey(HKEY hKey) /* don't close null handle or a pseudo handle */ if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000)) - return ERROR_INVALID_HANDLE; - Status = NtClose (hKey); - if (!NT_SUCCESS(Status)) { - LONG ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); - return ErrorCode; - } - return ERROR_SUCCESS; + return(ERROR_INVALID_HANDLE); + + Status = NtClose(hKey); + if (!NT_SUCCESS(Status)) + { + LONG ErrorCode = RtlNtStatusToDosError(Status); + SetLastError (ErrorCode); + return ErrorCode; + } + return(ERROR_SUCCESS); } @@ -360,11 +312,12 @@ RegCreateKeyExA(HKEY hKey, /* get the real parent key */ Status = MapDefaultKey(&ParentKey, hKey); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { LONG ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } + } DPRINT("ParentKey %x\n", (ULONG)ParentKey); if (lpClass != NULL) @@ -386,11 +339,13 @@ RegCreateKeyExA(HKEY hKey, if (lpClass != NULL) RtlFreeUnicodeString(&ClassString); DPRINT("Status %x\n", Status); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { LONG ErrorCode = RtlNtStatusToDosError(Status); SetLastError (ErrorCode); return ErrorCode; - } + } + return(ERROR_SUCCESS); } @@ -508,32 +463,39 @@ RegDeleteKeyA( LONG ErrorCode; Status = MapDefaultKey(&ParentKey, hKey); - if (!NT_SUCCESS(Status)) { - ErrorCode = RtlNtStatusToDosError(Status); - SetLastError (ErrorCode); - return ErrorCode; - } + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return(ErrorCode); + } + RtlInitAnsiString(&SubKeyStringA, (LPSTR)lpSubKey); RtlAnsiStringToUnicodeString(&SubKeyStringW, &SubKeyStringA, TRUE); - InitializeObjectAttributes (&ObjectAttributes, - &SubKeyStringW, - OBJ_CASE_INSENSITIVE, - (HANDLE)ParentKey, - NULL); + InitializeObjectAttributes(&ObjectAttributes, + &SubKeyStringW, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + NULL); + Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes); RtlFreeUnicodeString(&SubKeyStringW); - if (!NT_SUCCESS(Status)) { - ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); - return ErrorCode; - } + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; + } + Status = NtDeleteKey(TargetKey); NtClose(TargetKey); - if (!NT_SUCCESS(Status)) { - ErrorCode = RtlNtStatusToDosError(Status); - SetLastError(ErrorCode); - return ErrorCode; - } + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return ErrorCode; + } + return ERROR_SUCCESS; } @@ -726,7 +688,7 @@ RegEnumKeyExW( } RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength); *lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR)); - RegiTerminateWideString(lpName, *lpcbName); + lpName[KeyInfo->NameLength / sizeof(WCHAR)] = 0; if (lpClass) { RtlMoveMemory(lpClass, (PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset), @@ -939,13 +901,13 @@ RegEnumValueW( SetLastError(dwError); break; } - memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength); + RtlCopyMemory(lpValueName, ValueInfo->Name, ValueInfo->NameLength); *lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR)); - RegiTerminateWideString(lpValueName, *lpcbValueName); + lpValueName[ValueInfo->NameLength / sizeof(WCHAR)] = 0; if (lpType) *lpType = ValueInfo->Type; if (lpData) { - memcpy(lpData, + RtlCopyMemory(lpData, //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset), (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset), ValueInfo->DataLength); @@ -1054,21 +1016,26 @@ RegFlushKey(HKEY hKey) HKEY KeyHandle; NTSTATUS Status; LONG ErrorCode; - + if (hKey == HKEY_PERFORMANCE_DATA) return(ERROR_SUCCESS); + Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } + } + Status = NtFlushKey(KeyHandle); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } + } + return(ERROR_SUCCESS); } @@ -1076,13 +1043,11 @@ RegFlushKey(HKEY hKey) /************************************************************************ * RegGetKeySecurity */ -LONG -STDCALL -RegGetKeySecurity( - HKEY hKey, - SECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR pSecurityDescriptor, - LPDWORD lpcbSecurityDescriptor) +LONG STDCALL +RegGetKeySecurity (HKEY hKey, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor, + LPDWORD lpcbSecurityDescriptor) { UNIMPLEMENTED; SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -1093,49 +1058,147 @@ RegGetKeySecurity( /************************************************************************ * RegLoadKeyA */ -LONG -STDCALL -RegLoadKeyA( - HKEY hKey, - LPCSTR lpSubKey, - LPCSTR lpFile) +LONG STDCALL +RegLoadKeyA (HKEY hKey, + LPCSTR lpSubKey, + LPCSTR lpFile) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + UNICODE_STRING FileName; + UNICODE_STRING KeyName; + DWORD ErrorCode; + + RtlCreateUnicodeStringFromAsciiz (&KeyName, + (LPSTR)lpSubKey); + RtlCreateUnicodeStringFromAsciiz (&FileName, + (LPSTR)lpFile); + + ErrorCode = RegLoadKeyW (hKey, + KeyName.Buffer, + FileName.Buffer); + + RtlFreeUnicodeString (&FileName); + RtlFreeUnicodeString (&KeyName); + + return ErrorCode; } /************************************************************************ * RegLoadKeyW */ -LONG -STDCALL -RegLoadKeyW( - HKEY hKey, - LPCWSTR lpSubKey, - LPCWSTR lpFile) +LONG STDCALL +RegLoadKeyW (HKEY hKey, + LPCWSTR lpSubKey, + LPCWSTR lpFile) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + OBJECT_ATTRIBUTES FileObjectAttributes; + OBJECT_ATTRIBUTES KeyObjectAttributes; + UNICODE_STRING FileName; + UNICODE_STRING KeyName; + HANDLE KeyHandle; + DWORD ErrorCode; + NTSTATUS Status; + + if (hKey == HKEY_PERFORMANCE_DATA) + return ERROR_INVALID_HANDLE; + + Status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile, + &FileName, + NULL, + NULL)) + { + SetLastError (ERROR_BAD_PATHNAME); + return ERROR_BAD_PATHNAME; + } + + InitializeObjectAttributes (&FileObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + RtlInitUnicodeString (&KeyName, + (LPWSTR)lpSubKey); + + InitializeObjectAttributes (&KeyObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + + Status = NtLoadKey (&KeyObjectAttributes, + &FileObjectAttributes); + + RtlFreeUnicodeString (&FileName); + + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + return ERROR_SUCCESS; } /************************************************************************ * RegNotifyChangeKeyValue */ -LONG -STDCALL -RegNotifyChangeKeyValue( - HKEY hKey, - BOOL bWatchSubtree, - DWORD dwNotifyFilter, - HANDLE hEvent, - BOOL fAsynchronous) +LONG STDCALL +RegNotifyChangeKeyValue(HKEY hKey, + BOOL bWatchSubtree, + DWORD dwNotifyFilter, + HANDLE hEvent, + BOOL fAsynchronous) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE KeyHandle; + NTSTATUS Status; + + if (hKey == HKEY_PERFORMANCE_DATA) + { + return (ERROR_INVALID_HANDLE); + } + + if (fAsynchronous && hEvent == NULL) + { + return (ERROR_INVALID_PARAMETER); + } + + Status = MapDefaultKey (&KeyHandle, + hKey); + if (!NT_SUCCESS(Status)) + { + return (RtlNtStatusToDosError (Status)); + } + + /* FIXME: Remote key handles must fail */ + + Status = NtNotifyChangeKey (KeyHandle, + hEvent, + 0, + 0, + &IoStatusBlock, + dwNotifyFilter, + bWatchSubtree, + 0, + 0, + fAsynchronous); + if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT) + { + return (RtlNtStatusToDosError (Status)); + } + + return (ERROR_SUCCESS); } @@ -1326,13 +1389,19 @@ RegQueryInfoKeyW( LONG ErrorCode; ULONG Length; - if ((lpClass) && (!lpcbClass)) { - SetLastError(ERROR_INVALID_PARAMETER); - return ERROR_INVALID_PARAMETER; - } + if ((lpClass) && (!lpcbClass)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return ERROR_INVALID_PARAMETER; + } Status = MapDefaultKey(&KeyHandle, hKey); - CHECK_STATUS; + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError(Status); + SetLastError(ErrorCode); + return(ErrorCode); + } if (lpClass) { FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass; @@ -1832,6 +1901,24 @@ RegRestoreKeyW( /************************************************************************ + * RegSaveKeyA + */ +LONG STDCALL +RegSaveKeyA(HKEY hKey, + LPCSTR lpFile, + LPSECURITY_ATTRIBUTES lpSecurityAttributes) +{ + UNICODE_STRING FileName; + LONG ErrorCode; + + RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile); + ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes); + RtlFreeUnicodeString(&FileName); + return(ErrorCode); +} + + +/************************************************************************ * RegSaveKeyW */ LONG STDCALL @@ -1848,80 +1935,74 @@ RegSaveKeyW(HKEY hKey, NTSTATUS Status; LONG ErrorCode; - Status = MapDefaultKey(&KeyHandle, hKey); - if (!NT_SUCCESS(Status)) { + Status = MapDefaultKey (&KeyHandle, + hKey); + if (!NT_SUCCESS(Status)) + { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFile, - &NtName, NULL, NULL)) { + } + + if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile, + &NtName, + NULL, + NULL)) + { SetLastError(ERROR_INVALID_PARAMETER); return(ERROR_INVALID_PARAMETER); - } + } + if (lpSecurityAttributes != NULL) + { SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; - InitializeObjectAttributes(&ObjectAttributes, - &NtName, - OBJ_CASE_INSENSITIVE, - NULL, - SecurityDescriptor); - Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - FILE_SHARE_READ, - FILE_CREATE, - FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); + } + + InitializeObjectAttributes (&ObjectAttributes, + &NtName, + OBJ_CASE_INSENSITIVE, + NULL, + SecurityDescriptor); + Status = NtCreateFile (&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_CREATE, + FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); RtlFreeUnicodeString(&NtName); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - Status = NtSaveKey(KeyHandle, FileHandle); + } + + Status = NtSaveKey(KeyHandle, + FileHandle); NtClose(FileHandle); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { ErrorCode = RtlNtStatusToDosError(Status); SetLastError(ErrorCode); return(ErrorCode); - } - return(ERROR_SUCCESS); -} - - -/************************************************************************ - * RegSaveKeyA - */ -LONG STDCALL -RegSaveKeyA(HKEY hKey, - LPCSTR lpFile, - LPSECURITY_ATTRIBUTES lpSecurityAttributes) -{ - UNICODE_STRING FileName; - LONG ErrorCode; + } - RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile); - ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes); - RtlFreeUnicodeString(&FileName); - return(ErrorCode); + return(ERROR_SUCCESS); } /************************************************************************ * RegSetKeySecurity */ -LONG -STDCALL -RegSetKeySecurity( - HKEY hKey, - SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG? */ - PSECURITY_DESCRIPTOR pSecurityDescriptor - ) +LONG STDCALL +RegSetKeySecurity(HKEY hKey, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR pSecurityDescriptor) { UNIMPLEMENTED; SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -2098,14 +2179,12 @@ RegSetValueW( /************************************************************************ * RegSetValueA */ -LONG -STDCALL -RegSetValueA( - HKEY hKey, - LPCSTR lpSubKey, - DWORD dwType, - LPCSTR lpData, - DWORD cbData) +LONG STDCALL +RegSetValueA(HKEY hKey, + LPCSTR lpSubKey, + DWORD dwType, + LPCSTR lpData, + DWORD cbData) { WCHAR SubKeyNameBuffer[MAX_PATH+1]; UNICODE_STRING SubKeyName; @@ -2147,30 +2226,68 @@ RegSetValueA( /************************************************************************ * RegUnLoadKeyA */ -LONG -STDCALL -RegUnLoadKeyA( - HKEY hKey, - LPCSTR lpSubKey) +LONG STDCALL +RegUnLoadKeyA (HKEY hKey, + LPCSTR lpSubKey) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + UNICODE_STRING KeyName; + DWORD ErrorCode; + + RtlCreateUnicodeStringFromAsciiz (&KeyName, + (LPSTR)lpSubKey); + + ErrorCode = RegUnLoadKeyW (hKey, + KeyName.Buffer); + + RtlFreeUnicodeString (&KeyName); + + return ErrorCode; } /************************************************************************ * RegUnLoadKeyW */ -LONG -STDCALL -RegUnLoadKeyW( - HKEY hKey, - LPCWSTR lpSubKey) +LONG STDCALL +RegUnLoadKeyW (HKEY hKey, + LPCWSTR lpSubKey) { - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE KeyHandle; + DWORD ErrorCode; + NTSTATUS Status; + + if (hKey == HKEY_PERFORMANCE_DATA) + return ERROR_INVALID_HANDLE; + + Status = MapDefaultKey (&KeyHandle, hKey); + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + RtlInitUnicodeString (&KeyName, + (LPWSTR)lpSubKey); + + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + + Status = NtUnloadKey (&ObjectAttributes); + + if (!NT_SUCCESS(Status)) + { + ErrorCode = RtlNtStatusToDosError (Status); + SetLastError (ErrorCode); + return ErrorCode; + } + + return ERROR_SUCCESS; } /* EOF */ diff --git a/lib/advapi32/sec/.cvsignore b/lib/advapi32/sec/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/advapi32/sec/.cvsignore +++ b/lib/advapi32/sec/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/advapi32/service/.cvsignore b/lib/advapi32/service/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/advapi32/service/.cvsignore +++ b/lib/advapi32/service/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/advapi32/token/.cvsignore b/lib/advapi32/token/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/advapi32/token/.cvsignore +++ b/lib/advapi32/token/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/crtdll/crtdll.def b/lib/crtdll/crtdll.def index 76b2fd3..49a5582 100644 --- a/lib/crtdll/crtdll.def +++ b/lib/crtdll/crtdll.def @@ -151,7 +151,7 @@ _fputwchar _fsopen _fstat _ftime -_ftol +_ftol=NTDLL._ftol _fullpath _futime _gcvt diff --git a/lib/crtdll/makefile b/lib/crtdll/makefile index b7d83d8..b0db3bc 100644 --- a/lib/crtdll/makefile +++ b/lib/crtdll/makefile @@ -161,7 +161,6 @@ MATH_OBJECTS = \ math/floor.o \ $(PATH_TO_MSVCRT)/math/fmod.o \ $(PATH_TO_MSVCRT)/math/frexp.o \ - $(PATH_TO_MSVCRT)/math/ftol.o \ math/huge_val.o \ $(PATH_TO_MSVCRT)/math/hypot.o \ $(PATH_TO_MSVCRT)/math/j0_y0.o \ @@ -285,7 +284,7 @@ SEARCH_OBJECTS = \ $(PATH_TO_MSVCRT)/search/lsearch.o SETJMP_OBJECTS = \ - $(PATH_TO_MSVCRT)/setjmp/setjmp.o + $(PATH_TO_MSVCRT)/setjmp/i386/setjmp.o SIGNAL_OBJECTS = \ signal/xcptfil.o \ diff --git a/lib/crtdll/math/ftol.c b/lib/crtdll/math/ftol.c deleted file mode 100644 index 1753090..0000000 --- a/lib/crtdll/math/ftol.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long _ftol(double fl) -{ - return (long)fl; -} diff --git a/lib/epsapi/enum/drivers.c b/lib/epsapi/enum/drivers.c new file mode 100644 index 0000000..e2893b1 --- /dev/null +++ b/lib/epsapi/enum/drivers.c @@ -0,0 +1,227 @@ +/* $Id$ +*/ +/* + * COPYRIGHT: See COPYING in the top level directory + * LICENSE: See LGPL.txt in the top level directory + * PROJECT: ReactOS system libraries + * FILE: reactos/lib/epsapi/enum/drivers.c + * PURPOSE: Enumerate system modules + * PROGRAMMER: KJK::Hyperion + * UPDATE HISTORY: + * 02/04/2003: Created + * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and + * isolated in its own library to clear the confusion + * and improve reusability + */ + +#include +#include +#include + +#include + +NTSTATUS +NTAPI +PsaEnumerateSystemModules +( + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + register NTSTATUS nErrCode = STATUS_SUCCESS; + PSYSTEM_MODULES psmModules = NULL; + +#if 0 + __try + { +#endif + do + { + /* capture the system modules */ + nErrCode = PsaCaptureSystemModules(&psmModules); + + if(!NT_SUCCESS(nErrCode)) + /* failure */ + break; + + /* walk the system modules */ + nErrCode = PsaWalkSystemModules(psmModules, Callback, CallbackContext); + } + while(0); +#if 0 + } + __finally + { +#endif + /* free the capture */ + PsaFreeCapture(psmModules); +#if 0 + } +#endif + + /* return the last status */ + return nErrCode; +} + +NTSTATUS +NTAPI +PsaCaptureSystemModules +( + OUT PSYSTEM_MODULES * SystemModules +) +{ + SIZE_T nSize = 0; + register NTSTATUS nErrCode; + register PSYSTEM_MODULES psmModules = (PSYSTEM_MODULES)&nSize; + +#if 0 + __try + { +#endif + do + { + /* initial probe. We just get the count of system modules */ + nErrCode = NtQuerySystemInformation + ( + SystemModuleInformation, + psmModules, + sizeof(nSize), + NULL + ); + + if(nErrCode != STATUS_INFO_LENGTH_MISMATCH && !NT_SUCCESS(nErrCode)) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); + break; + } + + /* RATIONALE: the loading of a system module is a rare occurrence. To + minimize memory operations that could be expensive, or fragment the + pool/heap, we try to determine the buffer size in advance, knowing that + the number of elements is unlikely to change */ + nSize = + sizeof(*psmModules) + + (psmModules->Count - 1) * sizeof(SYSTEM_MODULE_INFORMATION); + + psmModules = NULL; + + do + { + register void * pTmp; + + /* free the buffer, and reallocate it to the new size. RATIONALE: since we + ignore the buffer's content at this point, there's no point in a realloc, + that could end up copying a large chunk of data we'd discard anyway */ + PsaiFree(psmModules); + pTmp = PsaiMalloc(nSize); + + if(pTmp == NULL) + { + /* failure */ + nErrCode = STATUS_NO_MEMORY; + DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", nErrCode); + break; + } + + psmModules = pTmp; + + /* query the information */ + nErrCode = NtQuerySystemInformation + ( + SystemModuleInformation, + psmModules, + nSize, + NULL + ); + + /* double the buffer for the next loop */ + nSize += nSize; + } + /* repeat until the buffer is big enough */ + while(nErrCode == STATUS_INFO_LENGTH_MISMATCH); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); + break; + } + + /* success */ + *SystemModules = psmModules; + + nErrCode = STATUS_SUCCESS; + } + while(0); +#if 0 + } + __finally + { +#endif + /* in case of failure, free the buffer */ + if(!NT_SUCCESS(nErrCode)) + PsaiFree(psmModules); +#if 0 + } +#endif + + /* return the last status */ + return (nErrCode); +} + +NTSTATUS +NTAPI +PsaWalkSystemModules +( + IN PSYSTEM_MODULES SystemModules, + IN PSYSMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + register NTSTATUS nErrCode; + register SIZE_T i; + + /* repeat until all modules have been returned */ + for(i = 0; i < SystemModules->Count; ++ i) + { + /* return current module to the callback */ + nErrCode = Callback(&(SystemModules->Modules[i]), CallbackContext); + + if(!NT_SUCCESS(nErrCode)) + /* failure */ + return nErrCode; + } + + /* success */ + return STATUS_SUCCESS; +} + +PSYSTEM_MODULE_INFORMATION +FASTCALL +PsaWalkFirstSystemModule +( + IN PSYSTEM_MODULES SystemModules +) +{ + return &(SystemModules->Modules[0]); +} + +PSYSTEM_MODULE_INFORMATION +FASTCALL +PsaWalkNextSystemModule +( + IN PSYSTEM_MODULE_INFORMATION CurrentSystemModule +) +{ + return (PSYSTEM_MODULE_INFORMATION) + ( + (ULONG_PTR)CurrentSystemModule + + ( + offsetof(SYSTEM_MODULES, Modules[1]) - + offsetof(SYSTEM_MODULES, Modules[0]) + ) + ); +} + +/* EOF */ diff --git a/lib/epsapi/enum/modules.c b/lib/epsapi/enum/modules.c new file mode 100644 index 0000000..fa4b17f --- /dev/null +++ b/lib/epsapi/enum/modules.c @@ -0,0 +1,176 @@ +/* $Id$ +*/ +/* + * COPYRIGHT: See COPYING in the top level directory + * LICENSE: See LGPL.txt in the top level directory + * PROJECT: ReactOS system libraries + * FILE: reactos/lib/epsapi/enum/module.c + * PURPOSE: Enumerate process modules + * PROGRAMMER: KJK::Hyperion + * UPDATE HISTORY: + * 10/06/2002: Created + * 29/08/2002: Generalized the interface to improve reusability, + * more efficient use of memory operations + * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree, + * for better reusability + * 02/04/2003: System modules enumeration moved into its own file + * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and + * isolated in its own library to clear the confusion + * and improve reusability + */ + +#include +#include +#include + +#include + +NTSTATUS +NTAPI +PsaEnumerateProcessModules +( + IN HANDLE ProcessHandle, + IN PPROCMOD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + register NTSTATUS nErrCode; + + /* current process - use direct memory copy */ + if(ProcessHandle == NtCurrentProcess()) + { + register PLIST_ENTRY pleListHead; + register PLIST_ENTRY pleCurEntry; + +#if 0 + /* FIXME: activate this when GCC supports SEH */ + __try + { +#endif + pleListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList); + pleCurEntry = pleListHead->Flink; + + while(pleCurEntry != pleListHead) + { + register PLDR_MODULE plmModule = CONTAINING_RECORD + ( + pleCurEntry, + LDR_MODULE, + InLoadOrderModuleList + ); + + /* return the current module to the callback */ + nErrCode = Callback(ProcessHandle, plmModule, CallbackContext); + + if(!NT_SUCCESS(nErrCode)) + /* failure */ + goto epm_Failure; + + pleCurEntry = plmModule->InLoadOrderModuleList.Flink; + } +#if 0 + /* FIXME: activate this when GCC supports SEH */ + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + return GetExceptionCode(); + } +#endif + } + /* another process */ + else + { + PROCESS_BASIC_INFORMATION pbiInfo; + PPEB_LDR_DATA ppldLdrData; + LDR_MODULE lmModule; + PLIST_ENTRY pleListHead; + PLIST_ENTRY pleCurEntry; + + /* query the process basic information (includes the PEB address) */ + nErrCode = NtQueryInformationProcess + ( + ProcessHandle, + ProcessBasicInformation, + &pbiInfo, + sizeof(pbiInfo), + NULL + ); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", nErrCode); + goto epm_Failure; + } + + /* get the address of the PE Loader data */ + nErrCode = NtReadVirtualMemory + ( + ProcessHandle, + &(pbiInfo.PebBaseAddress->Ldr), + &ppldLdrData, + sizeof(ppldLdrData), + NULL + ); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); + goto epm_Failure; + } + + /* head of the module list: the last element in the list will point to this */ + pleListHead = &ppldLdrData->InLoadOrderModuleList; + + /* get the address of the first element in the list */ + nErrCode = NtReadVirtualMemory + ( + ProcessHandle, + &(ppldLdrData->InLoadOrderModuleList.Flink), + &pleCurEntry, + sizeof(pleCurEntry), + NULL + ); + + while(pleCurEntry != pleListHead) + { + /* read the current module */ + nErrCode = NtReadVirtualMemory + ( + ProcessHandle, + CONTAINING_RECORD(pleCurEntry, LDR_MODULE, InLoadOrderModuleList), + &lmModule, + sizeof(lmModule), + NULL + ); + + if(!NT_SUCCESS(nErrCode)) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); + goto epm_Failure; + } + + /* return the current module to the callback */ + nErrCode = Callback(ProcessHandle, &lmModule, CallbackContext); + + if(!NT_SUCCESS(nErrCode)) + /* failure */ + goto epm_Failure; + + /* address of the next module in the list */ + pleCurEntry = lmModule.InLoadOrderModuleList.Flink; + } + + } + + /* success */ + return (STATUS_SUCCESS); + +epm_Failure: + /* failure */ + return (nErrCode); +} + +/* EOF */ diff --git a/lib/epsapi/enum/processes.c b/lib/epsapi/enum/processes.c new file mode 100644 index 0000000..4e9b68c --- /dev/null +++ b/lib/epsapi/enum/processes.c @@ -0,0 +1,378 @@ +/* $Id$ +*/ +/* + * COPYRIGHT: See COPYING in the top level directory + * LICENSE: See LGPL.txt in the top level directory + * PROJECT: ReactOS system libraries + * FILE: reactos/lib/epsapi/enum/processes.c + * PURPOSE: Enumerate processes and threads + * PROGRAMMER: KJK::Hyperion + * UPDATE HISTORY: + * 10/06/2002: Created + * 29/08/2002: Generalized the interface to improve reusability, + * more efficient use of memory operations + * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree, + * for better reusability. PsaEnumerateProcesses now + * expanded into: + * - PsaCaptureProcessesAndThreads + * - PsaFreeCapture + * - PsaWalkProcessesAndThreads + * - PsaWalkProcesses + * - PsaWalkThreads + * - PsaWalkFirstProcess + * - PsaWalkNextProcess + * - PsaWalkFirstThread + * - PsaWalkNextThread + * - PsaEnumerateProcessesAndThreads + * - PsaEnumerateProcesses + * - PsaEnumerateThreads + * 12/04/2003: internal PSAPI renamed EPSAPI (Extended PSAPI) and + * isolated in its own library to clear the confusion + * and improve reusability + */ + +#include +#include +#include + +#include + +NTSTATUS +NTAPI +PsaCaptureProcessesAndThreads +( + OUT PSYSTEM_PROCESSES * ProcessesAndThreads +) +{ + NTSTATUS nErrCode = STATUS_SUCCESS; + PSYSTEM_PROCESSES pInfoBuffer = NULL; + SIZE_T nSize = 32768; + + /* parameter validation */ + if(!ProcessesAndThreads) + return STATUS_INVALID_PARAMETER_1; + + /* FIXME: if the system has loaded several processes and threads, the buffer + could get really big. But if there's several processes and threads, the + system is already under stress, and a huge buffer could only make things + worse. The function should be profiled to see what's the average minimum + buffer size, to succeed on the first shot */ + do + { + void * pTmp; + + /* free the buffer, and reallocate it to the new size. RATIONALE: since we + ignore the buffer's contents at this point, there's no point in a realloc() + that could end up copying a large chunk of data we'd discard anyway */ + PsaiFree(pInfoBuffer); + pTmp = PsaiMalloc(nSize); + + if(pTmp == NULL) + { + /* failure */ + DPRINT(FAILED_WITH_STATUS, "PsaiMalloc", STATUS_NO_MEMORY); + nErrCode = STATUS_NO_MEMORY; + break; + } + + pInfoBuffer = pTmp; + + /* query the information */ + nErrCode = NtQuerySystemInformation + ( + SystemProcessesAndThreadsInformation, + pInfoBuffer, + nSize, + NULL + ); + + /* double the buffer size */ + nSize += nSize; + } + /* repeat until the buffer is big enough */ + while(nErrCode == STATUS_INFO_LENGTH_MISMATCH); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); + return nErrCode; + } + + /* success */ + *ProcessesAndThreads = pInfoBuffer; + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PsaWalkProcessesAndThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +) +{ + register NTSTATUS nErrCode = STATUS_SUCCESS; + + /* parameter validation */ + if(!ProcessCallback && !ThreadCallback) + return STATUS_INVALID_PARAMETER; + + ProcessesAndThreads = PsaWalkFirstProcess(ProcessesAndThreads); + + /* scan the process list */ + do + { + /* if the caller provided a process callback */ + if(ProcessCallback) + { + /* notify the callback */ + nErrCode = ProcessCallback(ProcessesAndThreads, ProcessCallbackContext); + + /* if the callback returned an error, break out */ + if(!NT_SUCCESS(nErrCode)) + break; + } + + /* if the caller provided a thread callback */ + if(ThreadCallback) + { + ULONG i; + PSYSTEM_THREADS pCurThread; + + /* scan the current process's thread list */ + for + ( + i = 0, pCurThread = PsaWalkFirstThread(ProcessesAndThreads); + i < ProcessesAndThreads->ThreadCount; + ++ i, pCurThread = PsaWalkNextThread(pCurThread) + ) + { + /* notify the callback */ + nErrCode = ThreadCallback(pCurThread, ThreadCallbackContext); + + /* if the callback returned an error, break out */ + if(!NT_SUCCESS(nErrCode)) goto epat_Breakout; + } + } + + /* move to the next process */ + ProcessesAndThreads = PsaWalkNextProcess(ProcessesAndThreads); + } + /* repeat until the end of the string */ + while(ProcessesAndThreads); + +epat_Breakout: + /* return the last status */ + return (nErrCode); +} + +NTSTATUS +NTAPI +PsaEnumerateProcessesAndThreads +( + IN PPROC_ENUM_ROUTINE ProcessCallback, + IN OUT PVOID ProcessCallbackContext, + IN PTHREAD_ENUM_ROUTINE ThreadCallback, + IN OUT PVOID ThreadCallbackContext +) +{ + register NTSTATUS nErrCode; + PSYSTEM_PROCESSES pInfoBuffer; + + /* parameter validation */ + if(!ProcessCallback && !ThreadCallback) + return STATUS_INVALID_PARAMETER; + + /* get the processes and threads list */ + nErrCode = PsaCaptureProcessesAndThreads(&pInfoBuffer); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + goto epat_Finalize; + + /* walk the processes and threads list */ + nErrCode = PsaWalkProcessesAndThreads + ( + pInfoBuffer, + ProcessCallback, + ProcessCallbackContext, + ThreadCallback, + ThreadCallbackContext + ); + +epat_Finalize: + /* free the buffer */ + PsaFreeCapture(pInfoBuffer); + + /* return the last status */ + return (nErrCode); +} + +VOID +NTAPI +PsaFreeCapture +( + IN PVOID Capture +) +{ + PsaiFree(Capture); +} + +NTSTATUS +NTAPI +PsaWalkProcesses +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + return PsaWalkProcessesAndThreads + ( + ProcessesAndThreads, + Callback, + CallbackContext, + NULL, + NULL + ); +} + +NTSTATUS +NTAPI +PsaWalkThreads +( + IN PSYSTEM_PROCESSES ProcessesAndThreads, + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + return PsaWalkProcessesAndThreads + ( + ProcessesAndThreads, + NULL, + NULL, + Callback, + CallbackContext + ); +} + +NTSTATUS +NTAPI +PsaEnumerateProcesses +( + IN PPROC_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + return PsaEnumerateProcessesAndThreads + ( + Callback, + CallbackContext, + NULL, + NULL + ); +} + +NTSTATUS +NTAPI +PsaEnumerateThreads +( + IN PTHREAD_ENUM_ROUTINE Callback, + IN OUT PVOID CallbackContext +) +{ + return PsaEnumerateProcessesAndThreads + ( + NULL, + NULL, + Callback, + CallbackContext + ); +} + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkFirstProcess +( + IN PSYSTEM_PROCESSES ProcessesAndThreads +) +{ + return ProcessesAndThreads; +} + +PSYSTEM_PROCESSES +FASTCALL +PsaWalkNextProcess +( + IN PSYSTEM_PROCESSES CurrentProcess +) +{ + if(CurrentProcess->NextEntryDelta == 0) + return NULL; + else + return + (PSYSTEM_PROCESSES) + ((ULONG_PTR)CurrentProcess + CurrentProcess->NextEntryDelta); +} + +PSYSTEM_THREADS +FASTCALL +PsaWalkFirstThread +( + IN PSYSTEM_PROCESSES CurrentProcess +) +{ + static SIZE_T nOffsetOfThreads = 0; + + /* get the offset of the Threads field (dependant on the kernel version) */ + if(!nOffsetOfThreads) + { + /* + FIXME: we should probably use the build number, instead, but it isn't + available as reliably as the major and minor version numbers + */ + switch(SharedUserData->NtMajorVersion) + { + /* NT 3 and 4 */ + case 3: + case 4: + { + nOffsetOfThreads = offsetof(SYSTEM_PROCESSES_NT4, Threads); + break; + } + + /* NT 5 and later */ + default: + case 5: + { + nOffsetOfThreads = offsetof(SYSTEM_PROCESSES_NT5, Threads); + break; + } + } + } + + return (PSYSTEM_THREADS)((ULONG_PTR)CurrentProcess + nOffsetOfThreads); +} + +PSYSTEM_THREADS +FASTCALL +PsaWalkNextThread +( + IN PSYSTEM_THREADS CurrentThread +) +{ + return (PSYSTEM_THREADS) + ( + (ULONG_PTR)CurrentThread + + ( + offsetof(SYSTEM_PROCESSES, Threads[1]) - + offsetof(SYSTEM_PROCESSES, Threads[0]) + ) + ); +} + +/* EOF */ diff --git a/lib/epsapi/makefile b/lib/epsapi/makefile new file mode 100644 index 0000000..f185c38 --- /dev/null +++ b/lib/epsapi/makefile @@ -0,0 +1,18 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = library + +TARGET_NAME = epsapi + +TARGET_OBJECTS = \ + enum/drivers.o \ + enum/modules.o \ + enum/processes.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/lib/fmifs/format.c b/lib/fmifs/format.c index 1f6d817..bf14bfd 100644 --- a/lib/fmifs/format.c +++ b/lib/fmifs/format.c @@ -13,6 +13,11 @@ #define _UNICODE #include #include +#include + +#define NDEBUG +#include + /* FMIFS.6 */ VOID @@ -35,14 +40,30 @@ FormatEx( PFMIFSCALLBACK Callback ) { - BOOL Argument = FALSE; + UNICODE_STRING usDriveRoot; + UNICODE_STRING usLabel; + BOOL Argument = FALSE; + + RtlInitUnicodeString(&usDriveRoot, DriveRoot); + RtlInitUnicodeString(&usLabel, Label); + + if (_wcsnicmp(Format, L"FAT", 3) == 0) + { + DPRINT1("FormatEx - FAT\n"); + VfatInitialize(); + + VfatFormat(&usDriveRoot, MediaFlag, &usLabel, QuickFormat, ClusterSize, Callback); - /* FAIL immediately */ - Callback( - DONE, /* Command */ - 0, /* DWORD Modifier */ - & Argument /* Argument */ + VfatCleanup(); + } + else + { + /* Unknown file system */ + Callback(DONE, /* Command */ + 0, /* DWORD Modifier */ + &Argument /* Argument */ ); + } } diff --git a/lib/fmifs/makefile b/lib/fmifs/makefile index 0e887a7..1ab8f93 100644 --- a/lib/fmifs/makefile +++ b/lib/fmifs/makefile @@ -12,7 +12,7 @@ TARGET_CFLAGS = -fno-builtin TARGET_LFLAGS = -nostdlib -nostartfiles -TARGET_SDKLIBS = ntdll.a kernel32.a +TARGET_SDKLIBS = vfatlib.a ntdll.a kernel32.a TARGET_OBJECTS = \ chkdsk.o \ @@ -24,11 +24,15 @@ TARGET_OBJECTS = \ init.o \ label.o \ media.o - + +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk +include $(TOOLS_PATH)/depend.mk + TARGET_FILES = misc/*.o # EOF diff --git a/lib/freetype/.cvsignore b/lib/freetype/.cvsignore new file mode 100644 index 0000000..864f27c --- /dev/null +++ b/lib/freetype/.cvsignore @@ -0,0 +1,5 @@ +.*.d +*.o +nul +freetype.dll +freetype.nostrip.dll diff --git a/lib/freetype/ChangeLog b/lib/freetype/ChangeLog new file mode 100644 index 0000000..2917038 --- /dev/null +++ b/lib/freetype/ChangeLog @@ -0,0 +1,5782 @@ +2003-03-27 David Turner + + * README: udpated + + * README.UNX: removed (now replaced by docs/INSTALL.UNX) + + * src/pshinter/pshalgo3.c: the hinter now performs as in 2.1.3 and + will ignore stem quantization only when FT_LOAD_TARGET_SMOOTH is used + + * src/base/ftobjs.c: changed the default computations to include rounding + in all cases, this is required to provide accurate kerning data when + native TrueType hinting is enabled. + + * src/type1/t1load.c: the Type 1 loader now accepts more general names + according to the Postscript spec (the previous one was too restrictive) + +2003-03-20 David Turner + + * docs/*: serious rewriting of the documentation + + * include/freetype/internal/ftobjs.h, src/base/ftobjs.c, src/bdf/bdfdrivr.c, + src/pcf/pcfdriver.c, src/pfr/pfrsbit.c, src/sfnt/ttsbit.c, + src/type42/t42objs.c, src/winfonts/winfnt.c: introduced three new functions + to deal with glyph bitmaps within FT_GlyphSlot objects. these are: + + ft_glyphslot_free_bitmap + ft_glyphslot_alloc_bitmap + ft_glyphslot_set_bitmap + + these are much more convenient to use than managing the FT_GLYPH_OWN_BITMAP + flag manually. the font drivers have been modified to use them as well. + + * src/cache/ftlru.c: fixed an invalid assertion check + + * src/autohint/ahglyph.h, src/autohint/ahglyph.c, src/autohint/ahglobal.c, + src/autohint/ahhint.c: fixed blue-scale problem + + * src/cache/ftccache.c: fixed small bug that could crash the cache + in rare circumstances (mostly with broken fonts) + + +2003-03-15 David Turner + + * src/truetyoe/ttdriver.c (Set_Char_Sizes): fixed a small rounding bug. + Actually, it seems that previous versions of FreeType didn't perform + TrueType rounding exactly as appropriate. + +2003-03-14 David Turner + + * src/truetype/ttdriver.c: fixing the small TrueType native rendering + glitches, they came from a small rounding error. + +2003-03-13 David Turner + + * src/base/ftdbgmem.c, docs/DEBUG.TXT: added new environment variables + to control memory debugging with FreeType. See the description of + "FT2_DEBUG_MEMORY", "FT2_ALLOC_TOTAL_MAX" and "FT2_ALLOC_COUNT_MAX" + in DEBUG.TXT + + * src/cache/ftccache.c, src/cache/ftccmap.c, src/cache/ftcsbits.c, + ftlru.c: fixed the cache sub-system to correctly deal with out-of-memory + conditions. + + * src/pfr/pfrobjs.c, src/pfr/pfrsbits.c: fixing compiler warnings and a + small memory leak + + * src/psaux/psobjs.c (t1_reallocate_table): fixed a bug (memory leak) that + only happened when trying to resize an array would end in an OOM. + + * src/smooth/ftgrays.c: removed compiler warnings / volatile bug + + * src/truetype/ttobjs.c: removed segmentation fault that happened in + tight memory environments. + +2003-02-28 Pixel + + * src/gzip/ftgzip.c (ft_gzip_file_done): fixed memory leak, the ZLib + stream was not properly finalized + +2003-02-25 Anthony Fok + + * src/cache/ftccmap.c: the cmap cache now supports UCS-4 charmaps + when available in Asian fonts + + * src/sfnt/ttload.c, src/base/ftobjs.c: changed "asian" to "Asian" in + comments + +2003-02-25 David Turner + + * src/gzip/ftgzip.c: fixed a bug that caused FreeType to loop endlessly + when trying to read certain compressed gzip files. The following test + could be used to reveal the bug: + + touch 0123456789 ; gzip 0123456789 ; ftdump 0123456789.gz + + + * src/pfr/pfrobjs.c, src/pfr/pfrload.c, src/pfr/pfrtypes.h: several + fixes to the PFR font driver: + + - the list of available embedded bitmaps was not correctly set + in the root FT_FaceRec structure describing the face + + - the glyph loader always tried to load the outlines when + FT_LOAD_SBITS_ONLY was specified + + - the table loaded now scans for *undocumented* elements of a + physical font's auxiliary data record, this is necessary to + retrieve the "real" family and style names. + + NOTE THAT THIS CHANGES THE FAMILY NAME OF MANY PFR FONTS !! + + * src/truetype/ttdriver.c (Set_Char_Sizes): fixed a rounding bug when + computing the scale factors for a given character size in points with + resolution. + + +2003-02-18 David Turner + + * src/truetype/ttdriver.c, src/truetype/ttobjs.h, src/truetype/ttobjs.c, + src/truetype/ttinterp.c, src/base/ftobjs.c: fixing the slight distortion + problem that occured due to the latest auto-hinter changes + + + * src/autohint/ahhint.c: disabled the advance width "correction" which + seemed to provide more trouble than benefits.. + +2003-02-13 Graham Asher + + * include/freetype/ftincrem.h, src/cff/cffgload.c, src/cid/cidgload.c, + src/truetype/ttgload.c, src/type1/t1gload.c + [FT_CONFIG_OPTION_INCREMENTAL]: I have changed the incremental loading + interface in a way that makes it simpler and allows glyph metrics to + be changed (e.g., by adding a constant, as required by CFF fonts) + rather than just overridden. This was required to make the GhsotScript- + to-FreeType bridge work. + +2003-01-31 David Turner + + * docs/CHANGES, docs/VERSION.DLL, docs/TODO: updating documentation for + the 2.1.4 release + + * builds/win32/visualc/freetype.dsp, builds/win32/visualc/index.html: + updating the project file for 2.1.4 + + * src/gzip/adler32.c, src/gzip/ftgzip.c, src/gzip/infblock.c, + src/gzip/infcodes.c, src/gzip/inflate.c, src/gzip/inftrees.c, + src/gzip/infutil.c: removed old-style (K&R)function definitions. This + avoids warnings with Visual C++ at its most pedantic mode. + + * src/pfr/pfrsbit.c: removed compiler warnings + + * src/cache/ftccmap.c: changed a FT_ERROR into a FT_TRACE1 since the + it caused "ftview" and others to dump too much junk when trying to + display a waterfall with a font without a Unicode charmap (e.g. + SYMBOL.TTF) + + * src/autohint/ahtypes.h, src/autohint/ahhint.c, src/base/ftobjs.c, + src/truetype/ttobjs.c: implemented FT_CONFIG_CHESTER_BLUE_SCALE, + corresponding to the last patch from David Chester, but with a + much simpler (and saner) implementation. + + * src/pshinter/pshalgo3.c: improved the Postscript hinter. Getting rid + of stem snapping seems to work well here (though the stems are still + slightly moved to increase contrast). + + THIS IMPROVES ANTI-ALIASED RENDERING, BUT MONOCHROME AND LCD MODES + STILL SUCK... I need to work this a bit + +2003-01-22 David Chester + + * src/autohint/ahhint.c: small fix to the stem width optimisation + +2003-01-22 David Turner + + * include/freetype/ftbdf.h, include/freetype/internal/bdftypes.h, + src/base/ftbdf.c, src/bdf/bdfdrivr.c, src/pcf/pcfdrivr.c, + src/pcf/pcfread.h: + + adding a new API, named FT_Get_BDF_Property to retrieve the BDF + properties of a given PCF or BDF font + + * src/sfnt/ttload.c (sfnt_dir_check): relaxed the "head" table size + verification to accept a few broken fonts who pad the size incorrectly + (the table should be padded, but its "size" field shouldn't per se + the spec) + +2003-01-18 Werner Lemberg + + * builds/unix/ltmain.sh: Regenerated with `libtoolize --force + --copy' from libtool 1.4.3. + * builds/unix/aclocal.m4: Regenerated with `aclocal -I .' from + automake 1.7.1. + * builds/unix/configure: Regenerated with autoconf 2.54. + * builds/unix/config.guess, builds/unix/config.sub: Updated from + `config' CVS module at subversions.gnu.org. + * builds/unix/install-sh, builds/unix/mkinstalldirs: Updated from + `automake' CVS module at subversions.gnu.org. + +2003-01-15 David Turner + + * include/freetype/freetype.h: Fixed documentation for + FT_Size_Metrics. + +2003-01-15 James Su + + * src/gzip/ftgzip.c: Bugfix: couldn't read certain gzip-ed font + files. + +2003-01-15 Huw D M Davies + + * include/freetype/config/ftheader.h, + include/freetype/internal/fnttypes.h, include/freetype/ftwinfnt.h, + src/base/winfnt.c, src/winfonts/winfnt.c, src/base/Jamfile, + src/base/rules.mk, src/base/descrip.mms: Added a Windows .FNT + specific API (mostly for Wine). Also fixed a nasty bug in the + header loader which would cause invalid memory overwrites. + +2003-01-14 Graham Asher + + * include/freetype/ftglyph.h, src/base/ftglyph.c: Added `const' to + the type of the first argument to FT_Matrix_Multiply, which isn't + changed -- this adds documentation and convenience. + +2003-01-13 Graham Asher + + * src/sfnt/ttload.c (tt_face_load_metrics) + [FT_CONFIG_OPTION_INCREMENTAL]: TrueType typefaces without + horizontal metrics (without the `hmtx' table) are now tolerated if + an incremental interface has been specified that has a + get_glyph_metrics function, implying that metrics will be supplied + from outside. This happens for certain Type 42 fonts passed from + GhostScript. + +2003-01-11 David Chester + + * include/freetype/config/ftoption.h, src/autohint/ahglobal.h, + src/autohint/ahglobal.c, src/autohint/ahglyph.c, + src/autohint/ahtypes.h: Patches to the auto-hinter in order to + slightly improve the output. Note that everything is controlled + through the new FT_CONFIG_OPTION_CHESTER_HINTS defined at the end of + "ftoption.h". There are also individual FT_CONFIG_CHESTER_XXX + macros to control individual "features". + + Note that all improvements are enabled by default, but can be + tweaked for optimization and testing purposes. The configuration + macros will most likely disappear in the short future. + +2003-01-11 David Turner + + * include/freetype/internal/fnttypes.h: Fixed a structure field + definition to avoid memory overwrites. + +2003-01-08 Huw Dawies + + * src/winfonts/winfnt.c: Read 16 bytes into "reserved2", not + "reserved". + + * src/base/ftobjs.c (find_unicode_charmap): Fixed the error code + returned when the font doesn't contain a Unicode charmap. This + allows FT2 to load "symbol.ttf" and a few others correctly since the + last release. + +2003-01-08 Owen Taylor + + * src/autohint/ahtypes.h, src/autohint/ahhint.c, + src/pshinter/pshalgo3.h, src/pshinter/pshalgo3.c: Implemented the + FT_RENDER_MODE_LIGHT hinting mode in the auto and postscript + hinters. + + * src/truetype/ttgload.c: Fixing the TrueType loader to handle + invalid composites correctly by limiting the recursion depth. + +2003-01-08 David Turner + + * Jamrules, Jamfile, Jamfile.in, src/*/Jamfile: Small changes to + support the compilation of FreeType 2 as part of larger projects + with their own configuration options (only with Jam). + +2003-01-07 David Turner + + * src/base/ftstroker.c: Probably the last bug-fixes to the stroker; + the API is likely to change, however. + + * src/base/fttrigon.c (FT_Angle_Diff): Fixing function: It returned + invalid values for large negative angle differences (resulting in + incorrect stroker computations, among other things). + + * src/cache/ftccache.c (ftc_node_unlink): Removing incorrect + assertion, and changing code to avoid hash table size contraction. + + * src/base/Jamfile, src/base/rules.mk, src/base/descrip.mms: Adding + "ftstroker.obj" to default build, as optional component. + +2002-12-26 David Turner + + * src/gzip/adler32.c, src/gzip/infblock.c, src/gzip/inflate.c, + src/gzip/inftrees.c, src/gzip/zconf.h, src/gzip/zlib.h, + src/gzip/zutil.h: Updates to allow compilation without compiler + warnings with LCC-Win32. + + * include/freetype/freetype.h, docs/VERSION.DLL, + builds/unix/configure.ac, builds/unix/configure: Updates for the + upcoming 2.1.4 release. + +2002-12-23 Anthony Fok + + * builds/unix/configure.ac, builds/unix/unix-cc.in, + builds/unix/unix-def.in: Small fix to configure sub-system on Unix + to allow other programs to correctly link with zlib when needed. + +2002-12-17 David Turner + + * src/base/ftobjs.c (find_unicode_charmap): Added some comments to + better explain what's happening there. + + * src/base/ftobjs.c (open_face): Included Graham Asher's fix to + prevent faces without Unicode charmaps from loading. + + * src/winfonts/winfnt.c: Included George Williams's fix to support + version 2 fonts correctly. + +2002-12-16 David Turner + + * docs/VERSION.DLL: Updating document to better explain the + differences between the three version numbers being used on Unix, as + well as providing an autoconf fragment provided by Lars Clausen. + + * src/smooth/ftgrays.c (gray_render_conic): Fixed small bug that + prevented bezier arcs with negative vertical coordinates to be + rendered appropriately. + +2002-12-02 Antoine Leca + + * src/base/ftobjs.c: Modified the logic to get Unicode charmaps. + Now it loads UCS-4 charmaps when there is one. + * src/base/ftobjs.c (find_unicode_charmap): New function. + * src/base/ftobjs.c (open_face): Refer to the above one. + * src/base/ftobjs.c (FT_Select_Charmap): Idem. + +2002-11-29 Antoine Leca + + * include/freetype/ftgzip.h: Correct the name of the controlling + macro (was __FTXF86_H__ ...). + +2002-11-27 Vincent Caron + + * builds/unix/unix-def.in, builds/unix/freetype-config.in, + builds/unix/configure.ac, src/gzip/rules.mk, src/gzip/ftgzip.c: + Adding support for system zlib installations if available on the + target platform (Unix only). + +2002-11-23 David Turner + + * src/cff/cffload.c (cff_charser_load): Modified charset loader to + accept pre-defined charsets, even when the font contains fewer + glyphs. Also enforced more checks to ensure that we never overflow + the character codes array in the encoding. + +2002-11-18 David Turner + + + * Version 2.1.3 is released. + ============================ + + +2002-11-07 David Turner + + * src/cache/ftcsbit.c (ftc_sbit_node_load): Fixed a small bug that + caused problems with embedded bitmaps. + + * src/otlayout/otlayout.h, src/otlyaout/otlconf.h, + src/otlayout/otlgsub.c, src/otlayout/otlgsub.h, + src/otlayout/otlparse.c, src/otlayout/otlparse.h, + src/otlayout/otlutils.h: Updating the OpenType Layout code, adding + support fot the first GSUB lookups. Nothing that really compiles + for now though. + + * src/autohint/ahhint.c: Disabled serif stem width quantization. It + produces slightly better shapes though this is not distinguishable + with many fonts. + +2002-11-05 David Turner + + * include/freetype/config/ftoption.h, src/gzip/ftgzip.c: Added + support for the FT_CONFIG_OPTION_SYSTEM_ZLIB option, used to specify + the use of system-wide zlib. + + Note that this macro, as well as + FT_CONFIG_OPTION_BYTECODE_INTERPRETER, is not #undef-ed anymore. + This allows the build system to define them depending on the + configuration (typically by adding -D flags at compile time). + + * src/sfnt/ttcmap0.c (tt_face_build_cmaps): Removed compiler + warnings in optimized mode relative to the "volatile" local + variables. This was not a compiler bug after all, but the fact that + a pointer to a volatile variable is not the same than a volatile + pointer to a variable :-) + + The fix was to change + `volatile FT_Byte* p' + into + `FT_Byte* volatile p'. + + * src/pfr/pfrload.c, src/pfr/pfrdrivr.c, src/gzip/inftrees.c: + Removed compiler warnings in optimized modes. + + * src/gzip/*.[hc]: Modified our zlib copy in order to prevent + exporting any zlib function names outside of the component. This + prevents linking problems on some platforms, when applications want + to link FreeType _and_ zlib together. + +2002-11-05 Juliusz + + * src/psaux/psobjs.c (ps_table_add): Modified increment loop in + order to implement exponential behaviour. + +2002-10-31 David Turner + + * include/freetype/ftgzip.h, src/gzip/ftgzip.c: Adding support for + gzip compressed streams. + + * src/pcf/pcfdriver.c: Adding automatic support for gzip-compressed + PCF files. + +2002-10-30 David Turner + + * FreeType 2.1.3rc3 released + +2002-10-25 David Turner + + * include/freetype/ftcache.h (FT_POINTER_TO_ULONG): New macro. + (FTC_FACE_ID_HASH): Rewritten, using FT_POINTER_TO_ULONG. + +2002-10-22 Giuseppe Ghibò + + * include/freetype/freetype.h (FT_Encoding): Fix entry for latin-2. + +2002-10-07 Werner Lemberg + + * include/freetype/freetype.h (FT_Open_Face): Use `const' for `args' + (suggested by Graham). + * src/base/ftobjs.c (FT_Open_Face): Updated. + (ft_input_stream_new): Ditto. + +2002-10-05 David Turner + + Adding support for embedded bitmaps to the PFR driver, and rewriting + its kerning loader/handler to use all kerning pairs in a physical + font (and not just the first item). + + * src/pfr/pfr.c: Include `pfrsbit.c'. + * src/pfr/pfrgload.c: Include `pfrsbit.h'. + * src/pfr/pfrload.c (pfr_extra_item_load_kerning_pairs): Rewritten. + (pfr_phy_font_done, pfr_phy_font_load): Updated. + * src/pfr/pfrobks.c: Include `pfrsbit.h'. + (pfr_face_init): Handle kerning and embedded bitmaps. + (pfr_slot_load): Load embedded bitmaps. + (PFR_KERN_INDEX): Removed. + (pfr_face_get_kerning): Rewritten. + * src/pfr/pfrsbit.c, src/pfr/pfrsbit.h: New files. + * src/pfr/pfrtypes.h (PFR_KernItemRec): New structure. + (PFR_KERN_INDEX): New macro. + (PFR_PhyFontRec): Add items for kerning and embedded bitmaps. + * src/pfr/Jamfile (_sources) [FT2_MULTI]: Add `pfrsbit'. + + * src/base/ftobjs.c (FT_Load_Glyph): Don't load bitmap fonts if + FT_LOAD_NO_RECURSE is set. + Load embedded bitmaps only if FT_LOAD_NO_BITMAP isn't set. + + * src/tools/docmaker/content.py, src/tools/docmaker/sources.py, + src/tools/docmaker/tohtml.py: Fixing a few nasty bugs. + + * src/sfnt/ttcmap0.c (tt_cmap4_validate): The validator for format 4 + sub-tables is now capable of dealing with invalid "length" fields at + the start of the sub-table. This allows fonts like "mg______.ttf" + (i.e. Marriage) to return accurate charmaps. + + * docs/CHANGES: Updated. + +2002-10-05 Werner Lemberg + + * src/smooth/ftgrays.c (SUBPIXELS): Add cast to `TPos'. + Update all callers. + (TRUNC): Add cast to `TCoord'. + Update all callers. + (TRaster): Use `TPos' for min_ex, max_ex, min_ey, max_ey, and + last_ey. + Update all casts. + (gray_render_line): Fix casts for `p' and `first'. + +2002-10-02 Detlef Würkner + + * src/bdf/bdflib.c (bdf_load_font): Allocate the _bdf_parse_t + structure with FT_ALLOC instead of using the stack. + +2002-09-27 Werner Lemberg + + * src/include/freetype/internal/tttypes.h (num_sbit_strikes, + num_sbit_scales): Use `FT_ULong'. + * src/sfnt/sfobjs.c (sfnt_load_face): Updated accordingly. + * src/sfnt/ttsbit.c (tt_face_set_sbit_strike): Ditto. + (find_sbit_image): Remove cast. + * src/raster/ftrend1.c (ft_raster1_render): Fix cast. + +2002-09-27 Wolfgang Domröse + + * src/sfnt/ttload.c (tt_face_load_names): Use cast. + * src/sfnt/ttcmap.c (code_to_next2): Use long constant. + (code_to_index4): Use cast. + (code_to_index8_12): Fix cast. + * src/sfnt/ttcmap0.c (tt_cmap4_char_next, tt_cmap8_char_index, + tt_cmap12_char_index): Use cast for `result'. + (tt_face_build_cmaps): Use cast. + * src/sfnt/sfobjs.c (tt_name_entry_ascii_from_ucs4): Use cast for + `code'. + (sfnt_load_face): Use FT_Int32 for `flags'. + + * src/smooth/ftgrays.c (gray_render_scanline, gray_render_line, + gray_compute_cbox, gray_convert_glyph, gray_raster_reset): Add casts + to `TCoord' and `int'. + More 16bit fixes. + s/FT_Pos/TPos/. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Add casts. + +2002-09-26 Werner Lemberg + + * src/sfnt/ttpost.c (load_post_names, tt_face_free_ps_names, + tt_face_get_ps_name): Replace switch statement with if clauses to + make it more portable. + + * src/cff/cffobjs.c (cff_face_init): Ditto. + + * include/freetype/ftmodule.h (FT_Module_Class): Use `FT_Long' for + `module_size'. + * include/freetype/ftrender.h (FT_Glyph_Class_): Use `FT_Long' for + `glyph_size'. + + * src/base/ftobjs.c (FT_Render_Glyph): Change second parameter to + `FT_Render_Mode'. + (FT_Render_Glyph_Internal): Change third parameter to + `FT_Render_Mode'. + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Change second parameter + to `FT_Render_Mode'. + + * src/raster/ftrend1.c (ft_raster1_render): Change third parameter + to `FT_Render_Mode'. + * src/smooth/ftsmooth.c (ft_smooth_render, ft_smooth_render_lcd, + ft_smooth_render_lcd_v): Ditto. + (ft_smooth_render_generic): Change third and fifth parameter to + `FT_Render_Mode'. + + * include/freetype/freetype.h, include/freetype/internal/ftobjs.h, + include/freetype/ftglyph.h: Updated. + + * src/cff/cffdrivr.c (Load_Glyph), src/pcf/pcfdriver.c + (PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load), + src/winfonts/winfnt.c (FNT_Load_Glyph), src/t42/t42objs.c + (T42_GlyphSlot_Load), src/bdf/bdfdrivr.c (BDF_Glyph_Load): Change + fourth parameter to `FT_Int32'. + + * src/pfr/pfrobjs.c (pfr_face_init): Add two missing parameters + and declare them as unused. + + * src/cid/cidparse.h (CID_Parser): Use FT_Long for `postscript_len'. + + * src/psnames/psnames.h (PS_Unicode_Value_Func): Change return + value to FT_UInt32. + * src/psnames/psmodule.c (ps_unicode_value, ps_build_unicode_table): + Updated accordingly. + +2002-09-26 Wolfgang Domröse + + * src/cff/cffdrivr.c (Get_Kerning): Use FT_Long for `middle'. + (cff_get_glyph_name): Use cast for result of ft_strlen. + * src/cff/cffparse.c (cff_parse_real): User cast for assigning + `exp'. + * src/cff/cffload.c (cff_index_get_pointers): Use FT_ULong for + some local variables. + (cff_charset_load, cff_encoding_load): Use casts to FT_UInt for some + switch statements. + (cff_font_load): Use cast in call to CFF_Load_FD_Select. + * src/cff/cffobjs.c (cff_size_init): Use more casts. + (cff_face_init): Use FT_Int32 for `flags'. + * src/cff/cffgload.c (cff_operator_seac): Use cast for assigning + `adx' and `ady'. + (cff_decoder_parse_charstrings): Use FT_ULong for third parameter. + Use more casts. + * src/cff/cffcmap.c (cff_cmap_unicode_init): Use cast for `count'. + + * src/cid/cidload.c (cid_read_subrs): Use FT_ULong for `len'. + * src/cid/cidgload.c (cid_load_glyph): Add missing cast for + `cid_get_offset'. + + * src/psaux/t1decode.c (t1_decoder_parse_charstrings) <18>: Use + cast for `num_points'. + (t1_decoder_init): Use cast for assigning `decoder->num_glyphs'. + + * src/base/ftdebug.c (ft_debug_init): Use FT_Int. + * include/freetype/internal/ftdriver.h (FT_Slot_LoadFunc): Use + `FT_Int32' for fourth parameter. + * src/base/ftobjs.c (open_face): Use cast for calling + clazz->init_face. + + * src/raster/ftraster.c (Set_High_Precision): Use `1' instead of + `1L'. + (Finalize_Profile_Table, Line_Up, ft_black_init): Use casts. + * src/raster/ftrend1.c (ft_raster1_render): Ditto. + + * src/sfnt/sfnt_dir_check: Compare `magic' with unsigned long + constant. + +2002-09-26 Detlef Würkner + + * builds/amiga/include/freetype/config/ftmodule.h: Updated. + +2002-09-25 David Turner + + * src/autohint/ahtypes.h (AH_HINT_METRICS): Disabling metrics + hinting in the auto-hinter. This produces much better anti-aliased + text. + + * docs/CHANGES: Updating the changes documentation. + +2002-09-25 Anthony Fok + + * src/sfnt/ttcmap0.c (tt_cmap4_validate, tt_cmap4_char_index, + tt_cmap4_char_next): Added support for opens___.ttf (it contains a + charmap that uses offset=0xFFFFU instead of 0x0000 to indicate a + missing glyph). + +2002-09-21 Wolfgang Domröse + + * src/truetype/ttdriver.c (Load_Glyph): Fourth parameter must be + FT_Int32. + * src/truetype/ttgload.c, src/truetype/ttgload.h (TT_Load_Glyph): + Ditto. + +2002-09-19 Wolfgang Domröse + + More 16bit fixes. + + * src/autohint/ahglobal.c (sort_values): Use FT_Pos for `swap'. + (ah_hinter_compute_widths): Use FT_Pos for `dist'. + Use AH_MAX_WIDTHS. + * src/autohint/ahglyph.c (ah_outline_scale_blue_edges): Use FT_Pos + for `delta'. + (ah_outline_compute_edges): Replace some ints with FT_Int and + FT_Pos. + (ah_test_extrema): Clean up code. + (ah_get_orientation): Use 4 FT_Int variables instead of FT_BBox to + hold indices. + * src/autohint/ahtypes.h (AH_SegmentRec): Change type of `score' + to FT_Pos. + +2002-09-19 Werner Lemberg + + * builds/unix/config.guess, builds/unix/config.sub: Updated to + recent versions. + +2002-09-18 David Turner + + * src/base/ftobjs.c (FT_Library_Version): Bugfix. + + * FreeType 2.1.3rc2 (release candidate 2) is released! + +2002-09-17 David Turner + + * include/freetype/freetype.h, include/freetype/ftimage.h, + include/freetype/ftstroker.h, include/freetype/ftsysio.h, + include/freetype/ftsysmem.h, include/freetype/ttnameid.h: Updating + the in-source documentation. + + * src/tools/docmaker/tohtml.py: Updating the HTML formatter in the + DocMaker tool. + + * src/tools/docmaker.py: Removed. + +2002-09-17 Werner Lemberg + + More 16bit fixes. + + * src/psaux/psobjs.c (reallocate_t1_table): Use FT_Long for + second parameter. + +2002-09-16 Werner Lemberg + + 16bit fixes from Wolfgang Domröse. + + * src/type1/t1parse.h (T1_ParserRec): Change type of `base_len' + and `private_len' to FT_Long. + * src/type1/t1parse.c (T1_Get_Private_Dict): Remove cast for + `private_len'. + * src/type1/t1load.c: Use FT_Int cast for most calls of T1_ToInt. + Use FT_PtrDist where appropriate. + (parse_encoding): Use FT_Long for `count' and `n'. + (read_binary_data): Use FT_Long* for second parameter. + * src/type1/t1afm.c (afm_atoindex): Use FT_PtrDist. + + * src/cache/ftcsbits.c (ftc_sbit_node_load): Remove unused label. + * src/pshinter/pshalgo3.c (psh3_hint_align): Remove unused variable. + +2002-09-14 Werner Lemberg + + Making ftgrays.c compile stand-alone again. + + * include/freetype/ftimage.h: Include ft2build.h only if _STANDALONE_ + isn't defined. + * src/smooth/ftgrays.c [_STANDALONE_]: Define ft_memset, + FT_BEGIN_HEADER, FT_END_HEADER. + (FT_MEM_ZERO): Define. + (TRaster) [GRAYS_USE_GAMMA]: Use `unsigned char' instead of FT_Byte. + (gray_render_span, gray_init_gamma): Don't use `FT_UInt'. + Don't cast with `FT_Byte'. + (grays_init_gamma): Don't use `FT_UInt'. + +2002-09-14 Werner Lemberg + + * src/base/ftinit.c (FT_Add_Default_Modules): Improve error message. + * src/pcf/pcfdriver.c (PCF_Face_Done): Improve tracing message. + * include/freetype/config/ftoption.h (FT_MAX_MODULES): Increased + to 32. + +2002-09-10 Werner Lemberg + + * builds/unix/configure.ac (version_info): Set to 9:2:3. + * builds/unix/configure: Regenerated. + * docs/VERSION.DLL: Updated. + +2002-09-09 David Turner + + * src/pshinter/pshalgo2.c (psh2_glyph_find_strong_points), + src/pshinter/pshalgo3.c (psh3_glyph_find_strong_points): Adding fix + to prevent seg fault when hints are provided in an empty glyph. + + * src/cache/ftccache.i (GEN_CACHE_LOOKUP) [FT_DEBUG_LEVEL_ERROR]: + Removed conditional code. This fixes a bug that prevented + compilation in debug mode of template instantiation. + + * include/freetype/ftimage.h: Removed incorrect "zft_" definitions + and updated constants documentation comments. + + * src/cff/cffparse.c (cff_parser_run): Fixed the CFF table loader. + It didn't accept empty arrays, and this prevented the loading of + certain fonts. + + * include/freetype/freetype.h (FT_FaceRec): Updating documentation + comment. The "descender" value is always *negative*, not positive. + +2002-09-09 Owen Taylor + + * src/pcf/pcfdriver.c (PCF_Glyph_Load): Fixing incorrect computation + of bitmap metrics. + +2002-09-08 David Turner + + Various updates to correctly support sub-pixel rendering. + + * include/freetype/config/ftmodule.h: Add two renderers for LCD. + + * src/base/ftobjs.c (FT_Load_Glyph): Updated. + + * src/smooth/ftsmooth.c (ft_smooth_render_lcd, + ft_smooth_render_lcd_v): Set FT_PIXEL_MODE_LCD and + FT_PIXEL_MODE_LCD_V, respectively. + + * include/freetype/cache/ftcimage.h (FTC_ImageTypeRec): New + structure. + Updated all users. + (FTC_ImageDesc): Removed. + (FTC_ImageCache_Lookup): Second parameter is now of type + `FTC_ImageType'. + Updated all users. + (FTC_IMAGE_DESC_COMPARE): Updated and renamed to... + (FTC_IMAGE_TYPE_COMPARE): This. + (FTC_IMAGE_DESC_HASH): Updated and renamed to... + (FTC_IMAGE_TYPE_HASH): This. + + * include/freetype/cache/ftcsbits.h (FTC_SBitRec): Field `num_grays' + replaced with `max_grays'. + `pitch' is now FT_Short. + (FTC_SBitCache_Lookup): Second parameter is now of type + `FTC_ImageType'. + Updated all users. + + * src/cache/ftcimage.c (FTC_ImageQueryRec, FTC_ImageFamilyRec): + Updated. + (ftc_image_node_init): Updated. + Moved code to convert type flags to load flags to... + (FTC_Image_Cache_Lookup): This function. + (ftc_image_family_init): Updated. + + * src/cache/ftcsbit.c (FTC_SBitQueryRec, FTC_SBitFamilyRec): + Updated. + (ftc_sbit_node_load): Updated. + Moved code to convert type flags to load flags to... + (FTC_SBitCache_Lookup): This function. + + * src/autohint/ahtypes.h (AH_HinterRec): Replace `no_*_hints' with + `do_*_snapping'. + Update all users (with negation). + * src/autohint/ahhint.c (ah_compute_stem_width): Fix threshold for + `dist' for `delta' < 40. + + * src/pshinter/pshalgo3.h (PSH3_GlyphRec): Replace `no_*_hints' with + `do_*_snapping'. + Update all users (with negation). + * src/pshinter/pshalgo3.c (psh3_dimension_quantize_len): New + function. + (psh3_hint_align): Use it. + Improve hinting code. + [STRONGER]: Removed. + (STRONGER): Removed. + + * include/freetype/freetype.h (FT_Set_Hint_Flags, FT_HINT_*): + Removed. + +2002-09-05 Werner Lemberg + + * src/cid/cidobjs.c (CID_Size_Init): Renamed to... + (cid_size_init): This. + * src/psaux/psobjs.c (T1_Builder_Add_Point1): Renamed to... + (t1_builder_add_point1): This. + + Updated all affected code. + + * src/pshinter/pshalgo3.c (psh3_hint_align): Fix compiler warnings. + * src/type1/t1gload.c (T1_Compute_Max_Advance): Ditto. + +2002-09-04 David Turner + + * include/freetype/freetype.h: Corrected the definition of + ft_encoding_symbol to be FT_ENCODING_MS_SYMBOL (instead of + the erroneous FT_ENCODING_SYMBOL). + + * builds/unix/unix-def.in (datadir): Initialize it (thanks to + Anthony Fok). + +2002-08-29 David Turner + + Slight modification to the Postscript hinter to slightly increase + the contrast of smooth hinting. This is very similar to what the + auto-hinter does when it comes to stem width computations. However, + it produces better results with well-hinted fonts. + + * include/freetype/internal/psaux.h (T1_Decoder_FuncsRec): Add hint + mode to `init' member function. + (T1_DecoderRec): Add hint mode. + * include/freetype/internal/pshints (T1_Hints_ApplyFunc, + T2_Hints_ApplyFunc): Pass `hint_mode', not `hint_flags'. + * src/psaux/t1decode.c (t1_decoder_init): Add hint mode argument. + * src/pshinter/pshalgo1.c (ps1_hints_apply): Pass hint mode, not + hint flags. + * src/pshinter/pshalgo2.c (ps2_hints_apply): Ditto. + * src/pshinter/pshalgo3.c (ps3_hints_apply): Ditto. + (STRONGER): New macro. + (psh3_hint_align, psh3_hint_table_align_hints): Pass `glyph' instead + of `hint_flags'. + Implement announced changes. + * src/pshinter/pshalgo3.h (PSH3_GlyphRec): Add flags to control + vertical and horizontal hints and snapping. + + * README, docs/CHANGES: Updating for the 2.1.3 release. + +2002-08-27 David Turner + + * Massive re-formatting changes to many, many source files. I don't + want to list them all here. The operations performed were all + logical transformations of the sources: + + - trying to convert all enums and constants to CAPITALIZED_STYLE, + #with define definitions like + + #define my_old_constants MY_NEW_CONSTANT + + - big, big update of the documentation comments + + * include/freetype/freetype.h, src/base/ftobjs.c, + src/smooth/ftsmooth.c, include/freetype/ftimage.h: Adding support + for LCD-optimized rendering though the new constants/enums: + + FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V + FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V + + This is still work in progress, don't expect everything to work + correctly though most of the features have been implemented. + + * Adding new FT_LOAD_XXX flags, used to specify both hinting and + rendering targets: + + FT_LOAD_TARGET_NORMAL :: anti-aliased hinting & rendering + FT_LOAD_TARGET_MONO :: monochrome bitmaps + FT_LOAD_TARGET_LCD :: horizontal RGB/BGR decimated + hinting & rendering + FT_LOAD_TARGET_LCD_V :: vertical RGB/BGR decimated + hinting & rendering + + Note that FT_LOAD_TARGET_NORMAL is 0, which means that the default + behaviour of the font engine is _unchanged_. + + * include/freetype/ftimage.h + (FT_Outline_{Move,Line,Conic,Cubic}To_Func): Renamed to... + (FT_Outline_{Move,Line,Conic,Cubic}ToFunc): This. + (FT_Raster_Span_Func): Renamed to ... + (FT_SpanFunc): This. + (FT_Raster_{New,Done,Reset,Set_Mode,Render}_Func): Renamed to ... + (FT_Raster_{New,Done,Reset,SetMode,Render}Func}: This. + + Updated all affected code. + + * include/freetype/ftrender.h + (FT_Glyph_{Init,Done,Transform,BBox,Copy,Prepare}_Func): Renamed + to ... + (FT_Glyph_{Init,Done,Transform,GetBBox,Copy,Prepare}Func): This. + (FTRenderer_{render,transform,getCBox,setMode}): Renamed to ... + (FT_Renderer_{RenderFunc,TransformFunc,GetCBoxFunc,SeteModeFunc}): + This. + + Updated all affected code. + + * src/autohint/ahtypes.h (AH_Point, AH_Segment, AH_Edge, AH_Globals, + AH_Face_Globals, AH_Outline, AH_Hinter): These typedefs are now + pointers to the corresponding `*Rec' structures. All source files + have been updated accordingly. + + * src/cff/cffgload.c (cff_decoder_init): Add hint mode as parameter. + * src/cff/cffgload.h (CFF_Decoder): Add `hint_mode' element. + + * src/cid/cidgload.c (CID_Compute_Max_Advance): Renamed to... + (cid_face_compute_max_advance): This. + (CID_Load_Glyph): Renamed to... + (cid_slot_load_glyph): This. + * src/cid/cidload.c (CID_Open_Face): Renamed to... + (cid_face_open): This. + * src/cid/cidobjs.c (CID_GlyphSlot_{Done,Init}): Renamed to... + (cid_slot_{done,init}): This. + (CID_Size_{Get_Globals_Funcs,Done,Reset): Renamed to... + (cid_size_{get_globals_funcs,done,reset): This. + (CID_Face_{Done,Init}): Renamed to... + (cid_face_{done,init}): This. + (CID_Driver_{Done,Init}: Renamed to... + (cid_driver_{done,init}: This. + * src/cid/cidparse.c (CID_{New,Done}_Parser): Renamed to... + (cid_parser_{new,done}): This. + * src/cid/cidparse.h (CID_Skip_{Spaces,Alpha}): Renamed to... + (cid_parser_skip_{spaces,alpha}): This. + (CID_To{Int,Fixed,CoordArray,FixedArray,Token,TokenArray}): Renamed + to... + (cid_parser_to_{int,fixed,coord_array,fixed_array,token,token_array}): + This. + (CID_Load_{Field,Field_Table): Renamed to... + (cid_parser_load_{field,field_table}): This. + * src/cid/cidriver.c (CID_Get_Interface): Renamed to... + (cid_get_interface): This. + + Updated all affected code. + + * src/psaux/psobjs.c (PS_Table_*): Renamed to... + (ps_table_*): This. + (T1_Builder_*): Renamed to... + (t1_builder_*): This. + * src/psaux/t1decode.c (T1_Decoder_*): Renamed to... + (t1_decoder_*): This. + + * src/psnames/psmodule.c (PS_*): Renamed to... + (ps_*): This. + + Updated all affected code. + + * src/sfnt/sfdriver (SFNT_Get_Interface): Renamed to... + (sfnt_get_interface): This. + * src/sfnt/sfobjs.c (SFNT_*): Renamed to... + (sfnt_*): This. + * src/sfnt/ttcmap.c (TT_CharMap_{Load,Free}): Renamed to... + (tt_face_{load,free}_charmap): This. + * src/sfnt/ttcmap0.c (TT_Build_CMaps): Renamed to... + (tt_face_build_cmaps): This. + * src/sfnt/ttload.c (TT_*): Renamed to... + (tt_face_*): This. + * src/sfnt/ttpost.c (TT_Post_Default_Names): Renamed to... + (tt_post_default_names): This. + (Load_*): Renamed to... + (load_*): This. + (TT_*): Renamed to... + (tt_face_*): This. + * src/sfnt/ttsbit.c (TT_*): Renamed to... + (tt_face_*): This. + ({Find,Load,Crop}_*): Renamed to... + ({find,load,crop}_*): This. + + Updated all affected code. + + * src/smooth/ftsmooth.c (ft_smooth_render): Renamed to... + (ft_smooth_render_generic): This. + Make function more generic by adding vertical and horizontal scaling + factors. + (ft_smooth_render, ft_smooth_render_lcd, ft_smooth_render_lcd_v): + New functions. + + (ft_smooth_locd_renderer_class, ft_smooth_lcdv_renderer_class): New + classes. + + * src/truetype/ttobjs.c (TT_{Done,New}_GlyphZone): Renamed to... + (tt_glyphzone_{done,new}): This. + (TT_{Face,Size,Driver}_*): Renamed to... + (tt_{face,size,driver}_*): This. + * src/truetype/ttpload.c (TT_Load_Locations): Renamed to... + (tt_face_load_loca): This. + (TT_Load_Programs): Renamed to... + (tt_face_load_fpgm): This. + (TT_*): Renamed to... + (tt_face_*): This. + +2002-08-27 Werner Lemberg + + * docs/VERSION.DLL: New file. + +2002-08-23 Graham Asher + + * src/cff/cffgload.c (cff_operator_seac) + [FT_CONFIG_OPTION_INCREMENTAL]: Incremental fonts (actually not + incremental in the case of CFF but just using callbacks to get glyph + recipes) pass the character code, not the glyph index, to the + get_glyph_data function; they have no valid charset table. + + * src/cff/cffload.c (cff_font_load): Removed special cases for + FT_CONFIG_OPTION_INCREMENTAL, which are no longer necessary; CFF + fonts provided via the incremental interface now have to conform + more closely to the CFF font format. + + * src/cff/cffload.h (cff_font_load): Removed argument now unneeded. + + * src/cff/cffobjs.c (cff_face_init): Changed call to cff_font_load + to conform with new signature. + +2002-08-22 David Turner + + * src/base/ftobject.c, src/base/ftsynth.c, src/base/ftstroker.c, + src/bdf/bdfdrivr.c: Removed compiler warnings. + +2002-08-21 Werner Lemberg + + * src/pshinter/pshalgo3.c (psh3_glyph_compute_inflections, + psh3_glyph_compute_extrema, psh3_hint_table_find_strong_point): Fix + compiler warnings and resolve shadowing of local variables. + +2002-08-21 David Turner + + The automatic and Postscript hinter now automatically detect + inflection points in glyph outlines and treats them specially. This + is very useful to prevent nasty effect like the disappearing + diagonals of "S" and "s" in many, many fonts. + + * src/autohint/ahtypes.h (ah_flag_inflection): New macro. + * src/autohint/ahangles.c (ah_angle_diff): New function. + * src/autohint/ahangles.h: Updated. + * src/autohint/ahglyph.c (ah_outline_compute_inflections): New + function. + (ah_outline_detect_features): Use it. + * src/autohint/ahhint.c (ah_hinter_align_strong_points) + [!AH_OPTION_NO_WEAK_INTERPOLATION]: Handle inflection. + + * src/tools/docmaker/docmaker.py, src/tools/docmaker/utils.py, + src/tools/docmaker/tohtml.py: Updating the DocMaker tool. + + * include/freetype/freetype.h: Changing the type of the "load_flags" + parameter from "FT_Int" to "FT_Int32", this in order to support more + options. This should only break binary and/or source compatibility + on 16-bit platforms (Atari?). + (FT_LOAD_NO_AUTOHINT): New macro. + + * src/base/ftobjs.c (FT_Load_Glyph): Updated. + Handle FT_LOAD_NO_AUTOHINT. + (FT_Load_Char): Updated. + + * src/pshinter/pshalgo3.c, src/base/ftobjs.c, src/base/ftobject.c, + src/autohint/ahglyph.c, include/freetype/freetype.h: Fixing typos + and removing compiler warnings. + +2002-08-20 Werner Lemberg + + * src/truetype/ttgload.c (TT_Get_Metrics): Add guard for k = 0. + +2002-08-20 David Turner + + * src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.c, + src/pshinter/pshglob.c, src/pshinter/pshrec.c, + src/autohint/ahmodule.c [DEBUG_HINTER]: Removing compiler warnings + (only used in development builds anyway). + + Improve support of local extrema and stem edge points. + + * src/pshinter/pshalgo3.h (PSH3_Hint_TableRec): Use PSH3_ZoneRec + for `zones'. + (PSH3_DIR_UP, PSH3_DIR_DOWN): Exchange values. + (PSH3_DIR_HORIZONTAL, PSH3_DIR_VERTICAL): New macros. + (PSH3_DIR_COMPARE, PSH3_DIR_IS_HORIZONTAL, PSH3_IS_VERTICAL): New + macros. + (PSH3_POINT_INFLEX): New enum. + (psh3_point_{is,set}_{off,inflex}): New macros. + (PSH3_POINT_{EXTREMUM,POSITIVE,NEGATIVE,EDGE_MIN,EDGE_MAX): New + enum values. + (psh3_point_{is,set}_{extremum,positive,negative,edge_min,edge_max}): + New macros. + (PSH3_PointRec): New members `flags2' and `org_v'. + (PSH3_POINT_EQUAL_ARG, PSH3_POINT_ANGLE): New macros. + + * src/pshinter/pshalgo3.c [DEBUG_HINTER]: Removing compiler + warnings. + (COMPUTE_INFLEXS): New macro. + (psh3_hint_align): Simplify some basic arithmetic computations. + (psh3_point_is_extremum): Removed. + (psh3_glyph_compute_inflections) [COMPUTE_INFLEXS]: New function. + (psh3_glyph_init) [COMPUTE_INFLEXS]: Use it. + (psh3_glyph_compute_extrema): New function. + (PSH3_STRONG_THRESHOLD): Increased to 30. + (psh3_hint_table_find_strong_point): Improved. + (psh3_glyph_find_strong_points, + psh3_glyph_interpolate_strong_points): Updated. + (psh3_hints_apply): Use psh3_glyph_compute_extrema. + + * test/gview.c (draw_ps3_hint, ps3_draw_control_points): New + functions. + Other small updates. + + * Jamfile: Small updates. + +2002-08-18 Arkadiusz Miskiewicz + + * builds/unix/install.mk (install, uninstall): Add $(DESTDIR) to + make life easier for package maintainers. + +2002-08-18 Werner Lemberg + + * src/pcf/pcfdriver.c (PCF_Glyph_Load): Fix computation of + horiBearingX. + * src/bdf/bdfdrivr.c (BDF_GlyphLoad): Fix computation of + horiBearingY. + +2002-08-16 George Williams + + Add support for Apple composite glyphs. + + * include/freetype/config/ftoption.h + (TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED): New macro. + + * src/truetype/ttgload.c (OVERLAP_COMPOUND, SCALED_COMPONENT_OFFSET, + UNSCALED_COMPONENT_OFFSET): New macros for additional OpenType + glyph loading flags. + (load_truetype_glyph): Implement it. + +2002-08-16 Werner Lemberg + + * src/cff/cffgload.c (cff_free_glyph_data), + src/cff/cffload.c (cff_font_load): Use FT_UNUSED. + +2002-08-15 Werner Lemberg + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Initialize `error'. + * src/sfnt/sfobjs.c (SFNT_Load_Face): Fix compiler warning. + +2002-08-15 Graham Asher + + Implemented the incremental font loading system for the CFF driver. + Tested using the GhostScript-to-FreeType bridge (under development). + + * src/cff/cffgload.c (cff_get_glyph_data, cff_free_glyph_data): New + functions. + (cff_operator_seac, cff_compute_max_advance, cff_slot_load): Use + them. + * src/cff/cffload.c (cff_font_load): Add `face' parameter. + Load charset and encoding only if there are glyphs. + [FT_CONFIG_OPTION_INCREMENTAL]: Incremental fonts don't need + character recipes. + * src/cff/cffload.h, src/cff/cffobjs.c: Updated. + + * src/cid/cidgload.c (cid_load_glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: Corrected the incremental font + loading implementation to use the new system introduced on + 2002-08-01. + +2002-08-06 Werner Lemberg + + * src/cff/cffcmap.c: Remove compiler warnings. + * src/cache/ftccache.c, src/cache/ftccache.i, + src/pfr/pfrload.c, src/pfr/pfrgload.c: s/index/idx/. + * src/cff/cffload.c: s/select/fdselect/. + * src/raster/ftraster.c: s/wait/waiting/. + +2002-08-01 Graham Asher + + * src/type1/t1load.c (T1_Open_Face): Tolerate a face with no + charstrings if there is an incremental loading interface. Type 1 + faces supplied by PostScript interpreters like GhostScript will + typically not provide any charstrings at load time, so this is + essential if they are to work. + +2002-08-01 Graham Asher + + Modified incremental loading interface to be closer to David's + preferences. The header freetype.h is not now affected, the + interface is specified via an FT_Parameter, the pointer to the + interface is hidden in an internal part of the face record, and all + the definitions are in ftincrem.h. + + * include/freetype/freeetype.h [FT_CONFIG_OPTION_INCREMENTAL]: + Removed. + * include/freetype/internal/ftobjs.h [FT_CONFIG_OPTION_INCREMENTAL]: + Include FT_INCREMENTAL_H. + (FT_Face_InternalRec) [FT_CONFIG_OPTION_INCREMENTAL]: Add + `incremental_interface'. + + * src/base/ftobjs.c (open_face, FT_Open_Face) + [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + * src/sfnt/sfobjs.c (SFNT_Load_Face) [FT_CONFIG_OPTION_INCREMENTAL]: + Updated. + + * src/truetype/ttgload.c (load_truetype_glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + Free loaded glyph data properly. + (compute_glyph_metrics, TT_Load_Glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + * src/truetype/ttobjs.c (TT_Face_Init) + [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + + * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String) + [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + (T1_Parse_Glyph) [FT_CONFIG_OPTION_INCREMENTAL]: Updated. + Free loaded glyph data properly. + (T1_Load_Glyph): Updated. + [FT_CONFIG_OPTION_INCREMENTAL]: Free loaded glyph data properly. + +2002-07-30 David Turner + + * include/freetype/ftincrem.h: Adding new experimental header file + to demonstrate a "cleaner" API to support incremental font loading. + + * include/freetype/config/ftheader.h (FT_INCREMENTAL_H): New macro. + + * src/tools/docmaker/*: Adding new (more advanced) version of + the DocMaker tool, using Python's sophisticated regexps. + +2002-07-28 Werner Lemberg + + s/ft_memset/FT_MEM_SET/. + s/FT_MEM_SET/FT_MEM_ZERO/ where appropriate. + +2002-07-27 Werner Lemberg + + * src/sfnt/ttload.c (sfnt_dir_check): Make it work with TTCs. + +2002-07-26 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: s/memset/ft_memset/. + + * src/autohint/ahhint.c (ah_hint_edges_3): Fix compiler warning. + * src/cff/cffload.c (cff_encoding_load): Remove `memory' variable. + * src/cff/cffcmap.c (cff_cmap_encoding_init): Remove `psnames' + variable. + * src/truetype/ttgload.c (load_truetype_glyph): Remove statement + without effect. + * src/truetype/ttdriver (Get_Char_Index, Get_Next_Char): Removed. + + * src/pshinter/pshalgo3.c (psh3_hint_table_record, + psh3_hint_table_init, psh3_hint_table_activate_mask): Fix error + message. + +2002-07-24 Graham Asher + + * src/truetype/ttobjs.c: Fix for bug reported by Sven Neumann + [sven@gimp.org] on the FreeType development forum: "If + FT_CONFIG_OPTION_INCREMENTAL is undefined (this is the default), the + TrueType loader crashes in line 852 of src/truetype/ttgload.c when + it tries to access face->glyph_locations." + +2002-07-18 Graham Asher + + Added types and structures to support incremental typeface loading. + The FT_Incremental_Interface structure, defined in freetype.h, is + designed to be passed to FT_Open_Face to provide callback functions + to obtain glyph recipes and metrics, for fonts like those passed + from PostScript that do not necessarily provide all, or any, glyph + information, when first opened. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_INCREMENTAL): + New configuration macro to enable incremental face loading. By + default it is not defined. + + * include/freetype/freetype.h (FT_Basic_Glyph_Metrics, + FT_Get_Glyph_Data_Func, FT_Get_Glyph_Metrics_Func, + FT_Incremental_Interface_Funcs, FT_Incremental_Interface) + [FT_CONFIG_OPTION_INCREMENTAL]: New. + (FT_Open_Args, FT_FaceRec) [FT_CONFIG_OPTION_INCREMENTAL]: New field + `incremental_interface'. + (FT_Open_Flags) [FT_CONFIG_OPTION_INCREMENTAL]: New enum + `ft_open_incremental'. + + * include/freetype/fttypes.h: Include FT_CONFIG_CONFIG_H. + (FT_Data): New structure to represent binary data. + + * src/base/ftobjs.c (open_face) [FT_CONFIG_OPTION_INCREMENTAL]: + Add parameter for incremental loading. + (FT_Open_Face) [FT_CONFIG_OPTION_INCREMENTAL]: Use incremental + interface. + + * src/truetype/ttgload.c (load_truetype_glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: Added the incremental loading system + for the TrueType driver. + (compute_glyph_metrics): Return FT_Error. + [FT_CONFIG_OPTION_INCREMENTAL]: Check for overriding metrics. + (TT_Load_Glyph) [FT_CONFIG_OPTION_INCREMENTAL]: Don't look for + the glyph table while handling an incremental font. + Get glyph offset. + + * src/truetype/ttobjs.c (TT_Face_Init) + [FT_CONFIG_OPTION_INCOREMENTAL]: Added the incremental loading + system for the TrueType driver. + + * src/cid/cidgload.c (cid_load_glyph) + [FT_CONFIG_OPTION_INCREMENTAL]: Added the incremental loading system + for the CID driver. + + * src/sfnt/sfobjs.c (SFNT_Load_Face) [FT_CONFIG_OPTION_INCREMENTAL]: + Changes to support incremental Type 42 fonts: Assume a font has + glyphs if it has an incremental interface object. + + * src/type1/t1gload.c (T1_Parse_Glyph): Renamed to... + (T1_Parse_Glyph_And_Get_Char_String): This. + [FT_CONFIG_OPTION_INCREMENTAL]: Added support for incrementally + loaded Type 1 faces. + (T1_Parse_Glyph): New function. + (T1_Load_Glyph): Updated. + +2002-07-17 David Turner + + Cleaning up the cache sub-system code; linear hashing is now the + default. + + * include/freetype/cache/ftccache.h, src/cache/ftccache.i, + src/cache/ftccache.c [!FTC_CACHE_USE_LINEAR_HASHING]: Removed. + (FTC_CACHE_USE_LINEAR_HASHING: Removed also. + + FT_CONFIG_OPTION_USE_CMAPS is now the default. + + * include/freetype/internal/ftdriver.h (FT_Driver_ClassRec): Remove + `get_char_index' and `get_next_char'. + + * include/freetype/config/ftoption.h, + include/freetype/internal/tttypes.h, src/base/ftobjs.c, + src/bdf/bdfdrivr.c, src/cff/cffobjs.c, src/pcf/pcfdrivr.c, + src/pfr/pfrdrivr.c, src/sfnt/sfobjs.c, src/sfnt/ttcmap0.c, + src/sfnt/ttcmap0.h, src/sfnt/ttload.c, src/type1/t1objs.c, + src/type42/t42objs.c, src/winfonts/winfnt.c + [!FT_CONFIG_OPTION_USE_CMAPS]: Removed. The new cmap code is now + the default. + + * src/type42/t42objs.c (T42_CMap_CharIndex, T42_CMap_CharNext): + Removed. + * src/type42/t42objs.h: Updated. + + * src/cid/cidriver.c (Cid_Get_Char_Index, Cid_Get_Next_Char): + Removed. + (t1_cid_driver_class): Updated. + * src/truetype/ttdriver.c (tt_driver_class): Updated. + * src/type1/t1driver.c (Get_Char_Index, Get_Next_Char): Removed + (t1_driver_class): Updated. + * src/type42/t42drivr.c (t42_driver_class): Updated. + + * src/base/ftobjs.c (open_face): Select Unicode cmap by default. + + * src/sfnt/ttload.c (TT_Load_SFNT_Header): Fixed a recent bug that + prevented OpenType fonts to be recognized by FreeType. + +2002-07-11 David Turner + + Changing the SFNT loader to check for SFNT-based font files + differently. We now ignore the range "helper" fields and check the + "head" table's magic number instead. + + * include/freetype/internal/tttypes.h (SFNT_HeaderRec): Add `offset' + field. + + * src/sfnt/ttload.c (sfnt_dir_check): New function. + (TT_Load_SFNT_HeaderRec): Renamed to... + (TT_Load_SFNT_Header): This. + Implement new functionality. + * src/sfnt/ttload.h: Updated. + * src/sfnt/sfdriver.c (sfnt_interface): Updated. + + * src/base/ftobject.c, src/base/fthash.c: Updated object sub-system + and dynamic hash table implementation (still experimental, don't + use). + * include/freetype/internal/fthash.h: Updated. + * include/freetype/internal/ftobjs.h (FT_LibraryRec): New member + `meta_class'. + + Fixing a bug in the Type 1 loader that prevented valid font bounding + boxes to be loaded from multiple master fonts. + + * include/freetype/t1tables.h (PS_BlendRec): Add `bboxes' field. + + * include/freetype/internal/psaux.h (T1_FieldType): Add + `T1_FIELD_TYPE_BBOX'. + (T1_FieldLocation): Add `T1_FIELD_LOCATION_BBOX'. + (T1_FIELD_BBOX): New macro. + + * src/psaux/psobjs.c (PS_Parser_LoadField): Handle T1_FIELD_TYPE_BBOX. + * src/type1/t1load.c (t1_allocate_blend): Create blend->bboxes. + (T1_Done_Blend): Free blend->bboxes. + (t1_load_keyword): Handle T1_FIELD_LOCATION_BBOX. + (parse_font_bbox): Commented out. + (t1_keywords): Comment out `parse_font_bbox'. + * src/type1/t1tokens.h: Define `FontBBox' field. + +2002-07-10 David Turner + + * src/cff/cffobjs.c: Small fix to select the Unicode charmap by + default when needed. + Small fix to allow OpenType fonts to support Adobe charmaps when + needed. + + * src/cff/cffcmap.c, src/cff/cffcmap.h: New files to support + charmaps for CFF fonts. + + * src/cff/cff.c, src/cff/Jamfile, src/cff/rules.mk: Updated. + + * include/freetype/internal/cfftypes.h (CFF_EncodingRec): Use + fixed-length arrays for `sids' and `codes'. Add `count' member. + (CFF_FontRec): Add `psnames' member. + + * src/cff/cffdrivr.c, src/cff/cffload.c, src/cff/cffload.h, + src/cff/cffobjs.c, src/cff/cffobjs.h, src/cff/cffparse.c, + src/cffparse.h, src/cff/cffgload.c, src/cff/cffgload.h: Adding + support for CFF charmaps, reformatting the sources, and removing + some bugs in the Encoding and Charset loaders. + Many fonts renamed to use lowercase only: + + CFF_Builder_Init -> cff_builder_init + CFF_Builder_Done -> cff_builder_done + CFF_Init_Decoder -> cff_decoder_init + CFF_Parse_CharStrings -> cff_decoder_parse_charstrings + CFF_Load_Glyph -> cff_slot_load + CFF_Init_Decoder -> cff_decoder_init + CFF_Prepare_Decoder -> cff_decoder_prepare + CFF_Get_Standard_Encoding -> cff_get_standard_encoding + CFF_Access_Element -> cff_index_access_element + CFF_Forget_Element -> cff_index_forget_element + CFF_Get_Name -> cff_index_get_name + CFF_Get_String -> cff_index_get_sid_string + CFF_Get_FD -> cff_fd_select_get + CFF_Done_Charset -> cff_charset_done + CFF_Load_Charset -> cff_charset_load + CFF_Done_Encoding -> cff_encoding_done + CFF_Load_Encoding -> cff_encoding_load + CFF_Done_SubFont -> cff_subfont_done + CFF_Load_Font -> cff_font_load + CFF_Done_Font -> cff_font_done + CFF_Size_Get_Global_Funcs -> cff_size_get_global_funcs + CFF_Size_Done -> cff_size_done + CFF_Size_Init -> cff_size_init + CFF_Size_Reset -> cff_size_reset + CFF_GlyphSlot_Done -> cff_slot_done + CFF_GlyphSlot_Init -> cff_slot_init + CFF_StrCopy -> cff_strcpy + CFF_Face_Init -> cff_face_init + CFF_Face_Done -> cff_face_done + CFF_Driver_Init -> cff_driver_init + CFF_Driver_Done -> cff_driver_done + CFF_Parser_Init -> cff_parser_init + CFF_Parser_Run -> cff_parser_run + + add_point -> cff_builder_add_point + add_point1 -> cff_builder_add_point1 + add_contour -> cff_builder_add_contour + close_contour -> cff_builder_close_contour + cff_explicit_index -> cff_index_get_pointers + +2002-07-09 Owen Taylor + + * src/pshinter/pshglob.c (psh_globals_new): Fixed a bug that + prevented the hinter from using correct standard width and height + values, resulting in hinting bugs with certain fonts (e.g. Utopia). + +2002-07-07 David Turner + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Added code to return + successfully when the function is called with a bitmap glyph (the + previous code simply returned with an error). + + * docs/DEBUG.TXT: Adding debugging support documentation. + + * src/base/ftdebug.c (ft_debug_init), builds/win32/ftdebug.c + (ft_debug_init), builds/amiga/src/ftdebug.c (ft_debug_init): Changed + the syntax of the FT2_DEBUG environment variable used to control + debugging output (i.e. logging and error messages). It must now + look like: + + any:6 memory:4 io:3 or + any:6,memory:4,io:3 or + any:6;memory:4;io:3 + +2002-07-07 Owen Taylor + + * src/pshinter/pshglob.c (psh_blues_snap_stem): Adding support for + blue fuzz. + * src/pshinter/pshglob.h (PSH_BluesRec): Add `blue_fuzz' field. + * src/type1/t1load.c (T1_Open_Face): Initialize `blue_fuzz'. + + Adding support for hinter-specific bit flags, and the new + FT_Set_Hint_Flags high-level API. + + * include/freetype/freetype.h (FT_Set_Hint_Flags): New function. + (FT_HINT_NO_INTEGER_STEM, FT_HINT_NO_HSTEM_ALIGN, + FT_HINT_NO_VSTEM_ALIGN): New macros. + + * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): Add + `hint_flags' member. + + * src/base/ftobjs.c (FT_Set_Hint_Flags): New function. + + * include/freetype/internal/psaux.h (T1_DecoderRec): Add `hint_flags' + member. + + * include/freetype/internal/pshints.h (T1_Hints_ApplyFunc, + T2_Hints_ApplyFunc): Add parameter to pass hint flags. + + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings, + T1_Decoder_Init): Use decoder->hint_flags. + * src/cff/cffgload.h (CFF_Builder): Add `hint_flags' field. + * src/cff/cffgload.c (CFF_Builder_Init): Set builder->hint_flags. + (CFF_Parse_CharStrings): Updated. + * src/pshinter/pshalgo1.c (ps1_hints_apply): Add parameter to handle + hint flags (unused). + * src/pshinter/pshalgo1.h: Updated. + * src/pshinter/pshalgo2.c (ps2_hints_apply): Add parameter to handle + hint flags (unused). + * src/pshinter/pshalgo2.h: Updated. + * src/pshinter/pshalgo3.c (ps3_hints_apply): Add parameter to handle + hint flags. + * src/pshinter/pshalgo3.h: Updated. + +2002-07-04 David Turner + + * src/pfr/pfrobjs.c (pfr_slot_load): Fixed a small bug that returned + incorrect advances when the outline resolution was different from + the metrics resolution. + + * src/autohint/ahhint.c: Removing compiler warnings. + + * src/autohint/ahglyph.c: s/FT_MEM_SET/FT_ZERO/ where appropriate. + (ah_outline_link_segments): Slight improvements to the serif + detection code. More work is needed though. + +2002-07-03 David Turner + + Small improvements to the automatic hinter. Uneven stem-widths have + now disappeared and everything looks much better, even if there are + still issues with serifed fonts. + + * src/autohint/ahtypes.h (AH_Globals): Added `stds' array. + * src/autohint/ahhint.c (OPTIM_STEM_SNAP): New #define. + (ah_snap_width): Commented out. + (ah_align_linked_edge): Renamed to... + (ah_compute_stem_width): This. + Don't allow uneven stem-widths. + (ah_align_linked_edge): New function. + (ah_align_serifed_edge): Don't strengthen serifs. + (ah_hint_edges_3, ah_hinter_scale_globals): Updated. + +2002-07-03 Owen Taylor + + Adding new algorithm based on Owen Taylor's recent work. + + * src/pshinter/pshalgo3.c, src/pshinter/pshalgo3.h: New files. + * src/pshinter/pshalgo.h: Updated. + Use pshalgo3 by default. + * src/pshinter/pshinter.c: Include pshalgo3.c. + + * src/pshinter/Jamfile, src/pshinter/rules.mk: Updated. + +2002-07-01 Owen Taylor + + * src/pshinter/pshalgo2.c (psh2_glyph_find_strong_points): Fix a bug + where, if a glyph has more than hint mask, the second mask gets + applied to points that should have been covered by the first mask. + +2002-07-01 Keith Packard + + * src/sfnt/ttcmap0.c (tt_cmap8_char_next, tt_cmap12_char_next): + Fixing the cmap 8 and 12 parsing routines. + +2002-07-01 David Turner + + * src/base/ftsynth.c: Include FT_TRIGONOMETRY_H. + (FT_Outline_Embolden): Renamed to... + (FT_GlyphSlot_Embolden): This. + Updated to new trigonometric functions. + (FT_Outline_Oblique): Renamed to... + (FT_GlyphSlot_Oblique): This. + (ft_norm): Removed. + * include/freetype/ftsynth.h: Updated. + +2002-06-26 David Turner + + * include/freetype/internal/ftobject.h: Updating the object + sub-system definitions (still experimental). + + * src/base/fthash.c (ft_hash_remove): Fixing a small reallocation + bug. + + * src/base/fttrigon.c (FT_Vector_From_Polar, FT_Angle_Diff): New + functions. + * include/freetype/fttrigon.h: Updated. + + + Adding path stroker component (work in progress). + + * include/freetype/ftstroker.h, src/base/ftstroker.c: New files. + * src/base/Jamfile: Updated. + + * include/freetype/config/ftheader.h (FT_STROKER_H): New macro. + + + * src/truetype/ttgload.c (TT_Load_Composite_Glyph), + src/base/ftoutln.c (FT_Vector_Transform): Fixed Werner's latest fix. + FT_Vector_Transform wasn't buggy, the TrueType composite loader was. + +2002-06-24 Werner Lemberg + + * include/freetype/freetype.h (FREETYPE_PATCH): Set to 3. + +2002-06-21 David Turner + + + * Version 2.1.2 released. + ========================= + + +2002-06-21 Roberto Alameda . + + * include/freetype/internal/t42types.h (T42_Font): Removed since + it is already in t42objs.h. + (T42_Face): Use T1_FontRec. + + * src/base/fttype1.c (FT_Get_PS_Font_Info): Updated. + (FT_Has_PS_Glyph_Names): Check for type42 driver name also. + * src/type42/t42objs.h: Include FT_INTERNAL_TYPE42_TYPES_H. + (T42_Face): Removed since it is already in t42types.h. + +2002-06-21 Detlef Würkner + + * src/pfrgload.c (pfr_glyph_load_compound): Fix loading of composite + glyphs. + +2002-06-21 Sven Neumann + + * src/prf/pfrtypes.h (PFR_KernPair): New structure. + (PFR_PhyFont): Use it. + (PFR_KernFlags): New enumeration. + * src/pfr/pfrload.c (pfr_extra_item_load_kerning_pairs): New + function. + (pfr_phy_font_extra_items): Use it. + (pfr_phy_font_done): Updated. + * src/pfr/pfrobjs.c (pfr_face_init): Set kerning flag conditionally. + (pfr_face_get_kerning): New function. + * src/pfr/pfrobjs.h: Updated. + * src/pfr/pfrdrivr.c (pfr_driver_class): Updated. + +2002-06-21 David Turner + + * README, docs/CHANGES: Preparing the 2.1.2 release. + +2002-06-19 Detlef Würkner + + * src/base/fttype1.c: Include FT_INTERNAL_TYPE42_TYPES_H. + (t1_face_check_cast): Removed. + (FT_Get_PS_Font_Info): Make it work with CID and Type 42 drivers + also. + +2002-06-19 Sebastien BARRE + + * src/type42/t42parse.c (t42_parse_sfnts): Fix compiler warning. + +2002-06-19 Werner Lemberg + + * src/base/ftoutln.c (FT_Vector_Transform): Fix serious typo + (xy <-> yx). + * src/truetype/ttgload.c (load_truetype_glyph): Replace `|' with + `||' to make code easier to read. + +2002-06-18 Roberto Alameda . + + * src/type42/t42objs.c (t42_check_size_change): Removed. + (T42_Size_SetChars, T42_Size_SetPixels): Use FT_Activate_Size + instead. + (T42_GlyphSlot_Load): Remove call to t42_check_size_change. + +2002-06-18 Detlef Würkner + + * src/psaux/t1cmap.c (t1_cmap_custom_char_index, + t1_cmap_custom_char_next): Fix index computation -- indices start + with 0 and not with cmap->first. + + Provide default charmaps. + + * src/bdf/bdfdrivr.c (BDF_Face_Init), src/pcf/pcfdriver.c + (PCF_Face_Init), src/pfr/pfrobjs.c (pfr_face_init), + src/type1/t1objs (T1_Face_Init), src/winfonts/winfnt.c + (FNT_Face_Init): Implement it. + +2002-06-17 Sven Neumann + + * src/pfr/pfrobjs.c (pfr_face_init): Fix typo. + +2002-06-16 Leonard Rosenthol + + Updated Win32/VC++ projects to include the new PFR driver. + + * builds/win32/visualc/freetype.dsp: Updated. + +2002-06-16 Anthony Fok + + Install freetype2.m4. + + * builds/unix/install.mk (install, uninstall): Handle it. + +2002-06-16 Detlef Würkner + + Same fix for PFR driver. + + * src/pfr/pfrcmap.c (pfr_cmap_char_index, pfr_cmap_char_next): + Increase return value by 1. + * src/pfr/pfrobjs.c (pfr_slot_load): Decrease index by 1. + +2002-06-15 Detlef Würkner + + Fix glyph indices to make index zero always the undefined glyph. + + * src/bdf/bdfdrivr.c (bdf_cmap_init): Don't decrease + cmap->num_encodings. + (bdf_cmap_char_index, bdf_cmap_char_next, BDF_Get_Char_Index): + Increase result by 1 for normal cases. + (BDF_Glyph_Load): Decrease index by 1. + + * src/pcf/pcfdriver.c (pcf_cmap_char_index, pcf_cmap_char_next, + PCF_Char_Get_Index): Increase result by 1 for normal cases. + (PCF_Glyph_Load): Decrease index by 1. + * src/pcf/pcfread.c (pcf_get_encodings): Don't decrease j for + allocating `encoding'. + + * src/base/ftobjs.c (FT_Load_Glyph, FT_Get_Glyph_Name): Fix + bounding tests. + +2002-06-14 Detlef Würkner + + Add new cmap support to BDF driver. + + * src/bdf/bdfdrivr.c (BDF_CMapRec) [FT_CONFIG_OPTION_USE_CMAPS]: + New structure. + (bdf_cmap_init, bdf_cmap_done, bdf_cmap_char_index, + bdf_cmap_char_next) [FT_CONFIG_OPTION_USE_CMAPS]: New functions. + (BDF_Get_Char_Index) [!FT_CONFIG_OPTION_USE_CMAPS]: Use only + conditionally. + (BDF_Face_Init): Handle `AVERAGE_WIDTH' and `POINT_SIZE' keywords. + Implement new cmap handling. + (bdf_driver_class): Updated. + +2002-06-14 Werner Lemberg + + * Makefile, configure, */*.mk, builds/unix/unix-def.in, + docs/CHANGES, docs/INSTALL: s/TOP/TOP_DIR/. + +2002-06-12 Werner Lemberg + + * src/bdf/bdflib.c: s/FT_Short/short/ for consistency. + +2002-06-11 David Turner + + * builds/win32/ftdebug.c: Added a missing #endif. + + * src/sfnt/ttload.c, src/bdf/bdflib.c: Removing compiler warnings. + + Removed the bug in Type 42 driver that prevented un-hinted outlines + to be loaded. + + * src/type42/t42objs.c (T42_Face_Init): Call FT_Done_Size. + (T42_Size_Init): Call FT_Activate_Size. + (t42_check_size_change): New function. + (T42_Size_SetChars, T42_Size_SetPixels): Use it. + (ft_glyphslot_clear): Replace FT_MEM_SET with FT_ZERO. + (T42_GlyphSlot_Load): Use t42_check_size_change. + Initialize more fields of `glyph'. + + * builds/win32/visualc/freetype.dsp: Updated. + +2002-06-09 David Turner + + + * Version 2.1.1 released. + ========================= + + +2002-06-08 Juliusz Chroboczek + + * include/freetype/internal/ftobjs.h, src/autohint/ahglyph.c, + src/base/ftobjs.c, src/sfnt/ttcmap0.c, src/smooth/ftgrays.c: Don't + use `setjmp', `longjmp', and `jmp_buf' but `ft_setjmp', `ft_longjmp', + and `ft_jmp_buf'. + Removed direct references to and when + appropriate, to eventually replace them with a + FT_CONFIG_STANDARD_LIBRARY_H. Useful for the XFree86 Font Server + backend based on FT2. + + * src/base/fttype1.c (FT_Has_PS_Glyph_Names): Fix return value. + +2002-06-08 David Turner + + * src/pcf/pcfdriver.c (pcf_cmap_char_next): Fixed a bug that caused + the function to return invalid values. + + * src/cache/ftccache.i: Removing a typo that prevented + the source's compilation. + + * src/cache/ftccache.c (ftc_node_hash_unlink): Fixed a + bug that caused nasty memory overwrites. The hash table's + buckets array wasn't correctly resized when shrinked. + +2002-06-08 Detlef Würkner + + * builds/amiga/smakefile, builds/amiga/makefile: Updated. + +2002-06-08 Werner Lemberg + + * src/cache/ftccache.c (ftc_node_hash_unlink, ftc_node_hash_link) + [FTC_CACHE_USE_LINEAR_HASHING]: Fix returned error code. + Fix debugging messages. + * src/cache/ftccache.i (GEN_CACHE_LOOKUP): Move declaration of + `family' and `hash' up to make it compilable with g++. + + * src/type42/t42error.h: New file. + * src/type42/t42drivr.c, src/type42/t42objs.c, + src/type42/t42parse.c: Use t42 error codes. + * src/type42/rules.mk: Updated. + + * src/base/ftnames.c: Include FT_INTERNAL_STREAM_H. + +2002-06-08 David Turner + + * src/cache/ftccmap.c: GEN_CACHE_FAMILY_COMPARE, + GEN_CACHE_NODE_COMPARE, GEN_CACHE_LOOKUP) [FTC_CACHE_USE_INLINE]: + New macros. + (ftc_cmap_cache_lookup) [!FTC_CACHE_USE_INLINE]: Typedef to + ftc_cache_lookup. + (FTC_CMapCache_Lookup): Updated. + + Adding various experimental optimizations to the cache manager. + + * include/freetype/cache/ftccache.h (FTC_CACHE_USE_INLINE, + FTC_CACHE_USE_LINEAR_HASHING): New options. + (FTC_CacheRec) [FTC_CACHE_USE_LINEAR_HASHING]: New elements `p', + `mask', and `slack'. + + * src/cache/ftccache.c (FTC_HASH_MAX_LOAD, FTC_HASH_MIN_LOAD, + FTC_HASH_SUB_LOAD) [FTC_CACHE_USE_LINEAR_HASHING, + FTC_HASH_INITIAL_SIZE]: New macros. + (ftc_node_mru_link, ftc_node_mru_up): Optimized. + (ftc_node_hash_unlink, ftc_node_hash_link) + [FTC_CACHE_USE_LINEAR_HASHING]: New variants. + (FTC_PRIMES_MIN, FTC_PRIMES_MAX, ftc_primes, ftc_prime_closest, + FTC_CACHE_RESIZE_TEST, ftc_cache_resize) + [!FTC_CACHE_USE_LINEAR_HASHING]: Define it conditionally. + (ftc_cache_init, ftc_cache_clear) [FTC_CACHE_USE_LINEAR_HASHING]: + Updated. + (ftc_cache_lookup) [FTC_CACHE_USE_LINEAR_HASHING]: Implement it. + + * src/cache/ftccache.i: New file. + + * src/cache/ftcsbits.c (GEN_CACHE_FAMILY_COMPARE, + GEN_CACHE_NODE_COMPARE, GEN_CACHE_LOOKUP) [FTC_CACHE_USE_INLINE]: + New macros. + (ftc_sbit_cache_lookup) [!FTC_CACHE_USE_INLINE]: Typedef to + ftc_cache_lookup. + (FTC_SBitCache_Lookup): Updated. + + * src/type42/t42parse.c: Removing duplicate function. + +2002-06-07 Graham Asher + + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Changed definition + from FT_EXPORT_DEF to FT_BASE_DEF. + +2002-06-07 David Turner + + Fixed the bug that prevented the correct display of fonts with + "ftview". + + * src/type42/t42drivr.c: Split into... + * src/type42/t42drivr.h, src/type42/t42parse.c, + src/type42/t42parse.h, src/type42/t42objs.h, src/type42/t42objs.c, + src/type42/type42.c: New files. + + (t42_get_glyph_name, t42_get_ps_name, t42_get_name_index): Use + `face->type1'. + + (Get_Interface): Renamed to... + (T42_Get_Interface): This. + Updated. + (T42_Open_Face, T42_Face_Done): Updated. + (T42_Face_Init): Add new cmap support. + Updated. + (T42_Driver_Init, T42_Driver_Done, T42_Size_Init, T42_Size_Done, + T42_GlyphSlot_Init, T42_GlyphSlot_Done): Updated. + (Get_Char_Index, Get_Next_Char): Renamed to... + (T42_CMap_CharIndex, T42_CMap_CharNext): This. + Updated. + (T42_Char_Size, T42_Pixel_Size): Renamed to... + (T42_Size_SetChars, T42_Size_SetPixels): This. + (T42_Load_Glyph): Renamed to... + (T42_GlyphSlot_Load): This. + + (t42_init_loader, t42_done_loader): Renamed to... + (t42_loader_init, t42_loader_done): This. + (T42_New_Parser, T42_Finalize_Parser): Renamed to... + (t42_parser_init, t42_parser_done): This. + (parse_dict): Renamed to... + (t42_parse_dict): This. + (is_alpha, is_space, hexval): Renamed to... + (t42_is_alpha, t42_is_space, t42_hexval): This. + (parse_font_name, parse_font_bbox, parse_font_matrix, + parse_encoding, parse_sfnts, parse_charstrings, parse_dict): + Renamed to... + (t42_parse_font_name, t42_parse_font_bbox, t42_parse_font_matrix, + t42_parse_encoding, t42_parse_sfnts, t42_parse_charstrings, + t42_parse_dict): This. + Updated. + + (t42_keywords): Updated. + + * src/type42/Jamfile, src/type42/descrip.mms: Updated. + +2002-06-03 Werner Lemberg + + Add 8bpp support to BDF driver. + + * src/bdf/bdflib.c (_bdf_parse_start): Handle 8bpp. + * src/bdf/bdfdrivr.c (BDF_Glyph_Load): Ditto. + * src/bdf/README: Updated. + +2002-06-02 Detlef Würkner + + * src/pfr/pfrload.c (pfr_phy_font_done): Free `blue_values' array. + +2002-05-29 Detlef Würkner + + * src/bdf/bdflib.c (_bdf_readstream): Allocate `buf' dynamically. + (_bdf_parse_glyphs): Use correct size for allocating + `font->unencoded'. + (bdf_load_font): Free array conditionally. + Return proper error code in case of failure. + * src/bdf/bdfdrivr.c (BDF_Face_Init): Make it more robust against + unusual fonts. + +2002-05-29 Werner Lemberg + + * src/bdf/descrip.mms, src/type42/descrip.mms: New files. + * descrip.mms (all): Updated. + + * src/bdf/bdflib.c (_bdf_parse_glyphs): Fix typo which prevented + compilation. + * src/pshglob.c (psh_blues_scale_zones): Fix compiler warning. + +2002-05-28 Detlef Würkner + + * builds/amiga/makefile, builds/amiga/smakefile, + amiga/include/freetype/config/ftmodule.h: Updated to include + support for BDF and Type42 drivers. + + * docs/modules.txt: Updated. + +2005-05-28 David Turner + + * docs/CHANGES: Updating file for next release (2.1.1). + + * src/bdf/bdflib.c: Removing compiler warnings. + + * include/freetype/ftxf86.h, src/base/ftxf86.c: New files. + They provide a new API (FT_Get_X11_Font_Format) to retrieve an + X11-compatible string describing the font format of a given face. + This was put in a new optional base source file, corresponding to a + new public header (named FT_XFREE86_H since this function should + only be used within the XFree86 font server IMO). + + * include/freetype/config/ftheader.h (FT_XFREE86_H): New macro (not + documented yet). + + * src/base/fttype1.c: New file, provoding two new API functions + (FT_Get_PS_Font_Info and FT_Has_PS_Glyph_Names). + * include/freetype/t1tables.h: Updated. + + * src/base/Jamfile, src/base/rules.mk, src/base/descrip.mms: + Updating build control files for the new files "ftxf86.c" and + "fttype1.c" in src/base. + + * src/pshinter/pshglob.c (psh_blues_scale_zones): Fixed a bug that + prevented family blue zones substitution from hapenning correctly. + + * include/freetype/ftbdf.h FT_Get_BDF_Charset_ID): Adding + documentation comment. + +2002-05-28 Werner Lemberg + + * src/base/ftnames.c (FT_Get_Sfnt_Name): Don't use FT_STREAM_READ_AT + but FT_STREAM_READ. + Declare `stream' variable. + + * src/bdf/bdflib.c (_bdf_parse_glyphs): Replace floating point math + with calls to `FT_MulDiv'. + +2002-05-28 David Turner + + Fixing the SFNT name table loader to support various buggy fonts. + It now ignores empty name entries, entries with invalid pointer + Offsets and certain fonts containing tables with broken + "storageOffset" fields. + + Name strings are now loaded on demand, which reduces the memory + requirements for a given FT_Face tremendously (for example, the name + table of Arial.ttf is about 10Kb and contains 70 names). + + This is a temporary fix. The whole name table loader and interface + will be rewritten in a much more cleanly way shortly, once CSEH have + been introduced in the sources. + + * include/freetype/internal/tttypes.h (TT_NameEntryRec): Change + type of `stringOffset' to FT_ULong. + (TT_NameTableRec): Change type of `numNameRecords' and + `storageOffset' to FT_UInt. + Replace `storage' with `stream'. + * src/base/ftnames.c (FT_Get_Sfnt_Name): Load name on demand. + * src/sfnt/sfdriver.c (get_sfnt_postscript_name): Ditto. + Make code more robust. + * src/sfnt/sfobjs.c (TT_NameEntry_ConvertFunc): New typedef. + (tt_face_get_name): Use it. + Make code more robust. + * src/sfnt/ttload.c (TT_Load_Names): Use `static' for arrays. + Handle invalid `storageOffset' data better. + Set length fields to zero for invalid or ignored data. + Remove code within FT_DEBUG_LEVEL_TRACE. + (TT_Free_Names): Updated. + +2002-05-24 Tim Mooney + + * builds/unix/ft-munmap.m4: New file, extracted FT_MUNMAP_DECL and + FT_MUNMAP_PARAM from aclocal.m4 into here, so aclocal.m4 can be + rebuilt from sources. Set macro serial to 1, and use third argument + to AC_DEFINE for our two custom symbols, so ftconfig.in could one day + be rebuilt with autoheader (not recommended now, ftconfig.in is a + custom source file) + +2002-05-22 Werner Lemberg + + * include/freetype/config/ftheader.h (FT_BEZIER_H): Removed. + (FT_BDF_H): New macro for accessing `ftbdf.h'. + + * src/type42/t42drivr.c (hexval): Fix typo. + +2002-05-21 Martin Muskens + + * src/psaux/psobjs.c (T1Radix): New function. + (t1_toint): Use it to handle numbers in radix format. + + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Add dummy + for undocumented, obsolete opcode 15. + +2002-05-21 David Turner + + * src/bdf/bdflib.c: Removed compiler warning, and changed all tables + to the "static const" storage specifier (instead of simply + `static'). + + * src/type42/t42drivr.c (hexval): Use more efficient code. + Removing compiler warnings. + * src/bdf/bdfdrivr.c: Removing compiler warnings. + + * include/freetype/internal/ftbdf.h, src/base/ftbdf.c, + src/base/descrip.mms, src/base/Jamfile, src/base/rules.mk + (FT_Get_BDF_Charset_ID): New API to retrieve BDF-specific strings + from a face. This is much cleaner than accessing the internal types + "BDF_Public_Face" defined in FT_INTERNAL_BDF_TYPES_H. + +2002-05-21 Werner Lemberg + + * src/bdf/README: Mention Microsoft's SBIT tool. + + * src/cff/cffdrivr.c, src/cid/cidriver.c, src/pcf/pcfdriver.c, + src/truetype/ttdriver.c, src/type1/t1driver.c, + src/winfonts/winfnt.c, src/type42/t42drivr.c, src/bdf/bdfdrivr.c + [FT_CONFIG_OPTION_DYNAMIC_DRIVERS]: Completely removed. It has + been never used. + +2002-05-21 Roberto Alameda . + + * src/type42/t42drivr.c: s/T42_ENCODING_TYPE_/T1_ENCODING_TYPE_/. + (parse_font_matrix): Remove unnecessary code. + (parse_sfnts): Initialize some variables. + (t42_driver_class) [TT_CONFIG_OPTION_BYTECODE_INTERPRETER]: Use + ft_module_driver_has_hinter conditionally. + Moved some type 42 specific structure definitions to... + * include/freetype/internal/t42types.h: New file. + * include/freetype/internal/internal.h (FT_INTERNAL_T42_TYPES_H): + New macro. + +2002-05-20 Werner Lemberg + + * include/freetype/cache/ftcsbits.h (FTC_SBit): Added a new field + `num_grays' for specifying the number of used gray levels. + * src/cache/ftcsbits.c (ftc_sbit_node_load): Initialize it. + +2002-05-19 Werner Lemberg + + Adding a driver for BDF fonts written by Francesco Zappa Nardelli + . Heavily modified by me to + better adapt it to FreeType, removing unneeded stuff. Additionally, + it now supports Mark Leisher's BDF extension for anti-aliased + bitmap glyphs with 2 and 4 bpp. + + * src/bdf/*: New driver. + * include/freetype/internal/bdftypes.h: New file. + * include/freetype/internal/fttrace.h: Added BDF driver components. + * include/freetype/fterrdef.h: Added error codes for BDF driver. + * include/freetype/config/ftmodule.h, src/Jamfile: Updated. + * include/freetype/internal/internal.h (FT_INTERNAL_BDF_TYPES_H): + New macro. + + * include/freetype/config/ftstdlib.h (ft_sprintf): New alias for + sprintf. + +2002-05-18 Werner Lemberg + + * include/freetype/internal/fttrace.h: Added Type 42 driver + component. + * src/type42/t42drivr.c: Use it. + + * include/freetype/internal/internal.h (FT_INTERNAL_PCF_TYPES_H): + New macro. + +2002-05-17 Werner Lemberg + + * src/type42/Jamfile: New file. + +2002-05-14 Werner Lemberg + + Adding a driver for Type42 fonts written by Roberto Alameda + . + + * src/type42/*: New driver. + * include/freetype/config/ftmodule.h, src/Jamfile: Updated. + * include/freetype/config/ftstdlib.h (ft_xdigit, ft_memcmp, + ft_atoi): New aliases for xdigit, memcmp, and atoi, respectively. + +2002-05-12 Owen Taylor + + * src/sfnt/ttload.c (TT_LookUp_Table): Protect against tables + with a zero length value. + +2002-05-12 Michael Pfeiffer + + * builds/beos/beos.mk: Include `link-std.mk'. + +2002-05-12 Werner Lemberg + + * src/type1/t1load.h (T1_Loader): Renamed to... + (T1_LoaderRec): This. + (T1_Loader): Now pointer to T1_LoaderRec. + * src/type1/t1load.c: Updated. + + * include/freetype/internal/t1types.h, src/type1/t1load.c, + src/type1/t1objs.c: + s/T1_ENCODING_TYPE_EXPORT/T1_ENCODING_TYPE_EXPERT/. + +2002-05-06 Werner Lemberg + + * README: Add a note regarding libttf vs. libfreetype. + +2002-05-05 Werner Lemberg + + FreeType 2 can now be built in an external directory with the + configure script also. + + * builds/freetype.mk (INCLUDES): Add `OBJ_DIR'. + + * builds/unix/detect.mk (have_mk): New variable to test for + external build. + (unix-def.mk): Defined according to value of `have_mk'. + * builds/unix/unix.mk (have_mk): New variable to test for + external build. + Select include paths for unix-def.mk and unix-cc.mk according + to value of `have_mk'. + * builds/unix/unix-def.in (OBJ_BUILD): New variable. + (DISTCLEAN): Use it. + * builds/unix/unix-cc.in (LIBTOOL): Define default value only + if not yet defined. + * builds/unix/install.mk (install): Use `OBJ_BUILD' for installing + freetype-config. + + * configure: Don't depend on bash features. + (ft2_dir, abs_curr_dir, abs_ft2_dir): New variables (code + partially taken from Autoconf). + Build a dummy Makefile if not building in source tree. + + * docs/INSTALL: Document it. + +2002-05-04 David Turner + + * src/truetype/ttgload.c (TT_Load_Glyph): Finally fixing the last + bug that prevented FreeType 2.x and FreeType 1.x to produce + bit-by-bit identical monochrome glyph bitmaps with native TrueType + hinting. The culprit was a single-bit flag that wasn't set + correctly by the TrueType glyph loader. + + * src/otlayout/otlayout.h, src/otlayout/otlbase.c, + src/otlayout/otlbase.h, src/otlayout/otlconf.h, + src/otlayout/otlgdef.c, src/otlayout/otlgdef.h, + src/otlayout/otlgpos.c, src/otlayout/otlgpos.h, + src/otlayout/otlgsub.c, src/otlayout/otlgsub.h, + src/otlayout/otljstf.c, src/otlayout/otljstf.h, + src/otlayout/otltable.c, src/otlayout/otltable.h, + src/otlayout/otltags.h: New OpenType Layout source files. The + module is still incomplete. + +2002-05-02 Werner Lemberg + + * src/sfnt/ttcmap0.c (tt_cmap4_char_index): Fix serious typo + (0xFFFU -> 0xFFFFU). + +2002-05-01 Werner Lemberg + + * docs/INSTALL: Fix URL of makepp. + +2002-05-01 David Turner + + * src/sfnt/sfobjs.c (tt_face_get_name): Fixing a bug that caused + FreeType to crash when certain broken fonts (e.g. "hya6gb.ttf") + were opened. + + * src/sfnt/ttload.c (TT_Load_Names): Applied a small work-around to + manage fonts containing a broken name table (e.g. "hya6gb.ttf"). + + * src/sfnt/ttcmap0.c (tt_cmap4_validate): Fixed over-restrictive + validation test. The charmap validator now accepts overlapping + ranges in format 4 charmaps. + + * src/sfnt/ttcmap0.c (tt_cmap4_char_index): Switched to a binary + search algorithm. Certain fonts contain more than 170 distinct + segments! + + * include/freetype/config/ftstdlib.h: Adding an alias for the `exit' + function. This will be used in the near future to panic in case of + unexpected exception (which shouldn't happen in theory). + + * include/freetype/internal/fthash.h, src/base/fthash.c: New files. + This is generic implementation of dynamic hash tables using a linear + algorithm (to get rid of `stalls' during resizes). In the future + this will be used in at least three parts of the library: the cache + sub-system, the object sub-system, and the memory debugger. + + * src/base/Jamfile: Updated. + + * include/freetype/internal/internal.h (FT_INTERNAL_HASH_H, + FT_INTERNAL_OBJECT_H): New macros. + + * include/freetype/internal/ftcore.h: New file to group all new + definitions related to exception handling and memory management. It + is very likely that this file will disappear or be renamed in the + future. + + * include/freetype/internal/ftobject.h, include/freetype/ftsysmem.h: + Adding comments to better explain the object sub-system as well as + the new memory manager interface. + +2002-04-30 Wenlin Institute (Tom Bishop) + + * src/base/ftmac.c (p2c_str): Removed. + (file_spec_from_path) [TARGET_API_MAC_CARBON]: Added support for + OS X. + (is_dfont) [TARGET_API_MAC_CARBON]: Define only for OS X. + Handle `nameLen' <= 6 also. + (parse_fond): Remove unused variable `name_table'. + Use functionality of old p2c_str directly. + Add safety checks. + (read_lwfn): Initialize `size_p'. + Check for size_p == NULL. + (new_memory_stream, open_face_from_buffer): Updated to FreeType 2.1. + (FT_New_Face_From_LWFN): Remove unused variable `memory'. + Remove some dead code. + (FT_New_Face_From_SFNT): Remove unused variable `stream'. + (FT_New_Face_From_dfont) [TARGET_API_MAC_CARBON]: Define only for + OS X. + (FT_New_Face_From_FOND): Remove unused variable `error'. + (ResourceForkSize): New function. + (FT_New_Face): Use it. + Handle empty resource forks. + Conditionalize some code for OS X. + Add code to call normal loader as a fallback. + +2002-04-30 Werner Lemberg + + `interface' is reserved on the Mac. + + * include/freetype/ftoutln.h, include/freetype/internal/sfnt.h, + src/base/ftoutln.c: s/interface/func_interface/. + * src/base/ftbbox.c (FT_Outline_Get_BBox): + s/interface/bbox_interface/. + * src/cff/cffdrivr.c: s/interface/module_interface/. + * src/cff/cffload.c, src/cff/cffload.h: + s/interface/psnames_interface/. + * src/cid/cidriver.c: s/interface/cid_interface/. + * src/sfnt/sfdriver.c: s/interface/module_interface/. + * src/smooth/ftgrays.c: s/interface/func_interface/. + * src/truetype/ttdriver.c: s/interface/tt_interface/. + * src/type1/t1driver.c: s/interface/t1_interface/. + + Some more variable renames to avoid troubles on the Mac. + + * src/raster/ftraster.c: + s/Unknown|Ascending|Descending|Flat/\1_State/. + * src/smooth/ftgrays.c: s/TScan/TCoord/. + + Other changes for the Mac. + + * include/freetype/config/ftconfig.h: Define FT_MACINTOSH for + Mac platforms. + * src/base/ftobjs.c: s/macintosh/FT_MACINTOSH/. + + * src/raster/ftrend1.c (ft_raster1_render): Make `pitch' always + an even number. + +2002-04-29 Jouk Jansen + + * descrip.mms (all): Add pfr driver. + +2002-04-28 Werner Lemberg + + * src/pfr/pfrerror.h: New file. + * include/freetype/ftmoderr.h: Add PFR error codes. + * src/pfr/pfrgload.c: Include pfrerror.h. + Use PCF error codes. + (pfr_extra_item_load_stem_snaps): Fix debug message. + * src/pfr/pfrgload.c: Include pfrerror.h. + Use PCF error codes. + (pfr_extra_item_load_bitmap_info, pfr_glyph_load_simple, + pfr_glyph_load_compound): Fix debug message. + * src/pfr/pfrobjs.c: Include pfrerror.h. + Use PCF error codes. + (pfr_face_init): Return PFR_Err_Unknown_File_Format. + * src/pfr/rules.mk (PFR_DRV_H): Include pfrerror.h. + + * src/pcf/pcfdriver.c (PCF_Face_Init) [!FT_CONFIG_OPTION_USE_CMAPS]: + `root' -> `face->root'. + * src/sfnt/ttcmap0.c (TT_Build_CMaps) [!FT_CONFIG_OPTION_USE_CMAPS]: + Removed. + * src/sfnt/ttcmap0.c: Declare TT_Build_CMaps only for + FT_CONFIG_OPTION_USE_CMAPS. + +2002-04-27 Werner Lemberg + + * src/cache/ftccache.c (ftc_cache_lookup), + src/cache/ftccmap.c (ftc_cmap_family_init), + src/cache/ftcmanag.c (ftc_family_table_alloc), + src/cache/ftcsbits.c (FTC_SBit_Cache_Lookup): Use FTC_Err_*. + src/cache/ftcimage.c (FTC_Image_Cache_Lookup): Use FTC_Err_*. + (FTC_ImageCache_Lookup): Fix handling of invalid arguments. + +2002-04-22 Werner Lemberg + + * builds/unix/configure.ac: Set `version_info' to 9:1:3 (FT2 + version 2.0.9 has 9:0:3). + * builds/unix/configure: Regenerated (using autoconf 2.53). + +2002-04-19 Werner Lemberg + + * src/pfr/pfrload.c (pfr_extra_items_farse): Fix debug message. + (pfr_phy_font_load): s/size/Size/ for local variable to avoid + compiler warning. + * src/pfr/pfrobjs.c (pfr_face_init): Fix debug message. + (pfr_slot_load): Remove redundant local variable. + +2002-04-19 David Turner + + Adding a PFR font driver to the FreeType sources. Note that it + doesn't support embedded bitmaps or kerning tables yet. + + src/pfr/*: New files. + + * include/freetype/config/ftmodule.h, + include/freetype/internal/fttrace.h, src/Jamefile: Updated. + + * src/type1/t1gload.h (T1_Load_Glyph), src/type1/t1gload.c + (T1_Load_Glyph): Fixed incorrect parameter sign-ness in callback + function. + + * include/freetype/internal/ftmemory.h (FT_MEM_ZERO, FT_ZERO): New + macros. + + * include/freetype/internal/ftstream.h (FT_NEXT_OFF3, FT_NEXT_UOFF3, + FT_NEXT_OFF3_LE, FT_NEXT_UOFF3_LE): New macros to parse in-memory + 24-bit integers. + +2002-04-18 David Turner + + * src/base/ftobjs.c, builds/win32/ftdebug.c, + builds/amiga/src/base/ftdebug.c: Version 2.1.0 couldn't be linked + against applications in Win32 and Amiga builds due to changes to + "src/base/ftdebug.c" that were not properly propagated to + "builds/win32" and "builds/amiga". This has been fixed. + + * include/freetype/internal/ftobject.h, + include/freetype/internal/ftexcept.h, include/freetype/ftsysmem.h, + include/freetype/ftsysio.h, src/base/ftsysmem.c, src/base/ftsysio.c: + New experimental files. + +2002-04-17 David Turner + + + * Version 2.1.0 released. + ========================= + + +2002-04-17 Michael Jansson + + * src/type1/t1gload.c (T1_Compute_Max_Advance): Fixed a small bug + that prevented the function to return the correct value. + +2002-04-16 Francesco Zappa Nardelli + + * src/pcf/pcfread (pcf_get_accell): Fix parsing of accelerator + tables. + +2002-04-15 David Turner + + * docs/FTL.txt: Formatting. + + * include/freetype/config/ftoption.h: Reduce the size of the + render pool from 32kByte to 16kByte. + + * src/pcf/pcfread.c (pcf_seek_to_table_type): Remove compiler + warning. + + * include/freetype/config/ftoption.h (FT_MAX_EXTENSIONS): Removed. + + * docs/CHANGES: Preparing 2.1.0 release. + +2002-04-13 Werner LEMBERG + + * src/cff/cffgload.c (CFF_Parse_CharStrings): s/rand/Rand/ to avoid + compiler warning. + +2002-04-12 David Turner + + * README.UNX: Updated the Unix-specific quick-compilation guide to + warn about the GNU Make requirement at compile time. + + * include/freetype/config/ftstdlib.h, + include/freetype/config/ftconfig.h, + include/freetype/config/ftheader.h, + include/freetype/internal/ftmemory.h, + include/freetype/internal/ftobjs.h, + + src/autohint/ahoptim.c, + + src/base/ftdbgmem.c, src/base/ftdebug.c, src/base/ftmac.c, + src/base/ftobjs.c, src/base/ftsystem.c, + + src/cache/ftcimage.c, src/cache/ftcsbits.c, + + src/cff/cffdriver.c, src/cff/cffload.c, src/cff/cffobjs.c, + + src/cid/cidload.c, src/cid/cidparse.c, src/cid/cidriver.c, + + src/pcf/pcfdriver.c, src/pcf/pcfread.c, + + src/psaux/t1cmap.c, src/psaux/t1decode.c, + + src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.c, + src/pshinter/pshrec.c, + + src/psnames/psmodule.c, + + src/raster/ftraster.c, + + src/sfnt/sfdriver.c, src/sfnt/ttload.c, + + src/smooth/ftgrays.c, + + src/type1/t1afm.c, src/type1/t1driver.c, src/type1/t1gload.c, + src/type1/t1load.c, src/type1/t1objs.c, src/type1/t1parse.c, + + builds/unix/ftconfig.in, builds/vms/ftconfig.h, + + builds/amiga/src/base/ftdebug.c: + + Added the new configuration file "ftstdlib.h" used to define + aliases for all ISO C library functions used by the engine + (e.g. strlen, qsort, setjmp, etc.). + + This eases the porting of FreeType 2 to environments like + XFree86 modules/extensions. + + Also removed many #include , #include , etc. + from the engine's sources where they are not needed. + + * src/sfnt/ttpost.c: Use macro name for psnames.h. + +2002-04-12 Vincent Caron + + * configure, builds/detect.mk: Updated the build system to print + a warning message in case GNU Make isn't used to build the library. + +2002-04-11 David Turner + + * README, docs/CHANGES, Jamfile.in: Updates for the 2.1.0 release. + + * docs/FTL.txt: Updated license text to provide a preferred + disclaimer and adjust copyright dates/extents. + + * include/freetype/cache/ftcglyph.h: Removing obsolete (and + confusing) comment. + + * Jamfile.in: New file. + +2002-04-11 Maxim Shemanarev + + * src/smooth/ftgrays.c (gray_hline): Minor optimization. + +2002-04-02 Werner Lemberg + + Fixes from the stable branch: + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_OLD_CALCS): + Removed. + [FT_CONFIG_OPTION_OLD_CALCS]: Removed. + * include/freetype/internal/ftcalc.h, src/base/ftcalc.c + [FT_CONFIG_OPTION_OLD_CALCS]: Removed. + + * src/base/fttrigon.c (FT_Vector_Length): Change algorithm to match + output of FreeType 1. + + * src/pshinter/pshglob.c (psh_globals_scale_widths): Fixed a small + bug that created un-even stem widths when hinting Postscript fonts. + + * src/type1/t1driver.c, src/type1/t1parse.c: 16bit fixes. + +2002-04-01 Werner Lemberg + + * src/truetype/ttgload.c: 16bit fixes. + (TT_Load_Simple_Glyph): Improve debug messages. + (load_truetype_glyph): Remove dead code. + * src/truetype/ttinterp.c: 16bit fixes. + * src/truetype/ttobjs.c: Ditto. + + * include/freetype/ftsnames.h, include/freetype/internal/sfnt.h, + src/cff/cffload.h, src/psaux/psobjs.h, src/truetype/ttinterp.[ch], + src/sfnt/ttpost.h: s/index/idx/. + +2002-03-31 Yao Zhang + + * src/truetype/ttobjs.c (TT_Size_Init): Fix typo. + +2002-03-31 Werner Lemberg + + * src/otlayout/otlcommn.c, src/otlayout/otlcommn.h: s/index/idx/. + * src/psaux/t1cmap.c: Ditto. + * src/sfnt/ttcmap0.c: Ditto. + + * include/freetype/internal/tttypes.h, + include/freetype/internal/sfnt.h (TT_Goto_Table_Func): Renamed to ... + (TT_Loader_GotoTableFunc): This. + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Fix debug + messages. + * src/psnames/psmodule.c (psnames_interface) + [!FT_CONFIG_OPTION_ADOBE_GLYPH_LIST]: Fix typo. + * src/sfnt/sfdriver.c (get_sfnt_table): 16bit fix. + * src/sfnt/ttcmap.c: 16bit fixes (0xFFFF -> 0xFFFFU). + * src/sfnt/ttcmap0.c: 16bit fixes. + (TT_Build_CMaps): Simplify debug messages. + (tt_cmap12_char_next): Fix offset. + * src/sfnt/ttload.c (TT_Load_Names, TT_Load_CMap): Fix debug + messages. + (TT_Load_OS2): 16bit fix. + +2002-03-30 David Turner + + * include/freetype/internal/tttypes.h: Adding comments to some of + the TT_FaceRec fields. + + * src/sfnt/ttcmap0.c (TT_Build_CMaps): Removed compiler warnings. + + * src/sfnt/sfobjs.c (tt_name_entry_ascii_from_{utf16,ucs4,other}: + New functions. + (tt_face_get_name): Use them to properly extract an ascii font name. + +2002-03-30 Werner Lemberg + + * include/freetype/t1tables.h (t1_blend_max): Fix typo. + * src/base/ftstream.c: Simplify FT_ERROR calls. + * src/cff/cffdrivr.c (cff_get_glyph_name): Fix debug message. + + * src/cff/cffobjs.c (CFF_Driver_Init, CFF_Driver_Done) + [TT_CONFIG_OPTION_EXTEND_ENGINE]: Removed. + * src/cff/sfobjs.c (SFNT_Load_Face) + [TT_CONFIG_OPTION_EXTEND_ENGINE]: Ditto. + * src/truetype/ttobjs.c (TT_Init_Driver, TT_Done_Driver) + [TT_CONFIG_OPTION_EXTEND_ENGINE]: Ditto. + + * src/truetype/ttdriver.c, src/truetype/ttobjs.c, + src/truetype/ttobjs.h: Renaming driver functions to the + FT__ scheme: + + TT_Init_Driver => TT_Driver_Init + TT_Done_Driver => TT_Driver_Done + TT_Init_Face => TT_Face_Init + TT_Done_Face => TT_Face_Done + TT_Init_Size => TT_Size_Init + TT_Done_Size => TT_Size_Done + TT_Reset_Size => TT_Size_Reset + +2002-03-29 Werner Lemberg + + * builds/vms/ftconfig.h: Rename LOCAL_DEF and LOCAL_FUNC to + FT_LOCAL and FT_LOCAL_DEF, respectively, as with other ftconfig.h + files. + * builds/unix/ftconfig.in: Add argument to FT_LOCAL and + FT_LOCAL_DEF. + * src/truetype/ttinterp.c: s/FT_Assert/FT_ASSERT/. + * builds/unix/configure.ac: Temporarily deactivate creation of + ../../Jamfile. + * builds/unix/configure: Updated. + +2002-03-28 KUSANO Takayuki + + * src/sfnt/sfdriver.c (get_sfnt_postscript_name): Fix serious typos. + +2002-03-28 Werner Lemberg + + * include/freetype/internal/psaux.h (PSAux_ServiceRec): Fix + compiler warnings. + * include/freetype/internal/t1types.h (T1_FaceRec): Use `const' for + some members. + * src/base/ftapi.c (FT_New_Memory_Stream): Fix typos. + * src/psaux/t1cmap.c (t1_cmap_std_init, t1_cmap_unicode_init): Add + cast. + (t1_cmap_{standard,expert,custom,unicode}_class_rec): Use + `FT_CALLBACK_TABLE_DEF'. + * src/psaux/t1cmap.h: Updated. + * src/sfnt/ttcmap0.c (TT_Build_CMaps): Use `ft_encoding_none' + instead of zero. + * src/type1/t1objs.c (T1_Face_Init): Use casts. + +2002-03-26 David Turner + + * src/sfnt/sfdriver.c, src/sfnt/sfobjs.c, src/sfnt/ttcmap0.c: + Fixed a small bug in the FT_CMaps support code. + +2002-03-25 David Turner + + * src/truetype/ttinterp.c (Norm): Replaced with... + (TT_VecLen): This. + (TT_MulFix14, TT_DotFix14): New functions. + (Project, Dual_Project, Free_Project, Compute_Point_Displacement, + Ins_SHPIX, Ins_MIAP, Ins_MIRP): Use them. + [FT_CONFIG_OPTION_OLD_CALCS]: Removed all code. + +2002-03-22 David Turner + + * src/base/ftobjs.c, src/sfnt/ttcmap0.c, src/type1/t1objs.c: + Various fixes to make the FT_CMaps support work correctly (more + tests are still needed). + + * include/freetype/internal/ftobjs.h, src/sfnt/Jamfile, + src/sfnt/rules.mk, src/sfnt/sfnt.c, src/sfnt/sfobjs.c, + src/sfnt/ttload.c, src/sfnt/ttcmap0.c, src/sfnt/ttcmap0.h: Updated + the SFNT charmap support to use FT_CMaps. + + * include/freetype/fterrdef.h: New file. + * include/freetype/fterrors.h: Include it. It contains all error + codes. + * include/freetype/config/ftheader.h (FT_ERROR_DEFINITIONS_H): New + macro. + + * include/freetype/internal/ftmemory.h, and a lot of other files: + Changed the names of memory macros. Examples: + + MEM_Set => FT_MEM_SET + MEM_Copy => FT_MEM_COPY + MEM_Move => FT_MEM_MOVE + + ALLOC => FT_ALLOC + FREE => FT_FREE + REALLOC = >FT_REALLOC + + FT_NEW was introduced to allocate a new object from a _typed_ + pointer. + + Note that ALLOC_ARRAY and REALLOC_ARRAY have been replaced by + FT_NEW_ARRAY and FT_RENEW_ARRAY which take _typed_ pointer + arguments. + + This results in _lots_ of sources being changed, but makes the code + more generic and less error-prone. + + * include/freetype/internal/ftstream.h, src/base/ftstream.c, + src/cff/cffload.c, src/pcf/pcfread.c, src/sfnt/ttcmap.c, + src/sfnt/ttcmap0.c, src/sfnt/ttload.c, src/sfnt/ttpost.c, + src/sfnt/ttsbit.c, src/truetype/ttgload.c, src/truetype/ttpload.c, + src/winfonts/winfnt.c: Changed the definitions of stream macros. + Examples: + + NEXT_Byte => FT_NEXT_BYTE + NEXT_Short => FT_NEXT_SHORT + NEXT_UShortLE => FT_NEXT_USHORT_LE + READ_Short => FT_READ_SHORT + GET_Long => FT_GET_LONG + etc. + + Also introduced the FT_PEEK_XXXX functions. + + * src/cff/cffobjs.c (CFF_Build_Unicode_Charmap): Removed commented + out function. + (find_encoding): Removed. + (CFF_Face_Init): Remove charmap support. + + * include/freetype/config/ftoption.h (FT_CONFIG_OPTION_USE_CMAPS, + TT_CONFIG_CMAP_FORMAT{0,2,4,6,8,10,12}): New macros to fine-tune + support of cmaps. + +2002-03-21 David Turner + + * src/base/ftobjs.c, src/pcf/pcfdriver.c, src/pcf/pcfread.c: Updated + to new FT_CMap definitions. + + * src/psaux/t1cmap.h, src/psaux/t1cmap.c, src/type1/t1cmap.h, + src/type1/t1cmap.c: Updating and moving the Type 1 FT_CMap support + from "src/type1" to "src/psaux" since it is going to be shared by + the Type 1 and CID font drivers. + + * src/psaux/Jamfile, src/psaux/psaux.c, src/psaux/psauxmod.c, + src/psaux/rules.mk, include/freetype/internal/psaux.h: Added support + for Type 1 FT_CMaps. + +2002-03-20 David Turner + + * src/base/ftgloadr.c (FT_GlyphLoader_CheckSubGlyphs): Fixed a + memory allocation bug that was due to un-careful renaming of the + FT_SubGlyph type. + + * src/base/ftdbgmem.c (ft_mem_table_destroy): Fixed a small bug that + caused the library to crash with Electric Fence when memory + debugging is used. + + * Renaming stream macros. Examples: + + FILE_Skip => FT_STREAM_SKIP + FILE_Read => FT_STREAM_READ + ACCESS_Frame => FT_FRAME_ENTER + FORGET_Frame => FT_FRAME_EXIT + etc. + + * src/sfnt/sfdriver.c (get_sfnt_postscript_name): Fixed memory leak. + + * include/freetype/internal/ftobjs.h: Changing the definition of + FT_CMap_CharNextFunc slightly. + + * src/cff/*.c: Updating CFF type definitions. + +2002-03-14 David Turner + + * include/freetype/internal/autohint.h, src/autohint/ahmodule.c, + src/base/ftapi.c, src/base/ftobjs.c: Updating the type definitions + for the auto-hinter module. + + FT_AutoHinter_Interface => FT_AutoHinter_ServiceRec + FT_AutoHinter_Interface* => FT_AutoHinter_Service + etc. + + FT_AutoHinter_Get_Global_Func => FT_AutoHinter_GlobalGetFunc + FT_AutoHinter_Done_Global_Func => FT_AutoHinter_GlobalDoneFunc + etc. + + * ahloader.h [_STANDALONE_]: Removed all conditional code. + + * include/freetype/internal/cfftypes.h, src/cff/*.c: Updating the + type definitions of the CFF font driver. + + CFF_Font => CFF_FontRec + CFF_Font* => CFF_Font + etc. + + * include/freetype/internal/fnttypes.h, src/winfonts/*.c: Updating + type definitions of the Windows FNT font driver. + + * include/freetype/internal/ftdriver.h, + include/freetype/internal/ftobjs.h, src/base/ftapi.c, + src/base/ftobjs.c, src/cff/cffdrivr.c, src/cff/cffdrivr.h, + src/cid/cidriver.c, src/cid/cidriver.h, src/pcf/pcfdriver.c, + src/pcf/pcfdriver.h, src/truetype/ttdriver.c, + src/truetype/ttdriver.h, src/type1/t1driver.c, src/type1/t1driver.h, + src/winfonts/winfnt.c, src/winfonts/winfnt.h: Updating type + definitions for font drivers. + + FTDriver_initFace => FT_Face_InitFunc + FTDriver_initGlyphSlot => FT_Slot_InitFunc + etc. + + * src/cid/cidobjs.c (CID_Face_Init): Remove dead code. + + * include/freetype/internal/ftobjs.h, src/base/ftobjs.c: Updated a + few face method definitions: + + FT_PSName_Requester => FT_Face_GetPostscriptNameFunc + FT_Glyph_Name_Requester => FT_Face_GetGlyphNameFunc + FT_Name_Index_Requester => FT_Face_GetGlyphNameIndexFunc + + * src/base/ftapi.c: New file. It contains backwards compatibility + functions. + + * include/freetype/internal/psaux.h, src/cid/cidload.c, + src/cidtoken.h, src/psaux/psobjs.c, src/psaux/psobjs.h, + src/psaux/t1decode.c, stc/type1/t1load.c, src/type1/t1tokens.h: + Updated common PostScript type definitions. + Renamed all enumeration values like to uppercase variants: + + t1_token_any => T1_TOKEN_TYPE_ANY + t1_field_cid_info => T1_FIELD_LOCATION_CID_INFO + etc. + + * include/freetype/internal/psglobals.h: Removed. + * include/freetype/internal/pshints.h, src/pshinter/pshglob.h: + Updated. + + * include/freetype/internal/tttypes.h, + include/freetype/internal/sfnt.h, src/base/ftnames.c, + src/cff/cffdrivr.c, src/sfnt/*.c, src/truetype/*.c: Updated + SFNT/TrueType type definitions. + + * include/freetype/freetype.h, include/freetype/internal/ftgloadr.h: + Updating type defintiions for the glyph loader. + +2002-03-13 Antoine Leca + + * include/freetype/config/ftoption.h: Changed the automatic + detection of Microsoft C compilers to automatically support 64-bit + integers only since revision 9.00 (i.e. >= Visual C++ 2.0). + +2002-03-08 Werner Lemberg + + * src/base/ftutil.c (FT_Realloc): Use MEM_Set instead of memset. + +2002-03-07 Werner Lemberg + + * src/base/ftdbgmem.c (ft_mem_table_resize, ft_mem_table_new, + ft_mem_table_set, ft_mem_debug_alloc, ft_mem_debug_free, + ft_mem_debug_realloc, ft_mem_debug_done, FT_Alloc_Debug, + FT_Realloc_Debug, FT_Free_Debug): Fix compiler warnings. + * src/base/ftcalc.c (FT_MulFix): Ditto. + * src/cff/cffdrivr.c (cff_get_name_index): Ditto. + * src/cff/cffobjs.c (CFF_Size_Get_Global_Funcs, CFF_Size_Init, + CFF_GlyphSlot_Init): Ditto. + * src/cid/cidobjs.c (CID_GlyphSlot_Init, + CID_Size_Get_Globals_Funcs): Ditto. + * src/type1/t1objs.c (T1_Size_Get_Globals_Funcs, T1_GlyphSlot_Init): + Ditto. + * src/pshinter/pshmod.c (pshinter_interface): Use `static const'. + * src/winfonts/winfnt.c (FNT_Get_Next_Char): Remove unused + variables. + + * include/freetype/internal/psaux.h (T1_Builder_Funcs): Renamed + to... + (T1_Builder_FuncsRec): This. + (T1_Builder_Funcs): New typedef. + (PSAux_Interface): Remove compiler warnings. + * src/psaux/psauxmod.c (t1_builder_funcs), src/psaux/psobjs.h + (t1_builder_funcs): Updated. + + * src/pshinter/pshglob.h (PSH_Blue_Align): Replaced with ... + (PSH_BLUE_ALIGN_{NONE,TOP,BOT}): New defines. + (PSH_AlignmentRec): Updated. + + * include/freetype/internal/ftstream.h (GET_Char, GET_Byte): Fix + typo. + * include/freetype/internal/ftgloadr.h (FT_SubGlyph): Ditto. + * src/base/ftstream (FT_Get_Char): Rename to... + (FT_Stream_Get_Char): This. + + * src/base/ftnames.c (FT_Get_Sfnt_Name): s/index/idx/ -- `index' is + a built-in function in gcc, causing warning messages with gcc 3.0. + * src/autohint/ahglyph.c (ah_outline_load): Ditto. + * src/autohint/ahglobal.c (ah_hinter_compute_blues): Ditto. + * src/cache/ftcmanag.c (ftc_family_table_alloc, + ftc_family_table_free, FTC_Manager_Done, FTC_Manager_Register_Cache): + Ditto. + * src/cff/cffload.c (cff_new_index, cff_done_index, + cff_explicit_index, CFF_Access_Element, CFF_Forget_Element, + CFF_Get_Name, CFF_Get_String, CFF_Load_SubFont, CFF_Load_Font, + CFF_Done_Font): Ditto. + * src/psaux/psobjs.c (PS_Table_Add, PS_Parser_LoadField): Ditto. + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Ditto. + * src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_clear_bit, + ps_mask_set_bit, ps_dimension_add_t1stem, ps_hints_t1stem3, + * src/pshinter/pshalgo1.c (psh1_hint_table_record, + psh1_hint_table_record_mask, psh1_hint_table_activate_mask): Ditto. + * src/pshinter/pshalgo2.c (psh2_hint_table_record, + psh2_hint_table_record_mask, psh2_hint_table_activate_mask): Ditto. + * src/sfnt/ttpost.c (Load_Format_20, Load_Format_25, + TT_Get_PS_Name): Ditto. + * src/truetype/ttgload.c (TT_Get_Metrics, Get_HMetrics, + load_truetype_glyph): Ditto. + * src/type1/t1load.c (parse_subrs, T1_Open_Face): Ditto. + * src/type1/t1afm.c (T1_Get_Kerning): Ditto. + * include/freetype/cache/ftcmanag.h (ftc_family_table_free): Ditto. + +2002-03-06 David Turner + + * src/type1/t1objs.c (T1_Face_Init), src/cid/cidobjs.c + (CID_Face_Init): Fixed another bug related to the + ascender/descender/text height of Postscript fonts. + + * src/pshinter/pshalgo2.c (print_zone): Renamed to ... + (psh2_print_zone): This. + * src/pshinter/pshalgo1.c (print_zone): Renamed to ... + (psh1_print_zone): This. + + * include/freetype/freetype.h, include/freetype/internal/ftobjs.h, + src/base/ftobjs.c: Adding the new FT_Library_Version API to return + the library's current version in dynamic links. + * src/base/ftinit.c (FT_Init_FreeType): Updated. + +2002-03-06 Werner Lemberg + + * src/pshinter/pshglob.h (PSH_DimensionRec): s/std/stdw/. + * src/pshinter/pshglob.c (psh_global_scale_widths, + psh_dimension_snap_width, psh_globals_destroy, psh_globals_new): + Ditto. + +2002-03-05 David Turner + + * src/type1/t1objs.c (T1_Face_Init), src/cff/cffobjs.c + (CFF_Face_Init), src/cid/cidobjs.c (CID_Face_Init): Removing the bug + that returned global BBox values in 16.16 fixed format (instead of + integer font units). + + * src/cid/cidriver.c (cid_get_postscript_name): Fixed a bug that + caused the CID driver to return Postscript font names with a leading + slash ("/") as in "/MOEKai-Regular". + + * src/sfnt/ttload.c (TT_Load_Names), src/sfnt/sfobjs.c (Get_Name), + src/sfnt/sfdriver.c (get_sfnt_postscript_name): Fixed the loader so + that it accepts broken fonts like "foxjump.ttf", which made FreeType + crash when trying to load them. + + Also improved the name table parser to be able to load + Windows-encoded entries before Macintosh or Unicode ones, since it + seems some fonts don't have reliable values here anyway. + + * include/freetype/internal/psnames.h: Add typedef for + `PSNames_Service'. + +2002-03-05 Werner Lemberg + + * builds/unix/aclocal.m4, builds/unix/ltmain.sh: Update to libtool + 1.4.2. + Apply a small patch for AIX to make shared libraries work (this + patch is already in the CVS version of libtool). + + * builds/unix/config.sub, builds/unix/config.guess: Updated to + recent versions. + + * builds/unix/configure.ac: Fix typo + (AC_CONFIG_FILE->AC_CONFIG_FILES). + + * builds/unix/configure: Regenerated. + +2002-02-28 David Turner + + * include/freetype/ftconfig.h: Changed `FT_LOCAL xxxx' to + `FT_LOCAL( xxxx )' everywhere in the source. The same goes for + `FT_LOCAL_DEF xxxx' which is translated to `FT_LOCAL_DEF( xxxxx )'. + + * include/freetype/freetype.h (FREETYPE_MINOR, FREETYPE_PATCH): + Changing version to 2.1.0 to indicate an unstable branch. + Added the declarations of FT_Get_First_Char and FT_Get_Next_Char. + + * src/base/ftobjs.c: Implement FT_Get_First_Char and + FT_Get_Next_Char. + + * include/freetype/t1tables.h: Renaming structure types. This + + typedef T1_Struct_ + { + } T1_Struct; + + becomes + + typedef PS_StructRec_ + { + } PS_StructRec, *PS_Struct; + + typedef PS_StructRec T1_Struct; /* backwards-compatibility */ + + Hence, we increase the coherency of the source code by effectively + using the `Rec' prefix for structure types. + +2002-02-27 David Turner + + * src/sfnt/ttload.c (TT_Load_Names): Simplifying and securing the + names table loader. Invalid individual name entries are now handled + correctly. This allows the loading of very buggy fonts like + "foxjump.ttf" without allocating tons of memory and causing crashes. + + * src/otlayout/otlcommon.h, src/otlayout/otlcommon.c: Adding (still + experimental) code for OpenType Layout tables validation and + parsing. + + * src/type1/t1cmap.h, src/type1/t1cmap.c: Adding (still + experimental) code for Type 1 charmap processing. + + * src/sfnt/ttcmap0.c: New file. It contains a new, still + experimental SFNT charmap processing support. + + * include/freetype/internal/ftobjs.h: Adding validation support as + well as internal charmap object definitions (FT_CMap != FT_CharMap). + +2002-02-24 David Turner + + * Renaming stream functions to the FT__ scheme: + + FT_Seek_Stream => FT_Stream_Seek + FT_Skip_Stream => FT_Stream_Skip + FT_Read_Stream => FT_Stream_Read + FT_Read_Stream_At => FT_Stream_Read_At + FT_Access_Frame => FT_Stream_Enter_Frame + FT_Forget_Frame => FT_Stream_Exit_Frame + FT_Extract_Frame => FT_Stream_Extract_Frame + FT_Release_Frame => FT_Stream_Release_Frame + FT_Get_XXXX => FT_Stream_Get_XXXX + FT_Read_XXXX => FT_Stream_Read_XXXX + + FT_New_Stream( filename, stream ) => + FT_Stream_Open( stream, filename ) + + (The function doesn't create the FT_Stream structure, it simply + initializes it for reading.) + + FT_New_Memory_Stream( library, FT_Byte* base, size, stream ) => + FT_Stream_Open_Memory( stream, const FT_Byte* base, size ) + + FT_Done_Stream => FT_Stream_Close + FT_Stream_IO => FT_Stream_IOFunc + FT_Stream_Close => FT_Stream_CloseFunc + + ft_close_stream => ft_ansi_stream_close (in base/ftsystem.c only) + ft_io_stream => ft_ansi_stream_io (in base/ftsystem.c only) + + * src/base/ftutil.c: New file. Contains all memory and list + management code (previously in "ftobjs.c" and "ftlist.c", + respectively). + + * include/freetype/internal/ftobjs.h: Moving all code related to + glyph loaders to ... + * include/freetype/"internal/ftgloadr.h: This new file. + "FT_GlyphLoader" is now a pointer to the structure + "FT_GlyphLoaderRec". + (ft_glyph_own_bitmap): Renamed to ... + (FT_GLYPH_OWN_BITMAP): This. + * src/base/ftobjs.c: Moving all code related to glyph loaders + to ... + * src/base/ftgloadr.c: This new file. + +2002-02-22 Werner Lemberg + + * include/freetype/internal/ftdebug.h (FT_Trace): Remove comma in + enum to avoid compiler warnings. + +2002-02-21 David Turner + + Modified the debug sub-system initialization. Trace levels can now + be specified within the "FT2_DEBUG" environment variable. See the + comments within "ftdebug.c" for more details. + + * src/base/ftdebug.c: (FT_SetTraceLevel): Removed. + (ft_debug_init): New function. + (ft_debug_dummy): Removed. + Updated to changes in ftdebug.h + + * include/freetype/internal/ftdebug.h: Always define + FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE is defined. + (FT_Assert): Renamed to ... + (FT_ASSERT): This. + Some stuff from ftdebug.h has been moved to ... + + * include/freetype/internal/fttrace.h: New file, to define the trace + levels used for debugging. It is used both to define enums and + toggle names for FT2_DEBUG. + + * include/freetype/internal/internal.h: Updated. + + * src/base/ftobjs.c, src/base/ftstream.c: Updated. + + * include/freetype/internal/ftextend.h, src/base/ftextend.c: + Removed. Both files are now completely obsolete. + * src/base/Jamfile, src/base/rules.mk: Updated. + + * include/freetype/fterrors.h: Adding "#undef FT_ERR_CAT" and + `#undef FT_ERR_XCAT" to avoid warnings with certain compilers (like + LCC). + + * src/pshinter/pshalgo2.c (print_zone): Renamed to ... + (psh2_print_zone): This to avoid errors during compilation of debug + library. + + * src/smooth/ftgrays.c (FT_COMPONENT): Change definition to as + `trace_smooth'. + +2002-02-20 David Turner + + * README: Adding "devel@freetype.org" address for bug reports. + +2002-02-20 Werner Lemberg + + * builds/unix/install.mk (check): New dummy target. + (.PHONY): Add it. + +2002-02-19 Werner Lemberg + + * builds/freetype.mk (FT_CFLAGS): Use $(INCLUDE_FLAGS) first. + + * src/cache/ftccache.c (ftc_cache_resize): Mark `error' as unused + to avoid compiler warning. + * src/cff/cffload.c (CFF_Get_String): Ditto. + * src/cff/cffobjs.c (CFF_StrCopy): Ditto. + * src/psaux/psobjs.c (PS_Table_Done): Ditto. + * src/pcf/pcfread.c (pcf_seek_to_table_type): Ditto. + * src/sfnt/sfdriver.c (get_sfnt_postscript_name): Ditto. + (pcf_get_bitmaps): The same for `sizebitmaps'. + * src/psaux/t1decode.c (T1_Decode_Parse_Charstrings): The same for + `orig_y'. + (t1operator_seac): Comment out more dead code. + * src/pshinter/pshalgo2.c (ps2_hints_apply): Add `DEBUG_HINTER' + conditional. + * src/truetype/ttgload.c (TT_Process_Simple_Glyph, + load_truetype_glyph): Add `TT_CONFIG_OPTION_BYTECODE_INTERPRETER' + conditional. + +2002-02-18 Werner Lemberg + + * src/autohint/ahglyph.c (ah_outline_link_segments): Remove unused + variables. + * src/autohint/ahhint.c (ah_align_serif_edge): Use FT_UNUSED instead + of UNUSED. + * src/autohint/ahmodule.c (ft_autohinter_reset): Ditto. + * src/pshinter/pshrec.c (ps_mask_table_merge): Fix typo in variable + swapping code. + * src/pshinter/pshglob.h (PSH_Blue_Align): Add PSH_BLUE_ALIGN_NONE. + * src/pshinter/pshglob.c (psh_blues_snap_stem): Use it. + * src/pshinter/pshalgo1.c (psh1_hint_table_optimize): Ditto. + * src/pshinter/pshalgo2.c (psh2_hint_align): Ditto. + * include/freetype/internal/ftobjs.h (UNUSED): Removed. + +2002-02-10 Roberto Alameda + + Add support for ISOLatin1 PS encoding. + + * include/freetype/freetype.h (ft_encoding_latin_1): New tag + (`lat1'). + * include/freetype/internal/t1types.h (T1_Encoding_Type): Add + `t1_encoding_isolatin1'. + * src/type1/t1driver.c (Get_Char_Index, Get_Next_Char): Handle + ft_encoding_latin_1. + * src/type1/t1load.c (parse_encoding): Handle `ISOLatin1Encoding'. + * src/type1/t1objs.c (T1_Face_Init): Handle `t1_encoding_isolatin1'. + +2002-02-09 Werner Lemberg + + * README: Fix typo. + * docs/CHANGES: Minor fixes. + + + * Version 2.0.8 released. + ========================= + + +2002-02-08 David Turner + + * docs/CHANGES: Updating for 2.0.8. + + * include/freetype/freetype.h: Setting `PATCH_LEVEL' to 8 and + removing `FT_Get_Next_Char' from the API (temporarily). + + * include/freetype/freetype.h: Adding comments to FT_Get_Next_Char; + note that this function might temporarily be removed for the 2.0.8 + release. + +2002-02-07 David Turner + + * src/pcf/pcfread.c (pcf_load_font): Removed immature support of + the AVERAGE_WIDTH property. + +2002-02-06 David Turner + + * src/sfnt/sfobjs.c (SFNT_Load_Face): Since many fonts embedded in + PDF documents do not include 'cmap', 'post' and 'name' tables, the + SFNT face loader has been changed to not immediately report an + error if these are not present. + + Note that the specification _requires_ these tables, but Adobe + seems to ignore it completely. + + * src/sfnt/ttcmap.c: Removing compiler warnings. + + * src/pcf/pcfread.c (pcf_read_TOC): Use FT_UInt. + (pcf_parse_metric, pcf_parse_compressed_metric): Removed. Code + is now in ... + (pcf_get_metric): Here. + (pcfSeekToType): Renamed to ... + (pcf_seek_to_table_type): This. + Use FT_Int. + (pcfHasType): Renamed to ... + (pcf_has_table_type): This. + Use FT_Int. + (find_property): Renamed to ... + (pcf_find_property): This. + Use FT_Int. + (pcf_get_bitmaps, pcf_get_encodings): Handle invalid PCF fonts + better (delaying format checks out of FT_Access_Frame .. + FT_Forget_Frame blocks to avoid leaving the stream in an incorrect + state when encountering an invalid PCF font). + + * src/pcf/pcfdriver.c (PCF_Done_Face): Renamed to ... + (PCF_Face_Done): This. + (PCF_Init_Face): Renamed to ... + (PCF_Face_Init): This. + (PCF_Get_Char_Index): Renamed to ... + (PCF_Char_Get_Index): This. + (PCF_Get_Next_Char): Renamed to ... + (PCF_Char_Get_Next): This. + (pcf_driver_class): Updated. + + * src/pcf/pcf.h (PCF_Done_Face): Removed. + +2002-02-06 Detlef Würkner + + * src/pcf/pcfdriver.c (FT_Done_Face): Fixed small memory leak. + + * src/pcf/pcfread.c (pcf_load_font): Now handles the "AVERAGE_WIDTH" + property to return correct character pixel (width/height) pairs for + embedded bitmaps. + +2002-02-04 Keith Packard + + Adding the function `FT_Get_Next_Char', doing the obvious thing + w.r.t. the selected charmap. + + * include/freetype/freetype.h: Add prototype. + * include/freetype/internal/ftdriver.h: Add `FTDriver_getNextChar' + typedef. + (FT_Driver_Class): Use it. + * include/freetype/internal/psnames.h: Add `PS_Next_Unicode_Func' + typedef. + (PSNames_Interface): Use it. + * include/freetype/internal/tttypes.h: Add `TT_CharNext_Func' + typedef. + (TT_CMapTable): Use it. + + * src/base/ftobjs.c (FT_Get_Next_Char): New function, implementing + high-level API. + * src/cff/cffdrivr.c (cff_get_next_char): New function. + (cff_driver_class): Add it. + * src/cid/cidriver.c (Cid_Get_Next_Char): New function. + (t1cid_driver_class): Add it. + * src/pcf/pcfdriver.c (PCF_Get_Next_Char): New function. + (pcf_driver_class): Add it. + * src/psnames/psmodule.c (PS_Next_Unicode): New function. + (psnames_interface): Add it. + * src/sfnt/ttcmap.c (code_to_next0, code_to_next2, code_to_next4, + code_to_next6, code_to_next_8_12, code_to_next_10): New auxiliary + functions. + (TT_CharMap_Load): Use them. + * src/truetype/ttdriver.c (Get_Next_Char): New function. + (tt_driver_class): Add it. + * src/type1/t1driver.c (Get_Next_Char): New function. + (t1_driver_class): Add it. + * src/winfnt/winfnt.c (FNT_Get_Next_Char): New function. + (winfnt_driver_class): Add it. + + * src/pcf/pcfread.c (pcf_load_font): For now, report Unicode for + Unicode and Latin 1 encodings. + +2002-02-02 Keith Packard + + * builds/unix/freetype-config.in: Add missing `fi'. + + + * Version 2.0.7 released. + ========================= + + +2002-02-01 David Turner + + * include/freetype/freetype.h: Increasing FREETYPE_PATCH to 7 + for the new release. + +2002-01-31 David Turner + + * README, README.UNX, docs/CHANGES: Updating documentation for the + 2.0.7 release. + +2002-01-30 David Turner + + * INSTALL: Moved to ... + * docs/INSTALL: Here to avoid conflicts with the "install" script on + Windows, where the filesystem doesn't preserve case. + +2002-01-29 David Turner + + * configure: Fixed the script. It previously didn't accept more + than one argument correctly. For example, when typing: + + ./configure --disable-shared --disable-nls + + the "--disable-nls" was incorrectly sent to the "make" program. + +2002-01-29 Werner Lemberg + + * README.UNX: Fix typo. + * builds/unix/install.mk (uninstall): Fix library name for libtool. + +2002-01-28 Francesco Zappa Nardelli + + * src/pcf/pcfdriver.c (PCF_Done_Face): Fix incorrect destruction of + the face object (face->toc.tables, face->root.family_name, + face->root.available_size, face->charset_encoding, + face->charset_registry are now freed). Thanks to Niels Moseley. + +2002-01-28 Roberto Alameda + + * src/type1/t1load.c (parse_encoding): Set `loader->num_chars'. + +2002-01-28 Werner Lemberg + + * src/type1/t1load.c (parse_subrs, parse_charstrings): Use copy + of `base' string for decrypting to not modify the original data. + Based on a patch by Jakub Bogusz . + +2002-01-27 Giuliano Pochini + + * src/smooth/ftgrays.c (gray_render_scanline): Fix bug which caused + bad rendering of thin lines (less than one pixel thick). + +2002-01-25 Werner Lemberg + + * src/cff/cffdrivr.c (cff_get_name_index): Make last patch work + actually. + +2002-01-25 Martin Zinser + + * src/cache/ftccache.c (ftc_node_done, ftc_node_destroy): Fix + compilation warnings. + * src/base/descrip.mms (OBJS): Add `ftmm.obj'. + * src/cache/descrip.mms (ftcache.obj): Dependencies added. + +2002-01-25 WANG Yi + + * src/cff/cffdrivr.c (cff_get_name_index): Fix deallocation bug. + +2002-01-21 Antoine Leca + + * docs/PATENTS: Typo fixed (thanks to Detlef "Hawkeye" Würkner) in + the URL for the online resource. + +2002-01-18 Ian Brown + + * builds/win32/ftdebug.c: New file. + * builds/win32/visualc/freetype.dsp: Updated. + +2002-01-18 Detlef Würkner + + * builds/amiga/src/base/ftsystem.c: Updated for AmigaOS 3.9. + * builds/amiga/README: Updated. + +2002-01-18 Ian Brown + + * builds/win32/visualc/freetype.dsp: Updated. + +2002-01-13 Werner Lemberg + + * builds/unix/freetype2.a4: The script was still buggy. + * builds/unix/freetype-config.in: Make it really work for any install + prefix. + +2002-01-10 Werner Lemberg + + * builds/unix/freetype2.a4: Fix some serious bugs. + +2002-01-09 David Turner + + * builds/unix/configure.ac: Build top-level Jamfile. + +2002-01-09 Maxim Shemanarev + + * src/smooth/ftgrays.c (gray_render_line): Small optimization to + the smooth anti-aliased renderer that deals with vertical segments. + This results in a 5-7% speedup in rendering speed. + +2002-01-08 David Turner + + Added some wrapper scripts to make the installation more + Unix-friendly. + + * configure, install: New files. + + * INSTALL, README.UNX: Updated installation documentation to use the + new 'configure' and 'install' scripts. + +2002-01-07 David Turner + + + * Version 2.0.6 released. + ========================= + + + * docs/BUGS, docs/CHANGES: Updating documentation for 2.0.6 release. + + * src/tools/docmaker.py: Fixed HTML quoting in sources. + (html_format): Replaced with ... + (html_quote): New function. + (html_quote0): New function. + (DocCode::dump_html: Small improvement. + (DocParagraph::dump, DocBlock::html): Use html_quote0 and html_quote. + + * include/freetype/config/ftoption.h: Setting default options for + a release build (debugging off, bytecode interpreter off). + + * src/base/ftobjs.c, src/base/ftoutln.c, src/cache/ftccmap.c, + src/cff/cffload.c, src/cff/cffobjs.c, src/pshinter/pshalgo2.c, + src/sfnt/ttload.c, src/sfnt/ttsbit.c: Removing small compiler + warnings (in pedantic compilation modes). + +2002-01-05 David Turner + + * src/autohint/ahhint.c (ah_align_linked_edge): Modified computation + of auto-hinted stem widths; this avoids color fringes in + "ClearType-like" rendering. + + * src/truetype/ttgload.c (TT_Load_Glyph_Header, + TT_Load_Simple_Glyph, TT_Load_Composite_Glyph, load_truetype_glyph): + Modified the TrueType loader to make it more paranoid; this avoids + nasty buffer overflows in the case of invalid glyph data (as + encountered in the output of some buggy font converters). + +2002-01-04 David Turner + + * README.UNX: Added special README file for Unix users. + + * builds/unix/ftsystem.c (FT_New_Stream): Fixed typo. + + * src/base/ftobjs.c: Added #include FT_OUTLINE_H to get rid + of compiler warnings. + + * src/base/ftoutln.c (FT_Outline_Check): Remove compiler warning. + +2002-01-03 Werner Lemberg + + * src/type1/t1objs.c (T1_Face_Init): Add cast to avoid compiler + warning. + +2002-01-03 Keith Packard + + * builds/unix/ftsystem.c (FT_New_Stream): Added a fix to ensure that + all FreeType input streams are closed in child processes of a "fork" + on Unix systems. This is important to avoid (potential) access + control issues. + +2002-01-03 David Turner + + * src/type1/t1objs.c (T1_Face_Init): Fixed a bug that crashed the + library when dealing with certain weird fonts like "Stalingrad", in + "sadn.pfb" (this font has no full font name entry). + + * src/base/ftoutln.c, include/freetype/ftoutln.h (FT_Outline_Check): + New function to check the consistency of outline data. + + * src/base/ftobjs.c (FT_Load_Glyph): Use `FT_Outline_Check' to + ensure that loaded glyphs are valid. This allows certain fonts like + "tt1095m_.ttf" to be loaded even though it appears they contain + really funky glyphs. + + There still is a bug there, though. + + * src/truetype/ttgload.c (load_truetype_glyph): Fix error condition. + +2001-12-30 David Turner + + * src/autohint/ahhint.c (ah_hinter_load): Fix advance width + computation of auto-hinted glyphs. This noticeably improves the + spacing of letters in KDE and Gnome. + +2001-12-25 Antoine Leca + + * builds/dos/detect.mk: Correcting the order for Borland compilers: + 16-bit bcc was never selected, always overridden by 32-bit bcc32. + +2001-12-22 Francesco Zappa Nardelli + + * src/pfc/pcfread.c (pcf_load_font): Handle property `POINT_SIZE' + and fix incorrect computation of `available_sizes'. + +2001-12-22 David Turner + + * src/autohint/ahhint.c (ah_hinter_load): Auto-hinted glyphs had an + incorrect glyph advance in the case of mono-width fonts (like + Courier, Andale Mono, and others). + +2001-12-22 Detlef Würkner + + * builds/amiga/*: Adaptations to latest changes. + Support added for MorphOS. + +2001-12-22 Werner Lemberg + + * src/pshinter/pshrec.c (FT_COMPONENT): Redefine to `trace_pshrec'. + (ps_mask_table_merge, ps_hints_open, ps_hints_stem, + ps_hints_t1stem3, ps_hints_t2mask, ps_hints_t2counter): Fix + FT_ERROR messages. + * src/pshinter/pshalgo1.c (FT_COMPONENT): Define as + `trace_pshalgo1'. + * src/pshinter/pshalgo2.c (FT_COMPONENT): Define as + `trace_pshalgo2'. + * include/freetype/internal/ftdebug.h (FT_Trace): Updated. + + * docs/modules.txt: New file. + +2001-12-21 David Turner + + * src/pshinter/pshrec.c (ps_hints_t2mask, ps_hints_t2counter): + Ignore invalid "hintmask" and "cntrmask" operators (instead of + returning an error). Glyph 2028 of the CFF font "MSung-Light-Acro" + couldn't be rendered otherwise (it seems its charstring is buggy, + though this requires more analysis). + (FT_COMPONENT): Define. + + * src/cff/cffgload.c (CFF_Parse_CharStrings), src/psaux/t1decode.c + (T1_Decoder_Parse_Charstrings), src/pshinter/pshalgo2.c (*), Fixed a + bug where the X and Y axis where inversed in the postscript hinter. + This caused problem when displaying on non-square surfaces. + + * src/pshinter/pshalgo2.c: s/vertical/dimension/. + + * src/pshinter/pshglob.c (psh_globals_new): Replaced a floating + point constant with a fixed-float equivalent. For some reasons not + all compilers are capable of directly computing a floating pointer + constant casted to FT_Fixed, and will link a math library instead. + +2001-12-20 Werner Lemberg + + * src/cache/ftccache.c (ftc_node_destroy, ftc_cache_lookup): Fix + tracing strings. + * src/cache/ftccmap.c (ftc_cmap_family_init): Ditto. + * src/cache/ftcmanag.c (ftc_family_table_alloc, + ftc_family_table_free, FTC_Manager_Check): Ditto. + * src/cache/ftcsbits.c (ftc_sbit_node_load): Ditto. + + * src/base/ftobjs.c (FT_Done_Library): Remove compiler warning. + +2001-12-20 David Turner + + Added PostScript hinter support to the CFF and CID drivers. + + * include/freetype/internal/cfftypes.h (CFF_Font): New member + `pshinter'. + * src/cff/cffload.c (CFF_Get_Standard_Encoding): New function. + * src/cff/cffload.h: Updated. + * src/cff/cffgload.c (CFF_Init_Builder): Renamed to ... + (CFF_Builder_Init): This. + Added new argument `hinting'. + (CFF_Done_Builder): Renamed to ... + (CFF_Builder_Done): This. + (CFF_Init_Decoder): Added new argument `hinting'. + (CFF_Parse_CharStrings): Implement vstem support. + (CFF_Load_Glyph): Updated. + Add hinting support. + (cff_lookup_glyph_by_stdcharcode): Use CFF_Get_Standard_Encoding(). + (cff_argument_counts): Updated. + * src/cff/cffgload.h: Updated. + * src/cff/cffobjs.c: Include FT_INTERNAL_POSTSCRIPT_HINTS_H. + (CFF_Size_Get_Globals_Funcs, CFF_Size_Done, CFF_Size_Init, + CFF_Size_Reset, CFF_GlyphSlot_Done, CFF_GLyphSlot_Init): New + functions. + (CFF_Init_Face): Renamed to ... + (CFF_Face_Init): This. + Add hinter support. + (CFF_Done_Face): Renamed to ... + (CFF_Face_Done): This. + (CFF_Init_Driver): Renamed to ... + (CFF_Driver_Init): This. + (CFF_Done_Driver): Renamed to ... + (CFF_Driver_Done): This. + * src/cff/cffobjs.h: Updated. + * src/cff/cffdrivr.c (cff_driver_class): Updated. + + * include/freetype/internal/t1types.h (CID_FaceRec): New member + `pshinter'. + * src/cid/cidgload.c (CID_Load_Glyph): Add hinter support. + * src/cid/cidobjs.c: Include FT_INTERNAL_POSTSCRIPT_HINTS_H. + (CID_GlyphSlot_Done, CID_GlyphSlot_Init, CID_Size_Get_Globals_Funcs, + CID_Size_Done, CID_Size_Init, CID_Size_Reset): New functions. + (CID_Done_Face): Renamed to ... + (CID_Face_Done): This. + (CID_Init_Face): Renamed to ... + (CID_Face_Init): This. + Add hinting support. + (CID_Init_Driver): Renamed to ... + (CID_Driver_Init): This. + (CID_Done_Driver): Renamed to ... + (CID_Driver_Done): This. + * src/cid/cidobjs.h: Updated. + * src/cidriver.c: Updated. + + * src/pshinter/pshrec.c (t2_hint_stems): Fixed. + + * src/base/ftobjs.c (FT_Done_Library): Fixed a stupid bug that + crashed the library on exit. + + * src/type1/t1gload.c (T1_Load_Glyph): Enable font matrix + transformation of hinted glyphs. + + * src/cid/cidload.c (cid_read_subrs): Fix error condition. + + * src/cid/cidobjs.c (CID_Face_Done): Fixed a memory leak; the subrs + routines were never released when CID faces were destroyed. + + * src/cff/cffload.h, src/cff/cffload.c, src/cff/cffgload.c: Updated + to move the definition of encoding tables back within "cffload.c" + instead of making them part of a shared header (causing problems in + "multi" builds). This reverts change 2001-08-08. + + * docs/CHANGES: Updated for 2.0.6 release. + * docs/TODO: Added "stem3 and counter hints support" to the TODO + list for the Postscript hinter. + * docs/BUGS: Closed the AUTOHINT-NO-SBITS bug. + +2001-12-19 David Turner + + * include/freetype/cache/ftcache.h: Added comments to indicate that + some of the exported functions should only be used by applications + that need to implement custom cache types. + + * src/truetype/ttgload.c (cur_to_org, org_to_cur): Fixed a nasty bug + that prevented composites from loading correctly, due to missing + parentheses around macro parameters. + + * src/sfnt/sfobjs.c (SFNT_Load_Face): Make the "post" and "name" + tables optional to load PCL fonts properly. + + * src/truetype/ttgload.c (TT_Load_Glyph), src/base/ftobjs.c + (FT_Load_Glyph), include/freetype/freetype.h (FT_LOAD_SBITS_ONLY): + "Fixed" the bug that prevented embedded bitmaps to be loaded when + the auto-hinter is used. This actually is a hack but will be enough + until the internal re-design scheduled for FreeType 2.1. + + * src/raster/ftrend1.c (ft_raster1_render): Fixed a nasty outline + shifting bug in the monochrome renderer. + + * README: Updated version numbers to 2.0.6. + +2001-12-17 Werner Lemberg + + * src/truetype/ttgload.c (load_truetype_glyph): Fix test for invalid + glyph header. + +2001-12-15 Werner Lemberg + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Remove compiler warning. + * include/freetype/ftcache.h (FTC_Node_Unref): Removed. It is + already in ftcmanag.h. + * src/cache/ftcsbits.c (ftc_sbit_node_load): Remove unused variable + `gfam'. + * src/cache/ftcmanag.c (ftc_family_table_alloc, + * ftc_family_table_free): Use FT_EXPORT_DEF. + * include/freetype/cache/ftcmanag.h: Updated. + * src/cache/ftccache.c (ftc_node_destroy): Use FT_EXPORT_DEF. + * src/cache/ftccmap.c (ftc_cmap_node_init): Remove unused variable + `cfam'. + Remove compiler warning. + (FTC_CMapCache_Lookup): Remove compiler warnings. + (ftc_cmap_family_init): Ditto. + (FTC_CMapCache_Lookup): Ditto. + + * builds/unix/configure.ac: Increase `version_info' to 8:0:2. + * builds/unix/configure: Regenerated. + +2001-12-14 Werner Lemberg + + * builds/mac/README: Updated. + +2001-12-14 Scott Long + + * src/truetype/ttgload.c (load_truetype_glyph): Fixing crash when + dealing with invalid fonts (i.e. glyph size < 10 bytes). + +2001-12-14 Sam Latinga + + * builds/mac/freetype.make: A new Makefile to build with MPW on + MacOS classic. + +2001-12-14 David Turner + + * src/truetype/ttgload.c (TT_Load_Glyph), src/type1/t1gload.c + (T1_Load_Glyph), src/cid/cidgload.c (CID_Load_Glyph), + src/cff/cffgload.c (CFF_Load_Glyph): Fixed a serious bug common to + all font drivers (the advance width was never hinted when it + should). + + * include/freetype/freetype.h (FREETYPE_PATCH): New macro. + * src/base/ftdbgmem.c (debug_mem_dummy) [!FT_DEBUG_MEMORY]: Don't + use `extern' keyword. + +2001-12-12 David Turner + + * src/pshint/pshglob.c (psh_blues_scale_zones, psh_blues_snap_stem + psh_globals_new): Adding correct BlueScale/BlueShift support, plus + family blues processing. + * src/pshint/pshglob.h (PSH_BluesRec): Updated. + + Started adding support for the Postscript hinter in the CFF module. + + * src/cff/cffgload.c: Include FT_INTERNAL_POSTSCRIPT_HINTS_H. + (CFF_Parse_CharStrings): Implement it. + * src/cff/cffgload.h: Updated. + +2001-12-12 Werner Lemberg + + * builds/unix/freetype2.m4: Some portability fixes. + +2001-12-11 Jouk Jansen + + * src/base/descrip.mms (OBJS): Add ftdebug.obj. + +2001-12-11 Werner Lemberg + + * src/sfnt/ttload.c (TT_Load_Generic_Header): Typos. + +2001-12-11 David Turner + + * builds/unix/freetype-config.in: Modified the script to prevent + passing "-L/usr/lib" to gcc. + + * docs/FTL.TXT: Simple fix (change "LICENSE.TXT" to "FTL.TXT"). + + * builds/unix/freetype2.m4: New file for checking configure paths. + We need to install it in $(prefix)/share/aclocal/freetype2.m4 but I + didn't modify builds/unix/install.mk yet. + + * INSTALL: Updated the instructions to build shared libraries with + Jam. They were simply wrong. + + * src/base/fttrigon.c (FT_Cos): Fixed a small bug that caused + slightly improper results for `FT_Cos' and `FT_Sin' (example: + FT_Sin(0) == -1!). + +2001-12-11 Detlef Würkner + + * include/freetype/internal/ftstream.h (GET_LongLE, GET_ULongLE): + Fixed incorrect argument types. + +2001-12-10 Francesco Zappa Nardelli + + * src/pcf/pcfdriver.c (PCF_Init_Face): Allow Xft to use PCF fonts + by setting the "face->metrics.max_advance" correctly. + +2001-12-07 David Turner + + * include/freetype/cache/ftccmap.h, src/cache/ftccmap.c: Added new + charmap cache. + * src/cache/ftcache.c: Updated. + + * src/autohint/ahhint.c (ah_hinter_hint_edges): s/UNUSED/FT_UNUSED/. + +2001-12-06 Leonard Rosenthol + + Added support for reading .dfont files on Mac OS X. Also added a + new routine which looks up a given font by name in the Mac OS and + returns the disk file where it resides. + + * src/base/ftmac.c: Include and . + (is_dfont): New auxiliary function. + (FT_New_Face_From_dfont): New function. + (FT_GetFile_From_Mac_Name): New exported function. + (FT_New_Face): Updated. + * include/freetype/ftmac.h: Updated. + +2001-12-06 David Turner + + * src/cache/Jamfile, src/cache/rules.mk: Updated. + +2001-12-06 Werner Lemberg + + * INSTALL: Small update. + +2001-12-05 David Turner + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Re-ordered code for + debugging purposes. + Comment out use of `origin'. + + * src/smooth/ftsmooth.c (ft_smooth_render): Fixed a nasty hidden bug + where outline shifting wasn't correctly undone after bitmap + rasterization. This created problems with certain glyphs (like '"' + of certain fonts) and the cache system. + + * src/pshinter/pshalgo1.c (psh1_hint_table_init): Fix typo. + * src/pshinter/pshalgo2.c (psh2_hint_table_init): Fix typo. + (ps2_hints_apply): Small fix. + +2001-12-05 David Turner + + * src/pshinter/pshalgo2.c (psh2_hint_table_init), + src/pshinter/pshalgo1.c (psh1_hint_table_init): Removed compiler + warnings. + + * include/freetype/ftcache.h, include/freetype/cache/*, src/cache/*: + Yet another massive rewrite of the caching sub-system in order to + both increase performance and allow simpler cache sub-classing. As + an example, the code for the image and sbit caches is now much + simpler. + + I still need to update the documentation in + www/freetype2/docs/cache.html to reflect the new design though. + + * include/freetype/config/ftheader.h (FT_CACHE_CHARMAP_H): New + macro. + (FT_CACHE_INTERNAL_CACHE_H): Updated. + +2001-12-05 David Krause + + * docs/license.txt: s/X Windows/X Window System/. + +2001-12-04 Werner Lemberg + + * src/raster/ftraster.c: Fix definition condition of MEM_Set(). + * src/smooth/ftgrays.c (M_Y): Change value to 192. + * src/base/ftdbgmem.c (ft_mem_table_destroy): Fix printf() parameter. + Remove unused variable. + * src/cache/ftcimage.c (ftc_image_node_init, + ftc_image_node_compare): Remove unused variables. + * src/cache/ftcsbits.c (ftc_sbit_node_weight): Remove unused + variable. + * src/raster/ftraster.c (MEM_Set): Move definition down to avoid + compiler warning. + * src/autohint/ahhint.c (ah_hinter_hint_edges): Use UNUSED() to + avoid compiler warnings. + * src/pcf/pcfread.c (tableNames): Use `const'. + (pcf_read_TOC): Change counter name to avoid compiler warning. + Use `const'. + * src/pshinter/pshrec.c (ps_hints_close): Remove redundant + declaration. + * src/pshinter/pshalgo1.c (psh1_hint_table_init): Rename variables + to avoid shadowing. + * src/pshinter/pshalgo2.c (psh2_hint_table_activate_mask): Ditto. + * src/type1/t1objs.h: Remove double declarations of `T1_Size_Init()' + and `T1_Size_Done()'. + +2001-11-20 Antoine Leca + + * include/freetype/ttnameid.h: Added some new Microsoft language + codes and LCIDs as found in MSDN (Passport SDK). Also added + comments about the meaning of bit 57 of the `OS/2' table + (TT_UCR_SURROGATES) which (with OpenType v.1.3) now means "there is + a character beyond 0xFFFF in this font". Thanks to Detlef Würkner + for noticing this. + +2001-11-20 David Turner + + * src/pshinter/{pshalgo2.c, pshalgo1.c}: Fixed stupid bug in sorting + routine that created nasty alignment artefacts. + + * src/pshinter/pshrec.c, tests/gview.c: Debugging updates. + + * src/smooth/ftgrays.c: De-activated experimental gamma support. + Apparently, `optimal' gamma tables depend on the monitor type, + resolution and general karma, so it's better to compute them outside + of the rasterizer itself. + (gray_convert_glyph): Use `volatile' keyword. + +2001-10-29 David Turner + + Adding experimental `gamma' support. This produces smoother glyphs + at small sizes for very little cost. + + * src/smooth/ftgrays.c (grays_init_gamma): New function. + (gray_raster_new): Use it. + + Various fixes to the auto-hinter. They merely improve the output of + sans-serif fonts. Note that there are still problems with serifed + fonts and composites (accented characters). + + * src/autohint/ahglyph.c (ah_outline_load, + ah_outline_link_segments): Implement it. + Fix typos. + (ah_outline_save, ah_outline_compute_segments): Fix typos. + * src/autohint/ahhint.c (ah_align_serif_edge): New argument + `vertical'. Implement improvement. + (ah_hint_edges_3, ah_hinter_hint_edges): Implement it. + Fix typos. + (ah_hinter_align_strong_points, ah_hinter_align_weak_points): Fix + typos. + (ah_hinter_load): Set `ah_debug_hinter' if DEBUG_HINTER is defined. + * src/autohint/ahmodule.c: Implement support for DEBUG_HINTER macro. + * src/autohint/ahtypes.h: Ditto. + (AH_Hinter): Remove `disable_horz_edges' and `disable_vert_edges' + (making them global as `ah_debug_disable_horz' and + `ah_debug_disable_vert'). + Fix typos. + + * tests/gview.c: Updated the debugging glyph viewer to show the + hints generated by the "autohint" module. + +2001-10-27 David Turner + + * src/cache/ftcchunk.c (ftc_chunk_cache_lookup): Fixed a bug that + considerably lowered the performance of the abstract chunk cache. + +2001-10-26 David Turner + + * include/freetype/ftcache.h, include/freetype/cache/*.h, + src/cache/*.c: Major re-design of the cache sub-system to provide + better performance as well as an "Acquire"/"Release" API. Seems to + work well here, but probably needs a bit more testing. + +2001-10-26 Leonard Rosenthol + + * builds/mac/README: Updated to reflect my taking over the project + and that is now being actively maintained. + + * src/base/ftmac.c (parse_fond): Applied patches from Paul Miller + to support loading a face other than the + first from a FOND resource. + (FT_New_Face_From_FOND): Updated. + +2001-10-25 Leonard Rosenthol + + * builds/mac/ftlib.prj: Update of CodeWarrior project file for Mac + OS for latest version (7) of CWPro and for recent changes to the FT + source tree. + +2001-10-25 David Turner + + * include/freetype/config/ftoption.h: Updated comments to explain + precisely how to use project-specific macro definitions without + modifying this file manually. + + (FT_CONFIG_FORCE_INT64): Define. + + (FT_DEBUG_MEMORY): New macro. + +2001-10-24 Tom Kacvinsky + + * builds/unix/ftsystem.c (FT_New_Memory): Added a missing `{'. + +2001-10-23 David Turner + + * include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c: + Improvements to the memory debugger to report more information in + case of errors. Also, some allocations that occured through REALLOC + couldn't be previously catched correctly. + + * src/autohint/ahglyph.c (ah_outline_compute_segments, + ah_outline_compute_edges), src/raster/ftraster.c (ft_black_new), + src/smooth/ftgrays.c (gray_render_span, gray_raster_new): Replaced + liberal uses of memset() by the MEM_Set() macro. + +2001-10-23 David Turner + + * src/raster/ftraster.c (Update): Removed to be inlined in ... + (Sort): Updated. + +2001-10-22 David Turner + + * builds/unix/ftsystem.c (FT_New_Memory, FT_Done_Memory), + builds/vms/ftsystem.c (FT_New_Memory, FT_Done_Memory), + builds/amiga/ftsystem.c (FT_New_Memory, FT_Done_Memory), + src/base/ftdbgmem.c: Updated the memory debugger and + platform-specific implementations of `ftsystem' in order to be able + to debug memory allocations on Unix, VMS and Amiga too! + + * src/pshinter/pshalgo2.c (psh2_hint_table_record_mask): Removed + some bogus warnings. + + * include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c: + Modified the debugging memory manager to report the location (source + file name + line number) where leaked memory blocks are allocated in + the source file. + + * src/base/ftdbgmem.c: New debugging memory manager. You must + define the FT_DEBUG_MEMORY macro in "ftoption.h" to enable it. It + will record every memory block allocated and report simple errors + like memory leaks and double deletes. + + * src/base/Jamfile: Include ftdbgmem. + * src/base/rules.mk: Ditto. + * src/base/ftbase.c: Include ftdbgmem.c. + + * include/freetype/config/ftoption.h: Added the FT_DEBUG_MEMORY + macro definition. + + * src/base/ftsystem.c (FT_New_Memory, FT_Done_Memory): Modified the + base component to use the debugging memory manager when the macro + FT_DEBUG_MEMORY is defined. + +2001-10-21 Tom Kacvinsky + + * src/cff/cffload.c (CFF_Done_Font): Free subfonts array only if + we are working with a CID keyed CFF font. Otherwise, a variable + that was never allocated memory might freed. This is a correction + to the previous patch for freeing subfonts. + +2001-10-21 Tom Kacvinsky + + * src/cff/cffload.c (CFF_Done_Font): Free the subfonts array to + avoid a memory leak. + +2001-10-21 David Turner + + * src/pshinter/pshalgo2.c, src/pshinter/pshalgo1.c, + src/pshinter/pshglob.c: Removing compiler warnings in pedantic modes + (in multi-object compilation mode, mainly). + +2001-10-20 Tom Kacvinsky + + * src/type1/t1load.c (parse_encoding): Add a test to make sure + that custom encodings (i.e., neither StandardEncoding nor + ExpertEncoding) are not loaded twice when the Type 1 font is + synthetic. + + * src/type1/t1load.c (parse_font_name, parse_subrs): Added a test + for when loading synthetic fonts to make sure that the font name + and subrotuines are not loaded twice. This is to remove a memory + leak that occured because the original memory blocks for these + objects were not deallocated when the objects were parsed the + second time. + +2001-10-19 David Turner + + * src/smooth/ftgrays.c, src/pshinter/pshglob.h, + src/pshinter/pshrec.c, src/pshinter/pshalgo2.c: Getting rid of + compiler warnings. + + * src/pshinter/module.mk, src/pshinter/rules.mk: Adding control + files to build the PostScript hinter with the "old" build system. + +2001-10-19 Jacob Jansen + + * descrip.mms, src/pshinter/descrip.mms: Updates to the VMS build + files. + +2001-10-18 David Turner + + * src/psnames/pstables.h, src/tools/glnames.py: Rewrote the + "glnames.py" script used to generate the "pstables.h" header file. + The old one contained a serious bug that made FreeType return + incorrect glyph names for certain glyphs. + + * src/truetype/ttdriver.c (Set_Char_Sizes): Changing computation of + pixel size from character size to use rounding. This is an + experiment to see whether this gives values similar to Windows for + scaled ascent/descent/etc. + + * src/base/ftcalc.c (FT_Div64by32): Changed the implementation + slightly since the original code was mis-compiled on Mac machines + using the MPW C compiler. + + * src/base/ftobjs.c (FT_Realloc): When a memory block was grown + through FT_Realloc(), the new bytes were not set to 0, which created + some strange bugs in the PostScript hinter. + (destroy_face): Don't deallocate unconditionally. + + * src/cid/cidgload.c (CID_Compute_Max_Advance, CID_Load_Glyph): + Adding support to new PostScript hinter. + + * include/freetype/internal/psglobal.h, + include/freetype/internal/pshints.h, + include/freetype/config/ftmodule.h, src/pshinter/Jamfile, + src/pshinter/pshalgo.h, src/pshinter/pshalgo1.h, + src/pshinter/pshalgo1.c, src/pshinter/pshalgo2.h, + src/pshinter/pshalgo2.c, src/pshinter/pshglob.h, + src/pshinter/pshglob.c, src/pshinter/pshinter.c, + src/pshinter/pshmod.c, src/pshinter/pshmod.h, src/pshinter/pshrec.c, + src/pshinter/pshrec.h: Adding new PostScript hinter module. + + * include/freetype/internal/ftobjs.h, + include/freetype/internal/internal.h, + include/freetype/internal/psaux.h, + include/freetype/internal/t1types.h, src/psaux/psobjs.c, + src/psaux/psobjs.h, src/psaux/t1decode.h, src/psaux/t1decode.c, + src/type1/t1driver.c, src/type1/t1gload.c, src/type1/t1objs.c, + src/type1/t1objs.h: Updates to use the new PostScript hinter. + + * tests/Jamfile, tests/gview.c: Adding a new glyph hinting + viewer/debugger to the source tree. Note that you will _not_ be + able to compile it since it depends on an unavailable graphics + library named "Nirvana" to render vector images. + +2001-10-17 David Turner + + + * Version 2.0.5 released. + ========================= + + + * include/freetype/freetype.h, include/internal/ftobjs.h, + src/base/ftobjs.c, src/type1/t1driver.c: Adding a new function named + 'FT_Get_Postscript_Name' to retrieve the PostScript name of a given + font. Should work with all formats except pure CFF/CEF fonts (this + will be added soon). + + * src/cid/cidriver (cid_get_postscript_name): New function. + (CID_Get_Interface): Handle `postscript_name' interface. + + * src/sfnt/sfdriver.c (get_sfnt_postscript_name): New function. + (SFNT_Get_Interface): Handle `postscript_name' interface. + + * src/type1/t1driver.c (t1_get_ps_name): New function. + (Get_Interface): Handle `postscript_name' interface. + + * README, docs/CHANGES: Updated for 2.0.5 release. + +2001-10-08 David Turner + + Fixed a bug in `glnames.py' that prevented it from generating + correct glyph names tables. This resulted in the unavailability of + certain glyphs like `Cacute', `cacute' and `lslash' in Unicode + charmaps, even if these were present in the font (causing problems + for Polish users). + + * src/tools/glnames.py (mac_standard_names): Fixed. + (t1_standard_strings): Some fixes and renamed to ... + (sid_standard_names): This. + (t1_expert_encoding): Fixed. + (the_adobe_glyph_list): Renamed to ... + (adobe_glyph_names): This. + (the_adobe_glyphs): Renamed to ... + (adobe_glyph_values): This. + (dump_mac_indices, dump_glyph_list, dump_unicode_values, main): + Updated. + * src/psnames/pstables.h: Regenerated. + * src/psnames/psmodule.c (PS_Unicode_Value): Fix offset. + Fix return value. + Use `sid_standard_table' and `ps_names_to_unicode' instead of + `t1_standard_glyphs' and `names_to_unicode'. + (PS_Macintosh_Name): Use `ps_glyph_names' instead of + `standard_glyph_names'. + (PS_Standard_Strings): Use `sid_standard_names' instead of + `t1_standard_glyphs'. + + * doc/BUGS, doc/TODO: New documents. + +2001-10-07 Richard Barber + + * src/cache/ftlru.c (FT_Lru_Lookup_Node): Fixed a bug that prevented + correct LRU behaviour. + +2001-10-07 David Turner + + setjmp() and longjmp() are now used for rollback (i.e. when memory + pool overflow occurs). + + Function names are now all uniformly prefixed with `gray_'. + + * src/smooth/ftgrays.c: Include . + (ErrRaster_MemoryOverflow): New macro. + (TArea): New type to store area values in each cell (using `int' was + too small on 16-bit systems). is included to properly + get the needed data type. + (TCell, TRaster): Use it. + (TRaster): New element `jump_buffer'. + (gray_compute_cbox): Use `RAS_ARG' as the only parameter and get + `outline' from it. + (gray_record_cell): Use longjmp(). + (gray_set_cell): Use gray_record_cell() for error handling. + (gray_render_line, gray_render_conic, gray_render_cubic): Simplify. + (gray_convert_glyph_inner): New function, using setjmp(). + (gray_convert_glyph): Use it. + +2001-10-07 David Turner + + Provide a public API to manage multiple size objects for a given + FT_Face in the new header file `ftsizes.h'. + + * include/freetype/ftsizes.h: New header file, + * include/freetype/internal/ftobjs.h: Use it. + Remove declarations of FT_New_Size and FT_Done_Size (moved to + ftsizes.h). + * include/freetype/config/ftheader.h (FT_SIZES_H): New macro. + * src/base/ftobjs.c (FT_Activate_Size): New function. + * src/cache/ftcmanag.c: Include ftsizes.h. + (ftc_manager_init_size, ftc_manager_flush_size): Use + FT_Activate_Size. + +2001-09-20 Detlef Würkner + + * builds/amiga/*: Added port to Amiga with the SAS/C compiler. + +2001-09-15 Detlef Würkner + + * src/type1/t1afm.c (T1_Done_AFM): Free `afm'. + +2001-09-10 Yao Zhang + + * src/sfnt/ttcmap.c (code_to_index2): Handle code values with + hi-byte == 0 correctly. + +2001-09-10 Werner Lemberg + + * builds/link-std.mk ($(PROJECT_LIBRARY)): Fix typo. + +2001-08-30 Martin Muskens + + * src/type1/t1load.c (parse_font_matrix): A new way to compute the + units per EM with greater accuracy (important for embedded T1 fonts + in PDF documents that were automatically generated from TrueType + ones). + + * src/type1/t1load.c (is_alpha): Now supports "+" in font names; + this is used in embedded fonts. + + * src/psaux/psobjs.c (PS_Table_Add): Fixed a reallocation bug that + generated a dangling pointer reference. + +2001-08-30 Anthony Feik + + * src/type1/t1afm.c (T1_Read_Afm): Now correctly sets the flag + FT_FACE_FLAG_KERNING when appropriate for Type1 + AFM files. + +2001-08-25 Werner Lemberg + + * src/sfnt/ttload.c (TT_Load_CMap): Fix frame length of + `cmap_rec_fields'. + + * include/freetype/fterrors.h [!FT_CONFIG_OPTION_USE_MODULE_ERRORS]: + Undefine FT_ERR_BASE before defining again. + +2001-08-22 Werner Lemberg + + * src/truetype/ttinterp.h: Fix prototype of TT_Move_Func. + +2001-08-21 Werner Lemberg + + * builds/dos/dos-def.mk (NO_OUTPUT): Don't use `&>' but `>'. + +2001-08-21 David Turner + + * include/freetype/config/ftoption.h: Changed the default setting + for FT_CONFIG_OPTION_USE_MODULE_ERRORS to undefined, since it breaks + source compatibility in a few cases. Updated the comment to explain + that too. + +2001-08-17 Martin Muskens + + * src/base/ftcalc.c (FT_MulDiv): Fixed serious typo. + +2001-08-12 Werner Lemberg + + Updating to OpenType 1.3. + + * include/freetype/internal/tttypes.h (TT_CMap0, TT_CMap2, TT_CMap4, + TT_CMap6): Adding field `language'. + (TT_CMapTable): Removing field `language'. + Type of `length' field changed to FT_ULong. + Adding fields for cmaps format 8, 10, and 12. + (TT_CMapGroup): New auxiliary structure. + (TT_CMap8_12, TT_CMap10): New structures. + * include/freetype/tttables.h (TT_HoriHeader, TT_VertHeader): + Removed last element of `Reserved' array. + * include/freetype/ttnameid.h (TT_PLATFORM_CUSTOM, TT_MS_ID_UCS_4, + TT_NAME_ID_CID_FINDFONT_NAME): New macros. + + * src/sfnt/ttcmap.c (TT_CharMap_Load): Updated loading of `language' + field to the new structures. + Fixed freeing of arrays in case of unsuccessful loads. + Added support for loading format 8, 10, and 12 cmaps. + (TT_CharMap_Free): Added support for freeing format 8, 10, and 12 + cmaps. + (code_to_index4): Small improvement. + (code_to_index6): Ditto. + (code_to_index8_12, code_to_index10): New functions. + * src/sfnt/ttload.c (TT_Load_Metrics_Header): Updated to new + structure. + (TT_Load_CMap): Ditto. + + * src/sfnt/sfobjs.c (tt_encodings): Add MS UCS4 table (before MS + Unicode). + +2001-08-11 Werner Lemberg + + * src/type1/t1driver.c (t1_get_name_index): Fix compiler warning. + +2001-08-09 Tom Kacvinsky + + * src/cff/cffdrivr.c (get_cff_glyph_name): Renamed to + cff_get_glyph_name for consistency. + + (cff_get_glyph_index): Minor documentation change. + + * src/type1/t1driver.c (t1_get_name_index): New function used in + Get_Interface as the function returned when the "name_index" + function is requested. + + (get_t1_glyph_name): Renamed to t1_get_glyph_name for consistency. + +2001-08-08 Tom Kacvinsky + + * src/cff/cffload.c: Removed definitions of cff_isoadobe_charset, + cff_expert_charset, cff_expertsubset_charset, cff_standard_encoding, + and cff_expert_encoding arrays to cffload.h. + + * src/cff/cffload.h: Added definitions of cff_isoadobe_charset, + cff_expert_charset, cff_expertsubset_charset, cff_standard_encoding, + and cff_expert_encoding arrays. + + * src/cff/cffdrivr.c (cff_get_name_index): New function, returned + when `cff_get_interface' is called with a request for the + "name_index" function. + + (cff_get_interface): Modified so that it returns the function + `cff_get_name_index' when the "name_index" function is requested. + + * src/base/ftobjs.c (FT_Get_Name_Index): New function, used to + return a glyph index for a given glyph name only if the driver + supports glyph names. + + * include/freetype/internal/ftobjs.h (FT_Name_Index_Requester): + New function pointer type defintion used in the function + FT_Get_Name_Index. + + * include/freetype/freetype.h (FT_Get_Name_Index): Added + documentation and prototype. + +2001-07-26 Werner Lemberg + + * builds/cygwin/*: Removed. Use the unix stuff instead. + +2001-07-26 Jouk Jansen + + * builds/vms/ftconfig.h (FT_CALLBACK_DEF): Updated to change dated + 2001-06-27. + +2001-07-17 Werner Lemberg + + * include/freetype/internal/psaux.h (PS_Table): Use FT_Offset for + `cursor' and `capacity'. + * src/psaux/psobjc.c (reallocate_t1_table): Use FT_Long for second + parameter. + (PS_Table_Add): Use FT_Offset for `new_size'. + + Add support for version 0.5 maxp tables. + + * src/sfnt/ttload.c (TT_Load_MaxProfile): Implement it. + (TT_Load_OS2): Initialize some values. + +2001-07-13 Werner Lemberg + + * src/base/ftsynth.c: Include ftcalc.h unconditionally. + +2001-07-07 David Turner + + * src/truetype/ttgload.c, src/truetype/ttinterp.c, src/pcf/pcfread: + Removed pedantic compiler warnings when the bytecode interpreter is + compiled in. + +2001-07-03 Werner Lemberg + + * src/autohint/ahhint.c (ah_hinter_align_weak_points): Remove + unused variable `edges'. + (ah_hinter_load): Remove unused variables `old_width' and + `new_width'. + * src/cid/cidload.c (cid_decrypt): Use `U' for constant (again). + * src/psaux/psobjs.c (T1_Decrypt): Ditto. + * src/type1/t1parse.c (T1_Get_Private_Dict): Ditto. + +2001-06-28 David Turner + + * include/internal/ftstream.h: Modified the definitions + of the FT_GET_XXXX and NEXT_XXXX macros for 16-bit correctness. + +2001-06-26 Werner Lemberg + + * src/cid/cidload.c, src/cid/cidload.h (cid_decrypt): Use FT_Offset + instead of FT_Int as type for `length' parameter. + * include/freetype/internal/psaux.h (PSAux_Interface): Updated. + +2001-06-27 Wolfgang Domröse + + * src/psaux/psobjs.c, src/psaux/psobjs.h (T1_Decrypt): Use FT_Offset + instead of FT_Int as type for `length' parameter. + + + * Version 2.0.4 released. + ========================= + + +2001-06-27 David Turner + + * builds/unix/ftconfig.in: Changed the definition of the + FT_CALLBACK_DEF macro. + + * include/freetype/ftconfig.h, src/*/*.c: Changed the definition and + use of the FT_CALLBACK_DEF macro in order to support 16-bit + compilers. + + * builds/unix/ftconfig.in: Changed the definition of the + FT_CALLBACK_DEF macro. + + * src/sfnt/ttload.c (TT_Load_Kern): The kern table loader now ensures + that the kerning table is correctly sorted (some problem fonts don't + have a correct kern table). + +2001-06-26 Wolfgang Domröse + + * include/freetype/internal/ftstream.h (FT_GET_OFF3_LE): Fix typo. + +2001-06-24 David Turner + + * src/base/ftcalc.c (ft_div64by32): Fixed the source to work + correctly on 16-bit systems. + +2001-06-23 Anthony Fok + + * debian/*: Added Debian package build directory for 2.0.4. + +2001-06-22 David Turner + + * docs/PATENTS: Added patents disclaimer. This one was missing! + + * docs/CHANGES, docs/todo: Updated for the upcoming 2.0.4 release. + +2001-06-20 Werner Lemberg + + * include/freetype/config/ftconfig.h: Add two more `L's to + constants. + Add missing semicolons. + + * builds/toplevel.mk: Do similar change as for + builds/unix/detect.mk. + + * include/freetype/freetype.h (FT_ENC_TAG): New version to make it + easier to redefine. + * include/freetype/ftimage.h (FT_IMAGE_TAG): Ditto. + + * src/pcf/pcfread.c (pcf_get_encodings): Add cast. + +2001-06-19 David Turner + + * builds/win32/visualc/freetype.dsp, builds/win32/visualc/index.html: + Updated the Visual C++ project (for the 2.0.4 release). + + * builds/unix/detect.mk: Added rule for AIX detection (which uses + /usr/sbin/init instead of /sbin/init). + + * include/freetype/fterrors.h, src/*/*err*.h: Updated some of the + error macros to simplify handling of new error scheme. + +2001-06-19 Werner Lemberg + + * include/freetype/fttypes.h (FT_ERROR_MODULE): New macro. + +2001-06-19 David Turner + + Removing _lots_ of compiler warnings when the most pedantic warning + levels of Visual C++ and Borland C++ are used. Too many files to be + listed here, but FT2 now compiles without warnings with VC++ and the + "/W4" warning level (lint-style). + + * include/freetype/freetype.h (FT_New_Memory_Face): Updated + documentation. + * include/freetype/fttypes.h (FT_BOOL): New macro. + * include/freetype/internal/ftdebug.h: Add #pragma for Visual C++ + to suppress warning. + * include/freetype/internal/ftstream.h (FT_GET_SHORT_{BE,LE}, + FT_GET_OFF3_{BE,LE}, FT_GET_LONG_{BE,LE}): New macros. + (NEXT_*): Use them. + * src/autohint/ahglobal.c: Include FT_INTERNAL_DEBUG_H. + (FT_New_Memory_Face): Add `const' to function declaration. + +2001-06-18 Werner Lemberg + + Minor cleanups to remove compiler warnings. + + * include/freetype/cache/ftcmanag.h (FTC_MAX_BYTES_DEFAULT): Use + `L' for constant. + * include/freetype/config/ftoption.h (FT_RENDER_POOL_SIZE): Ditto. + * src/base/ftcalc.c (FT_MulDiv): Use `L' for constant. + * src/base/ftglyph.c (FT_Glyph_Get_CBox): Remove `error' variable. + * src/base/fttrigon.c (ft_trig_arctan_table): Use `L' for constants. + * src/base/ftobjs.c (FT_Done_Size): Fix return value. + (FT_Set_Char_Size, FT_Set_Pixel_Sizes, FT_Get_Kerning): Remove + unused `memory' variable. + * src/autohint/ahglyph.c (ah_get_orientation): Use `L' for constant. + * src/autohint/ahhint.c (ah_hint_edges_3, + ah_hinter_align_edge_points): Remove unused `before' and `after' + variables. + (ah_hinter_align_weak_points): Remove unused `edge_limit' variable. + (ah_hinter_load): Remove unused `new_advance', `start_contour', + and `metrics' variables. + * src/cff/cffload.c (CFF_Load_Encoding): Remove dead code to avoid + compiler warning. + * src/cff/cffobjs.c (CFF_Init_Face): Remove unused `base_offset' + variable. + * src/cff/cffgload.c (CFF_Parse_CharStrings): Remove unused + `outline' variable. + (cff_compute_bias): Use `U' for constant. + * src/cid/cidload.c (cid_decrypt): Ditto. + * src/psaux/psobjs.c (T1_Decrypt): Ditto. + * src/psaux/t1decode.c (T1_Decoder_Parse_CharStrings): Ditto. + * src/sfnt/ttload.c (TT_Load_Kern): Remove unused `version' + variable. + * src/sfnt/ttsbit.c (TT_Load_SBit_Image): Remove unused `top' + variable. + * src/truetype/ttgload.c (load_truetype_glyph): Remove unused + `num_contours' and `ins_offset' variables. + (compute_glyph_metrics): Remove unused `Top' and `x_scale' + variables. + (TT_Load_Glyph): Remove unused `memory' variable. + * src/smooth/ftgrays.c (grays_raster_render): Use `L' for constants. + +2001-06-18 Werner Lemberg + + Make the new error scheme source compatible with older FT versions + by introducing another layer. + + * include/freetype/fterrors.h (FT_ERRORDEF_, FT_NOERRORDEF_): New + macros. + (FT_NOERRORDEF): Removed. + * include/*/*err*.h: Use FT_ERRORDEF_ and FT_NOERRORDEF_. + +2001-06-16 Werner Lemberg + + * include/freetype/freetype.h (FT_ENC_TAG): New macro. + (FT_Encoding_): Use it. + * include/freetype/ftimage.h (FT_IMAGE_TAG): Define it + conditionally. + +2001-06-14 David Turner + + Modified the TrueType interpreter to let it use the new + trigonometric functions provided in "fttrigon.h". This gets rid of + some old 64-bit computation routines, as well as many warnings when + compiling the library with the "long long" 64-bit integer type. + + * include/freetype/config/ftoption.h: Undefine + FT_CONFIG_OPTION_OLD_CALCS. + * include/freetype/internal/ftcalc.h: Rearrange use of + FT_CONFIG_OPTION_OLD_CALCS. + * src/base/ftcalc.c: Add declaration of FT_Int64 if + FT_CONFIG_OPTION_OLD_CALCS isn't defined. + * src/truetype/ttinterp.c: Use FT_TRIGONOMETRY_H. + (Norm): Add a special version if FT_CONFIG_OPTION_OLD_CALCS isn't + defined. + (Current_Ratio, Normalize): Simplify code. + +2001-06-11 Mike Owens + + * src/base/ftcalc.c (FT_MulDiv, FT_DivFix, FT_Sqrt64): Remove + compiler warnings. + +2001-06-08 Werner Lemberg + + * builds/unix/configure.in: Renamed to ... + * builds/unix/configure.ac: This to make sure that autoconf 2.50 is + needed. + Run `autoupdate' on it. + Increase `version_info' to 7:0:1. + * builds/unix/configure: Regenerated. + +2001-06-08 David Turner + + * src/autohint/ahhint.c (ah_hinter_load_glyph): Fixed a bug that + corrupted transformed glyphs that were auto-hinted (the transform + was applied twice). + + Fixed a bug that returned an invalid linear width for composite + TrueType glyphs. + + * include/internal/tttypes.h (TT_Loader_): Two new elements `linear' + and `linear_def'. + * src/truetype/ttgload.c (load_truetype_glyph, + compute_glyph_metrics): Use it. + + * include/fttypes.h (FT_ERROR_BASE): New macro. + * src/base/ftobjs.c (FT_Open_Face, FT_Render_Glyph_Internal): Use it + to make source code work with the new error scheme implemented by + Werner. + * src/base/ftoutln.c (FT_Outline_Render): Ditto. + +2001-06-07 Werner Lemberg + + Updating to libtool 1.4.0 and autoconf 2.50. + + * builds/unix/ltconfig: Removed. + * builds/unix/ltmain.sh, builds/unix/configure.in, + builds/unix/aclocal.m4: Updated. + * builds/unix/configure: Regenerated. + +2001-06-06 Werner Lemberg + + Complete redesign of error codes. Please check ftmoderr.h for more + details. + + * include/freetype/internal/cfferrs.h, + include/freetype/internal/tterrors.h, + include/freetype/internal/t1errors.h: Removed. Replaced with files + local to the module. All extra error codes have been moved to + `fterrors.h'. + + * src/sfnt/ttpost.h: Move error codes to `fterrors.h'. + + * src/autohint/aherrors.h, src/cache/ftcerror.h, src/cff/cfferrs.h, + src/cid/ciderrs.h, src/pcf/pcferror.h, src/psaux/psauxerr.h, + src/psnames/psnamerr.h, src/raster/rasterrs.h, src/sfnt/sferrors.h, + src/smooth/ftsmerrs.h, src/truetype/tterrors.h, + src/type1/t1errors.h, src/winfonts/fnterrs.h: New files defining the + error names for the module it belongs to. + + * include/freetype/ftmoderr.h: New file, defining the module error + offsets. Its structure is similar to `fterrors.h'. + + * include/freetype/fterrors.h (FT_NOERRORDEF): New macro. + (FT_ERRORDEF): Redefined to use module error offsets. + All internal error codes are now public; unused error codes have + been removed, some are new. + + * include/freetype/config/ftheader.h (FT_MODULE_ERRORS_H): New + macro. + * include/freetype/config/ftoption.h + (FT_CONFIG_OPTION_USE_MODULE_ERRORS): New macro. + + All other source files have been updated to use the new error codes; + some already existing (internal) error codes local to a module have + been renamed to give them the same name as in the base module. + + All make files have been updated to include the local error files. + +2001-06-06 Werner Lemberg + + * src/cid/cidtokens.h: Replaced with... + * src/cid/cidtoken.h: This file for 8+3 consistency. + + * src/raster/ftraster.c: Use macros for header file names. + + * src/include/freetype/tttables.h (TT_HoriHeader_, TT_VertHeader_): + Fix length of `Reserved' array. Note that this isn't the real fix + since recent OpenType specs have introduced a `CaretOffset' field + instead of the first reserved byte. + +2001-05-29 Werner Lemberg + + * INSTALL: Minor fixes. + + + * Version 2.0.3 released. + ========================= + + +2001-05-29 David Turner + + * INSTALL, docs/CHANGES: Updated. + +2001-05-25 David Turner + + Moved several documents from the top-level to the "docs" directory. + + * src/base/ftcalc.c (FT_DivFix): Small fix to return value. + +2001-05-16 David Turner + + * src/truetype/ttgload.c (load_truetype_glyph): Fixed a bug in the + composite loader. Spotted by Keith Packard. + * src/base/ftobjs.c (FT_GlyphLoader_Check_Points, + FT_GlyphLoader_Check_Subglyphs): Ditto. + +2001-05-14 David Turner + + Fixed the incorrect blue zone computations, and improved the + composite support. Note that these changes result in improved + rendering, while sometimes introducing their own artefacts. This is + probably the last big change to the autohinter before the + introduction of a complete replacement. + + * src/autohint/ahglobal.c (sort_values): Fix loop. + * src/autohint/ahglyph.c: Removed some obsolete code. + (ah_outline_compute_edges): Modify code to set the ah_edge_round + flag. + (ah_outline_compute_blue_edges): Add code to compute active blue + zones. + * src/autohint/ahhint.c (ah_hinter_glyph_load): Change load_flags + value. + + * src/base/ftcalc.c (FT_DivFix): Fixed a bug in the 64-bit code that + created incorrect scale factors! + (FT_Round_Fix, FT_CeilFix, FT_FloorFix): Minor improvements. + +2001-05-12 Werner Lemberg + + * include/freetype/ftbbox.h: FTBBOX_H -> __FTBBOX_H__. + * include/freetype/fttrigon.h: __FT_TRIGONOMETRY_H__ -> + __FTTRIGON_H__. + Include FT_FREETYPE_H. + Beautified; added copyright. + * src/base/fttrigon.c: Beautified; added copyright. + +2001-05-11 David Turner + + * src/cff/cffparse.c (cff_parse_font_matrix), src/cid/cidload.c + (parse_font_matrix), src/type1/t1load.c (parse_font_matrix): Fixed + the incorrect EM size computation. + + * include/freetype/fttrigon.h, src/base/fttrigon.c: New files, + adding trigonometric functions to the core API (using Cordic + algorithms). + * src/base/ftbase.c, src/base/Jamfile, src/base/rules.mk: Use them. + + * builds/newline: New file. + * builds/top_level.mk, builds/detect.mk: Use it. This fixes + problems with Make on Windows 2000, as well as problems when "make + distclean" is invoked on a non-Unix platform when there is no + "config.mk" in the current directory. + + * builds/freetype.mk: Fixed a problem with object deletions under + Dos/Windows/OS/2 systems. + + Added new directory to hold tools and test programs. + + * docs/docmaker.py, docs/glnames.py: Moved to... + * src/tools/docmaker.py, src/tools/glnames.py: This place. + * src/tools/cordic.py: New file used to compute arctangent table + needed by fttrigon.c. + * src/tools/test_bbox.c, src/tools/test_trig.c: New test files. + + * src/tools/docmaker.py: Improved the script to add the current date + at the footer of each web page (useful to distinguish between + versions). + + * Jamfile: Fixed incorrect HDRMACRO argument. + + * TODO: Removed the cubic arc bbox computation note, since it has been + fixed recently. + * src/base/ftbbox.c (test_cubic_zero): Renamed to... + (test_cubic_extrema): This function. Use `UL' for unsigned long + constants. + + * include/freetype/t1tables.h, include/freetype/config/ftoption.h: + Formatting. + +2001-05-10 David Turner + + * src/base/ftobjs.c (FT_Open_Face): Fixed a small memory leak + which happened when trying to open 0-size font files! + +2001-05-09 Werner Lemberg + + * include/freetype/internal/ftcalc.h: Move declaration of + FT_SqrtFixed() out of `#ifdef FT_LONG64'. + +2001-05-08 Francesco Zappa Nardelli + + * src/pcfdriver.c (PCF_Load_Glyph): Fixed incorrect bitmap width + computation. + +2001-05-08 David Turner + + * docs/docmaker.py: Updated the DocMaker script in order to add + command line options (--output,--prefix,--title), fix the erroneous + line numbers reported during errors and warnings, and other + formatting issues. + + * src/base/ftcalc.c (FT_MulDiv, FT_MulFix, FT_DivFix): Various tiny + fixes related to rounding in 64-bits routines and + pseudo-"optimizations". + +2001-04-27 David Turner + + * src/base/ftbbox.c (BBox_Cubic_Check): Fixed the coefficient + normalization algorithm (invalid final bit position, and invalid + shift computation). + +2001-04-26 Werner Lemberg + + * builds/unix/config.guess, builds/unix/config.sub: Updated to + latest versions from gnu.org. + + * builds/compiler/gcc-dev.mk: Add `-Wno-long-long' flag. + + * include/freetype/internal/ftcalc.h: Define FT_SqrtFixed() + uncoditionally. + * src/base/ftbbox.c: Include FT_INTERNAL_CALC_H. + Fix compiler warnings. + * src/base/ftcalc.c: Fix (potential) compiler warnings. + +2001-04-26 David Turner + + * src/base/ftcalc.c (FT_SqrtFixed): Corrected/optimized the 32-bit + fixed-point square root computation. It is now used even with + 64-bits integers, as it is _much_ faster than calling FT_Sqrt64 :-) + + * src/base/ftbbox.c: Removed invalid "#include FT_BEZIER_H" line. + +2001-04-25 David Turner + + * src/base/ftbbox.c (BBox_Cubic_Check): Rewrote function to use + direct computations with 16.16 values instead of sub-divisions. It + is now slower, but proves a point :-) + + * src/raster/ftraster.c, src/smooth/ftgrays.c, src/base/ftbbox.c: + Fixed the bezier stack depths. + + * src/base/ftcalc.c (FT_MulFix): Minor rounding fix. + + * builds/beos: Added BeOS-specific files to the old build system + (no changes were necessary to support BeOS in the Jamfile though). + +2001-04-20 David Turner + + * ftconfig.h, ftoption.h: Updated "ftconfig.h" to detect 64-bit int + types on platforms where Autoconf is not available). Also removed + FTCALC_USE_LONG_LONG and replaced it with + FT_CONFIG_OPTION_FORCE_INT64. + + * builds/win32/freetype.dsp: Updated the Visual C++ project file. + Doesn't create a DLL yet. + + * cffgload.c: Removed a compilation warning. + +2001-04-10 Tom Kacvinsky + + * t1load.c (parse_charstrings): Changed code for placing .notdef + glyph into slot 0 so that we no longer have a memory access + violation. + + * t1load.h: In structure T1_Loader, added swap_table (of type + PS_Table) to facilitate placing the .notdef glyph into slot 0. + +2001-04-10 Francesco Zappa Nardelli + + * src/pcf/pcfdriver.c (PCF_Get_Char_Index): Fix return value. + +2001-04-09 Laurence Withers + + * builds/dos/detect.mk: Add support for bash. + +2001-04-05 Werner Lemberg + + * builds/os2/*.mk: These files have been forgotten to update to + the structure of similar makefiles. + * builds/dos/*.mk: Ditto. + * builds/ansi/*.mk: Ditto. + + * builds/win32/win32-def.mk (BUILD): Fix typo. + + * builds/compiler/*.mk (CLEAN_LIBRARY): Don't use NO_OUTPUT. + This is already used in the link_*.mk files. + +2001-04-03 Werner Lemberg + + * src/*/Jamfile: Slight changes to make files more cryptic. + +2001-04-03 Werner Lemberg + + * Jamfile, src/Jamfile, src/*/Jamfile: Formatted. Slight changes + to give files identical structure. + +2001-04-02 Werner Lemberg + + * CHANGES: Reformatted, minor fixes. + * TODO: Updated. + * README: Formatting. + * include/freetype/freetype.h: Formatting. + + * Jamfile: Fix typo. + + * src/cff/cffparse.c: Move error code #defines to... + * include/freetype/internal/cfferrs.h: This file. + * src/cff/cffdrivr.c, src/cff/cffobjs.c, src/cff/cffload.c: Replaced + `FT_Err_*' with `CFF_Err_*'. + * src/cid/cidparse.c: Replaced `FT_Err_*' with `T1_Err_*'. + * src/psaux/psobjs.c, src/psaux/t1decode.c: Ditto. + * src/sfnt/sfobcs.c, src/sfnt/ttload.c: Replaced `FT_Err_*' with + `TT_Err_*'. + * src/truetype/ttgload.c, src/truetype/ttobjs.c: Ditto. + * src/type1/t1gload.c, src/type1/t1load.c, src/type1/t1objs.c, + src/type1/t1parse.c: Replaced `FT_Err_*' with `T1_Err_*'. + + * include/freetype/internal/cfferrs.h: Add + `CFF_Err_Unknown_File_Format'. + * include/freetype/internal/t1errors.h: Add + `T1_Err_Unknown_File_Format'. + * include/freetype/internal/tterrors.h: Add + `TT_Err_Unknown_File_Format'. + + * src/cff/cffload.h: Add `cff_*_encoding' and `cff_*_charset' + references. + * src/psaux/psobjs.c: Include `FT_INTERNAL_TYPE1_ERRORS_H'. + + * src/cff/cffobjs.c (CFF_Init_Face, CFF_Done_Face): Use + FT_LOCAL_DEF. + * src/cid/cidobjs.c (CID_Done_Driver): Ditto. + * src/trutype/ttobjs.c (TT_Init_Face, TT_Done_Face, TT_Init_Size): + Ditto. + * src/type1/t1objs.c (T1_Done_Driver): Ditto. + * src/pcf/pcfdriver.c (PCF_Done_Face): Ditto. + * src/pcf/pcf.h: Use FT_LOCAL for `PCF_Done_Face'. + +2001-04-02 Tom Kacvinsky + + * src/sfnt/ttload.c (TT_Load_Metrics): Fix an improper pointer + dereference. Submitted by Herbert Duerr + +2001-03-26 Tom Kacvinsky + + * include/freetype/config/ftconfig.h: Changed hexadecimal + constants to use suffix U to avoid problems with HP-UX's c89 + compiler. Submitted by G.W. Lucas + +2001-03-24 David Turner + + * Jamrules, Jamfile, src/Jamfile, src/*/Jamfile: Adding jamfiles to + the source tree. See www.freetype.org/jam/index.html for details. + + + * Version 2.0.2 released. + ========================= + + +2001-03-20 Werner Lemberg + + * builds/win32/detekt.mk: Fix .PHONY target for Intel compiler. + +2001-03-20 David Turner + + * include/freetype/config/ftheader.h, include/freetype/ftsnames.h: + Renamed "ftnames.h" to "ftsnames.h", and FT_NAMES_H to + FT_SFNT_NAMES_H. + + * docs/docmaker.py: Added generation of INDEX link in table of + contents. + + * INSTALL, docs/BUILD: Updated documentation to indicate that the + compilation process has changed slightly (no more `src' required in + the include path). + + * builds/*/*-def.mk: Changed the objects directory from "obj" to + "objs". + + * include/freetype/config/ftheader.h: Removed obsolete macros like + FT_SOURCE_FILE, etc. and added cache-specific macro definitions that + were previously defined in . Added comments to + be included in a new API Reference section. + + * src/*/*: Removed the use of FT_SOURCE_FILE, etc. Now, each + component needs to add its own directory to the include path at + compile time. Modified all "rules.mk" and "descrip.mms" + accordingly. + +2001-03-20 Werner Lemberg + + * builds/unix/configure.in: Add $ft_version. + * builds/unix/freetype-config.in: Use it. + * builds/unix/configure: Updated. + +2001-03-19 Tom Kacvinsky + + * src/type1/t1load.c (parse_font_matrix): Assign the units per em + value an unsigned short value, first by shifting right 16 bits, + then by casting the results to FT_UShort. + + * src/cff/cffparse.c (cff_parse_font_bbox): Assign the units per em + value an unsigned short value, first by shifting right 16 bits, + then by casting the results to FT_UShort. + +2001-03-17 David Turner + + * src/cid/cidobjs.c, src/cid/cidload.c, src/pcf/pcfread.c, + src/type1/t1load.c, src/type1/t1objs.c: Added a few casts to remove + compiler warnings in pedantic modes. + + * include/config/ft2build.h, include/config/ftheader.h: The file + "ft2build.h" was renamed to "ftheader.h" to avoid conflicts with the + top-level . + + * include/config/ftheader.h: Added new section describing the #include + macros. + +2001-03-17 Tom Kacvinsky + + * src/cff/cffparse.c (cff_parse_font_bbox): Obtain rounded FT_Fixed + values for the bounding box numbers. + + * src/cff/cffobjs.c (CFF_Init_Face): When processing a CFF/CEF font, + set `root->ascender' (`root->descender') to the integer part of + `root->bbox.yMax' (`root->bbox.yMin', respectively). + +2001-03-16 Tom Kacvinsky + + * src/cff/cffdrivr.c (get_cff_glyph_name): New function. Used in + cff_get_interface to facilitate getting a glyph name for glyph index + via FT_Get_Glyph_Name(). + + (cff_get_interface): Added support for getting a glyph name via the + "glyph_name" module interface. Uses the new function + get_cff_glyph_name(). + Submitted by Sander van der Wal + + * src/cff/cffobjs.c (CFF_Init_Face): Logical or the face flags with + FT_FACE_FLAG_GLYPH_NAMES only if FT_CONFIG_OPTION_NO_GLYPH_NAMES is + not defined. This is to add support for getting a glyph name from a + glyph index via FT_Get_Glyph_Name(). + Submitted by Sander van der Wal + + * src/cff/cffgload.c (CFF_Parse_CharStrings): Added support for + deprecated operator "dotsection". + Submitted by Sander van der Wal + +2001-03-12 Werner Lemberg + + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Fix error + messages. + + * INSTALL, docs/BUILD: We need GNU make 3.78.1 or newer. + +2001-03-12 Tom Kacvinsky + + * include/freetype/internal/psaux.h: Changed the lenIV member of + the T1_Decoder_ struct to be an FT_Int instead of an FT_UInt. + + * src/psaux/t1decode.c (T1_Decoder_Parse_Charstrings): Adjust + for lenIV seed bytes at the start of a decrypted subroutine. + + * src/cid/cidload.c (cid_read_subrs): Decrypt subroutines only + if lenIV >= 0. + + * src/cid/cidgload.c (cid_load_glyph): Decrypt charstrings only + if lenIV >= 0. + +2001-03-11 Werner Lemberg + + * TODO: Updated. + + * src/pcf/pcfread.c: Put READ_Fields() always in a conditional to + avoid compiler warnings. + +2001-03-10 Tom Kacvinsky + + * TODO: New file. + + * include/freetype/freetype.h: Added prototypes and notes for + three new functions: FT_RoundFix, FT_CeilFix, and FT_FloorFix. + * src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_FloorFix): Added + implementation code. + + * src/cid/cidobjs.c (CID_Init_Face): Use calculated units_per_EM, + and if that is not available, default to 1000 units per EM. Changed + assignment code for ascender and descender values. + * src/cid/cidload.c (parse_font_matrix): Added units_per_EM + processing. + (parse_font_bbox): Changed to use FT_Fixed number handling. + + * src/type1/t1objs.c (T1_Init_Face): Changed the assignment code + for ascender, descender, and max_advance_width. + * src/type1/t1load.c (parse_font_bbox): Changed to use FT_Fixed + number handling. + +2001-03-10 Henrik Grubbström + + * src/*/*.c: Added many casts to make code more 64bit-safe. + +2001-03-07 Werner Lemberg + + * INSTALL, docs/BUILD: We need GNU make 3.78 or newer. + +2001-03-07 Tom Kacvinsky + + * src/type1/t1objs.c (T1_Init_Face): Minor correction: We must wait + until parse_font_bbox is changed before we use logical shift rights + in the assignments of `root->ascender', `root->descender', and + `root->max_advance_width'. + + (T1_Done_Face): Free `char_name' table to avoid a memory leak. + Submitted by Sander van der Wal . + +2001-03-05 Tom Kacvinsky + + * src/cff/cffgload.c (CFF_Load_Glyph): Set glyph control data to the + the Type 2 glyph charstring (used by conversion programs). + Submitted by Ha Shao . + +2001-03-04 Antoine Leca + + * include/freetype/ttnameid.h: Correct a stupid typo which prevented + correct compilation (TT_MS_LANGID_TIGRIGNA_ETHIOPIA appeared twice). + +2001-03-04 Werner Lemberg + + * src/autohint/ahtypes.h (AH_Hinter): Add elements + `disable_horz_edges', `disable_vert_edges'. + * src/autohint/ahhint.c (ah_hint_edges_3, ah_hinter_hint_edges): Use + them (and remove static variables with the same names). + * src/pcf/pcfutil.c (BitOrderInvert): Add `const'. + * docs/glnames.py: Updated to latest pstables.h changes. + + * builds/unix/detect.mk: Add test for Hurd. + * builds/hurd/detect.mk: Removed. + +2001-03-04 Sander van der Wal + + * src/psnames/pstables.h: Add more `const'. + * src/pcf/pcfutil.c: Ditto. + +2001-03-04 Werner Lemberg + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Fixing typo + (FT_Glyph_Done -> FT_Done_Glyph). + +2001-03-01 Antoine Leca + + * include/freetype/ttnameid.h: Added some new Microsoft language + codes and LCIDs as found in Office Xp. + +2001-02-28 David Turner + + * builds/hurd/detect.mk: New file. Added support to detect the GNU + Hurd operating system as Unix-like. Fix submitted by Anthony Fok + . + + * src/type1/t1gload.c (T1_Load_Glyph): Set glyph control data to the + the Type 1 glyph charstring (used by conversion programs). + Submitted by Ha Shao . + +2001-02-22 David Turner + + * src/base/ftgrays.c (grays_sweep): The function didn't exit + immediately if `num_cells' was 0 as it should. Thanks to Boris for + finding this out. + + * src/base/ftglyph.c (FT_Glyph_To_Bitmap): Fixed memory leak when + bitmap rendering fails (thanks to Graham Asher). + +2001-02-13 Werner Lemberg + + * docs/docmaker.py (DocSection::add_element): Use + `self.print_error()'. + + * builds/unix/config.{guess,sub}: Updated (from ftp.gnu.org). + +2001-02-13 David Turner + + * docs/docmaker.py, include/freetype/*.h: Updated the DocMaker + script to support chapters and section block ordering. Updated the + public header files accordingly. + + * src/base/ftglyph.c (FT_Glyph_Copy): Advance width and glyph format + were not correctly copied. + +2001-02-08 Tom Kacvinsky + + * src/cff/cffparse.c (cff_parse_font_matrix): Removed an + unnecessary fprintf( stderr, ... ). + +2001-02-07 Tom Kacvinsky + + * src/type1/t1objs.c (T1_Init_Face): Added code to get the + units_per_EM from the value assigned in parse_font_matrix, if + available. Default to 1000 if not available. + + * src/cff/cffparse.c (cff_parse_font_matrix): Added logic to get + the units_per_EM from the FontMatrix. + + (cff_parse_fixed_thousand): New function. Gets a real number from + the CFF font, but multiplies by 1000 (this is to avoid rounding + errors when placing this real number into a 16.16 fixed number). + + (cff_parse_real): Added code so that the integer part is moved + into the high sixteen bits of the 16.16 fixed number. + + * src/cff/cffobjs.c (CFF_Init_Face): Added logic to get the units + per EM from the CFF dictionary, if available. + + * include/freetype/internal/cfftypes.h: In struct CFF_Font_Dict_, + added a units_per_em member to facilitate passing of units_per_em + from function cff_parse_font_matrix. + + * src/type1/t1load.c (is_alpha): Make `-' a legal alphanumeric + character. This is so that font names with `-' are fully parsed, + etc... + +2001-02-02 Werner Lemberg + + * src/psaux/psobjs.c (shift_elements): Remove if clause (which is + obsolete now). + + (reallocate_t1_table, PS_Table_Done): Replace REALLOC() with ALLOC() + + MEM_Copy() to avoid a memory bug. + +2001-02-01 David Turner + + * docs/docmaker.py: Improved the index sorting routine to place + capital letters before small ones. Added the "" marker to + section blocks in order to give the order of blocks. + +2001-01-30 Antoine Leca + + * include/freetype/ttnameid.h: Latest updates to Microsoft language + ID codes. + +2001-01-24 Tom Kacvinsky + + * src/cff/t1load.c (parse_font_matrix): Added heuristic to get + units_per_EM from the font matrix. + + (parse_dict): Deleted test to see whether the FontInfo keyword has + been seen. Deletion of this test allows fonts without FontInfo + dictionaries to be parsed by the Type 1 driver. + + (T1_Open_Face): Deleted empty subroutines array test to make sure + fonts with no subroutines still are parsed. + +2001-01-17 Francesco Zappa Nardelli + + * src/pcfread.c (pcf_get_properties, pcf_get_metrics, + pcf_get_bitmaps): Fix compiler errors. + +2001-01-11 David Turner + + * src/pcf/pcfread.c: Removed some compilation warnings related + to comparison of signed vs. unsigned integers. + + * include/freetype/internal/ftdebug.h: Changed the debug trace + constants from trace_t2xxxx to trace_cffxxxx to be able to compile + the CFF driver in debug mode. + +2001-01-11 Matthew Crosby + + * builds/unix/freetype-config.in: Fix problems with separate + --prefix and --exec-prefix. + +2001-01-11 David Turner + + * docs/docmaker.py: Added cross-references generation as well as + more robust handling of pathname wildcard matching. + +2001-01-10 Werner Lemberg + + * docs/docmaker.py: Minor improvements to reduce unwanted spaces + and empty lines in output. + +2001-01-09 David Turner + + * docs/docmaker.py: Improved script to generate table of contents + and index pages. It also supports wildcards on non Unix systems. + + * include/freetype/*.h, include/freetype/cache/*.h: Updated comments + to include section definitions/delimitations for the API Reference + generator. + + * include/freetype/freetype.h: Moved declaration of + `FT_Generic_Finalizer' and the `FT_Generic' structure to... + * include/freetype/fttypes.h: here. + +2001-01-04 Werner Lemberg + + * include/freetype/ttnameid.h: Updated Unicode code range comments. + +2001-01-03 Tom Kacvinsky + + * src/cff/rules.mk: Use cffgload.{c,h} instead of t2gload.{c,h}. + + * include/freetype/internal/internal.h: Changed to use cfftypes.h + (cfferrs.h) instead of t2types.h (t2errors.h, respectively). + + * include/freetype/internal/cfftypes.h: Merged in changes from + t2types.h and made this the canonical `types' header for the CFF + driver. + + * include/freetype/internal/t2types.h: This file was merged with + cfftypes.h and is no longer necessary. + + * include/freetype/internal/t2errors.h: Renamed to cfferrs.h. + + * src/cff/cffobjs.c, src/cff/cffobjs.h, src/cff/cffparse.c, + src/cff/cffdrivr.c, src/cff/cff.c, src/cff/cffload.c, + src/cff/cffgload.c, src/cff/cffgload.h: Changed to use + cffgload.{c,h} instead of t2gload.{c,h}. All occurences of t2_ + (T2_) were replaced with cff_ (CFF_, respectively). + + * src/cff/t2gload.h: Renamed cffgload.h. + + * src/cff/t2gload.c: Renamed cffgload.c + +2000-01-02 Jouk Jansen + + * builds/vms: Support files for VMS architecture added. + * descrip.mms, src/*/descrip.mms: VMS makefiles added. + * README.VMS: New file. + +2000-01-01 Werner Lemberg + + * LICENSE.TXT: Added info about PCF driver license. + +2001-01-01 Francesco Zappa Nardelli + + * src/pcf/*: New driver module for PCF font format (used in + X Window System). + * include/freetype/internal/ftdebug.h (FT_Trace): Added values for + PCF driver. + * include/freetype/internal/pcftypes.h: New file. + * include/freetype/config/ftmodule.h: Added PCF driver module. + +2001-01-01 Werner Lemberg + + * src/winfonts/winfnt.c (FNT_Get_Char_Index): Fix parameter type. + +2000-12-31 Werner Lemberg + + * builds/modules.mk (clean_module_list): Fixed deletion of module + file in case `make make_module_list' is called before `make setup'. + +2000-12-30 Werner Lemberg + + * src/cff/cffload.c (CFF_Load_Charset): Improved error messages. + (CFF_Load_Charset, CFF_Load_Encoding): Remove unnecessary variable + definition. + +2000-12-30 Tom Kacvinsky + + * include/freetype/internal/t2types.h, + include/freetype/internal/cfftypes.h: Changed the structures for + CFF_Encoding and CFF_Encoding for the new implementations of the + charset and encoding parsers in the CFF driver. + + * src/cff/t2gload.c (t2_lookup_glyph_by_stdcharcode, + t2_operator_seac): Added these functions for use in implementing the + seac emulation provided by the Type 2 endchar operator. + (T2_Parse_CharStrings): Added seac emulation for the endchar + operator. + + * src/cff/cffload.c (CFF_Load_Encoding, CFF_Load_Charset, + CFF_Done_Encoding, CFF_Done_Charset): Extended to load and parse the + charset/encoding tables, and free the memory used by them when the + CFF driver is finished with them. Added tables + + cff_isoadobe_charset + cff_expert_charset + cff_expertsubset_charset + cff_standard_encoding + cff_expert_encoding + + so that the encoding/charset parser can handle predefined encodings and + charsets. + +2000-12-24 Tom Kacvinsky + + * src/cff/t2gload.c (T2_Load_Glyph): Added code so that the font + transform is applied. + + * src/cff/cffparse.c (cff_parse_font_matrix): Added code so that + the font matrix numbers are scaled by 1/(matrix->yy). Also, the + offset vector now contains integer values instead of 16.16 fixed + numbers. + +2000-12-22 Tom Kacvinsky + + * src/autohint/ahhint.c (ah_hinter_load_glyph): + Removed unnecessary comments and commented-out code. + +2000-12-21 David Turner + + * src/cid/cidafm.c, src/cid/cidafm.h: removed un-needed files, + we'll work on supporting CID AFM files later I guess :-) + +2000-12-21 Tom Kacvinsky + + * src/autohint/ahhint.c (ah_hinter_load, ah_hinter_load_glyph): + Changed so that fonts with a non-standard FontMatrix render + correctly. Previously, the first glyph rendered from such a + font did not have the tranformation matrix applied. + +2000-12-17 Werner Lemberg + + * *.mk: Added lots of `.PHONY' targets. + +2000-12-17 Karsten Fleischer + + * *.mk: Implemented `platform' target to disable auto-detection. + +2000-12-14 Werner Lemberg + + * docs/design/modules.html: Removed. Covered by design-*.html. + + * INSTALL: Added info about makepp. + +2000-12-14 David Turner + + Added support for clipped direct rendering in the smooth renderer. + This should not break binary compatibility of existing applications. + + * include/freetype/fttypes.h, include/freetype/ftimage.h: Move + definition of the FT_BBox structure from the former to the latter. + * include/freetype/ftimage.h: Add `ft_raster_flag_clip' value to + FT_Raster_Flag enumeration. + Add `clip_box' element to FT_Raster_Params structure. + * src/smooth/ftgrays.c (grays_convert_glyph): Implement it. + + * INSTALL: Updated installation instructions on Win32, listing the + new "make setup list" target used to list supported + compilers/targets. + + * src/raster/ftraster.c (ft_black_render): Test for unsupported + direct rendering before testing arguments. + +2000-12-13 David Turner + + * include/freetype/config/ft2build.h, + include/freetype/internal/internal.h: Fixed header inclusion macros + to use direct definitions. This is the only way to do these things + in a portable way :-( The rest of the code should follow shortly + though everything compiles now. + + * builds/compiler/intelc.mk, builds/compiler/watcom.mk: New files. + + * builds/win32/detect.mk: Added support for the Intel C/C++ + compiler, as well as _preliminary_ (read: doesn't work!) support for + Watcom. Also added a new setup target. Type "make setup list" for + a list of supported command-line compilers on Win32. + + * src/base/ftdebug.c: Added dummy symbol to avoid empty file if + conditionals are off. + +2000-12-13 Werner Lemberg + + * builds/unix/ftsystem.c: Fixed typos. Fixed inclusion of wrong + ftconfig.h file. + +2000-12-12 Werner Lemberg + + * include/freetype/config/ft2build.h (FT2_ROOT, FT2_CONFIG_ROOT): + Removed. ANSI C doesn't (explicitly) allow macro expansion in + arguments using `##'. + (FT2_PUBLIC_FILE, FT2_CONFIG_FILE, FT2_INTERNAL_FILE): Use directory + names directly. Make them configurable. Use `##' to strip leading + and trailing spaces from arguments. + + * builds/unix/ft2unix.h: Adapted. + + * src/base/ftsystem.c (ft_alloc, ft_realloc, ft_free, ft_io_stream, + ft_close_stream): Use FT_CALLBACK_DEF. + + * builds/unix/ftsystem.c: Use new header scheme. + (FT_Done_Memory): Use free() from FT_Memory structure. + + * src/base/ftinit.c, src/base/ftmac.c: Header scheme fixes. + +2000-12-11 Werner Lemberg + + * include/freetype/config/ft2build.h (FT2_CONFIG_ROOT, + FT2_PUBLIC_FILE, FT2_CONFIG_FILE, FT2_INTERNAL_FILE, + FT_SOURCE_FILE): Use `##' operator to be really ANSI C compliant. + +2000-12-09 Werner Lemberg + + * builds/unix/detect.mk: Remove unused USE_CFLAGS variable. + +2000-12-08 Werner Lemberg + + * */*.h: Changed body inclusion macro names to start and end with + `__' (those which haven't converted yet). Fixed minor conversion + issues. + + * src/winfonts/winfnt.c: Updated to new header inclusion scheme. + + * src/truetype/ttinterp.c: Remove unused CALC_Length() macro. + +2000-12-07 David Turner + + * */*.[ch]: Changed source files to adhere to the new + header inclusion scheme. Not completely tested but works for now + here. + + * src/cff/t2driver.c: Renamed and updated to... + * src/cff/cffdrivr.c: New file. + * src/cff/t2driver.h: Renamed and updated to... + * src/cff/cffdrivr.h: New file. + * src/cff/t2load.c: Renamed and updated to... + * src/cff/cffload.c: New file. + * src/cff/t2load.h: Renamed and updated to... + * src/cff/cffload.h: New file. + * src/cff/t2objs.c: Renamed and updated to... + * src/cff/cffobjs.c: New file. + * src/cff/t2objs.h: Renamed and updated to... + * src/cff/cffobjs.h: New file. + * src/cff/t2parse.c: Renamed and updated to... + * src/cff/cffparse.c: New file. + * src/cff/t2parse.h: Renamed and updated to... + * src/cff/cffparse.h: New file. + * src/cff/t2tokens.h: Renamed and updated to... + * src/cff/cfftoken.h: New file. + + * src/cff/cff.c, src/cff/rules.mk: Updated. + +2000-12-06 David Turner + + * src/cache/ftlru.c (FT_Lru_Done): Fixed memory leak. + +2000-12-06 Werner Lemberg + + * builds/module.mk: Replaced `xxx #' with `xxx$(space). + * builds/os2/detekt.mk, builds/win32/detekt.mk: Moved comment to + avoid trailing spaces in variable. + * builds/freetype.mk: Use $(D) instead of $D to make statement more + readable. + + * docs/docmaker.py: Formatting. + +2000-12-05 David Turner + + * src/psaux/psauxmod.c: Fixed a broken inclusion of component + header files (an FT_FLAT_COMPILE test was missing). + + * src/cache/ftcmanag.c (FTC_Manager_Done): Fixed a bug that caused + an occasional crash when the function was called (due to a dangling + pointer). + + * src/base/ftsystem.c (FT_Done_Memory): Fixed an obvious bug: + The ANSI "free()" function was called instead of "memory->free()". + + * docs/docmaker.py: Added section filtering, multi-page generation + (index page generation is still missing though). + +2000-12-04 David Turner + + * builds/unix/install.mk, builds/unix/ft2unix.h: The file "ft2unix.h" + is now installed as for Unix systems. Note that we + still use the "freetype2/freetype" installation path for now. + + * */*.[ch]: Now using as the default build and setup + configuration file in all public headers. Internal source files + still need some changes though. + + * builds/devel/ft2build.h, builds/devel/ftoption.h: Created a new + directory to hold all development options for both the Unix and + Win32 developer builds. + + * builds/win32/detect.mk, builds/win32/w32-bccd.mk, + builds/win32/w32-dev.mk: Changed the developer build targets to + "devel-gcc" and "devel-bcc" in order to be able to develop with the + Borland C++ compiler. + +2000-12-01 David Turner + + + * Version 2.0.1 released. + ========================= + + + * builds/unix/configure.in, builds/unix/configure, + builds/cygwin/configure.in, builds/cygwin/configure: Setting + "version_info" to 6:1:0 for the 2.0.1 release. + + * CHANGES: Added a summary of changes between 2.0.1 and 2.0. + + * builds/unix/ftconfig.in, builds/cygwin/ftconfig.in: Changes + to allow compilation under Unix with the Unix-specific config + files. + +2000-12-01 Werner Lemberg + + * INSTALL: Revised. + * builds/compiler/bcc-dev.mk, builds/compiler/visualage.mk, + builds/compiler/bcc.mk, builds/win32/w32-bcc.mk, + builds/win32/w32-bccd.mk: Revised. + * include/freetype/config/ftbuild.h, + include/freetype/internal/internal.h: Revised. + * include/freetype/ftimage.h: Updated to new header inclusion scheme. + +2000-11-30 Werner Lemberg + + * builds/toplevel.mk (.PHONY): Adding `distclean'. + * builds/unix/detect.mk (.PHONY): Adding `devel', `unix', `lcc', + `setup'. + +2000-11-30 David Turner + + * INSTALL: Slightly updated the quick starter documentation to + include IDE compilation, prevent against BSD Make, and specify "make + setup" instead of a single "make" for build configuration. + + * include/config/ftbuild.h, include/internal/internal.h: Added new + configuration files used to determine the location of all public, + configuration, and internal header files for FreeType 2. Modified + all headers under "include/freetype" to reflect this change. Note + that we still need to change the library source files themselves + though. + + * builds/compiler/bcc.mk, builds/compiler/bcc-dev.mk, + builds/win32/w32-bcc.mk, builds/win32/w32-bccd.mk, + builds/win32/detect.mk: Added new files to support compilation with + the free Borland C++ command-line compiler. Modified the detection + rules to recognize the new "bcc32" target in "make setup bcc32". + + * src/sfnt/ttcmap.c, src/sfnt/ttpost.c, src/sfnt/ttsbit.c, + src/truetype/ttobjs.c, src/truetype/ttgload.c, + src/truetype/ttinterp.c: Fixed a few comparisons that Borland C++ + didn't really like. Basically, this compiler complains when FT_UInt + is compared to FT_UShort (apparently, it promotes `UShort' to `Int' + in these cases). + +2000-11-30 Tom Kacvinsky + + * t2objs.c (T2_Init_Face): Added calculation of `face->height' for + pure CFF fonts. + + * t1objs.c (T1_Init_Face): Fixed computation of `face->height'. + +2000-11-29 David Turner + + * src/base/ftbbox.c (BBox_Conic_Check): Fixed a really stupid + bug in the formula used to compute the conic Bézier extrema + of non-monotonous arcs. + +2000-11-29 Werner Lemberg + + * src/base/ftcalc.c (FT_SqrtFixed), src/base/ftobjs.c + (FT_Set_Renderer): Use FT_EXPORT_DEF. + * src/cache/ftcimage.c (FTC_Image_Cache_Lookup), + src/cache/ftcmanag.c (FTC_Manager_Done, FTC_Manager_Reset, + FTC_Manager_Lookup_Face, FTC_Manager_Lookup_Size, + FTC_Manager_Register_Cache), src/cache/ftcsbits.c + (FTC_SBit_Cache_Lookup): Ditto. + + * src/include/freetype/cache/ftcglyph.h (FTC_GlyphNode_Init), + src/include/freetype/ftmac.h (FT_New_Face_From_FOND): Use FT_EXPORT. + +2000-11-29 Werner Lemberg + + * src/sfnt/sfdriver.c: Include ttsbit.h and ttpost.h only + conditionally. + + * src/truetype/ttdriver.c (Set_Char_Sizes, Set_Pixel_Sizes): Set + `size->strike_index' only conditionally. + + * src/type1/t1driver.c, src/type1/t1objs.c: Include t1afm.h only + conditionally. + + * src/winfonts/winfnt.h: Move all type definitions to... + * src/include/freetype/internal/fnttypes.h: New file. + * src/winfonts/winfnt.c: Use it. + +2000-11-29 ??? ??? + + * include/freetype/internal/ftdebug.h: Replaced FT_CAT and FT_XCAT + with a direct solution (which also satifies picky compilers). + +2000-11-28 YAMANO-UCHI Hidetoshi + + * src/truetype/ttobjs.c (TT_Init_Size): Fix #ifdef's to work with + disabled interpreter also. + + * src/base/ftnames.c (FT_Get_Sfnt_Name_Count): Fix incorrect + parentheses. + +2000-11-26 Tom Kacvinsky + + * src/cff/t2gload.c (T2_Parse_CharStrings): Added logic to glyph + width setting code to take into account even/odd argument counts + and glyph width operand before endchar/hmoveto/vmoveto. + +2000-11-26 Werner Lemberg + + * builds/ansi/ansi.mk: Fix inclusion order of files. + +2000-11-26 Keith Packard + + * src/type1/t1objs.c (T1_Init_Face): Compute style flags. + +2000-11-26 Werner Lemberg + + * builds/compiler/ansi-cc.mk (CLEAN_LIBRARY): Fix rule and + conditional. + +2000-11-23 Werner Lemberg + + * src/type1/t1load.c (parse_subrs, parse_charstrings): Use decrypt + function from PSAux module. + + * src/type1/t1parse.c (T1_Done_Parse): Renamed to... + (T1_Finalize_Parser): New function (to avoid name clash with a + function in the PSAux module). + (T1_Decrypt): Removed since it is duplicated in the PSAux module. + (T1_Get_Private_Dict): Added `psaux' as new parameter; use decrypt + function from PSAux module. + + * src/type1/t1parse.h: Adapted. + +2000-11-22 Tom Kacvinsky + + * src/cff/t2objs.c (T2_Init_Face): For pure CFF fonts, set + `root->num_faces' to `cff->num_faces' and set `units_per_EM' + to 1000. + + * src/cff/t2parse.c (parse_t2_real): Fixed real number parsing + loop. + + * src/cff/t2load.c (T2_Get_String): Called T2_Get_Name with a + sid that was off by one. + +2000-11-16 David Turner + + * src/autohint/ahtypes.h (AH_Hinter): Added new fields to control + auto-hinting of synthetic Type 1 fonts. + + * src/autohint/ahhint.c (ah_hinter_load, ah_hinter_load_glyph): + Added auto-hinting support of synthetic Type 1 fonts. + +2000-11-12 Tom Kacvinsky + + * src/sfnt/ttload.c (TT_LookUp_Table, TT_Load_Generic_Table): Change + tracing output. + + * src/sfnt/sfobjs.c (SFNT_Load_Face): Set boolean variable + `has-outline' to true only if the font has a `glyf' or `CFF ' table. + +2000-11-11 Werner Lemberg + + * builds/win32/visualc/freetype.dsp: Fix raster1->raster and + type1z->type1. + +2000-11-11 Tom Kacvinsky + + * builds/unix/freetype-config.in, builds/cygwin/freetype-config.in: + Added a --libtool option. When freetype-config --libtool is + invoked, the absolute path to the libtool convenience library + is returned. + +2000-11-11 Werner Lemberg + + * builds/cygwin/cygwin-def.in: Same fix as previous. + +2000-11-10 Tom Kacvinsky + + * builds/unix/unix-def.in: Add + + INSTALL_PROGRAM := @INSTALL_PROGRAM@ + INSTALL_SCRIPT := @INSTALL_SCRIPT@ + + so that installation of freetype-config does not fail. + +2000-11-10 Werner Lemberg + + * builds/cygwin/freetype-config.in, builds/unix/freetype-config.in: + Move test down for empty --exec-prefix. + Fix --version. + + * builds/cygwin/install.mk, builds/unix/install.mk: Use + $(INSTALL_SCRIPT) for installation of freetype-config. + + * builds/cygwin/install.mk: Fix clean target names. + +2000-11-09 David Turner + + + * Version 2.0 released. + ======================= + + +Local Variables: +version-control: never +coding: latin-1 +End: diff --git a/lib/freetype/Jamfile b/lib/freetype/Jamfile new file mode 100644 index 0000000..3ba645f --- /dev/null +++ b/lib/freetype/Jamfile @@ -0,0 +1,132 @@ +# FreeType 2 top Jamfile (c) 2001-2002 David Turner +# + +# The HDRMACRO is already defined in FTJam and is used to add +# the content of certain macros to the list of included header +# files. +# +# we can compile FreeType 2 with classic Jam however thanks to +# the following code +# +if ! $(JAM_TOOLSET) +{ + rule HDRMACRO + { + # nothing !! + } +} + +# We need to invoke a SubDir rule if the FT2 source directory top is not the +# current directory. This allows us to build FreeType 2 as part of a larger +# project easily. +# +if $(FT2_TOP) != $(DOT) +{ + SubDir FT2_TOP ; +} + +# +# The following macros define the include directory, the source directory +# and the final library name (without library extensions). They can be +# replaced by other definitions when the library is compiled as part of +# a larger project. +# + +# name of FreeType include directory during compilation. +# relative to FT2_TOP +# +FT2_INCLUDE_DIR ?= include ; + +# name of FreeType source directory during compilation. +# relative to FT2_TOP +# +FT2_SRC_DIR ?= src ; + +# name of final library, without extension +# +FT2_LIB ?= $(LIBPREFIX)freetype ; + + +# define FT2_BUILD_INCLUDE to point to your build-specific directory +# this is prepended to FT2_INCLUDE_DIR. This can be used to specify +# the location of a custom which will point to custom +# versions of "ftmodule.h" and "ftoption.h", for example +# +FT2_BUILD_INCLUDE ?= ; + +# the list of modules to compile on any given build of the library +# by default, this will contain _all_ modules defined in FT2_SRC_DIR +# +# IMPORTANT: You'll need to change the content of "ftmodule.h" as well +# if you modify this list or provide your own. +# +FT2_COMPONENTS ?= gzip # support for gzip-compressed files. + autohint # auto-hinter + base # base component (public APIs) + bdf # BDF font driver + cache # cache sub-system + cff # CFF/CEF font driver + cid # Postscript CID-keyed font driver + pcf # PCF font driver + pfr # PFR/TrueDoc font driver + psaux # Common Postscript routines module + pshinter # Postscript hinter module + psnames # Postscript names handling + raster # Monochrome rasterizer + smooth # Anti-aliased rasterizer + sfnt # SFNT-based format support routines + truetype # TrueType font driver + type1 # Postscript Type 1 font driver + type42 # Postscript Type 42 (embedded TrueType) driver + winfonts # Windows FON/FNT font driver + ; + + +# don't touch +# +FT2_INCLUDE = $(FT2_BUILD_INCLUDE) + [ FT2_SubDir $(FT2_INCLUDE_DIR) ] ; + +FT2_SRC = [ FT2_SubDir $(FT2_SRC_DIR) ] ; + +# only used by FreeType developers +# +if $(DEBUG_HINTER) +{ + CCFLAGS += -DDEBUG_HINTER ; +} + + +# We need "freetype2/include" in the current include path in order to +# compile any part of FreeType 2. +# +HDRS += $(FT2_INCLUDE) ; + + +# Uncomment the following line if you want to build individual source files +# for each FreeType 2 module. this is only useful during development, and +# is better defined as an environment variable anyway ! +# +# FT2_MULTI = true ; + +# The file is used to define macros that are +# later used in #include statements. It needs to be parsed in order to +# record these definitions. +# +HDRMACRO [ FT2_SubDir include freetype config ftheader.h ] ; +HDRMACRO [ FT2_SubDir include freetype internal internal.h ] ; + +# Now include the Jamfile in "freetype2/src", used to drive the compilation +# of each FreeType 2 component and/or module. +# +SubInclude FT2_TOP $(FT2_SRC_DIR) ; + + +# tests files (hinter debugging). only used by FreeType developers +# +if $(DEBUG_HINTER) +{ + SubInclude FT2_TOP tests ; +} + +# end of top Jamfile diff --git a/lib/freetype/Jamfile.in b/lib/freetype/Jamfile.in new file mode 100644 index 0000000..2ba53bd --- /dev/null +++ b/lib/freetype/Jamfile.in @@ -0,0 +1,133 @@ +# FreeType 2 top Jamfile (c) 2001-2002 David Turner +# + +# The HDRMACRO is already defined in FTJam and is used to add +# the content of certain macros to the list of included header +# files. +# +# we can compile FreeType 2 with classic Jam however thanks to +# the following code +# +if ! $(JAM_TOOLSET) +{ + rule HDRMACRO + { + # nothing !! + } +} + +# We need to invoke a SubDir rule if the FT2 source directory top is not the +# current directory. This allows us to build FreeType 2 as part of a larger +# project easily. +# +if $(FT2_TOP) != $(DOT) +{ + SubDir FT2_TOP ; +} + +# +# The following macros define the include directory, the source directory +# and the final library name (without library extensions). They can be +# replaced by other definitions when the library is compiled as part of +# a larger project. +# + +# name of FreeType include directory during compilation. +# relative to FT2_TOP +# +FT2_INCLUDE_DIR ?= include ; + +# name of FreeType source directory during compilation. +# relative to FT2_TOP +# +FT2_SRC_DIR ?= src ; + +# name of final library, without extension +# +FT2_LIB ?= $(LIBPREFIX)freetype ; + + +# define FT2_BUILD_INCLUDE to point to your build-specific directory +# this is prepended to FT2_INCLUDE_DIR. This can be used to specify +# the location of a custom which will point to custom +# versions of "ftmodule.h" and "ftoption.h", for example +# +FT2_BUILD_INCLUDE ?= ; + +# the list of modules to compile on any given build of the library +# by default, this will contain _all_ modules defined in FT2_SRC_DIR +# +# IMPORTANT: You'll need to change the content of "ftmodule.h" as well +# if you modify this list or provide your own. +# +FT2_COMPONENTS ?= gzip # support for gzip-compressed files. + autohint # auto-hinter + base # base component (public APIs) + bdf # BDF font driver + cache # cache sub-system + cff # CFF/CEF font driver + cid # Postscript CID-keyed font driver + pcf # PCF font driver + pfr # PFR/TrueDoc font driver + psaux # Common Postscript routines module + pshinter # Postscript hinter module + psnames # Postscript names handling + raster # Monochrome rasterizer + smooth # Anti-aliased rasterizer + sfnt # SFNT-based format support routines + truetype # TrueType font driver + type1 # Postscript Type 1 font driver + type42 # Postscript Type 42 (embedded TrueType) driver + winfonts # Windows FON/FNT font driver + ; + + +# don't touch +# +FT2_INCLUDE = $(FT2_BUILD_INCLUDE) + [ FT2_SubDir $(FT2_INCLUDE_DIR) ] ; + +FT2_SRC = [ FT2_SubDir $(FT2_SRC_DIR) ] ; + +# only used by FreeType developers +# +if $(DEBUG_HINTER) +{ + CCFLAGS += -DDEBUG_HINTER ; +} + + +# We need "freetype2/include" in the current include path in order to +# compile any part of FreeType 2. +# +HDRS += $(FT2_INCLUDE) ; + + +#SubDirHdr += $(FT2_INCLUDE) ; + +# Uncomment the following line if you want to build individual source files +# for each FreeType 2 module. +# +# FT2_MULTI = true ; + +# The file is used to define macros that are +# later used in #include statements. It needs to be parsed in order to +# record these definitions. +# +HDRMACRO [ FT2_SubDir include freetype config ftheader.h ] ; +HDRMACRO [ FT2_SubDir include freetype internal internal.h ] ; + +# Now include the Jamfile in "freetype2/src", used to drive the compilation +# of each FreeType 2 component and/or module. +# +SubInclude FT2_TOP $(FT2_SRC_DIR) ; + + +# tests files (hinter debugging). only used by FreeType developers +# +if $(DEBUG_HINTER) +{ + SubInclude FT2_TOP tests ; +} + +# end of top Jamfile diff --git a/lib/freetype/Jamrules b/lib/freetype/Jamrules new file mode 100644 index 0000000..c05e508 --- /dev/null +++ b/lib/freetype/Jamrules @@ -0,0 +1,61 @@ +# FreeType 2 JamRules (c) 2001 David Turner +# +# This file contains the Jam rules needed to build the FreeType 2 library. +# It is shared by all Jamfiles and is included only once in the build +# process. +# + + +# call SubDirHdrs on a list of directories +# +rule AddSubDirHdrs +{ + local x ; + + for x in $(<) + { + SubDirHdrs $(x) ; + } +} + + +# Determine prefix of library file. We must use "libxxxxx" on Unix systems, +# while all other simply use the real name. +# +if $(UNIX) +{ + LIBPREFIX ?= lib ; +} +else +{ + LIBPREFIX ?= "" ; +} + +# FT2_TOP contains the location of the FreeType source directory. You can +# set it to a specific value if you want to compile the library as part of a +# larger project. +# +FT2_TOP ?= $(DOT) ; + +# Define a new rule used to declare a sub directory of the Nirvana source +# tree. +# +rule FT2_SubDir +{ + if $(FT2_TOP) = $(DOT) + { + return [ FDirName $(<) ] ; + } + else + { + return [ FDirName $(FT2_TOP) $(<) ] ; + } +} + +# We also set ALL_LOCATE_TARGET in order to place all object and library +# files in "objs". +# +ALL_LOCATE_TARGET ?= [ FT2_SubDir objs ] ; + + +# end of Jamrules diff --git a/lib/freetype/Makefile b/lib/freetype/Makefile new file mode 100644 index 0000000..3c06362 --- /dev/null +++ b/lib/freetype/Makefile @@ -0,0 +1,57 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = kmdll + +TARGET_NAME = freetype + +TARGET_NORC = yes + +TARGET_DEFONLY = yes + +include $(PATH_TO_TOP)/config + +ifeq ($(DBG), 1) +CFLAGS_DBG := -g +else +CFLAGS_DBG := +endif + +TARGET_CFLAGS = $(CFLAGS_DBG) -Iinclude -Wall + +ROS_OBJECTS = rosglue.o i386/setjmplongjmp.o + +TARGET_OBJECTS = objs/*.o $(ROS_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +unexport CFLAGS + +all: $(MK_FULLNAME) $(MK_NOSTRIPNAME) + +objs/*.o objs/libfreetype.a: +ifeq ($(DBG), 1) + @$(MAKE) -f Makefile.freetype CFLAGS="-c -g -Wall" CC:=$(CC) +else + @$(MAKE) -f Makefile.freetype CC:=$(CC) +endif + +# Automatic dependency tracking +DEP_OBJECTS := $(ROS_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk + +freetype_def: objs/libfreetype.a + nm objs/libfreetype.a | gawk 'BEGIN { printf "LIBRARY freetype\r\nEXPORTS\r\n"; } 3 == NF && $$2 == "T" { printf "%s\r\n", substr($$3, 2, length($$3) - 2); }' > freetype.def + +.dummy: + +%/TAGS: .dummy + etags $(@D)/\*.c -o $(@D)/TAGS + +etags: TAGS +TAGS: i386/TAGS + +# EOF diff --git a/lib/freetype/Makefile.freetype b/lib/freetype/Makefile.freetype new file mode 100644 index 0000000..e1fbdf2 --- /dev/null +++ b/lib/freetype/Makefile.freetype @@ -0,0 +1,32 @@ +# +# FreeType 2 build system -- top-level Makefile +# + + +# Copyright 1996-2000 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. + + +# Project names +# +PROJECT := freetype +PROJECT_TITLE := FreeType + +USE_MODULES := 1 + +# The variable TOP_DIR holds the path to the topmost directory in the project +# engine source hierarchy. If it is not defined, default it to `.'. +# +ifndef TOP_DIR + TOP_DIR := . +endif + +include $(TOP_DIR)/builds/toplevel.mk + +# EOF diff --git a/lib/freetype/README b/lib/freetype/README new file mode 100644 index 0000000..13445c7 --- /dev/null +++ b/lib/freetype/README @@ -0,0 +1,42 @@ + + Special notes to Unix users + =========================== + + Please read the file "docs/UPGRADE.UNX", it contains important + information regarding the installation of FreeType on Unix systems, + especially GNU based operating systems like GNU/Linux. + + FreeType 2's library is called `libfreetype', FreeType 1's library + is called `libttf'. They are *not* compatible! + + + FreeType 2.1.4 + ============== + + Please read the docs/CHANGES file, it contains IMPORTANT + INFORMATION. + + Read the files "docs/INSTALL" for installation instructions. + + Note that the FreeType 2 documentation is now available as a + separate package from our sites. See: + + ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.4.tar.bz2 + ftp://ftp.freetype.org/pub/freetype2/ftdocs-2.1.4.tar.gz + ftp://ftp.freetype.org/pub/freetype2/ftdoc214.zip + + + Reports + ======= + + Please report bugs by e-mail to `devel@freetype.org'. Don't + forget to send a detailed explanation of the problem -- there is + nothing worse than receiving a terse message that only says "it + doesn't work". + + + + Enjoy! + + + The FreeType Team diff --git a/lib/freetype/README.ROS b/lib/freetype/README.ROS new file mode 100644 index 0000000..8a113a5 --- /dev/null +++ b/lib/freetype/README.ROS @@ -0,0 +1,68 @@ +CREDITS + +The code in this tree is based (it is actually an exact copy with some +ReactOS specific extra files) on the FreeType library, version 2.1.3. +It was written and is being maintained by the FreeType team. The projects +website is http://www.freetype.org. + + +NOTES + +Please note that there are two Makefiles in the freetype directory: +- Makefile.freetype which is the original Makefile from the FreeType + distribution +- Makefile which is the ReactOS specific Makefile. It will use the + original Makefile.freetype when needed. +Normally you will just use Makefile and not worry about Makefile.freetype. +There will also be 2 FreeType libraries, lib/freetype/objs/libfreetype.a +and dk/nkm/lib/freetype.a. The second one is the import library for +freetype.dll and is the one that is used in the rest of ReactOS. +lib/freetype/objs/libfreetype.a is a static library which is used to +create the DLL. + + +PORTING A NEW VERSION + +Please note that the procedure below is a one-time only procedure, to be +performed by whoever imports a new FreeType version into the ReactOS +source tree. Once the new version has been committed to CVS all other +developers can just use the normal build procedure. + +First, save the old version: + +move lib\freetype lib\freetype.old + +Unpack the FreeType distribution and copy the files to lib/freetype +(note: without the version number which is present in the pathnames in +the distribution archive). +Setup the FreeType build by copying the correct configuration file: + +copy lib\freetype\builds\win32\w32-mingw32.mk lib\freetype\config.mk + +Copy the ReactOS specific files from the old directory to the new: + +move lib\freetype\Makefile lib\freetype\Makefile.freetype +mkdir lib\freetype\i386 +copy lib\freetype.old\rosglue.c lib\freetype +copy lib\freetype.old\i386\setjmplongjmp.s lib\freetype\i386 +copy lib\freetype.old\Makefile lib\freetype +copy lib\freetype.old\README.ROS lib\freetype +copy lib\freetype.old\.cvsignore lib\freetype +copy lib\freetype.old\objs\.cvsignore lib\freetype\objs +copy lib\freetype.old\i386\.cvsignore lib\freetype\i386 + +Next you need to create the freetype.def file. Since this depends on the +"gawk" command, you'll need to have MSYS installed, which is not one of +the normally required packages to build ReactOS. You can get MSYS from the +MinGW site at http://sourceforge.net/projects/mingw. Once you have MSYS +installed you can create the new freetype.def file: + +make freetype_def + +Well, that's all there is to it. You can delete the old version in +lib\freetype.old. Please adjust the version number in the heading of this +file, so it is obvious to everyone which FreeType version we're using. +After testing, you can commit the new/changed files to CVS. ALthough files +config.mk and freetype.def are generated, they should be included in CVS. + +$Id$ diff --git a/lib/freetype/builds/amiga/README b/lib/freetype/builds/amiga/README new file mode 100644 index 0000000..1611666 --- /dev/null +++ b/lib/freetype/builds/amiga/README @@ -0,0 +1,90 @@ +The makefile is for ppc-morphos-gcc-2.95.3-bin.tgz (gcc 2.95.3 hosted +on 68k-Amiga producing MorphOS-PPC-binaries from +http://www.morphos.de). To use it, type "make assign", then "make"; +it produces a link library libft2_ppc.a. + +The smakefile is a makefile for Amiga SAS/C 6.58 (no longer available, +latest sold version was 6.50, updates can be found in Aminet). It is +based on the version found in the sourcecode of ttf.library 0.83b for +FreeType 1.3.1 from Richard Griffith (ragriffi@sprynet.com, +http://ragriffi.home.sprynet.com). + +You will also need the latest include files and amiga.lib from the +Amiga web site (http://www.amiga.com/3.9/download/NDK3.9.lha) for +AmigaOS 3.9; the generated code should work under AmigaOS 2.04 and up. + +To use it, call "smake assign" and then "smake" from the builds/amiga +directory. The results are: + +- A link library "ft2_680x0.lib" (where x depends on the setting of + the CPU entry in the smakefile) containing all FreeType2 parts + except of the init code, debugging code, and the system interface + code. + +- ftsystem.o, an object module containing the standard version of the + system interface code which uses fopen() fclose() fread() fseek() + ftell() malloc() realloc() and free() from lib:sc.lib (not pure). + +- ftsystempure.o, an object module containing the pure version of the + system interface code which uses Open() Close() Read() Seek() + ExamineFH() AsmAllocPooled() AsmFreePooled() etc. This version can + be used in both normal programs and in Amiga run-time shared system + librarys (can be linked with lib:libinit.o, no copying of DATA and + BSS hunks for each OpenLibrary() necessary). Source code is in + src/base/ftsystem.c. + +- ftdebug.o, an object module containing the standard version of the + debugging code which uses vprintf() and exit() (not pure). + Debugging can be turned on in FT:include/freetype/config/ftoption.h + and with FT_SetTraceLevel(). + +- ftdebugpure.o, an object module containing the pure version of the + debugging code which uses KVPrintf() from lib:debug.lib and no + exit(). For debugging of Amiga run-time shared system libraries. + Source code is in src/base/ftdebug.c. + +- NO ftinit.o. Since linking with a link library should result in + linking only the needed object modules in it, but standard + ftsystem.o would force ALL FreeType2 modules to be linked to your + program, I decided to use a different scheme: You must #include + FT:src/base/ftinit.c in your sourcecode and specify with #define + statements which modules you need. See + include/freetype/config/ftmodule.h. + + +To use in your own programs: + +- Insert the #define and #include statements from top of + include/freetype/config/ftmodule.h in your source code and uncomment + the #define statements for the FreeType2 modules you need. + +- You can use either PARAMETERS=REGISTER or PARAMETERS=STACK for + calling the FreeType2 functions, since the link library and the + object files are compiled with PARAMETERS=BOTH. + +- "smake assign" (assign "FT:" to the FreeType2 main directory). + +- Compile your program. + +- Link with either ftsystem.o or ftsystempure.o, if debugging enabled + with either ftdebug.o or (ftdebugpure.o and lib:debug.lib), and with + ft2_680x0.lib as link library. + + +To adapt to other compilers: + +- The standard ANSI C maximum length of 31 significant characters in + identifiers is not enough for FreeType2. Check if your compiler has + a minimum length of 40 significant characters or can be switched to + it. "idlen=40" is the option for SAS/C. Setting #define + HAVE_LIMIT_ON_IDENTS in an include file may also work (not tested). + +- Make sure that the include directory in builds/amiga is searched + before the normal FreeType2 include directory, so you are able to + replace problematic include files with your own version (same may be + useful for the src directory). + +- An example of how to replace/workaround a problematic include file + is include/config/ftconfig.h; it changes a #define that would + prevent SAS/C from generating XDEF's where it should do that and + then includes the standard FreeType2 include file. diff --git a/lib/freetype/builds/amiga/include/freetype/config/ftconfig.h b/lib/freetype/builds/amiga/include/freetype/config/ftconfig.h new file mode 100644 index 0000000..9c6ff45 --- /dev/null +++ b/lib/freetype/builds/amiga/include/freetype/config/ftconfig.h @@ -0,0 +1,20 @@ +// TetiSoft: We must change FT_BASE_DEF and FT_EXPORT_DEF + +//#define FT_BASE_DEF( x ) extern x // SAS/C wouldn't generate an XDEF +//#define FT_EXPORT_DEF( x ) extern x // SAS/C wouldn't generate an XDEF +#undef FT_BASE_DEF +#define FT_BASE_DEF( x ) x +#undef FT_EXPORT_DEF +#define FT_EXPORT_DEF( x ) x + +// TetiSoft: now include original file +#ifndef __MORPHOS__ +#include "FT:include/freetype/config/ftconfig.h" +#else +// We must define that, it seems that +// lib/gcc-lib/ppc-morphos/2.95.3/include/syslimits.h is missing in +// ppc-morphos-gcc-2.95.3-bin.tgz (gcc for 68k producing MorphOS PPC elf +// binaries from http://www.morphos.de) +#define _LIBC_LIMITS_H_ +#include "/FT/include/freetype/config/ftconfig.h" +#endif diff --git a/lib/freetype/builds/amiga/include/freetype/config/ftmodule.h b/lib/freetype/builds/amiga/include/freetype/config/ftmodule.h new file mode 100644 index 0000000..d7bc9cb --- /dev/null +++ b/lib/freetype/builds/amiga/include/freetype/config/ftmodule.h @@ -0,0 +1,123 @@ +// TetiSoft: To specify which modules you need, +// insert the following in your source file and uncomment as needed: + +/* +//#define FT_USE_AUTOHINT // autohinter +//#define FT_USE_RASTER // monochrome rasterizer +//#define FT_USE_SMOOTH // anti-aliasing rasterizer +//#define FT_USE_TT // truetype font driver +//#define FT_USE_T1 // type1 font driver +//#define FT_USE_T42 // type42 font driver +//#define FT_USE_T1CID // cid-keyed type1 font driver // no cmap support +//#define FT_USE_CFF // opentype font driver +//#define FT_USE_BDF // bdf bitmap font driver +//#define FT_USE_PCF // pcf bitmap font driver +//#define FT_USE_PFR // pfr font driver +//#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver +#include "FT:src/base/ftinit.c" +*/ + +// TetiSoft: make sure that needed support modules are built in. +// Dependencies can be found by searching for FT_Get_Module. + +#ifdef FT_USE_T42 +#define FT_USE_TT +#endif + +#ifdef FT_USE_TT +#define FT_USE_SFNT +#endif + +#ifdef FT_USE_CFF +#define FT_USE_SFNT +#define FT_USE_PSHINT +#define FT_USE_PSNAMES +#endif + +#ifdef FT_USE_T1 +#define FT_USE_PSAUX +#define FT_USE_PSHINT +#define FT_USE_PSNAMES +#endif + +#ifdef FT_USE_T1CID +#define FT_USE_PSAUX +#define FT_USE_PSHINT +#define FT_USE_PSNAMES +#endif + +#ifdef FT_USE_PSAUX +#define FT_USE_PSNAMES +#endif + +#ifdef FT_USE_SFNT +#define FT_USE_PSNAMES +#endif + +// TetiSoft: Now include the modules + +#ifdef FT_USE_AUTOHINT +FT_USE_MODULE(autohint_module_class) +#endif + +#ifdef FT_USE_PSHINT +FT_USE_MODULE(pshinter_module_class) +#endif + +#ifdef FT_USE_CFF +FT_USE_MODULE(cff_driver_class) +#endif + +#ifdef FT_USE_T1CID +FT_USE_MODULE(t1cid_driver_class) +#endif + +#ifdef FT_USE_BDF +FT_USE_MODULE(bdf_driver_class) +#endif + +#ifdef FT_USE_PCF +FT_USE_MODULE(pcf_driver_class) +#endif + +#ifdef FT_USE_PFR +FT_USE_MODULE(pfr_driver_class) +#endif + +#ifdef FT_USE_PSAUX +FT_USE_MODULE(psaux_module_class) +#endif + +#ifdef FT_USE_PSNAMES +FT_USE_MODULE(psnames_module_class) +#endif + +#ifdef FT_USE_RASTER +FT_USE_MODULE(ft_raster1_renderer_class) +#endif + +#ifdef FT_USE_SFNT +FT_USE_MODULE(sfnt_module_class) +#endif + +#ifdef FT_USE_SMOOTH +FT_USE_MODULE(ft_smooth_renderer_class) +FT_USE_MODULE(ft_smooth_lcd_renderer_class) +FT_USE_MODULE(ft_smooth_lcdv_renderer_class) +#endif + +#ifdef FT_USE_TT +FT_USE_MODULE(tt_driver_class) +#endif + +#ifdef FT_USE_T1 +FT_USE_MODULE(t1_driver_class) +#endif + +#ifdef FT_USE_T42 +FT_USE_MODULE(t42_driver_class) +#endif + +#ifdef FT_USE_WINFNT +FT_USE_MODULE(winfnt_driver_class) +#endif diff --git a/lib/freetype/builds/amiga/makefile b/lib/freetype/builds/amiga/makefile new file mode 100644 index 0000000..db77330 --- /dev/null +++ b/lib/freetype/builds/amiga/makefile @@ -0,0 +1,207 @@ +# +# Makefile for FreeType2 link library using ppc-morphos-gcc-2.95.3-bin.tgz +# (gcc 2.95.3 hosted on 68k-Amiga producing MorphOS-PPC-binaries from +# http://www.morphos.de) +# +# to build from the builds/amiga directory call +# +# make assign +# make +# +# Your programs source code should start with this +# (uncomment the parts you do not need to keep the program small): +# ---8<--- +#define FT_USE_AUTOHINT // autohinter +#define FT_USE_RASTER // monochrome rasterizer +#define FT_USE_SMOOTH // anti-aliasing rasterizer +#define FT_USE_TT // truetype font driver +#define FT_USE_T1 // type1 font driver +#define FT_USE_T42 // type42 font driver +#define FT_USE_T1CID // cid-keyed type1 font driver +#define FT_USE_CFF // opentype font driver +#define FT_USE_BDF // bdf bitmap font driver +#define FT_USE_PCF // pcf bitmap font driver +#define FT_USE_PFR // pfr font driver +#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver +#include "FT:src/base/ftinit.c" +# ---8<--- +# +# link your programs with libft2_ppc.a and either ftsystem.ppc.o or ftsystempure.ppc.o +# (and either ftdebug.ppc.o or ftdebugpure.ppc.o if you enabled FT_DEBUG_LEVEL_ERROR or +# FT_DEBUG_LEVEL_TRACE in include/freetype/config/ftoption.h). + +all: libft2_ppc.a ftsystem.ppc.o ftsystempure.ppc.o + +assign: + assign FT: // + +FTSRC = /FT/src + +CC = ppc-morphos-gcc +AR = ppc-morphos-ar rc +RANLIB = ppc-morphos-ranlib +LD = ppc-morphos-ld +CFLAGS = -O2 -I/emu/emulinclude/includegcc -I/emu/include -Iinclude -I$(FTSRC) -I/FT/include + +# +# FreeType2 library base +# +ftbase.ppc.o: $(FTSRC)/base/ftbase.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftinit.ppc.o: $(FTSRC)/base/ftinit.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftsystem.ppc.o: $(FTSRC)/base/ftsystem.c + $(CC) -c $(CFLAGS) -o $@ $< + +# pure version for use in run-time library etc +ftsystempure.ppc.o: src/base/ftsystem.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftdebug.ppc.o: $(FTSRC)/base/ftdebug.c + $(CC) -c $(CFLAGS) -o $@ $< + +# pure version for use in run-time library etc +ftdebugpure.ppc.o: src/base/ftdebug.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library base extensions +# +ftglyph.ppc.o: $(FTSRC)/base/ftglyph.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftbbox.ppc.o: $(FTSRC)/base/ftbbox.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftmm.ppc.o: $(FTSRC)/base/ftmm.c + $(CC) -c $(CFLAGS) -o $@ $< + +ftsynth.ppc.o: $(FTSRC)/base/ftsynth.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library autohinting module +# +autohint.ppc.o: $(FTSRC)/autohint/autohint.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library autohinting module extensions +# +ahoptim.ppc.o: $(FTSRC)/autohint/ahoptim.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library postscript hinting module +# +pshinter.ppc.o: $(FTSRC)/pshinter/pshinter.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library PS support module +# +psaux.ppc.o: $(FTSRC)/psaux/psaux.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library PS glyph names module +# +psnames.ppc.o: $(FTSRC)/psnames/psnames.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library monochrome raster module +# +raster.ppc.o: $(FTSRC)/raster/raster.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library anti-aliasing raster module +# +smooth.ppc.o: $(FTSRC)/smooth/smooth.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library 'sfnt' module +# +sfnt.ppc.o: $(FTSRC)/sfnt/sfnt.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library glyph and image caching system (still experimental) +# +ftcache.ppc.o: $(FTSRC)/cache/ftcache.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library OpenType font driver +# +cff.ppc.o: $(FTSRC)/cff/cff.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library TrueType font driver +# +truetype.ppc.o: $(FTSRC)/truetype/truetype.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library Type1 font driver +# +type1.ppc.o: $(FTSRC)/type1/type1.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library Type42 font driver +# +type42.ppc.o: $(FTSRC)/type42/type42.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library CID-keyed Type1 font driver +# +type1cid.ppc.o: $(FTSRC)/cid/type1cid.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library BDF bitmap font driver +# +bdf.ppc.o: $(FTSRC)/bdf/bdf.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library PCF bitmap font driver +# +pcf.ppc.o: $(FTSRC)/pcf/pcf.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library PFR font driver +# +pfr.ppc.o: $(FTSRC)/pfr/pfr.c + $(CC) -c $(CFLAGS) -o $@ $< + +# +# FreeType2 library Windows FNT/FON bitmap font driver +# +winfnt.ppc.o: $(FTSRC)/winfonts/winfnt.c + $(CC) -c $(CFLAGS) -o $@ $< + +BASEPPC = ftbase.ppc.o ftglyph.ppc.o ftbbox.ppc.o ftmm.ppc.o ftsynth.ppc.o + +DEBUGPPC = ftdebug.ppc.o ftdebugpure.ppc.o + +AHINTPPC = autohint.ppc.o ahoptim.ppc.o + +PSPPC = psaux.ppc.o psnames.ppc.o pshinter.ppc.o + +RASTERPPC = raster.ppc.o smooth.ppc.o + +FONTDPPC = cff.ppc.o type1.ppc.o type42.ppc.o type1cid.ppc.o truetype.ppc.o\ + bdf.ppc.o pcf.ppc.o pfr.ppc.o winfnt.ppc.o + +libft2_ppc.a: $(BASEPPC) $(AHINTPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) + $(AR) $@ $(BASEPPC) $(AHINTPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 diff --git a/lib/freetype/builds/amiga/smakefile b/lib/freetype/builds/amiga/smakefile new file mode 100644 index 0000000..c8b3e6c --- /dev/null +++ b/lib/freetype/builds/amiga/smakefile @@ -0,0 +1,236 @@ +# +# Makefile for FreeType2 link library using Amiga SAS/C 6.58 +# +# to build from the builds/amiga directory call +# +# smake assign +# smake +# +# Your programs source code should start with this +# (uncomment the parts you do not need to keep the program small): +# ---8<--- +#define FT_USE_AUTOHINT // autohinter +#define FT_USE_RASTER // monochrome rasterizer +#define FT_USE_SMOOTH // anti-aliasing rasterizer +#define FT_USE_TT // truetype font driver +#define FT_USE_T1 // type1 font driver +#define FT_USE_T42 // type42 font driver +#define FT_USE_T1CID // cid-keyed type1 font driver +#define FT_USE_CFF // opentype font driver +#define FT_USE_BDF // bdf bitmap font driver +#define FT_USE_PCF // pcf bitmap font driver +#define FT_USE_PFR // pfr font driver +#define FT_USE_WINFNT // windows .fnt|.fon bitmap font driver +#include "FT:src/base/ftinit.c" +# ---8<--- +# +# link your programs with ft2_680x0.lib and either ftsystem.o or ftsystempure.o +# (and either ftdebug.o or ftdebugpure.o if you enabled FT_DEBUG_LEVEL_ERROR or +# FT_DEBUG_LEVEL_TRACE in include/freetype/config/ftoption.h). + +OBJBASE = ftbase.o ftglyph.o ftbbox.o ftmm.o ftsynth.o + +OBJSYSTEM = ftsystem.o ftsystempure.o + +OBJDEBUG = ftdebug.o ftdebugpure.o + +OBJAHINT = autohint.o ahoptim.o + +OBJPSHINT = pshinter.o + +OBJPSAUX = psaux.o + +OBJPSNAM = psnames.o + +OBJRAST = raster.o + +OBJSMOOTH = smooth.o + +OBJSFNT = sfnt.o + +OBJCACHE = ftcache.o + +OBJPS = $(OBJPSAUX) $(OBJPSNAM) $(OBJPSHINT) + +OBJRASTER = $(OBJRAST) $(OBJSMOOTH) + +OBJFONTD = cff.o type1.o type42.o type1cid.o\ + truetype.o winfnt.o bdf.o pcf.o pfr.o + +CORE = FT:src/ + +CPU = 68000 +#CPU = 68020 +#CPU = 68030 +#CPU = 68040 +#CPU = 68060 + +OPTIMIZER = optinlocal + +SCFLAGS = optimize opttime optsched strmerge strsect=near idlen=40 cpu=$(CPU)\ + idir=include/ idir=$(CORE) idir=FT:include/ nostackcheck nochkabort\ + noicons ignore=79,85,110,306 parameters=both + +LIB = ft2_$(CPU).lib + +# sample linker options +OPTS = link lib=$(LIB),lib:sc.lib,lib:amiga.lib,lib:debug.lib\ + smallcode smalldata noicons utillib + +# sample program entry +#myprog: myprog.c ftsystem.o $(LIB) +# sc $< programname=$@ ftsystem.o $(SCFLAGS) $(OPTS) + +all: $(LIB) $(OBJSYSTEM) $(OBJDEBUG) + +assign: + assign FT: // + +# uses separate object modules in lib to make for easier debugging +# also, can make smaller programs if entire engine is not used +ft2_$(CPU).lib: $(OBJBASE) $(OBJAHINT) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) + oml $@ r $(OBJBASE) $(OBJAHINT) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) + +clean: + -delete \#?.o + +realclean: clean + -delete ft2$(CPU).lib + +# +# freetype library base +# +ftbase.o: $(CORE)base/ftbase.c + sc $(SCFLAGS) objname=$@ $< +ftinit.o: $(CORE)base/ftinit.c + sc $(SCFLAGS) objname=$@ $< +ftsystem.o: $(CORE)base/ftsystem.c + sc $(SCFLAGS) objname=$@ $< +ftsystempure.o: src/base/ftsystem.c ## pure version for use in run-time library etc + sc $(SCFLAGS) objname=$@ $< +ftdebug.o: $(CORE)base/ftdebug.c + sc $(SCFLAGS) objname=$@ $< +ftdebugpure.o: src/base/ftdebug.c ## pure version for use in run-time library etc + sc $(SCFLAGS) objname=$@ $< +# +# freetype library base extensions +# +ftglyph.o: $(CORE)base/ftglyph.c + sc $(SCFLAGS) objname=$@ $< +ftbbox.o: $(CORE)base/ftbbox.c + sc $(SCFLAGS) objname=$@ $< +ftmm.o: $(CORE)base/ftmm.c + sc $(SCFLAGS) objname=$@ $< +ftsynth.o: $(CORE)base/ftsynth.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library autohinting module +# +autohint.o: $(CORE)autohint/autohint.c + sc $(SCFLAGS) objname=$@ $< +# +# freetype library autohinting module extensions +# +ahoptim.o: $(CORE)autohint/ahoptim.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library PS hinting module +# +pshinter.o: $(CORE)pshinter/pshinter.c + sc $(SCFLAGS) objname=$@ $< +# +# freetype library PS support module +# +psaux.o: $(CORE)psaux/psaux.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library PS glyph names module +# +psnames.o: $(CORE)psnames/psnames.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library monochrome raster module +# +raster.o: $(CORE)raster/raster.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library anti-aliasing raster module +# +smooth.o: $(CORE)smooth/smooth.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library 'sfnt' module +# +sfnt.o: $(CORE)sfnt/sfnt.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library glyph and image caching system (still experimental) +# +ftcache.o: $(CORE)cache/ftcache.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library OpenType font driver +# +cff.o: $(CORE)cff/cff.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library TrueType font driver +# +truetype.o: $(CORE)truetype/truetype.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library Type1 font driver +# +type1.o: $(CORE)type1/type1.c + sc $(SCFLAGS) objname=$@ $< + +# +# FreeType2 library Type42 font driver +# +type42.o: $(CORE)type42/type42.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library CID-keyed Type1 font driver +# +type1cid.o: $(CORE)cid/type1cid.c + sc $(SCFLAGS) objname=$@ $< +# +# freetype library CID-keyed Type1 font driver extensions +# +#cidafm.o: $(CORE)cid/cidafm.c +# sc $(SCFLAGS) objname=$@ $< + +# +# freetype library BDF bitmap font driver +# +bdf.o: $(CORE)bdf/bdf.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library PCF bitmap font driver +# +pcf.o: $(CORE)pcf/pcf.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library PFR font driver +# +pfr.o: $(CORE)pfr/pfr.c + sc $(SCFLAGS) objname=$@ $< + +# +# freetype library Windows FNT/FON bitmap font driver +# +winfnt.o: $(CORE)winfonts/winfnt.c + sc $(SCFLAGS) objname=$@ $< diff --git a/lib/freetype/builds/amiga/src/base/ftdebug.c b/lib/freetype/builds/amiga/src/base/ftdebug.c new file mode 100644 index 0000000..a618687 --- /dev/null +++ b/lib/freetype/builds/amiga/src/base/ftdebug.c @@ -0,0 +1,185 @@ +// TetiSoft: replaced vprintf() with KVPrintF() and commented out exit() +extern void __stdargs KVPrintF( const char *formatString, const void *values ); + +/***************************************************************************/ +/* */ +/* ftdebug.c */ +/* */ +/* Debugging and logging component (body). */ +/* */ +/* Copyright 1996-2001 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). */ + /* */ + /* - error mode */ + /* */ + /* Only error messages are generated. */ + /* */ + /* - release mode: */ + /* */ + /* No error message is sent or generated. The code is free from any */ + /* debugging parts. */ + /* */ + /*************************************************************************/ + + +#include +#include FT_INTERNAL_DEBUG_H + + +#ifdef FT_DEBUG_LEVEL_TRACE + char ft_trace_levels[trace_max]; +#endif + + +#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE ) + + +#include +#include + + + FT_EXPORT_DEF( void ) + FT_Message( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); +// vprintf( fmt, ap ); + KVPrintF( fmt, ap ); + va_end( ap ); + } + + + FT_EXPORT_DEF( void ) + FT_Panic( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); +// vprintf( fmt, ap ); + KVPrintF( fmt, ap ); + va_end( ap ); + +// exit( EXIT_FAILURE ); + } + + + + /* since I don't know wether "getenv" is available on the Amiga */ + /* I prefer to simply disable this code for now in all builds */ + /* */ + +/* #ifdef FT_DEBUG_LEVEL_TRACE */ +#if 0 + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + const char* ft2_debug = getenv( "FT2_DEBUG" ); + + + if ( ft2_debug ) + { + const char* p = ft2_debug; + const char* q; + + + for ( ; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) + continue; + + /* read toggle name, followed by '=' */ + q = p; + while ( *p && *p != ':' ) + p++; + + if ( *p == ':' && p > q ) + { + int n, i, len = p - q; + int level = -1, found = -1; + + + for ( n = 0; n < trace_count; n++ ) + { + const char* toggle = ft_trace_toggles[n]; + + + for ( i = 0; i < len; i++ ) + { + if ( toggle[i] != q[i] ) + break; + } + + if ( i == len && toggle[i] == 0 ) + { + found = n; + break; + } + } + + /* read level */ + p++; + if ( *p ) + { + level = *p++ - '0'; + if ( level < 0 || level > 6 ) + level = -1; + } + + if ( found >= 0 && level >= 0 ) + { + if ( found == trace_any ) + { + /* special case for "any" */ + for ( n = 0; n < trace_count; n++ ) + ft_trace_levels[n] = level; + } + else + ft_trace_levels[found] = level; + } + } + } + } + } + + +#else /* !FT_DEBUG_LEVEL_TRACE */ + + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + /* nothing */ + } + + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +/* END */ diff --git a/lib/freetype/builds/amiga/src/base/ftsystem.c b/lib/freetype/builds/amiga/src/base/ftsystem.c new file mode 100644 index 0000000..e76d416 --- /dev/null +++ b/lib/freetype/builds/amiga/src/base/ftsystem.c @@ -0,0 +1,450 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* Amiga-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 contains the Amiga interface used by FreeType to access */ + /* low-level, i.e. memory management, i/o access as well as thread */ + /* synchronisation. */ + /* */ + /*************************************************************************/ + + +// Maintained by Detlef Würkner + +// TetiSoft: Modified to avoid fopen() fclose() fread() fseek() ftell() +// malloc() realloc() and free() which can't be used in an amiga +// shared run-time library linked with libinit.o + +#include + +#ifdef __GNUC__ +// Avoid warnings "struct X declared inside parameter list" +#include +#include +#include +#include +#endif + +// Necessary with OS3.9 includes +#define __USE_SYSBASE + +#include +#include + +#ifndef __GNUC__ +/* TetiSoft: Missing in alib_protos.h, see amiga.lib autodoc + * (These amiga.lib functions work under AmigaOS V33 and up) + */ +extern APTR __asm +AsmCreatePool( register __d0 ULONG memFlags, + register __d1 ULONG puddleSize, + register __d2 ULONG threshSize, + register __a6 struct ExecBase* SysBase ); + +extern VOID __asm +AsmDeletePool( register __a0 APTR poolHeader, + register __a6 struct ExecBase* SysBase ); + +extern APTR __asm +AsmAllocPooled( register __a0 APTR poolHeader, + register __d0 ULONG memSize, + register __a6 struct ExecBase* SysBase ); + +extern VOID __asm +AsmFreePooled( register __a0 APTR poolHeader, + register __a1 APTR memory, + register __d0 ULONG memSize, + register __a6 struct ExecBase* SysBase); +#endif + + +// TetiSoft: C implementation of AllocVecPooled (see autodoc exec/AllocPooled) +APTR +AllocVecPooled( APTR poolHeader, + ULONG memSize ) +{ + ULONG newSize = memSize + sizeof ( ULONG ); +#ifdef __GNUC__ + ULONG *mem = AllocPooled( poolHeader, newSize ); +#else + ULONG *mem = AsmAllocPooled( poolHeader, newSize, SysBase ); +#endif + + if ( !mem ) + return NULL; + *mem = newSize; + return mem + 1; +} + + +// TetiSoft: C implementation of FreeVecPooled (see autodoc exec/AllocPooled) +void +FreeVecPooled( APTR poolHeader, + APTR memory ) +{ + ULONG *realmem = (ULONG *)memory - 1; + +#ifdef __GNUC__ + FreePooled( poolHeader, realmem, *realmem ); +#else + AsmFreePooled( poolHeader, realmem, *realmem, SysBase ); +#endif +} + + +#include +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + +#include +#include +#include + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* It is not necessary to do any error checking for the */ + /* allocation-related functions. This will be done by the higher level */ + /* routines like FT_Alloc() or FT_Realloc(). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* ft_alloc */ + /* */ + /* */ + /* The memory allocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { +// FT_UNUSED( memory ); + +// return malloc( size ); + return AllocVecPooled( memory->user, size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_realloc */ + /* */ + /* */ + /* The memory reallocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { +// FT_UNUSED( memory ); +// FT_UNUSED( cur_size ); + +// return realloc( block, new_size ); + + void* new_block; + + new_block = AllocVecPooled ( memory->user, new_size ); + if ( new_block != NULL ) + { + CopyMem ( block, new_block, + ( new_size > cur_size ) ? cur_size : new_size ); + FreeVecPooled ( memory->user, block ); + } + return new_block; + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_free */ + /* */ + /* */ + /* The memory release function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { +// FT_UNUSED( memory ); + +// free( block ); + + FreeVecPooled( memory->user, block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +// #define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) +#define STREAM_FILE( stream ) ( (BPTR)stream->descriptor.pointer ) // TetiSoft + + + /*************************************************************************/ + /* */ + /* */ + /* ft_close_stream */ + /* */ + /* */ + /* The function to close a stream. */ + /* */ + /* */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_close_stream( FT_Stream stream ) + { +// fclose( STREAM_FILE( stream ) ); + Close( STREAM_FILE( stream ) ); // TetiSoft + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_io_stream */ + /* */ + /* */ + /* The function to open a stream. */ + /* */ + /* */ + /* stream :: A pointer to the stream object. */ + /* */ + /* offset :: The position in the data stream to start reading. */ + /* */ + /* buffer :: The address of buffer to store the read data. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* */ + /* The number of bytes actually read. */ + /* */ + FT_CALLBACK_DEF( unsigned long ) + ft_io_stream( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { +// FILE* file; + BPTR file; // TetiSoft + + + file = STREAM_FILE( stream ); + +// fseek( file, offset, SEEK_SET ); + Seek( file, offset, OFFSET_BEGINNING ); // TetiSoft + +// return (unsigned long)fread( buffer, 1, count, file ); + return (unsigned long)FRead( file, buffer, 1, count); + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { +// FILE* file; + BPTR file; // TetiSoft + struct FileInfoBlock* fib; // TetiSoft + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + +// file = fopen( filepathname, "rb" ); + file = Open( filepathname, MODE_OLDFILE ); // TetiSoft + if ( !file ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + +// fseek( file, 0, SEEK_END ); +// astream->size = ftell( file ); +// fseek( file, 0, SEEK_SET ); + fib = AllocDosObject( DOS_FIB, NULL ); + if ( !fib ) + { + Close ( file ); + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + if ( !( ExamineFH( file, fib ) ) ) + { + FreeDosObject( DOS_FIB, fib ); + Close ( file ); + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + stream->size = fib->fib_Size; + FreeDosObject( DOS_FIB, fib ); + +// stream->descriptor.pointer = file; + stream->descriptor.pointer = (void *)file; + + stream->pathname.pointer = (char*)filepathname; + stream->pos = 0; + + stream->read = ft_io_stream; + stream->close = ft_close_stream; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + +// memory = (FT_Memory)malloc( sizeof ( *memory ) ); + memory = (FT_Memory)AllocVec( sizeof ( *memory ), MEMF_PUBLIC ); + if ( memory ) + { +// memory->user = 0; +#ifdef __GNUC__ + memory->user = CreatePool( MEMF_PUBLIC, 2048, 2048 ); +#else + memory->user = AsmCreatePool( MEMF_PUBLIC, 2048, 2048, SysBase ); +#endif + if ( memory->user == NULL ) + { + FreeVec( memory ); + memory = NULL; + } + else + { + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + +#ifdef __GNUC__ + DeletePool( memory->user ); +#else + AsmDeletePool( memory->user, SysBase ); +#endif + FreeVec( memory ); + } + + +/* END */ diff --git a/lib/freetype/builds/ansi/ansi-def.mk b/lib/freetype/builds/ansi/ansi-def.mk new file mode 100644 index 0000000..032a7b8 --- /dev/null +++ b/lib/freetype/builds/ansi/ansi-def.mk @@ -0,0 +1,94 @@ +# +# FreeType 2 configuration rules for a `normal' ANSI system +# + + +# Copyright 1996-2000 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 TOP_DIR + TOP_DIR := . +endif + +DELETE := rm -f +SEP := / +HOSTSEP := $(SEP) +BUILD := $(TOP_DIR)/builds/ansi +PLATFORM := ansi + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f $TOP_DIR/Makefile setup [options] +# make -f $TOP_DIR/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(TOP_DIR)$(SEP)objs +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := lib$(PROJECT) + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := + + +# EOF diff --git a/lib/freetype/builds/ansi/ansi.mk b/lib/freetype/builds/ansi/ansi.mk new file mode 100644 index 0000000..739d485 --- /dev/null +++ b/lib/freetype/builds/ansi/ansi.mk @@ -0,0 +1,20 @@ +# +# FreeType 2 configuration rules for a `normal' pseudo ANSI compiler/system +# + + +# Copyright 1996-2000 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 $(TOP_DIR)/builds/ansi/ansi-def.mk +include $(TOP_DIR)/builds/compiler/ansi-cc.mk +include $(TOP_DIR)/builds/link_std.mk + +# EOF diff --git a/lib/freetype/builds/beos/beos-def.mk b/lib/freetype/builds/beos/beos-def.mk new file mode 100644 index 0000000..eb55db9 --- /dev/null +++ b/lib/freetype/builds/beos/beos-def.mk @@ -0,0 +1,96 @@ +# +# FreeType 2 configuration rules for a BeOS system +# +# this is similar to the "ansi-def.mk" file, except for BUILD and PLATFORM +# + + +# Copyright 1996-2000 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 TOP_DIR + TOP_DIR := . +endif + +DELETE := rm -f +SEP := / +HOSTSEP := $(SEP) +BUILD := $(TOP_DIR)/builds/neos +PLATFORM := beos + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f $TOP_DIR/Makefile setup [options] +# make -f $TOP_DIR/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(TOP_DIR)$(SEP)objs +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := lib$(PROJECT) + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := + + +# EOF diff --git a/lib/freetype/builds/beos/beos.mk b/lib/freetype/builds/beos/beos.mk new file mode 100644 index 0000000..1ccf8ce --- /dev/null +++ b/lib/freetype/builds/beos/beos.mk @@ -0,0 +1,19 @@ +# +# FreeType 2 configuration rules for a BeOS system +# + +# Copyright 1996-2000, 2002 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 $(TOP_DIR)/builds/compiler/ansi-cc.mk +include $(TOP_DIR)/builds/beos/beos-def.mk +include $(TOP_DIR)/builds/link_std.mk + +# EOF + diff --git a/lib/freetype/builds/beos/detect.mk b/lib/freetype/builds/beos/detect.mk new file mode 100644 index 0000000..89b3f68 --- /dev/null +++ b/lib/freetype/builds/beos/detect.mk @@ -0,0 +1,41 @@ +# +# FreeType 2 configuration file to detect an BeOS host platform. +# + + +# Copyright 1996-2000 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. + + +.PHONY: setup + + +ifeq ($(PLATFORM),ansi) + + ifdef BE_HOST_CPU + + PLATFORM := beos + + endif # test MACHTYPE beos +endif + +ifeq ($(PLATFORM),beos) + + DELETE := rm -f + SEP := / + HOSTSEP := $(SEP) + BUILD := $(TOP_DIR)/builds/beos + CONFIG_FILE := beos.mk + + setup: std_setup + +endif # test PLATFORM beos + +# EOF + diff --git a/lib/freetype/builds/compiler/ansi-cc.mk b/lib/freetype/builds/compiler/ansi-cc.mk new file mode 100644 index 0000000..0309e39 --- /dev/null +++ b/lib/freetype/builds/compiler/ansi-cc.mk @@ -0,0 +1,81 @@ +# +# FreeType 2 generic pseudo ANSI compiler +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := cc + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := o +SO := o + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := a +SA := a + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +# we assume the compiler is already strictly ANSI +# +ANSIFLAGS := + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +LINK_LIBRARY = $(AR) -r $@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/bcc-dev.mk b/lib/freetype/builds/compiler/bcc-dev.mk new file mode 100644 index 0000000..aa5c369 --- /dev/null +++ b/lib/freetype/builds/compiler/bcc-dev.mk @@ -0,0 +1,80 @@ +# +# FreeType 2 Borland C++-specific with NO OPTIMIZATIONS + DEBUGGING +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := bcc32 + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := + + +# Target flag -- no trailing space. +# +T := -o + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -q -c -y -d -v -Od -w-par -w-ccc -w-rch -w-pro -w-aus +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := -A + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +TARGET_OBJECTS = $(subst $(SEP),\\,$(OBJECTS_LIST)) +LINK_LIBRARY = tlib /u $(subst $(SEP),\\,$@) $(TARGET_OBJECTS:%=+%) + +# EOF diff --git a/lib/freetype/builds/compiler/bcc.mk b/lib/freetype/builds/compiler/bcc.mk new file mode 100644 index 0000000..938ecee --- /dev/null +++ b/lib/freetype/builds/compiler/bcc.mk @@ -0,0 +1,80 @@ +# +# FreeType 2 Borland C++-specific rules +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := bcc32 + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := + + +# Target flag -- no trailing space. +# +T := -o + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c -q -y -d -v -Od -w-par -w-ccc -w-rch -w-pro -w-aus +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := -A + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +TARGET_OBJECTS = $(subst $(SEP),\\,$(OBJECTS_LIST)) +LINK_LIBRARY = tlib /u $(subst $(SEP),\\,$@) $(TARGET_OBJECTS:%=+%) + +# EOF diff --git a/lib/freetype/builds/compiler/gcc-dev.mk b/lib/freetype/builds/compiler/gcc-dev.mk new file mode 100644 index 0000000..76d0ba0 --- /dev/null +++ b/lib/freetype/builds/compiler/gcc-dev.mk @@ -0,0 +1,89 @@ +# +# FreeType 2 gcc-specific with NO OPTIMIZATIONS + DEBUGGING +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := gcc + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := o +SO := o + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := a +SA := a + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c -g -O0 \ + -Wall \ + -W \ + -Wundef \ + -Wshadow \ + -Wpointer-arith \ + -Wwrite-strings \ + -Wstrict-prototypes \ + -Wredundant-decls \ + -Wnested-externs \ + -Wno-long-long +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := -ansi -pedantic + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +LINK_LIBRARY = $(AR) -r $@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/gcc.mk b/lib/freetype/builds/compiler/gcc.mk new file mode 100644 index 0000000..f2c94de --- /dev/null +++ b/lib/freetype/builds/compiler/gcc.mk @@ -0,0 +1,78 @@ +# +# FreeType 2 gcc-specific definitions +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := gcc + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := o +SO := o + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := a +SA := a + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c -g -O6 -Wall +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := -ansi -pedantic + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +LINK_LIBRARY = $(AR) -r $@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/intelc.mk b/lib/freetype/builds/compiler/intelc.mk new file mode 100644 index 0000000..0c3088a --- /dev/null +++ b/lib/freetype/builds/compiler/intelc.mk @@ -0,0 +1,84 @@ +# +# FreeType 2 Intel C/C++ definitions (VC++ compatibility mode) +# + + +# Copyright 1996-2000 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. + + +# compiler command line name +# +CC := icl + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := /I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := /D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := /Fl + + +# Target flag. +# +T := /Fo + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +# Note that the Intel C/C++ compiler version 4.5 complains about +# the use of FT_FIELD_OFFSET with "value must be arithmetic type"! +# This really looks like a bug in the compiler because the macro +# _does_ compute an arithmetic value, so we disable this warning +# with "/Qwd32". +# +ifndef CFLAGS + CFLAGS := /nologo /c /Ox /G5 /W3 /Qwd32 +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := /Qansi /Za + +# Library linking +# +#CLEAN_LIBRARY = +LINK_LIBRARY = lib /nologo /out:$@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/unix-lcc.mk b/lib/freetype/builds/compiler/unix-lcc.mk new file mode 100644 index 0000000..fd8c7fb --- /dev/null +++ b/lib/freetype/builds/compiler/unix-lcc.mk @@ -0,0 +1,85 @@ +# +# FreeType 2 Unix LCC specific definitions +# + + +# Copyright 1996-2000 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. + + +# Command line name +# +CC := lcc + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := o +SO := o + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := a +SA := a + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o$(space) + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c -g +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +# LCC is pure ANSI anyway! +# +# the "-A" flag simply increments verbosity about non ANSI code +# +ANSIFLAGS := -A + + +# library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +LINK_LIBRARY = $(AR) -r $@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/visualage.mk b/lib/freetype/builds/compiler/visualage.mk new file mode 100644 index 0000000..3d07ac6 --- /dev/null +++ b/lib/freetype/builds/compiler/visualage.mk @@ -0,0 +1,76 @@ +# +# FreeType 2 Visual Age C++ specific definitions +# + + +# Copyright 1996-2000 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. + + +# command line compiler name +# +CC := icc + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := /I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := /D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := /Fl + + +# Target flag. +# +T := /Fo + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +ifndef CFLAGS + CFLAGS := /Q- /Gd+ /O2 /G5 /W3 /C +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSI_FLAGS := /Sa + + +# Library linking +# +#CLEAN_LIBRARY := +LINK_LIBRARY = lib /nologo /out:$@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/visualc.mk b/lib/freetype/builds/compiler/visualc.mk new file mode 100644 index 0000000..235a4df --- /dev/null +++ b/lib/freetype/builds/compiler/visualc.mk @@ -0,0 +1,79 @@ +# +# FreeType 2 Visual C++ definitions +# + + +# Copyright 1996-2000 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. + + +# compiler command line name +# +CC := cl + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := /I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := /D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := /Fl + + +# Target flag. +# +T := /Fo + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := /nologo /c /Ox /G5 /W3 /WX +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := /Za + + +# Library linking +# +#CLEAN_LIBRARY = +LINK_LIBRARY = lib /nologo /out:$@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/watcom.mk b/lib/freetype/builds/compiler/watcom.mk new file mode 100644 index 0000000..7669ed6 --- /dev/null +++ b/lib/freetype/builds/compiler/watcom.mk @@ -0,0 +1,81 @@ +# +# FreeType 2 Watcom-specific definitions +# + + +# Copyright 1996-2000 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. + + +# Compiler command line name +# +CC := wcc386 + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I= + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -FO= + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -zq +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := -za + + +# Library linking +# +ifndef CLEAN_LIBRARY + CLEAN_LIBRARY = $(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) +endif +LINK_LIBRARY = wlib -q -o = $@ $(OBJECTS_LIST) + +# EOF diff --git a/lib/freetype/builds/compiler/win-lcc.mk b/lib/freetype/builds/compiler/win-lcc.mk new file mode 100644 index 0000000..6e9512a --- /dev/null +++ b/lib/freetype/builds/compiler/win-lcc.mk @@ -0,0 +1,81 @@ +# +# FreeType 2 Win32-LCC specific definitions +# + + +# Copyright 1996-2000 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. + + +# Command line name +# +CC := lcc + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := obj +SO := obj + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := lib +SA := lib + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -Fl + + +# Target flag. +# +T := -Fo + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +ifndef CFLAGS + CFLAGS := -c -g2 -O +endif + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +# LCC is pure ANSI anyway! +# +ANSIFLAGS := + + +# library linking +# +#CLEAN_LIBRARY := +LINK_LIBRARY = lcclib /out:$(subst $(SEP),\\,$@) $(subst $(SEP),\\,$(OBJECTS_LIST)) + +# EOF diff --git a/lib/freetype/builds/detect.mk b/lib/freetype/builds/detect.mk new file mode 100644 index 0000000..5c7b74c --- /dev/null +++ b/lib/freetype/builds/detect.mk @@ -0,0 +1,143 @@ +# +# FreeType 2 host platform detection rules +# + + +# Copyright 1996-2000 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 sub-Makefile is in charge of detecting the current platform. It sets +# the following variables: +# +# BUILD The configuration and system-specific directory. Usually +# `freetype/builds/$(PLATFORM)' but can be different for +# custom builds of the library. +# +# The following variables must be defined in system specific `detect.mk' +# files: +# +# PLATFORM The detected platform. This will default to `ansi' if +# auto-detection fails. +# CONFIG_FILE The configuration sub-makefile to use. This usually depends +# on the compiler defined in the `CC' environment variable. +# DELETE The shell command used to remove a given file. +# COPY The shell command used to copy one file. +# SEP The platform-specific directory separator. +# CC The compiler to use. +# +# You need to set the following variable(s) before calling it: +# +# TOP_DIR The top-most directory in the FreeType library source +# hierarchy. If not defined, it will default to `.'. + +# If TOP_DIR is not defined, default it to `.' +# +ifndef TOP_DIR + TOP_DIR := . +endif + +# Set auto-detection default to `ansi' resp. UNIX-like operating systems. +# Note that we delay evaluation of $(BUILD_CONFIG_), $(BUILD), and +# $(CONFIG_RULES). +# +PLATFORM := ansi +DELETE := $(RM) +COPY := cp +SEP := / + +BUILD_CONFIG_ = $(TOP_DIR)$(SEP)builds$(SEP) +BUILD = $(BUILD_CONFIG_)$(PLATFORM) +CONFIG_RULES = $(BUILD)$(SEP)$(CONFIG_FILE) + +# We define the BACKSLASH variable to hold a single back-slash character. +# This is needed because a line like +# +# SEP := \ +# +# does not work with GNU Make (the backslash is interpreted as a line +# continuation). While a line like +# +# SEP := \\ +# +# really defines $(SEP) as `\' on Unix, and `\\' on Dos and Windows! +# +BACKSLASH := $(strip \ ) + +# Find all auto-detectable platforms. +# +PLATFORMS_ := $(notdir $(subst /detect.mk,,$(wildcard $(BUILD_CONFIG_)*/detect.mk))) +.PHONY: $(PLATFORMS_) ansi + +# Filter out platform specified as setup target. +# +PLATFORM := $(firstword $(filter $(MAKECMDGOALS),$(PLATFORMS_))) + +# If no setup target platform was specified, enable auto-detection/ +# default platform. +# +ifeq ($(PLATFORM),) + PLATFORM := ansi +endif + +# If the user has explicitly asked for `ansi' on the command line, +# disable auto-detection. +# +ifeq ($(findstring ansi,$(MAKECMDGOALS)),) + # Now, include all detection rule files found in the `builds/' + # directories. Note that the calling order of the various `detect.mk' + # files isn't predictable. + # + include $(wildcard $(BUILD_CONFIG_)*/detect.mk) +endif + +# In case no detection rule file was successful, use the default. +# +ifndef CONFIG_FILE + CONFIG_FILE := ansi.mk + setup: std_setup + .PHONY: setup +endif + +# The following targets are equivalent, with the exception that they use +# a slightly different syntax for the `echo' command. +# +# std_setup: defined for most (i.e. Unix-like) platforms +# dos_setup: defined for Dos-ish platforms like Dos, Windows & OS/2 +# +.PHONY: std_setup dos_setup + +std_setup: + @echo "" + @echo "$(PROJECT_TITLE) build system -- automatic system detection" + @echo "" + @echo "The following settings are used:" + @echo "" + @echo " platform $(PLATFORM)" + @echo " compiler $(CC)" + @echo " configuration directory $(BUILD)" + @echo " configuration rules $(CONFIG_RULES)" + @echo "" + @echo "If this does not correspond to your system or settings please remove the file" + @echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help." + @echo "" + @echo "Otherwise, simply type \`$(MAKE)' again to build the library." + @echo "" + @$(COPY) $(CONFIG_RULES) $(CONFIG_MK) + + +# Special case for Dos, Windows, OS/2, where echo "" doesn't work correctly! +# +dos_setup: + @type builds\newline + @echo $(PROJECT_TITLE) build system -- automatic system detection + @type builds\newline + @echo The following settings are used: + @type builds\newline + @echo platform \ No newline at end of file diff --git a/lib/freetype/builds/dos/detect.mk b/lib/freetype/builds/dos/detect.mk new file mode 100644 index 0000000..0467848 --- /dev/null +++ b/lib/freetype/builds/dos/detect.mk @@ -0,0 +1,111 @@ +# +# FreeType 2 configuration file to detect a DOS host platform. +# + + +# Copyright 1996-2000 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. + + +.PHONY: setup + + +ifeq ($(PLATFORM),ansi) + + # Test for DJGPP by checking the DJGPP environment variable, which must be + # set in order to use the system (ie. it will always be present when the + # `make' utility is run). + # + # We test for the COMSPEC environment variable, then run the `ver' + # command-line program to see if its output contains the word `Dos'. + # + # If this is true, we are running a Dos-ish platform (or an emulation). + # + ifdef DJGPP + PLATFORM := dos + else + ifdef COMSPEC + is_dos := $(findstring Dos,$(shell ver)) + + # We try to recognize a Dos session under OS/2. The `ver' command + # returns `Operating System/2 ...' there, so `is_dos' should be empty. + # + # To recognize a Dos session under OS/2, we check COMSPEC for the + # substring `MDOS\COMMAND' + # + ifeq ($(is_dos),) + is_dos := $(findstring MDOS\COMMAND,$(COMSPEC)) + endif + endif # test COMSPEC + + ifneq ($(is_dos),) + + PLATFORM := dos + + endif # test Dos + endif # test DJGPP +endif # test PLATFORM ansi + +ifeq ($(PLATFORM),dos) + + # Use DJGPP (i.e. gcc) by default. + # + CONFIG_FILE := dos-gcc.mk + SEP := / + ifndef CC + CC := gcc + endif + + # additionally, we provide hooks for various other compilers + # + ifneq ($(findstring turboc,$(MAKECMDGOALS)),) # Turbo C + CONFIG_FILE := dos-tcc.mk + SEP := $(BACKSLASH) + CC := tcc + turboc: setup + .PHONY: turboc + endif + + ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++ + CONFIG_FILE := dos-wat.mk + SEP := $(BACKSLASH) + CC := wcc386 + watcom: setup + .PHONY: watcom + endif + + ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C/C++ 32-bit + CONFIG_FILE := dos-bcc.mk + SEP := $(BACKSLASH) + CC := bcc32 + borlandc: setup + .PHONY: borlandc + endif + + ifneq ($(findstring borlandc16,$(MAKECMDGOALS)),) # Borland C/C++ 16-bit + CONFIG_FILE := dos-bcc.mk + SEP := $(BACKSLASH) + CC := bcc + borlandc16: setup + .PHONY: borlandc16 + endif + + ifneq ($(findstring bash,$(SHELL)),) # check for bash + DELETE := rm + COPY := cp + setup: std_setup + else + DELETE := del + COPY := copy + setup: dos_setup + endif + +endif # test PLATFORM dos + +# EOF diff --git a/lib/freetype/builds/dos/dos-def.mk b/lib/freetype/builds/dos/dos-def.mk new file mode 100644 index 0000000..d2bcbd4 --- /dev/null +++ b/lib/freetype/builds/dos/dos-def.mk @@ -0,0 +1,59 @@ +# +# FreeType 2 DOS specific definitions +# + + +# Copyright 1996-2000 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. + + +DELETE := del +HOSTSEP := $(strip \ ) +BUILD := $(TOP_DIR)$(SEP)builds$(SEP)dos +PLATFORM := dos + +# except for DJGPP/GCC on Dos +ifndef SEP +SEP := $(HOSTSEP) +endif + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f %TOP_DIR%/Makefile setup [options] +# make -f %TOP_DIR%/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(TOP_DIR)$(SEP)objs +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := $(PROJECT) + + +# The NO_OUTPUT macro is used to ignore the output of commands. +# +NO_OUTPUT = > nul + + +# EOF diff --git a/lib/freetype/builds/dos/dos-gcc.mk b/lib/freetype/builds/dos/dos-gcc.mk new file mode 100644 index 0000000..14a9d38 --- /dev/null +++ b/lib/freetype/builds/dos/dos-gcc.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 configuration rules for the DJGPP compiler +# + + +# Copyright 1996-2000 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. + + +SEP := / + +include $(TOP_DIR)/builds/dos/dos-def.mk +include $(TOP_DIR)/builds/compiler/gcc.mk +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/freetype.mk b/lib/freetype/builds/freetype.mk new file mode 100644 index 0000000..9b5921c --- /dev/null +++ b/lib/freetype/builds/freetype.mk @@ -0,0 +1,307 @@ +# +# FreeType 2 library sub-Makefile +# + + +# Copyright 1996-2000, 2002 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. + + +# DO NOT INVOKE THIS MAKEFILE DIRECTLY! IT IS MEANT TO BE INCLUDED BY +# OTHER MAKEFILES. + + +# The following variables (set by other Makefile components, in the +# environment, or on the command line) are used: +# +# BUILD The architecture dependent directory, +# e.g. `$(TOP_DIR)/builds/unix'. +# +# OBJ_DIR The directory in which object files are created. +# +# LIB_DIR The directory in which the library is created. +# +# INCLUDES A list of directories to be included additionally. +# Usually empty. +# +# CFLAGS Compilation flags. This overrides the default settings +# in the platform-specific configuration files. +# +# FTSYS_SRC If set, its value is used as the name of a replacement +# file for `src/base/ftsystem.c'. +# +# FTDEBUG_SRC If set, its value is used as the name of a replacement +# file for `src/base/ftdebug.c'. [For a normal build, this +# file does nothing.] +# +# FT_MODULE_LIST The file which contains the list of modules for the +# current build. Usually, this is automatically created by +# `modules.mk'. +# +# BASE_OBJ_S +# BASE_OBJ_M A list of base objects (for single object and multiple +# object builds, respectively). Set up in +# `src/base/rules.mk'. +# +# BASE_EXT_OBJ A list of base extension objects. Set up in +# `src/base/rules.mk'. +# +# DRV_OBJ_S +# DRV_OBJ_M A list of driver objects (for single object and multiple +# object builds, respectively). Set up cumulatively in +# `src//rules.mk'. +# +# CLEAN +# DISTCLEAN The sub-makefiles can append additional stuff to these two +# variables which is to be removed for the `clean' resp. +# `distclean' target. +# +# TOP_DIR, SEP, +# LIBRARY, CC, +# A, I, O, T Check `config.mk' for details. + + +# The targets `objects' and `library' are defined at the end of this +# Makefile after all other rules have been included. +# +.PHONY: single multi objects library + +# default target -- build single objects and library +# +single: objects library + +# `multi' target -- build multiple objects and library +# +multi: objects library + + +# The FreeType source directory, usually `./src'. +# +SRC := $(TOP_DIR)$(SEP)src + + +# The directory where the base layer components are placed, usually +# `./src/base'. +# +BASE_DIR := $(SRC)$(SEP)base + +# The build header file used to define all public header file names +# as macro. +# +ifndef FT_BUILD_H + FT_BUILD_H := $(TOP_DIR)$(SEP)include$(SEP)ft2build.h + FTBUILD_CMD := +else + FTBUILD_CMD = $(D)FT_BUILD_H=$(FT_BUILD_H) +endif + +# A few short-cuts in order to avoid typing $(SEP) all the time for the +# directory separator. +# +# For example: $(SRC_) equals to `./src/' where `.' is $(TOP_DIR). +# +# +SRC_ := $(SRC)$(SEP) +BASE_ := $(BASE_DIR)$(SEP) +OBJ_ := $(OBJ_DIR)$(SEP) +LIB_ := $(LIB_DIR)$(SEP) +PUBLIC_ := $(TOP_DIR)$(SEP)include$(SEP)freetype$(SEP) +INTERNAL_ := $(PUBLIC_)internal$(SEP) +CONFIG_ := $(PUBLIC_)config$(SEP) +CACHE_ := $(PUBLIC_)cache$(SEP) + + +# The final name of the library file. +# +PROJECT_LIBRARY := $(LIB_)$(LIBRARY).$A + + +# include paths +# +# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed +# in front of the include list. Porters are then able to +# put their own version of some of the FreeType components +# in the `freetype/builds/' directory, as these +# files will override the default sources. +# +INCLUDES := $(OBJ_DIR) $(BUILD) $(TOP_DIR)$(SEP)include + +INCLUDE_FLAGS = $(INCLUDES:%=$I%) + + +# C flags used for the compilation of an object file. This must include at +# least the paths for the `base' and `builds/' directories; +# debug/optimization/warning flags + ansi compliance if needed. +# +# $(INCLUDE_FLAGS) should come before $(CFLAGS) to avoid problems with +# old FreeType versions. +# +FT_CFLAGS = $(INCLUDE_FLAGS) $(CFLAGS) +FT_CC = $(CC) $(FT_CFLAGS) +FT_COMPILE = $(CC) $(ANSIFLAGS) $(FT_CFLAGS) + + +# Include the `modules' rules file. +# +include $(TOP_DIR)/builds/modules.mk + + +# Initialize the list of objects. +# +OBJECTS_LIST := + + +# Define $(PUBLIC_H) as the list of all public header files located in +# `$(TOP_DIR)/include/freetype'. $(BASE_H), $(CACHE_H), and $(CONFIG_H) are +# defined similarly. +# +# This is used to simplify the dependency rules -- if one of these files +# changes, the whole library is recompiled. +# +PUBLIC_H := $(wildcard $(PUBLIC_)*.h) +BASE_H := $(wildcard $(INTERNAL_)*.h) +CONFIG_H := $(wildcard $(CONFIG_)*.h) \ + $(wildcard $(BUILD)$(SEP)freetype$(SEP)config$(SEP)*.h) +CACHE_H := $(wildcard $(CACHE_)*.h) + +FREETYPE_H := $(PUBLIC_H) $(BASE_H) $(CONFIG_H) $(CACHE_H) + + +# ftsystem component +# +ifndef FTSYS_SRC + FTSYS_SRC = $(BASE_)ftsystem.c +endif + +FTSYS_OBJ = $(OBJ_)ftsystem.$O + +OBJECTS_LIST += $(FTSYS_OBJ) + +$(FTSYS_OBJ): $(FTSYS_SRC) $(FREETYPE_H) + $(FT_COMPILE) $T$@ $< + + +# ftdebug component +# +ifndef FTDEBUG_SRC + FTDEBUG_SRC = $(BASE_)ftdebug.c +endif + +FTDEBUG_OBJ = $(OBJ_)ftdebug.$O + +OBJECTS_LIST += $(FTDEBUG_OBJ) + +$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(FREETYPE_H) + $(FT_COMPILE) $T$@ $< + + +# Include all rule files from FreeType components. +# +include $(wildcard $(SRC)/*/rules.mk) + + +# ftinit component +# +# The C source `ftinit.c' contains the FreeType initialization routines. +# It is able to automatically register one or more drivers when the API +# function FT_Init_FreeType() is called. +# +# The set of initial drivers is determined by the driver Makefiles +# includes above. Each driver Makefile updates the FTINIT_xxx lists +# which contain additional include paths and macros used to compile the +# single `ftinit.c' source. +# +FTINIT_SRC := $(BASE_)ftinit.c +FTINIT_OBJ := $(OBJ_)ftinit.$O + +OBJECTS_LIST += $(FTINIT_OBJ) + +$(FTINIT_OBJ): $(FTINIT_SRC) $(FREETYPE_H) $(FT_MODULE_LIST) + $(FT_COMPILE) $T$@ $< + + +# All FreeType library objects +# +# By default, we include the base layer extensions. These could be +# omitted on builds which do not want them. +# +OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) +OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) + + +# The target `multi' on the Make command line indicates that we want to +# compile each source file independently. +# +# Otherwise, each module/driver is compiled in a single object file through +# source file inclusion (see `src/base/ftbase.c' or +# `src/truetype/truetype.c' for examples). +# +BASE_OBJECTS := $(OBJECTS_LIST) + +ifneq ($(findstring multi,$(MAKECMDGOALS)),) + OBJECTS_LIST += $(OBJ_M) +else + OBJECTS_LIST += $(OBJ_S) +endif + +objects: $(OBJECTS_LIST) + +library: $(PROJECT_LIBRARY) + +.c.$O: + $(FT_COMPILE) $T$@ $< + + +.PHONY: clean_project_std distclean_project_std + +# Standard cleaning and distclean rules. These are not accepted +# on all systems though. +# +clean_project_std: + -$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S) $(CLEAN) + +distclean_project_std: clean_project_std + -$(DELETE) $(PROJECT_LIBRARY) + -$(DELETE) *.orig *~ core *.core $(DISTCLEAN) + + +.PHONY: clean_project_dos distclean_project_dos + +# The Dos command shell does not support very long list of arguments, so +# we are stuck with wildcards. +# +# Don't break the command lines with \; this prevents the "del" command from +# working correctly on Win9x. +# +clean_project_dos: + -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(OBJ_))*.$O $(CLEAN) $(NO_OUTPUT) + +distclean_project_dos: clean_project_dos + -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(PROJECT_LIBRARY)) $(DISTCLEAN) $(NO_OUTPUT) + + +.PHONY: remove_config_mk + +# Remove configuration file (used for distclean). +# +remove_config_mk: + -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(CONFIG_MK)) $(NO_OUTPUT) + + +.PHONY: clean distclean + +# The `config.mk' file must define `clean_freetype' and +# `distclean_freetype'. Implementations may use to relay these to either +# the `std' or `dos' versions from above, or simply provide their own +# implementation. +# +clean: clean_project +distclean: distclean_project remove_config_mk + +# EOF diff --git a/lib/freetype/builds/link_dos.mk b/lib/freetype/builds/link_dos.mk new file mode 100644 index 0000000..bc36ed0 --- /dev/null +++ b/lib/freetype/builds/link_dos.mk @@ -0,0 +1,41 @@ +# +# Link instructions for Dos-like systems (Dos, Win32, OS/2) +# + + +# Copyright 1996-2000 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. + + +ifdef BUILD_PROJECT + + .PHONY: clean_project distclean_project + + # Now include the main sub-makefile. It contains all the rules used to + # build the library with the previous variables defined. + # + include $(TOP_DIR)/builds/$(PROJECT).mk + + # The cleanup targets. + # + clean_project: clean_project_dos + distclean_project: distclean_project_dos + + # This final rule is used to link all object files into a single library. + # this is compiler-specific + # + $(PROJECT_LIBRARY): $(OBJECTS_LIST) + ifdef CLEAN_LIBRARY + -$(CLEAN_LIBRARY) $(NO_OUTPUT) + endif + $(LINK_LIBRARY) + +endif + +# EOF diff --git a/lib/freetype/builds/link_std.mk b/lib/freetype/builds/link_std.mk new file mode 100644 index 0000000..d59f2c3 --- /dev/null +++ b/lib/freetype/builds/link_std.mk @@ -0,0 +1,41 @@ +# +# Link instructions for standard systems +# + + +# Copyright 1996-2000 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. + + +ifdef BUILD_PROJECT + + .PHONY: clean_project distclean_project + + # Now include the main sub-makefile. It contains all the rules used to + # build the library with the previous variables defined. + # + include $(TOP_DIR)/builds/$(PROJECT).mk + + # The cleanup targets. + # + clean_project: clean_project_std + distclean_project: distclean_project_std + + # This final rule is used to link all object files into a single library. + # this is compiler-specific + # + $(PROJECT_LIBRARY): $(OBJECTS_LIST) + ifdef CLEAN_LIBRARY + -$(CLEAN_LIBRARY) $(NO_OUTPUT) + endif + $(LINK_LIBRARY) + +endif + +# EOF diff --git a/lib/freetype/builds/mac/README b/lib/freetype/builds/mac/README new file mode 100644 index 0000000..f933c56 --- /dev/null +++ b/lib/freetype/builds/mac/README @@ -0,0 +1,14 @@ +This folder contains + + . a Makefile for Apple MPW build environment (currently PPC only) + + . supporting code and CodeWarrior Pro 7 project files to build the + FreeType library. + +Notes: +The library will be built as a static lib in the obj/ folder. + +Current maintainer: Leonard Rosenthol, +Originally prepared by Just van Rossum, + +This directory is now actively maintained as part of the FreeType Project. diff --git a/lib/freetype/builds/mac/freetype.make b/lib/freetype/builds/mac/freetype.make new file mode 100644 index 0000000..0767ada --- /dev/null +++ b/lib/freetype/builds/mac/freetype.make @@ -0,0 +1,3 @@ +# Makefile for Apple MPW build environment (currently PPC only) + +MAKEFILE = Makefile diff --git a/lib/freetype/builds/mac/ftlib.prj b/lib/freetype/builds/mac/ftlib.prj new file mode 100644 index 0000000000000000000000000000000000000000..9cf443f5ff29ca86c1d7b4f72ae7e80a38ed20d6 GIT binary patch literal 603 zcmd_myAA)>8B)kBIW^iePt-%O;0cF>B4bV+G&g&y|%5L|MXA#3#sDM z20z}0*xzpkID_mt46*mnWS?M|eSs176-L<)7-N56+-v2&C)hQZWOrbSJ%nlY3})C{ mm}MVfj(vuC_6-);cUWY> $(subst $(SEP),$(HOSTSEP),$(MODULE_LIST)) + REMOVE_MODULE := @-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(MODULE_LIST)) +else + OPEN_MODULE := @echo " + CLOSE_MODULE := " >> $(MODULE_LIST) + REMOVE_MODULE := @-$(DELETE) $(MODULE_LIST) +endif + + +# Before the modules list file can be generated, we must remove the file in +# order to `clean' the list. +# +clean_module_list: + $(REMOVE_MODULE) + @-echo Regenerating the modules list in $(MODULE_LIST)... + +make_module_list: clean_module_list + @echo done. + +# $(OPEN_DRIVER) & $(CLOSE_DRIVER) are used to specify a given font driver +# in the `module.mk' rules file. +# +OPEN_DRIVER := $(OPEN_MODULE)FT_USE_MODULE( +CLOSE_DRIVER := )$(CLOSE_MODULE) + +ECHO_DRIVER := @echo "* module:$(space) +ECHO_DRIVER_DESC := ( +ECHO_DRIVER_DONE := )" + +# Each `module.mk' in the `src' sub-dirs is used to add one rule to the +# target `make_module_list'. +# +include $(wildcard $(TOP_DIR)/src/*/module.mk) + +# EOF diff --git a/lib/freetype/builds/newline b/lib/freetype/builds/newline new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/freetype/builds/newline @@ -0,0 +1 @@ + diff --git a/lib/freetype/builds/os2/detect.mk b/lib/freetype/builds/os2/detect.mk new file mode 100644 index 0000000..d332be7 --- /dev/null +++ b/lib/freetype/builds/os2/detect.mk @@ -0,0 +1,75 @@ +# +# FreeType 2 configuration file to detect an OS/2 host platform. +# + + +# Copyright 1996-2000 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. + + +.PHONY: setup + + +ifeq ($(PLATFORM),ansi) + + ifdef OS2_SHELL + + PLATFORM := os2 + + endif # test OS2_SHELL +endif + +ifeq ($(PLATFORM),os2) + + COPY := copy + DELETE := del + + # gcc-emx by default + CONFIG_FILE := os2-gcc.mk + SEP := / + + # additionally, we provide hooks for various other compilers + # + ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++ + CONFIG_FILE := os2-icc.mk + SEP := $(BACKSLASH) + CC := icc + visualage: setup + .PHONY: visualage + endif + + ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++ + CONFIG_FILE := os2-wat.mk + SEP := $(BACKSLASH) + CC := wcc386 + watcom: setup + .PHONY: watcom + endif + + ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C++ 32-bit + CONFIG_FILE := os2-bcc.mk + SEP := $(BACKSLASH) + CC := bcc32 + borlandc: setup + .PHONY: borlandc + endif + + ifneq ($(findstring devel,$(MAKECMDGOALS)),) # development target + CONFIG_FILE := os2-dev.mk + CC := gcc + SEP := / + devel: setup + .PHONY: devel + endif + + setup: dos_setup + +endif # test PLATFORM os2 + +# EOF diff --git a/lib/freetype/builds/os2/os2-def.mk b/lib/freetype/builds/os2/os2-def.mk new file mode 100644 index 0000000..ef4b811 --- /dev/null +++ b/lib/freetype/builds/os2/os2-def.mk @@ -0,0 +1,58 @@ +# +# FreeType 2 OS/2 specific definitions +# + + +# Copyright 1996-2000 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. + + +DELETE := del +HOSTSEP := $(strip \ ) +BUILD := $(TOP_DIR)$(SEP)builds$(SEP)os2 +PLATFORM := os2 + +# except for GCC+emx on OS/2 +ifndef SEP + SEP := $(HOSTSEP) +endif + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f %TOP_DIR%/Makefile setup [options] +# make -f %TOP_DIR%/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(TOP_DIR)$(SEP)objs +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := $(PROJECT) + + +# The NO_OUTPUT macro is used to ignore the output of commands. +# +NO_OUTPUT = 2> nul + +# EOF diff --git a/lib/freetype/builds/os2/os2-dev.mk b/lib/freetype/builds/os2/os2-dev.mk new file mode 100644 index 0000000..6527b79 --- /dev/null +++ b/lib/freetype/builds/os2/os2-dev.mk @@ -0,0 +1,33 @@ +# +# FreeType 2 configuration rules for OS/2 + GCC +# +# Development version without optimizations. +# + + +# Copyright 1996-2000 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 TOP_DIR + TOP_DIR := . +endif + +SEP := / + +include $(TOP_DIR)/builds/os2/os2-def.mk +BUILD := $(TOP_DIR)/builds/devel + +include $(TOP_DIR)/builds/compiler/gcc-dev.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + + +# EOF diff --git a/lib/freetype/builds/os2/os2-gcc.mk b/lib/freetype/builds/os2/os2-gcc.mk new file mode 100644 index 0000000..5853862 --- /dev/null +++ b/lib/freetype/builds/os2/os2-gcc.mk @@ -0,0 +1,27 @@ +# +# FreeType 2 configuration rules for the OS/2 + gcc +# + + +# Copyright 1996-2000 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. + + +SEP := / + +# include OS/2-specific definitions +include $(TOP_DIR)/builds/os2/os2-def.mk + +# include gcc-specific definitions +include $(TOP_DIR)/builds/compiler/gcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/toplevel.mk b/lib/freetype/builds/toplevel.mk new file mode 100644 index 0000000..2e9fbd0 --- /dev/null +++ b/lib/freetype/builds/toplevel.mk @@ -0,0 +1,135 @@ +# +# FreeType build system -- top-level sub-Makefile +# + + +# Copyright 1996-2000 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 designed for GNU Make, do not use it with another Make tool! +# +# It works as follows: +# +# - When invoked for the first time, this Makefile will include the rules +# found in `PROJECT/builds/detect.mk'. They are in charge of detecting +# the current platform. +# +# A summary of the detection will be displayed, and the file `config.mk' +# will be created in the current directory. +# +# - When invoked later, this Makefile will include the rules found in +# `config.mk'. This sub-Makefile will define some system-specific +# variables (like compiler, compilation flags, object suffix, etc.), then +# include the rules found in `PROJECT/builds/PROJECT.mk', used to build +# the library. +# +# See the comments in `builds/detect.mk' and `builds/PROJECT.mk' for more +# details on host platform detection and library builds. + + +.PHONY: all setup distclean modules + +# The `space' variable is used to avoid trailing spaces in defining the +# `T' variable later. +# +empty := +space := $(empty) $(empty) + + +ifndef CONFIG_MK + CONFIG_MK := config.mk +endif + +# If no configuration sub-makefile is present, or if `setup' is the target +# to be built, run the auto-detection rules to figure out which +# configuration rules file to use. +# +# Note that the configuration file is put in the current directory, which is +# not necessarily $(TOP_DIR). + +# If `config.mk' is not present, set `check_platform'. +# +ifeq ($(wildcard $(CONFIG_MK)),) + check_platform := 1 +endif + +# If `setup' is one of the targets requested, set `check_platform'. +# +ifneq ($(findstring setup,$(MAKECMDGOALS)),) + check_platform := 1 +endif + +# Include the automatic host platform detection rules when we need to +# check the platform. +# +ifdef check_platform + + # This is the first rule `make' sees. + # + all: setup + + ifdef USE_MODULES + # If the module list $(MODULE_LIST) file is not present, generate it. + # + #modules: make_module_list setup + endif + + include $(TOP_DIR)/builds/detect.mk + + ifdef USE_MODULES + include $(TOP_DIR)/builds/modules.mk + + ifeq ($(wildcard $(MODULE_LIST)),) + setup: make_module_list + endif + endif + + # This rule makes sense for Unix only to remove files created by a run + # of the configure script which hasn't been successful (so that no + # `config.mk' has been created). It uses the built-in $(RM) command of + # GNU make. Similarly, `nul' is created if e.g. `make setup win32' has + # been erroneously used. + # + # note: This test is duplicated in "builds/toplevel.mk". + # + is_unix := $(strip $(wildcard /sbin/init) $(wildcard /usr/sbin/init) $(wildcard /hurd/auth)) + ifneq ($(is_unix),) + + distclean: + $(RM) builds/unix/config.cache + $(RM) builds/unix/config.log + $(RM) builds/unix/config.status + $(RM) builds/unix/unix-def.mk + $(RM) builds/unix/unix-cc.mk + $(RM) nul + + endif # test is_unix + + # IMPORTANT: + # + # `setup' must be defined by the host platform detection rules to create + # the `config.mk' file in the current directory. + +else + + # A configuration sub-Makefile is present -- simply run it. + # + all: single + + ifdef USE_MODULES + modules: make_module_list + endif + + BUILD_PROJECT := yes + include $(CONFIG_MK) + +endif # test check_platform + +# EOF diff --git a/lib/freetype/builds/unix/.cvsignore b/lib/freetype/builds/unix/.cvsignore new file mode 100644 index 0000000..cc8ec6a --- /dev/null +++ b/lib/freetype/builds/unix/.cvsignore @@ -0,0 +1,8 @@ +unix-def.mk +unix-cc.mk +config.status +config.cache +config.log +libtool +ftconfig.h +freetype-config diff --git a/lib/freetype/builds/unix/aclocal.m4 b/lib/freetype/builds/unix/aclocal.m4 new file mode 100644 index 0000000..bb44b8d --- /dev/null +++ b/lib/freetype/builds/unix/aclocal.m4 @@ -0,0 +1,3665 @@ +# generated automatically by aclocal 1.7.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +# serial 1 FT_MUNMAP_DECL + +AC_DEFUN(FT_MUNMAP_DECL, +[AC_MSG_CHECKING([whether munmap must be declared]) +AC_CACHE_VAL(ft_cv_munmap_decl, +[AC_TRY_COMPILE([ +#ifdef HAVE_UNISTD_H +#include +#endif +#include ], +[char *(*pfn) = (char *(*))munmap], +ft_cv_munmap_decl=no, +ft_cv_munmap_decl=yes)]) +AC_MSG_RESULT($ft_cv_munmap_decl) +if test $ft_cv_munmap_decl = yes; then + AC_DEFINE(NEED_MUNMAP_DECL,, + [Define to 1 if munmap() is not defined in ]) +fi]) + +AC_DEFUN(FT_MUNMAP_PARAM, +[AC_MSG_CHECKING([for munmap's first parameter type]) +AC_TRY_COMPILE([ +#include +#include +int munmap(void *, size_t);],, + AC_MSG_RESULT([void *]);AC_DEFINE(MUNMAP_USES_VOIDP,, + [Define to 1 if the first argument of munmap is of type void *]), + AC_MSG_RESULT([char *])) +]) + +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL + +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +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_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([LT_AC_PROG_SED])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# 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.$ac_objext` 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_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + 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* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# AC_LIBTOOL_HEADER_ASSERT +# ------------------------ +AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], +[AC_CACHE_CHECK([whether $CC supports assert without backlinking], + [lt_cv_func_assert_works], + [case $host in + *-*-solaris*) + if test "$GCC" = yes && test "$with_gnu_ld" != yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) lt_cv_func_assert_works=no ;; + *) lt_cv_func_assert_works=yes ;; + esac + fi + ;; + esac]) + +if test "x$lt_cv_func_assert_works" = xyes; then + AC_CHECK_HEADERS(assert.h) +fi +])# AC_LIBTOOL_HEADER_ASSERT + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# 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 +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +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. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && 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.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[[]] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${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 && + 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' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # 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=$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' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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 configure 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' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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 echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + 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 +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# 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' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +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 + +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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +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 +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + 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 + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + 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'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + 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 + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +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.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; 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 + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # 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 + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +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 + AC_MSG_CHECKING([if we can lock with hard links]) + 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 + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # 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 + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +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= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +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. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # 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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +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* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + 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 $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # 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_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # 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. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + 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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${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 $linker_flags' + 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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${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* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + 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 $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$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* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + 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 + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_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* | pw32*) + # 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 $compiler_flags `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$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + 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 $linker_flags /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 $linker_flags' + 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 $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + 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* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [[12]].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $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 $linker_flags' + 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 $linker_flags~$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 + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + 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 $linker_flags' + 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 $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +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 +AC_MSG_RESULT([$hardcode_action]) + +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker 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" + +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* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) 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. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + hardcode_into_libs=yes + ;; + +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 + ;; + +bsdi4*) + version_type=linux + 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 $libdir' + shlibpath_var=LD_LIBRARY_PATH + 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" + export_dynamic_flag_spec=-rdynamic + # 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* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +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*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + 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 + hardcode_into_libs=yes + ;; + +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* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + 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* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + 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 + ;; + 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}" + ;; + +# 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 + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + 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 + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + 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$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + 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" + hardcode_into_libs=yes + ;; + +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 + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +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 + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + 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 +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +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*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +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 + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + 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 extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib 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 \ + global_symbol_to_c_name_address \ + 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 | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $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 ltmain.sh. +# +# Copyright (C) 1996-2000 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. + +# A sed that does not truncate output. +SED=$lt_SED + +# 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 "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# 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 add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# 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=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# 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=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_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_support=$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=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_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=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# 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 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_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 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_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=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# 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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # 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-2000 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() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# 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 < 1) +# 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> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# 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], +[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], +[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], +[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_DISABLE_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_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + 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 + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# 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_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + 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 + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_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 + lt_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 "$lt_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 + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_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_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_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 + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_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. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[[012]]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[[78]]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_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]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl +AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_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 + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_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 "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$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* | *-*-pw32*) + # 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 and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and LTDLINCL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately 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='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and LTDLINCL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately 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='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" +]) +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +AC_MSG_RESULT([$SED]) +]) + diff --git a/lib/freetype/builds/unix/config.guess b/lib/freetype/builds/unix/config.guess new file mode 100644 index 0000000..78f6b92 --- /dev/null +++ b/lib/freetype/builds/unix/config.guess @@ -0,0 +1,1409 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-01-10' + +# 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. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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 build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +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 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-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 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:MicroBSD:*:*) + echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE} + exit 0 ;; + 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. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + 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-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000: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 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + 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=`(sed 1q /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 ;; + # 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 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${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) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + 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 -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + 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 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${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 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + 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:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${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=${UNAME_VERSION}.${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 BSD 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:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #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 + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + 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 -o $dummy $dummy.c && $dummy && exit 0 + 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:*:* | *3000*: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 ;; + 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*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + 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/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/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:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i586-pc-interix3 + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + 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 i586-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 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # 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. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # 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. + 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:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + 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|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^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:*:*:*) + # Left here for compatibility: + # 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 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*: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.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-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:*: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 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + 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 ;; + SX-6:SUPER-UX:*:*) + echo sx6-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 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + 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 + +eval $set_cc_for_build +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) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# 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 -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# 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 + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/freetype/builds/unix/config.sub b/lib/freetype/builds/unix/config.sub new file mode 100644 index 0000000..04baf3d --- /dev/null +++ b/lib/freetype/builds/unix/config.sub @@ -0,0 +1,1473 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-01-03' + +# 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. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# 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. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +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 + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + 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 | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + 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 + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +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. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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*86 | x86_64) + 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. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + 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 + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + 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 + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + 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 + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*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 + ;; + 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 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + 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 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + 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 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-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/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-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 + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + 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 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + 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 + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + 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 + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + 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* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -microbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -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|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # 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[0-9]* | -*MiNT | -MiNT[0-9]*) + 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*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + 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 + ;; + or32-*) + os=-coff + ;; + *-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 + ;; + f30[01]-fujitsu | f700-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* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/freetype/builds/unix/configure b/lib/freetype/builds/unix/configure new file mode 100644 index 0000000..92c1696 --- /dev/null +++ b/lib/freetype/builds/unix/configure @@ -0,0 +1,9831 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.54. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +fi + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${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 && + 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' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # 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=$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' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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 configure 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' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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 echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "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-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="ftconfig.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS version_info ft_version build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP XX_CFLAGS XX_ANSIFLAGS RMF RMDIR INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA EGREP FTSYS_SRC LIBZ SYSTEM_ZLIB LN_S ECHO RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP LIBTOOL LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +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' + +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 + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # 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_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$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 ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) 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 | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$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 | -n) + 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_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + 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 "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# 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_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + 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 "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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 <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shared=PKGS build shared libraries default=yes + --enable-static=PKGS build static libraries default=yes + --enable-fast-install=PKGS optimize for fast installation default=yes + --disable-libtool-lock avoid locking (might break parallel builds) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-zlib use internal zlib instead of system-wide + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-pic try to use only PIC/non-PIC objects default=use both + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.54. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell meta-characters. +ac_configure_args= +ac_sep= +for ac_arg +do + case $ac_arg in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n ) continue ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# 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 + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# 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 "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers ftconfig.h:ftconfig.in" + + +version_info='9:3:3' + +ft_version=`echo $version_info | tr : .` + + +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 + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6 +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_target_alias=$target_alias +test "x$ac_cv_target_alias" = "x" && + ac_cv_target_alias=$ac_cv_host_alias +ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6 +target=$ac_cv_target +target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +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 "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +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 $# != 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 + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +check \`config.log' for details." >&5 +echo "$as_me: error: C compiler cannot create executables +check \`config.log' for details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&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 "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall" + XX_ANSIFLAGS="-pedantic -ansi" +else + case "$host" in + *-dec-osf*) + CFLAGS= + XX_CFLAGS="-std1 -g3" + XX_ANSIFLAGS= + ;; + *) + XX_CFLAGS= + XX_ANSIFLAGS= + ;; + esac +fi + + + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RMF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RMF"; then + ac_cv_prog_RMF="$RMF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RMF="rm -f" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RMF=$ac_cv_prog_RMF +if test -n "$RMF"; then + echo "$as_me:$LINENO: result: $RMF" >&5 +echo "${ECHO_T}$RMF" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +# Extract the first word of "rmdir", so it can be a program name with args. +set dummy rmdir; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RMDIR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RMDIR"; then + ac_cv_prog_RMDIR="$RMDIR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RMDIR="rmdir" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RMDIR=$ac_cv_prog_RMDIR +if test -n "$RMDIR"; then + echo "$as_me:$LINENO: result: $RMDIR" >&5 +echo "${ECHO_T}$RMDIR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&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 +# AmigaOS /C/install, which installs bootblocks on floppy discs +# 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 "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /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 + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +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 "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&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}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +case "$INSTALL" in + /*) + ;; + */*) + INSTALL="`pwd`/$INSTALL" ;; +esac + + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + 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 <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + 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 <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#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); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + +for ac_header in fcntl.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6 +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((int *) 0) + return 0; +if (sizeof (int)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_int=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_int=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6 + +echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6 +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_int" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77" >&5 +echo "$as_me: error: cannot compute sizeof (int), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (int)); } +unsigned long ulongval () { return (long) (sizeof (int)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (int))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (int)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77" >&5 +echo "$as_me: error: cannot compute sizeof (int), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_int=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6 +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((long *) 0) + return 0; +if (sizeof (long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_long=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6 + +echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6 +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$ac_cv_type_long" = yes; then + # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo= ac_hi= +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_lo=`expr '(' $ac_mid ')' + 1` +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77" >&5 +echo "$as_me: error: cannot compute sizeof (long), 77" >&2;} + { (exit 1); exit 1; }; } ;; +esac +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 +echo "$as_me: error: cannot run test program while cross compiling" >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +long longval () { return (long) (sizeof (long)); } +unsigned long ulongval () { return (long) (sizeof (long)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + exit (1); + if (((long) (sizeof (long))) < 0) + { + long i = longval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%ld\n", i); + } + else + { + unsigned long i = ulongval (); + if (i != ((long) (sizeof (long)))) + exit (1); + fprintf (f, "%lu\n", i); + } + exit (ferror (f) || fclose (f) != 0); + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77" >&5 +echo "$as_me: error: cannot compute sizeof (long), 77" >&2;} + { (exit 1); exit 1; }; } +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +rm -f conftest.val +else + ac_cv_sizeof_long=0 +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6 +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + + + + +for ac_header in stdlib.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_func in getpagesize +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 (); +char (*f) (); + +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 +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +echo "$as_me:$LINENO: checking for working mmap" >&5 +echo $ECHO_N "checking for working mmap... $ECHO_C" >&6 +if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +/* malloc might have been renamed as rpl_malloc. */ +#undef malloc + +/* Thanks to Mike Haertel and Jim Avera for this test. + Here is a matrix of mmap possibilities: + mmap private not fixed + mmap private fixed at somewhere currently unmapped + mmap private fixed at somewhere already mapped + mmap shared not fixed + mmap shared fixed at somewhere currently unmapped + mmap shared fixed at somewhere already mapped + For private mappings, we should verify that changes cannot be read() + back from the file, nor mmap's back from the file at a different + address. (There have been systems where private was not correctly + implemented like the infamous i386 svr4.0, and systems where the + VM page cache was not coherent with the file system buffer cache + like early versions of FreeBSD and possibly contemporary NetBSD.) + For shared mappings, we should conversely verify that changes get + propagated back to all the places they're supposed to be. + + Grep wants private fixed already mapped. + The main things grep needs to know about mmap are: + * does it exist and is it safe to write into the mmap'd area + * how to use it (BSD variants) */ + +#include +#include + +#if !STDC_HEADERS && !HAVE_STDLIB_H +char *malloc (); +#endif + +/* This mess was copied from the GNU getpagesize.h. */ +#if !HAVE_GETPAGESIZE +/* Assume that all systems that can run configure have sys/param.h. */ +# if !HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# if 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 */ + +int +main () +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize (); + + /* First, make a file with some known garbage in it. */ + data = (char *) malloc (pagesize); + if (!data) + exit (1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand (); + umask (0); + fd = creat ("conftest.mmap", 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 ("conftest.mmap", O_RDWR); + if (fd < 0) + exit (1); + data2 = (char *) 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 = (char *) 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); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_mmap_fixed_mapped=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 +echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MMAP 1 +_ACEOF + +fi +rm -f conftest.mmap + +if test "$ac_cv_func_mmap_fixed_mapped" != yes; then + FTSYS_SRC='$(BASE_)ftsystem.c' +else + FTSYS_SRC='$(BUILD)/ftsystem.c' + + echo "$as_me:$LINENO: checking whether munmap must be declared" >&5 +echo $ECHO_N "checking whether munmap must be declared... $ECHO_C" >&6 +if test "${ft_cv_munmap_decl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +int +main () +{ +char *(*pfn) = (char *(*))munmap + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ft_cv_munmap_decl=no +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ft_cv_munmap_decl=yes +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi + +echo "$as_me:$LINENO: result: $ft_cv_munmap_decl" >&5 +echo "${ECHO_T}$ft_cv_munmap_decl" >&6 +if test $ft_cv_munmap_decl = yes; then + +cat >>confdefs.h <<\_ACEOF +#define NEED_MUNMAP_DECL +_ACEOF + +fi + echo "$as_me:$LINENO: checking for munmap's first parameter type" >&5 +echo $ECHO_N "checking for munmap's first parameter type... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#include +#include +int munmap(void *, size_t); +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + echo "$as_me:$LINENO: result: void *" >&5 +echo "${ECHO_T}void *" >&6; +cat >>confdefs.h <<\_ACEOF +#define MUNMAP_USES_VOIDP +_ACEOF + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +echo "$as_me:$LINENO: result: char *" >&5 +echo "${ECHO_T}char *" >&6 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi + + + + +for ac_func in memcpy memmove +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 (); +char (*f) (); + +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 +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +# Check whether --with-zlib or --without-zlib was given. +if test "${with_zlib+set}" = set; then + withval="$with_zlib" + +fi; +if test x$with_zlib != xno && test -z "$LIBZ"; then + echo "$as_me:$LINENO: checking for gzsetparams in -lz" >&5 +echo $ECHO_N "checking for gzsetparams in -lz... $ECHO_C" >&6 +if test "${ac_cv_lib_z_gzsetparams+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gzsetparams (); +int +main () +{ +gzsetparams (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_z_gzsetparams=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_z_gzsetparams=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzsetparams" >&5 +echo "${ECHO_T}$ac_cv_lib_z_gzsetparams" >&6 +if test $ac_cv_lib_z_gzsetparams = yes; then + if test "${ac_cv_header_zlib_h+set}" = set; then + echo "$as_me:$LINENO: checking for zlib.h" >&5 +echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_zlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking zlib.h usability" >&5 +echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking zlib.h presence" >&5 +echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for zlib.h" >&5 +echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_zlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_zlib_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 + +fi +if test $ac_cv_header_zlib_h = yes; then + LIBZ='-lz' +fi + + +fi + +fi +if test x$with_zlib != xno && test -n "$LIBZ"; then + CFLAGS="$CFLAGS -DFT_CONFIG_OPTION_SYSTEM_ZLIB" + LDFLAGS="$LDFLAGS $LIBZ" + SYSTEM_ZLIB=yes +fi + + + + + + + +# 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-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=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; +# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac + PATH_SEPARATOR=$lt_cv_sys_path_separator +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 "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by GCC" >&5 +echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + 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 "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_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 + lt_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 "$lt_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 + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi +echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6 +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6 +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_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 + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_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 "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6 + +echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6 +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_executable_p="test -f" +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" + fi + done + done +done + + # Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/sed$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + _max=0 + _count=0 + # Add /usr/xpg4/bin/sed as it is typically found on Solaris + # along with /bin/sed that truncates output. + for _sed in $_sed_list /usr/xpg4/bin/sed; do + test ! -f ${_sed} && break + cat /dev/null > "$tmp/sed.in" + _count=0 + echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" + # Check for GNU sed and select it if it is found. + if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then + lt_cv_path_SED=${_sed} + break + fi + while true; do + cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" + mv "$tmp/sed.tmp" "$tmp/sed.in" + cp "$tmp/sed.in" "$tmp/sed.nl" + echo >>"$tmp/sed.nl" + ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break + cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break + # 40000 chars as input seems more than enough + test $_count -gt 10 && break + _count=`expr $_count + 1` + if test $_count -gt $_max; then + _max=$_count + lt_cv_path_SED=$_sed + fi + done + done + rm -rf "$tmp" + +fi + +if test "X$SED" != "X"; then + lt_cv_path_SED=$SED +else + SED=$lt_cv_path_SED +fi +echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6 + +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + +echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 +echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_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. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + irix5* | nonstopux*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64*) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +openbsd*) + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + else + lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' + fi + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_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]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; +esac + +fi +echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + + + + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo "$as_me:$LINENO: checking command to parse $NM output" >&5 +echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6 +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# 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 +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris* | sysv5*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +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. +lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && 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.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + 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 $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= + global_symbol_to_c_name_address= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" + global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; +then + echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6 +else + echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6 +fi + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + 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 + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6 +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + 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 + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + + +enable_dlopen=no +enable_win32_dll=no + +# 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 && enable_libtool_lock=yes + +# 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 5628 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` 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 "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6 +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +lt_cv_cc_needs_belf=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&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 + +# 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' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +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 + +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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&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 "$as_me:$LINENO: result: $objdir" >&5 +echo "${ECHO_T}$objdir" >&6 + + + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi; +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_pic+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + 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 + # not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + 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'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + lt_cv_prog_cc_wl='-Wl,' + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6* | nonstopux*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi + +fi + +if test -z "$lt_cv_prog_cc_pic"; then + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 +else + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6 + + # Check to make sure the pic_flag actually works. + echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6 + if test "${lt_cv_prog_cc_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + 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 + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 + lt_cv_prog_cc_pic_works=no + +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + +fi + + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6 +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5 +echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;} + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then : + else + { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 +echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} + lt_cv_prog_cc_can_build_shared=no + fi +fi + +echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6 +if test "${lt_cv_prog_cc_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + lt_cv_prog_cc_static_works=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi + + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5 +echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6 + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6 +if test "${lt_cv_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +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.$ac_objext" +compiler_c_o=no +if { (eval echo configure:6142: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; 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 + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +fi + +compiler_c_o=$lt_cv_compiler_c_o +echo "$as_me:$LINENO: result: $compiler_c_o" >&5 +echo "${ECHO_T}$compiler_c_o" >&6 + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6 + if test "${lt_cv_compiler_o_lo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + save_objext="$ac_objext" + ac_objext=lo + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; 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 + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + ac_objext="$save_objext" + CFLAGS="$save_CFLAGS" + +fi + + compiler_o_lo=$lt_cv_compiler_o_lo + echo "$as_me:$LINENO: result: $compiler_o_lo" >&5 +echo "${ECHO_T}$compiler_o_lo" >&6 +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 "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&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 "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6 + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: 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 "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6 + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +int some_variable = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; 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 + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$compiler_rtti_exceptions" >&6 + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&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= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +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. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32*) + # 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 "$GCC" != yes; then + with_gnu_ld=no + fi + ;; +openbsd*) + with_gnu_ld=no + ;; +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* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + 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 $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # 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_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # 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. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \$# in + 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + 4) echo " \$2 \$3 \$4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; + *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + 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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${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 $linker_flags' + 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 $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${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* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + 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 $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$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* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + hardcode_direct=yes + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + 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 + esac + + shared_flag='-shared' + else + # not using gcc + if test "$host_cpu" = ia64; then + shared_flag='${wl}-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_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* | pw32*) + # 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 $compiler_flags `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$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[012]) + allow_undefined_flag='-undefined suppress' + ;; + *) # Darwin 1.3 on + allow_undefined_flag='-flat_namespace -undefined suppress' + ;; + esac + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. Also zsh mangles + # `"' quotes if we put them in here... so don't! + archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + 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 $linker_flags /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 $linker_flags' + 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 $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + 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* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + export_dynamic_flag_spec='${wl}-Bexport' + ;; + + solaris*) + # gcc --version < 3.0 without binutils cannot create self contained + # shared libraries reliably, requiring libgcc.a to resolve some of + # the object symbols generated in some cases. Libraries that use + # assert need libgcc.a to resolve __eprintf, for example. Linking + # a copy of libgcc.a into every shared library to guarantee resolving + # such symbols causes other problems: According to Tim Van Holder + # , C++ libraries end up with a separate + # (to the application) exception stack for one thing. + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + case `$CC --version 2>/dev/null` in + [12].*) + cat <&2 + +*** Warning: Releases of GCC earlier than version 3.0 cannot reliably +*** create self contained shared libraries on Solaris systems, without +*** introducing a dependency on libgcc.a. Therefore, libtool is disabling +*** -no-undefined support, which will at least allow you to build shared +*** libraries. However, you may find that when you link such libraries +*** into an application without using GCC, you have to manually add +*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to +*** upgrade to a newer version of GCC. Another option is to rebuild your +*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. + +EOF + no_undefined_flag= + ;; + esac + fi + # $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 $linker_flags' + 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 $linker_flags~$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 + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + 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 $linker_flags' + 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 $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6 +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&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 "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6 + +striplib= +old_striplib= +echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6 +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6 +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" + +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* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) 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. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + fi + hardcode_into_libs=yes + ;; + +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 + ;; + +bsdi4*) + version_type=linux + 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 $libdir' + shlibpath_var=LD_LIBRARY_PATH + 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" + export_dynamic_flag_spec=-rdynamic + # 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* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +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*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + 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 + hardcode_into_libs=yes + ;; + +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* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) version_type=irix ;; + esac + 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* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + 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 + ;; + 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}" + ;; + +# 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 + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + 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 + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case "$host_os" in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + 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$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + 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" + hardcode_into_libs=yes + ;; + +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 + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +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 + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + 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 "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&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*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6 + +echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6 +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&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 + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6 +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 (); +char (*f) (); + +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 +f = shl_load; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6 +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 () +{ +shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dld_shl_load=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6 +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +char (*f) (); + +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 +f = dlopen; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6 +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6 +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* 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 () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_svld_dlopen=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6 +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dld_link (); +int +main () +{ +dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dld_dld_link=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6 +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6 + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6 + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + 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 + + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6 + if test "${lt_cv_archive_cmds_need_lc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + $rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi +fi + + echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5 +echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6 + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS SED \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + 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 extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib 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 \ + global_symbol_to_c_name_address \ + 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 | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $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 ltmain.sh. +# +# Copyright (C) 1996-2000 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. + +# A sed that does not truncate output. +SED=$lt_SED + +# 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 "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# 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 add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# 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=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# 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=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_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_support=$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=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_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=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address + +# 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 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_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 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_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=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# 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 "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # 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-2000 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() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# 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 < 1) +# 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> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + ac_config_files="$ac_config_files unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config" + + + +cat >confcache <<\_ACEOF +# 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, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# 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 \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.54. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.54, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" + exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "unix-cc.mk" ) CONFIG_FILES="$CONFIG_FILES unix-cc.mk:unix-cc.in" ;; + "unix-def.mk" ) CONFIG_FILES="$CONFIG_FILES unix-def.mk:unix-def.in" ;; + "freetype-config" ) CONFIG_FILES="$CONFIG_FILES freetype-config" ;; + "ftconfig.h" ) CONFIG_HEADERS="$CONFIG_HEADERS ftconfig.h:ftconfig.in" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@version_info@,$version_info,;t t +s,@ft_version@,$ft_version,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@target@,$target,;t t +s,@target_cpu@,$target_cpu,;t t +s,@target_vendor@,$target_vendor,;t t +s,@target_os@,$target_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@XX_CFLAGS@,$XX_CFLAGS,;t t +s,@XX_ANSIFLAGS@,$XX_ANSIFLAGS,;t t +s,@RMF@,$RMF,;t t +s,@RMDIR@,$RMDIR,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@EGREP@,$EGREP,;t t +s,@FTSYS_SRC@,$FTSYS_SRC,;t t +s,@LIBZ@,$LIBZ,;t t +s,@SYSTEM_ZLIB@,$SYSTEM_ZLIB,;t t +s,@LN_S@,$LN_S,;t t +s,@ECHO@,$ECHO,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@LIBTOOL@,$LIBTOOL,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # 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_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # 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" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# 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=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# 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.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# 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.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + diff --git a/lib/freetype/builds/unix/configure.ac b/lib/freetype/builds/unix/configure.ac new file mode 100644 index 0000000..a90200a --- /dev/null +++ b/lib/freetype/builds/unix/configure.ac @@ -0,0 +1,116 @@ +dnl This file is part of the FreeType project. +dnl +dnl Process this file with autoconf to produce a configure script. +dnl + +AC_INIT +AC_CONFIG_SRCDIR([ftconfig.in]) + +dnl configuration file -- stay in 8.3 limit +AC_CONFIG_HEADER(ftconfig.h:ftconfig.in) + +dnl Don't forget to update VERSION.DLL! +version_info='9:3:3' +AC_SUBST(version_info) +ft_version=`echo $version_info | tr : .` +AC_SUBST(ft_version) + +dnl checks for system type +AC_CANONICAL_TARGET([]) + +dnl checks for programs +AC_PROG_CC +AC_PROG_CPP + +dnl get Compiler flags right. +if test "x$CC" = xgcc; then + XX_CFLAGS="-Wall" + XX_ANSIFLAGS="-pedantic -ansi" +else + case "$host" in + *-dec-osf*) + CFLAGS= + XX_CFLAGS="-std1 -g3" + XX_ANSIFLAGS= + ;; + *) + XX_CFLAGS= + XX_ANSIFLAGS= + ;; + esac +fi +AC_SUBST(XX_CFLAGS) +AC_SUBST(XX_ANSIFLAGS) + +AC_CHECK_PROG(RMF, rm, rm -f) +AC_CHECK_PROG(RMDIR, rmdir, rmdir) + +dnl Since this file will be finally moved to another directory we make +dnl the path of the install script absolute. This small code snippet has +dnl been taken from automake's `ylwrap' script. +AC_PROG_INSTALL +case "$INSTALL" in + /*) + ;; + */*) + INSTALL="`pwd`/$INSTALL" ;; +esac + +dnl checks for header files +AC_HEADER_STDC +AC_CHECK_HEADERS(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 + FTSYS_SRC='$(BASE_)ftsystem.c' +else + FTSYS_SRC='$(BUILD)/ftsystem.c' + + FT_MUNMAP_DECL + FT_MUNMAP_PARAM +fi +AC_SUBST(FTSYS_SRC) + +AC_CHECK_FUNCS(memcpy memmove) + + +dnl Check for system zlib +AC_ARG_WITH(zlib, + [ --without-zlib use internal zlib instead of system-wide]) +if test x$with_zlib != xno && test -z "$LIBZ"; then + AC_CHECK_LIB(z, gzsetparams, [AC_CHECK_HEADER(zlib.h, LIBZ='-lz')]) +fi +if test x$with_zlib != xno && test -n "$LIBZ"; then + CFLAGS="$CFLAGS -DFT_CONFIG_OPTION_SYSTEM_ZLIB" + LDFLAGS="$LDFLAGS $LIBZ" + SYSTEM_ZLIB=yes +fi +AC_SUBST(LIBZ) +AC_SUBST(CFLAGS) +AC_SUBST(LDFLAGS) +AC_SUBST(SYSTEM_ZLIB) + + + +AC_PROG_LIBTOOL + +dnl create the Unix-specific sub-Makefiles `builds/unix/unix-def.mk' +dnl and 'builds/unix/unix-cc.mk' that will be used by the build system +dnl +AC_CONFIG_FILES([unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config]) + +dnl re-generate the Jamfile to use libtool now +dnl +dnl AC_CONFIG_FILES([../../Jamfile:../../Jamfile.in]) + +AC_OUTPUT + +dnl end of configure.ac diff --git a/lib/freetype/builds/unix/detect.mk b/lib/freetype/builds/unix/detect.mk new file mode 100644 index 0000000..516f8ff --- /dev/null +++ b/lib/freetype/builds/unix/detect.mk @@ -0,0 +1,87 @@ +# +# FreeType 2 configuration file to detect a UNIX host platform. +# + + +# Copyright 1996-2000, 2002 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. + +.PHONY: setup + +ifeq ($(PLATFORM),ansi) + + # Note: this test is duplicated in "builds/toplevel.mk". + # + is_unix := $(strip $(wildcard /sbin/init) $(wildcard /usr/sbin/init) $(wildcard /hurd/auth)) + ifneq ($(is_unix),) + + PLATFORM := unix + + endif # test is_unix +endif # test PLATFORM ansi + +ifeq ($(PLATFORM),unix) + COPY := cp + DELETE := rm -f + + # If `devel' is the requested target, we use a special configuration + # file named `unix-dev.mk'. It disables optimization and libtool. + # + ifneq ($(findstring devel,$(MAKECMDGOALS)),) + CONFIG_FILE := unix-dev.mk + CC := gcc + devel: setup + .PHONY: devel + else + + # If `lcc' is the requested target, we use a special configuration + # file named `unix-lcc.mk'. It disables libtool for LCC. + # + ifneq ($(findstring lcc,$(MAKECMDGOALS)),) + CONFIG_FILE := unix-lcc.mk + CC := lcc + lcc: setup + .PHONY: lcc + else + + # If a Unix platform is detected, the configure script is called and + # `unix-def.mk' together with `unix-cc.mk' is created. + # + # Arguments to `configure' should be in the CFG variable. Example: + # + # make CFG="--prefix=/usr --disable-static" + # + # If you need to set CFLAGS or LDFLAGS, do it here also. + # + # Feel free to add support for other platform specific compilers in + # this directory (e.g. solaris.mk + changes here to detect the + # platform). + # + CONFIG_FILE := unix.mk + setup: unix-def.mk + unix: setup + .PHONY: unix + endif + endif + + setup: std_setup + + have_mk := $(strip $(wildcard $(OBJ_DIR)/Makefile)) + ifneq ($(have_mk),) + # we are building FT2 not in the src tree + unix-def.mk: $(TOP_DIR)/builds/unix/unix-def.in + $(TOP_DIR)/builds/unix/configure $(CFG) + else + unix-def.mk: $(TOP_DIR)/builds/unix/unix-def.in + cd builds/unix; ./configure $(CFG) + endif + +endif # test PLATFORM unix + +# EOF diff --git a/lib/freetype/builds/unix/freetype-config.in b/lib/freetype/builds/unix/freetype-config.in new file mode 100644 index 0000000..c5a3e5a --- /dev/null +++ b/lib/freetype/builds/unix/freetype-config.in @@ -0,0 +1,104 @@ +#! /bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ + +usage() +{ + cat <&2 +fi + +while test $# -gt 0 ; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + local_prefix=yes + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + local_prefix=yes + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --version) + echo @ft_version@ + exit 0 + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + --libtool) + echo_libtool=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +if test "$local_prefix" = "yes" ; then + if test "$exec_prefix_set" != "yes" ; then + exec_prefix=$prefix + fi +fi + +if test "$echo_prefix" = "yes" ; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes" ; then + echo $exec_prefix +fi + +if test "$echo_cflags" = "yes" ; then + cflags="-I@includedir@/freetype2" + if test "@includedir@" != "/usr/include" ; then + echo -I@includedir@ $cflags + else + echo $cflags + fi +fi + +if test "$echo_libs" = "yes" ; then + libs="-lfreetype @LIBZ@" + if test "@libdir@" != "/usr/lib" ; then + echo -L@libdir@ $libs + else + echo $libs + fi +fi + +if test "$echo_libtool" = "yes" ; then + convlib="libfreetype.la" + echo @libdir@/$convlib +fi + +# EOF diff --git a/lib/freetype/builds/unix/freetype2.m4 b/lib/freetype/builds/unix/freetype2.m4 new file mode 100644 index 0000000..21c6445 --- /dev/null +++ b/lib/freetype/builds/unix/freetype2.m4 @@ -0,0 +1,143 @@ +# Configure paths for FreeType2 +# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor + +dnl AC_CHECK_FT2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for FreeType2, and define FT2_CFLAGS and FT2_LIBS +dnl +AC_DEFUN(AC_CHECK_FT2, +[dnl +dnl Get the cflags and libraries from the freetype-config script +dnl +AC_ARG_WITH(ft-prefix, +[ --with-ft-prefix=PREFIX + Prefix where FreeType is installed (optional)], + ft_config_prefix="$withval", ft_config_prefix="") +AC_ARG_WITH(ft-exec-prefix, +[ --with-ft-exec-prefix=PREFIX + Exec prefix where FreeType is installed (optional)], + ft_config_exec_prefix="$withval", ft_config_exec_prefix="") +AC_ARG_ENABLE(freetypetest, +[ --disable-freetypetest Do not try to compile and run + a test FreeType program], + [], enable_fttest=yes) + +if test x$ft_config_exec_prefix != x ; then + ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix" + if test x${FT2_CONFIG+set} != xset ; then + FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config + fi +fi +if test x$ft_config_prefix != x ; then + ft_config_args="$ft_config_args --prefix=$ft_config_prefix" + if test x${FT2_CONFIG+set} != xset ; then + FT2_CONFIG=$ft_config_prefix/bin/freetype-config + fi +fi +AC_PATH_PROG(FT2_CONFIG, freetype-config, no) + +min_ft_version=ifelse([$1], ,6.1.0,$1) +AC_MSG_CHECKING(for FreeType - version >= $min_ft_version) +no_ft="" +if test "$FT2_CONFIG" = "no" ; then + no_ft=yes +else + FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags` + FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs` + ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + ft_min_major_version=`echo $min_ft_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + ft_min_minor_version=`echo $min_ft_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + ft_min_micro_version=`echo $min_ft_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test x$enable_fttest = xyes ; then + ft_config_is_lt="" + if test $ft_config_major_version -lt $ft_min_major_version ; then + ft_config_is_lt=yes + else + if test $ft_config_major_version -eq $ft_min_major_version ; then + if test $ft_config_minor_version -lt $ft_min_minor_version ; then + ft_config_is_lt=yes + else + if test $ft_config_minor_version -eq $ft_min_minor_version ; then + if test $ft_config_micro_version -lt $ft_min_micro_version ; then + ft_config_is_lt=yes + fi + fi + fi + fi + fi + if test x$ft_config_is_lt = xyes ; then + no_ft=yes + else + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $FT2_CFLAGS" + LIBS="$FT2_LIBS $LIBS" +dnl +dnl Sanity checks for the results of freetype-config to some extent +dnl + AC_TRY_RUN([ +#include +#include FT_FREETYPE_H +#include +#include + +int +main() +{ + FT_Library library; + FT_Error error; + + error = FT_Init_FreeType(&library); + + if (error) + return 1; + else + { + FT_Done_FreeType(library); + return 0; + } +} +],, no_ft=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi # test $ft_config_version -lt $ft_min_version + fi # test x$enable_fttest = xyes +fi # test "$FT2_CONFIG" = "no" +if test x$no_ft = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) +else + AC_MSG_RESULT(no) + if test "$FT2_CONFIG" = "no" ; then + echo "*** The freetype-config script installed by FreeType 2 could not be found." + echo "*** If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the FT2_CONFIG environment variable to the" + echo "*** full path to freetype-config." + else + if test x$ft_config_is_lt = xyes ; then + echo "*** Your installed version of the FreeType 2 library is too old." + echo "*** If you have different versions of FreeType 2, make sure that" + echo "*** correct values for --with-ft-prefix or --with-ft-exec-prefix" + echo "*** are used, or set the FT2_CONFIG environment variable to the" + echo "*** full path to freetype-config." + else + echo "*** The FreeType test program failed to run. If your system uses" + echo "*** shared libraries and they are installed outside the normal" + echo "*** system library path, make sure the variable LD_LIBRARY_PATH" + echo "*** (or whatever is appropiate for your system) is correctly set." + fi + fi + FT2_CFLAGS="" + FT2_LIBS="" + ifelse([$3], , :, [$3]) +fi +AC_SUBST(FT2_CFLAGS) +AC_SUBST(FT2_LIBS) +]) diff --git a/lib/freetype/builds/unix/ft-munmap.m4 b/lib/freetype/builds/unix/ft-munmap.m4 new file mode 100644 index 0000000..37ebbd9 --- /dev/null +++ b/lib/freetype/builds/unix/ft-munmap.m4 @@ -0,0 +1,31 @@ +## FreeType specific autoconf tests + +# serial 1 FT_MUNMAP_DECL + +AC_DEFUN(FT_MUNMAP_DECL, +[AC_MSG_CHECKING([whether munmap must be declared]) +AC_CACHE_VAL(ft_cv_munmap_decl, +[AC_TRY_COMPILE([ +#ifdef HAVE_UNISTD_H +#include +#endif +#include ], +[char *(*pfn) = (char *(*))munmap], +ft_cv_munmap_decl=no, +ft_cv_munmap_decl=yes)]) +AC_MSG_RESULT($ft_cv_munmap_decl) +if test $ft_cv_munmap_decl = yes; then + AC_DEFINE(NEED_MUNMAP_DECL,, + [Define to 1 if munmap() is not defined in ]) +fi]) + +AC_DEFUN(FT_MUNMAP_PARAM, +[AC_MSG_CHECKING([for munmap's first parameter type]) +AC_TRY_COMPILE([ +#include +#include +int munmap(void *, size_t);],, + AC_MSG_RESULT([void *]);AC_DEFINE(MUNMAP_USES_VOIDP,, + [Define to 1 if the first argument of munmap is of type void *]), + AC_MSG_RESULT([char *])) +]) diff --git a/lib/freetype/builds/unix/ft2unix.h b/lib/freetype/builds/unix/ft2unix.h new file mode 100644 index 0000000..c4299c3 --- /dev/null +++ b/lib/freetype/builds/unix/ft2unix.h @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2001 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 a Unix-specific version of that should be used */ + /* exclusively *after* installation of the library. */ + /* */ + /* It assumes that "/usr/local/include/freetype2" (or wathever is */ + /* returned by the "freetype-config --cflags" command) is in your */ + /* compilation include path. */ + /* */ + /* We don't need to do anything special in this release. However, for */ + /* FreeType 2.1, the following installation changes will be performed: */ + /* */ + /* - The contents of "freetype-2.1/include/freetype" will be installed */ + /* to "/usr/local/include/freetype2" instead of */ + /* "/usr/local/include/freetype2/freetype". */ + /* */ + /* - This file will #include , instead */ + /* of . */ + /* */ + /* - The contents of "ftheader.h" will be processed with `sed' to */ + /* replace all "" with "". */ + /* */ + /* - Adding "/usr/local/include/freetype2" to your compilation include */ + /* path will not be necessary anymore. The command */ + /* "freetype-config --cflags" will return an empty string. */ + /* */ + /* - Client applications which adhere to the new inclusion scheme */ + /* WILL NOT NEED TO BE MODIFIED to compile with FT 2.1! */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_UNIX_H__ +#define __FT2_BUILD_UNIX_H__ + + /* "/usr/local/include/freetype2" must be in your current inclusion path */ +#include + +#endif /* __FT2_BUILD_UNIX_H__ */ + + +/* END */ diff --git a/lib/freetype/builds/unix/ftconfig.in b/lib/freetype/builds/unix/ftconfig.in new file mode 100644 index 0000000..c751103 --- /dev/null +++ b/lib/freetype/builds/unix/ftconfig.in @@ -0,0 +1,261 @@ +/***************************************************************************/ +/* */ +/* ftconfig.in */ +/* */ +/* UNIX-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2000, 2002 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 header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + +#define HAVE_UNISTD_H 0 +#define HAVE_FCNTL_H 0 + +#define SIZEOF_INT 2 +#define SIZEOF_LONG 2 + +#define FT_SIZEOF_INT SIZEOF_INT +#define FT_SIZEOF_LONG SIZEOF_LONG + + + /* Preferred alignment of data */ +#define FT_ALIGNMENT 8 + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* IntN types */ + /* */ + /* Used to guarantee the size of some specific integers. */ + /* */ + typedef signed short FT_Int16; + typedef unsigned short FT_UInt16; + +#if FT_SIZEOF_INT == 4 + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == 4 + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + +#if FT_SIZEOF_LONG == 8 + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long + +#else + + /*************************************************************************/ + /* */ + /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ + /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ + /* `ftoption.h'. */ + /* */ + /* Note that this will produce many -ansi warnings during library */ + /* compilation, and that in many cases, the generated code will be */ + /* neither smaller nor faster! */ + /* */ +#ifdef FTCALC_USE_LONG_LONG + +#define FT_LONG64 +#define FT_INT64 long long + +#endif /* FTCALC_USE_LONG_LONG */ +#endif /* FT_SIZEOF_LONG == 8 */ + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) extern x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) extern "C" x +#else +#define FT_BASE_DEF( x ) extern x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/lib/freetype/builds/unix/ftsystem.c b/lib/freetype/builds/unix/ftsystem.c new file mode 100644 index 0000000..4ae260c --- /dev/null +++ b/lib/freetype/builds/unix/ftsystem.c @@ -0,0 +1,334 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* Unix-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 + /* we use our special ftconfig.h file, not the standard one */ +#include +#include FT_INTERNAL_DEBUG_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + /* memory-mapping includes and definitions */ +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#ifndef MAP_FILE +#define MAP_FILE 0x00 +#endif + +#ifdef MUNMAP_USES_VOIDP +#define MUNMAP_ARG_CAST void * +#else +#define MUNMAP_ARG_CAST char * +#endif + +#ifdef NEED_MUNMAP_DECL + +#ifdef __cplusplus + extern "C" +#else + extern +#endif + int + munmap( char* addr, + int len ); + +#define MUNMAP_ARG_CAST char * + +#endif /* NEED_DECLARATION_MUNMAP */ + + +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include +#include + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* ft_alloc */ + /* */ + /* */ + /* The memory allocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return malloc( size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_realloc */ + /* */ + /* */ + /* The memory reallocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return realloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_free */ + /* */ + /* */ + /* The memory release function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + free( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* */ + /* ft_close_stream */ + /* */ + /* */ + /* The function to close a stream. */ + /* */ + /* */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_close_stream( FT_Stream stream ) + { + munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + int file; + struct stat stat_buf; + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + + /* open the file */ + file = open( filepathname, O_RDONLY ); + if ( file < 0 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + return FT_Err_Cannot_Open_Resource; + } + + /* Here we ensure that a "fork" will _not_ duplicate */ + /* our opened input streams on Unix. This is critical */ + /* since it avoids some (possible) access control */ + /* issues and cleans up the kernel file table a bit. */ + /* */ +#ifdef F_SETFD +#ifdef FD_CLOEXEC + (void)fcntl( file, F_SETFD, FD_CLOEXEC ); +#else + (void)fcntl( file, F_SETFD, 1 ); +#endif /* FD_CLOEXEC */ +#endif /* F_SETFD */ + + if ( fstat( file, &stat_buf ) < 0 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not `fstat' file `%s'\n", filepathname )); + goto Fail_Map; + } + + stream->size = stat_buf.st_size; + stream->pos = 0; + stream->base = (unsigned char *)mmap( NULL, + stream->size, + PROT_READ, + MAP_FILE | MAP_PRIVATE, + file, + 0 ); + + if ( (long)stream->base == -1 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not `mmap' file `%s'\n", filepathname )); + goto Fail_Map; + } + + close( file ); + + stream->descriptor.pointer = stream->base; + stream->pathname.pointer = (char*)filepathname; + + stream->close = ft_close_stream; + stream->read = 0; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + + Fail_Map: + close( file ); + + stream->base = NULL; + stream->size = 0; + stream->pos = 0; + + return FT_Err_Cannot_Open_Stream; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)malloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + memory->free( memory, memory ); + } + + +/* END */ diff --git a/lib/freetype/builds/unix/install-sh b/lib/freetype/builds/unix/install-sh new file mode 100644 index 0000000..57a2fbd --- /dev/null +++ b/lib/freetype/builds/unix/install-sh @@ -0,0 +1,269 @@ +#!/bin/sh +# install - install a program, script, or datafile +# This originally came from X11R5 (mit/util/scripts/install.sh). + +scriptversion=2003-01-17.15 + +# Copyright 1991 by the Massachusetts Institute of Technology +# (FSF changes in the public domain.) +# +# 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= + +usage="Usage: $0 [OPTION]... SRCFILE DSTFILE + or: $0 -d DIR1 DIR2... + +In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. +In the second, create the directory path DIR. + +Options: +-b=TRANSFORMBASENAME +-c copy source (using $cpprog) instead of moving (using $mvprog). +-d create directories instead of installing files. +-g GROUP $chgrp installed files to GROUP. +-m MODE $chmod installed files to MODE. +-o USER $chown installed files to USER. +-s strip installed files (using $stripprog). +-t=TRANSFORM +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit 0;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + --version) echo "$0 $scriptversion"; exit 0;; + + *) if test -z "$src"; then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if test -z "$src"; then + echo "$0: no input file specified." >&2 + exit 1 +fi + +if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + instcmd=: + chmodcmd= + else + instcmd=$mkdirprog + 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 test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + dst=$dst/`basename "$src"` + 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 test ! -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 test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + test -d "$pathcomp" || $mkdirprog "$pathcomp" + pathcomp=$pathcomp/ + done +fi + +if test -n "$dir_arg"; then + $doit $instcmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + +else + # If we're going to rename the final executable, determine the name now. + if test -z "$transformarg"; then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename \ + | sed $transformarg`$transformbasename + fi + + # don't allow the sed command to completely eliminate the filename. + test -z "$dstfile" && dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/#inst.$$# + rmtmp=$dstdir/#rm.$$# + + # Trap to clean up those temp files at exit. + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Move or copy the file name to the temp name + $doit $instcmd "$src" "$dsttmp" && + + # 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. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now remove or move aside any old file at destination location. We + # try this two ways since rm can't unlink itself on some systems and + # the destination file might be busy for other reasons. In this case, + # the final cleanup might fail but the new file should still install + # successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" +fi && + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/freetype/builds/unix/install.mk b/lib/freetype/builds/unix/install.mk new file mode 100644 index 0000000..cfd24f8 --- /dev/null +++ b/lib/freetype/builds/unix/install.mk @@ -0,0 +1,93 @@ +# +# FreeType 2 installation instructions for Unix systems +# + + +# Copyright 1996-2000, 2002 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. + +# If you say +# +# make install DESTDIR=/tmp/somewhere/ +# +# don't forget the final backslash (this command is mainly for package +# maintainers). + + +.PHONY: install uninstall check + +# Unix installation and deinstallation targets. +install: $(PROJECT_LIBRARY) + $(MKINSTALLDIRS) $(DESTDIR)$(libdir) \ + $(DESTDIR)$(includedir)/freetype2/freetype/config \ + $(DESTDIR)$(includedir)/freetype2/freetype/internal \ + $(DESTDIR)$(includedir)/freetype2/freetype/cache \ + $(DESTDIR)$(bindir) \ + $(DESTDIR)$(datadir)/aclocal + $(LIBTOOL) --mode=install $(INSTALL) \ + $(PROJECT_LIBRARY) $(DESTDIR)$(libdir) + -for P in $(PUBLIC_H) ; do \ + $(INSTALL_DATA) \ + $$P $(DESTDIR)$(includedir)/freetype2/freetype ; \ + done + -for P in $(BASE_H) ; do \ + $(INSTALL_DATA) \ + $$P $(DESTDIR)$(includedir)/freetype2/freetype/internal ; \ + done + -for P in $(CONFIG_H) ; do \ + $(INSTALL_DATA) \ + $$P $(DESTDIR)$(includedir)/freetype2/freetype/config ; \ + done + -for P in $(CACHE_H) ; do \ + $(INSTALL_DATA) \ + $$P $(DESTDIR)$(includedir)/freetype2/freetype/cache ; \ + done + $(INSTALL_DATA) $(BUILD)/ft2unix.h $(DESTDIR)$(includedir)/ft2build.h + $(INSTALL_SCRIPT) -m 755 $(OBJ_BUILD)/freetype-config \ + $(DESTDIR)$(bindir)/freetype-config + $(INSTALL_SCRIPT) -m 644 $(BUILD)/freetype2.m4 \ + $(DESTDIR)$(datadir)/aclocal/freetype2.m4 + + +uninstall: + -$(LIBTOOL) --mode=uninstall $(RM) $(DESTDIR)$(libdir)/$(LIBRARY).$A + -$(DELETE) $(DESTDIR)$(includedir)/freetype2/freetype/cache/* + -$(DELDIR) $(DESTDIR)$(includedir)/freetype2/freetype/cache + -$(DELETE) $(DESTDIR)$(includedir)/freetype2/freetype/config/* + -$(DELDIR) $(DESTDIR)$(includedir)/freetype2/freetype/config + -$(DELETE) $(DESTDIR)$(includedir)/freetype2/freetype/internal/* + -$(DELDIR) $(DESTDIR)$(includedir)/freetype2/freetype/internal + -$(DELETE) $(DESTDIR)$(includedir)/freetype2/freetype/* + -$(DELDIR) $(DESTDIR)$(includedir)/freetype2/freetype + -$(DELDIR) $(DESTDIR)$(includedir)/freetype2 + -$(DELETE) $(DESTDIR)$(includedir)/ft2build.h + -$(DELETE) $(DESTDIR)$(bindir)/freetype-config + -$(DELETE) $(DESTDIR)$(datadir)/aclocal/freetype2.m4 + + +check: + @echo There is no validation suite for this package. + + +.PHONY: clean_project_unix distclean_project_unix + +# Unix cleaning and distclean rules. +# +clean_project_unix: + -$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S) + -$(DELETE) $(patsubst %.$O,%.$(SO),$(BASE_OBJECTS) $(OBJ_M) $(OBJ_S)) \ + $(CLEAN) + +distclean_project_unix: clean_project_unix + -$(DELETE) $(PROJECT_LIBRARY) + -$(DELETE) $(OBJ_DIR)/.libs/* + -$(DELDIR) $(OBJ_DIR)/.libs + -$(DELETE) *.orig *~ core *.core $(DISTCLEAN) + +# EOF diff --git a/lib/freetype/builds/unix/ltmain.sh b/lib/freetype/builds/unix/ltmain.sh new file mode 100644 index 0000000..7e0c9f4 --- /dev/null +++ b/lib/freetype/builds/unix/ltmain.sh @@ -0,0 +1,5062 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# 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 + +# 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) + execute_dlfiles="$execute_dlfiles $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" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --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 this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc* | xlc*) + 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= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # 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 + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + 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 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # 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 $run 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 + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + 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 "$pic_mode" != default) && + 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 + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + 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 + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + 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 + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-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 + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&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 + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # 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= + continue + ;; + 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 + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + 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: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | no/*-*-nonstopux*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + 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: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + 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) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + 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 + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + 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= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + 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 # arg + + # 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 # argument parsing loop + + 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 + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + 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 object directory. + 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 + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test $linkmode = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test $linkmode = oldlib && test $linkmode = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test $pass = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test $pass = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test $pass = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test $pass = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: Trying to link with static lib archive $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" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not used here." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test $pass != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test $linkmode = oldlib && test $linkmode = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test $pass = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test $linkmode != prog && test $linkmode != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # 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 \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test $pass = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test $pass = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test $linkmode = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test $linkmode = prog && test $pass != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test $linkmode = lib && test $hardcode_into_libs = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + 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 + if test $linkmode = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test $linkmode = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-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 + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test $linkmode = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test $linkmode = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + add="-l$name" + fi + + if test $linkmode = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test $linkmode = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # 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_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This system can not link to static lib archive $lib." + 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." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + 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 + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test $linkmode = lib; then + if test -n "$dependency_libs" && + { test $hardcode_into_libs != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test $link_all_deplibs != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # 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 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test $pass = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test $pass != dlopen; then + test $pass != scan && dependency_libs="$newdependency_libs" + if test $pass != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test $linkmode = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + 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" + objs="$objs$old_deplibs" + ;; + + lib) + # 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 + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' 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 + + 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. + 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] | [1-9][0-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] | [1-9][0-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] | [1-9][0-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) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$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="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + 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" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $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" + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring="" + ;; + *) + verstring="0.0" + ;; + esac + 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 + fi + + if test "$mode" != relink; then + # Remove our outputs. + $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}.* + 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 + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd*) + # Do not include libc due to us having libc/libc_r. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test $build_libtool_need_lc = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # 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: linker path does not have real file for library $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" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for file magic test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check below in file_magic test + if eval echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | egrep "$match_pattern_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: linker path does not have real file for library $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" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + echo "*** with $libname and none of the candidates passed a file format test" + echo "*** using a regex pattern. Last file checked: $potlib" + fi + 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 + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + 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." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + 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 + fi + 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 + if test $hardcode_into_libs = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $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\" + dep_rpath="$dep_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 dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # 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 + test -z "$dlname" && dlname=$soname + + 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) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $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\" + 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\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + save_deplibs="$deplibs" + for conv in $convenience; do + tmp_deplibs= + for test_deplib in $deplibs; do + if test "$test_deplib" != "$conv"; then + tmp_deplibs="$tmp_deplibs $test_deplib" + fi + done + deplibs="$tmp_deplibs" + done + eval cmds=\"$archive_cmds\" + deplibs="$save_deplibs" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # 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 + ;; + + obj) + 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$old_deplibs"; 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$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + 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" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + 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 + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + 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_support" = 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 + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + ;; + esac + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + 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 "$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 + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + 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" + + 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$old_deplibs" | $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" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + 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 void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 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*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -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 $need_relink = no || 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 "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + 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 + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + 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 + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + 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: + notinst_deplibs='$notinst_deplibs' +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'$exeext + 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 relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $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' + 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 + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $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$old_deplibs "`$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 in case 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 + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + 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" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # 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 + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $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='$tdlname' + +# 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 + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + 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 || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; 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 + *.$libext) + # 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= + relink_command= + # 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" + + if test -n "$relink_command"; then + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + 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\" + 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"` + ;; + *.$objext) + 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. + case $host in + *cygwin*|*mingw*) + wrapper=`echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; 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'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $wrapper ;; + *) . ./$wrapper ;; + esac + + 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 + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + 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 + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $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 $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + 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_cmd='$SHELL $0 --finish$current_libdirs' + else + exit 0 + fi + ;; + + # 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\" + 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 the \`-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 + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # 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 prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) 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 + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + 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 $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit 1 +fi + +# 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: + + clean remove files from the build directory + 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 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build 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, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +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 + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -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-fast-install disable the fast-install mode + -no-install link a not-installable executable + -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/lib/freetype/builds/unix/mkinstalldirs b/lib/freetype/builds/unix/mkinstalldirs new file mode 100644 index 0000000..d2d5f21 --- /dev/null +++ b/lib/freetype/builds/unix/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +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" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/lib/freetype/builds/unix/unix-cc.in b/lib/freetype/builds/unix/unix-cc.in new file mode 100644 index 0000000..9de770d --- /dev/null +++ b/lib/freetype/builds/unix/unix-cc.in @@ -0,0 +1,84 @@ +# template for Unix-specific compiler definitions +# + +CC := @CC@ + +ifndef LIBTOOL + LIBTOOL := $(BUILD)/libtool +endif + + +# The object file extension (for standard and static libraries). This can be +# .o, .tco, .obj, etc., depending on the platform. +# +O := lo +SO := o + + +# The library file extension (for standard and static libraries). This can +# be .a, .lib, etc., depending on the platform. +# +A := la +SA := a + + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := lib$(PROJECT) + + +# Path inclusion flag. Some compilers use a different flag than `-I' to +# specify an additional include path. Examples are `/i=' or `-J'. +# +I := -I + + +# C flag used to define a macro before the compilation of a given source +# object. Usually it is `-D' like in `-DDEBUG'. +# +D := -D + + +# The link flag used to specify a given library file on link. Note that +# this is only used to compile the demo programs, not the library itself. +# +L := -l + + +# Target flag. +# +T := -o # Don't remove this comment line! We need the space after `-o'. + + +# C flags +# +# These should concern: debug output, optimization & warnings. +# +# Use the ANSIFLAGS variable to define the compiler flags used to enfore +# ANSI compliance. +# +CFLAGS := -c @XX_CFLAGS@ @CFLAGS@ + +# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. +# +ANSIFLAGS := @XX_ANSIFLAGS@ + +# C compiler to use -- we use libtool! +# +# +CCraw := $(CC) +CC := $(LIBTOOL) --mode=compile $(CCraw) + +# Linker flags. +# +LDFLAGS := @LDFLAGS@ + + +# Library linking +# +LINK_LIBRARY = $(LIBTOOL) --mode=link $(CCraw) -o $@ $(OBJECTS_LIST) \ + -rpath $(libdir) -version-info $(version_info) \ + $(LDFLAGS) + +# EOF diff --git a/lib/freetype/builds/unix/unix-def.in b/lib/freetype/builds/unix/unix-def.in new file mode 100644 index 0000000..790bf89 --- /dev/null +++ b/lib/freetype/builds/unix/unix-def.in @@ -0,0 +1,99 @@ +# +# FreeType 2 configuration rules templates for Unix + configure +# + + +# Copyright 1996-2000, 2002 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 TOP_DIR + TOP_DIR := . +endif +TOP_DIR := $(shell cd $(TOP_DIR); pwd) + +DELETE := @RMF@ +DELDIR := @RMDIR@ +SEP := / +HOSTSEP := $(SEP) +BUILD := $(TOP_DIR)/builds/unix +PLATFORM := unix + +# this is used for `make distclean' and `make install' +ifndef OBJ_BUILD + OBJ_BUILD := $(BUILD) +endif + +# don't use `:=' here since the path stuff will be included after this file +# +FTSYS_SRC = @FTSYS_SRC@ + +INSTALL := @INSTALL@ +INSTALL_DATA := @INSTALL_DATA@ +INSTALL_PROGRAM := @INSTALL_PROGRAM@ +INSTALL_SCRIPT := @INSTALL_SCRIPT@ +MKINSTALLDIRS := $(BUILD)/mkinstalldirs + +DISTCLEAN += $(OBJ_BUILD)/config.cache \ + $(OBJ_BUILD)/config.log \ + $(OBJ_BUILD)/config.status \ + $(OBJ_BUILD)/unix-def.mk \ + $(OBJ_BUILD)/unix-cc.mk \ + $(OBJ_BUILD)/ftconfig.h \ + $(OBJ_BUILD)/freetype-config \ + $(LIBTOOL) \ + $(OBJ_BUILD)/Makefile + + +# Standard installation variables. +# +prefix := @prefix@ +exec_prefix := @exec_prefix@ +libdir := @libdir@ +bindir := @bindir@ +includedir := @includedir@ +datadir := @datadir@ + +version_info := @version_info@ + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f $TOP_DIR/Makefile setup [options] +# make -f $TOP_DIR/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(shell cd $(TOP_DIR)/objs; pwd) +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + + +# The SYSTEM_ZLIB macro is defined if the user wishes to link dynamically +# with its system wide zlib. If SYSTEM_ZLIB is 'yes', the zlib part of the +# ftgzip module is not compiled in. +SYSTEM_ZLIB := @SYSTEM_ZLIB@ + + +# The NO_OUTPUT macro is appended to command lines in order to ignore +# the output of some programs. +# +NO_OUTPUT := 2> /dev/null + +# EOF diff --git a/lib/freetype/builds/unix/unix-dev.mk b/lib/freetype/builds/unix/unix-dev.mk new file mode 100644 index 0000000..2f10734 --- /dev/null +++ b/lib/freetype/builds/unix/unix-dev.mk @@ -0,0 +1,25 @@ +# +# FreeType 2 Configuration rules for Unix + GCC +# +# Development version without optimizations & libtool +# and no installation. +# + + +# Copyright 1996-2000 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 $(TOP_DIR)/builds/unix/unixddef.mk +BUILD := $(TOP_DIR)/builds/devel + +include $(TOP_DIR)/builds/compiler/gcc-dev.mk +include $(TOP_DIR)/builds/link_std.mk + +# EOF diff --git a/lib/freetype/builds/unix/unix-lcc.mk b/lib/freetype/builds/unix/unix-lcc.mk new file mode 100644 index 0000000..4ade02c --- /dev/null +++ b/lib/freetype/builds/unix/unix-lcc.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Configuration rules for Unix + LCC +# +# Development version without optimizations & libtool +# and no installation. +# + + +# Copyright 1996-2000 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 $(TOP_DIR)/builds/unix/unixddef.mk +include $(TOP_DIR)/builds/compiler/unix-lcc.mk +include $(TOP_DIR)/builds/link_std.mk + +# EOF diff --git a/lib/freetype/builds/unix/unix.mk b/lib/freetype/builds/unix/unix.mk new file mode 100644 index 0000000..fae08b3 --- /dev/null +++ b/lib/freetype/builds/unix/unix.mk @@ -0,0 +1,57 @@ +# +# FreeType 2 configuration rules for UNIX platforms +# + + +# Copyright 1996-2000, 2002 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. + +have_mk := $(strip $(wildcard $(TOP_DIR)/builds/unix/unix-def.mk)) +ifneq ($(have_mk),) + include $(TOP_DIR)/builds/unix/unix-def.mk + include $(TOP_DIR)/builds/unix/unix-cc.mk +else + # we are building FT2 not in the src tree + include $(OBJ_DIR)/unix-def.mk + include $(OBJ_DIR)/unix-cc.mk +endif + +ifdef BUILD_PROJECT + + .PHONY: clean_project distclean_project + + # Now include the main sub-makefile. It contains all the rules used to + # build the library with the previous variables defined. + # + include $(TOP_DIR)/builds/$(PROJECT).mk + + + # The cleanup targets. + # + clean_project: clean_project_unix + distclean_project: distclean_project_unix + + + # This final rule is used to link all object files into a single library. + # It is part of the system-specific sub-Makefile because not all + # librarians accept a simple syntax like + # + # librarian library_file {list of object files} + # + $(PROJECT_LIBRARY): $(OBJECTS_LIST) +ifdef CLEAN_LIBRARY + -$(CLEAN_LIBRARY) $(NO_OUTPUT) +endif + $(LINK_LIBRARY) + +endif + +include $(TOP_DIR)/builds/unix/install.mk + +# EOF diff --git a/lib/freetype/builds/unix/unixddef.mk b/lib/freetype/builds/unix/unixddef.mk new file mode 100644 index 0000000..1ea1543 --- /dev/null +++ b/lib/freetype/builds/unix/unixddef.mk @@ -0,0 +1,56 @@ +# +# FreeType 2 configuration rules templates for +# development under Unix with no configure script (gcc only) +# + + +# Copyright 1996-2000 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 TOP_DIR + TOP_DIR := . +endif +TOP_DIR := $(shell cd $(TOP_DIR); pwd) + +DELETE := rm -f +SEP := / +HOSTSEP := $(SEP) + +# we use a special devel ftoption.h +BUILD := $(TOP_DIR)/builds/devel + +# do not set the platform to `unix', or libtool will trick you +PLATFORM := unixdev + + +# The directory where all object files are placed. +# +ifndef OBJ_DIR + OBJ_DIR := $(shell cd $(TOP_DIR)/objs; pwd) +endif + + +# library file name +# +LIBRARY := lib$(PROJECT) + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + + +# +NO_OUTPUT := 2> /dev/null + +# EOF diff --git a/lib/freetype/builds/vms/descrip.mms b/lib/freetype/builds/vms/descrip.mms new file mode 100644 index 0000000..54392d1 --- /dev/null +++ b/lib/freetype/builds/vms/descrip.mms @@ -0,0 +1,25 @@ +# +# FreeType 2 system rules for VMS +# + + +# Copyright 2001 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([],[--.include],[--.src.base]) + +OBJS=ftsystem.obj + +all : $(OBJS) + library/create [--.lib]freetype.olb $(OBJS) + +ftsystem.obj : ftsystem.c ftconfig.h + +# EOF diff --git a/lib/freetype/builds/vms/ftconfig.h b/lib/freetype/builds/vms/ftconfig.h new file mode 100644 index 0000000..3174ffe --- /dev/null +++ b/lib/freetype/builds/vms/ftconfig.h @@ -0,0 +1,238 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* VMS-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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 header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /*************************************************************************/ + + +#ifndef FTCONFIG_H +#define FTCONFIG_H + + + /* Include the header file containing all developer build options */ +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + +#define HAVE_UNISTD_H 1 +#define HAVE_FCNTL_H 1 + +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 + +#define FT_SIZEOF_INT 4 +#define FT_SIZEOF_LONG 4 + + + /* Preferred alignment of data */ +#define FT_ALIGNMENT 8 + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* IntN types */ + /* */ + /* Used to guarantee the size of some specific integers. */ + /* */ + typedef signed short FT_Int16; + typedef unsigned short FT_UInt16; + +#if FT_SIZEOF_INT == 4 + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == 4 + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + +#if FT_SIZEOF_LONG == 8 + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long + +#else + + /*************************************************************************/ + /* */ + /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ + /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ + /* `ftoption.h'. */ + /* */ + /* Note that this will produce many -ansi warnings during library */ + /* compilation, and that in many cases, the generated code will be */ + /* neither smaller nor faster! */ + /* */ +#ifdef FTCALC_USE_LONG_LONG + +#define FT_LONG64 +#define FT_INT64 long long + +#endif /* FTCALC_USE_LONG_LONG */ + +#endif /* FT_SIZEOF_LONG == 8 */ + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + +#ifndef BASE_DEF + +#ifdef __cplusplus +#define BASE_DEF( x ) extern "C" x +#else +#define BASE_DEF( x ) extern x +#endif + +#endif /* !BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ +#ifdef __cplusplus + +#define FT_CALLBACK_DEF( x ) extern "C" x +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" + +#else + +#define FT_CALLBACK_DEF( x ) static x +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF + +#endif /* __cplusplus */ + +FT_END_HEADER + +#endif /* FTCONFIG_H */ + + +/* END */ diff --git a/lib/freetype/builds/vms/ftsystem.c b/lib/freetype/builds/vms/ftsystem.c new file mode 100644 index 0000000..8a198e6 --- /dev/null +++ b/lib/freetype/builds/vms/ftsystem.c @@ -0,0 +1,321 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* VMS-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 + /* we use our special ftconfig.h file, not the standard one */ +#include +#include FT_INTERNAL_DEBUG_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + /* memory-mapping includes and definitions */ +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#ifndef MAP_FILE +#define MAP_FILE 0x00 +#endif + +#ifdef MUNMAP_USES_VOIDP +#define MUNMAP_ARG_CAST void * +#else +#define MUNMAP_ARG_CAST char * +#endif + +#ifdef NEED_MUNMAP_DECL + +#ifdef __cplusplus + extern "C" +#else + extern +#endif + int + munmap( char* addr, + int len ); + +#define MUNMAP_ARG_CAST char * + +#endif /* NEED_DECLARATION_MUNMAP */ + + +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include +#include + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* ft_alloc */ + /* */ + /* */ + /* The memory allocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return malloc( size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_realloc */ + /* */ + /* */ + /* The memory reallocation function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return realloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* ft_free */ + /* */ + /* */ + /* The memory release function. */ + /* */ + /* */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + free( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* */ + /* ft_close_stream */ + /* */ + /* */ + /* The function to close a stream. */ + /* */ + /* */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_close_stream( FT_Stream stream ) + { + munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + int file; + struct stat stat_buf; + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + + /* open the file */ + file = open( filepathname, O_RDONLY ); + if ( file < 0 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + return FT_Err_Cannot_Open_Resource; + } + + if ( fstat( file, &stat_buf ) < 0 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not `fstat' file `%s'\n", filepathname )); + goto Fail_Map; + } + + stream->size = stat_buf.st_size; + stream->pos = 0; + stream->base = (unsigned char *)mmap( NULL, + stream->size, + PROT_READ, + MAP_FILE | MAP_PRIVATE, + file, + 0 ); + + if ( (long)stream->base == -1 ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not `mmap' file `%s'\n", filepathname )); + goto Fail_Map; + } + + close( file ); + + stream->descriptor.pointer = stream->base; + stream->pathname.pointer = (char*)filepathname; + + stream->close = ft_close_stream; + stream->read = 0; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + + Fail_Map: + close( file ); + + stream->base = NULL; + stream->size = 0; + stream->pos = 0; + + return FT_Err_Cannot_Open_Stream; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)malloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + memory->free( memory, memory ); + } + + +/* END */ diff --git a/lib/freetype/builds/win32/detect.mk b/lib/freetype/builds/win32/detect.mk new file mode 100644 index 0000000..d7fc029 --- /dev/null +++ b/lib/freetype/builds/win32/detect.mk @@ -0,0 +1,61 @@ +# +# FreeType 2 configuration file to detect a Win32 host platform. +# + + +# Copyright 1996-2000 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. + + +.PHONY: setup + + +ifeq ($(PLATFORM),ansi) + + # Detecting Windows NT is easy, as the OS variable must be defined and + # contains `Windows_NT'. Untested with Windows 2K, but I guess it should + # work... + # + ifeq ($(OS),Windows_NT) + + is_windows := 1 + + # We test for the COMSPEC environment variable, then run the `ver' + # command-line program to see if its output contains the word `Windows'. + # + # If this is true, we are running a win32 platform (or an emulation). + # + else + ifdef COMSPEC + is_windows := $(findstring Windows,$(strip $(shell ver))) + endif + endif # test NT + + ifdef is_windows + + PLATFORM := win32 + + endif +endif # test PLATFORM ansi + +ifeq ($(PLATFORM),win32) + + DELETE := del + COPY := copy + + # gcc Makefile by default + CONFIG_FILE := w32-gcc.mk + SEP := / + ifeq ($(firstword $(CC)),cc) + CC := gcc + endif + + ifneq ($(findstring list,$(MAKECMDGOALS)),) # test for the "list" target + dump_target_list: + @echo \ No newline at end of file diff --git a/lib/freetype/builds/win32/ftdebug.c b/lib/freetype/builds/win32/ftdebug.c new file mode 100644 index 0000000..5816a4f --- /dev/null +++ b/lib/freetype/builds/win32/ftdebug.c @@ -0,0 +1,211 @@ +/***************************************************************************/ +/* */ +/* ftdebug.c */ +/* */ +/* Debugging and logging component for Win32 (body). */ +/* */ +/* Copyright 1996-2001, 2002 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). */ + /* */ + /* - error mode */ + /* */ + /* Only error messages are generated. */ + /* */ + /* - release mode: */ + /* */ + /* No error message is sent or generated. The code is free from any */ + /* debugging parts. */ + /* */ + /*************************************************************************/ + + +#include +#include FT_INTERNAL_DEBUG_H + + +#ifdef FT_DEBUG_LEVEL_ERROR + + +# include +# include +# include + +# include + + + FT_EXPORT_DEF( void ) + FT_Message( const char* fmt, ... ) + { + static char buf[8192]; + va_list ap; + + + va_start( ap, fmt ); + vsprintf( buf, fmt, ap ); + OutputDebugStringA( buf ); + va_end( ap ); + } + + + FT_EXPORT_DEF( void ) + FT_Panic( const char* fmt, ... ) + { + static char buf[8192]; + va_list ap; + + + va_start( ap, fmt ); + vsprintf( buf, fmt, ap ); + OutputDebugStringA( buf ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + + +# ifdef FT_DEBUG_LEVEL_TRACE + + + /* array of trace levels, initialized to 0 */ + int ft_trace_levels[trace_count]; + + /* define array of trace toggle names */ +# define FT_TRACE_DEF( x ) #x , + + static const char* ft_trace_toggles[trace_count + 1] = + { +# include FT_INTERNAL_TRACE_H + NULL + }; + +# undef FT_TRACE_DEF + + + /*************************************************************************/ + /* */ + /* Initialize the tracing sub-system. This is done by retrieving the */ + /* value of the "FT2_DEBUG" environment variable. It must be a list of */ + /* toggles, separated by spaces, `;' or `,'. Example: */ + /* */ + /* "any:3 memory:6 stream:5" */ + /* */ + /* This will request that all levels be set to 3, except the trace level */ + /* for the memory and stream components which are set to 6 and 5, */ + /* respectively. */ + /* */ + /* See the file for details of the */ + /* available toggle names. */ + /* */ + /* The level must be between 0 and 6; 0 means quiet (except for serious */ + /* runtime errors), and 6 means _very_ verbose. */ + /* */ + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + const char* ft2_debug = getenv( "FT2_DEBUG" ); + + + if ( ft2_debug ) + { + const char* p = ft2_debug; + const char* q; + + + for ( ; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) + continue; + + /* read toggle name, followed by ':' */ + q = p; + while ( *p && *p != ':' ) + p++; + + if ( *p == ':' && p > q ) + { + int n, i, len = p - q; + int level = -1, found = -1; + + + for ( n = 0; n < trace_count; n++ ) + { + const char* toggle = ft_trace_toggles[n]; + + + for ( i = 0; i < len; i++ ) + { + if ( toggle[i] != q[i] ) + break; + } + + if ( i == len && toggle[i] == 0 ) + { + found = n; + break; + } + } + + /* read level */ + p++; + if ( *p ) + { + level = *p++ - '0'; + if ( level < 0 || level > 6 ) + level = -1; + } + + if ( found >= 0 && level >= 0 ) + { + if ( found == trace_any ) + { + /* special case for "any" */ + for ( n = 0; n < trace_count; n++ ) + ft_trace_levels[n] = level; + } + else + ft_trace_levels[found] = level; + } + } + } + } + } + + +# else /* !FT_DEBUG_LEVEL_TRACE */ + + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + /* nothing */ + } + + +# endif /* !FT_DEBUG_LEVEL_TRACE */ + +#endif /* FT_DEBUG_LEVEL_ERROR */ + +/* END */ diff --git a/lib/freetype/builds/win32/visualc/freetype.dsp b/lib/freetype/builds/win32/visualc/freetype.dsp new file mode 100644 index 0000000..1512059 --- /dev/null +++ b/lib/freetype/builds/win32/visualc/freetype.dsp @@ -0,0 +1,345 @@ +# Microsoft Developer Studio Project File - Name="freetype" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=freetype - Win32 Debug Singlethreaded +!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 Singlethreaded" +!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 "freetype - Win32 Debug Multithreaded" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Release Multithreaded" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Release Singlethreaded" (based on "Win32 (x86) Static Library") +!MESSAGE "freetype - Win32 Debug Singlethreaded" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.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 "..\..\..\objs\release" +# PROP Intermediate_Dir "..\..\..\objs\release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /MD /Za /W4 /GX /Zi /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c +# SUBTRACT CPP /nologo /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\..\objs\freetype214.lib" + +!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 "..\..\..\objs\debug" +# PROP Intermediate_Dir "..\..\..\objs\debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /MDd /Za /W4 /GX /Zi /Od /I "..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /FD /GZ /c +# SUBTRACT CPP /nologo /X /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\..\objs\freetype214_D.lib" + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug Multithreaded" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "freetype___Win32_Debug_Multithreaded" +# PROP BASE Intermediate_Dir "freetype___Win32_Debug_Multithreaded" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\..\objs\debug_mt" +# PROP Intermediate_Dir "..\..\..\objs\debug_mt" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Za /W3 /Gm /GX /ZI /Od /I "..\freetype\include\\" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_FLAT_COMPILE" /YX /FD /GZ /c +# SUBTRACT BASE CPP /X +# ADD CPP /MTd /Za /W4 /GX /Zi /Od /I "..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /FD /GZ /c +# SUBTRACT CPP /nologo /X /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"lib\freetype200b8_D.lib" +# ADD LIB32 /nologo /out:"..\..\..\objs\freetype214MT_D.lib" + +!ELSEIF "$(CFG)" == "freetype - Win32 Release Multithreaded" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "freetype___Win32_Release_Multithreaded" +# PROP BASE Intermediate_Dir "freetype___Win32_Release_Multithreaded" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\..\objs\release_mt" +# PROP Intermediate_Dir "..\..\..\objs\release_mt" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Za /W3 /GX /O2 /I "..\freetype\include\\" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_FLAT_COMPILE" /YX /FD /c +# ADD CPP /MT /Za /W4 /GX /Zi /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c +# SUBTRACT CPP /nologo /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"lib\freetype200b8.lib" +# ADD LIB32 /nologo /out:"..\..\..\objs\freetype214MT.lib" + +!ELSEIF "$(CFG)" == "freetype - Win32 Release Singlethreaded" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "freetype___Win32_Release_Singlethreaded" +# PROP BASE Intermediate_Dir "freetype___Win32_Release_Singlethreaded" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\..\objs\release_st" +# PROP Intermediate_Dir "..\..\..\objs\release_st" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /Za /W4 /GX /Zi /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /Za /W4 /GX /Zi /O2 /I "..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /FD /c +# SUBTRACT CPP /nologo /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype206.lib" +# ADD LIB32 /out:"..\..\..\objs\freetype214ST.lib" +# SUBTRACT LIB32 /nologo + +!ELSEIF "$(CFG)" == "freetype - Win32 Debug Singlethreaded" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "freetype___Win32_Debug_Singlethreaded" +# PROP BASE Intermediate_Dir "freetype___Win32_Debug_Singlethreaded" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\..\objs\debug_st" +# PROP Intermediate_Dir "..\..\..\objs\debug_st" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /Za /W4 /Gm /GX /Zi /Od /I "..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /FD /GZ /c +# SUBTRACT BASE CPP /X /YX +# ADD CPP /Za /W4 /GX /Zi /Od /I "..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "FT_DEBUG_LEVEL_ERROR" /D "FT_DEBUG_LEVEL_TRACE" /FD /GZ /c +# SUBTRACT CPP /nologo /X /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo /out:"..\..\..\objs\freetype206_D.lib" +# ADD LIB32 /nologo /out:"..\..\..\objs\freetype214ST_D.lib" + +!ENDIF + +# Begin Target + +# Name "freetype - Win32 Release" +# Name "freetype - Win32 Debug" +# Name "freetype - Win32 Debug Multithreaded" +# Name "freetype - Win32 Release Multithreaded" +# Name "freetype - Win32 Release Singlethreaded" +# Name "freetype - Win32 Debug Singlethreaded" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\autohint\autohint.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\bdf\bdf.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\cff\cff.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\base\ftbase.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\cache\ftcache.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\ftdebug.c +# ADD CPP /Ze +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\base\ftglyph.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\gzip\ftgzip.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\base\ftinit.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\base\ftmm.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\base\ftsystem.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\pcf\pcf.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\pfr\pfr.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\psaux\psaux.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\pshinter\pshinter.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\psnames\psmodule.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\raster\raster.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\sfnt\sfnt.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\smooth\smooth.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\truetype\truetype.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\type1\type1.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\cid\type1cid.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\type42\type42.c +# SUBTRACT CPP /Fr +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\winfonts\winfnt.c +# SUBTRACT CPP /Fr +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\ft2build.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\freetype\config\ftconfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\freetype\config\ftheader.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\freetype\config\ftmodule.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\freetype\config\ftoption.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\freetype\config\ftstdlib.h +# End Source File +# End Group +# End Target +# End Project diff --git a/lib/freetype/builds/win32/visualc/freetype.dsw b/lib/freetype/builds/win32/visualc/freetype.dsw new file mode 100644 index 0000000..b1b375d --- /dev/null +++ b/lib/freetype/builds/win32/visualc/freetype.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.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/freetype/builds/win32/visualc/index.html b/lib/freetype/builds/win32/visualc/index.html new file mode 100644 index 0000000..d491c5a --- /dev/null +++ b/lib/freetype/builds/win32/visualc/index.html @@ -0,0 +1,27 @@ + +
+FreeType 2 Project Files for Visual C++ +
+ + +

FreeType 2 Project Files for Visual C++

+ +

This directory contains a project file for Visual C++, named + freetype.dsp. It will compile the following libraries + from the FreeType 2.1.4 sources:

+ +
    +
    +    freetype214.lib     - release build; single threaded
    +    freetype214_D.lib   - debug build;   single threaded
    +    freetype214MT.lib   - release build; multi-threaded
    +    freetype214MT_D.lib - debug build;   multi-threaded
    +  
    +
+ +

Build directories are placed in the top-level "objs" directory

+ +

Enjoy :-)

+ + + \ No newline at end of file diff --git a/lib/freetype/builds/win32/w32-bcc.mk b/lib/freetype/builds/win32/w32-bcc.mk new file mode 100644 index 0000000..5c24724 --- /dev/null +++ b/lib/freetype/builds/win32/w32-bcc.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Borland C++ on Win32 +# + + +# Copyright 1996-2000 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. + + +SEP := / +include $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/bcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-bccd.mk b/lib/freetype/builds/win32/w32-bccd.mk new file mode 100644 index 0000000..80e44ff --- /dev/null +++ b/lib/freetype/builds/win32/w32-bccd.mk @@ -0,0 +1,26 @@ +# +# FreeType 2 Borland C++ on Win32 + debugging +# + + +# Copyright 1996-2000 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. + + +SEP := / + +include $(TOP_DIR)/builds/win32/win32-def.mk +BUILD := $(TOP_DIR)/builds/devel + +include $(TOP_DIR)/builds/compiler/bcc-dev.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-dev.mk b/lib/freetype/builds/win32/w32-dev.mk new file mode 100644 index 0000000..17aa0aa --- /dev/null +++ b/lib/freetype/builds/win32/w32-dev.mk @@ -0,0 +1,38 @@ +# +# FreeType 2 configuration rules for Win32 + GCC +# +# Development version without optimizations. +# + + +# Copyright 1996-2000 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 version requires that GNU Make is invoked from the Windows +# Shell (_not_ Cygwin BASH)! +# + +ifndef TOP_DIR + TOP_DIR := . +endif + +SEP := / + +include $(TOP_DIR)/builds/win32/win32-def.mk +BUILD := $(TOP_DIR)/builds/devel + +include $(TOP_DIR)/builds/compiler/gcc-dev.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + + + +# EOF diff --git a/lib/freetype/builds/win32/w32-gcc.mk b/lib/freetype/builds/win32/w32-gcc.mk new file mode 100644 index 0000000..86f6ddd --- /dev/null +++ b/lib/freetype/builds/win32/w32-gcc.mk @@ -0,0 +1,29 @@ +# +# FreeType 2 configuration rules for Win32 + GCC +# + + +# Copyright 1996-2000 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 separator must be set before including win32-def +# as it defaults to "\" on Win32 +SEP := / + +# include Win32-specific definitions +include $(TOP_DIR)/builds/win32/win32-def.mk + +# include gcc-specific definitions +include $(TOP_DIR)/builds/compiler/gcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-icc.mk b/lib/freetype/builds/win32/w32-icc.mk new file mode 100644 index 0000000..8b63ce0 --- /dev/null +++ b/lib/freetype/builds/win32/w32-icc.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 configuration rules for Win32 + IBM Visual Age C++ +# + + +# Copyright 1996-2000 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 $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/visualage.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-intl.mk b/lib/freetype/builds/win32/w32-intl.mk new file mode 100644 index 0000000..4f6a034 --- /dev/null +++ b/lib/freetype/builds/win32/w32-intl.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 configuration rules for Intel C/C++ on Win32 +# + + +# Copyright 1996-2000 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. + + +SEP := / +include $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/intelc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-lcc.mk b/lib/freetype/builds/win32/w32-lcc.mk new file mode 100644 index 0000000..a147c4c --- /dev/null +++ b/lib/freetype/builds/win32/w32-lcc.mk @@ -0,0 +1,24 @@ +# +# FreeType 2 configuration rules for Win32 + LCC +# + + +# Copyright 1996-2000 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. + + +SEP := / +include $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/win-lcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF + diff --git a/lib/freetype/builds/win32/w32-mingw32.mk b/lib/freetype/builds/win32/w32-mingw32.mk new file mode 100644 index 0000000..236e810 --- /dev/null +++ b/lib/freetype/builds/win32/w32-mingw32.mk @@ -0,0 +1,31 @@ +# +# FreeType 2 configuration rules for mingw32 +# + + +# Copyright 1996-2000 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 separator must be set before including win32-def +# as it defaults to "\" on Win32 +SEP := / + +# include Win32-specific definitions +include $(TOP_DIR)/builds/win32/win32-def.mk + +LIBRARY := lib$(PROJECT) + +# include gcc-specific definitions +include $(TOP_DIR)/builds/compiler/gcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-vcc.mk b/lib/freetype/builds/win32/w32-vcc.mk new file mode 100644 index 0000000..459e187 --- /dev/null +++ b/lib/freetype/builds/win32/w32-vcc.mk @@ -0,0 +1,23 @@ +# +# FreeType 2 Visual C++ on Win32 +# + + +# Copyright 1996-2000 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. + + +SEP := / +include $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/visualc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/builds/win32/w32-wat.mk b/lib/freetype/builds/win32/w32-wat.mk new file mode 100644 index 0000000..ab250dc --- /dev/null +++ b/lib/freetype/builds/win32/w32-wat.mk @@ -0,0 +1,26 @@ +# +# FreeType 2 configuration rules for Watcom C/C++ +# + + +# Copyright 1996-2000 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. + + +SEP := / +ISEP := $(strip \ ) + +include $(TOP_DIR)/builds/win32/win32-def.mk +include $(TOP_DIR)/builds/compiler/watcom.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF + diff --git a/lib/freetype/builds/win32/win32-def.mk b/lib/freetype/builds/win32/win32-def.mk new file mode 100644 index 0000000..9b43a03 --- /dev/null +++ b/lib/freetype/builds/win32/win32-def.mk @@ -0,0 +1,61 @@ +# +# FreeType 2 Win32 specific definitions +# + + +# Copyright 1996-2000 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. + + +DELETE := del +HOSTSEP := $(strip \ ) +BUILD := $(TOP_DIR)$(SEP)builds$(SEP)win32 +PLATFORM := win32 + +# by default, we use "\" as a separator on Win32 +# but certain compilers accept "/" as well +# +ifndef SEP + SEP := $(HOSTSEP) +endif + + +# The directory where all object files are placed. +# +# This lets you build the library in your own directory with something like +# +# set TOP_DIR=.../path/to/freetype2/top/dir... +# set OBJ_DIR=.../path/to/obj/dir +# make -f %TOP_DIR%/Makefile setup [options] +# make -f %TOP_DIR%/Makefile +# +ifndef OBJ_DIR + OBJ_DIR := $(TOP_DIR)$(SEP)objs +endif + + +# The directory where all library files are placed. +# +# By default, this is the same as $(OBJ_DIR); however, this can be changed +# to suit particular needs. +# +LIB_DIR := $(OBJ_DIR) + + +# The name of the final library file. Note that the DOS-specific Makefile +# uses a shorter (8.3) name. +# +LIBRARY := $(PROJECT) + + +# The NO_OUTPUT macro is used to ignore the output of commands. +# +NO_OUTPUT = 2> nul + +# EOF diff --git a/lib/freetype/config.mk b/lib/freetype/config.mk new file mode 100644 index 0000000..236e810 --- /dev/null +++ b/lib/freetype/config.mk @@ -0,0 +1,31 @@ +# +# FreeType 2 configuration rules for mingw32 +# + + +# Copyright 1996-2000 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 separator must be set before including win32-def +# as it defaults to "\" on Win32 +SEP := / + +# include Win32-specific definitions +include $(TOP_DIR)/builds/win32/win32-def.mk + +LIBRARY := lib$(PROJECT) + +# include gcc-specific definitions +include $(TOP_DIR)/builds/compiler/gcc.mk + +# include linking instructions +include $(TOP_DIR)/builds/link_dos.mk + +# EOF diff --git a/lib/freetype/configure b/lib/freetype/configure new file mode 100644 index 0000000..1198380 --- /dev/null +++ b/lib/freetype/configure @@ -0,0 +1,60 @@ +#!/bin/sh +# +# Call the 'configure' script located in 'builds/unix'. +# +# This should re-generate the following files: +# +# config.mk +# Jamfile +# install +# + +if test "x$GNUMAKE" = x; then + GNUMAKE=make +fi + +if test -z "`$GNUMAKE -v 2>/dev/null | grep GNU`"; then + echo "Sorry, GNU make is required to build FreeType2." >&2 + echo "Please try \`GNUMAKE= $0'." >&2 + exit 1 +fi + +# Uh, oh. This is taken from autoconf. They know what they are doing... + +if expr a : '\(a\)' >/dev/null 2>&1; then + ft_expr=expr +else + ft_expr=false +fi + +ft2_dir=`(dirname "$0") 2>/dev/null || +$ft_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +abs_curr_dir=`pwd` +abs_ft2_dir=`cd "$ft2_dir" && pwd` + +# build a dummy Makefile if we are not building in the source tree + +if test "$abs_curr_dir" != "$abs_ft2_dir"; then + echo "OBJ_DIR=$abs_curr_dir" > Makefile + echo "TOP_DIR=$abs_ft2_dir" >> Makefile + echo "OBJ_BUILD=$abs_curr_dir" >> Makefile + echo "LIBTOOL=$abs_curr_dir/libtool" >> Makefile + echo "include $abs_ft2_dir/Makefile" >> Makefile +fi + +# call make + +CFG="$@" $GNUMAKE setup unix + +# eof diff --git a/lib/freetype/descrip.mms b/lib/freetype/descrip.mms new file mode 100644 index 0000000..0692443 --- /dev/null +++ b/lib/freetype/descrip.mms @@ -0,0 +1,73 @@ +# +# FreeType 2 build system -- top-level Makefile for OpenVMS +# + + +# Copyright 2001 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. + + +all : + define freetype [--.include.freetype] + define psaux [-.psaux] + define autohint [-.autohint] + define base [-.base] + define cache [-.cache] + define cff [-.cff] + define cid [-.cid] + define pcf [-.pcf] + define psnames [-.psnames] + define raster [-.raster] + define sfnt [-.sfnt] + define smooth [-.smooth] + define truetype [-.truetype] + define type1 [-.type1] + define winfonts [-.winfonts] + if f$search("lib.dir") .eqs. "" then create/directory [.lib] + set default [.builds.vms] + $(MMS)$(MMSQUALIFIERS) + set default [--.src.autohint] + $(MMS)$(MMSQUALIFIERS) + set default [-.base] + $(MMS)$(MMSQUALIFIERS) + set default [-.bdf] + $(MMS)$(MMSQUALIFIERS) + set default [-.cache] + $(MMS)$(MMSQUALIFIERS) + set default [-.cff] + $(MMS)$(MMSQUALIFIERS) + set default [-.cid] + $(MMS)$(MMSQUALIFIERS) + set default [-.pcf] + $(MMS)$(MMSQUALIFIERS) + set default [-.pfr] + $(MMS)$(MMSQUALIFIERS) + set default [-.psaux] + $(MMS)$(MMSQUALIFIERS) + set default [-.pshinter] + $(MMS)$(MMSQUALIFIERS) + set default [-.psnames] + $(MMS)$(MMSQUALIFIERS) + set default [-.raster] + $(MMS)$(MMSQUALIFIERS) + set default [-.sfnt] + $(MMS)$(MMSQUALIFIERS) + set default [-.smooth] + $(MMS)$(MMSQUALIFIERS) + set default [-.truetype] + $(MMS)$(MMSQUALIFIERS) + set default [-.type1] + $(MMS)$(MMSQUALIFIERS) + set default [-.type42] + $(MMS)$(MMSQUALIFIERS) + set default [-.winfonts] + $(MMS)$(MMSQUALIFIERS) + set default [--] + +# EOF diff --git a/lib/freetype/devel/ft2build.h b/lib/freetype/devel/ft2build.h new file mode 100644 index 0000000..da8b655 --- /dev/null +++ b/lib/freetype/devel/ft2build.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001 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 a development version of that is used + * to build the library in debug mode. Its only difference with + * the reference is that is forces the use of the local "ftoption.h" + * which contains different settings for all configuration macros + * + * to use it, you must define the environment variable FT2_BUILD_INCLUDE + * to point to the directory containing these two files ("ft2build.h" and + * "ftoption.h"), then invoke Jam as usual + */ + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#define FT_CONFIG_OPTIONS_H + +#include + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/lib/freetype/devel/ftoption.h b/lib/freetype/devel/ftoption.h new file mode 100644 index 0000000..df14c5a --- /dev/null +++ b/lib/freetype/devel/ftoption.h @@ -0,0 +1,502 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include + + /* + * this is a special developer version of "ftoption.h", it is used + * to define all debugging options, as well as the TrueType bytecode + * interpreter + */ + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in "$BUILD/freetype/config/ftoption.h", where "$BUILD" */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory "builds/" by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file to "$BUILD/ft2build.h" and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H */ + /* #include */ + /* */ + /* will use "$BUILD/myftoptions.h" instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is . */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit ints is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining here the macro FT_CONFIG_OPTION_FORCE_INT64. */ + /* */ + /* For most compilers, this will only create compilation warnings */ + /* when building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file "ftconfig.h" either statically, or through Autoconf */ + /* on platforms that support it. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses 'zlib' to */ + /* partially uncompress the file on the fly (see src/base/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this "feature". Note that */ + /* this will however force you to link the zlib to any program that */ + /* also uses FreeType. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's "ftgzip" component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* do not #undef this macro here, since the build system might */ + /* define for certain configurations */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This allows FreeType to be used with the PostScript language, using */ + /* the GhostScript interpreter. */ + /* */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4kByte. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ +#define FT_DEBUG_LEVEL_ERROR +#define FT_DEBUG_LEVEL_TRACE + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable "FT_DEBUG_MEMORY" is also defined! */ + /* */ +#define FT_DEBUG_MEMORY + + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. Note that there are */ + /* important patent issues related to the use of the interpreter. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* do not #undef this macro here, since the build system might */ + /* define for certain configurations */ + /* */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scale */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* */ + +/* + * the FT_CONFIG_OPTION_CHESTER_XXXX macros are used to toggle some recent + * improvements to the auto-hinter contributed by David Chester. They will + * most likely disappear completely in the next release. For now, you should + * always keep them defined + * + */ +#define FT_CONFIG_OPTION_CHESTER_HINTS + +#ifdef FT_CONFIG_OPTION_CHESTER_HINTS + +# define FT_CONFIG_CHESTER_SMALL_F +# define FT_CONFIG_CHESTER_ASCENDER +# define FT_CONFIG_CHESTER_SERIF +# define FT_CONFIG_CHESTER_STEM +# define FT_CONFIG_CHESTER_BLUE_SCALE + +#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */ + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/lib/freetype/docs/CHANGES b/lib/freetype/docs/CHANGES new file mode 100644 index 0000000..0a8e3f8 --- /dev/null +++ b/lib/freetype/docs/CHANGES @@ -0,0 +1,2036 @@ +LATEST CHANGES BETWEEN 2.1.4 and 2.1.3 + + I. IMPORTANT BUG FIXES + + - updated to newest libtool version, fixes build problems on various + platforms. + + - a fix in the Gzip stream reader, it couldn't read certain .gz files + properly due to a small typo. In certain cases, FreeType could also + loop endlessly when trying to load tiny gzipped files. + + - the configure script now tries to use the system-wide zlib when + it finds one (instead of the copy found in src/gzip). And + "freetype-config" has been updated to return relevant flags in this + case when invoked with "--libs" (e.g. "-lzlib") + + - certain fonts couldn't be loaded by 2.1.3 because they lacked a + Unicode charmap (e.g. SYMBOL.TTF). FreeType erroneously rejected + them. + + - the CFF loader was modified to accept fonts which only + contain a subset of their reference charset. This prevented the + correct use of PDF-embedded fonts. + + - the logic to detect Unicode charmaps has been modified. this is required + to support fonts which include both 16-bit and 32-bit charmaps (like + very recent asian ones) using the new 10 and 12 SFNT formats. + + - the TrueType loader now limits the depth of composite glyphs. This is + necessary to prevent broken fonts to break the engine by blowing the + stack with recursive glyph definitions. + + - the CMap cache is now capable of managing UCS-4 character codes that + are mapped through extended charmaps in recent TrueType/OpenType fonts + + - the cache sub-system now properly manages out-of-memory conditions, + instead of blindly reporting them to the caller. This means that it + will try to empty the cache before restarting its allocations to see + if that can help. + + - the PFR driver didn't return the list of available embedded bitmaps + properly. + + II. IMPORTANT CHANGES + + - David Chester contributed some enhancements to the auto-hinter that + significantly increase the quality of its output. The Postscript hinter + was also improved in several ways.. + + - the FT_RENDER_MODE_LIGHT render mode was implemented + + - a new API, called FT_Get_BDF_Property has been added to FT_BDF_H to + retrieve BDF properties from BDF _and_ PCF font files. THIS IS STILL + EXPERIMENTAL, since it hasn't been properly tested yet. + + - a Windows FNT specific API has been added, mostly to access font + headers. This is used by Wine + + - TrueType tables without a "hmtx" table are now tolerated when an + incremental interface is used. This happens for certain Type42 fonts + passed from Ghostscript to FreeType. + + - the PFR font driver is now capable of returning the font family and + style names when they're available (instead of the sole "FontID"). This + is performed by parsing an *undocumented* portion of the font file !! + + III. MISCELLANEOUS + + - the path stroker in FT_STROKER_H has entered beta stage. It now works + very well, but it's interface might change a bit in the future. More + on this in later releases + + - the documentation for FT_Size_Metrics didn't appear properly in the + API reference + + - the file docs/VERSION.DLL has been updated to explain versioning + with FreeType (i.e. comparing release/libtool/so numbers, and how + to use them in Autoconf scripts) + + - the installation documentation has been seriously revamped. Everything + is now in the "docs" directory. + +============================================================================== +LATEST CHANGES BETWEEN 2.1.3 and 2.1.2 + + I. IMPORTANT BUG FIXES + + - FT_Vector_Transform had been incorrectly modified in 2.1.2, resulting + in incorrect transformations being applied (for example, rotations + were processed in opposite angles). + + - The format 8 and 12 TrueType charmap enumeration routines have been + fixed (FT_Get_Next_Char returned invalid values). + + - The PFR font driver returned incorrect advance widths if the outline + and metrics resolution defined in the font file were different. + + - FT_Glyph_To_Bitmap now returns successfully when called with an + FT_BitmapGlyph argument (it previously returned an error). + + - A bug in the Type 1 loader that prevented valid font bounding boxes to + be loaded from multiple master fonts. + + - The SFNT validation code has been rewritten. FreeType can now load + "broken" fonts that were usable on Windows, but not with previous + versions of the library. + + - The computation of bearings in the BDF driver has been fixed. + + - The Postscript hinter crashed when trying to hint certain glyphs (more + precisely, when trying to apply hints to an empty glyph outline). + + - The TrueType glyph loader now supports composites in "Apple format" + (they differ slightly from Microsoft/OpenType ones in the way transform + offsets are computed). + + - FreeType was very slow at opening certain asian CID/CFF fonts, due + to fixed increment in dynamic array re-allocations. This has been + changed to exponential behaviour to get acceptable performance + + II. IMPORTANT CHANGES + + - the PCF driver now supports gzip-compressed font files natively. This + means that you'll be able to use all these bitmap fonts that come + with XFree86 with FreeType (and libXft/libXft2, by extension). + + - The automatic and postscript hinters have both been updated. This + results in a relatively important increase of rendering quality since + many nasty defaults have been supressed. Please visit the web page: + + http://www.freetype.org/hinting/smooth-hinting.html + + for additional details on this topic. + + - The "load_flags" parameter of FT_Load_Glyph is now an FT_Int32 + (instead of just being an FT_Int). This breaks source and binary + compatibility for 16bit systems only, while retaining both of them for + 32 and 64 bit ones. + + Some new flags have been added consequently: + + FT_LOAD_NO_AUTOHINT :: Disable the use of the auto-hinter + (but not native format hinters). + + FT_LOAD_TARGET_NORMAL :: Hint and render for normal anti-aliased + displays. + + FT_LOAD_TARGET_MONO :: Hint and render for 1-bit displays. + + FT_LOAD_TARGET_LCD :: Hint and render for horizontal RGB or BGR + sub-pixel displays (like LCD screens). + THIS IS STILL EXPERIMENTAL! + + FT_LOAD_TARGET_LCD_V :: Same as FT_LOAD_TARGET_LCD, for vertical + sub-pixel displays (like rotated LCD + screens). THIS IS STILL EXPERIMENTAL! + + FT_LOAD_MONOCHROME is still supported, but only affects rendering, not + the hinting. + + Note that the 'ftview' demo program available in the 'ft2demos' package + has been updated to support LCD-optimized display on non-paletted + displays (under Win32 and X11) + + - The PFR driver now supports embedded bitmaps (all formats supported), + and returns correct kerning metrics for all glyphs + + - The TrueType charmap loader now supports certain "broken" fonts that + load under Windows without problems. + + - The cache API has been slightly modified (it's still a beta!): + + - The type FTC_ImageDesc has been removed; it is now replaced by + FTC_ImageTypeRec. Note that one of its fields is a `load_flag' + parameter for FT_Load_Glyph. + + - The field "num_grays" of FT_SBitRec has been changed to "max_grays" + in order to fit within a single byte. Its maximum value is thus 255 + (instead of 256 as previously). + + + III. MISCELLANEOUS + + - Added support for the DESTDIR variable during "make install". This + simplifies packaging of FreeType. + + - included modified copies of the ZLib sources in 'src/gzip' in order + to support gzip-compressed PCF fonts. We do not use the system-provided + zlib for now, though this is a probable enhancement for future releases + + - The DocMaker tool used to generate the on-line API reference has been + completely rewritten. It is now located in + "src/tools/docmaker/docmaker.py". Features: + + - better cross-referenced output + - more polished output + - uses Python regular expressions (though it didn't speed the + program) + - much more modular structure, which allows for different "backends" + in order to generate HTML, XML, or whatever format. + + One can regenerate the API reference by calling: + + python src/tools/docmaker/docmaker.py \ + --prefix=ft2 \ + --title=FreeType-2.1.3 \ + --output= + include/freetype/*.h \ + include/freetype/config/*.h \ + include/freetype/cache/*.h + + - A new, experimental, support for incremental font loading (i.e., + loading of fonts where the glyphs are not in the font file itself, but + provided by an external component, like a Postscript interpreter) has + been added by Graham Asher. This is still work in progress, however. + + - A new, EXPERIMENTAL, path stroker has been added. It doesn't suffer + from severe rounding errors and treat bezier arcs directly. Still + work in progress (i.e. not part of the official API). See the file + for some of the details. + + - The massive re-formatting of sources and internal re-design is still + under-way. Many internal functions, constants, and types have been + renamed. + + +======================================================================== + +LATEST CHANGES BETWEEN 2.1.2 and 2.1.1 + + I. IMPORTANT BUG FIXES + + - Many font drivers didn't select a Unicode charmap by default when + a new face was opened (with the FT_CONFIG_OPTION_USE_CMAPS options + enabled), causing many applications to not be able to display text + correctly with the 2.1.x releases. + + - The PFR driver had a bug in its composite loading code that produces + incorrectly placed accents with many fonts. + + - The Type42 driver crashed sometimes due to a nasty bug. + + - The Type 1 custom encoding charmap didn't handle the case where the + first glyph index wasn't 0. + + - A serious typo in the TrueType composite loader produced incorrectly + placed glyphs in fonts like "Wingdings" and a few others. + + + II. MISCELLANEOUS + + - The Win32 Visual C++ project file has been updated to include the + PFR driver as well. + + - "freetype.m4" is now installed by default by "make install" on Unix + systems. + + - The function FT_Get_PS_Font_Info now works with CID and Type42 fonts + as well. + + +======================================================================== + +LATEST CHANGES BETWEEN 2.1.1 and 2.1.0 + + I. IMPORTANT BUG FIXES + + - The `version_info' returned by `freetype-config' in 2.1.0 returned an + invalid value. It now returns 9:1:3 (2.0.9 returned 9:0:3). + + - Version 2.1.0 couldn't be linked against applications on Win32 and + Amiga systems due to a new debug function that wasn't properly + propagated to the system-specific directory in `builds'. + + - Various MacOS and Mac OS X specific fixes. + + - Fixed a bug in the TrueType charmap validation routines that made + version 2.1.0 too restrictive -- many popular fonts have been + rejected. + + - There was still a very small difference between the monochrome glyph + bitmaps produced by FreeType 1.x and FreeType 2.x with the bytecode + interpreter enabled. This was caused by an invalid flag setting in + the TrueType glyph loader, making the rasterizer change its drop-out + control mode. Now theresults should _really_ be completely identical. + + - The TrueType name table loader has been improved to support many + popular though buggy Asian fonts. It now ignores empty name entries, + invalid pointer offsets and a few other incorrect subtleties. + Moreover, name strings are now loaded on demand, which reduces the + memory load of many faces (e.g. the ARIAL.TTF font file contains a + 10kByte name table with 70 names). + + - Fixed a bug in the Postscript hinter that prevented family blues + substitution to happen correctly. + + + II. NEW FEATURES + + - Three new font drivers in this release: + + * A BDF font driver, contributed by Franco Zappa Nardelli, heavily + modified by Werner Lemberg. It also supports anti-aliased bitmaps + (using a slightly extended BDF format). + + * A Type42 font driver, contributed by Roberto Alameda. It is + still experimental but seems to work relatively well. + + * A PFR font driver, contributed by David Turner himself. It doesn't + support PFR hinting -- note that BitStream has at least two patents + on this format! + + + III. MISCELLANEOUS + + - The cache sub-system has been optimized in important ways. Cache hits + are now significantly faster. For example, using the CMap cache is + about twice faster than calling FT_Get_Char_Index on most platforms. + Similarly, using an SBit cache is about five times faster than loading + the bitmaps from a bitmap file, and 300 to 500 times faster than + generating them from a scalable format. + + Note that you should recompile your sources if you designed a custom + cache class for the FT2 Cache subsystem, since the changes performed + are source, but not binary, compatible. + + +======================================================================== + +LATEST CHANGES BETWEEN 2.1.0 and 2.0.9 + + I. IMPORTANT BUG FIXES + + - The TrueType bytecode interpreter has been fixed to produce + _exactly_ the same output as FreeType 1.x. Previous differences + were due to slightly distinct fixed-point computation routines + used to perform dot products and vector length measurements. + + It seems that native TrueType hinting is _extremely_ sensitive + to rounding errors. The required vector computation routines have + been optimized and placed within the "ttinterp.c" file. + + - Fixed the parsing of accelerator tables in the PCF font driver. + + - Fixed the Type1 glyph loader routine used to compute the font's + maximum advance width. + + II. NEW FEATURES + + - The `configure' script used on Unix systems has been modified to + check that GNU Make is being used to build the library. Otherwise, + it will display a message proposing to use the GNUMAKE environment + variable to name it. + + The Unix-specific file README.UNX has been modified accordingly. + + + III. MISCELLANEOUS + + - The FreeType License in `docs/FTL.txt' has been updated to include + a proposed preferred disclaimer. If you are using FreeType in your + products, you are encouraged (but not mandated) to use the following + text in your documentation: + + """ + Portions of this software are copyright © 1996-2002 The FreeType + Project (www.freetype.org). All rights reserved. + """ + + - The default size of the render pool has been reduced to 16kByte. + This shouldn't result in any noticeable performance penalty, unless + you are using the engine as-is to render very large and complex + glyphs. + + - The FreeType 2 redesign has begun. More information can be found + at this URL: + + http://www.freetype.org/freetype2/redesign.html + + The following internal changes have been performed within the sources + of this release: + + - Many internal types have been renamed to increase consistency. + The following should be true, except for public types: + + * All structure types have a name ending in "Rec" (short for + `record'). + + * A pointer-to-structure type has the same name as the + structure, _without_ the "Rec" suffix. + + Example: + + typedef struct FooRec_ + { + ... + + } FooRec, *Foo; + + - Many internal macros have been renamed to increase consistency. + The following should be true: + + * All macros have a name beginning with "FT_". This required + a few changes like + + ALLOC => FT_ALLOC + FREE => FT_FREE + REALLOC => FT_REALLOC + + * All macros are completely UPPERCASE. This required a few + changes like: + + READ_Short => FT_READ_SHORT + NEXT_Short => FT_NEXT_SHORT + GET_ULongLE => FT_GET_ULONG_LE + MEM_Set => FT_MEM_SET + MEM_Copy => FT_MEM_COPY + etc. + + * Whenever possible, all macro names follow the + FT__ pattern. For example + + ACCESS_Frame => FT_FRAME_ENTER + FORGET_Frame => FT_FRAME_EXIT + EXTRACT_Frame => FT_FRAME_EXTRACT + RELEASE_Frame => FT_FRAME_RELEASE + + FILE_Pos => FT_STREAM_POS + FILE_Seek => FT_STREAM_SEEK + FILE_Read => FT_STREAM_READ + FILE_ReadAt => FT_STREAM_READ_AT + READ_Fields => FT_STREAM_READ_FIELDS + + - Many internal functions have been renamed to follow the + FT__ pattern. For example: + + FT_Seek_Stream => FT_Stream_Seek + FT_Read_Stream_At => FT_Stream_ReadAt + FT_Done_Stream => FT_Stream_Close + FT_New_Stream => FT_Stream_Open + FT_New_Memory_Stream => FT_Stream_OpenMemory + FT_Extract_Frame => FT_Stream_ExtractFrame + + Note that method names do not contain "_". + + - The FT_ALLOC_ARRAY and FT_REALLOC_ARRAY have been replaced + with FT_NEW_ARRAY and FT_RENEW_ARRAY which do not take a type + as the fourth argument. Instead, the array element type size + is computed automatically from the type of the target pointer + used. + + - A new object class, FT_CMap, has been introduced. These + internal objects are used to model character maps. This eases + the support of additional charmap types within the engine. + + - A new configuration file named "ftstdlib.h" has been added + to `include/freetype/config'. It is used to define aliases + for _every_ routine of the ISO C library that the font engine + uses. Each aliases has a "ft_" prefix (e.g. "ft_strlen" is an + alias for "strlen"). + + This is used to ease the porting of FreeType 2 to exotic runtime + environments where the ISO C Library isn't available (e.g. + XFree86 extension modules). + + More details are available in the "ChangeLog" file. + + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.9 and 2.0.8 + + I. IMPORTANT BUG FIXES + + - Certain fonts like "foxjump.ttf" contain broken name tables with + invalid entries and wild offsets. This caused FreeType to crash when + trying to load them. + + The SFNT `name' table loader has been fixed to be able to support + these strange fonts. + + Moreover, the code in charge of processing this table has been changed + to always favour Windows-formatted entries over other ones. Hence, a + font that works on Windows but not on the Mac will load cleanly in + FreeType and report accurate values for Family & PostScript names. + + - The CID font driver has been fixed. It unfortunately returned a + Postscript Font name with a leading slash, as in + "/MunhwaGothic-Regular". + + - FreeType 2 should now compile fine on AIX 4.3.3 as a shared library. + + - A bug in the Postscript hinter has been found and fixed, removing + un-even stem widths at small pixel sizes (like 14-17). + + This improves the quality of a certain number of Postscript fonts. + + + II. NEW FEATURES + + - A new function named `FT_Library_Version' has been added to return + the current library's major, minor, and patch version numbers. This + is important since the macros FREETYPE_MAJOR, FREETYPE_MINOR, and + FREETYPE_PATCH cannot be used when the library is dynamically linked + by a program. + + - Two new APIs have been added: `FT_Get_First_Char' and + `FT_Get_Next_Char'. + + Together, these can be used to iterate efficiently over the currently + selected charmap of a given face. Read the API reference for more + details. + + + III. MISCELLANEOUS + + - The FreeType sources are under heavy internal re-factoring. As a + consequence, we have created a branch named "STABLE" on the CVS to + hold all future releases/fixes in the 2.0.x family. + + The HEAD branch now contains the re-factored sources and shouldn't be + used for testing or packaging new releases. In case you would like + to access the 2.0.9 sources from our CVS repository, use the tag + `VER-2-0-9'. + + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.8 and 2.0.7 + + I. IMPORTANT BUG FIXES + + - There was a small but nasty bug in "freetype-config.in" which + caused the "freetype-config" script to fail on Unix. + + This didn't prevent the installation of the library or even + its execution, but caused problems when trying to compile many + Unix packages that depend on it. + + - Some TrueType or OpenType fonts embedded in PDF documents do + not have a 'cmap', 'post' and 'name' as is required by the + specification. FreeType no longer refuses to load such fonts. + + - various fixes to the PCF font driver + + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.7 and 2.0.6 + + I. IMPORTANT BUG FIXES + + - Fixed two bugs in the Type 1 font driver. The first one resulted in a + memory leak in subtle cases. The other one caused FreeType to crash + when trying to load ".gsf" files (Ghostscript so-called Postscript + fonts). + + (This made _many_ KDE applications crash on certain systems. FreeType + _is_ becoming a critical system component on Linux :-) + + - Fixed a memory leak in the CFF font driver. + + - Fixed a memory leak in the PCF font driver. + + - Fixed the Visual C++ project file "builds/win32/visualc/freetype.dsp" + since it didn't include the Postscript hinter component, causing + errors at build time. + + - Fixed a small rendering bug in the anti-aliased renderer that only + occurred when trying to draw thin (less than 1 pixel) strokes. + + - Fixed "builds/unix/freetype2.a4" which is used to generate a valid + "freetype2.m4" for use with autoconf. + + - Fixed the OpenVMS Makefiles. + + + II. MISCELLANEOUS + + - Added "configure" and "install" scripts to the top-level directory. + A GNU-style installation is thus now easily possible with + + ./configure + make + make install + + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.6 and 2.0.5 + + I. IMPORTANT BUG FIXES + + - It wasn't possible to load embedded bitmaps when the auto-hinter was + used. This is now fixed. + + - The TrueType font driver didn't load some composites properly (the + sub-glyphs were slightly shifted, and this was only noticeable when + using monochrome rendering). + + - Various fixes to the auto-hinter. They merely improve the output of + sans-serif fonts. Note that there are still problems with serifed + fonts and composites (accented characters). + + - All scalable font drivers erroneously returned un-fitted glyph + advances when hinting was requested. This created problems for a + number of layout applications. This is a very old bug that got + undetected mainly because most test/demo program perform rounding + explicitly or implicitly (through the cache). + + - FT_Glyph_To_Bitmap() did erroneously modify the source glyph in + certain cases. + + - "glnames.py" still contained a bug that made FreeType return invalid + names for certain glyphs. + + - The library crashed when loading certain Type 1 fonts like "sadn.pfb" + ("Stalingrad Normal"), which appear to contain pathetic font info + dictionaries. + + - The TrueType glyph loader is now much more paranoid and checks everything + when loading a given glyph image. This was necessary to avoid + problems (crashes and/or memory overwrites) with broken fonts that + came from a really buggy automatic font converter. + + + II. IMPORTANT UPDATES AND NEW FEATURES + + - Important updates to the Mac-specific parts of the library. + + - The caching sub-system has been completely re-designed, and its API + has evolved (the old one is still supported for backwards + compatibility). + + The documentation for it is not yet completed, sorry. For now, you + are encouraged to continue using the old API. However, the ftview + demo program in the ft2demos package has already been updated to use + the new caching functions. + + - A new charmap cache is provided too. See FTC_CMapCache(). This is + useful to perform character code -> glyph index translations quickly, + without the need for an opened FT_Face. + + - A NEW POSTSCRIPT HINTER module has been added to support native hints + in the following formats: PostScript Type 1, PostScript CID, and + CFF/CEF. + + Please test! Note that the auto-hinter produces better results for a + number of badly-hinted fonts (mostly auto-generated ones) though. + + - A memory debugger is now part of the standard FreeType sources. To + enable it, define FT_DEBUG_MEMORY in , and + recompile the library. + + Additionally, define the _environment_ variable FT_DEBUG_MEMORY and + run any program using FreeType. When the library is exited, a summary + of memory footprints and possible leaks will be displayed. + + This works transparently with _any_ program that uses FreeType. + However, you will need a lot of memory to use this (allocated blocks + are never released to the heap to detect double deletes easily). + + + III. MISCELLANEOUS + + - We are aware of subtle differences between the output of FreeType + versions 1 and 2 when it comes to monochrome TrueType-hinted glyphs. + These are most probably due to small differences in the monochrome + rasterizers and will be worked out in an upcoming release. + + - We have decided to fork the sources in a "stable" branch, and an + "unstable" one, since FreeType is becoming a critical component of + many Unix systems. + + The next bug-fix releases of the library will be named 2.0.7, 2.0.8, + etc., while the "2.1" branch will contain a version of the sources + where we will start major reworking of the library's internals, in + order to produce FreeType 2.2.0 (or even 3.0) in a more distant + future. + + We also hope that this scheme will allow much more frequent releases + than in the past. + + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.5 and 2.0.4 + + NOTE THAT 2.0.5 DOES NOT CONTAIN THE POSTSCRIPT HINTER. THIS MODULE WILL + BE PART OF THE NEXT RELEASE (EITHER 2.0.6 or 2.1) + + - Fixed a bug that made certain glyphs, like "Cacute", "cacute" and + "lslash" unavailable from Unicode charmaps of Postscript fonts. This + prevented the correct display of Polish text, for example. + + - The kerning table of Type 1 fonts was loaded by FreeType, when its AFM + file was attached to its face, but the FT_FACE_FLAG_HAS_KERNING bit + flags was not set correctly, preventing FT_Get_Kerning to return + meaningful values. + + - Improved SFNT (TrueType & OpenType) charmap support. Slightly better + performance, as well as support for the new formats defined by the + OpenType 1.3 specification (8, 10, and 12) + + - Fixed a serious typo in "src/base/ftcalc.c" which caused invalid + computations in certain rare cases, producing ugly artefacts. + + - The size of the EM square is computed with a more accurate algorithm + for Postscript fonts. The old one caused slight errors with embedded + fonts found in PDF documents. + + - Fixed a bug in the cache manager that prevented normal LRU behaviour + within the cache manager, causing unnecessary reloads (for FT_Face and + FT_Size objects only). + + - Added a new function named "FT_Get_Name_Index" to retrieve the glyph + index of a given glyph name, when found in a face. + + - Added a new function named "FT_Get_Postscript_Name" to retrieve the + "unique" Postscript font name of a given face. + + - Added a new public header size named FT_SIZES_H (or + ) providing new FT_Size-management functions: + FT_New_Size, FT_Activate_Size, FT_Done_Size. + + - Fixed a reallocation bug that generated a dangling pointer (and possibly + memory leaks) with Postscript fonts (in src/psaux/psobjs.c). + + - Many fixes for 16-bit correctness. + + - Removed many pedantic compiler warnings from the sources. + + - Added an Amiga build directory in "builds/amiga". + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.4 and 2.0.3 + + - Fixed a rather annoying bug that was introduced in 2.0.3. Namely, the + font transformation set through FT_Set_Transform was applied twice to + auto-hinted glyphs, resulting in incorrectly rotated text output. + + - Fixed _many_ compiler warnings. FT2 should now compile cleanly with + Visual C++'s most pedantic warning level (/W4). It already compiled + fine with GCC and a few other compilers. + + - Fixed a bug that prevented the linear advance width of composite + TrueType glyphs to be correctly returned. + + - Fixed the Visual C++ project files located in "builds/win32/visualc" + (previous versions used older names of the library). + + - Many 32-bit constants have an "L" appended to their value, in order + to improve the 16-bitness of the code. Someone is actually trying to + use FT2 on an Atari ST machine! + + - Updated the "builds/detect.mk" file in order to automatically build + FT2 on AIX systems. AIX uses "/usr/sbin/init" instead of "/sbin/init" + and wasn't previously detected as a Unix platform by the FreeType build + system. + + - Updated the Unix-specific portions of the build system (new libtool + version, etc.). + + - The SFNT kerning lodaer now ensures that the table is sorted (since some + problem fonts do not meet this requirement). + +============================================================================ + +LATEST CHANGES BETWEEN 2.0.3 and 2.0.2 + + I. CHANGES TO THE MODULES / FONT DRIVERS + + - THE AUTO-HINTER HAS BEEN SLIGHTLY IMPROVED, in order to fix several + annoying artefacts, mainly: + + - Blue zone alignement of horizontal stems wasn't performed + correctly, resulting in artefacts like the "d" being placed one + pixel below the "b" in some fonts like Time New Roman. + + - Overshoot thresholding wasn't performed correctly, creating + unpleasant artefacts at large character pixel sizes. + + - Composite glyph loading has been simplified. This gets rid + of various artefacts where the components of a composite glyphs + were not correctly spaced. + + These are the last changes to the current auto-hinting module. A new + hinting sub-system is currently in the work in order to support native + hints in Type 1 / CFF / OpenType fonts, as well as globally improve + rendering. + + - The PCF driver has been fixed. It reported invalid glyph dimensions + for the fonts available on Solaris. + + - The Type 1, CID and CFF drivers have been modified to fix the + computation of the EM size. + + - The Type 1 driver has been fixed to avoid a dangerous bug that + crashed the library with non-conforming fonts (i.e. ones that do not + place the .notdef glyph at position 0). + + - The TrueType driver had a rather subtle bug (dangling pointer when + loading composite glyphs) that could crash the library in rare + occasions! + + + II. HIGH-LEVEL API CHANGES + + - The error code enumeration values have been changed. An error value + is decomposed in a generic error code, and a module number. see + for details. + + - A new public header file has been introduced, named FT_TRIGONOMETRY_H + (include/freetype/fttrig.h), providing trigonometric functions to + compute sines, cosines, arctangents, etc. with 16.16 fixed precision. + The implementation is based on the CORDIC algorithm and is very fast + while being sufficiently accurate. + + + III. INTERNALS + + - Added BeOS-specific files in the old build sub-system. Note that + no changes were required to compile the library with Jam. + + - The configuration is now capable of automatically detecting 64-bit + integers on a set of predefined compilers (GCC, Visual C++, Borland + C++) and will use them by default. This provides a small performance + boost. + + - A small memory leak that happened when opening 0-sized files (duh!) + have been fixed. + + - Fixed bezier stack depth bug in the routines provided by the + FT_BBOX_H header file. Also fixed similar bugs in the rasterizers. + + - The outline bounding box code has been rewritten to use direct + computations, instead of bezier sub-division, to compute the exact + bounding box of glyphs. This is slightly slower but more accurate. + + - The build system has been improved and fixed, mainly to support "make" + on Windows 2000 correctly, avoid problems with "make distclean" on non + Unix systems, etc. + + - Hexadecimal constants have been suffixed with "U" to avoid problems + with certain compilers on 64-bit platforms. + + - A new directory named "src/tools" has been created. It contains + Python scripts and simple unit test programs used to develop the + library. + + - The DocMaker tool has been moved from "docs" to "src/tools" and + has been updated with the following: + + - Now accepts the "--title=XXXX" or "-t XXXX" option from the + command line to set the project's name in the generated API + reference. + + - Now accepts the "--output=DIR" or "-o DIR" option from the + command line to set the output directory for all generated HTML + files. + + - Now accepts the "--prefix=XXXX" or "-p XXX" option from the + command line to set the file prefix to use for all generated HTML + files. + + - Now generates the current time/data on each generated page + in order to distinguish between versions. + + DocMaker can be used with other projects now, not only FT2 (e.g. MLib, + FTLayout, etc.). + +=========================================================================== + +LATEST CHANGES BETWEEN 2.0.2 and 2.0.1 + + + I. CHANGES TO THE MODULES / FONT DRIVERS + + - THE TRUETYPE BYTECODE INTERPRETER IS NOW TURNED OFF, in order to + avoid legal problems with the Apple patents. It seems that we + mistakenly turned this option on in previous releases of the + build. + + Note that if you want to use the bytecode interpreter in order + to get high-quality TrueType rendering, you will need to toggle + by hand the definition of the + TT_CONFIG_OPTION_BYTECODE_INTERPRETER macro in the file + "include/freetype/config/ftoption.h". + + - The CFF driver has been improved by Tom Kacvinsky and Sander van + der Wal: + + * Support for "seac" emulation. + * Support for "dotsection". + * Support for retrieving glyph names through + "FT_Get_Glyph_Name". + + The first two items are necessary to correctly a large number of + Type 1 fonts converted to the CFF formats by Adobe Acrobat. + + - The Type 1 driver was also improved by Tom & others: + + * Better EM size computation. + * Better support for synthetic (transformed) fonts. + * The Type 1 driver returns the charstrings corresponding to + each glyph in the "glyph->control_data" field after a call to + "FT_Load_Glyph" (thanks Ha Shao). + + - Various other bugfixes, including the following: + + * Fixed a nasty memory leak in the Type 1 driver. + * The autohinter and the pcf driver used static writable data + when they shouldn't. + * Many casts were added to make the code more 64-bits safe. It + also now compiles on Windows XP 64-bits without warnings. + * Some incorrect writable statics were removed in the "autohint" + and "pcf" drivers. FreeType 2 now compiles on Epoc again. + + + II. CHANGES TO THE HIGH-LEVEL API + + - The library header files inclusion scheme has been changed. The + old scheme looked like: + + #include + #include + #include + #include + + Now you should use: + + #include + #include FT_FREETYPE_H + #include FT_GLYPH_H + #include FT_CACHE_H + #include FT_CACHE_IMAGE_H + + NOTE THAT THE OLD INCLUSION SCHEME WILL STILL WORK WITH THIS + RELEASE. HOWEVER, WE DO NOT GUARANTEE THAT THIS WILL STILL BE + TRUE IN THE NEXT ONE (A.K.A. FREETYPE 2.1). + + The file is used to define the header filename + macros. The complete and commented list of macros is available + in the API reference under the section name "Header File Macros" + in Chapter I. + + For more information, see section I of the following document: + + http://www.freetype.org/ + freetype2/docs/tutorial/step1.html + + or + + http://freetype.sourceforge.net/ + freetype2/docs/tutorial/step1.html + + - Many, many comments have been added to the public source file in + order to automatically generate the API Reference through the + "docmaker.py" Python script. + + The latter has been updated to support the grouping of sections + in chapters and better index sort. See: + + http://www.freetype.org/freetype2/docs/reference/ft2-toc.html + + + III. CHANGES TO THE BUILD PROCESS + + - If you are not building FreeType 2 with its own build system + (but with your own Makefiles or project files), you will need to + be aware that the build process has changed a little bit. + + You don't need to put the "src" directory in the include path + when compiling any FT2 component. Instead, simply put the + component's directory in the current include path. + + So, if you were doing something like: + + cc -c -Iinclude -Isrc src/base/ftbase.c + + change the line to: + + cc -c -Iinclude -Isrc/base src/base/ftbase.c + + If you were doing something like: + + cd src/base + cc -c -I../../include -I.. ftbase.c + + change it to: + + cd src/base + cc -c -I../../include ftbase.c + + +====================================================================== + +LATEST CHANGES BETWEEN 2.0.1 and 2.0 + + 2.0.1 introduces a few changes: + + - Fixed many bugs related to the support of CFF / OpenType fonts. + These formats are now much better supported though there is + still work planned to deal with charset tables and PDF-embedded + CFF files that use the old "seac" command. + + - The library could not be compiled in debug mode with a very + small number of C compilers whose pre-processors didn't + implement the "##" directive correctly (i.e. per se the ANSI C + specification!) An elegant fix was found. + + - Added support for the free Borland command-line C++ Builder + compiler. Use "make setup bcc32". Also fixed a few source + lines that generated new warnings with BCC32. + + - Fixed a bug in FT_Outline_Get_BBox when computing the extrema of + a conic Bezier arc. + + - Updated the INSTALL file to add IDE compilation. + + - Other minor bug fixes, from invalid Type 1 style flags to + correct support of synthetic (obliqued) fonts in the + auto-hinter, better support for embedded bitmaps in a SFNT font. + + - Fixed some problems with "freetype-config". + + Finally, the "standard" scheme for including FreeType headers is now + gradually changing, but this will be explained in a later release + (probably 2.0.2). + + And very special thanks to Tom Kacvinsky and YAMANO-UCHI Hidetoshi + for their contributions! + + +====================================================================== + +CHANGES BETWEEN beta8 and 2.0 + + - Changed the default installation path for public headers from + "include/freetype" to "include/freetype2". + + Also added a new "freetype-config" that is automatically generated + and installed on Unix and Cygwin systems. The script itself is + used to retrieve the current install path, C compilation flags as + well as linker flags. + + - Fixed several small bugs: + + * Incorrect max advance width for fixed-pitch Type 1 fonts. + * Incorrect glyph names for certain TrueType fonts. + * The glyph advance was not copied when FT_Glyph_To_Bitmap was + called. + * The linearHoriAdvance and linerVertAdvance fields were not + correctly returned for glyphs processed by the auto-hinter. + * "type1z" renamed back to "type1"; the old "type1" module has + been removed. + + - Revamped the build system to make it a lot more generic. This + will allow us to re-use nearly un-modified in lots of other + projects (including FreeType Layout). + + - Changed "cid" to use "psaux" too. + + - Added the cache sub-system. See as well as + the sources in "src/cache". Note that it compiles but is still + untested for now. + + - Updated "docs/docmaker.py", a draft API reference is available at + http://www.freetype.org/ft2api.html. + + - Changed "type1" to use "psaux". + + - Created a new module named "psaux" to hold the Type 1 & Type 2 + parsing routines. It should be used by "type1", "cid", and "cff" + in the future. + + - Fixed an important bug in "FT_Glyph_Get_CBox". + + - Fixed some compiler warnings that happened since the TrueType + bytecode decoder was deactivated by default. + + - Fixed two memory leaks: + + * The memory manager (16 bytes) isn't released in + FT_Done_FreeType! + * Using custom input streams, the copy of the original stream was + never released. + + - Fixed the auto-hinter by performing automatic computation of the + "filling direction" of each glyph. This is done through a simple + and fast approximation, and seems to work (problems spotted by + Werner though). The Arphic fonts are a lot nicer though there are + still a lot of things to do to handle Asian fonts correctly. + + +====================================================================== + +BETA-8 (RELEASE CANDIDATE) CHANGES + + - Deactivated the TrueType bytecode interpreter by default. + + - Deactivated the "src/type1" font driver. Now "src/type1z" is used + by default. + + - Updates to the build system. We now compile the library correctly + under Unix system through "configure" which is automatically + called on the first "make" invocation. + + - Added the auto-hinting module! Fixing some bugs here and there. + + - Found some bugs in the composite loader (seac) of the Type1-based + font drivers. + + - Renamed the directory "freetype2/config" to "freetype2/builds" and + updated all relevant files. + + - Found a memory leak in the "type1" driver. + + - Incorporated Tom's patches to support flex operators correctly in + OpenType/CFF fonts. Now all I need is to support pure CFF and CEF + fonts to be done with this driver :-) + + - Added the Windows FNT/FON driver in "src/winfonts". For now, it + always "simulates" a Unicode charmap, so it shouldn't be + considered completed right now. + + It is there to be more a proof of concept than anything else + anyway. The driver is a single C source file, that compiles to 3 + Kb of code. + + I'm still working on the PCF/BDF drivers, but I'm too lazy to + finish them now. + + - CHANGES TO THE HIGH-LEVEL API + + * FT_Get_Kerning has a new parameter that allows you to select the + coordinates of the kerning vector (font units, scaled, scaled + + grid-fitted). + * The outline functions are now in and not + part of anymore. + * now contains declarations for + FT_New_Library, FT_Done_Library, FT_Add_Default_Modules. + * The so-called convenience functions have moved from "ftoutln.c" + to "ftglyph.c", and are thus available with this optional + component of the library. They are declared in + now. + * Anti-aliased rendering is now the default for FT_Render_Glyph + (i.e. corresponds to render_mode == 0 == ft_render_mode_normal). + To generate a monochrome bitmap, use ft_render_mode_mono, or the + FT_LOAD_MONOCHROME flag in FT_Load_Glyph/FT_Load_Char. + FT_LOAD_ANTI_ALIAS is still defined, but values to 0. + * now include , + solving a few headaches :-) + * The type FT_GlyphSlotRec has now a "library" field. + + - CHANGES TO THE "ftglyph.h" API + + This API has been severely modified in order to make it simpler, + clearer, and more efficient. It certainly now looks like a real + "glyph factory" object, and allows client applications to manage + (i.e. transform, bbox and render) glyph images without ever + knowing their original format. + + - Added support for CID-keyed fonts to the CFF driver. Maybe + support for pure CFF + CEF fonts should come in? + + - Cleaned up source code in order to avoid two functions with the + same name. Also changed the names of the files in "type1z" from + "t1XXXX" to "z1XXXX" in order to avoid any conflicts. + + "make multi" now works well :-) + + Also removed the use of "cidafm" for now, even if the source files + are still there. This functionality will certainly go into a + specific module. + + - ADDED SUPPORT FOR THE AUTO-HINTER + + It works :-) I have a demo program which simply is a copy of + "ftview" that does a `FT_Add_Module(library, + &autohinter_module_class)' after library initialization, and Type + 1 & OpenType/CFF fonts are now hinted. + + CID fonts are not hinted, as they include no charmap and the + auto-hinter doesn't include "generic" global metrics computations + yet. + + Now, I need to release this thing to the FreeType 2 source. + + - CHANGES TO THE RENDERER MODULES + + The monochrome and smooth renderers are now in two distinct + directories, namely "src/raster1" and "src/smooth". Note that the + old "src/renderer" is now gone. + + I ditched the 5-gray-levels renderers. Basically, it involved a + simple #define toggle in 'src/raster1/ftraster.c'. + + FT_Render_Glyph, FT_Outline_Render & FT_Outline_Get_Bitmap now + select the best renderer available, depending on render mode. If + the current renderer for a given glyph image format isn't capable + of supporting the render mode, another one will be found in the + library's list. This means that client applications do not need + to switch or set the renderers themselves (as in the latest + change), they'll get what they want automatically. At last. + + Changed the demo programs accordingly. + + - MAJOR INTERNAL REDESIGN: + + A lot of internal modifications have been performed lately on the + source in order to provide the following enhancements: + + * More generic module support: + + The FT_Module type is now defined to represent a handle to a + given module. The file contains the + FT_Module_Class definition, as well as the module-loading public + API. + + The FT_Driver type is still defined, and still represents a + pointer to a font driver. Note that FT_Add_Driver is replaced + by FT_Add_Module, FT_Get_Driver by FT_Get_Module, etc. + + * Support for generic glyph image types: + + The FT_Renderer type is a pointer to a module used to perform + various operations on glyph image. + + Each renderer is capable of handling images in a single format + (e.g. ft_glyph_format_outline). Its functions are used to: + + - transform an glyph image + - render a glyph image into a bitmap + - return the control box (dimensions) of a given glyph image + + The scan converters "ftraster.c" and "ftgrays.c" have been moved + to the new directory "src/renderer", and are used to provide two + default renderer modules. + + One corresponds to the "standard" scan-converter, the other to + the "smooth" one. + + he current renderer can be set through the new function + FT_Set_Renderer. + + The old raster-related function FT_Set_Raster, FT_Get_Raster and + FT_Set_Raster_Mode have now disappeared, in favor of the new: + + FT_Get_Renderer + FT_Set_Renderer + + See the file for more details. + + These changes were necessary to properly support different + scalable formats in the future, like bi-color glyphs, etc. + + * Glyph loader object: + + A new internal object, called a 'glyph loader' has been + introduced in the base layer. It is used by all scalable format + font drivers to load glyphs and composites. + + This object has been created to reduce the code size of each + driver, as each one of them basically re-implemented its + functionality. + + See and the FT_GlyphLoader type for + more information. + + * FT_GlyphSlot has new fields: + + In order to support extended features (see below), the + FT_GlyphSlot structure has a few new fields: + + linearHoriAdvance: + + This field gives the linearly scaled (i.e. scaled but + unhinted) advance width for the glyph, expressed as a 16.16 + fixed pixel value. This is useful to perform WYSIWYG text. + + linearVertAdvance: + This field gives the linearly scaled advance height for the + glyph (relevant in vertical glyph layouts only). This is + useful to perform WYSIWYG text. + + Note that the two above field replace the removed "metrics2" + field in the glyph slot. + + advance: + This field is a vector that gives the transformed advance for + the glyph. By default, it corresponds to the advance width, + unless FT_LOAD_VERTICAL_LAYOUT was specified when calling + FT_Load_Glyph or FT_Load_Char. + + bitmap_left: + This field gives the distance in integer pixels from the + current pen position to the left-most pixel of a glyph image + IF IT IS A BITMAP. It is only valid when the "format" field + is set to "ft_glyph_format_bitmap", for example, after calling + the new function FT_Render_Glyph. + + bitmap_top: + This field gives the distance in integer pixels from the + current pen position (located on the baseline) to the top-most + pixel of the glyph image IF IT IS A BITMAP. Positive values + correspond to upwards Y. + + loader: + This is a new private field for the glyph slot. Client + applications should not touch it. + + + * Support for transforms and direct rendering in FT_Load_Glyph: + + Most of the functionality found in has been + moved to the core library. Hence, the following: + + - A transform can be specified for a face through + FT_Set_Transform. this transform is applied by FT_Load_Glyph + to scalable glyph images (i.e. NOT TO BITMAPS) before the + function returns, unless the bit flag FT_LOAD_IGNORE_TRANSFORM + was set in the load flags. + + - Once a glyph image has been loaded, it can be directly + converted to a bitmap by using the new FT_Render_Glyph + function. Note that this function takes the glyph image from + the glyph slot, and converts it to a bitmap whose properties + are returned in "face.glyph.bitmap", "face.glyph.bitmap_left" + and "face.glyph.bitmap_top". The original native image might + be lost after the conversion. + + - When using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph + and FT_Load_Char functions will call FT_Render_Glyph + automatically when needed. + + - Reformatted all modules source code in order to get rid of the + basic data types redifinitions (i.e. "TT_Int" instead of "FT_Int", + "T1_Fixed" instead of "FT_Fixed"). Hence the format-specific + prefixes like "TT_", "T1_", "T2_" and "CID_" are only used for + relevant structures. + + +====================================================================== + +OLD CHANGES FOR BETA 7 + + - bug-fixed the OpenType/CFF parser. It now loads and displays my + two fonts nicely, but I'm pretty certain that more testing is + needed :-) + + - fixed the crummy Type 1 hinter, it now handles accented characters + correctly (well, the accent is not always well placed, but that's + another problem..) + + - added the CID-keyed Type 1 driver in "src/cid". Works pretty well + for only 13 Kb of code ;-) Doesn't read AFM files though, nor the + really useful CMAP files.. + + - fixed two bugs in the smooth renderer (src/base/ftgrays.c). Thanks + to Boris Letocha for spotting them and providing a fix.. + + - fixed potential "divide by zero" bugs in ftcalc.c.. my god.. + + - added source code for the OpenType/CFF driver (still incomplete + though..) + + - modified the SFNT driver slightly to perform more robust header + checks in TT_Load_SFNT_Header. This prevents certain font files + (e.g. some Type 1 Multiple Masters) from being incorrectly + "recognized" as TrueType font files.. + + - moved a lot of stuff from the TrueType driver to the SFNT module, + this allows greater code re-use between font drivers + (e.g. TrueType, OpenType, Compact-TrueType, etc..) + + - added a tiny segment cache to the SFNT Charmap 4 decoder, in order + to minimally speed it up.. + + - added support for Multiple Master fonts in "type1z". There is also + a new file named which defines functions to + manage them from client applications. + + The new file "src/base/ftmm.c" is also optional to the engine.. + + - various formatting changes (e.g. EXPORT_DEF -> FT_EXPORT_DEF) + + small bug fixes in FT_Load_Glyph, the "type1" driver, etc.. + + - a minor fix to the Type 1 driver to let them apply the font matrix + correctly (used for many oblique fonts..) + + - some fixes for 64-bit systems (mainly changing some FT_TRACE calls + to use %p instead of %lx).. Thanks to Karl Robillard + + - fixed some bugs in the sbit loader (src/base/sfnt/ttsbit.c) + + added a new flag, FT_LOAD_CROP_BITMAP to query that bitmaps be + cropped when loaded from a file (maybe I should move the bitmap + cropper to the base layer ??). + + - changed the default number of gray levels of the smooth renderer + to 256 (instead of the previous 128). Of course, the human eye + can't see any difference ;-) + + - removed TT_MAX_SUBGLYPHS, there is no static limit on the number + of subglyphs in a TrueType font now.. + + +====================================================================== + +OLD CHANGES 16 May 2000 + + - tagged "BETA-6" in the CVS tree. This one is a serious release + candidate even though it doesn't incorporate the auto-hinter yet.. + + - various obsolete files were removed, and copyright header updated + + - finally updated the standard raster to fix the monochrome + rendering bug + re-enable support for 5-gray levels anti-aliasing + (suck, suck..) + + - created new header files, and modified sources accordingly: + + + - simple FreeType types, without the API + + - definition of memory-management macros + + - added the "DSIG" (OpenType Digital Signature) tag to + + + - light update/cleaning of the build system + changes to the sources + in order to get rid of _all_ compiler warnings with three + compilers, i.e: + + gcc with "-ansi -pedantic -Wall -W", Visual C++ with "/W3 /WX" and + LCC + + IMPORTANT NOTE FOR WIN32-LCC USERS: + | + | It seems the C pre-processor that comes with LCC is broken, it + | doesn't recognize the ANSI standard directives # and ## + | correctly when one of the argument is a macro. Also, something + | like: + | + | #define F(x) print##x + | + | F(("hello")) + | + | will get incorrectly translated to: + | + | print "hello") + | + | by its pre-processor. For this reason, you simply cannot build + | FreeType 2 in debug mode with this compiler.. + + - yet another massive grunt work. I've changed the definition of the + EXPORT_DEF, EXPORT_FUNC, BASE_DEF & BASE_FUNC macros. These now + take an argument, which is the function's return value type. + + This is necessary to compile FreeType as a DLL on Windows and + OS/2. Depending on the compiler used, a compiler-specific keyword + like __export or __system must be placed before (VisualC++) or + after (BorlandC++) the type.. + + Of course, this needed a lot of changes throughout the source code + to make it compile again... All cleaned up now, apparently.. + + Note also that there is a new EXPORT_VAR macro defined to allow + the _declaration_ of an exportable public (constant) + variable. This is the case of the raster interfaces (see + ftraster.h and ftgrays.h), as well as each module's interface (see + sfdriver.h, psdriver.h, etc..) + + - new feature: it is now possible to pass extra parameters to font + drivers when creating a new face object. For now, + this capability is unused. It could however prove to + be useful in a near future.. + + the FT_Open_Args structure was changes, as well as the internal + driver interface (the specific "init_face" module function has + now a different signature). + + - updated the tutorial (not finished though). + + - updated the top-level BUILD document + + - fixed a potential memory leak that could occur when loading + embedded bitmaps. + + - added the declaration of FT_New_Memory_Face in + , as it was missing from the public header + (the implementation was already in "ftobjs.c"). + + - the file has been seriously updated in order + to allow the automatic generation of error message tables. See the + comments within it for more information. + + - major directory hierarchy re-organisation. This was done for two + things: + + * first, to ease the "manual" compilation of the library by + requiring at lot less include paths :-) + + * second, to allow external programs to effectively access + internal data fields. For example, this can be extremely + useful if someone wants to write a font producer or a font + manager on top of FreeType. + + Basically, you should now use the 'freetype/' prefix for header + inclusion, as in: + + #include + #include + + Some new include sub-directories are available: + + a. the "freetype/config" directory, contains two files used to + configure the build of the library. Client applications should + not need to look at these normally, but they can if they want. + + #include + #include + + b. the "freetype/internal" directory, contains header files that + describes library internals. These are the header files that + were previously found in the "src/base" and "src/shared" + directories. + + + As usual, the build system and the demos have been updated to + reflect the change.. + + Here's a layout of the new directory hierarchy: + + TOP_DIR + include/ + freetype/ + freetype.h + ... + config/ + ftoption.h + ftconfig.h + ftmodule.h + + internal/ + ftobjs.h + ftstream.h + ftcalc.h + ... + + src/ + base/ + ... + + sfnt/ + psnames/ + truetype/ + type1/ + type1z/ + + + Compiling a module is now much easier, for example, the following + should work when in the TOP_DIR directory on an ANSI build: + + gcc -c -I./include -I./src/base src/base/ftbase.c + gcc -c -I./include -I./src/sfnt src/sfnt/sfnt.c + etc.. + + (of course, using -Iconfig/ if you provide system-specific + configuration files). + + - updated the structure of FT_Outline_Funcs in order to allow direct + coordinate scaling within the outline decomposition routine (this + is important for virtual "on" points with TrueType outlines) + + updates to the rasters to support this.. + + - updated the OS/2 table loading code in "src/sfnt/ttload.c" in + order to support version 2 of the table (see OpenType 1.2 spec) + + - created "include/tttables.h" and "include/t1tables.h" to allow + client applications to access some of the SFNT and T1 tables of a + face with a procedural interface (see FT_Get_Sfnt_Table()) + + updates to internal source files to reflect the change.. + + - some cleanups in the source code to get rid of warnings when + compiling with the "-Wall -W -ansi -pedantic" options in gcc. + + - debugged and moved the smooth renderer to "src/base/ftgrays.c" and + its header to "include/ftgrays.h" + + - updated TT_MAX_SUBGLYPHS to 96 as some CJK fonts have composites + with up to 80 sub-glyphs !! Thanks to Werner + + +====================================================================== + +OLD CHANGES - 14-apr-2000 + + - fixed a bug in the TrueType glyph loader that prevented the + correct loading of some CJK glyphs in mingli.ttf + + - improved the standard Type 1 hinter in "src/type1" + + - fixed two bugs in the experimental Type 1 driver in "src/type1z" + to handle the new XFree86 4.0 fonts (and a few other ones..) + + - the smooth renderer is now complete and supports sub-banding to + render large glyphs at high speed. However, it is still located in + "demos/src/ftgrays.c" and should move to the library itself in the + next beta.. NOTE: The smooth renderer doesn't compile in + stand-alone mode anymore, but this should be fixed RSN.. + + - introduced convenience functions to more easily deal with glyph + images, see "include/ftglyph.h" for more details, as well as the + new demo program named "demos/src/ftstring.c" that demonstrates + its use + + - implemented FT_LOAD_NO_RECURSE in both the TrueType and Type 1 + drivers (this is required by the auto-hinter to improve its + results). + + - changed the raster interface, in order to allow client + applications to provide their own span-drawing callbacks. However, + only the smooth renderer supports this. See "FT_Raster_Params" in + the file "include/ftimage.h" + + - fixed a small bug in FT_MulFix that caused incorrect transform + computation! + + - Note: The tutorial is out-of-date, grumpf.. :-( + + +====================================================================== + +OLD CHANGES - 12-mar-2000 + + - changed the layout of configuration files : now, all ANSI + configuration files are located in + "freetype2/config". System-specific over-rides can be placed in + "freetype2/config/". + + - moved all configuration macros to "config/ftoption.h" + + - improvements in the Type 1 driver with AFM support + + - changed the fields in the FT_Outline structure : the old "flags" + array is re-named "tags", while all ancient flags are encoded into + a single unsigned int named "flags". + + - introduced new flags in FT_Outline.flags (see + ft_outline_.... enums in "ftimage.h"). + + - changed outline functions to "FT_Outline_" syntax + + - added a smooth anti-alias renderer to the demonstration programs + + - added Mac graphics driver (thanks Just) + + - FT_Open_Face changed in order to received a pointer to a + FT_Open_Args descriptor.. + + - various cleanups, a few more API functions implemented (see + FT_Attach_File) + + - updated some docs + + +====================================================================== + +OLD CHANGES - 22-feb-2000 + + - introduced the "psnames" module. It is used to: + + o convert a Postscript glyph name into the equivalent Unicode + character code (used by the Type 1 driver(s) to synthetize on + the fly a Unicode charmap). + + o provide an interface to retrieve the Postscript names of the + Macintosh, Adobe Standard & Adobe Expert character codes. + (the Macintosh names are used by the SFNT-module postscript + names support routines, while the other two tables are used by + the Type 1 driver(s)). + + - introduced the "type1z" alternate Type 1 driver. This is a (still + experimental) driver for the Type 1 format that will ultimately + replace the one in "src/type1". It uses pattern matching to load + data from the font, instead of a finite state analyzer. It works + much better than the "old" driver with "broken" fonts. It is also + much smaller (under 15 Kb). + + - the Type 1 drivers (both in "src/type1" and "src/type1z") are + nearly complete. They both provide automatic Unicode charmap + synthesis through the "psnames" module. No re-encoding vector is + needed. (note that they still leak memory due to some code + missing, and I'm getting lazy). + + Trivial AFM support has been added to read kerning information but + wasn't exactly tested as it should ;-) + + - The TrueType glyph loader has been seriously rewritten (see the + file "src/truetype/ttgload.c". It is now much, much simpler as + well as easier to read, maintain and understand :-) Preliminary + versions introduced a memory leak that has been reported by Jack + Davis, and is now fixed.. + + - introduced the new "ft_glyph_format_plotter", used to represent + stroked outlines like Windows "Vector" fonts, and certain Type 1 + fonts like "Hershey". The corresponding raster will be written + soon. + + - FT_New_Memory_Face is gone. Likewise, FT_Open_Face has a new + interface that uses a structure to describe the input stream, the + driver (if required), etc.. + + +TODO + + - Write FT_Get_Glyph_Bitmap and FT_Load_Glyph_Bitmap + + - Add a function like FT_Load_Character( face, char_code, load_flags + ) that would really embbed a call to FT_Get_Char_Index then + FT_Load_Glyph to ease developer's work. + + - Update the tutorial! + + - consider adding support for Multiple Master fonts in the Type 1 + drivers. + + - Test the AFM routines of the Type 1 drivers to check that kerning + information is returned correctly. + + - write a decent auto-gridding component !! We need this to release + FreeType 2.0 gold ! + + +less urgent needs: + + - add a CFF/Type2 driver + - add a BDF driver + - add a FNT/PCF/HBF driver + - add a Speedo driver from the X11 sources + + +====================================================================== + +OLDER CHANGES - 27-jan-2000 + + - updated the "sfnt" module interface to allow several SFNT-based + drivers to co-exist peacefully + + - updated the "T1_Face" type to better separate Postscript font + content from the rest of the FT_Face structure. Might be used + later by the CFF/Type2 driver.. + + - added an experimental replacement Type 1 driver featuring advanced + (and speedy) pattern matching to retrieve the data from postscript + fonts. + + - very minor changes in the implementation of FT_Set_Char_Size and + FT_Set_Pixel_Sizes (they now implement default to ligthen the font + driver's code). + + +====================================================================== + +OLD MESSAGE + +This file summarizes the changes that occured since the last "beta" of +FreeType 2. Because the list is important, it has been divided into +separate sections: + +Table Of Contents: + + I High-Level Interface (easier !) + II Directory Structure + III Glyph Image Formats + IV Build System + V Portability + VI Font Drivers + + +---------------------------------------------------------------------- + +High-Level Interface: + + The high-level API has been considerably simplified. Here is how: + + - resource objects have disappeared. this means that face objects + can now be created with a single function call (see FT_New_Face + and FT_Open_Face) + + - when calling either FT_New_Face & FT_Open_Face, a size object + and a glyph slot object are automatically created for the face, + and can be accessed through "face->glyph" and "face->size" if + one really needs to. In most cases, there's no need to call + FT_New_Size or FT_New_Glyph. + + - similarly, FT_Load_Glyph now only takes a "face" argument + (instead of a glyph slot and a size). Also, it's "result" + parameter is gone, as the glyph image type is returned in the + field "face->glyph.format" + + - the list of available charmaps is directly accessible through + "face->charmaps", counting "face->num_charmaps" elements. Each + charmap has an 'encoding' field which specifies which known + encoding it deals with. Valid values are, for example : + + ft_encoding_unicode (for ASCII, Latin-1 and Unicode) + ft_encoding_apple_roman + ft_encoding_sjis + ft_encoding_adobe_standard + ft_encoding_adobe_expert + + other values may be added in the future. Each charmap still + holds its "platform_id" and "encoding_id" values in case the + encoding is too exotic for the current library + + +---------------------------------------------------------------------- + +Directory Structure: + + Should seem obvious to most of you: + + freetype/ + config/ -- configuration sub-makefiles + ansi/ + unix/ -- platform-specific configuration files + win32/ + os2/ + msdos/ + + include/ -- public header files, those to be included + directly by client apps + + src/ -- sources of the library + base/ -- the base layer + sfnt/ -- the sfnt "driver" (see the drivers section + below) + truetype/ -- the truetype driver + type1/ -- the type1 driver + shared/ -- some header files shared between drivers + + demos/ -- demos/tools + + docs/ -- documentation (a bit empty for now) + + +---------------------------------------------------------------------- + +Glyph Image Formats: + + Drivers are now able to register new glyph image formats within the + library. For now, the base layer supports of course bitmaps and + vector outlines, but one could imagine something different like + colored bitmaps, bi-color vectors or wathever else (Metafonts anyone + ??). + + See the file `include/ftimage.h'. Note also that the type + FT_Raster_Map is gone, and is now replaced by FT_Bitmap, which + should encompass all known bitmap types. + + Each new image format must provide at least one "raster", i.e. a + module capable of transforming the glyph image into a bitmap. It's + also possible to change the default raster used for a given glyph + image format. + + The default outline scan-converter now uses 128 levels of grays by + default, which tends to smooth many things. Note that the demo + programs have been updated significantly in order to display these.. + + +---------------------------------------------------------------------- + +Build system: + + You still need GNU Make to build the library. The build system has + been very seriously re-vamped in order to provide things like : + + - automatic host platform detection (reverting to 'config/ansi' if + it is not detected, with pseudo-standard compilation flags) + + - the ability to compile from the Makefiles with very different and + exotic compilers. Note that linking the library can be difficult + for some platforms. + + For example, the file `config/win32/lcclib.bat' is invoked by the + build system to create the ".lib" file with LCC-Win32 because its + librarian has too many flaws to be invoked directly from the + Makefile. + + Here's how it works: + + - the first time you type `make', the build system runs a series of + sub-makefiles in order to detect your host platform. It then dumps + what it found, and creates a file called `config.mk' in the + current directory. This is a sub-Makefile used to define many + important Make variables used to build the library. + + - the second time, the build system detects the `config.mk' then use + it to build the library. All object files go into 'obj' by + default, as well as the library file, but this can easily be + changed. + + Note that you can run "make setup" to force another host platform + detection even if a `config.mk' is present in the current + directory. Another solution is simply to delete the file, then + re-run make. + + Finally, the default compiler for all platforms is gcc (for now, + this will hopefully changed in the future). You can however specify + a different compiler by specifying it after the 'setup' target as + in: + + gnumake setup lcc on Win32 to use the LCC compiler + gnumake setup visualc on Win32 to use Visual C++ + + See the file `config//detect.mk' for a list of supported + compilers for your platforms. + + It should be relatively easy to write new detection rules files and + config.mk.. + + Finally, to build the demo programs, go to `demos' and launch GNU + Make, it will use the `config.mk' in the top directory to build the + test programs.. + + +---------------------------------------------------------------------- + +Portability: + + In the previous beta, a single FT_System object was used to + encompass all low-level operations like thread synchronisation, + memory management and i/o access. This has been greatly simplified: + + - thread synchronisation has been dropped, for the simple reason + that the library is already re-entrant, and that if you really + need two threads accessing the same FT_Library, you should + really synchronize access to it yourself with a simple mutex. + + - memory management is performed through a very simple object + called "FT_Memory", which really is a table containing a table + of pointers to functions like malloc, realloc and free as well + as some user data (closure). + + - resources have disappeared (they created more problems than they + solved), and i/o management have been simplified greatly as a + result. Streams are defined through FT_Stream objects, which can + be either memory-based or disk-based. + + Note that each face has its own stream, which is closed only + when the face object is destroyed. Hence, a function like + TT_Flush_Face in 1.x cannot be directly supported. However, if + you really need something like this, you can easily tailor your + own streams to achieve the same feature at a lower level (and + use FT_Open_Face instead of FT_New_Face to create the face). + + See the file "include/ftsystem.h" for more details, as well as the + implementations found in "config/unix" and "config/ansi". + + +---------------------------------------------------------------------- + +Font Drivers: + + The Font Driver interface has been modified in order to support + extensions & versioning. + + + The list of the font drivers that are statically linked to the + library at compile time is managed through a new configuration file + called `config//ftmodule.h'. + + This file is autogenerated when invoking `make modules'. This target + will parse all sub-directories of 'src', looking for a "module.mk" + rules file, used to describe the driver to the build system. + + Hence, one should call `make modules' each time a font driver is + added or removed from the `src' directory. + + Finally, this version provides a "pseudo-driver" in `src/sfnt'. This + driver doesn't support font files directly, but provides services + used by all TrueType-like font drivers. Hence, its code is shared + between the TrueType & OpenType font formats, and possibly more + formats to come if we're lucky.. + + +---------------------------------------------------------------------- + +Extensions support: + + The extensions support is inspired by the one found in 1.x. + + Now, each font driver has its own "extension registry", which lists + which extensions are available for the font faces managed by the + driver. + + Extension ids are now strings, rather than 4-byte tags, as this is + usually more readable.. + + Each extension has: + - some data, associated to each face object + - an interface (table of function pointers) + + An extension that is format-specific should simply register itself + to the correct font driver. Here is some example code: + + // Registering an extensions + // + FT_Error FT_Init_XXXX_Extension( FT_Library library ) + { + FT_DriverInterface* tt_driver; + + driver = FT_Get_Driver( library, "truetype" ); + if (!driver) return FT_Err_Unimplemented_Feature; + + return FT_Register_Extension( driver, &extension_class ); + } + + + // Implementing the extensions + // + FT_Error FT_Proceed_Extension_XXX( FT_Face face ) + { + FT_XXX_Extension ext; + FT_XXX_Extension_Interface ext_interface; + + ext = FT_Get_Extension( face, "extensionid", &ext_interface ); + if (!ext) return error; + + return ext_interface->do_it(ext); + } + +--- end of CHANGES --- diff --git a/lib/freetype/docs/CUSTOMIZE b/lib/freetype/docs/CUSTOMIZE new file mode 100644 index 0000000..397c2c3 --- /dev/null +++ b/lib/freetype/docs/CUSTOMIZE @@ -0,0 +1,117 @@ +How to customize the compilation of the library: +================================================ + + FreeType is highly customizable to fit various needs, and this document + details how it is possible to select options and components at compilation + time. + + +I. Configuration macros: + + the file found in "include/freetype/config/ftoption.h" contains a list + of commented configuration macros that can be toggled by developers to + indicate which features to activate in their build of the library. + + these options range from debug level to availability of certain + features, like native TrueType hinting through a bytecode interpreter. + + we invite you to read this file for more information. You can change + the file's content to suit your needs, or override it with one of the + techniques described below.. + + +II. Modules list: + + the file found in "include/freetype/config/ftmodule.h" contains a list + of names corresponding to the modules / font drivers to be statically + compiled in the FreeType library during the build. + + you can change it to suit your own preferences. Be aware that certain + modules depend on others, as described by the file "modules.txt" in + this directory. + + you can modify the file's content to suit your needs, or override it + at compile time with one of the methods described below + + +III. System interface: + + FreeType's default interface to the system (i.e. the parts that deal with + memory management and i/o streams) is located in "src/base/ftsystem.c". + + the current implementation uses standard C library calls to manage + memory and read font files. It is however possible to write custom + implementations to suit specific systems. + + to tell the GNU Make-based build system to use a custom system interface, + you'll need to define the environment variable FTSYS_SRC to point to + the relevant implementation, like in: + + on Unix: + ./configure + export FTSYS_SRC=foo/my_ftsystem.c + make + make install + + on Windows: + make setup + set FTSYS_SRC=foo/my_ftsystem.c + make + + +IV. Overriding default configuration and module headers: + + it is possible to over-ride the default configuration and module headers + without changing the original files. There are two ways to do that: + + 1. Using the C include path: + + use the C include path to ensure that your own versions of the + files are used at compile time when the lines: + + #include FT_CONFIG_OPTIONS_H + #include FT_CONFIG_MODULES_H + + are compiled. Their default values being + and , you can do something like: + + custom/ + freetype/ + config/ + ftoption.h => custom options header + ftmodule.h => custom modules list + + include/ => normal FreeType 2 include + freetype/ + ... + + then change the C include path to always give the path to "custom" + before the FreeType 2 "include" + + + 2. Re-defining FT_CONFIG_OPTIONS_H and FT_CONFIG_MODULES_H + + another way to do the same thing is to re-define the macros used + to name the configuration headers. To do so, you'll need a custom + "ft2build.h", whose content can be as simple as: + + #ifndef __FT2_BUILD_GENERIC_H__ + #define __FT2_BUILD_GENERIC_H__ + + #define FT_CONFIG_OPTIONS_H + #define FT_CONFIG_MACROS_H + + #include + + #endif /* __FT2_BUILD_GENERIC_H__ */ + + place them in: + + custom/ + ft2build.h => custom version described above + my-ftoption.h => custom options header + my-ftmodule.h => custom modules list header + + and change the C include path to ensure that "custom" is always placed + before the FT2 "include" during compilation. + diff --git a/lib/freetype/docs/DEBUG b/lib/freetype/docs/DEBUG new file mode 100644 index 0000000..03ed703 --- /dev/null +++ b/lib/freetype/docs/DEBUG @@ -0,0 +1,183 @@ +Debugging within the FreeType sources: +====================================== + +I. Configuration macros +----------------------- + +There are several ways to enable debugging features in a FreeType 2 +builds. This is controlled through the definition of special macros +located in the file "ftoptions.h". The macros are: + + + FT_DEBUG_LEVEL_ERROR + + #define this macro if you want to compile the FT_ERROR macro calls + used to print error messages during program execution. This will + not stop the program, but is very useful to spot invalid fonts + during development and code workarounds for them. + + FT_DEBUG_LEVEL_TRACE + + #define this macro if you want to compile both the FT_ERROR macro + and the FT_TRACE one. This also includes the variants FT_TRACE0, + FT_TRACE1, FT_TRACE2, ..., FT_TRACE6. + + The trace macros are used to send debugging messages when an + appropriate "debug level" is configured at runtime through the + FT2_DEBUG environment variable (more on this later). + + FT_DEBUG_MEMORY + + If this macro is #defined, the FreeType engines is linked with a + small but effective debugging memory manager that tracks all + allocations and frees that are performed within the font engine. + + When the FT2_DEBUG_MEMORY environment variable is defined at + runtime, a call to FT_Done_FreeType will dump memory statistics, + including the list of leaked memory blocks with the source locations + where these were allocated. It's always a very good idea to define + this in development builds. This works with _any_ program linked to + FreeType, but requires a big deal of memory (the debugging memory + manager never frees the blocks to the heap in order to detect double + frees). + + When FT2_DEBUG_MEMORY isn't defined at runtime, the debugging memory + manager is ignored, and performance is un-affected. + + +II. Debugging macros +-------------------- + +Several macros can be used within the FreeType sources to help debugging +its code: + + 1. FT_ERROR(( ... )) + + This macro is used to send debug messages that indicate relatively + serious errors (like broken font files), but will not stop the + execution of the running program. Its code is compiled only when + either FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined in + "ftoption.h". + + Note that you must use with a printf-like signature, but with double + parentheses, like in: + + FT_ERROR(( "your %s is not %s\n", "foo", "bar" )); + + + 2. FT_ASSERT( condition ) + + This macro is used to check strong assertions at runtime. If its + condition isn't TRUE, the program will abort with a panic message. + Its code is compiled when either FT_DEBUG_LEVEL_ERROR or + FT_DEBUG_LEVEL_TRACE are defined. You don't need double-parentheses + here. For example: + + FT_ASSERT( ptr != NULL ); + + + 3. FT_TRACE( level, (message...) ) + + The FT_TRACE macro is used to send general-purpose debugging + messages during program execution. This macro uses an *implicit* + macro named FT_COMPONENT used to name the current FreeType component + being run. + + The developer should always define FT_COMPONENT as appropriate, for + example as in: + + #undef FT_COMPONENT + #define FT_COMPONENT trace_io + + The value of the FT_COMPONENT macro is an enumeration named + trace_XXXX where XXXX is one of the component names defined in the + internal file . + + Each such component is assigned a "debug level", ranging from 0 to 6 + when a program linked with FreeType starts, through the use of the + FT2_DEBUG environment variable, described later. + + When FT_TRACE is called, its level is compared to the one of the + corresponding component. Messages with trace levels *higher* than + the corresponding component level are filtered and never printed. + + This means that trace messages with level 0 are always printed, + those with level 2 are only printed when the component level is *at + least* 2. + + The second parameter to FT_TRACE must contain parentheses and + correspond to a print-like call, as in: + + FT_TRACE( 2, ( "your %s is not %s\n", "foo", "bar" ) ) + + The shortcut macros FT_TRACE0, FT_TRACE1, FT_TRACE2_, ... FT_TRACE6 + can be used with constant level indices, and are much cleaner to + use, as in + + FT_TRACE2(( "your %s is not %s\n", "foo", "bar" )); + + +III. Environment variables +-------------------------- + +The following environment variables control debugging output and +behaviour of FreeType at runtime: + + + FT2_DEBUG + + This variable is only used when FreeType is built with + FT_DEBUG_LEVEL_TRACE defined. It contains a list of component level + definitions, following this format: + + component1:level1 component2:level2 component3:level3 ... + + where "componentX" is the name of a tracing component, as defined in + "fttrace.h", but without the "trace_" prefix, and "levelX" is the + corresponding level to use at runtime. + + "any" is a special component name that will be interpreted as + "any/all components". For example, the following definitions + + set FT2_DEBUG=any:2 memory:5 io:4 (on Windows) + export FT2_DEBUG="any:2 memory:5 io:4" (on Linux) + + both stipulate that all components should have level 2, except for + the memory and io components which will be set to trace levels 5 and + 4 respectively. + + FT2_DEBUG_MEMORY + + This environment variable, when defined, tells FreeType to use a + debugging memory manager that will track leaked memory blocks as + well as other common errors like double frees. It is also capable + of reporting _where_ the leaked blocks were allocated, which + considerably saves time when debugging new additions to the library. + + This code is only compiled when FreeType is built with the + FT_DEBUG_MEMORY macro #defined in "ftoption.h" though, it will be + ignored in other builds. + + + FT2_ALLOC_TOTAL_MAX + + this variable is ignored if FT2_DEBUG_MEMORY is not defined. It allows + you to specify a maximum heap size for all memory allocations performed + by FreeType. This is very useful to test the robustness of the font + engine and programs that use it in tight memory conditions. + + If it is undefined, or if its value is not strictly positive, then no + allocation bounds are checked at runtime. + + + FT2_ALLOC_COUNT_MAX + + this variable is ignored if FT2_DEBUG_MEMORY is not defined. It allows + you to sepcify a maximum number of memory allocations performed by + FreeType before returning the error FT_Err_Out_Of_Memory. This is + useful for debugging and testing the engine's robustness. + + If it is undefined, or if its value is not strictly positive, then no + allocation bounsd are checked at runtime. + +End of file diff --git a/lib/freetype/docs/FTL.txt b/lib/freetype/docs/FTL.txt new file mode 100644 index 0000000..0967302 --- /dev/null +++ b/lib/freetype/docs/FTL.txt @@ -0,0 +1,174 @@ + The FreeType Project LICENSE + ---------------------------- + + 2002-Apr-11 + + Copyright 1996-2002 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 will 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 have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © 1996-2002 The FreeType + Project (www.freetype.org). All rights reserved. + """ + + +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 Project, 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-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS 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. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.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 Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes 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'. + + 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. + +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/lib/freetype/docs/GPL.txt b/lib/freetype/docs/GPL.txt new file mode 100644 index 0000000..e8a612e --- /dev/null +++ b/lib/freetype/docs/GPL.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/lib/freetype/docs/INSTALL b/lib/freetype/docs/INSTALL new file mode 100644 index 0000000..8f5bc32 --- /dev/null +++ b/lib/freetype/docs/INSTALL @@ -0,0 +1,65 @@ +Welcome + +There are several ways to build the FreeType library, depending on your +system and the level of customization you need. Here's a short overview +of the documentation available: + +I. Normal installation and upgrades: + + 1. Native TrueType Hinting: + + Native TrueType hinting is disabled by default[1]. If you really need it, + read the file "TRUETYPE" for information. + + + 2. Unix Systems (as well as Cygwin or MSys on Windows): + + Please read *both* UPGRADE.UNX and INSTALL.UNX to install or upgrade + FreeType 2 on a Unix system. Note that you *will* need GNU Make, since + other make tools won't work (this includes BSD Make !!) + + 3. On VMS with the "mms" build tool: + + see INSTALL.VMS for installation instructions on this platform + + 4. Other systems using GNU Make: + + on non-Unix platforms, it's possible to build the library using + GNU Make utility. Note that *NO OTHER MAKE TOOL WILL WORK* !! + This methods supports several compilers on Windows, OS/2 and BeOS, + including Mingw, Visual C++, Borland C++, and more. + + instructions are provided in the file "INSTALL.GNU" + + + 5. With an IDE Project File (e.g. for Visual Studio or CodeWarrior): + + we provide a small number of "project files" for various IDEs to + automatically build the library as well. Note that these files are + not supported and sporadically maintained by FreeType developers, + so don't expect them to work in each release. + + to find them, have a look at the content of the "builds/" + directory, where stands for your OS or environment. + + + 6. From you own IDE, or own Makefiles: + + If you want to create your own project file, follow the instructions + given in the "INSTALL.ANY" document of this directory. + + +II. Custom builds of the library: + + Customizing the compilation of FreeType is easy, and allows you to select + only the components of the font engine that you really need. For more details + read the file "CUSTOMIZE" + + +-------------------------------------------------------------------- + +[1] More details on: http://www.freetype.org/patents.html + +End of file + + \ No newline at end of file diff --git a/lib/freetype/docs/INSTALL.ANY b/lib/freetype/docs/INSTALL.ANY new file mode 100644 index 0000000..5e2cf0e --- /dev/null +++ b/lib/freetype/docs/INSTALL.ANY @@ -0,0 +1,96 @@ +Instructions on how to build FreeType with your own build tool: + + see the file "CUSTOMIZE" to learn how to customize FreeType to + specific environments. + + follow these simple steps: + +I. Normal way: +-------------- + + * DISABLE PRE-COMPILED HEADERS ! This is very important for Visual + C++, because FreeType uses lines like: + + #include FT_FREETYPE_H + + which are not correctly supported by this compiler, while being + ISO C compliant !! + + * You need to add the directories "freetype2/include" to your include + path when compiling the library. + + * FreeType 2 is made of several components; each one of them is + located in a subdirectory of "freetype2/src". For example, + 'freetype2/src/truetype/' contains the TrueType font driver. + + * DO NOT COMPILE ALL C FILES! Rather, compile the following ones: + + -- base components (required) + + src/base/ftsystem.c + src/base/ftinit.c + src/base/ftdebug.c + src/base/ftbase.c + src/base/ftglyph.c + src/base/ftbbox.c + src/base/ftmm.c + src/base/ftpfr.c -- optional, see + src/base/ftbdf.c -- optional, see + src/base/ftwinfnt.c -- optional, see + + src/base/ftmac.c -- only on the Macintosh + + -- other components are optional + + src/autohint/autohint.c -- auto hinting module + src/cache/ftcache.c -- cache sub-system (in beta) + src/sfnt/sfnt.c -- SFNT files support + (TrueType & OpenType) + src/cff/cff.c -- CFF/OpenType font driver + src/pfr/pfr.c -- PFR/TrueDoc font driver + src/bdf/bdf.c -- BDF font driver + src/pcf/pcf.c -- PCF font driver + src/psnames/psnames.c -- Postscript glyph names support + src/psaux/psaux.c -- Postscript Type 1 parsing + src/truetype/truetype.c -- TrueType font driver + src/type1/type1.c -- Type 1 font driver + src/cid/type1cid.c -- Type 1 CID-keyed font driver + src/winfonts/winfonts.c -- Windows FONT / FNT font driver + src/raster1/raster1.c -- monochrome rasterizer + src/smooth/smooth.c -- anti-aliasing rasterizer + + Note: + + `truetype.c' needs `sfnt.c' and `psnames.c' + `type1.c' needs `psaux.c' and `psnames.c' + `type1cid.c' needs `psaux.c' and `psnames.c' + `cff.c' needs `sfnt.c', `psaux.c', and `psnames.c' + + that should be it ! in case of problems, see the archives of + the FreeType development mailing list. + + +II. Support for flat-directory compilation +------------------------------------------ + + It is possible to put all FreeType 2 source files into a single + directory, with the *exception* of the `include' hierarchy. + + 1. Copy all files in current directory: + + cp freetype2/src/base/*.[hc] . + cp freetype2/src/raster1/*.[hc] . + cp freetype2/src/smooth/*.[hc] . + etc. + + 2. Compile sources: + + cc -c -Ifreetype2/include ftsystem.c + cc -c -Ifreetype2/include ftinit.c + cc -c -Ifreetype2/include ftdebug.c + cc -c -Ifreetype2/include ftbase.c + etc. + + You don't need to define the FT_FLAT_COMPILATION macro (as this was + required in previous releases of FreeType 2). + diff --git a/lib/freetype/docs/INSTALL.GNU b/lib/freetype/docs/INSTALL.GNU new file mode 100644 index 0000000..df6f012 --- /dev/null +++ b/lib/freetype/docs/INSTALL.GNU @@ -0,0 +1,128 @@ +This document contains instructions on how to build the FreeType library +on non-Unix systems with the help of GNU Make. Note that if you're running +Cygwin or MSys in Windows, you should follow the instructions of INSTALL.UNX +instead. + + + FreeType 2 includes a powerful and flexible build system that allows + you to easily compile it on a great variety of platforms from the + command line. To do so, just follow these simple instructions: + + a. Install GNU Make + + Because GNU Make is the only Make tool supported to compile + FreeType 2, you should install it on your machine. + + The FreeType 2 build system relies on many features special to GNU + Make -- trying to build the library with any other Make tool will + *fail*. + + NEARLY ALL OTHER MAKE TOOLS WILL FAIL, INCLUDING "BSD MAKE", SO + REALLY INSTALL A RECENT VERSION OF GNU MAKE ON YOUR SYSTEM! + + Make sure that you are invoking GNU Make from the command line, by + typing something like: + + make -v + + to display its version number. + + VERSION 3.78.1 OR NEWER IS NEEDED! + + + + b. Invoke 'make' + + Go to the root directory of FreeType 2, then simply invoke GNU + Make from the command line. This will launch the FreeType 2 host + platform detection routines. A summary will be displayed, for + example, on Win32: + + + ============================================================== + FreeType build system -- automatic system detection + + The following settings are used: + + platform win32 + compiler gcc + configuration directory ./builds/win32 + configuration rules ./builds/win32/w32-gcc.mk + + If this does not correspond to your system or settings please + remove the file 'config.mk' from this directory then read the + INSTALL file for help. + + Otherwise, simply type 'make' again to build the library. + ============================================================= + + + If the detected settings correspond to your platform and compiler, + skip to step e. Note that if your platform is completely alien to + the build system, the detected platform will be 'ansi'. + + + c. Configure the build system for a different compiler + + If the build system correctly detected your platform, but you want + to use a different compiler than the one specified in the summary + (for most platforms, gcc is the defaut compiler), invoke GNU Make + with + + make setup + + For example: + + to use Visual C++ on Win32, type: "make setup visualc" + to use Borland C++ on Win32, type "make setup bcc32" + to use Watcom C++ on Win32, type "make setup watcom" + to use Intel C++ on Win32, type "make setup intelc" + to use LCC-Win32 on Win32, type: "make setup lcc" + to use Watcom C++ on OS/2, type "make setup watcom" + to use VisualAge C++ on OS/2, type "make setup visualage" + + The name to use is platform-dependent. The list of + available compilers for your system is available in the file + `builds//detect.mk' + + If you are satisfied by the new configuration summary, skip to + step e. + + d. Configure the build system for an unknown platform/compiler + + The auto-detection/setup phase of the build system copies a file + to the current directory under the name `config.mk'. + + For example, on OS/2+gcc, it would simply copy + `builds/os2/os2-gcc.mk' to `./config.mk'. + + If for some reason your platform isn't correctly detected, copy + manually the configuration sub-makefile to `./config.mk' and go to + step e. + + Note that this file is a sub-Makefile used to specify Make + variables for compiler and linker invocation during the build. + You can easily create your own version from one of the existing + configuration files, then copy it to the current directory under + the name `./config.mk'. + + e. Build the library + + The auto-detection/setup phase should have copied a file in the + current directory, called `./config.mk'. This file contains + definitions of various Make variables used to invoke the compiler + and linker during the build. + + To launch the build, simply invoke GNU Make again: The top + Makefile will detect the configuration file and run the build with + it. + + + + Final note: + + the build system builds a statically linked library of the font engine + in the "objs" directory. It does _not_ support the build of DLLs on + Windows and OS/2, if you need these, you'll have to either use + a IDE-specific project file, or follow the instructions in + "INSTALL.ANY" to create your own Makefiles. diff --git a/lib/freetype/docs/INSTALL.UNX b/lib/freetype/docs/INSTALL.UNX new file mode 100644 index 0000000..6af176d --- /dev/null +++ b/lib/freetype/docs/INSTALL.UNX @@ -0,0 +1,181 @@ +This document contains instructions on how to build the FreeType library +on Unix systems. This also works for emulations like Cygwin or MSys on +Win32: + + + I. Ensure that you are using GNU Make + ------------------------------------- + + The FreeType build system _exclusively_ works with GNU Make. You + will not be able to compile the library with the instructions + below using any other alternative (including BSD Make). + + Trying to compile the library with a different Make tool will + print a message like: + + Sorry, GNU make is required to build FreeType2. + + and the build process will be aborted. If this happens, install + GNU Make on your system, and use the GNUMAKE environment variable + to name it. + + + + IV. Build and install the library + --------------------------------- + + The following should work on all Unix systems where the 'make' + command invokes GNU Make: + + ./configure --prefix= + make + make install (as root) + + where "" must be replaced by the prefix returned by + the "freetype-config" command. + + When using a different command to invoke GNU Make, use the GNUMAKE + variable. For example, if `gmake' is the command to use on your + system, do something like: + + GNUMAKE=gmake ./configure --prefix= + gmake + gmake install (as root) + + If this still doesn't work, something's rotten on your system( + (e.g. you're using a very old version of GNU Make) + + + +I. Unix systems +--------------- + + If you have GNU Make installed, simply type + + ./configure + make + make install + + on the command line to configure, build and install FreeType on your + system. Note that the default installation path is "/usr/local". + + Please read the file README.UNX, it contains _critical_ information + regarding the installation of FreeType on many Unix systems. + + +II. From the command line +------------------------- + + If you are not using Unix, there are two ways to quickly build + FreeType 2 from the command line. + + The first, and favorite one, is to use the "Jam" build tool. Jam is + a highly portable replacement for Make whose control files do not + depend on the current platform or compiler toolset. + + For more information, please see: + + http://www.freetype.org/jam/index.html + + The second one is to use "GNU Make" (and NO OTHER MAKE TOOL). + + + 1. Building FT2 with "Jam" + -------------------------- + + Once you've got *our version* of the Jam tool installed on your + system, simply go to the top-level FT2 directory, then type + + "jam" + + on the command line. This will build the library and place it in + the "objs" directory. + + By default, a static library is built. On Unix systems, it is + possible to build a shared library through the "libtool" script. + You need to have libtool installed on your system, then re-define + a few environment variables before invoking Jam, as in + + export CC="libtool --mode=compile cc" + export LINK="libtool --mode=link cc" + jam + + In later releases of FT2, building shared libraries with Jam + should become automatic on Unix systems. + + + 2. Building FT2 with "GNU Make" + ------------------------------- + + You need to have GNU Make (version 3.78.1 or newer) installed on + your system to compile the library from the command line. This will + _NOT_ work with other make tools (including BSD make)! + + [Well, this is not really correct. Recently, a perl implementation + of make called `makepp' has appeared which can also build FreeType 2 + successfully on Unix platforms. See http://makepp.sourceforge.net + for more details.] + + - Go to the `freetype2' directory. + + - Unix (any C compiler should work): + + - make setup (don't worry, this will invoke a configure script) + - make + - make install + + Alternatively, you can pass parameters to the configure script + within the CFG variable, as in: + + - make setup CFG="--prefix=/usr" + - make + - make install + + If the configure script isn't run, try to add `unix' as a target + on the command line, e.g.: + + - make setup unix CFG="--prefix=/opt/experimental" + + + - Windows: + + We provide a version of GNU Make for Win32 on the FreeType site. + See http://www.freetype.org/download.html for details. + + - gcc (Mingw, _not_ CygWin): + + - make setup + - make + + + - Visual C++: + + - make setup visualc + - make + + + - other compilers: + + - make setup bcc32 -> Borland C++ 32 bits + - make setup intelc -> Intel C++ + - make setup watcom -> Watcom C++ + - make setup lcc -> Win32-LCC + + + If you want to build FreeType 2 in another directory, you must set + two environment variables, `OJB_DIR' and `TOP_DIR'. The former + gives the directory where the object files and the library should be + created (this directory must exist), the latter the top directory of + the FreeType 2 source tree. Example: + + OBJ_DIR=~/freetype2.compiled TOP_DIR=~/freetype2 \ + make -f$TOP_DIR/Makefile setup ansi + OBJ_DIR=~/freetype2.compiled TOP_DIR=~/freetype2 \ + make -f$TOP_DIR/Makefile + + On Unix boxes, calling `configure' from the build directory is + sufficient; it will build a small Makefile which calls the + FreeType 2 Makefile with the necessary parameters. + + +--- end of INSTALL -- diff --git a/lib/freetype/docs/INSTALL.VMS b/lib/freetype/docs/INSTALL.VMS new file mode 100644 index 0000000..a82b9fd --- /dev/null +++ b/lib/freetype/docs/INSTALL.VMS @@ -0,0 +1,35 @@ +How to build the freetype2 library on VMS +----------------------------------------- + +Just type one of the following depending on the type of external entries you +want: + + mms + +or + + mms/macro=("COMP_FLAGS=/name=(as_is,short)") + +The library is avalaible in the directory + + [.LIB] + +To compile applications using freetype2 you'll need to define the logical +FREETYPE pointing to the directory + + [.INCLUDE.FREETYPE] + +(i.e., if the directory in which this README.VMS file is located is +$disk:[freetype] then define the logical with + + define freetype $disk:[freetype.include.freetype] + +This version has been tested with Compaq C V6.2-006 on OpenVMS Alpha V7.2-1. + + + Any problems can be reported to + + joukj@hrem.stm.tudelft.nl + + + Jouk Jansen diff --git a/lib/freetype/docs/PATENTS b/lib/freetype/docs/PATENTS new file mode 100644 index 0000000..717bb7d --- /dev/null +++ b/lib/freetype/docs/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.html + +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/lib/freetype/docs/TODO b/lib/freetype/docs/TODO new file mode 100644 index 0000000..b0abb68 --- /dev/null +++ b/lib/freetype/docs/TODO @@ -0,0 +1,13 @@ +Note that the list of known bugs for FreeType 2 is now located in the +document "docs/BUGS". + +Here is a list of items that need to be addressed in FreeType 2; they are +not exactly bugs, but should be considered though: + +* Implement stem3/counter hints properly in the Postscript hinter. + +* FInalize the cache sub-system. If has been in beta for too long :-) + +* The automatic and Postscript hinters have been improved to increase + the quality of AA text, but Monochrome and LCD hinting still suck. we + need to do something about that.. diff --git a/lib/freetype/docs/TRUETYPE b/lib/freetype/docs/TRUETYPE new file mode 100644 index 0000000..4ec4001 --- /dev/null +++ b/lib/freetype/docs/TRUETYPE @@ -0,0 +1,23 @@ +How to enable the TrueType native hinter if you need it +-------------------------------------------------------- + + The TrueType bytecode interpreter is disabled in all public + releases of the FreeType packages for patents reasons (see + http://www.freetype.org/patents.html for more details). + + However, many Linux distributions do enable the interpreter in the + FreeType packages (DEB/RPM/etc.) they produce for their platforms. + If you are using TrueType fonts on your system, you most probably + want to enable it manually by doing the following: + + - open the file "include/freetype/config/ftoption.h" + + - locate a line that says: + + #undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + - change it to: + + #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + of course, this must be done _before_ compiling the library diff --git a/lib/freetype/docs/UPGRADE.UNX b/lib/freetype/docs/UPGRADE.UNX new file mode 100644 index 0000000..0e67f90 --- /dev/null +++ b/lib/freetype/docs/UPGRADE.UNX @@ -0,0 +1,124 @@ + +SPECIAL NOTE FOR UNIX USERS +=========================== + + If you are installing this release of FreeType on a system that + already uses release 2.0.5 (or even an older version), you have to + perform a few special steps to ensure that everything goes well. + + + I. Enable the TrueType bytecode hinter if you need it + ----------------------------------------------------- + + See the instructions in the file "TRUETYPE" of this directory. + + Note that FreeType supports TrueType fonts without the bytecode + interpreter through its auto-hinter, which now generate relatively good + results with most fonts. + + + II. Determine the correct installation path + -------------------------------------------- + + By default, the source package will install the library in + "/usr/local". However, many Unix distributions now install the + library in "/usr", since FreeType is becoming a critical system + component. + + If FreeType is already installed on your system, type + + freetype-config --prefix + + on the command line. This should return the installation path to + use below (e.g. "/usr" or "/usr/local"). Otherwise, simply use + "/usr" (or what you think is adequate for your installation). + + + + III. Ensure that you are using GNU Make + --------------------------------------- + + The FreeType build system _exclusively_ works with GNU Make. You + will not be able to compile the library with the instructions + below using any other alternative (including BSD Make). + + Trying to compile the library with a different Make tool will + print a message like: + + Sorry, GNU make is required to build FreeType2. + + and the build process will be aborted. If this happens, install + GNU Make on your system, and use the GNUMAKE environment variable + to name it. + + + + IV. Build and install the library + --------------------------------- + + The following should work on all Unix systems where the `make' + command invokes GNU Make: + + ./configure --prefix= + make + make install (as root) + + where "" must be replaced by the prefix returned by + the "freetype-config" command. + + When using a different command to invoke GNU Make, use the GNUMAKE + variable. For example, if `gmake' is the command to use on your + system, do something like: + + GNUMAKE=gmake ./configure --prefix= + gmake + gmake install (as root) + + If this still doesn't work, read the detailed compilation + procedure available in the file "docs/BUILD" for troubleshooting. + + + V. Take care of XFree86 version 4 + --------------------------------- + + Certain recent Linux distributions will install _several_ versions + of FreeType on your system. For example, on a fresh Mandrake 8.1 + system, you can find the following files: + + /usr/lib/libfreetype.so which links to + /usr/lib/libfreetype.6.1.0.so + + and + + /usr/X11R6/lib/libfreetype.so which links to + /usr/X11R6/lib/libfreetype.6.0.so + + Note that these files correspond to two distinct versions of the + library! It seems that this surprising issue is due to the + install scripts of recent XFree86 servers (from 4.1.0) which + irremediably install their own (dated) version of the library in + "/usr/X11R6/lib". + + In certain _rare_ cases you may experience minor problems if you + install this release of the library in "/usr" only, namely, that + certain applications will not benefit from the bug fixes and + rendering improvements you'd expect. + + There are two good ways to deal with this situation: + + - Install the library _twice_, in "/usr" and in "/usr/X11R6" + (you have to do that each time you install a new FreeType + release though). + + - Change the link in /usr/X11R6/lib/libfreetype.so to point to + + /usr/lib/libfreetype.so, + + and get rid of + + /usr/X11R6/lib/libfreetype.6.0.so + + The FreeType Team is not responsible for this problem, so please + contact either the XFree86 development team or your Linux + distributor to help clear this issue in case the information given + here doesn't help. diff --git a/lib/freetype/docs/VERSION.DLL b/lib/freetype/docs/VERSION.DLL new file mode 100644 index 0000000..ec4f4c6 --- /dev/null +++ b/lib/freetype/docs/VERSION.DLL @@ -0,0 +1,90 @@ +Due to our use of "libtool" to generate and install the FreeType 2 libraries +on Unix systems, as well as other historical events, it is generally very +difficult to know precisely which release of the font engine is installed +on a given system. + +This file tries to explain why and to document ways to properly detect +FreeType on Unix. + + +I. Version & Release numbers: + +For each new public release of FreeType 2, there are generally *three* +distinct "version" numbers to consider: + + * the official FT2 release number, like 2.0.9, or 2.1.3 + + * the libtool (and Unix) specific version number, like "9.2.3". This + is what "freetype-config --version" will return + + * the platform-specific shared object number, used for example when + the library is installed as "/usr/lib/libfreetype.so.6.3.2" + + +the platform-specific number is, unsurprisingly, platform-specific and varies +with the operating system you're using (several variants of Linux, FreeBSD, +Solaris, etc...). You should thus _never_ use it, even for simple tests. + +the libtool-specific number does not equal the release number but is tied +to it. + +the release number is available at *compile* time through the following +macros defined in FT_FREETYPE_H: + + - FREETYPE_MAJOR : major release number + - FREETYPE_MINOR : minor release number + - FREETYPE_PATCH : patch release number + +see below for some Autoconf fragment to + + +the release number is also available at *runtime* through the +"FT_Library_Version" API. Unfortunately, this one wasn't available or +working correctly before the 2.1.3 official release !! + + +II. Table: + +the following is a simple table that gives, for each official release, +the corresponding libtool number, as well as the shared object number +found on _most_ systems, but not all of them: + + release libtool so +------------------------------------- + 2.1.4 9.3.3 6.3.3 + 2.1.3 9.2.3 6.3.2 + 2.1.2 9.1.3 6.3.1 + 2.1.1 9.0.3 ? + 2.1.0 8.0.2 ? + 2.0.9 9.0.3 ? + 2.0.8 8.0.2 ? + +the libtool numbers are a bit inconsistent due to the library's history: + + - 2.1.0 was created as a development branch from 2.0.8 + (hence the same libtool numbers) + + - 2.0.9 was a bug-fix release of the "stable" branch, we + apparently incorrectly increased its libtool number + + - 2.1.4 is still in the "development" branch, however it's stable enough + to be the basis of an upcoming 2.2.0 release + + + +III. AutoConf Code Fragment: + +Lars Clausen contributed the following Autoconf fragment to detect at +which version of FreeType is installed on your system. This one tests +for a version that is at least 2.0.9, you should change the last line to +check against other release numbers. + + AC_MSG_CHECKING([for version of FreeType]) + FREETYPE_INCLUDE=`freetype-config --cflags | cut -c3-` + FREETYPE_MAJOR=`grep '^#define FREETYPE_MAJOR' $FREETYPE_INCLUDE/freetype/freetype.h | cut -d' ' -f3` + FREETYPE_MINOR=`grep '^#define FREETYPE_MINOR' $FREETYPE_INCLUDE/freetype/freetype.h | cut -d' ' -f3` + FREETYPE_PATCH=`grep '^#define FREETYPE_PATCH' $FREETYPE_INCLUDE/freetype/freetype.h | cut -d' ' -f3` + FREETYPE_VERSION=`echo | awk "BEGIN { printf \"%d\", ($FREETYPE_MAJOR * 1000 + $FREETYPE_MINOR) * 1000 + $FREETYPE_PATCH;}"` + AC_MSG_RESULT([$FREETYPE_MAJOR.$FREETYPE_MINOR.$FREETYPE_PATCH]) + if test "$FREETYPE_VERSION" -ge 2000009; then + diff --git a/lib/freetype/docs/license.txt b/lib/freetype/docs/license.txt new file mode 100644 index 0000000..51b52bf --- /dev/null +++ b/lib/freetype/docs/license.txt @@ -0,0 +1,28 @@ + + The FreeType 2 font engine is copyrighted work, and cannot be + used legally without a software license. In order to make this + project usable to a vast majority of developers, we distribute it + under two dual licenses. + + What this means is that *you* must choose *one* license among those + described below, then obey all its terms and conditions when using + FreeType 2 in any of your projects or products: + + + - The FreeType License, found in the file "FTL.TXT", which is + an BSD-style open-source license *with* an advertising + clause that forces you to explicitely cite the + FreeType project in your product's documentation. All + details are in the license file + + + - The GNU General Public License, found in "GPL.TXT", which is + the traditionnal and "viral" GPL license, that + forces you to redistribute the _complete_ sources of all + your products that simply use FreeType 2. + + + Note that the contributed PCF driver comes with a license similar to + that of X Window System which is compatible to the above two + licenses (see file src/pcf/readme). + diff --git a/lib/freetype/docs/modules.txt b/lib/freetype/docs/modules.txt new file mode 100644 index 0000000..04f4d12 --- /dev/null +++ b/lib/freetype/docs/modules.txt @@ -0,0 +1,14 @@ +This file shows the interdependencies of various FreeType modules. + +Note that the use of `psnames' can be controlled in ftconfig.h +(FT_CONFIG_OPTION_POSTSCRIPT_NAMES). + + module dependency + --------------------------------------- + cff sfnt, pshinter, psnames + cid psaux, pshinter, psnames + truetype sfnt + type1 psaux, pshinter, psnames + type42 truetype + psaux psnames + sfnt psnames diff --git a/lib/freetype/freetype.def b/lib/freetype/freetype.def new file mode 100644 index 0000000..f42930c --- /dev/null +++ b/lib/freetype/freetype.def @@ -0,0 +1,273 @@ +LIBRARY freetype +EXPORTS +FT_Done_Memory +FT_New_Memory +FT_Stream_Open +ft_debug_init +FT_Add_Default_Modules +FT_Done_FreeType +FT_Init_FreeType +_debug_mem_dummy +FT_Activate_Size +FT_Add_Module +FT_Add64 +FT_Alloc +FT_Angle_Diff +FT_Atan2 +FT_Attach_File +FT_Attach_Stream +FT_CeilFix +FT_CMap_Done +FT_CMap_New +FT_Cos +FT_Div64by32 +FT_DivFix +FT_Done_Face +FT_Done_GlyphSlot +FT_Done_Library +FT_Done_Size +FT_FloorFix +FT_Free +FT_Get_Char_Index +FT_Get_First_Char +FT_Get_Glyph_Name +FT_Get_Kerning +FT_Get_Module +FT_Get_Module_Interface +FT_Get_Name_Index +FT_Get_Next_Char +FT_Get_Postscript_Name +FT_Get_Renderer +FT_Get_Sfnt_Name +FT_Get_Sfnt_Name_Count +FT_Get_Sfnt_Table +FT_GlyphLoader_Add +FT_GlyphLoader_CheckPoints +FT_GlyphLoader_CheckSubGlyphs +FT_GlyphLoader_CopyPoints +FT_GlyphLoader_CreateExtra +FT_GlyphLoader_Done +FT_GlyphLoader_New +FT_GlyphLoader_Prepare +FT_GlyphLoader_Reset +FT_GlyphLoader_Rewind +ft_glyphslot_alloc_bitmap +ft_glyphslot_free_bitmap +ft_glyphslot_set_bitmap +FT_Library_Version +FT_List_Add +FT_List_Finalize +FT_List_Find +FT_List_Insert +FT_List_Iterate +FT_List_Remove +FT_List_Up +FT_Load_Char +FT_Load_Glyph +FT_Load_Sfnt_Table +FT_Lookup_Renderer +FT_MulDiv +FT_MulFix +FT_MulTo64 +FT_New_Face +FT_New_GlyphSlot +FT_New_Library +FT_New_Memory_Face +FT_New_Size +FT_Open_Face +FT_Outline_Check +FT_Outline_Copy +FT_Outline_Decompose +FT_Outline_Done +FT_Outline_Done_Internal +FT_Outline_Get_Bitmap +FT_Outline_Get_CBox +FT_Outline_New +FT_Outline_New_Internal +FT_Outline_Render +FT_Outline_Reverse +FT_Outline_Transform +FT_Outline_Translate +FT_Realloc +FT_Remove_Module +FT_Render_Glyph +FT_Render_Glyph_Internal +FT_RoundFix +FT_Select_Charmap +FT_Set_Char_Size +FT_Set_Charmap +FT_Set_Debug_Hook +FT_Set_Hint_Flags +FT_Set_Pixel_Sizes +FT_Set_Renderer +FT_Set_Transform +FT_Sin +FT_Sqrt32 +FT_SqrtFixed +FT_Stream_Close +FT_Stream_EnterFrame +FT_Stream_ExitFrame +FT_Stream_ExtractFrame +FT_Stream_GetChar +FT_Stream_GetLong +FT_Stream_GetLongLE +FT_Stream_GetOffset +FT_Stream_GetShort +FT_Stream_GetShortLE +FT_Stream_OpenMemory +FT_Stream_Pos +FT_Stream_Read +FT_Stream_ReadAt +FT_Stream_ReadChar +FT_Stream_ReadFields +FT_Stream_ReadLong +FT_Stream_ReadLongLE +FT_Stream_ReadOffset +FT_Stream_ReadShort +FT_Stream_ReadShortLE +FT_Stream_ReleaseFrame +FT_Stream_Seek +FT_Stream_Skip +FT_Tan +ft_validator_error +ft_validator_init +ft_validator_run +FT_Vector_From_Polar +FT_Vector_Length +FT_Vector_Polarize +FT_Vector_Rotate +FT_Vector_Transform +FT_Vector_Unit +ft_bitmap_glyph_class +FT_Done_Glyph +FT_Get_Glyph +FT_Glyph_Copy +FT_Glyph_Get_CBox +FT_Glyph_To_Bitmap +FT_Glyph_Transform +FT_Matrix_Invert +FT_Matrix_Multiply +ft_outline_glyph_class +FT_Get_Multi_Master +FT_Set_MM_Blend_Coordinates +FT_Set_MM_Design_Coordinates +FT_Get_BDF_Charset_ID +FT_Get_BDF_Property +FT_Get_PS_Font_Info +FT_Has_PS_Glyph_Names +FT_Get_X11_Font_Format +FT_Get_PFR_Advance +FT_Get_PFR_Kerning +FT_Get_PFR_Metrics +FT_Stroker_BeginSubPath +FT_Stroker_ConicTo +FT_Stroker_CubicTo +FT_Stroker_Done +FT_Stroker_EndSubPath +FT_Stroker_Export +FT_Stroker_GetCounts +FT_Stroker_LineTo +FT_Stroker_New +FT_Stroker_ParseOutline +FT_Stroker_Set +FT_Get_WinFNT_Header +FT_Outline_Get_BBox +ah_arctan +autohint_module_class +ft_autohinter_service +bdf_cmap_class +bdf_driver_class +FT_LruList_Destroy +FT_LruList_Lookup +FT_LruList_New +FT_LruList_Remove +FT_LruList_Remove_Selection +FT_LruList_Reset +ftc_cache_clear +ftc_cache_done +ftc_cache_init +ftc_cache_lookup +ftc_cmap_cache_class +FTC_CMapCache_Lookup +FTC_CMapCache_New +ftc_face_list_class +ftc_family_done +ftc_family_init +ftc_family_table_alloc +ftc_family_table_free +ftc_glyph_family_done +ftc_glyph_family_init +ftc_glyph_node_compare +ftc_glyph_node_done +ftc_glyph_node_init +ftc_image_cache_class +FTC_Image_Cache_Lookup +FTC_Image_Cache_New +FTC_ImageCache_Lookup +FTC_ImageCache_New +FTC_Manager_Compress +FTC_Manager_Done +FTC_Manager_Lookup_Face +FTC_Manager_Lookup_Size +FTC_Manager_New +FTC_Manager_Register_Cache +FTC_Manager_Reset +ftc_node_destroy +ftc_node_done +FTC_Node_Unref +ftc_sbit_cache_class +FTC_SBit_Cache_Lookup +FTC_SBit_Cache_New +FTC_SBitCache_Lookup +FTC_SBitCache_New +ftc_size_list_class +cff_cmap_encoding_class_rec +cff_cmap_unicode_class_rec +cff_driver_class +t1cid_driver_class +FT_Stream_OpenGzip +BitOrderInvert +FourByteSwap +pcf_cmap_class +pcf_driver_class +RepadBitmap +TwoByteSwap +pfr_cmap_class_rec +pfr_driver_class +pfr_service_rec +ps_parser_funcs +ps_table_funcs +psaux_module_class +t1_builder_funcs +t1_cmap_classes +t1_cmap_custom_class_rec +t1_cmap_expert_class_rec +t1_cmap_standard_class_rec +t1_cmap_unicode_class_rec +t1_decoder_funcs +ps1_hints_apply +ps2_hints_apply +ps3_hints_apply +pshinter_module_class +psnames_module_class +ft_raster1_renderer_class +ft_raster5_renderer_class +ft_standard_raster +sbit_metrics_fields +sfnt_module_class +tt_cmap0_class_rec +tt_cmap10_class_rec +tt_cmap12_class_rec +tt_cmap2_class_rec +tt_cmap4_class_rec +tt_cmap6_class_rec +tt_cmap8_class_rec +ft_grays_raster +ft_smooth_lcd_renderer_class +ft_smooth_lcdv_renderer_class +ft_smooth_renderer_class +gray_raster_render +tt_driver_class +t1_driver_class +t42_driver_class +winfnt_driver_class diff --git a/lib/freetype/i386/.cvsignore b/lib/freetype/i386/.cvsignore new file mode 100644 index 0000000..2806cdc --- /dev/null +++ b/lib/freetype/i386/.cvsignore @@ -0,0 +1,2 @@ +.*.d +*.o \ No newline at end of file diff --git a/lib/freetype/i386/setjmplongjmp.s b/lib/freetype/i386/setjmplongjmp.s new file mode 100644 index 0000000..36514db --- /dev/null +++ b/lib/freetype/i386/setjmplongjmp.s @@ -0,0 +1,87 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: FreeType implementation for ReactOS + * PURPOSE: Implementation of _setjmp/longjmp + * FILE: thirdparty/freetype/i386/setjmplongjmp.s + * PROGRAMMER: Ge van Geldorp (ge@gse.nl) + * NOTES: Copied from glibc. + * I have the feeling this could be implemented using the SEH + * routines, but if it's good enough for glibc it's propably + * good enough for me... + * The MingW headers define jmp_buf to be an array of 16 ints, + * based on the jmp_buf used by MSCVRT. We're using only 6 of + * them, so plenty of space. + */ + +#define JB_BX 0 +#define JB_SI 1 +#define JB_DI 2 +#define JB_BP 3 +#define JB_SP 4 +#define JB_PC 5 + +#define PCOFF 0 + +#define JMPBUF 4 + +/* + * int + * _setjmp(jmp_buf env); + * + * Parameters: + * [ESP+04h] - jmp_buf env + * Registers: + * None + * Returns: + * 0 + * Notes: + * Sets up the jmp_buf + */ +.globl __setjmp +__setjmp: + xorl %eax, %eax + movl JMPBUF(%esp), %edx + + /* Save registers. */ + movl %ebx, (JB_BX*4)(%edx) + movl %esi, (JB_SI*4)(%edx) + movl %edi, (JB_DI*4)(%edx) + leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ + movl %ecx, (JB_SP*4)(%edx) + movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */ + movl %ecx, (JB_PC*4)(%edx) + movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ + ret + +#define VAL 8 + +/* + * void + * longjmp(jmp_buf env, int value); + * + * Parameters: + * [ESP+04h] - jmp_buf setup by _setjmp + * [ESP+08h] - int value to return + * Registers: + * None + * Returns: + * Doesn't return + * Notes: + * Non-local goto + */ +.globl _longjmp +_longjmp: + movl JMPBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ + + movl VAL(%esp), %eax /* Second argument is return value. */ + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + /* Restore registers. */ + movl (JB_BX*4)(%ecx), %ebx + movl (JB_SI*4)(%ecx), %esi + movl (JB_DI*4)(%ecx), %edi + movl (JB_BP*4)(%ecx), %ebp + movl (JB_SP*4)(%ecx), %esp + /* Jump to saved PC. */ + jmp *%edx diff --git a/lib/freetype/include/freetype/cache/ftccache.h b/lib/freetype/include/freetype/cache/ftccache.h new file mode 100644 index 0000000..701b13e --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftccache.h @@ -0,0 +1,304 @@ +/***************************************************************************/ +/* */ +/* ftccache.h */ +/* */ +/* FreeType internal cache interface (specification). */ +/* */ +/* Copyright 2000-2001, 2002 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 __FTCCACHE_H__ +#define __FTCCACHE_H__ + + +/* define to allow cache lookup inlining */ +#define FTC_CACHE_USE_INLINE + + +FT_BEGIN_HEADER + + /* handle to cache object */ + typedef struct FTC_CacheRec_* FTC_Cache; + + /* handle to cache class */ + typedef const struct FTC_Cache_ClassRec_* FTC_Cache_Class; + + /* handle to cache node family */ + typedef struct FTC_FamilyRec_* FTC_Family; + + /* handle to cache root query */ + typedef struct FTC_QueryRec_* FTC_Query; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each cache controls one or more cache nodes. Each node is part of */ + /* the global_lru list of the manager. Its `data' field however is used */ + /* as a reference count for now. */ + /* */ + /* A node can be anything, depending on the type of information held by */ + /* the cache. It can be an individual glyph image, a set of bitmaps */ + /* glyphs for a given size, some metrics, etc. */ + /* */ + /*************************************************************************/ + + /* structure size should be 20 bytes on 32-bits machines */ + typedef struct FTC_NodeRec_ + { + FTC_Node mru_next; /* circular mru list pointer */ + FTC_Node mru_prev; /* circular mru list pointer */ + FTC_Node link; /* used for hashing */ + FT_UInt32 hash; /* used for hashing too */ + FT_UShort fam_index; /* index of family the node belongs to */ + FT_Short ref_count; /* reference count for this node */ + + } FTC_NodeRec; + + +#define FTC_NODE( x ) ( (FTC_Node)(x) ) +#define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* can be used as a FTC_Node_DoneFunc */ + FT_EXPORT( void ) + ftc_node_done( FTC_Node node, + FTC_Cache cache ); + + /* reserved for manager's use */ + FT_EXPORT( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE QUERY DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* A structure modelling a cache node query. The following fields must */ + /* all be set by the @FTC_Family_CompareFunc method of a cache's family */ + /* list. */ + /* */ + typedef struct FTC_QueryRec_ + { + FTC_Family family; + FT_UFast hash; + + } FTC_QueryRec; + + +#define FTC_QUERY( x ) ( (FTC_Query)(x) ) +#define FTC_QUERY_P( x ) ( (FTC_Query*)(x) ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE FAMILY DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FamilyRec_ + { + FT_LruNodeRec lru; + FTC_Cache cache; + FT_UInt num_nodes; + FT_UInt fam_index; + + } FTC_FamilyRec; + + +#define FTC_FAMILY( x ) ( (FTC_Family)(x) ) +#define FTC_FAMILY_P( x ) ( (FTC_Family*)(x) ) + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* must be called by any FTC_Node_InitFunc routine */ + FT_EXPORT( FT_Error ) + ftc_family_init( FTC_Family family, + FTC_Query query, + FTC_Cache cache ); + + + /* can be used as a FTC_Family_DoneFunc; otherwise, must be called */ + /* by any family finalizer function */ + FT_EXPORT( void ) + ftc_family_done( FTC_Family family ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* each cache really implements a dynamic hash table to manage its nodes */ + typedef struct FTC_CacheRec_ + { + FTC_Manager manager; + FT_Memory memory; + FTC_Cache_Class clazz; + + FT_UInt cache_index; /* in manager's table */ + FT_Pointer cache_data; /* used by cache node methods */ + + FT_UFast p; + FT_UFast mask; + FT_Long slack; + FTC_Node* buckets; + + FT_LruList_ClassRec family_class; + FT_LruList families; + + } FTC_CacheRec; + + +#define FTC_CACHE( x ) ( (FTC_Cache)(x) ) +#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) + + + /* initialize a given cache */ + typedef FT_Error + (*FTC_Cache_InitFunc)( FTC_Cache cache ); + + /* clear a cache */ + typedef void + (*FTC_Cache_ClearFunc)( FTC_Cache cache ); + + /* finalize a given cache */ + typedef void + (*FTC_Cache_DoneFunc)( FTC_Cache cache ); + + + typedef FT_Error + (*FTC_Family_InitFunc)( FTC_Family family, + FTC_Query query, + FTC_Cache cache ); + + typedef FT_Int + (*FTC_Family_CompareFunc)( FTC_Family family, + FTC_Query query ); + + typedef void + (*FTC_Family_DoneFunc)( FTC_Family family, + FTC_Cache cache ); + + /* initialize a new cache node */ + typedef FT_Error + (*FTC_Node_InitFunc)( FTC_Node node, + FT_Pointer type, + FTC_Cache cache ); + + /* compute the weight of a given cache node */ + typedef FT_ULong + (*FTC_Node_WeightFunc)( FTC_Node node, + FTC_Cache cache ); + + /* compare a node to a given key pair */ + typedef FT_Bool + (*FTC_Node_CompareFunc)( FTC_Node node, + FT_Pointer key, + FTC_Cache cache ); + + /* finalize a given cache node */ + typedef void + (*FTC_Node_DoneFunc)( FTC_Node node, + FTC_Cache cache ); + + + typedef struct FTC_Cache_ClassRec_ + { + FT_UInt cache_size; + FTC_Cache_InitFunc cache_init; + FTC_Cache_ClearFunc cache_clear; + FTC_Cache_DoneFunc cache_done; + + FT_UInt family_size; + FTC_Family_InitFunc family_init; + FTC_Family_CompareFunc family_compare; + FTC_Family_DoneFunc family_done; + + FT_UInt node_size; + FTC_Node_InitFunc node_init; + FTC_Node_WeightFunc node_weight; + FTC_Node_CompareFunc node_compare; + FTC_Node_DoneFunc node_done; + + } FTC_Cache_ClassRec; + + + /* */ + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* can be used directly as FTC_Cache_DoneFunc(), or called by custom */ + /* cache finalizers */ + FT_EXPORT( void ) + ftc_cache_done( FTC_Cache cache ); + + /* can be used directly as FTC_Cache_ClearFunc(), or called by custom */ + /* cache clear routines */ + FT_EXPORT( void ) + ftc_cache_clear( FTC_Cache cache ); + + /* initalize the hash table within the cache */ + FT_EXPORT( FT_Error ) + ftc_cache_init( FTC_Cache cache ); + + /* can be called when the key's hash value has been computed */ + FT_EXPORT( FT_Error ) + ftc_cache_lookup( FTC_Cache cache, + FTC_Query query, + FTC_Node *anode ); + + /* */ + +FT_END_HEADER + + +#endif /* __FTCCACHE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftccmap.h b/lib/freetype/include/freetype/cache/ftccmap.h new file mode 100644 index 0000000..11f7b03 --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftccmap.h @@ -0,0 +1,216 @@ +/***************************************************************************/ +/* */ +/* ftccmap.h */ +/* */ +/* FreeType charmap cache (specification). */ +/* */ +/* Copyright 2000-2001 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 __FTCCMAP_H__ +#define __FTCCMAP_H__ + +#include +#include FT_CACHE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* @type: */ + /* FTC_CmapCache */ + /* */ + /* @description: */ + /* An opaque handle used to manager a charmap cache. This cache is */ + /* to hold character codes -> glyph indices mappings. */ + /* */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /*************************************************************************/ + /* */ + /* @type: */ + /* FTC_CMapDesc */ + /* */ + /* @description: */ + /* A handle to an @FTC_CMapDescRec structure used to describe a given */ + /* charmap in a charmap cache. */ + /* */ + /* Each @FTC_CMapDesc describes which charmap (of which @FTC_Face) we */ + /* want to use in @FTC_CMapCache_Lookup. */ + /* */ + typedef struct FTC_CMapDescRec_* FTC_CMapDesc; + + + /*************************************************************************/ + /* */ + /* @enum: */ + /* FTC_CMapType */ + /* */ + /* @description: */ + /* The list of valid @FTC_CMap types. They indicate how we want to */ + /* address a charmap within an @FTC_FaceID. */ + /* */ + /* @values: */ + /* FTC_CMAP_BY_INDEX :: */ + /* Address a charmap by its index in the corresponding @FT_Face. */ + /* */ + /* FTC_CMAP_BY_ENCODING :: */ + /* Use a @FT_Face charmap that corresponds to a given encoding. */ + /* */ + /* FTC_CMAP_BY_ID :: */ + /* Use an @FT_Face charmap that corresponds to a given */ + /* (platform,encoding) ID. See @FTC_CMapIdRec. */ + /* */ + typedef enum FTC_CMapType_ + { + FTC_CMAP_BY_INDEX = 0, + FTC_CMAP_BY_ENCODING = 1, + FTC_CMAP_BY_ID = 2 + + } FTC_CMapType; + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* FTC_CMapIdRec */ + /* */ + /* @description: */ + /* A short structure to identify a charmap by a (platform,encoding) */ + /* pair of values. */ + /* */ + /* @fields: */ + /* platform :: The platform ID. */ + /* */ + /* encoding :: The encoding ID. */ + /* */ + typedef struct FTC_CMapIdRec_ + { + FT_UInt platform; + FT_UInt encoding; + + } FTC_CMapIdRec; + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* FTC_CMapDescRec */ + /* */ + /* @description: */ + /* A structure to describe a given charmap to @FTC_CMapCache. */ + /* */ + /* @fields: */ + /* face_id :: @FTC_FaceID of the face this charmap belongs to. */ + /* */ + /* type :: The type of charmap, see @FTC_CMapType. */ + /* */ + /* u.index :: For @FTC_CMAP_BY_INDEX types, this is the charmap */ + /* index (within a @FT_Face) we want to use. */ + /* */ + /* u.encoding :: For @FTC_CMAP_BY_ENCODING types, this is the charmap */ + /* encoding we want to use. see @FT_Encoding. */ + /* */ + /* u.id :: For @FTC_CMAP_BY_ID types, this is the */ + /* (platform,encoding) pair we want to use. see */ + /* @FTC_CMapIdRec and @FT_CharMapRec. */ + /* */ + typedef struct FTC_CMapDescRec_ + { + FTC_FaceID face_id; + FTC_CMapType type; + + union + { + FT_UInt index; + FT_Encoding encoding; + FTC_CMapIdRec id; + + } u; + + } FTC_CMapDescRec; + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FTC_CMapCache_New */ + /* */ + /* @description: */ + /* Creates a new charmap cache. */ + /* */ + /* @input: */ + /* manager :: A handle to the cache manager. */ + /* */ + /* @output: */ + /* acache :: A new cache handle. NULL in case of error. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* Like all other caches, this one will be destroyed with the cache */ + /* manager. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FTC_CMapCache_Lookup */ + /* */ + /* @description: */ + /* Translates a character code into a glyph index, using the charmap */ + /* cache. */ + /* */ + /* @input: */ + /* cache :: A charmap cache handle. */ + /* */ + /* cmap_desc :: A charmap descriptor handle. */ + /* */ + /* char_code :: The character code (in the corresponding charmap). */ + /* */ + /* @return: */ + /* Glyph index. 0 means "no glyph". */ + /* */ + /* @note: */ + /* This function doesn't return @FTC_Node handles, since there is no */ + /* real use for them with typical uses of charmaps. */ + /* */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_CMapDesc cmap_desc, + FT_UInt32 char_code ); + + /* */ + + +FT_END_HEADER + + +#endif /* __FTCCMAP_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftcglyph.h b/lib/freetype/include/freetype/cache/ftcglyph.h new file mode 100644 index 0000000..3d14cf0 --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftcglyph.h @@ -0,0 +1,193 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.h */ +/* */ +/* FreeType abstract glyph cache (specification). */ +/* */ +/* Copyright 2000-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Important: The functions defined in this file are only used to */ + /* implement an abstract glyph cache class. You need to */ + /* provide additional logic to implement a complete cache. */ + /* For example, see `ftcimage.h' and `ftcimage.c' which */ + /* implement a FT_Glyph cache based on this code. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCGLYPH_H__ +#define __FTCGLYPH_H__ + + +#include +#include FT_CACHE_H +#include FT_CACHE_MANAGER_H + +#include + + +FT_BEGIN_HEADER + + + /* each glyph set is characterized by a "glyph set type" which must be */ + /* defined by sub-classes */ + typedef struct FTC_GlyphFamilyRec_* FTC_GlyphFamily; + + /* handle to a glyph cache node */ + typedef struct FTC_GlyphNodeRec_* FTC_GlyphNode; + + + /* size should be 24 + chunk size on 32-bit machines; */ + /* note that the node's hash is ((gfam->hash << 16) | glyph_index) -- */ + /* this _must_ be set properly by the glyph node initializer */ + /* */ + typedef struct FTC_GlyphNodeRec_ + { + FTC_NodeRec node; + FT_UShort item_count; + FT_UShort item_start; + + } FTC_GlyphNodeRec; + + +#define FTC_GLYPH_NODE( x ) ( (FTC_GlyphNode)(x) ) +#define FTC_GLYPH_NODE_P( x ) ( (FTC_GlyphNode*)(x) ) + + + typedef struct FTC_GlyphQueryRec_ + { + FTC_QueryRec query; + FT_UInt gindex; + + } FTC_GlyphQueryRec, *FTC_GlyphQuery; + + +#define FTC_GLYPH_QUERY( x ) ( (FTC_GlyphQuery)(x) ) + + + /* a glyph set is used to categorize glyphs of a given type */ + typedef struct FTC_GlyphFamilyRec_ + { + FTC_FamilyRec family; + FT_UInt32 hash; + FT_UInt item_total; /* total number of glyphs in family */ + FT_UInt item_count; /* number of glyph items per node */ + + } FTC_GlyphFamilyRec; + + +#define FTC_GLYPH_FAMILY( x ) ( (FTC_GlyphFamily)(x) ) +#define FTC_GLYPH_FAMILY_P( x ) ( (FTC_GlyphFamily*)(x) ) + +#define FTC_GLYPH_FAMILY_MEMORY( x ) FTC_FAMILY(x)->cache->memory + + + /* each glyph node contains a 'chunk' of glyph items; */ + /* translate a glyph index into a chunk index */ +#define FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) \ + ( ( gindex ) / FTC_GLYPH_FAMILY( gfam )->item_count ) + + /* find a glyph index's chunk, and return its start index */ +#define FTC_GLYPH_FAMILY_START( gfam, gindex ) \ + ( FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) * \ + FTC_GLYPH_FAMILY( gfam )->item_count ) + + /* compute a glyph request's hash value */ +#define FTC_GLYPH_FAMILY_HASH( gfam, gindex ) \ + ( (FT_UFast)( \ + ( FTC_GLYPH_FAMILY( gfam )->hash << 16 ) | \ + ( FTC_GLYPH_FAMILY_CHUNK( gfam, gindex ) & 0xFFFF ) ) ) + + /* must be called in an FTC_Family_CompareFunc to update the query */ + /* whenever a glyph set is matched in the lookup, or when it */ + /* is created */ +#define FTC_GLYPH_FAMILY_FOUND( gfam, gquery ) \ + do \ + { \ + FTC_QUERY( gquery )->family = FTC_FAMILY( gfam ); \ + FTC_QUERY( gquery )->hash = \ + FTC_GLYPH_FAMILY_HASH( gfam, \ + FTC_GLYPH_QUERY( gquery )->gindex ); \ + } while ( 0 ) + + /* retrieve glyph index of glyph node */ +#define FTC_GLYPH_NODE_GINDEX( x ) \ + ( (FT_UInt)( FTC_GLYPH_NODE( x )->node.hash & 0xFFFF ) ) + + + /*************************************************************************/ + /* */ + /* These functions are exported so that they can be called from */ + /* user-provided cache classes; otherwise, they are really part of the */ + /* cache sub-system internals. */ + /* */ + + /* must be called by derived FTC_Node_InitFunc routines */ + FT_EXPORT( void ) + ftc_glyph_node_init( FTC_GlyphNode node, + FT_UInt gindex, /* glyph index for node */ + FTC_GlyphFamily gfam ); + + /* returns TRUE iff the query's glyph index correspond to the node; */ + /* this assumes that the "family" and "hash" fields of the query are */ + /* already correctly set */ + FT_EXPORT( FT_Bool ) + ftc_glyph_node_compare( FTC_GlyphNode gnode, + FTC_GlyphQuery gquery ); + + /* must be called by derived FTC_Node_DoneFunc routines */ + FT_EXPORT( void ) + ftc_glyph_node_done( FTC_GlyphNode node, + FTC_Cache cache ); + + + /* must be called by derived FTC_Family_InitFunc; */ + /* calls "ftc_family_init" */ + FT_EXPORT( FT_Error ) + ftc_glyph_family_init( FTC_GlyphFamily gfam, + FT_UInt32 hash, + FT_UInt item_count, + FT_UInt item_total, + FTC_GlyphQuery gquery, + FTC_Cache cache ); + + FT_EXPORT( void ) + ftc_glyph_family_done( FTC_GlyphFamily gfam ); + + + /* */ + +FT_END_HEADER + + +#endif /* __FTCGLYPH_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftcimage.h b/lib/freetype/include/freetype/cache/ftcimage.h new file mode 100644 index 0000000..382d991 --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftcimage.h @@ -0,0 +1,312 @@ +/***************************************************************************/ +/* */ +/* ftcimage.h */ +/* */ +/* FreeType Image cache (specification). */ +/* */ +/* Copyright 2000-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Each image cache really manages FT_Glyph objects. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCIMAGE_H__ +#define __FTCIMAGE_H__ + + +#include +#include FT_CACHE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************** + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A simple structure used to describe the type of glyph image to be + * loaded into the cache. + * + * @fields: + * font :: An @FTC_FontRec used to describe the glyph's face and size. + * + * flags :: The load flags to be applied when loading the glyph; see + * the @FT_LOAD_XXX constants for details. + * + * @note: + * This type completely replaces the @FTC_Image_Desc structure which is + * now obsolete. + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FontRec font; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + /* */ + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \ + (d1)->flags == (d2)->flags ) + +#define FTC_IMAGE_TYPE_HASH( d ) \ + (FT_UFast)( FTC_FONT_HASH( &(d)->font ) ^ \ + ( (d)->flags << 4 ) ) + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache */ + /* */ + /* */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_New */ + /* */ + /* */ + /* Creates a new glyph image cache. */ + /* */ + /* */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ImageCache_Lookup */ + /* */ + /* */ + /* Retrieves a given glyph image from a glyph image cache. */ + /* */ + /* */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* */ + /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If "anode" is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* "release" it. */ + /* */ + /* If "anode" is NULL, the cache node is left unchanged, which means */ + /* that the FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + /* */ + +#define ftc_image_format( x ) ( (x) & 7 ) + + +#define ftc_image_format_bitmap 0x0000 +#define ftc_image_format_outline 0x0001 + +#define ftc_image_format_mask 0x000F + +#define ftc_image_flag_monochrome 0x0010 +#define ftc_image_flag_unhinted 0x0020 +#define ftc_image_flag_autohinted 0x0040 +#define ftc_image_flag_unscaled 0x0080 +#define ftc_image_flag_no_sbits 0x0100 + + /* monochrome bitmap */ +#define ftc_image_mono ftc_image_format_bitmap | \ + ftc_image_flag_monochrome + + /* anti-aliased bitmap */ +#define ftc_image_grays ftc_image_format_bitmap + + /* scaled outline */ +#define ftc_image_outline ftc_image_format_outline + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Desc */ + /* */ + /* */ + /* THIS TYPE IS DEPRECATED. Use @FTC_ImageDesc instead. */ + /* */ + /* A simple structure used to describe a given glyph image category. */ + /* */ + /* */ + /* size :: An @FTC_SizeRec used to describe the glyph's face */ + /* and size. */ + /* */ + /* image_type :: The glyph image's type. */ + /* */ + typedef struct FTC_Image_Desc_ + { + FTC_FontRec font; + FT_UInt image_type; + + } FTC_Image_Desc; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache */ + /* */ + /* */ + /* THIS TYPE IS DEPRECATED. Use @FTC_ImageCache instead. */ + /* */ + typedef FTC_ImageCache FTC_Image_Cache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_New */ + /* */ + /* */ + /* THIS FUNCTION IS DEPRECATED. Use @FTC_ImageCache_New instead. */ + /* */ + /* Creates a new glyph image cache. */ + /* */ + /* */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Image_Cache_Lookup */ + /* */ + /* */ + /* THIS FUNCTION IS DEPRECATED. Use @FTC_ImageCache_Lookup instead. */ + /* */ + /* */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* desc :: A pointer to a glyph image descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* */ + /* aglyph :: The corresponding @FT_Glyph object. 0 in case of */ + /* failure. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* Because the glyph image cache limits the total amount of memory */ + /* taken by the glyphs it holds, the returned glyph might disappear */ + /* on a later invocation of this function! It is a cache after */ + /* all... */ + /* */ + /* Use this function to "lock" the glyph as long as it is needed. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Image_Cache_Lookup( FTC_Image_Cache cache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FT_Glyph *aglyph ); + + /* */ + +FT_END_HEADER + + +#endif /* __FTCIMAGE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftcmanag.h b/lib/freetype/include/freetype/cache/ftcmanag.h new file mode 100644 index 0000000..97c7759 --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftcmanag.h @@ -0,0 +1,244 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.h */ +/* */ +/* FreeType Cache Manager (specification). */ +/* */ +/* Copyright 2000-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A cache manager is in charge of the following: */ + /* */ + /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ + /* objects. The mapping itself is performed through a user-provided */ + /* callback. However, the manager maintains a small cache of FT_Face */ + /* and FT_Size objects in order to speed up things considerably. */ + /* */ + /* - Manage one or more cache objects. Each cache is in charge of */ + /* holding a varying number of `cache nodes'. Each cache node */ + /* represents a minimal amount of individually accessible cached */ + /* data. For example, a cache node can be an FT_Glyph image */ + /* containing a vector outline, or some glyph metrics, or anything */ + /* else. */ + /* */ + /* Each cache node has a certain size in bytes that is added to the */ + /* total amount of `cache memory' within the manager. */ + /* */ + /* All cache nodes are located in a global LRU list, where the oldest */ + /* node is at the tail of the list. */ + /* */ + /* Each node belongs to a single cache, and includes a reference */ + /* count to avoid destroying it (due to caching). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCMANAG_H__ +#define __FTCMANAG_H__ + + +#include +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_LRU_H +#include FT_CACHE_INTERNAL_CACHE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + +#define FTC_MAX_FACES_DEFAULT 2 +#define FTC_MAX_SIZES_DEFAULT 4 +#define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */ + + /* maximum number of caches registered in a single manager */ +#define FTC_MAX_CACHES 16 + + + typedef struct FTC_FamilyEntryRec_ + { + FTC_Family family; + FTC_Cache cache; + FT_UInt index; + FT_UInt link; + + } FTC_FamilyEntryRec, *FTC_FamilyEntry; + + +#define FTC_FAMILY_ENTRY_NONE ( (FT_UInt)-1 ) + + + typedef struct FTC_FamilyTableRec_ + { + FT_UInt count; + FT_UInt size; + FTC_FamilyEntry entries; + FT_UInt free; + + } FTC_FamilyTableRec, *FTC_FamilyTable; + + + FT_EXPORT( FT_Error ) + ftc_family_table_alloc( FTC_FamilyTable table, + FT_Memory memory, + FTC_FamilyEntry *aentry ); + + FT_EXPORT( void ) + ftc_family_table_free( FTC_FamilyTable table, + FT_UInt idx ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_ManagerRec */ + /* */ + /* */ + /* The cache manager structure. */ + /* */ + /* */ + /* library :: A handle to a FreeType library instance. */ + /* */ + /* faces_list :: The lru list of @FT_Face objects in the cache. */ + /* */ + /* sizes_list :: The lru list of @FT_Size objects in the cache. */ + /* */ + /* max_weight :: The maximum cache pool weight. */ + /* */ + /* cur_weight :: The current cache pool weight. */ + /* */ + /* num_nodes :: The current number of nodes in the manager. */ + /* */ + /* nodes_list :: The global lru list of all cache nodes. */ + /* */ + /* caches :: A table of installed/registered cache objects. */ + /* */ + /* request_data :: User-provided data passed to the requester. */ + /* */ + /* request_face :: User-provided function used to implement a mapping */ + /* between abstract @FTC_FaceID values and real */ + /* @FT_Face objects. */ + /* */ + /* families :: Global table of families. */ + /* */ + typedef struct FTC_ManagerRec_ + { + FT_Library library; + FT_LruList faces_list; + FT_LruList sizes_list; + + FT_ULong max_weight; + FT_ULong cur_weight; + + FT_UInt num_nodes; + FTC_Node nodes_list; + + FTC_Cache caches[FTC_MAX_CACHES]; + + FT_Pointer request_data; + FTC_Face_Requester request_face; + + FTC_FamilyTableRec families; + + } FTC_ManagerRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Manager_Compress */ + /* */ + /* */ + /* This function is used to check the state of the cache manager if */ + /* its `num_bytes' field is greater than its `max_bytes' field. It */ + /* will flush as many old cache nodes as possible (ignoring cache */ + /* nodes with a non-zero reference count). */ + /* */ + /* */ + /* manager :: A handle to the cache manager. */ + /* */ + /* */ + /* Client applications should not call this function directly. It is */ + /* normally invoked by specific cache implementations. */ + /* */ + /* The reason this function is exported is to allow client-specific */ + /* cache classes. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Compress( FTC_Manager manager ); + + + /* this must be used internally for the moment */ + FT_EXPORT( FT_Error ) + FTC_Manager_Register_Cache( FTC_Manager manager, + FTC_Cache_Class clazz, + FTC_Cache *acache ); + + + /* can be called to increment a node's reference count */ + FT_EXPORT( void ) + FTC_Node_Ref( FTC_Node node, + FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_Node_Unref */ + /* */ + /* */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + /* */ + +FT_END_HEADER + + +#endif /* __FTCMANAG_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftcsbits.h b/lib/freetype/include/freetype/cache/ftcsbits.h new file mode 100644 index 0000000..6f8ef99 --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftcsbits.h @@ -0,0 +1,275 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.h */ +/* */ +/* A small-bitmap cache (specification). */ +/* */ +/* Copyright 2000-2001, 2002 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 __FTCSBITS_H__ +#define __FTCSBITS_H__ + + +#include +#include FT_CACHE_H +#include FT_CACHE_IMAGE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /*
*/ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit */ + /* */ + /* */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitRec */ + /* */ + /* */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* Y coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to 255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache */ + /* */ + /* */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit_Cache */ + /* */ + /* */ + /* DEPRECATED. Use @FTC_SBitCache instead. */ + /* */ + typedef FTC_SBitCache FTC_SBit_Cache; + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_New */ + /* */ + /* */ + /* Creates a new cache to store small glyph bitmaps. */ + /* */ + /* */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBitCache_Lookup */ + /* */ + /* */ + /* Looks up a given small glyph bitmap in a given sbit cache and */ + /* "lock" it to prevent its flushing from the cache until needed */ + /* */ + /* */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If "anode" is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to "release" it. */ + /* */ + /* If "anode" is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit_Cache_New */ + /* */ + /* */ + /* DEPRECATED. Use @FTC_SBitCache_New instead. */ + /* */ + /* Creates a new cache to store small glyph bitmaps. */ + /* */ + /* */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBit_Cache *acache ); + + + /*************************************************************************/ + /* */ + /* */ + /* FTC_SBit_Cache_Lookup */ + /* */ + /* */ + /* DEPRECATED. Use @FTC_SBitCache_Lookup instead. */ + /* */ + /* Looks up a given small glyph bitmap in a given sbit cache. */ + /* */ + /* */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* desc :: A pointer to the glyph image descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to 0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FTC_SBit *sbit ); + + +FT_END_HEADER + +#endif /* __FTCSBITS_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/cache/ftlru.h b/lib/freetype/include/freetype/cache/ftlru.h new file mode 100644 index 0000000..9e4507e --- /dev/null +++ b/lib/freetype/include/freetype/cache/ftlru.h @@ -0,0 +1,202 @@ +/***************************************************************************/ +/* */ +/* ftlru.h */ +/* */ +/* Simple LRU list-cache (specification). */ +/* */ +/* Copyright 2000-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* An LRU is a list that cannot hold more than a certain number of */ + /* elements (`max_elements'). All elements in the list are sorted in */ + /* least-recently-used order, i.e., the `oldest' element is at the tail */ + /* of the list. */ + /* */ + /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ + /* the list is searched for an element with the corresponding key. If */ + /* it is found, the element is moved to the head of the list and is */ + /* returned. */ + /* */ + /* If no corresponding element is found, the lookup routine will try to */ + /* obtain a new element with the relevant key. If the list is already */ + /* full, the oldest element from the list is discarded and replaced by a */ + /* new one; a new element is added to the list otherwise. */ + /* */ + /* Note that it is possible to pre-allocate the element list nodes. */ + /* This is handy if `max_elements' is sufficiently small, as it saves */ + /* allocations/releases during the lookup process. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTLRU_H__ +#define __FTLRU_H__ + + +#include +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* generic list key type */ + typedef FT_Pointer FT_LruKey; + + /* a list list handle */ + typedef struct FT_LruListRec_* FT_LruList; + + /* a list class handle */ + typedef const struct FT_LruList_ClassRec_* FT_LruList_Class; + + /* a list node handle */ + typedef struct FT_LruNodeRec_* FT_LruNode; + + /* the list node structure */ + typedef struct FT_LruNodeRec_ + { + FT_LruNode next; + FT_LruKey key; + + } FT_LruNodeRec; + + + /* the list structure */ + typedef struct FT_LruListRec_ + { + FT_Memory memory; + FT_LruList_Class clazz; + FT_LruNode nodes; + FT_UInt max_nodes; + FT_UInt num_nodes; + FT_Pointer data; + + } FT_LruListRec; + + + /* initialize a list list */ + typedef FT_Error + (*FT_LruList_InitFunc)( FT_LruList list ); + + /* finalize a list list */ + typedef void + (*FT_LruList_DoneFunc)( FT_LruList list ); + + /* this method is used to initialize a new list element node */ + typedef FT_Error + (*FT_LruNode_InitFunc)( FT_LruNode node, + FT_LruKey key, + FT_Pointer data ); + + /* this method is used to finalize a given list element node */ + typedef void + (*FT_LruNode_DoneFunc)( FT_LruNode node, + FT_Pointer data ); + + /* If defined, this method is called when the list if full */ + /* during the lookup process -- it is used to change the contents */ + /* of a list element node instead of calling `done_element()', */ + /* then `init_element()'. Set it to 0 for default behaviour. */ + typedef FT_Error + (*FT_LruNode_FlushFunc)( FT_LruNode node, + FT_LruKey new_key, + FT_Pointer data ); + + /* If defined, this method is used to compare a list element node */ + /* with a given key during a lookup. If set to 0, the `key' */ + /* fields will be directly compared instead. */ + typedef FT_Bool + (*FT_LruNode_CompareFunc)( FT_LruNode node, + FT_LruKey key, + FT_Pointer data ); + + /* A selector is used to indicate whether a given list element node */ + /* is part of a selection for FT_LruList_Remove_Selection(). The */ + /* functrion must return true (i.e., non-null) to indicate that the */ + /* node is part of it. */ + typedef FT_Bool + (*FT_LruNode_SelectFunc)( FT_LruNode node, + FT_Pointer data, + FT_Pointer list_data ); + + /* LRU class */ + typedef struct FT_LruList_ClassRec_ + { + FT_UInt list_size; + FT_LruList_InitFunc list_init; /* optional */ + FT_LruList_DoneFunc list_done; /* optional */ + + FT_UInt node_size; + FT_LruNode_InitFunc node_init; /* MANDATORY */ + FT_LruNode_DoneFunc node_done; /* optional */ + FT_LruNode_FlushFunc node_flush; /* optional */ + FT_LruNode_CompareFunc node_compare; /* optional */ + + } FT_LruList_ClassRec; + + + /* The following functions must be exported in the case where */ + /* applications would want to write their own cache classes. */ + + FT_EXPORT( FT_Error ) + FT_LruList_New( FT_LruList_Class clazz, + FT_UInt max_elements, + FT_Pointer user_data, + FT_Memory memory, + FT_LruList *alist ); + + FT_EXPORT( void ) + FT_LruList_Reset( FT_LruList list ); + + FT_EXPORT( void ) + FT_LruList_Destroy ( FT_LruList list ); + + FT_EXPORT( FT_Error ) + FT_LruList_Lookup( FT_LruList list, + FT_LruKey key, + FT_LruNode *anode ); + + FT_EXPORT( void ) + FT_LruList_Remove( FT_LruList list, + FT_LruNode node ); + + FT_EXPORT( void ) + FT_LruList_Remove_Selection( FT_LruList list, + FT_LruNode_SelectFunc select_func, + FT_Pointer select_data ); + + /* */ + +FT_END_HEADER + + +#endif /* __FTLRU_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/config/ftconfig.h b/lib/freetype/include/freetype/config/ftconfig.h new file mode 100644 index 0000000..72bee0c --- /dev/null +++ b/lib/freetype/include/freetype/config/ftconfig.h @@ -0,0 +1,334 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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 header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /* This ANSI version should stay in `include/freetype/config'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* The number of bytes in an `int' type. */ +#if FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT 4 +#elif FT_UINT_MAX == 0xFFFFU +#define FT_SIZEOF_INT 2 +#elif FT_UINT_MAX > 0xFFFFFFFFU && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_INT 8 +#else +#error "Unsupported number of bytes in `int' type!" +#endif + + /* The number of bytes in a `long' type. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG 4 +#elif FT_ULONG_MAX > 0xFFFFFFFFU && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFU +#define FT_SIZEOF_LONG 8 +#else +#error "Unsupported number of bytes in `long' type!" +#endif + + + /* Preferred alignment of data */ +#define FT_ALIGNMENT 8 + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) +#define FT_MACINTOSH 1 +#endif + + + /*************************************************************************/ + /* */ + /* IntN types */ + /* */ + /* Used to guarantee the size of some specific integers. */ + /* */ + typedef signed short FT_Int16; + typedef unsigned short FT_UInt16; + +#if FT_SIZEOF_INT == 4 + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == 4 + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + /* now, lookup for an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= 4 + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= 4 + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == 8 + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWKS__ ) /* Metrowerks CodeWarrior */ + + /* I don't know if it provides 64-bit data types, any suggestion */ + /* is welcome. */ + +#elif defined( __GNUC__ ) + + /* GCC provides the "long long" type */ +#define FT_LONG64 +#define FT_INT64 long long int + +#endif /* FT_SIZEOF_LONG == 8 */ + + + /*************************************************************************/ + /* */ + /* A 64-bit data type will create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable their use if */ + /* __STDC__ is defined. You can however ignore this rule by */ + /* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#ifdef __STDC__ + + /* undefine the 64-bit macros in strict ANSI compilation mode */ +#undef FT_LONG64 +#undef FT_INT64 + +#endif /* __STDC__ */ + +#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) extern "C" x +#else +#define FT_BASE_DEF( x ) extern x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/config/ftheader.h b/lib/freetype/include/freetype/config/ftheader.h new file mode 100644 index 0000000..e5ae7e4 --- /dev/null +++ b/lib/freetype/include/freetype/config/ftheader.h @@ -0,0 +1,535 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2001, 2002 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 __FT_HEADER_H__ +#define __FT_HEADER_H__ + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_BEGIN_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_END_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /*
*/ + /* header_file_macros */ + /* */ + /* */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType 2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3 naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that is allows for more flexibility in the */ + /* way FreeType 2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + /* configuration files */ + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_CONFIG_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 configuration data. */ + /* */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_STANDARD_LIBRARY_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 configuration data. */ + /* */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_OPTIONS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 project-specific configuration options. */ + /* */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_MODULES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 modules that are statically linked to new */ + /* library instances in @FT_Init_FreeType. */ + /* */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> +#endif + + /* public headers */ + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_FREETYPE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the base FreeType 2 API. */ + /* */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ERRORS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 error codes (and messages). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MODULE_ERRORS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 module error offsets (and messages). */ + /* */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SYSTEM_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the FreeType 2 interface to low-level operations (i.e. memory */ + /* management and stream i/o). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IMAGE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* types definitions related to glyph images (i.e. bitmaps, outlines, */ + /* scan-converter parameters). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TYPES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the basic data types defined by FreeType 2. */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_TYPES_H <freetype/fttypes.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_LIST_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list management API of FreeType 2. */ + /* */ + /* (Most applications will never need to include this file.) */ + /* */ +#define FT_LIST_H <freetype/ftlist.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_OUTLINE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the scalable outline management API of FreeType 2. */ + /* */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SIZES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API used to manage multiple @FT_Size objects per face. */ + /* */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MODULE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the module management API of FreeType 2. */ + /* */ +#define FT_MODULE_H <freetype/ftmodule.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_RENDER_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the renderer module management API of FreeType 2. */ + /* */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TYPE1_TABLES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the types and API specific to the Type 1 format. */ + /* */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_IDS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the enumeration values used to identify name strings, languages, */ + /* encodings, etc. This file really contains a _large_ set of */ + /* constant macro definitions, taken from the TrueType and OpenType */ + /* specifications. */ + /* */ +#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_TABLES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the types and API specific to the TrueType (as well as OpenType) */ + /* format. */ + /* */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_TAGS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of TrueType 4-byte `tags' used to identify blocks */ + /* in SFNT-based font formats (i.e. TrueType and OpenType). */ + /* */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_BDF_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to access BDF-specific strings from a */ + /* face. */ + /* */ +#define FT_BDF_H <freetype/ftbdf.h> + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_GZIP_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support for gzip-compressed files. */ + /* */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_WINFONTS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support Windows .FNT files */ + /* */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_GLYPH_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional glyph management component. */ + /* */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_BBOX_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional exact bounding box computation routines. */ + /* */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional FreeType 2 cache sub-system. */ + /* */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_IMAGE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `glyph image' API of the FreeType 2 cache sub-system. */ + /* */ + /* It is used to define a cache for @FT_Glyph elements. You can also */ + /* see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need */ + /* to store small glyph bitmaps, as it will use less memory. */ + /* */ +#define FT_CACHE_IMAGE_H <freetype/cache/ftcimage.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_SMALL_BITMAPS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `small bitmaps' API of the FreeType 2 cache sub-system. */ + /* */ + /* It is used to define a cache for small glyph bitmaps in a */ + /* relatively memory-efficient way. You can also use the API defined */ + /* in @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, */ + /* including scalable outlines. */ + /* */ +#define FT_CACHE_SMALL_BITMAPS_H <freetype/cache/ftcsbits.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_CHARMAP_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `charmap' API of the FreeType 2 cache sub-system. */ + /* */ +#define FT_CACHE_CHARMAP_H <freetype/cache/ftccmap.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MAC_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the Macintosh-specific FreeType 2 API. The latter is used to */ + /* access fonts embedded in resource forks. */ + /* */ + /* This header file must be explicitly included by client */ + /* applications compiled on the Mac (note that the base API still */ + /* works though). */ + /* */ +#define FT_MAC_H <freetype/ftmac.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MULTIPLE_MASTERS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the optional multiple-masters management API of FreeType 2. */ + /* */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SFNT_NAMES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the optional FreeType 2 API used to access embedded `name' strings */ + /* in SFNT-based font formats (i.e. TrueType and OpenType). */ + /* */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + /* */ + +#define FT_TRIGONOMETRY_H <freetype/fttrigon.h> +#define FT_STROKER_H <freetype/ftstroker.h> +#define FT_SYNTHESIS_H <freetype/ftsynth.h> +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + +#define FT_CACHE_MANAGER_H <freetype/cache/ftcmanag.h> + +#define FT_CACHE_INTERNAL_LRU_H <freetype/cache/ftlru.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/cache/ftcglyph.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/cache/ftccache.h> + +#define FT_XFREE86_H <freetype/ftxf86.h> + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + + /* now include internal headers definitions from <freetype/internal/...> */ + +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/config/ftmodule.h b/lib/freetype/include/freetype/config/ftmodule.h new file mode 100644 index 0000000..d0e6f16 --- /dev/null +++ b/lib/freetype/include/freetype/config/ftmodule.h @@ -0,0 +1,19 @@ +FT_USE_MODULE(autohint_module_class) +FT_USE_MODULE(cff_driver_class) +FT_USE_MODULE(t1cid_driver_class) +FT_USE_MODULE(pcf_driver_class) +FT_USE_MODULE(bdf_driver_class) +FT_USE_MODULE(psaux_module_class) +FT_USE_MODULE(psnames_module_class) +FT_USE_MODULE(pshinter_module_class) +FT_USE_MODULE(ft_raster1_renderer_class) +FT_USE_MODULE(sfnt_module_class) +FT_USE_MODULE(ft_smooth_renderer_class) +FT_USE_MODULE(ft_smooth_lcd_renderer_class) +FT_USE_MODULE(ft_smooth_lcdv_renderer_class) +FT_USE_MODULE(tt_driver_class) +FT_USE_MODULE(t1_driver_class) +FT_USE_MODULE(t42_driver_class) +FT_USE_MODULE(pfr_driver_class) +FT_USE_MODULE(winfnt_driver_class) + diff --git a/lib/freetype/include/freetype/config/ftoption.h b/lib/freetype/include/freetype/config/ftoption.h new file mode 100644 index 0000000..4e3457f --- /dev/null +++ b/lib/freetype/include/freetype/config/ftoption.h @@ -0,0 +1,497 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in "$BUILD/freetype/config/ftoption.h", where "$BUILD" */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory "builds/<system>" by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to "$BUILD/ft2build.h" and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use "$BUILD/myftoptions.h" instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit ints is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining here the macro FT_CONFIG_OPTION_FORCE_INT64. */ + /* */ + /* For most compilers, this will only create compilation warnings */ + /* when building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file "ftconfig.h" either statically, or through Autoconf */ + /* on platforms that support it. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses 'zlib' to */ + /* partially uncompress the file on the fly (see src/base/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this "feature". Note that */ + /* this will however force you to link the zlib to any program that */ + /* also uses FreeType. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's "ftgzip" component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* do not #undef this macro here, since the build system might */ + /* define for certain configurations */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This allows FreeType to be used with the PostScript language, using */ + /* the GhostScript interpreter. */ + /* */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4kByte. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable "FT_DEBUG_MEMORY" is also defined! */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. Note that there are */ + /* important patent issues related to the use of the interpreter. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* do not #undef this macro here, since the build system might */ + /* define for certain configurations */ + /* */ +/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scale */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* */ + +/* + * the FT_CONFIG_OPTION_CHESTER_XXXX macros are used to toggle some recent + * improvements to the auto-hinter contributed by David Chester. They will + * most likely disappear completely in the next release. For now, you should + * always keep them defined + * + */ +#define FT_CONFIG_OPTION_CHESTER_HINTS + +#ifdef FT_CONFIG_OPTION_CHESTER_HINTS + +# define FT_CONFIG_CHESTER_SMALL_F +# define FT_CONFIG_CHESTER_ASCENDER +# define FT_CONFIG_CHESTER_SERIF +# define FT_CONFIG_CHESTER_STEM +# define FT_CONFIG_CHESTER_BLUE_SCALE + +#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */ + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/config/ftstdlib.h b/lib/freetype/include/freetype/config/ftstdlib.h new file mode 100644 index 0000000..6c06091 --- /dev/null +++ b/lib/freetype/include/freetype/config/ftstdlib.h @@ -0,0 +1,140 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002 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 group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines __FTSTDLIB_H__ before this one to override */ + /* it. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, "ftconfig.h" will refuse to compile anyway with a */ + /* message like "couldn't find 32-bit type" or something similar. */ + /* */ + /* IMPORTANT NOTE: We do not define aliases for heap management and */ + /* i/o routines (i.e. malloc/free/fopen/fread/...) */ + /* since these functions should all be encapsulated */ + /* by platform-specific implementations of */ + /* "ftsystem.c". */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <ctype.h> + +#define ft_isalnum isalnum +#define ft_isupper isupper +#define ft_islower islower +#define ft_xdigit isxdigit + + +#include <string.h> + +#define ft_strlen strlen +#define ft_strcmp strcmp +#define ft_strncmp strncmp +#define ft_memcpy memcpy +#define ft_strcpy strcpy +#define ft_strncpy strncpy +#define ft_memset memset +#define ft_memmove memmove +#define ft_memcmp memcmp + +#include <stdio.h> + +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort +#define ft_exit exit /* only used to exit from unhandled exceptions */ + +#define ft_atoi atoi + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_setjmp setjmp /* same thing here */ +#define ft_longjmp longjmp /* " */ + + + /* the following is only used for debugging purposes, i.e. when */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + /* */ +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/freetype.h b/lib/freetype/include/freetype/freetype.h new file mode 100644 index 0000000..4d6c5a2 --- /dev/null +++ b/lib/freetype/include/freetype/freetype.h @@ -0,0 +1,2866 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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__ +#define __FREETYPE_H__ + + + /*************************************************************************/ + /* */ + /* The `raster' component duplicates some of the declarations in */ + /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ + /* */ + + + /*************************************************************************/ + /* */ + /* The FREETYPE_MAJOR and FREETYPE_MINOR macros are used to version the */ + /* new FreeType design, which is able to host several kinds of font */ + /* drivers. It starts at 2.0. */ + /* */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 1 +#define FREETYPE_PATCH 4 + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType 2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the public high-level API of FreeType 2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_FAST_GLYPHS */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* FT_Library_Version */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Open_Flags */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_CROP_BITMAP */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. Note */ + /* that values are expressed in 26.6 fractional pixel format or in */ + /* font units, depending on context. */ + /* */ + /* <Fields> */ + /* width :: The glyph's width. */ + /* */ + /* height :: The glyph's height. */ + /* */ + /* horiBearingX :: Horizontal left side bearing. */ + /* */ + /* horiBearingY :: Horizontal top side bearing. */ + /* */ + /* horiAdvance :: Horizontal advance width. */ + /* */ + /* vertBearingX :: Vertical left side bearing. */ + /* */ + /* vertBearingY :: Vertical top side bearing. */ + /* */ + /* vertAdvance :: Vertical advance height. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; /* glyph width */ + FT_Pos height; /* glyph height */ + + FT_Pos horiBearingX; /* left side bearing in horizontal layouts */ + FT_Pos horiBearingY; /* top side bearing in horizontal layouts */ + FT_Pos horiAdvance; /* advance width for horizontal layout */ + + FT_Pos vertBearingX; /* left side bearing in vertical layouts */ + FT_Pos vertBearingY; /* top side bearing in vertical layouts */ + FT_Pos vertAdvance; /* advance height for vertical layout */ + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* An extremely simple structure used to model the size of a bitmap */ + /* strike (i.e., a bitmap instance of the font for a given */ + /* resolution) in a fixed-size font face. This is used for the */ + /* `available_sizes' field of the FT_Face_Properties structure. */ + /* */ + /* <Fields> */ + /* height :: The character height in pixels. */ + /* */ + /* width :: The character width in pixels. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* <Also> */ + /* The @FT_FaceRec details the publicly accessible fields of a given */ + /* face object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to a given size object. Such an object models the data */ + /* that depends on the current _resolution_ and _character size_ in a */ + /* given @FT_Face. */ + /* */ + /* <Note> */ + /* Each face object owns one or more sizes. There is however a */ + /* single _active_ size for the face at any time that will be used by */ + /* functions like @FT_Load_Glyph, @FT_Get_Kerning, etc. */ + /* */ + /* You can use the @FT_Activate_Size API to change the current */ + /* active size of any given face. */ + /* */ + /* <Also> */ + /* The @FT_SizeRec structure details the publicly accessible fields */ + /* of a given face object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any one of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e. the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* @FT_GlyphSlotRec details the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be "active" and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* "face->num_charmaps" and "face->charmaps" fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as "face->charmap". */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four letter tags into an unsigned long. It is */ + /* used to define "encoding" identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* #define FT_ENC_TAG( value, a, b, c, d ) (value) */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify encodings supported by charmaps. */ + /* Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ + /* all character codes must be expressed as FT_Longs. */ + /* */ + /* The values of this type correspond to specific character */ + /* repertories (i.e. charsets), and not to text encoding methods */ + /* (like UTF-8, UTF-16, GB2312_EUC, etc.). */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value 0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Corresponds to Microsoft's Japanese SJIS encoding. More info */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Corresponds to the encoding system for Simplified Chinese, as */ + /* used in China. Only found in some TrueType fonts. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Corresponds to the encoding system for Traditional Chinese, as */ + /* used in Taiwan and Hong Kong. Only found in some TrueType fonts. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* This is a Microsoft encoding that is only found in some TrueType */ + /* fonts. For more information, see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* The Korean standard character set (KS C-5601-1992), which */ + /* corresponds to Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* Only found on some rare TrueType fonts. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type 1 */ + /* Postscript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type 1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type 1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type 1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType and */ + /* OpenType fonts contain a charmap for this encoding, since older */ + /* versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthetizes a Unicode charmap */ + /* for Postscript fonts, using their glyph names dictionaries. */ + /* However, it will also report the encodings defined explicitly in */ + /* the font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_MS_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_MS_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_MS_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_MS_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_MS_JOHAB, 'j', 'o', 'h', 'a' ), + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_encoding_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated; use the corresponding @FT_Encoding */ + /* values instead. */ + /* */ + /* <Values> */ + /* ft_encoding_none :: see @FT_ENCODING_NONE */ + /* ft_encoding_unicode :: see @FT_ENCODING_UNICODE */ + /* ft_encoding_latin_2 :: see @FT_ENCODING_OLD_LATIN_2 */ + /* ft_encoding_symbol :: see @FT_ENCODING_MS_SYMBOL */ + /* ft_encoding_sjis :: see @FT_ENCODING_MS_SJIS */ + /* ft_encoding_gb2312 :: see @FT_ENCODING_MS_GB2312 */ + /* ft_encoding_big5 :: see @FT_ENCODING_MS_BIG5 */ + /* ft_encoding_wansung :: see @FT_ENCODING_MS_WANSUNG */ + /* ft_encoding_johab :: see @FT_ENCODING_MS_JOHAB */ + /* */ + /* ft_encoding_adobe_standard :: see @FT_ENCODING_ADOBE_STANDARD */ + /* ft_encoding_adobe_expert :: see @FT_ENCODING_ADOBE_EXPERT */ + /* ft_encoding_adobe_custom :: see @FT_ENCODING_ADOBE_CUSTOM */ + /* ft_encoding_latin_1 :: see @FT_ENCODING_ADOBE_LATIN_1 */ + /* */ + /* ft_encoding_apple_roman :: see @FT_ENCODING_APPLE_ROMAN */ + /* */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_MS_SJIS +#define ft_encoding_gb2312 FT_ENCODING_MS_GB2312 +#define ft_encoding_big5 FT_ENCODING_MS_BIG5 +#define ft_encoding_wansung FT_ENCODING_MS_WANSUNG +#define ft_encoding_johab FT_ENCODING_MS_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an FT_Face_InternalRec structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType 2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models the */ + /* resolution and point-size independent data found in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: In the case where the face is located in a */ + /* collection (i.e., a file which embeds */ + /* several faces), this is the total number of */ + /* faces found in the resource. 1 by default. */ + /* */ + /* face_index :: The index of the face in its font file. */ + /* Usually, this is 0 for all normal font */ + /* formats. It can be more in the case of */ + /* collections (which embed several fonts in a */ + /* single resource/file). */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see the */ + /* @FT_FACE_FLAG_XXX constants for details. */ + /* */ + /* style_flags :: A set of bit flags indicating the style of */ + /* the face (i.e., italic, bold, underline, */ + /* etc). See the @FT_STYLE_FLAG_XXX */ + /* constants. */ + /* */ + /* num_glyphs :: The total number of glyphs in the face. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized/Unicode versions of this string. */ + /* Applications should use the format specific */ + /* interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of fixed sizes available in this */ + /* face. This should be set to 0 for scalable */ + /* fonts, unless its face includes a complete */ + /* set of glyphs (called a `strike') for the */ + /* specified sizes. */ + /* */ + /* available_sizes :: An array of sizes specifying the available */ + /* bitmap/graymap sizes that are contained in */ + /* in the font face. Should be set to NULL if */ + /* the field `num_fixed_sizes' is set to 0. */ + /* */ + /* num_charmaps :: The total number of character maps in the */ + /* face. */ + /* */ + /* charmaps :: A table of pointers to the face's charmaps. */ + /* Used to scan the list of available charmaps */ + /* -- this table might change after a call to */ + /* @FT_Attach_File or @FT_Attach_Stream (e.g. */ + /* if used to hook an additional encoding or */ + /* CMap to the face object). */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see units_per_EM). */ + /* The box is large enough to contain any */ + /* glyph from the font. Thus, bbox.yMax can */ + /* be seen as the `maximal ascender', */ + /* bbox.yMin as the `minimal descender', and */ + /* the maximal glyph width is given by */ + /* `bbox.xMax-bbox.xMin' (not to be confused */ + /* with the maximal _advance_width_). Only */ + /* relevant for scalable formats. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, 1000 for Type1 fonts, and */ + /* should be set to the (unrealistic) value 1 */ + /* for fixed-sizes fonts. Only relevant for */ + /* scalable formats. */ + /* */ + /* ascender :: The face's ascender is the vertical */ + /* distance from the baseline to the topmost */ + /* point of any glyph in the face. This */ + /* field's value is positive, expressed in */ + /* font units. Some font designs use a value */ + /* different from `bbox.yMax'. Only relevant */ + /* for scalable formats. */ + /* */ + /* descender :: The face's descender is the vertical */ + /* distance from the baseline to the */ + /* bottommost point of any glyph in the face. */ + /* This field's value is *negative*, expressed */ + /* in font units. Some font designs use a */ + /* value different from `bbox.yMin'. Only */ + /* relevant for scalable formats. */ + /* */ + /* height :: The face's height is the vertical distance */ + /* from one baseline to the next when writing */ + /* several lines of text. Its value is always */ + /* positive, expressed in font units. The */ + /* value can be computed as */ + /* `ascender+descender+line_gap' where the */ + /* value of `line_gap' is also called */ + /* `external leading'. Only relevant for */ + /* scalable formats. */ + /* */ + /* max_advance_width :: The maximal advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximal advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and should */ + /* be set to the `height' for fonts that do */ + /* not provide vertical metrics. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It's the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). This */ + /* object is created automatically with a new */ + /* face object. However, certain kinds of */ + /* applications (mainly tools like converters) */ + /* can need more than one slot to ease their */ + /* task. */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# the following are only relevant to scalable outlines */ + FT_BBox bbox; + + FT_UShort units_per_EM; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; + void* extensions; + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the 'face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face provides vectorial outlines. This */ + /* doesn't prevent embedded bitmaps, i.e., a face can have both */ + /* this bit and @FT_FACE_FLAG_FIXED_SIZES set */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains `fixed sizes', i.e., bitmap */ + /* strikes for some given pixel sizes. See the `num_fixed_sizes' */ + /* and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Note that if unset, this function will always */ + /* return the vector (0,0). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Names. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Name when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) + + /* */ + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_HORIZONTAL( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains */ + /* horizontal metrics (this is true for all font formats though). */ + /* */ + /* @also: */ + /* @FT_HAS_VERTICAL can be used to check for vertical metrics. */ + /* */ +#define FT_HAS_HORIZONTAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_VERTICAL( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains vertical */ + /* metrics. */ + /* */ +#define FT_HAS_VERTICAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_KERNING( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains kerning */ + /* data that can be accessed with @FT_Get_Kerning. */ + /* */ +#define FT_HAS_KERNING( face ) \ + ( face->face_flags & FT_FACE_FLAG_KERNING ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IS_SCALABLE( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains a */ + /* scalable font face (true for TrueType, Type 1, CID, and */ + /* OpenType/CFF font formats. */ + /* */ +#define FT_IS_SCALABLE( face ) \ + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IS_SFNT( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains a font */ + /* whose format is based on the SFNT storage scheme. This usually */ + /* means: TrueType fonts, OpenType fonts, as well as SFNT-based */ + /* embedded bitmap fonts. */ + /* */ + /* If this macro is true, all functions defined in @FT_SFNT_NAMES_H */ + /* and @FT_TRUETYPE_TABLES_H are available. */ + /* */ +#define FT_IS_SFNT( face ) \ + ( face->face_flags & FT_FACE_FLAG_SFNT ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IS_FIXED_WIDTH( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains a font */ + /* face that contains fixed-width (or "monospace", "fixed-pitch", */ + /* etc.) glyphs. */ + /* */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IS_FIXED_SIZES( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains some */ + /* embedded bitmaps. See the `fixed_sizes' field of the @FT_FaceRec */ + /* structure. */ + /* */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + + /* */ + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_FAST_GLYPHS( face ) */ + /* */ + /* @description: */ + /* Deprecated; indicates that the face contains so-called "fast" */ + /* glyph bitmaps. */ + /* */ +#define FT_HAS_FAST_GLYPHS( face ) \ + ( face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_GLYPH_NAMES( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains some */ + /* glyph names that can be accessed through @FT_Get_Glyph_Names. */ + /* */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_HAS_MULTIPLE_MASTERS( face ) */ + /* */ + /* @description: */ + /* A macro that returns true whenever a face object contains some */ + /* multiple masters. The functions provided by */ + /* @FT_MULTIPLE_MASTERS_H are then available to choose the exact */ + /* design you want. */ + /* */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /*************************************************************************/ + /* */ + /* <Constant> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit-flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face is italicized. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an FT_Size_InternalRec structure, used to */ + /* model private data of a given FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure returned scaled important distances for */ + /* a given size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The character width, expressed in integer pixels. */ + /* This is the width of the EM square expressed in */ + /* pixels, hence the term `ppem' (pixels per EM). */ + /* */ + /* y_ppem :: The character height, expressed in integer pixels. */ + /* This is the height of the EM square expressed in */ + /* pixels, hence the term `ppem' (pixels per EM). */ + /* */ + /* x_scale :: A simple 16.16 fixed point format coefficient used */ + /* to scale horizontal distances expressed in font */ + /* units to fractional (26.6) pixel coordinates. */ + /* */ + /* y_scale :: A simple 16.16 fixed point format coefficient used */ + /* to scale vertical distances expressed in font */ + /* units to fractional (26.6) pixel coordinates. */ + /* */ + /* ascender :: The ascender, expressed in 26.6 fixed point */ + /* pixels. Always positive. */ + /* */ + /* descender :: The descender, expressed in 26.6 fixed point */ + /* pixels. Always negative. */ + /* */ + /* height :: The text height, expressed in 26.6 fixed point */ + /* pixels. Always positive. */ + /* */ + /* max_advance :: Maximum horizontal advance, expressed in 26.6 */ + /* fixed point pixels. Always positive. */ + /* */ + /* <Note> */ + /* The values of `ascender', `descender', and `height' are only the */ + /* scaled versions of `face->ascender', `face->descender', and */ + /* `face->height'. */ + /* */ + /* Unfortunately, due to glyph hinting, these values might not be */ + /* exact for certain fonts, they thus must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact pixel ascender and descender */ + /* is to render _all_ glyphs. As this would be a definite */ + /* performance hit, it is up to client applications to perform such */ + /* computations. */ + /* */ + typedef struct FT_Size_Metrics_ + { + FT_UShort x_ppem; /* horizontal pixels per EM */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* two scales used to convert font units */ + FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates.. */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models the */ + /* resolution and pointsize dependent data of a given face. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, which is unused by the FreeType */ + /* library or any of its drivers. It can be used by */ + /* client applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an FT_Slot_InternalRec structure, used to */ + /* model private data of a given FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they */ + /* vectorial or bitmap/graymaps. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer which is unused by the */ + /* FreeType library or any of its drivers. It */ + /* can be used by client applications to link */ + /* their own data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: For scalable formats only, this field holds */ + /* the linearly scaled horizontal advance width */ + /* for the glyph (i.e. the scaled and unhinted */ + /* value of the hori advance). This can be */ + /* important to perform correct WYSIWYG layout. */ + /* */ + /* Note that this value is expressed by default */ + /* in 16.16 pixels. However, when the glyph is */ + /* loaded with the FT_LOAD_LINEAR_DESIGN flag, */ + /* this field contains simply the value of the */ + /* advance in original font units. */ + /* */ + /* linearVertAdvance :: For scalable formats only, this field holds */ + /* the linearly scaled vertical advance height */ + /* for the glyph. See linearHoriAdvance for */ + /* comments. */ + /* */ + /* advance :: This is the transformed advance width for the */ + /* glyph. */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* FT_GLYPH_FORMAT_BITMAP, */ + /* FT_GLYPH_FORMAT_OUTLINE, and */ + /* FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: This is the bitmap's left bearing expressed */ + /* in integer pixels. Of course, this is only */ + /* valid if the format is */ + /* FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* bitmap_top :: This is the bitmap's top bearing expressed in */ + /* integer pixels. Remember that this is the */ + /* distance from the baseline to the top-most */ + /* glyph scanline, upwards y-coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* ft_glyph_bitmap_outline. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This format is only valid for the composite */ + /* glyph format, that should normally only be */ + /* loaded with the FT_LOAD_NO_RECURSE flag. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type 1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client apps. */ + /* Note that the app will need to know about the */ + /* image format. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g. a vectorial outline for TrueType and */ + /* Type 1 formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then convert it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g. coordinates [0,0] on the baseline). Of course, */ + /* `slot->format' is also changed to `FT_GLYPH_FORMAT_BITMAP' . */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt flags; + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initializes a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros FT_FREETYPE_MAJOR, FT_FREETYPE_MINOR, and */ + /* FT_FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a 'library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use `FT_Init_FreeType'. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroys a given FreeType library object and all of its childs, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Open_Flags */ + /* */ + /* <Description> */ + /* An enumeration used to list the bit flags used within the */ + /* `flags' field of the @FT_Open_Args structure. */ + /* */ + /* <Fields> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C */ + /* path name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' & `params' field. */ + /* */ + /* ft_open_memory :: deprecated. use @FT_OPEN_MEMORY instead */ + /* */ + /* ft_open_stream :: deprecated. use @FT_OPEN_STREAM instead */ + /* */ + /* ft_open_pathname :: deprecated. use @FT_OPEN_PATHNAME instead */ + /* */ + /* ft_open_driver :: deprecated, use @FT_OPEN_DRIVER instead */ + /* */ + /* ft_open_params :: deprecated, use @FT_OPEN_PARAMS instead */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ + typedef enum + { + FT_OPEN_MEMORY = 1, + FT_OPEN_STREAM = 2, + FT_OPEN_PATHNAME = 4, + FT_OPEN_DRIVER = 8, + FT_OPEN_PARAMS = 16 + + } FT_Open_Flags; + +#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ +#define ft_open_stream FT_OPEN_STREAM /* deprecated */ +#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ +#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ +#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters */ + /* to @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A 4-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The id and function of parameters are driver-specific. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file/stream. */ + /* A pointer to such a structure can be used as a parameter for the */ + /* functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to 0, FreeType will try to load */ + /* the face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' which */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* memory file of `memory_size' bytes,located at `memory_address'. */ + /* */ + /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face will only try to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* `num_params' and `params' will be used. They are ignored */ + /* otherwise. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_Open_Flags flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* Creates a new face object from a given resource and typeface index */ + /* using a pathname to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index 0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* @FT_New_Face can be used to determine and/or check the font format */ + /* of a given font resource. If the `face_index' field is negative, */ + /* the function will _not_ return any face handle in `aface'. Its */ + /* return value should be 0 if the font format is recognized, or */ + /* non-zero otherwise. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* Creates a new face object from a given resource and typeface index */ + /* using a font file already loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index 0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The font data bytes are used _directly_ by the @FT_Face object. */ + /* This means that they are not copied, and that the client is */ + /* responsible for releasing/destroying them _after_ the */ + /* corresponding call to @FT_Done_Face . */ + /* */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* @FT_New_Memory_Face can be used to determine and/or check the font */ + /* format of a given font resource. If the `face_index' field is */ + /* negative, the function will _not_ return any face handle in */ + /* `aface'. Its return value should be 0 if the font format is */ + /* recognized, or non-zero otherwise. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Opens a face object from a given resource and typeface index using */ + /* an `FT_Open_Args' structure. If the face object doesn't exist, it */ + /* will be created. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* be filled by the caller. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index 0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* @FT_Open_Face can be used to determine and/or check the font */ + /* format of a given font resource. If the `face_index' field is */ + /* negative, the function will _not_ return any face handle in */ + /* `*face'. Its return value should be 0 if the font format is */ + /* recognized, or non-zero otherwise. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* `Attaches' a given font file to an existing face. This is usually */ + /* to read additional information for a single face object. For */ + /* example, it is used to read the AFM files that come with Type 1 */ + /* fonts in order to add kerning data and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: An 8-bit pathname naming the `metrics' file. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If your font file is in memory, or if you want to provide your */ + /* own input stream object, use @FT_Attach_Stream. */ + /* */ + /* The meaning of the `attach' action (i.e., what really happens when */ + /* the new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* This function is similar to @FT_Attach_File with the exception */ + /* that it reads the attachment from an arbitrary stream. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to an FT_Open_Args structure used to */ + /* describe the input stream to FreeType. */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e. what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discards a given face object, as well as all of its child slots */ + /* and sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* Sets the character dimensions of a given face object. The */ + /* `char_width' and `char_height' values are used for the width and */ + /* height, respectively, expressed in 26.6 fractional points. */ + /* */ + /* If the horizontal or vertical resolution values are zero, a */ + /* default value of 72dpi is used. Similarly, if one of the */ + /* character dimensions is zero, its value is set equal to the other. */ + /* */ + /* <InOut> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Input> */ + /* char_width :: The character width, in 26.6 fractional points. */ + /* */ + /* char_height :: The character height, in 26.6 fractional */ + /* points. */ + /* */ + /* horz_resolution :: The horizontal resolution. */ + /* */ + /* vert_resolution :: The vertical resolution. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* When dealing with fixed-size faces (i.e., non-scalable formats), */ + /* use the function @FT_Set_Pixel_Sizes. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* Sets the character dimensions of a given face object. The width */ + /* and height are expressed in integer pixels. */ + /* */ + /* If one of the character dimensions is zero, its value is set equal */ + /* to the other. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The character width, in integer pixels. */ + /* */ + /* pixel_height :: The character height, in integer pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* <Note> */ + /* The values of `pixel_width' and `pixel_height' correspond to the */ + /* pixel values of the _typographic_ character size, which are NOT */ + /* necessarily the same as the dimensions of the glyph `bitmap */ + /* cells'. */ + /* */ + /* The `character size' is really the size of an abstract square */ + /* called the `EM', used to design the font. However, depending */ + /* on the font design, glyphs will be smaller or greater than the */ + /* EM. */ + /* */ + /* This means that setting the pixel size to, say, 8x8 doesn't */ + /* guarantee in any way that you will get glyph bitmaps that all fit */ + /* within an 8x8 cell (sometimes even far from it). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* will be loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* @FT_Set_Transform. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* will be loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If the face has no current charmap, or if the character code */ + /* is not defined in the charmap, this function will return an */ + /* error. */ + /* */ + /* If the glyph image is not a bitmap, and if the bit flag */ + /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ + /* transformed with the information passed to a previous call to */ + /* @FT_Set_Transform. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /**************************************************************************** + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit-field constants, used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to 0, this value is used a default glyph load. In this + * case, the following will happen: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. The + * bitmap data can be accessed from the glyph slot (see note below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then "hinted" to the pixel grid in + * order to optimize it. The outline data can be accessed from the + * glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the vector outline being loaded to 26.6 fractional + * pixels, but kept in font units. Note that this also disables + * hinting and the loading of embedded bitmaps. You should only use it + * when you want to retrieve the original glyph outlines in font units. + * + * FT_LOAD_NO_HINTING :: + * Don't hint glyph outlines after their scaling to device pixels. + * This generally generates "blurrier" glyphs in anti-aliased modes. + * + * This flag is ignored if @FT_LOAD_NO_SCALE is set. + * + * FT_LOAD_RENDER :: + * Render the glyph outline immediately into a bitmap before the glyph + * loader returns. By default, the glyph is rendered for the + * @FT_RENDER_MODE_NORMAL mode, which corresponds to 8-bit anti-aliased + * bitmaps using 256 opacity levels. You can use either + * @FT_LOAD_TARGET_MONO or @FT_LOAD_MONOCHROME to render 1-bit + * monochrome bitmaps. + * + * This flag is ignored if @FT_LOAD_NO_SCALE is set. + * + * FT_LOAD_NO_BITMAP :: + * Don't look for bitmaps when loading the glyph. Only scalable + * outlines will be loaded when available, and scaled, hinted, or + * rendered depending on other bit flags. + * + * This does not prevent you from rendering outlines to bitmaps + * with @FT_LOAD_RENDER, however. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Prepare the glyph image for vertical text layout. This basically + * means that `face.glyph.advance' will correspond to the vertical + * advance height (instead of the default horizontal advance width), + * and that the glyph image will be translated to match the vertical + * bearings positions. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Force the use of the FreeType auto-hinter when a glyph outline is + * loaded. You shouldn't need this in a typical application, since it + * is mostly used to experiment with its algorithm. + * + * FT_LOAD_CROP_BITMAP :: + * Indicates that the glyph loader should try to crop the bitmap (i.e., + * remove all space around its black bits) when loading it. This is + * only useful when loading embedded bitmaps in certain fonts, since + * bitmaps rendered with @FT_LOAD_RENDER are always cropped by default. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the glyph loader should perform pedantic + * verifications during glyph loading, rejecting invalid fonts. This + * is mostly used to detect broken glyphs in fonts. By default, + * FreeType tries to handle broken fonts also. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Indicates that the glyph loader should ignore the global advance + * width defined in the font. As far as we know, this is only used by + * the X-TrueType font server, in order to deal correctly with the + * incorrect metrics contained in DynaLab's TrueType CJK fonts. + * + * FT_LOAD_NO_RECURSE :: + * This flag is only used internally. It merely indicates that the + * glyph loader should not load composite glyphs recursively. Instead, + * it should set the `num_subglyph' and `subglyphs' values of the glyph + * slot accordingly, and set "glyph->format" to + * @FT_GLYPH_FORMAT_COMPOSITE. + * + * The description of sub-glyphs is not available to client + * applications for now. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the glyph loader should not try to transform the + * loaded glyph image. This doesn't prevent scaling, hinting, or + * rendering. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want + * to render a 1-bit monochrome glyph bitmap from a vectorial outline. + * + * Note that this has no effect on the hinting algorithm used by the + * glyph loader. You should better use @FT_LOAD_TARGET_MONO if you + * want to render monochrome-optimized glyph images instead. + * + * FT_LOAD_LINEAR_DESIGN :: + * Return the linearly scaled metrics expressed in original font units + * instead of the default 16.16 pixel values. + * + * FT_LOAD_NO_AUTOHINT :: + * Indicates that the auto-hinter should never be used to hint glyph + * outlines. This doesn't prevent native format-specific hinters from + * being used. This can be important for certain fonts where unhinted + * output is better than auto-hinted one. + */ +#define FT_LOAD_NO_SCALE 0x1 +#define FT_LOAD_NO_HINTING 0x2 +#define FT_LOAD_RENDER 0x4 +#define FT_LOAD_NO_BITMAP 0x8 +#define FT_LOAD_VERTICAL_LAYOUT 0x10 +#define FT_LOAD_FORCE_AUTOHINT 0x20 +#define FT_LOAD_CROP_BITMAP 0x40 +#define FT_LOAD_PEDANTIC 0x80 +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 0x200 +#define FT_LOAD_NO_RECURSE 0x400 +#define FT_LOAD_IGNORE_TRANSFORM 0x800 +#define FT_LOAD_MONOCHROME 0x1000 +#define FT_LOAD_LINEAR_DESIGN 0x2000 + + /* temporary hack! */ +#define FT_LOAD_SBITS_ONLY 0x4000 +#define FT_LOAD_NO_AUTOHINT 0x8000U + + /* */ + +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + +#define FT_LOAD_DEFAULT 0x0 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images just before they are converted to bitmaps in a glyph slot */ + /* when @FT_Render_Glyph is called. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use 0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Sizes or @FT_Set_Pixel_Sizes. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType 2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline, as well as specific */ + /* hinting optimizations. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps, using 256 levels of opacity. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is similar to @FT_RENDER_MODE_NORMAL, except that this */ + /* changes the hinting to prevent stem width quantization. This */ + /* results in glyph shapes that are more similar to the original, */ + /* while being a bit more fuzzy ("better shapes", instead of */ + /* "better contrast" if you want :-) THIS IS STILL EXPERIMENTAL, */ + /* FOR NOW, THIS WILL PRODUCE RESULTS SIMILAR TO NORMAL MODE !! */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps. */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB/BGR sub-pixel displays, */ + /* like LCD-screens. It produces 8-bit bitmaps that are 3 times */ + /* the width of the original glyph outline in pixels, and which use */ + /* the @FT_PIXEL_MODE_LCD mode. THIS IS STILL EXPERIMENTAL, DO NOT */ + /* USE FOR NOW !! */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB/BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3 times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph are */ + /* _not filtered_ to reduce color-fringes. It is up to the caller to */ + /* perform this pass. THIS IS STILL EXPERIMENTAL, DO NOT USE FOR NOW */ + /* !! */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_render_mode_xxx */ + /* */ + /* <Description> */ + /* These constats are deprecated. Use the corresponding */ + /* @FT_Render_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Converts a given glyph image to a bitmap. It does so by */ + /* inspecting the glyph image format, find the relevant renderer, and */ + /* invoke it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See FT_Render_Mode for a list */ + /* of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ + /* distances (value is 0). */ + /* */ + /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ + /* distances. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_default */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ + /* instead. */ + /* */ +#define ft_kerning_default FT_KERNING_DEFAULT + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unfitted */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ + /* instead. */ + /* */ +#define ft_kerning_unfitted FT_KERNING_UNFITTED + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unscaled */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ + /* instead. */ + /* */ +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Returns the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale/dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieves the ASCII name of a given glyph in a face. This only */ + /* works for those faces where FT_HAS_GLYPH_NAME(face) returns true. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximal number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name will be */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' will be set to 0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* This function is not compiled within the library if the config */ + /* macro FT_CONFIG_OPTION_NO_GLYPH_NAMES is defined in */ + /* `include/freetype/config/ftoptions.h' */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieves the ASCII Postscript name of a given face, if available. */ + /* This should only work with Postscript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's Postscript name. NULL if un-available. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and will be destroyed */ + /* with it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Selects a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function will return an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Selects a given charmap for character code to glyph index */ + /* decoding. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function will return an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the face->charmaps[] */ + /* table). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Returns the glyph index of a given character code. This function */ + /* uses a charmap object to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0 means `undefined character code'. */ + /* */ + /* <Note> */ + /* FreeType computes its own glyph indices which are not necessarily */ + /* the same as used in the font in case the font is based on glyph */ + /* indices. Reason for this behaviour is to assure that index 0 is */ + /* never used, representing the missing glyph. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It will also return the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0 if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Note that `*agindex' will be set to 0 if the charmap is empty. */ + /* The result itself can be 0 in two cases: if the charmap is empty */ + /* or when the value 0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value 'char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0 if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* through all character codes available in a given charmap. See */ + /* the note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' will be set to 0 when there are no more codes */ + /* in the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Returns the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0 means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximal accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + /* <Note> */ + /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ + /* 32 bits, then the division is computed directly. Otherwise, we */ + /* use a specialized version of the old @FT_MulDiv64. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x8000) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `a & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transforms a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + FT_Matrix* matrix ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FREETYPE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftbbox.h b/lib/freetype/include/freetype/ftbbox.h new file mode 100644 index 0000000..e661613 --- /dev/null +++ b/lib/freetype/include/freetype/ftbbox.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2001 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 has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTBBOX_H__ +#define __FTBBOX_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Computes the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm which returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bezier arcs are walked over to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBBOX_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftbdf.h b/lib/freetype/include/freetype/ftbdf.h new file mode 100644 index 0000000..71735e3 --- /dev/null +++ b/lib/freetype/include/freetype/ftbdf.h @@ -0,0 +1,182 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002 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 __FTBDF_H__ +#define __FTBDF_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF Fonts */ + /* */ + /* <Abstract> */ + /* BDF-specific APIs */ + /* */ + /* <Description> */ + /* This section contains the declaration of BDF-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * list of BDF property types + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * value 0 is used to indicate a missing property + * + * BDF_PROPERTY_TYPE_ATOM :: + * property is a string atom + * + * BDF_PROPERTY_TYPE_INTEGER :: + * property is a 32-bit signed integer + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * property is a 32-bit unsigned integer + */ + typedef enum + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: BDF_Property + * + * @description: + * handle to a @BDF_PropertyRec structure used to model a given + * BDF/PCF property + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + /********************************************************************** + * + * @struct: BDF_PropertyRec + * + * @description: + * models a given BDF/PCF property + * + * @note: + * type :: property type + * u.atom :: atom string, when type is @BDF_PROPERTY_TYPE_ATOM + * u.integer :: signed integer, when type is @BDF_PROPERTY_TYPE_INTEGER + * u.cardinal :: unsigned integer, when type is @BDF_PROPERTY_TYPE_CARDINAL + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieves a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * handle to input face + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C string, owned by the face. + * + * @return: + * FreeType rror code. 0 means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieves a BDF property from a BDF or PCF font file + * + * @input: + * face :: handle to input face + * name :: property name + * + * @output: + * aproperty :: the property + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. it also returns an error when the property is not in the + * font. + * + * in case of error, "aproperty->type" is always set to + * @BDF_PROPERTY_TYPE_NONE + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftcache.h b/lib/freetype/include/freetype/ftcache.h new file mode 100644 index 0000000..82af391 --- /dev/null +++ b/lib/freetype/include/freetype/ftcache.h @@ -0,0 +1,415 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS BETA CODE. *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTCACHE_H__ +#define __FTCACHE_H__ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /* <Title> */ + /* Cache Sub-System */ + /* */ + /* <Abstract> */ + /* How to cache face, size, and glyph data with FreeType 2. */ + /* */ + /* <Description> */ + /* This section describes the FreeType 2 cache sub-system which is */ + /* stile in beta. */ + /* */ + /* <Order> */ + /* FTC_Manager */ + /* FTC_FaceID */ + /* FTC_Face_Requester */ + /* */ + /* FTC_Manager_New */ + /* FTC_Manager_Lookup_Face */ + /* FTC_Manager_Lookup_Size */ + /* */ + /* FTC_Node */ + /* FTC_Node_Ref */ + /* FTC_Node_Unref */ + /* */ + /* FTC_Font */ + /* FTC_ImageDesc */ + /* FTC_ImageCache */ + /* FTC_ImageCache_New */ + /* FTC_ImageCache_Lookup */ + /* */ + /* FTC_SBit */ + /* FTC_SBitCache */ + /* FTC_SBitCache_New */ + /* FTC_SBitCache_Lookup */ + /* */ + /* */ + /* FTC_Image_Desc */ + /* FTC_Image_Cache */ + /* FTC_Image_Cache_Lookup */ + /* */ + /* FTC_SBit_Cache */ + /* FTC_SBit_Cache_Lookup */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_FaceID */ + /* */ + /* <Description> */ + /* A generic pointer type that is used to identity face objects. The */ + /* contents of such objects is application-dependent. */ + /* */ + typedef FT_Pointer FTC_FaceID; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FTC_Face_Requester */ + /* */ + /* <Description> */ + /* A callback function provided by client applications. It is used */ + /* to translate a given @FTC_FaceID into a new valid @FT_Face object. */ + /* */ + /* <Input> */ + /* face_id :: The face ID to resolve. */ + /* */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* data :: Application-provided request data. */ + /* */ + /* <Output> */ + /* aface :: A new @FT_Face handle. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The face requester should not perform funny things on the returned */ + /* face object, like creating a new @FT_Size for it, or setting a */ + /* transformation through @FT_Set_Transform! */ + /* */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer request_data, + FT_Face* aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_FontRec */ + /* */ + /* <Description> */ + /* A simple structure used to describe a given `font' to the cache */ + /* manager. Note that a `font' is the combination of a given face */ + /* with a given character size. */ + /* */ + /* <Fields> */ + /* face_id :: The ID of the face to use. */ + /* */ + /* pix_width :: The character width in integer pixels. */ + /* */ + /* pix_height :: The character height in integer pixels. */ + /* */ + typedef struct FTC_FontRec_ + { + FTC_FaceID face_id; + FT_UShort pix_width; + FT_UShort pix_height; + + } FTC_FontRec; + + + /* */ + + +#define FTC_FONT_COMPARE( f1, f2 ) \ + ( (f1)->face_id == (f2)->face_id && \ + (f1)->pix_width == (f2)->pix_width && \ + (f1)->pix_height == (f2)->pix_height ) + +#define FT_POINTER_TO_ULONG( p ) ((FT_ULong)(FT_Pointer)(p)) + +#define FTC_FACE_ID_HASH( i ) \ + ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^ \ + ( FT_POINTER_TO_ULONG( i ) << 7 ) ) ) + +#define FTC_FONT_HASH( f ) \ + (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \ + ((f)->pix_width << 8) ^ \ + ((f)->pix_height) ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Font */ + /* */ + /* <Description> */ + /* A simple handle to an @FTC_FontRec structure. */ + /* */ + typedef FTC_FontRec* FTC_Font; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object is used to cache one or more @FT_Face objects, along */ + /* with corresponding @FT_Size objects. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of 0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you lookup nodes, you have the ability to "acquire" them, i.e., */ + /* to increment their reference count. This will prevent the node */ + /* from being flushed out of the cache until you explicitly "release" */ + /* it (see @FTC_Node_Release). */ + /* */ + /* See also @FTC_BitsetCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Creates a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of faces to keep alive in manager. */ + /* Use 0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of sizes to keep alive in manager. */ + /* Use 0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data. */ + /* Use 0 for defaults. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0 in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empties a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroys a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Lookup_Face */ + /* */ + /* <Description> */ + /* Retrieves the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be 0). If you need a specific `font size', */ + /* use @FTC_Manager_Lookup_Size instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Lookup_Size */ + /* */ + /* <Description> */ + /* Retrieves the @FT_Face and @FT_Size objects that correspond to a */ + /* given @FTC_SizeID. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* size_id :: The ID of the `font size' to use. */ + /* */ + /* <Output> */ + /* aface :: A pointer to the handle of the face object. Set it to */ + /* zero if you don't need it. */ + /* */ + /* asize :: A pointer to the handle of the size object. Set it to */ + /* zero if you don't need it. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* Similarly, the returned @FT_Size object is always owned by the */ + /* manager. You should never try to discard it, and never change its */ + /* settings with @FT_Set_Pixel_Sizes or @FT_Set_Char_Size! */ + /* */ + /* The returned size object is the face's current size, which means */ + /* that you can call @FT_Load_Glyph with the face if you need to. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ); + + +FT_END_HEADER + +#endif /* __FTCACHE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftchapters.h b/lib/freetype/include/freetype/ftchapters.h new file mode 100644 index 0000000..c134ec1 --- /dev/null +++ b/lib/freetype/include/freetype/ftchapters.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* basic_types */ +/* base_interface */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* pfr_fonts */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* raster */ +/* system_interface */ +/* module_management */ +/* */ +/***************************************************************************/ + diff --git a/lib/freetype/include/freetype/fterrdef.h b/lib/freetype/include/freetype/fterrdef.h new file mode 100644 index 0000000..4ef606d --- /dev/null +++ b/lib/freetype/include/freetype/fterrdef.h @@ -0,0 +1,229 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST OF ERROR CODES/MESSAGES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + + /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ + /* including this file. */ + + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, \ + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, \ + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, \ + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, \ + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, \ + "broken offset within table" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, \ + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, \ + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, \ + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, \ + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, \ + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, \ + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, \ + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, \ + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, \ + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, \ + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, \ + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, \ + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, \ + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, \ + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, \ + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + "argument stack underflow" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB3, \ + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, \ + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, \ + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \ + "`BBX' field missing" ) + + +/* END */ diff --git a/lib/freetype/include/freetype/fterrors.h b/lib/freetype/include/freetype/fterrors.h new file mode 100644 index 0000000..1def4f9 --- /dev/null +++ b/lib/freetype/include/freetype/fterrors.h @@ -0,0 +1,207 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 special header file is used to define the handling of FT2 */ + /* enumeration constants. It can also be used to generate error message */ + /* strings with a small macro trick explained below. */ + /* */ + /* I - Error Formats */ + /* ----------------- */ + /* */ + /* Since release 2.1, the error constants have changed. The lower */ + /* byte of the error value gives the "generic" error code, while the */ + /* higher byte indicates in which module the error occurred. */ + /* */ + /* You can use the macro FT_ERROR_BASE(x) macro to extract the generic */ + /* error code from an FT_Error value. */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* undefined in ftoption.h in order to make the higher byte always */ + /* zero, in case you need to be compatible with previous versions of */ + /* FreeType 2. */ + /* */ + /* */ + /* II - Error Message strings */ + /* -------------------------- */ + /* */ + /* The error definitions below are made through special macros that */ + /* allow client applications to build a table of error message strings */ + /* if they need it. The strings are not included in a normal build of */ + /* FreeType 2 to save space (most client applications do not use */ + /* them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file: */ + /* */ + /* FT_ERROR_START_LIST :: */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls */ + /* (see below). */ + /* */ + /* FT_ERROR_DEF( e, v, s ) :: */ + /* This macro is called to define one single error. */ + /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ + /* `v' is the error numerical value. */ + /* `s' is the corresponding error string. */ + /* */ + /* FT_ERROR_END_LIST :: */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* this file. */ + /* */ + /* Here is a simple example: */ + /* */ + /* { */ + /* #undef __FTERRORS_H__ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTERRORS_H__ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#undef FT_ERR_XCAT +#undef FT_ERR_CAT + +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for FT_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* no include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_PREFIX +#undef FT_ERR_BASE +#undef FT_ERR_CONCAT + +#endif /* __FTERRORS_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftglyph.h b/lib/freetype/include/freetype/ftglyph.h new file mode 100644 index 0000000..e1acae7 --- /dev/null +++ b/lib/freetype/include/freetype/ftglyph.h @@ -0,0 +1,517 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2001 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 contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTGLYPH_H__ +#define __FTGLYPH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed float format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of `FT_GlyphRec'. */ + /* */ + /* <Fields> */ + /* root :: The root FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards-y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast FT_Glyph to FT_BitmapGlyph if you have */ + /* glyph->format == FT_GLYPH_FORMAT_BITMAP. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by the BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of `FT_GlyphRec'. */ + /* */ + /* <Fields> */ + /* root :: The root FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast FT_Glyph to FT_OutlineGlyph if you have */ + /* glyph->format == FT_GLYPH_FORMAT_OUTLINE. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* FT_LOAD_NO_SCALE was used in FT_Load_Glyph() or FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0 in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transforms a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (the glyph format is not scalable if it is */ + /* not zero). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + /* */ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Returns a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bezier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bezier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode which indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the Y-upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to `ft_glyph_bbox_unscaled' to get unscaled font */ + /* units. */ + /* */ + /* If `bbox_mode' is set to `ft_glyph_bbox_subpixels' the bbox */ + /* coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* `ft_glyph_bbox_gridfit', the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* `ft_glyph_bbox_truncate'. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to `ft_glyph_bbox_pixels'. */ + /* */ + /* The default value for `bbox_mode' is `ft_glyph_bbox_pixels'. */ + /* */ + enum + { + ft_glyph_bbox_unscaled = 0, /* return unscaled font units */ + ft_glyph_bbox_subpixels = 0, /* return unfitted 26.6 coordinates */ + ft_glyph_bbox_gridfit = 1, /* return grid-fitted 26.6 coordinates */ + ft_glyph_bbox_truncate = 2, /* return coordinates in integer pixels */ + ft_glyph_bbox_pixels = 3 /* return grid-fitted pixel coordinates */ + }; + + + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Converts a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describe how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be 0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. In case of error, it it translated back to its */ + /* original position and the glyph is left untouched. */ + /* */ + /* The first parameter is a pointer to a FT_Glyph handle, that will */ + /* be replaced by this function. Typically, you would use (omitting */ + /* error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroy old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_default, */ + /* 0, 1 ); */ + /* if ( error ) // glyph unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* This function will always fail if the glyph's format isn't */ + /* scalable. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroys a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Performs the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLYPH_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftgzip.h b/lib/freetype/include/freetype/ftgzip.h new file mode 100644 index 0000000..c254622 --- /dev/null +++ b/lib/freetype/include/freetype/ftgzip.h @@ -0,0 +1,86 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* Copyright 2002 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 __FTGZIP_H__ +#define __FTGZIP_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @type: FT_Stream_OpenGzip + * + * @description: + * open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed *.pcf.gz fonts that come + * with XFree86 + * + * @input: + * stream :: target embedding stream + * source :: source stream, used to + * + * @return: + * error code. 0 means success + * + * @note: + * the source stream must be opened _before_ calling this function. + * + * calling @FT_Stream_Close on the new stream will *not* call + * @FT_Stream_Close on the source stream. None of the stream objects + * will be released to the heap. + * + * the stream implementation is very basic, and resets the decompression + * process each time seeking backwards is needed within the stream + * + * in certain builds of the library, gzip compression recognition is + * automatic when calling @FT_New_Face or @FT_Open_Face. This means that + * if no font driver is capable of handling the raw compressed file, + * the library will try to open a gzip stream from it and re-open + * the face with it. + * + * this function may return "FT_Err_Unimplemented" if your build of + * FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + /* */ + +FT_END_HEADER + +#endif /* __FTGZIP_H__ */ diff --git a/lib/freetype/include/freetype/ftimage.h b/lib/freetype/include/freetype/ftimage.h new file mode 100644 index 0000000..fe46bf5 --- /dev/null +++ b/lib/freetype/include/freetype/ftimage.h @@ -0,0 +1,1241 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTIMAGE_H__ +#define __FTIMAGE_H__ + + +/* _STANDALONE_ is from ftgrays.c */ +#ifndef _STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is a 32-bit integer used to store vectorial */ + /* coordinates. Depending on the context, these can represent */ + /* distances in integer font units, or 26.6 fixed float pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value 0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1 bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of value "gray" levels is stored in the `num_bytes' field of */ + /* the @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ + /* images used for display on LCD displays; the bitmap's width is */ + /* three times wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ + /* images used for display on rotated LCD displays; the bitmap's */ + /* height is three times taller than the original glyph image. */ + /* See also @FT_RENDER_MODE_LCD_V. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_pixel_mode_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Pixel_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_pixel_mode_none :: see @FT_PIXEL_MODE_NONE */ + /* ft_pixel_mode_mono :: see @FT_PIXEL_MODE_MONO */ + /* ft_pixel_mode_grays :: see @FT_PIXEL_MODE_GRAY */ + /* ft_pixel_mode_pal2 :: see @FT_PIXEL_MODE_GRAY2 */ + /* ft_pixel_mode_pal4 :: see @FT_PIXEL_MODE_GRAY4 */ + /* */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + /* */ + +#if 0 + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Palette_Mode */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ + /* */ + /* An enumeration type used to describe the format of a bitmap */ + /* palette, used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ + /* */ + /* <Fields> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-bytes RGB */ + /* records. */ + /* */ + /* ft_palette_mode_rgba :: The palette is an array of 4-bytes RGBA */ + /* records. */ + /* */ + /* <Note> */ + /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ + /* FreeType, these types are not handled by the library itself. */ + /* */ + typedef enum FT_Palette_Mode_ + { + ft_palette_mode_rgb = 0, + ft_palette_mode_rgba, + + ft_palettte_mode_max /* do not remove */ + + } FT_Palette_Mode; + + /* */ + +#endif + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* `FT_PIXEL_MODE_GRAY'; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel_mode, i.e., how pixel bits are stored. */ + /* */ + /* palette_mode :: This field is only used with paletted pixel modes; */ + /* it indicates how the palette is stored. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; only */ + /* used for paletted pixel modes. */ + /* */ + /* <Note> */ + /* For now, the only pixel mode supported by FreeType are mono and */ + /* grays. However, drivers might be added in the future to support */ + /* more `colorful' options. */ + /* */ + /* When using pixel modes pal2, pal4 and pal8 with a void `palette' */ + /* field, a gray pixmap with respectively 4, 16, and 256 levels of */ + /* gray is assumed. This, in order to be compatible with some */ + /* embedded bitmap formats defined in the TrueType specification. */ + /* */ + /* Note that no font was found presenting such embedded bitmaps, so */ + /* this is currently completely unhandled by the library. */ + /* */ + typedef struct FT_Bitmap_ + { + int rows; + int width; + int pitch; + unsigned char* buffer; + short num_grays; + char pixel_mode; + char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. If bit 0 is unset, the */ + /* point is `off' the curve, i.e. a Bezier control */ + /* point, while it is `on' when set. */ + /* */ + /* Bit 1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bezier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See FT_Outline_Flags. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Outline_Flags */ + /* */ + /* <Description> */ + /* A simple type used to enumerates the flags in an outline's */ + /* `outline_flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: Value 0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: If set, this flag indicates that the */ + /* outline's field arrays (i.e. */ + /* `points', `flags' & `contours') are */ + /* `owned' by the outline object, and */ + /* should thus be freed when it is */ + /* destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: By default, outlines are filled using */ + /* the non-zero winding rule. If set to */ + /* 1, the outline will be filled using */ + /* the even-odd fill rule (only works */ + /* with the smooth raster). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: By default, outside contours of an */ + /* outline are oriented in clock-wise */ + /* direction, as defined in the TrueType */ + /* specification. This flag is set if */ + /* the outline uses the opposite */ + /* direction (typically for Type 1 */ + /* fonts). This flag is ignored by the */ + /* scan-converter. However, it is very */ + /* important for the auto-hinter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: By default, the scan converter will */ + /* try to detect drop-outs in an outline */ + /* and correct the glyph bitmap to */ + /* ensure consistent shape continuity. */ + /* If set, this flag hints the scan-line */ + /* converter to ignore such cases. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: This flag indicates that the */ + /* scan-line converter should try to */ + /* convert this outline to bitmaps with */ + /* the highest possible quality. It is */ + /* typically set for small character */ + /* sizes. Note that this is only a */ + /* hint, that might be completely */ + /* ignored by a given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: This flag is set to force a given */ + /* scan-converter to only use a single */ + /* pass over the outline to render a */ + /* bitmap glyph image. Normally, it is */ + /* set for very large character sizes. */ + /* It is only a hint, that might be */ + /* completely ignored by a given */ + /* scan-converter. */ + /* */ + typedef enum FT_Outline_Flags_ + { + FT_OUTLINE_NONE = 0, + FT_OUTLINE_OWNER = 1, + FT_OUTLINE_EVEN_ODD_FILL = 2, + FT_OUTLINE_REVERSE_FILL = 4, + FT_OUTLINE_IGNORE_DROPOUTS = 8, + FT_OUTLINE_HIGH_PRECISION = 256, + FT_OUTLINE_SINGLE_PASS = 512 + + } FT_Outline_Flags; + + + /************************************************************************* + * + * @enum: + * ft_outline_xxx + * + * @description: + * These constants are deprecated. Please use the corresponding + * @FT_OUTLINE_XXX values. + * + * @values: + * ft_outline_none :: See @FT_OUTLINE_NONE. + * ft_outline_owner :: See @FT_OUTLINE_OWNER. + * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. + * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. + * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. + * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. + * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. + */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type use to describe the signature of a `conic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bezier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( FT_Vector* control, + FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bezier control point. */ + /* */ + /* control2 :: A pointer to the second Bezier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Beziers, */ + /* as well as `move to' and `close to' operations. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bezier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bezier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* */ + /* Set the value of `shift' and `delta' to 0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four letter tags into an unsigned long. */ + /* */ + /* <Note> */ + /* Since many 16bit compilers don't like 32bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) (value) */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value 0 is reserved and does describe a glyph format. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_FLAG_NO_RECURSE, and is */ + /* used to report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vertorial outline made of line segments */ + /* and Bezier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside/outside */ + /* contours. Some Type 1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_format_xxx */ + /* */ + /* <Description> */ + /* A list of decprecated constants. Use the corresponding */ + /* @FT_Glyph_Format values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_format_none :: see @FT_GLYPH_FORMAT_NONE */ + /* ft_glyph_format_composite :: see @FT_GLYPH_FORMAT_COMPOSITE */ + /* ft_glyph_format_bitmap :: see @FT_GLYPH_FORMAT_BITMAP */ + /* ft_glyph_format_outline :: see @FT_GLYPH_FORMAT_OUTLINE */ + /* ft_glyph_format_plotter :: see @FT_GLYPH_FORMAT_PLOTTER */ + /* */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `freetype/ftrender.h' for */ + /* more details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* A handle (pointer) to a raster object. Each object can be used */ + /* independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray (or black) pixels */ + /* when rendering a monochrome or anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). Only used for anti-aliased */ + /* rendering. */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* FT_SpanFunc which takes the y-coordinate of the span as a */ + /* a parameter. */ + /* */ + /* The coverage value is always between 0 and 255, even if the number */ + /* of gray levels have been set through FT_Set_Gray_Levels(). */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y-coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + /* Note that the `count' field cannot be greater than a fixed value */ + /* defined by the FT_MAX_GRAY_SPANS configuration macro in */ + /* ftoption.h. By default, this value is set to 32, which means that */ + /* if there are more than 32 spans on a given scanline, the callback */ + /* will be called several times with the same `y' parameter in order */ + /* to draw all callbacks. */ + /* */ + /* Otherwise, the callback is only called once per scan-line, and */ + /* only for those scanlines that do have `gray' pixels on them. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to test whether a given target pixel is already set to the drawing */ + /* `color'. These tests are crucial to implement drop-out control */ + /* per-se the TrueType spec. */ + /* */ + /* <Input> */ + /* y :: The pixel's y-coordinate. */ + /* */ + /* x :: The pixel's x-coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1 if the pixel is `set', 0 otherwise. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to set an individual target pixel. This is crucial to implement */ + /* drop-out control according to the TrueType specification. */ + /* */ + /* <Input> */ + /* y :: The pixel's y-coordinate. */ + /* */ + /* x :: The pixel's x-coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1 if the pixel is `set', 0 otherwise. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Raster_Flag */ + /* */ + /* <Description> */ + /* An enumeration to list the bit flags as used in the `flags' field */ + /* of a FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit) */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Note that for now, direct rendering is */ + /* only possible with anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* "clip_box" field of the FT_Raster_Params */ + /* structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ + typedef enum + { + FT_RASTER_FLAG_DEFAULT = 0, + FT_RASTER_FLAG_AA = 1, + FT_RASTER_FLAG_DIRECT = 2, + FT_RASTER_FLAG_CLIP = 4 + + } FT_Raster_Flag; + +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g. an */ + /* FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: The black span drawing callback. */ + /* */ + /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* */ + /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the FT_RASTER_FLAG_AA bit */ + /* flag is set in the `flags' field, otherwise a monochrome bitmap */ + /* will be generated. */ + /* */ + /* If the FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans, in the case of an aa glyph bitmap, it will call */ + /* `black_spans', and `bit_test' and `bit_set' in the case of a */ + /* monochrome bitmap. This allows direct composition over a */ + /* pre-existing bitmap through user-provided callbacks to perform the */ + /* span drawing/composition. */ + /* */ + /* Note that the `bit_test' and `bit_set' callbacks are required when */ + /* rendering a monochrome bitmap, as they are crucial to implement */ + /* correct drop-out control as defined in the TrueType specification. */ + /* */ + typedef struct FT_Raster_Params_ + { + FT_Bitmap* target; + void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; + FT_Raster_BitTest_Func bit_test; /* doesn't work! */ + FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is a FT_Memory, i.e., a handle to the standard */ + /* FreeType memory allocator. However, this field can be completely */ + /* ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType provides an area of memory called the `render pool', */ + /* available to all registered rasters. This pool can be freely used */ + /* during a given scan-conversion but is shared by all rasters. Its */ + /* content is thus transient. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters can ignore the render pool and rely on dynamic memory */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). However, this is not */ + /* recommended for efficiency purposes. */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invokes a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to a FT_Raster_Params structure used to store */ + /* the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0 means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its FT_Raster_Funcs structure. It can be an */ + /* FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* FT_Err_Unimplemented_Feature error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files demos/src/ftgrays.c and demos/src/ftgrays2.c for */ + /* examples of distinct implementations which support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTIMAGE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftincrem.h b/lib/freetype/include/freetype/ftincrem.h new file mode 100644 index 0000000..c9e8b56 --- /dev/null +++ b/lib/freetype/include/freetype/ftincrem.h @@ -0,0 +1,287 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002 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 __FTINCREM_H__ +#define __FTINCREM_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * "incremental" glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g. Postscript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the 'vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + + } FT_Incremental_MetricsRec, *FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the 'glyf' table. For Postscript formats, it must correspond to the + * *unencrypted* charstring bytes, without any 'lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * If this function returns succesfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @struct: + * FT_Incremental_FuncsRec + * + * @description: + * A table of functions for accessing fonts that load data + * incrementally. Used in @FT_Incremental_Interface. + * + * @fields: + * get_glyph_data :: + * The function to get glyph data. Must not be null. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = (FT_Open_Flags)( FT_OPEN_PATHNAME | + * FT_OPEN_PARAMS ); + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + +FT_END_HEADER + +#endif /* __FTINCREM_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftlist.h b/lib/freetype/include/freetype/ftlist.h new file mode 100644 index 0000000..1c51017 --- /dev/null +++ b/lib/freetype/include/freetype/ftlist.h @@ -0,0 +1,268 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2001 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 implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTLIST_H__ +#define __FTLIST_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Finds the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Appends an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Inserts an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Removes a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Moves a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function which is called during a list parse */ + /* by FT_List_Iterate(). */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to FT_List_Iterate(). */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parses a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An interator function, called on each node of the */ + /* list. */ + /* user :: A user-supplied field which is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An FT_List iterator function which is called during a list */ + /* finalization by FT_List_Finalize() to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to FT_List_Iterate(). It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroys all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. */ + /* */ + /* memory :: The current memory object which handles deallocation. */ + /* */ + /* user :: A user-supplied field which is passed as the last */ + /* argument to the destructor. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTLIST_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftmac.h b/lib/freetype/include/freetype/ftmac.h new file mode 100644 index 0000000..b9f89ba --- /dev/null +++ b/lib/freetype/include/freetype/ftmac.h @@ -0,0 +1,128 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2001 by */ +/* Just van Rossum, 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: Include this file after <freetype/freetype.h> and after the */ +/* Mac-specific <Types.h> header (or any other Mac header that */ +/* includes <Types.h>); we use Handle type. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMAC_H__ +#define __FTMAC_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac-Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Creates a new face object from an FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: An FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create FT_Face abjects from fonts */ + /* that are installed in the system like so: */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Returns an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (eg. Times New Roman Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to @FT_New_Face. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ); + + /* */ + + +FT_END_HEADER + + +#endif /* __FTMAC_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftmm.h b/lib/freetype/include/freetype/ftmm.h new file mode 100644 index 0000000..5e681b2 --- /dev/null +++ b/lib/freetype/include/freetype/ftmm.h @@ -0,0 +1,203 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTMM_H__ +#define __FTMM_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e. the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed 4. */ + /* */ + /* num_designs :: Number of designs; should ne normally 2^num_axis */ + /* even though the Type 1 specification strangely */ + /* allows for intermediate designs to be present. This */ + /* number cannot exceed 16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + /* */ + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieves the Multiple Master descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMM_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftmoderr.h b/lib/freetype/include/freetype/ftmoderr.h new file mode 100644 index 0000000..59e15c1 --- /dev/null +++ b/lib/freetype/include/freetype/ftmoderr.h @@ -0,0 +1,149 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001, 2002 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 define the FreeType module error offsets. */ + /* */ + /* The lower byte gives the error code, the higher byte gives the */ + /* module. The base module has error offset 0. For example, the error */ + /* `FT_Err_Invalid_File_Format' has value 0x003, the error */ + /* `TT_Err_Invalid_File_Format' has value 0xB03, the error */ + /* `T1_Err_Invalid_File_Format' has value 0xC03, etc. */ + /* */ + /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */ + /* to make the higher byte always zero (disabling the module error */ + /* mechanism). */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef __FTMODERR_H__ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /* To use such a table, all errors must be ANDed with 0xFF00 to remove */ + /* the error code. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTMODERR_H__ +#define __FTMODERR_H__ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autohint, 0x100, "autohinter module" ) + FT_MODERRDEF( Cache, 0x200, "cache module" ) + FT_MODERRDEF( CFF, 0x300, "CFF module" ) + FT_MODERRDEF( CID, 0x400, "CID module" ) + FT_MODERRDEF( PCF, 0x500, "PCF module" ) + FT_MODERRDEF( PSaux, 0x600, "PS auxiliary module" ) + FT_MODERRDEF( PSnames, 0x700, "PS names module" ) + FT_MODERRDEF( Raster, 0x800, "raster module" ) + FT_MODERRDEF( SFNT, 0x900, "SFNT module" ) + FT_MODERRDEF( Smooth, 0xA00, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0xB00, "TrueType module" ) + FT_MODERRDEF( Type1, 0xC00, "Type 1 module" ) + FT_MODERRDEF( Winfonts, 0xD00, "Windows FON/FNT module" ) + FT_MODERRDEF( PFR, 0xE00, "PFR module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* __FTMODERR_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftmodule.h b/lib/freetype/include/freetype/ftmodule.h new file mode 100644 index 0000000..2ec5a03 --- /dev/null +++ b/lib/freetype/include/freetype/ftmodule.h @@ -0,0 +1,307 @@ +/***************************************************************************/ +/* */ +/* ftmodule.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTMODULE_H__ +#define __FTMODULE_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, and remove modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ + typedef enum FT_Module_Flags_ + { + ft_module_font_driver = 1, /* this module is a font driver */ + ft_module_renderer = 2, /* this module is a renderer */ + ft_module_hinter = 4, /* this module is a glyph hinter */ + ft_module_styler = 8, /* this module is a styler */ + + ft_module_driver_scalable = 0x100, /* the driver supports scalable */ + /* fonts */ + ft_module_driver_no_outlines = 0x200, /* the driver does not support */ + /* vector outlines */ + ft_module_driver_has_hinter = 0x400 /* the driver provides its own */ + /* hinter */ + + } FT_Module_Flags; + + + typedef void + (*FT_Module_Interface)( void ); + + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires */ + /* (starts at version 2.0, i.e 0x20000) */ + /* */ + /* module_init :: A function used to initialize (not create) a */ + /* new module object. */ + /* */ + /* module_done :: A function used to finalize (not destroy) a */ + /* given module object */ + /* */ + /* get_interface :: Queries a given module for a specific */ + /* interface by name. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Adds a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Finds a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0 if none was found. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for :-) */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Removes a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discards a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + + + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Sets a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in ftobjs.h, e.g. */ + /* FT_DEBUG_HOOK_TRUETYPE. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type 1 interpreter) are defined. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Adds the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* FT_New_Library() (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMODULE_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftoutln.h b/lib/freetype/include/freetype/ftoutln.h new file mode 100644 index 0000000..fdf7ed2 --- /dev/null +++ b/lib/freetype/include/freetype/ftoutln.h @@ -0,0 +1,400 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTOUTLN_H__ +#define __FTOUTLN_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_Outline_Flags */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveTo_Func */ + /* FT_Outline_LineTo_Func */ + /* FT_Outline_ConicTo_Func */ + /* FT_Outline_CubicTo_Func */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walks over an outline's structure to decompose it into individual */ + /* segments and Bezier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means sucess. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Creates a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will NOT necessarily be FREED, when */ + /* destroying the library, by FT_Done_FreeType(). */ + /* */ + /* numPoints :: The maximal number of points within the outline. */ + /* */ + /* numContours :: The maximal number of contours within the outline. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. NULL in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroys an outline created with FT_Outline_New(). */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use FT_Free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Returns an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bezier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bezier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Applies a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copies an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Applies a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use FT_Outline_Translate() if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( FT_Outline* outline, + FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverses the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This functions toggles the bit flag `FT_OUTLINE_REVERSE_FILL' in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Renders an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! */ + /* */ + /* It will use the raster correponding to the default glyph format. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Renders an outline within a bitmap using the current scan-convert. */ + /* This functions uses an FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to a FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOUTLN_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftpfr.h b/lib/freetype/include/freetype/ftpfr.h new file mode 100644 index 0000000..2125391 --- /dev/null +++ b/lib/freetype/include/freetype/ftpfr.h @@ -0,0 +1,156 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data */ +/* */ +/* Copyright 2002 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 __FTPFR_H__ +#define __FTPFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific APIs */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * returns the outline and metrics resolutions of a given PFR + * face. + * + * @input: + * face :: handle to input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * outline resolution. This is equivalent to "face->units_per_EM". + * optional (parameter can be NULL) + * + * ametrics_resolution :: + * metrics_resolution. This is equivalent to "outline_resolution" + * for non-PFR fonts. can be NULL + * optional (parameter can be NULL) + * + * ametrics_x_scale :: + * a 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * 'face->size->x_scale', but for metrics only. + * optional (parameter can be NULL) + * + * ametrics_y_scale :: + * same as 'ametrics_x_scale', but for the vertical direction. + * optional (parameter can be NULL) + * + * @note: + * if the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * returns the kerning pair corresponding to two glyphs in + * a PFR face. The distance is expressed in metrics units, unlike + * the result of @FT_Get_Kerning. + * + * @input: + * face :: handle to input face. + * left :: left glyph index + * right :: right glyph index + * + * @output: + * avector :: kerning vector + * + * @note: + * this function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always return distances converted to outline units. + * + * you can use the value of the 'x_scale' and 'y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * returns a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: handle to input face. + * gindex :: glyph index + * + * @output: + * aadvance :: glyph advance in metrics units + * + * @return: + * error code. 0 means success + * + * @note: + * you can use the 'x_scale' or 'y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e. 1/64th of pixels) + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftrender.h b/lib/freetype/include/freetype/ftrender.h new file mode 100644 index 0000000..db3ca94 --- /dev/null +++ b/lib/freetype/include/freetype/ftrender.h @@ -0,0 +1,229 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTRENDER_H__ +#define __FTRENDER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_Matrix* matrix, + FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For `FT_GLYPH_FORMAT_OUTLINE' renderers only, this */ + /* is a pointer to its raster's class. */ + /* */ + /* raster :: For `FT_GLYPH_FORMAT_OUTLINE' renderers only. this */ + /* is a pointer to the corresponding raster object, */ + /* if any. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieves the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0 if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use FT_Add_Module(). To retrieve a */ + /* renderer by its name, use FT_Get_Module(). */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Sets the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTRENDER_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftsizes.h b/lib/freetype/include/freetype/ftsizes.h new file mode 100644 index 0000000..0fd6f0f --- /dev/null +++ b/lib/freetype/include/freetype/ftsizes.h @@ -0,0 +1,151 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSIZES_H__ +#define __FTSIZES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g. with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the "face->size" */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current "active" size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Creates a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discards a given size object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the last-created one to */ + /* determine the "current character pixel size". */ + /* */ + /* This function can be used to "activate" a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If "face" is the size's parent face object, this function changes */ + /* the value of "face->size" to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSIZES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftsnames.h b/lib/freetype/include/freetype/ftsnames.h new file mode 100644 index 0000000..356f983 --- /dev/null +++ b/lib/freetype/include/freetype/ftsnames.h @@ -0,0 +1,161 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002 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 __FT_SFNT_NAMES_H__ +#define __FT_SFNT_NAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specification allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc.. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details.. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieves the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieves a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. */ + /* */ + /* Use FT_Get_Sfnt_Name_Count() to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FT_SFNT_NAMES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftstroker.h b/lib/freetype/include/freetype/ftstroker.h new file mode 100644 index 0000000..a714056 --- /dev/null +++ b/lib/freetype/include/freetype/ftstroker.h @@ -0,0 +1,139 @@ +#ifndef __FT_STROKER_H__ +#define __FT_STROKER_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H + +FT_BEGIN_HEADER + +/*@************************************************************* + * + * @type: FT_Stroker + * + * @description: + * opaque handler to a path stroker object + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + +/*@************************************************************* + * + * @enum: FT_Stroker_LineJoin + * + * @description: + * these values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * used to render rounded line joins. circular arcs are used + * to join two lines smoothly + * + * FT_STROKER_LINEJOIN_BEVEL :: + * used to render beveled line joins; i.e. the two joining lines + * are extended until they intersect + * + * FT_STROKER_LINEJOIN_MITER :: + * same as beveled rendering, except that an additional line + * break is added if the angle between the two joining lines + * is too closed (this is useful to avoid unpleasant spikes + * in beveled rendering). + */ + typedef enum + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL, + FT_STROKER_LINEJOIN_MITER + + } FT_Stroker_LineJoin; + + +/*@************************************************************* + * + * @enum: FT_Stroker_LineCap + * + * @description: + * these values determine how the end of opened sub-paths are + * rendered in a stroke + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * the end of lines is rendered as a full stop on the last + * point itself + * + * FT_STROKER_LINECAP_ROUND :: + * the end of lines is rendered as a half-circle around the + * last point + * + * FT_STROKER_LINECAP_SQUARE :: + * the end of lines is rendered as a square around the + * last point + */ + typedef enum + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + /* */ + + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Memory memory, + FT_Stroker *astroker ); + + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + +FT_END_HEADER + +#endif /* __FT_STROKER_H__ */ diff --git a/lib/freetype/include/freetype/ftsynth.h b/lib/freetype/include/freetype/ftsynth.h new file mode 100644 index 0000000..2424ff6 --- /dev/null +++ b/lib/freetype/include/freetype/ftsynth.h @@ -0,0 +1,65 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE, THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTSYNTH_H__ +#define __FTSYNTH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* This code is completely experimental -- use with care! */ + /* It will probably be completely rewritten in the future */ + /* or even integrated into the library. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + +FT_END_HEADER + +#endif /* __FTSYNTH_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftsysio.h b/lib/freetype/include/freetype/ftsysio.h new file mode 100644 index 0000000..f8e4954 --- /dev/null +++ b/lib/freetype/include/freetype/ftsysio.h @@ -0,0 +1,195 @@ +#ifndef __FT_SYSTEM_IO_H__ +#define __FT_SYSTEM_IO_H__ + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** NOTE: THE CONTENT OF THIS FILE IS NOT CURRENTLY USED *****/ + /***** IN NORMAL BUILDS. CONSIDER IT EXPERIMENTAL. *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + /******************************************************************** + * + * designing custom streams is a bit different now + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECT_H + +FT_BEGIN_HEADER + + /*@******************************************************************* + * + * @type: FT_Stream + * + * @description: + * handle to an input stream object. These are also @FT_Object handles + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /*@******************************************************************* + * + * @type: FT_Stream_Class + * + * @description: + * opaque handle to a @FT_Stream_ClassRec class structure describing + * the methods of input streams + */ + typedef const struct FT_Stream_ClassRec_* FT_Stream_Class; + + + /*@******************************************************************* + * + * @functype: FT_Stream_ReadFunc + * + * @description: + * a method used to read bytes from an input stream into memory + * + * @input: + * stream :: target stream handle + * buffer :: target buffer address + * size :: number of bytes to read + * + * @return: + * number of bytes effectively read. Must be <= 'size'. + */ + typedef FT_ULong (*FT_Stream_ReadFunc)( FT_Stream stream, + FT_Byte* buffer, + FT_ULong size ); + + + /*@******************************************************************* + * + * @functype: FT_Stream_SeekFunc + * + * @description: + * a method used to seek to a new position within a stream + * + * @input: + * stream :: target stream handle + * pos :: new read position, from start of stream + * + * @return: + * error code. 0 means success + */ + typedef FT_Error (*FT_Stream_SeekFunc)( FT_Stream stream, + FT_ULong pos ); + + + /*@******************************************************************* + * + * @struct: FT_Stream_ClassRec + * + * @description: + * a structure used to describe an input stream class + * + * @input: + * clazz :: root @FT_ClassRec fields + * stream_read :: stream byte read method + * stream_seek :: stream seek method + */ + typedef struct FT_Stream_ClassRec_ + { + FT_ClassRec clazz; + FT_Stream_ReadFunc stream_read; + FT_Stream_SeekFunc stream_seek; + + } FT_Stream_ClassRec; + + /* */ + +#define FT_STREAM_CLASS(x) ((FT_Stream_Class)(x)) +#define FT_STREAM_CLASS__READ(x) FT_STREAM_CLASS(x)->stream_read +#define FT_STREAM_CLASS__SEEK(x) FT_STREAM_CLASS(x)->stream_seek; + + /*@******************************************************************* + * + * @struct: FT_StreamRec + * + * @description: + * the input stream object structure. See @FT_Stream_ClassRec for + * its class descriptor + * + * @fields: + * object :: root @FT_ObjectRec fields + * size :: size of stream in bytes (0 if unknown) + * pos :: current position within stream + * base :: for memory-based streams, the address of the stream's + * first data byte in memory. NULL otherwise + * + * cursor :: the current cursor position within an input stream + * frame. Only valid within a FT_FRAME_ENTER .. FT_FRAME_EXIT + * block; NULL otherwise + * + * limit :: the current frame limit within a FT_FRAME_ENTER .. + * FT_FRAME_EXIT block. NULL otherwise + */ + typedef struct FT_StreamRec_ + { + FT_ObjectRec object; + FT_ULong size; + FT_ULong pos; + const FT_Byte* base; + const FT_Byte* cursor; + const FT_Byte* limit; + + } FT_StreamRec; + + /* some useful macros */ +#define FT_STREAM(x) ((FT_Stream)(x)) +#define FT_STREAM_P(x) ((FT_Stream*)(x)) + +#define FT_STREAM__READ(x) FT_STREAM_CLASS__READ(FT_OBJECT__CLASS(x)) +#define FT_STREAM__SEEK(x) FT_STREAM_CLASS__SEEK(FT_OBJECT__CLASS(x)) + +#define FT_STREAM_IS_BASED(x) ( FT_STREAM(x)->base != NULL ) + + /* */ + + /* create new memory-based stream */ + FT_BASE( FT_Error ) ft_stream_new_memory( const FT_Byte* stream_base, + FT_ULong stream_size, + FT_Memory memory, + FT_Stream *astream ); + + FT_BASE( FT_Error ) ft_stream_new_iso( const char* pathanme, + FT_Memory memory, + FT_Stream *astream ); + + + /* handle to default stream class implementation for a given build */ + /* this is used by "FT_New_Face" */ + /* */ + FT_APIVAR( FT_Type ) ft_stream_default_type; + +FT_END_HEADER + +#endif /* __FT_SYSTEM_STREAM_H__ */ diff --git a/lib/freetype/include/freetype/ftsysmem.h b/lib/freetype/include/freetype/ftsysmem.h new file mode 100644 index 0000000..8de0c4d --- /dev/null +++ b/lib/freetype/include/freetype/ftsysmem.h @@ -0,0 +1,202 @@ +#ifndef __FT_SYSTEM_MEMORY_H__ +#define __FT_SYSTEM_MEMORY_H__ + +#include <ft2build.h> + +FT_BEGIN_HEADER + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** NOTE: THE CONTENT OF THIS FILE IS NOT CURRENTLY USED *****/ + /***** IN NORMAL BUILDS. CONSIDER IT EXPERIMENTAL. *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + /*@********************************************************************** + * + * @type: FT_Memory + * + * @description: + * opaque handle to a memory manager handle. Note that since FreeType + * 2.2, the memory manager structure FT_MemoryRec is hidden to client + * applications. + * + * however, you can still define custom allocators easily using the + * @ft_memory_new API + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /*@********************************************************************** + * + * @functype: FT_Memory_AllocFunc + * + * @description: + * a function used to allocate a block of memory. + * + * @input: + * size :: size of blocks in bytes. Always > 0 !! + * mem_data :: memory-manager specific optional argument + * (see @ft_memory_new) + * + * @return: + * address of new block. NULL in case of memory exhaustion + */ + typedef FT_Pointer (*FT_Memory_AllocFunc)( FT_ULong size, + FT_Pointer mem_data ); + + + /*@********************************************************************** + * + * @functype: FT_Memory_FreeFunc + * + * @description: + * a function used to release a block of memory created through + * @FT_Memory_AllocFunc or @FT_Memory_ReallocFunc + * + * @input: + * block :: address of target memory block. cannot be NULL !! + * mem_data :: memory-manager specific optional argument + * (see @ft_memory_new) + */ + typedef void (*FT_Memory_FreeFunc) ( FT_Pointer block, + FT_Pointer mem_data ); + + + /*@********************************************************************** + * + * @functype: FT_Memory_ReallocFunc + * + * @description: + * a function used to reallocate a memory block. + * + * @input: + * block :: address of target memory block. cannot be NULL !! + * new_size :: new requested size in bytes + * cur_size :: current block size in bytes + * mem_data :: memory-manager specific optional argument + * (see @ft_memory_new) + */ + typedef FT_Pointer (*FT_Memory_ReallocFunc)( FT_Pointer block, + FT_ULong new_size, + FT_ULong cur_size, + FT_Pointer mem_data ); + + + /*@********************************************************************** + * + * @functype: FT_Memory_CreateFunc + * + * @description: + * a function used to create a @FT_Memory object to model a + * memory manager + * + * @input: + * size :: size of memory manager structure in bytes + * init_data :: optional initialisation argument + * + * @output: + * amem_data :: memory-manager specific argument to block management + * routines. + * + * @return: + * handle to new memory manager object. NULL in case of failure + */ + typedef FT_Pointer (*FT_Memory_CreateFunc)( FT_UInt size, + FT_Pointer init_data, + FT_Pointer *amem_data ); + + + /*@********************************************************************** + * + * @functype: FT_Memory_DestroyFunc + * + * @description: + * a function used to destroy a given @FT_Memory manager + * + * @input: + * memory :: target memory manager handle + * mem_data :: option manager-specific argument + */ + typedef void (*FT_Memory_DestroyFunc)( FT_Memory memory, + FT_Pointer mem_data ); + + + /*@********************************************************************** + * + * @struct: FT_Memory_FuncsRec + * + * @description: + * a function used to hold all methods of a given memory manager + * implementation. + * + * @fields: + * mem_alloc :: block allocation routine + * mem_free :: block release routine + * mem_realloc :: block re-allocation routine + * mem_create :: manager creation routine + * mem_destroy :: manager destruction routine + */ + typedef struct FT_Memory_FuncsRec_ + { + FT_Memory_AllocFunc mem_alloc; + FT_Memory_FreeFunc mem_free; + FT_Memory_ReallocFunc mem_realloc; + FT_Memory_CreateFunc mem_create; + FT_Memory_DestroyFunc mem_destroy; + + } FT_Memory_FuncsRec, *FT_Memory_Funcs; + + + /*@********************************************************************** + * + * @type: FT_Memory_Funcs + * + * @description: + * a pointer to a constant @FT_Memory_FuncsRec structure used to + * describe a given memory manager implementation. + */ + typedef const FT_Memory_FuncsRec* FT_Memory_Funcs; + + + /*@********************************************************************** + * + * @function: ft_memory_new + * + * @description: + * create a new memory manager, given a set of memory methods + * + * @input: + * mem_funcs :: handle to memory manager implementation descriptor + * mem_init_data :: optional initialisation argument, passed to + * @FT_Memory_CreateFunc + * + * @return: + * new memory manager handle. NULL in case of failure + */ + FT_BASE( FT_Memory ) + ft_memory_new( FT_Memory_Funcs mem_funcs, + FT_Pointer mem_init_data ); + + + /*@********************************************************************** + * + * @function: ft_memory_destroy + * + * @description: + * destroy a given memory manager + * + * @input: + * memory :: handle to target memory manager + */ + FT_BASE( void ) + ft_memory_destroy( FT_Memory memory ); + +/* */ + +FT_END_HEADER + +#endif /* __FT_SYSTEM_MEMORY_H__ */ diff --git a/lib/freetype/include/freetype/ftsystem.h b/lib/freetype/include/freetype/ftsystem.h new file mode 100644 index 0000000..d1c55f7 --- /dev/null +++ b/lib/freetype/include/freetype/ftsystem.h @@ -0,0 +1,309 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTSYSTEM_H__ +#define __FTSYSTEM_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* input i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @type: */ + /* FT_Memory */ + /* */ + /* @description: */ + /* A handle to a given memory manager object, defined with a */ + /* @FT_MemoryRec structure. */ + /* */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* FT_Alloc_Func */ + /* */ + /* @description: */ + /* A function used to allocate `size' bytes from `memory'. */ + /* */ + /* @input: */ + /* memory :: A handle to the source memory manager. */ + /* */ + /* size :: The size in bytes to allocate. */ + /* */ + /* @return: */ + /* Address of new memory block. 0 in case of failure. */ + /* */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* FT_Free_Func */ + /* */ + /* @description: */ + /* A function used to release a given block of memory. */ + /* */ + /* @input: */ + /* memory :: A handle to the source memory manager. */ + /* */ + /* block :: The address of the target memory block. */ + /* */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* FT_Realloc_Func */ + /* */ + /* @description: */ + /* a function used to re-allocate a given block of memory. */ + /* */ + /* @input: */ + /* memory :: A handle to the source memory manager. */ + /* */ + /* cur_size :: The block's current size in bytes. */ + /* */ + /* new_size :: The block's requested new size. */ + /* */ + /* block :: The block's current address. */ + /* */ + /* @return: */ + /* New block address. 0 in case of memory shortage. */ + /* */ + /* @note: */ + /* In case of error, the old block must still be available. */ + /* */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* FT_MemoryRec */ + /* */ + /* @description: */ + /* A structure used to describe a given memory manager to FreeType 2. */ + /* */ + /* @fields: */ + /* user :: A generic typeless pointer for user data. */ + /* */ + /* alloc :: A pointer type to an allocation function. */ + /* */ + /* free :: A pointer type to an memory freeing function. */ + /* */ + /* realloc :: A pointer type to a reallocation function. */ + /* */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @type: */ + /* FT_Stream */ + /* */ + /* @description: */ + /* A handle to an input stream. */ + /* */ + typedef struct FT_StreamRec_* FT_Stream; + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* FT_StreamDesc */ + /* */ + /* @description: */ + /* A union type used to store either a long or a pointer. This is */ + /* used to store a file descriptor or a FILE* in an input stream. */ + /* */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* FT_Stream_IoFunc */ + /* */ + /* @description: */ + /* A function used to seek and read data from a given input stream. */ + /* */ + /* @input: */ + /* stream :: A handle to the source stream. */ + /* */ + /* offset :: The offset of read in stream (always from start). */ + /* */ + /* buffer :: The address of the read buffer. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* @return: */ + /* The number of bytes effectively read by the stream. */ + /* */ + /* @note: */ + /* This function might be called to perform a seek or skip operation */ + /* with a `count' of 0. */ + /* */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* FT_Stream_CloseFunc */ + /* */ + /* @description: */ + /* A function used to close a given input stream. */ + /* */ + /* @input: */ + /* stream :: A handle to the target stream. */ + /* */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* FT_StreamRec */ + /* */ + /* @description: */ + /* A structure used to describe an input stream. */ + /* */ + /* @input: */ + /* base :: For memory-based streams, this is the address of the */ + /* first stream byte in memory. This field should */ + /* always be set to NULL for disk-based streams. */ + /* */ + /* size :: The stream size in bytes. */ + /* */ + /* pos :: The current position within the stream. */ + /* */ + /* descriptor :: This field is a union that can hold an integer or a */ + /* pointer. It is used by stream implementations to */ + /* store file descriptors or FILE* pointers. */ + /* */ + /* pathname :: This field is completely ignored by FreeType. */ + /* However, it is often useful during debugging to use */ + /* it to store the stream's filename (where available). */ + /* */ + /* read :: The stream's input function. */ + /* */ + /* close :: The stream;s close function. */ + /* */ + /* memory :: The memory manager to use to preload frames. This is */ + /* set internally by FreeType and shouldn't be touched */ + /* by stream implementations. */ + /* */ + /* cursor :: This field is set and used internally by FreeType */ + /* when parsing frames. */ + /* */ + /* limit :: This field is set and used internally by FreeType */ + /* when parsing frames. */ + /* */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYSTEM_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/fttrigon.h b/lib/freetype/include/freetype/fttrigon.h new file mode 100644 index 0000000..3b8257b --- /dev/null +++ b/lib/freetype/include/freetype/fttrigon.h @@ -0,0 +1,325 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001 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 __FTTRIGON_H__ +#define __FTTRIGON_H__ + +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* @section: */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @type: */ + /* FT_Angle */ + /* */ + /* @description: */ + /* This type is used to model angle values in FreeType. Note that */ + /* the angle is a 16.16 fixed float value expressed in degrees. */ + /* */ + typedef FT_Fixed FT_Angle; + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ANGLE_PI */ + /* */ + /* @description: */ + /* The angle pi expressed in @FT_Angle units. */ + /* */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ANGLE_2PI */ + /* */ + /* @description: */ + /* The angle 2*pi expressed in @FT_Angle units. */ + /* */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ANGLE_PI2 */ + /* */ + /* @description: */ + /* The angle pi/2 expressed in @FT_Angle units. */ + /* */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ANGLE_PI4 */ + /* */ + /* @description: */ + /* The angle pi/4 expressed in @FT_Angle units. */ + /* */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Sin */ + /* */ + /* @description: */ + /* Return the sinus of a given angle in fixed point format. */ + /* */ + /* @input: */ + /* angle :: The input angle. */ + /* */ + /* @return: */ + /* The sinus value. */ + /* */ + /* @note: */ + /* If you need both the sinus and cosinus for a given angle, use the */ + /* function @FT_Vector_Unit. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Cos */ + /* */ + /* @description: */ + /* Return the cosinus of a given angle in fixed point format. */ + /* */ + /* @input: */ + /* angle :: The input angle. */ + /* */ + /* @return: */ + /* The cosinus value. */ + /* */ + /* @note: */ + /* If you need both the sinus and cosinus for a given angle, use the */ + /* function @FT_Vector_Unit. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Tan */ + /* */ + /* @description: */ + /* Return the tangent of a given angle in fixed point format. */ + /* */ + /* @input: */ + /* angle :: The input angle. */ + /* */ + /* @return: */ + /* The tangent value. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Atan2 */ + /* */ + /* @description: */ + /* Return the arc-tangent corresponding to a given vector (x,y) in */ + /* the 2d plane. */ + /* */ + /* @input: */ + /* x :: The horizontal vector coordinate. */ + /* */ + /* y :: The vertical vector coordinate. */ + /* */ + /* @return: */ + /* The arc-tangent value (i.e. angle). */ + /* */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Angle_Diff */ + /* */ + /* @description: */ + /* Return the difference between two angles. The result is always */ + /* constrained to the ]-PI..PI] interval. */ + /* */ + /* @input: */ + /* angle1 :: First angle. */ + /* */ + /* angle2 :: Second angle. */ + /* */ + /* @return: */ + /* Contrainted value of `value2-value1'. */ + /* */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_Unit */ + /* */ + /* @description: */ + /* Return the unit vector corresponding to a given angle. After the */ + /* call, the value of `vec.x' will be `sin(angle)', and the value of */ + /* `vec.y' will be `cos(angle)'. */ + /* */ + /* This function is useful to retrieve both the sinus and cosinus of */ + /* a given angle quickly. */ + /* */ + /* @output: */ + /* vec :: The address of target vector. */ + /* */ + /* @input: */ + /* angle :: The address of angle. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_Rotate */ + /* */ + /* @description: */ + /* Rotate a vector by a given angle. */ + /* */ + /* @inout: */ + /* vec :: The address of target vector. */ + /* */ + /* @input: */ + /* angle :: The address of angle. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_Length */ + /* */ + /* @description: */ + /* Return the length of a given vector. */ + /* */ + /* @input: */ + /* vec :: The address of target vector. */ + /* */ + /* @return: */ + /* The vector length, expressed in the same units that the original */ + /* vector coordinates. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_Normalize */ + /* */ + /* @description: */ + /* Normalize a given vector (i.e. compute the equivalent unit */ + /* vector). */ + /* */ + /* @inout: */ + /* vec :: The address of target vector. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Normalize( FT_Vector* vec ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_Polarize */ + /* */ + /* @description: */ + /* Compute both the length and angle of a given vector. */ + /* */ + /* @input: */ + /* vec :: The address of source vector. */ + /* */ + /* @output: */ + /* length :: The vector length. */ + /* angle :: The vector angle. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /*************************************************************************/ + /* */ + /* @function: */ + /* FT_Vector_From_Polar */ + /* */ + /* @description: */ + /* Compute vector coordinates from a length and angle. */ + /* */ + /* @output: */ + /* vec :: The address of source vector. */ + /* */ + /* @input: */ + /* length :: The vector length. */ + /* angle :: The vector angle. */ + /* */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTTRIGON_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/fttypes.h b/lib/freetype/include/freetype/fttypes.h new file mode 100644 index 0000000..2782f74 --- /dev/null +++ b/lib/freetype/include/freetype/fttypes.h @@ -0,0 +1,558 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2001 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 __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType 2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed float type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed float type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed float values, like scales */ + /* or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of 0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI C `size_t' type, i.e. the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI C `ptrdiff_t' type, i.e. the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef size_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed float format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describes a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object which is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Most FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four letter tags which are used to label */ + /* TrueType tables into an unsigned long to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32bit integers. Don't redefine this */ + /* macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through a */ + /* FT_List record (see FT_ListRec). As its name suggests, a */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + + /* */ + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) + + /* return base error code (without module-specific prefix) */ +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) + + /* return module error code */ +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftwinfnt.h b/lib/freetype/include/freetype/ftwinfnt.h new file mode 100644 index 0000000..6d29fe1 --- /dev/null +++ b/lib/freetype/include/freetype/ftwinfnt.h @@ -0,0 +1,129 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2002 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 __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Fonts */ + /* */ + /* <Abstract> */ + /* Windows FNT specific APIs */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec_ */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec, *FT_WinFNT_Header; + + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieves a Windows FNT font info header. + * + * @input: + * face :: handle to input face + * + * @output: + * header :: WinFNT header. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function only works with Windows FNT faces, returning an erro + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ); + + /* */ + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ftxf86.h b/lib/freetype/include/freetype/ftxf86.h new file mode 100644 index 0000000..5a7582f --- /dev/null +++ b/lib/freetype/include/freetype/ftxf86.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* ftxf86.h */ +/* */ +/* Support functions for X11. */ +/* */ +/* Copyright 2002 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 __FTXF86_H__ +#define __FTXF86_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + /* this comment is intentionally disabled for now, to prevent this */ + /* function from appearing in the API Reference. */ + + /*@***********************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_X11_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face as an X11 */ + /* FONT_PROPERTY. It should only be used by the FreeType 2 font */ + /* backend of the XFree86 font server. */ + /* */ + /* <Input> */ + /* face :: Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + FT_EXPORT_DEF( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + /* */ + +FT_END_HEADER + +#endif /* __FTXF86_H__ */ diff --git a/lib/freetype/include/freetype/internal/autohint.h b/lib/freetype/include/freetype/internal/autohint.h new file mode 100644 index 0000000..22340af --- /dev/null +++ b/lib/freetype/include/freetype/internal/autohint.h @@ -0,0 +1,205 @@ +/***************************************************************************/ +/* */ +/* autohint.h */ +/* */ +/* High-level `autohint' module-specific interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 auto-hinter is used to load and automatically hint glyphs if a */ + /* format-specific hinter isn't available. */ + /* */ + /*************************************************************************/ + + +#ifndef __AUTOHINT_H__ +#define __AUTOHINT_H__ + + + /*************************************************************************/ + /* */ + /* A small technical note regarding automatic hinting in order to */ + /* clarify this module interface. */ + /* */ + /* An automatic hinter might compute two kinds of data for a given face: */ + /* */ + /* - global hints: Usually some metrics that describe global properties */ + /* of the face. It is computed by scanning more or less */ + /* agressively the glyphs in the face, and thus can be */ + /* very slow to compute (even if the size of global */ + /* hints is really small). */ + /* */ + /* - glyph hints: These describe some important features of the glyph */ + /* outline, as well as how to align them. They are */ + /* generally much faster to compute than global hints. */ + /* */ + /* The current FreeType auto-hinter does a pretty good job while */ + /* performing fast computations for both global and glyph hints. */ + /* However, we might be interested in introducing more complex and */ + /* powerful algorithms in the future, like the one described in the John */ + /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ + /* */ + /* Because a sufficiently sophisticated font management system would */ + /* typically implement an LRU cache of opened face objects to reduce */ + /* memory usage, it is a good idea to be able to avoid recomputing */ + /* global hints every time the same face is re-opened. */ + /* */ + /* We thus provide the ability to cache global hints outside of the face */ + /* object, in order to speed up font re-opening time. Of course, this */ + /* feature is purely optional, so most client programs won't even notice */ + /* it. */ + /* */ + /* I initially thought that it would be a good idea to cache the glyph */ + /* hints too. However, my general idea now is that if you really need */ + /* to cache these too, you are simply in need of a new font format, */ + /* where all this information could be stored within the font file and */ + /* decoded on the fly. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct FT_AutoHinterRec_ *FT_AutoHinter; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalGetFunc */ + /* */ + /* <Description> */ + /* Retrieves the global hints computed for a given face object the */ + /* resulting data is dissociated from the face and will survive a */ + /* call to FT_Done_Face(). It must be discarded through the API */ + /* FT_AutoHinter_GlobalDoneFunc(). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* global_hints :: A typeless pointer to the global hints. */ + /* */ + /* global_len :: The size in bytes of the global hints. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalDoneFunc */ + /* */ + /* <Description> */ + /* Discards the global hints retrieved through */ + /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ + /* are freed from memory. */ + /* */ + /* <Input> */ + /* hinter :: A handle to the auto-hinter module. */ + /* */ + /* global :: A pointer to retrieved global hints to discard. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, + void* global ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalResetFunc */ + /* */ + /* <Description> */ + /* This function is used to recompute the global metrics in a given */ + /* font. This is useful when global font data changes (e.g. Multiple */ + /* Masters fonts where blend coordinates change). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the face. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, + FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlyphLoadFunc */ + /* */ + /* <Description> */ + /* This function is used to load, scale, and automatically hint a */ + /* glyph from a given face. */ + /* */ + /* <Input> */ + /* face :: A handle to the face. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* load_flags :: The load flags. */ + /* */ + /* <Note> */ + /* This function is capable of loading composite glyphs by hinting */ + /* each sub-glyph independently (which improves quality). */ + /* */ + /* It will call the font driver with FT_Load_Glyph(), with */ + /* FT_LOAD_NO_SCALE set. */ + /* */ + typedef FT_Error + (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_AutoHinter_ServiceRec */ + /* */ + /* <Description> */ + /* The auto-hinter module's interface. */ + /* */ + typedef struct FT_AutoHinter_ServiceRec_ + { + FT_AutoHinter_GlobalResetFunc reset_face; + FT_AutoHinter_GlobalGetFunc get_global_hints; + FT_AutoHinter_GlobalDoneFunc done_global_hints; + FT_AutoHinter_GlyphLoadFunc load_glyph; + + } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; + + +FT_END_HEADER + +#endif /* __AUTOHINT_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/bdftypes.h b/lib/freetype/include/freetype/internal/bdftypes.h new file mode 100644 index 0000000..3a1ec64 --- /dev/null +++ b/lib/freetype/include/freetype/internal/bdftypes.h @@ -0,0 +1,58 @@ +/* bdftypes.h + + FreeType font driver for bdf fonts + + Copyright (C) 2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __BDFTYPES_H__ +#define __BDFTYPES_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_BDF_H + + +FT_BEGIN_HEADER + + + typedef struct BDF_Public_FaceRec_ + { + FT_FaceRec root; + + char* charset_encoding; + char* charset_registry; + + } BDF_Public_FaceRec, *BDF_Public_Face; + + + typedef FT_Error (*BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + +FT_END_HEADER + + +#endif /* __BDFTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/cfftypes.h b/lib/freetype/include/freetype/internal/cfftypes.h new file mode 100644 index 0000000..82e1e91 --- /dev/null +++ b/lib/freetype/include/freetype/internal/cfftypes.h @@ -0,0 +1,256 @@ +/***************************************************************************/ +/* */ +/* cfftypes.h */ +/* */ +/* Basic OpenType/CFF type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFTYPES_H__ +#define __CFFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CFF_IndexRec */ + /* */ + /* <Description> */ + /* A structure used to model a CFF Index table. */ + /* */ + /* <Fields> */ + /* stream :: The source input stream. */ + /* */ + /* count :: The number of elements in the index. */ + /* */ + /* off_size :: The size in bytes of object offsets in index. */ + /* */ + /* data_offset :: The position of first data byte in the index's */ + /* bytes. */ + /* */ + /* offsets :: A table of element offsets in the index. */ + /* */ + /* bytes :: If the index is loaded in memory, its bytes. */ + /* */ + typedef struct CFF_IndexRec_ + { + FT_Stream stream; + FT_UInt count; + FT_Byte off_size; + FT_ULong data_offset; + + FT_ULong* offsets; + FT_Byte* bytes; + + } CFF_IndexRec, *CFF_Index; + + + typedef struct CFF_EncodingRec_ + { + FT_UInt format; + FT_ULong offset; + + FT_UInt count; + FT_UShort sids [256]; /* avoid dynamic allocations */ + FT_UShort codes[256]; + + } CFF_EncodingRec, *CFF_Encoding; + + + typedef struct CFF_CharsetRec_ + { + + FT_UInt format; + FT_ULong offset; + + FT_UShort* sids; + + } CFF_CharsetRec, *CFF_Charset; + + + typedef struct CFF_FontRecDictRec_ + { + FT_UInt version; + FT_UInt notice; + FT_UInt copyright; + FT_UInt full_name; + FT_UInt family_name; + FT_UInt weight; + FT_Bool is_fixed_pitch; + FT_Fixed italic_angle; + FT_Pos underline_position; + FT_Pos underline_thickness; + FT_Int paint_type; + FT_Int charstring_type; + FT_Matrix font_matrix; + FT_UShort units_per_em; + FT_Vector font_offset; + FT_ULong unique_id; + FT_BBox font_bbox; + FT_Pos stroke_width; + FT_ULong charset_offset; + FT_ULong encoding_offset; + FT_ULong charstrings_offset; + FT_ULong private_offset; + FT_ULong private_size; + FT_Long synthetic_base; + FT_UInt embedded_postscript; + FT_UInt base_font_name; + FT_UInt postscript; + + /* these should only be used for the top-level font dictionary */ + FT_UInt cid_registry; + FT_UInt cid_ordering; + FT_ULong cid_supplement; + + FT_Long cid_font_version; + FT_Long cid_font_revision; + FT_Long cid_font_type; + FT_Long cid_count; + FT_ULong cid_uid_base; + FT_ULong cid_fd_array_offset; + FT_ULong cid_fd_select_offset; + FT_UInt cid_font_name; + + } CFF_FontRecDictRec, *CFF_FontRecDict; + + + typedef struct CFF_PrivateRec_ + { + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Pos blue_values[14]; + FT_Pos other_blues[10]; + FT_Pos family_blues[14]; + FT_Pos family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Pos blue_shift; + FT_Pos blue_fuzz; + FT_Pos standard_width; + FT_Pos standard_height; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Pos snap_widths[13]; + FT_Pos snap_heights[13]; + FT_Bool force_bold; + FT_Fixed force_bold_threshold; + FT_Int lenIV; + FT_Int language_group; + FT_Fixed expansion_factor; + FT_Long initial_random_seed; + FT_ULong local_subrs_offset; + FT_Pos default_width; + FT_Pos nominal_width; + + } CFF_PrivateRec, *CFF_Private; + + + typedef struct CFF_FDSelectRec_ + { + FT_Byte format; + FT_UInt range_count; + + /* that's the table, taken from the file `as is' */ + FT_Byte* data; + FT_UInt data_size; + + /* small cache for format 3 only */ + FT_UInt cache_first; + FT_UInt cache_count; + FT_Byte cache_fd; + + } CFF_FDSelectRec, *CFF_FDSelect; + + + /* A SubFont packs a font dict and a private dict together. They are */ + /* needed to support CID-keyed CFF fonts. */ + typedef struct CFF_SubFontRec_ + { + CFF_FontRecDictRec font_dict; + CFF_PrivateRec private_dict; + + CFF_IndexRec local_subrs_index; + FT_UInt num_local_subrs; + FT_Byte** local_subrs; + + } CFF_SubFontRec, *CFF_SubFont; + + + /* maximum number of sub-fonts in a CID-keyed file */ +#define CFF_MAX_CID_FONTS 16 + + + typedef struct CFF_FontRec_ + { + FT_Stream stream; + FT_Memory memory; + FT_UInt num_faces; + FT_UInt num_glyphs; + + FT_Byte version_major; + FT_Byte version_minor; + FT_Byte header_size; + FT_Byte absolute_offsize; + + + CFF_IndexRec name_index; + CFF_IndexRec top_dict_index; + CFF_IndexRec string_index; + CFF_IndexRec global_subrs_index; + + CFF_EncodingRec encoding; + CFF_CharsetRec charset; + + CFF_IndexRec charstrings_index; + CFF_IndexRec font_dict_index; + CFF_IndexRec private_index; + CFF_IndexRec local_subrs_index; + + FT_String* font_name; + FT_UInt num_global_subrs; + FT_Byte** global_subrs; + + CFF_SubFontRec top_font; + FT_UInt num_subfonts; + CFF_SubFont subfonts[CFF_MAX_CID_FONTS]; + + CFF_FDSelectRec fd_select; + + /* interface to PostScript hinter */ + void* pshinter; + + /* interface to Postscript Names service */ + void* psnames; + + } CFF_FontRec, *CFF_Font; + + +FT_END_HEADER + +#endif /* __CFFTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/fnttypes.h b/lib/freetype/include/freetype/internal/fnttypes.h new file mode 100644 index 0000000..a85d6ab --- /dev/null +++ b/lib/freetype/include/freetype/internal/fnttypes.h @@ -0,0 +1,114 @@ +/***************************************************************************/ +/* */ +/* fnttypes.h */ +/* */ +/* Basic Windows FNT/FON type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FNTTYPES_H__ +#define __FNTTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_WINFONTS_H + + +FT_BEGIN_HEADER + + + typedef struct WinMZ_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort lfanew; + + } WinMZ_HeaderRec; + + + typedef struct WinNE_HeaderRec_ + { + FT_UShort magic; + /* skipped content */ + FT_UShort resource_tab_offset; + FT_UShort rname_tab_offset; + + } WinNE_HeaderRec; + + + typedef struct WinNameInfoRec_ + { + FT_UShort offset; + FT_UShort length; + FT_UShort flags; + FT_UShort id; + FT_UShort handle; + FT_UShort usage; + + } WinNameInfoRec; + + + typedef struct WinResourceInfoRec_ + { + FT_UShort type_id; + FT_UShort count; + + } WinResourceInfoRec; + + +#define WINFNT_MZ_MAGIC 0x5A4D +#define WINFNT_NE_MAGIC 0x454E + + + typedef struct FNT_FontRec_ + { + FT_ULong offset; + FT_Int size_shift; + + FT_WinFNT_HeaderRec header; + + FT_Byte* fnt_frame; + FT_ULong fnt_size; + + } FNT_FontRec, *FNT_Font; + + + typedef struct FNT_SizeRec_ + { + FT_SizeRec root; + FNT_Font font; + + } FNT_SizeRec, *FNT_Size; + + + typedef struct FNT_FaceRec_ + { + FT_FaceRec root; + + FT_UInt num_fonts; + FNT_Font fonts; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } FNT_FaceRec, *FNT_Face; + + +FT_END_HEADER + +#endif /* __FNTTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftcalc.h b/lib/freetype/include/freetype/internal/ftcalc.h new file mode 100644 index 0000000..af1f640 --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftcalc.h @@ -0,0 +1,77 @@ +/***************************************************************************/ +/* */ +/* ftcalc.h */ +/* */ +/* Arithmetic computations (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTCALC_H__ +#define __FTCALC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + FT_EXPORT( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ); + + +#define SQRT_32( x ) FT_Sqrt32( x ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Sqrt32 */ + /* */ + /* <Description> */ + /* Computes the square root of an Int32 integer (which will be */ + /* handled as an unsigned long value). */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + FT_EXPORT( FT_Int32 ) + FT_Sqrt32( FT_Int32 x ); + + + /*************************************************************************/ + /* */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ + : ( -( ( 32 - (x) ) & -64 ) ) ) + + +FT_END_HEADER + +#endif /* __FTCALC_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftcore.h b/lib/freetype/include/freetype/internal/ftcore.h new file mode 100644 index 0000000..3c3c94f --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftcore.h @@ -0,0 +1,185 @@ +#ifndef __FT_CORE_H__ +#define __FT_CORE_H__ + +#include <ft2build.h> +#include FT_TYPES_H +#include FT_SYSTEM_MEMORY_H + +FT_BEGIN_HEADER + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** C L E A N U P S T A C K *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + + /************************************************************************ + * + * @functype: FT_CleanupFunc + * + * @description: + * a function used to cleanup a given item on the cleanup stack + * + * @input: + * item :: target item pointer + * item_data :: optional argument to cleanup routine + */ + typedef void (*FT_CleanupFunc)( FT_Pointer item, + FT_Pointer item_data ); + + + + /************************************************************************ + * + * @type: FT_XHandler + * + * @description: + * handle to an exception-handler structure for the FreeType + * exception sub-system + * + * @note: + * exception handlers are allocated on the stack within a + * @FT_XTRY macro. Do not try to access them directly. + */ + typedef struct FT_XHandlerRec_* FT_XHandler; + + +/* the size of a cleanup chunk in bytes is FT_CLEANUP_CHUNK_SIZE*12 + 4 */ +/* this must be a small power of 2 whenever possible.. */ +/* */ +/* with a value of 5, we have a byte size of 64 bytes per chunk.. */ +/* */ +#define FT_CLEANUP_CHUNK_SIZE 5 + + + + typedef struct FT_CleanupItemRec_ + { + FT_Pointer item; + FT_CleanupFunc item_func; + FT_Pointer item_data; + + } FT_CleanupItemRec; + + + typedef struct FT_CleanupChunkRec_* FT_CleanupChunk; + + typedef struct FT_CleanupChunkRec_ + { + FT_CleanupChunk link; + FT_CleanupItemRec items[ FT_CLEANUP_CHUNK_SIZE ]; + + } FT_CleanupChunkRec; + + + typedef struct FT_CleanupStackRec_ + { + FT_CleanupItem top; + FT_CleanupItem limit; + FT_CleanupChunk chunk; + FT_CleanupChunkRec chunk_0; /* avoids stupid dynamic allocation */ + FT_Memory memory; + + } FT_CleanupStackRec, *FT_CleanupStack; + + + FT_BASE( void ) + ft_cleanup_stack_push( FT_CleanupStack stack, + FT_Pointer item, + FT_CleanupFunc item_func, + FT_Pointer item_data ); + + FT_BASE( void ) + ft_cleanup_stack_pop( FT_CleanupStack stack, + FT_Int destroy ); + + FT_BASE( FT_CleanupItem ) + ft_cleanup_stack_peek( FT_CleanupStack stack ); + + FT_BASE( void ) + ft_cleanup_throw( FT_CleanupStack stack, + FT_Error error ); + + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** M E M O R Y M A N A G E R *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + typedef struct FT_MemoryRec_ + { + FT_Memory_AllocFunc mem_alloc; /* shortcut to funcs->mem_alloc */ + FT_Memory_FreeFunc mem_free; /* shortcut to funcs->mem_free */ + FT_Pointer mem_data; + const FT_Memory_Funcs mem_funcs; + + FT_CleanupStackRec cleanup_stack; + FT_Pointer meta_class; + + } FT_MemoryRec; + + +#define FT_MEMORY(x) ((FT_Memory)(x)) +#define FT_MEMORY__ALLOC(x) FT_MEMORY(x)->mem_alloc +#define FT_MEMORY__FREE(x) FT_MEMORY(x)->mem_free +#define FT_MEMORY__REALLOC(x) FT_MEMORY(x)->mem_funcs->mem_realloc +#define FT_MEMORY__CLEANUP(x) (&FT_MEMORY(x)->cleanup_stack) +#define FT_MEMORY__META_CLASS(x) ((FT_MetaClass)(FT_MEMORY(x)->meta_class)) + + + /**************************************************************************/ + /**************************************************************************/ + /***** *****/ + /***** E X C E P T I O N H A N D L I N G *****/ + /***** *****/ + /**************************************************************************/ + /**************************************************************************/ + + + /************************************************************************ + * + * @struct: FT_XHandlerRec + * + * @description: + * exception handler structure + * + * @fields: + * previous :: previous handler in chain. + * jum_buffer :: processor state used by setjmp/longjmp to implement + * exception control transfer + * error :: exception error code + * mark :: top of cleanup stack when @FT_XTRY is used + */ + typedef struct FT_XHandlerRec_ + { + FT_XHandler previous; + ft_jmp_buf jump_buffer; + volatile FT_Error error; + FT_Pointer mark; + + } FT_XHandlerRec; + + FT_BASE( void ) + ft_xhandler_enter( FT_XHandler xhandler, + FT_Memory memory ); + + FT_BASE( void ) + ft_xhandler_exit( FT_XHandler xhandler ); + + + + + + + + +FT_END_HEADER + +#endif /* __FT_CORE_H__ */ diff --git a/lib/freetype/include/freetype/internal/ftdebug.h b/lib/freetype/include/freetype/internal/ftdebug.h new file mode 100644 index 0000000..129c91f --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftdebug.h @@ -0,0 +1,196 @@ +/***************************************************************************/ +/* */ +/* ftdebug.h */ +/* */ +/* Debugging and logging component (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/* */ +/* IMPORTANT: A description of FreeType's debugging support can be */ +/* found in "docs/DEBUG.TXT". Read it if you need to use or */ +/* understand this code. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDEBUG_H__ +#define __FTDEBUG_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H + + +FT_BEGIN_HEADER + + + /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ + /* is already defined; this simplifies the following #ifdefs */ + /* */ +#ifdef FT_DEBUG_LEVEL_TRACE +#undef FT_DEBUG_LEVEL_ERROR +#define FT_DEBUG_LEVEL_ERROR +#endif + + + /*************************************************************************/ + /* */ + /* Define the trace enums as well as the trace levels array when they */ + /* are needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE_DEF( x ) trace_ ## x , + + /* defining the enumeration */ + typedef enum + { +#include FT_INTERNAL_TRACE_H + trace_count + + } FT_Trace; + + + /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ + extern int ft_trace_levels[trace_count]; + +#undef FT_TRACE_DEF + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Define the FT_TRACE macro */ + /* */ + /* IMPORTANT! */ + /* */ + /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ + /* value before using any TRACE macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_COMPONENT] >= level ) \ + FT_Message varformat; \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* You need two opening resp. closing parentheses! */ + /* */ + /* Example: FT_TRACE0(( "Value is %i", foo )) */ + /* */ + /*************************************************************************/ + +#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) +#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) +#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) +#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) +#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) +#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) +#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) +#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) + + + /*************************************************************************/ + /* */ + /* Define the FT_ERROR macro */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ERROR( varformat ) FT_Message varformat + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define the FT_ASSERT macro */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ASSERT( condition ) \ + do \ + { \ + if ( !( condition ) ) \ + FT_Panic( "assertion failed on line %d of file %s\n", \ + __LINE__, __FILE__ ); \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ASSERT( condition ) do ; while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define 'FT_Message' and 'FT_Panic' when needed */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#include "stdio.h" /* for vprintf() */ + + /* print a message */ + FT_EXPORT( void ) + FT_Message( const char* fmt, ... ); + + /* print a message and exit */ + FT_EXPORT( void ) + FT_Panic( const char* fmt, ... ); + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + FT_BASE( void ) + ft_debug_init( void ); + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* we disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + +FT_END_HEADER + +#endif /* __FTDEBUG_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftdriver.h b/lib/freetype/include/freetype/internal/ftdriver.h new file mode 100644 index 0000000..9323910 --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftdriver.h @@ -0,0 +1,202 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType font driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTDRIVER_H__ +#define __FTDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_ResetPointsFunc)( FT_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + typedef FT_Error + (*FT_Size_ResetPixelsFunc)( FT_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_UInt + (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Long + (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Bool vertical, + FT_UShort* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* set_char_sizes :: A handle to a function used to set the new */ + /* character size in points + resolution. Can be */ + /* set to 0 to indicate default behaviour. */ + /* */ + /* set_pixel_sizes :: A handle to a function used to set the new */ + /* character size in pixels. Can be set to 0 to */ + /* indicate default behaviour. */ + /* */ + /* load_glyph :: A function handle to load a given glyph image */ + /* in a slot. This field is mandatory! */ + /* */ + /* get_char_index :: A function handle to return the glyph index of */ + /* a given character for a given charmap. This */ + /* field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return the advances */ + /* of 'count' glyphs, starting at `index'. the */ + /* `vertical' flags must be set when vertical */ + /* advances are queried. The advances buffer is */ + /* caller-allocated. */ + /* */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph' and */ + /* `get_char_index' can be set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Int face_object_size; + FT_Int size_object_size; + FT_Int slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + + FT_Size_ResetPointsFunc set_char_sizes; + FT_Size_ResetPixelsFunc set_pixel_sizes; + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + +FT_END_HEADER + +#endif /* __FTDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftexcept.h b/lib/freetype/include/freetype/internal/ftexcept.h new file mode 100644 index 0000000..f5495e5 --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftexcept.h @@ -0,0 +1,82 @@ +#ifndef __FT_EXCEPT_H__ +#define __FT_EXCEPT_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + +FT_BEGIN_HEADER + + + + /* I can't find a better place for this for now */ + +<<<<<<< ftexcept.h +======= + +/* the size of a cleanup chunk in bytes is FT_CLEANUP_CHUNK_SIZE*12 + 4 */ +/* this must be a small power of 2 whenever possible.. */ +/* */ +/* with a value of 5, we have a byte size of 64 bytes per chunk.. */ +/* */ +#define FT_CLEANUP_CHUNK_SIZE 5 + + + + typedef struct FT_CleanupItemRec_ + { + FT_Pointer item; + FT_CleanupFunc item_func; + FT_Pointer item_data; + + } FT_CleanupItemRec; + + typedef struct FT_CleanupChunkRec_* FT_CleanupChunk; + + typedef struct FT_CleanupChunkRec_ + { + FT_CleanupChunk link; + FT_CleanupItemRec items[ FT_CLEANUP_CHUNK_SIZE ]; + + } FT_CleanupChunkRec; + + + typedef struct FT_CleanupStackRec_ + { + FT_CleanupItem top; + FT_CleanupItem limit; + FT_CleanupChunk chunk; + FT_CleanupChunkRec chunk_0; /* avoids stupid dynamic allocation */ + FT_Memory memory; + + } FT_CleanupStackRec, *FT_CleanupStack; + + + FT_BASE( void ) + ft_cleanup_stack_push( FT_CleanupStack stack, + FT_Pointer item, + FT_CleanupFunc item_func, + FT_Pointer item_data ); + + FT_BASE( void ) + ft_cleanup_stack_pop( FT_CleanupStack stack, + FT_Int destroy ); + + FT_BASE( FT_CleanupItem ) + ft_cleanup_stack_peek( FT_CleanupStack stack ); + + FT_BASE( void ) + ft_xhandler_enter( FT_XHandler xhandler, + FT_Memory memory ); + + FT_BASE( void ) + ft_xhandler_exit( FT_XHandler xhandler ); + + + FT_BASE( void ) + ft_cleanup_throw( FT_CleanupStack stack, + FT_Error error ); + +>>>>>>> 1.2 +FT_END_HEADER + +#endif /* __FT_EXCEPT_H__ */ diff --git a/lib/freetype/include/freetype/internal/ftgloadr.h b/lib/freetype/include/freetype/internal/ftgloadr.h new file mode 100644 index 0000000..d66d10b --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftgloadr.h @@ -0,0 +1,153 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.h */ +/* */ +/* The FreeType glyph loader (specification). */ +/* */ +/* Copyright 2002 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 __FTGLOADR_H__ +#define __FTGLOADR_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphLoader */ + /* */ + /* <Description> */ + /* The glyph loader is an internal object used to load several glyphs */ + /* together (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The glyph loader implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; + + +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + enum + { + FT_GLYPH_OWN_BITMAP = 1 + }; + + + typedef struct FT_SubGlyphRec_ + { + FT_Int index; + FT_UShort flags; + FT_Int arg1; + FT_Int arg2; + FT_Matrix transform; + + } FT_SubGlyphRec; + + + typedef struct FT_GlyphLoadRec_ + { + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ + + } FT_GlyphLoadRec, *FT_GlyphLoad; + + + typedef struct FT_GlyphLoaderRec_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoadRec base; + FT_GlyphLoadRec current; + + void* other; /* for possible future extension? */ + + } FT_GlyphLoaderRec; + + + /* create new empty glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ); + + /* add an extra points table to a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); + + /* destroy a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ); + + /* reset a glyph loader (frees everything int it) */ + FT_BASE( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ); + + /* rewind a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); + + /* check that there is enough room to add 'n_points' and 'n_contours' */ + /* to the glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ); + + /* check that there is enough room to add 'n_subs' sub-glyphs to */ + /* a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ); + + /* prepare a glyph loader, i.e. empty the current glyph */ + FT_BASE( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); + + /* add the current glyph to the base glyph */ + FT_BASE( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ); + + /* copy points from one glyph loader to another */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLOADR_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/fthash.h b/lib/freetype/include/freetype/internal/fthash.h new file mode 100644 index 0000000..b95b6c9 --- /dev/null +++ b/lib/freetype/include/freetype/internal/fthash.h @@ -0,0 +1,502 @@ +/****************************************************************** + * + * fthash.h - fast dynamic hash tables + * + * Copyright 2002 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 header is used to define dynamic hash tables as described + * by the article "Main-Memory Linear Hashing - Some Enhancements + * of Larson's Algorithm" by Mikael Petterson. + * + * Basically, linear hashing prevents big "stalls" during + * resizes of the buckets array by only splitting one bucket + * at a time. This ensures excellent response time even when + * the table is frequently resized.. + * + * + * Note that the use of the FT_Hash type is rather unusual in order + * to be as generic and efficient as possible. See the comments in the + * following definitions for more details. + */ + +#ifndef __FT_HASH_H__ +#define __FT_HASH_H__ + +#include <ft2build.h> +#include FT_TYPES_H + +FT_BEGIN_HEADER + + /*********************************************************** + * + * @type: FT_Hash + * + * @description: + * handle to a @FT_HashRec structure used to model a + * dynamic hash table + */ + typedef struct FT_HashRec_* FT_Hash; + + + /*********************************************************** + * + * @type: FT_HashNode + * + * @description: + * handle to a @FT_HashNodeRec structure used to model a + * single node of a hash table + */ + typedef struct FT_HashNodeRec_* FT_HashNode; + + + /*********************************************************** + * + * @type: FT_HashLookup + * + * @description: + * handle to a @FT_HashNode pointer. This is returned by + * the @ft_hash_lookup function and can later be used by + * @ft_hash_add or @ft_hash_remove + */ + typedef FT_HashNode* FT_HashLookup; + + + /*********************************************************** + * + * @type: FT_Hash_EqualFunc + * + * @description: + * a function used to compare two nodes of the hash table + * + * @input: + * node1 :: handle to first node + * node2 :: handle to second node + * + * @return: + * 1 iff the 'keys' in 'node1' and 'node2' are identical. + * 0 otherwise. + */ + typedef FT_Int (*FT_Hash_EqualFunc)( FT_HashNode node1, + FT_HashNode node2 ); + + + /*********************************************************** + * + * @struct: FT_HashRec + * + * @description: + * a structure used to model a dynamic hash table. + * + * @fields: + * memory :: memory manager used to allocate + * the buckets array and the hash nodes + * + * buckets :: array of hash buckets + * + * node_size :: size of node in bytes + * node_compare :: a function used to compare two nodes + * node_hash :: a function used to compute the hash + * value of a given node + * p :: + * mask :: + * slack :: + * + * @note: + * 'p', 'mask' and 'slack' are control values managed by + * the hash table. Do not try to interpret them directly. + * + * You can grab the hash table size by calling + * '@ft_hash_get_size'. + */ + typedef struct FT_HashRec_ + { + FT_HashNode* buckets; + FT_UInt p; + FT_UInt mask; /* really maxp-1 */ + FT_Long slack; + FT_Hash_EqualFunc node_equal; + FT_Memory memory; + + } FT_HashRec; + + + /*********************************************************** + * + * @struct: FT_HashNodeRec + * + * @description: + * a structure used to model the root fields of a dynamic + * hash table node. + * + * it's up to client applications to "sub-class" this + * structure to add relevant (key,value) definitions + * + * @fields: + * link :: pointer to next node in bucket's collision list + * hash :: 32-bit hash value for this node + * + * @note: + * it's up to client applications to "sub-class" this structure + * to add relevant (key,value) type definitions. For example, + * if we want to build a "string -> int" mapping, we could use + * something like: + * + * { + * typedef struct MyNodeRec_ + * { + * FT_HashNodeRec hnode; + * const char* key; + * int value; + * + * } MyNodeRec, *MyNode; + * } + * + */ + typedef struct FT_HashNodeRec_ + { + FT_HashNode link; + FT_UInt32 hash; + + } FT_HashNodeRec; + + + /**************************************************************** + * + * @function: ft_hash_init + * + * @description: + * initialize a dynamic hash table + * + * @input: + * table :: handle to target hash table structure + * node_equal :: node comparison function + * memory :: memory manager handle used to allocate the + * buckets array within the hash table + * + * @return: + * error code. 0 means success + * + * @note: + * the node comparison function should only compare node _keys_ + * and ignore values !! with good hashing computation (which the + * user must perform itself), the comparison function should be + * pretty seldom called. + * + * here is a simple example: + * + * { + * static int my_equal( MyNode node1, + * MyNode node2 ) + * { + * // compare keys of 'node1' and 'node2' + * return (strcmp( node1->key, node2->key ) == 0); + * } + * + * .... + * + * ft_hash_init( &hash, (FT_Hash_EqualFunc) my_compare, memory ); + * .... + * } + */ + FT_BASE( FT_Error ) + ft_hash_init( FT_Hash table, + FT_Hash_EqualFunc compare, + FT_Memory memory ); + + + /**************************************************************** + * + * @function: ft_hash_lookup + * + * @description: + * search a hash table to find a node corresponding to a given + * key. + * + * @input: + * table :: handle to target hash table structure + * keynode :: handle to a reference hash node that will be + * only used for key comparisons with the table's + * elements + * + * @return: + * a pointer-to-hash-node value, which must be used as followed: + * + * - if '*result' is NULL, the key wasn't found in the hash + * table. The value of 'result' can be used to add new elements + * through @ft_hash_add however.. + * + * - if '*result' is not NULL, it's a handle to the first table + * node that corresponds to the search key. The value of 'result' + * can be used to remove this element through @ft_hash_remove + * + * @note: + * here is an example: + * + * { + * // maps a string to an integer with a hash table + * // returns -1 in case of failure + * // + * int my_lookup( FT_Hash table, + * const char* key ) + * { + * MyNode* pnode; + * MyNodeRec noderec; + * + * // set-up key node. It's 'hash' and 'key' fields must + * // be set correctly.. we ignore 'link' and 'value' + * // + * noderec.hnode.hash = strhash( key ); + * noderec.key = key; + * + * // perform search - return value + * // + * pnode = (MyNode) ft_hash_lookup( table, &noderec ); + * if ( *pnode ) + * { + * // we found it + * return (*pnode)->value; + * } + * return -1; + * } + * } + */ + FT_BASE_DEF( FT_HashLookup ) + ft_hash_lookup( FT_Hash table, + FT_HashNode keynode ); + + + /**************************************************************** + * + * @function: ft_hash_add + * + * @description: + * add a new node to a dynamic hash table. the user must + * call @ft_hash_lookup and allocate a new node before calling + * this function. + * + * @input: + * table :: hash table handle + * lookup :: pointer-to-hash-node value returned by @ft_hash_lookup + * new_node :: handle to new hash node. All its fields must be correctly + * set, including 'hash'. + * + * @return: + * error code. 0 means success + * + * @note: + * this function should always be used _after_ a call to @ft_hash_lookup + * that returns a pointer to a NULL handle. Here's an example: + * + * { + * // sets the value corresponding to a given string key + * // + * void my_set( FT_Hash table, + * const char* key, + * int value ) + * { + * MyNode* pnode; + * MyNodeRec noderec; + * MyNode node; + * + * // set-up key node. It's 'hash' and 'key' fields must + * // be set correctly.. + * noderec.hnode.hash = strhash( key ); + * noderec.key = key; + * + * // perform search - return value + * pnode = (MyNode) ft_hash_lookup( table, &noderec ); + * if ( *pnode ) + * { + * // we found it, simply replace the value in the node + * (*pnode)->value = value; + * return; + * } + * + * // allocate a new node - and set it up + * node = (MyNode) malloc( sizeof(*node) ); + * if ( node == NULL ) ..... + * + * node->hnode.hash = noderec.hnode.hash; + * node->key = key; + * node->value = value; + * + * // add it to the hash table + * error = ft_hash_add( table, pnode, node ); + * if (error) .... + * } + */ + FT_BASE( FT_Error ) + ft_hash_add( FT_Hash table, + FT_HashLookup lookup, + FT_HashNode new_node ); + + + /**************************************************************** + * + * @function: ft_hash_remove + * + * @description: + * try to remove the node corresponding to a given key from + * a hash table. This must be called after @ft_hash_lookup + * + * @input: + * table :: hash table handle + * lookup :: pointer-to-hash-node value returned by @ft_hash_lookup + * + * @note: + * this function doesn't free the node itself !! Here's an example: + * + * { + * // sets the value corresponding to a given string key + * // + * void my_remove( FT_Hash table, + * const char* key ) + * { + * MyNodeRec noderec; + * MyNode node; + * + * noderec.hnode.hash = strhash(key); + * noderec.key = key; + * node = &noderec; + * + * pnode = ft_hash_lookup( table, &noderec ); + * node = *pnode; + * if ( node != NULL ) + * { + * error = ft_hash_remove( table, pnode ); + * if ( !error ) + * free( node ); + * } + * } + * } + */ + FT_BASE( FT_Error ) + ft_hash_remove( FT_Hash table, + FT_HashLookup lookup ); + + + + /**************************************************************** + * + * @function: ft_hash_get_size + * + * @description: + * return the number of elements in a given hash table + * + * @input: + * table :: handle to target hash table structure + * + * @return: + * number of elements. 0 if empty + */ + FT_BASE( FT_UInt ) + ft_hash_get_size( FT_Hash table ); + + + + /**************************************************************** + * + * @functype: FT_Hash_ForeachFunc + * + * @description: + * a function used to iterate over all elements of a given + * hash table + * + * @input: + * node :: handle to target @FT_HashNodeRec node structure + * data :: optional argument to iteration routine + * + * @also: @ft_hash_foreach + */ + typedef void (*FT_Hash_ForeachFunc)( const FT_HashNode node, + const FT_Pointer data ); + + + /**************************************************************** + * + * @function: ft_hash_foreach + * + * @description: + * parse over all elements in a hash table + * + * @input: + * table :: handle to target hash table structure + * foreach_func :: iteration routine called for each element + * foreach_data :: optional argument to the iteration routine + * + * @note: + * this function is often used to release all elements from a + * hash table. See the example given for @ft_hash_done + */ + FT_BASE( void ) + ft_hash_foreach( FT_Hash table, + FT_Hash_ForeachFunc foreach_func, + const FT_Pointer foreach_data ); + + + + /**************************************************************** + * + * @function: ft_hash_done + * + * @description: + * finalize a given hash table + * + * @input: + * table :: handle to target hash table structure + * node_func :: optional iteration function pointer. this + * can be used to destroy all nodes explicitely + * node_data :: optional argument to the node iterator + * + * @note: + * this function simply frees the hash table's buckets. + * you probably will need to call @ft_hash_foreach to + * destroy all its elements before @ft_hash_done, as in + * the following example: + * + * { + * static void my_node_clear( const MyNode node ) + * { + * free( node ); + * } + * + * static void my_done( FT_Hash table ) + * { + * ft_hash_done( table, (FT_Hash_ForeachFunc) my_node_clear, NULL ); + * } + * } + */ + FT_BASE( void ) + ft_hash_done( FT_Hash table, + FT_Hash_ForeachFunc item_func, + const FT_Pointer item_data ); + + /* */ + + /* compute bucket index from hash value in a dynamic hash table */ + /* this is only used to break encapsulation to speed lookups in */ + /* the FreeType cache manager !! */ + /* */ + +#define FT_HASH_COMPUTE_INDEX(_table,_hash,_index) \ + { \ + FT_UInt _mask = (_table)->mask; \ + FT_UInt _hash0 = (_hash); \ + \ + (_index) = (FT_UInt)( (_hash0) & _mask ) ); \ + if ( (_index) < (_table)->p ) \ + (_index) = (FT_uInt)( (_hash0) & ( 2*_mask+1 ) ); \ + } + + +FT_END_HEADER + +#endif /* __FT_HASH_H__ */ diff --git a/lib/freetype/include/freetype/internal/ftmemory.h b/lib/freetype/include/freetype/internal/ftmemory.h new file mode 100644 index 0000000..cbe66d7 --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftmemory.h @@ -0,0 +1,296 @@ +/***************************************************************************/ +/* */ +/* ftmemory.h */ +/* */ +/* The FreeType memory management macros (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTMEMORY_H__ +#define __FTMEMORY_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_SET_ERROR */ + /* */ + /* <Description> */ + /* This macro is used to set an implicit `error' variable to a given */ + /* expression's value (usually a function call), and convert it to a */ + /* boolean which is set whenever the value is != 0. */ + /* */ +#undef FT_SET_ERROR +#define FT_SET_ERROR( expression ) \ + ( ( error = (expression) ) != 0 ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M E M O R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef FT_DEBUG_MEMORY + + FT_BASE( FT_Error ) + FT_Alloc_Debug( FT_Memory memory, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ); + + FT_BASE( FT_Error ) + FT_Realloc_Debug( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ); + + FT_BASE( void ) + FT_Free_Debug( FT_Memory memory, + FT_Pointer block, + const char* file_name, + FT_Long line_no ); + +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Alloc */ + /* */ + /* <Description> */ + /* Allocates a new block of memory. The returned area is always */ + /* zero-filled; this is a strong convention in many FreeType parts. */ + /* */ + /* <Input> */ + /* memory :: A handle to a given `memory object' which handles */ + /* allocation. */ + /* */ + /* size :: The size in bytes of the block to allocate. */ + /* */ + /* <Output> */ + /* P :: A pointer to the fresh new block. It should be set to */ + /* NULL if `size' is 0, or in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Alloc( FT_Memory memory, + FT_Long size, + void* *P ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Realloc */ + /* */ + /* <Description> */ + /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */ + /* from the heap, possibly changing `*P'. */ + /* */ + /* <Input> */ + /* memory :: A handle to a given `memory object' which handles */ + /* reallocation. */ + /* */ + /* current :: The current block size in bytes. */ + /* */ + /* size :: The new block size in bytes. */ + /* */ + /* <InOut> */ + /* P :: A pointer to the fresh new block. It should be set to */ + /* NULL if `size' is 0, or in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* All callers of FT_Realloc() _must_ provide the current block size */ + /* as well as the new one. */ + /* */ + FT_BASE( FT_Error ) + FT_Realloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void** P ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Free */ + /* */ + /* <Description> */ + /* Releases a given block of memory allocated through FT_Alloc(). */ + /* */ + /* <Input> */ + /* memory :: A handle to a given `memory object' which handles */ + /* memory deallocation */ + /* */ + /* P :: This is the _address_ of a _pointer_ which points to the */ + /* allocated block. It is always set to NULL on exit. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* If P or *P are NULL, this function should return successfully. */ + /* This is a strong convention within all of FreeType and its */ + /* drivers. */ + /* */ + FT_BASE( void ) + FT_Free( FT_Memory memory, + void** P ); + + +#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) + +#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) + +#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) + + +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) + + + /*************************************************************************/ + /* */ + /* We first define FT_MEM_ALLOC, FT_MEM_REALLOC, and FT_MEM_FREE. All */ + /* macros use an _implicit_ `memory' parameter to access the current */ + /* memory allocator. */ + /* */ + +#ifdef FT_DEBUG_MEMORY + +#define FT_MEM_ALLOC( _pointer_, _size_ ) \ + FT_Alloc_Debug( memory, _size_, \ + (void**)&(_pointer_), __FILE__, __LINE__ ) + +#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ + FT_Realloc_Debug( memory, _current_, _size_, \ + (void**)&(_pointer_), __FILE__, __LINE__ ) + +#define FT_MEM_FREE( _pointer_ ) \ + FT_Free_Debug( memory, (void**)&(_pointer_), __FILE__, __LINE__ ) + + +#else /* !FT_DEBUG_MEMORY */ + + +#define FT_MEM_ALLOC( _pointer_, _size_ ) \ + FT_Alloc( memory, _size_, (void**)&(_pointer_) ) + +#define FT_MEM_FREE( _pointer_ ) \ + FT_Free( memory, (void**)&(_pointer_) ) + +#define FT_MEM_REALLOC( _pointer_, _current_, _size_ ) \ + FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) ) + + +#endif /* !FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* The following functions macros expect that their pointer argument is */ + /* _typed_ in order to automatically compute array element sizes. */ + /* */ + +#define FT_MEM_NEW( _pointer_ ) \ + FT_MEM_ALLOC( _pointer_, sizeof ( *(_pointer_) ) ) + +#define FT_MEM_NEW_ARRAY( _pointer_, _count_ ) \ + FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( *(_pointer_) ) ) + +#define FT_MEM_RENEW_ARRAY( _pointer_, _old_, _new_ ) \ + FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( *(_pointer_) ), \ + (_new_) * sizeof ( *(_pointer_) ) ) + + + /*************************************************************************/ + /* */ + /* the following macros are obsolete but kept for compatibility reasons */ + /* */ + +#define FT_MEM_ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + FT_MEM_ALLOC( _pointer_, (_count_) * sizeof ( _type_ ) ) + +#define FT_MEM_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) \ + FT_MEM_REALLOC( _pointer_, (_old_) * sizeof ( _type ), \ + (_new_) * sizeof ( _type_ ) ) + + + /*************************************************************************/ + /* */ + /* The following macros are variants of their FT_MEM_XXXX equivalents; */ + /* they are used to set an _implicit_ `error' variable and return TRUE */ + /* if an error occured (i.e. if 'error != 0'). */ + /* */ + +#define FT_ALLOC( _pointer_, _size_ ) \ + FT_SET_ERROR( FT_MEM_ALLOC( _pointer_, _size_ ) ) + +#define FT_REALLOC( _pointer_, _current_, _size_ ) \ + FT_SET_ERROR( FT_MEM_REALLOC( _pointer_, _current_, _size_ ) ) + +#define FT_FREE( _pointer_ ) \ + FT_MEM_FREE( _pointer_ ) + +#define FT_NEW( _pointer_ ) \ + FT_SET_ERROR( FT_MEM_NEW( _pointer_ ) ) + +#define FT_NEW_ARRAY( _pointer_, _count_ ) \ + FT_SET_ERROR( FT_MEM_NEW_ARRAY( _pointer_, _count_ ) ) + +#define FT_RENEW_ARRAY( _pointer_, _old_, _new_ ) \ + FT_SET_ERROR( FT_MEM_RENEW_ARRAY( _pointer_, _old_, _new_ ) ) + +#define FT_ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ + FT_SET_ERROR( FT_MEM_ALLOC( _pointer_, \ + (_count_) * sizeof ( _type_ ) ) ) + +#define FT_REALLOC_ARRAY( _pointer_, _old_, _new_, _type_ ) \ + FT_SET_ERROR( FT_MEM_REALLOC( _pointer_, \ + (_old_) * sizeof ( _type_ ), \ + (_new_) * sizeof ( _type_ ) ) ) + + /* */ + + +FT_END_HEADER + +#endif /* __FTMEMORY_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftobject.h b/lib/freetype/include/freetype/internal/ftobject.h new file mode 100644 index 0000000..f285d9e --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftobject.h @@ -0,0 +1,533 @@ +#ifndef __FT_OBJECT_H__ +#define __FT_OBJECT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + /************************************************************** + * + * @type: FT_Object + * + * @description: + * handle to a FreeType Object. See @FT_ObjectRec + */ + typedef struct FT_ObjectRec_* FT_Object; + + + /************************************************************** + * + * @type: FT_Class + * + * @description: + * handle to a constant class handle to a FreeType Object. + * + * Note that a class is itself a @FT_Object and are dynamically + * allocated on the heap. + * + * @also: + * @FT_ClassRec, @FT_Object, @FT_ObjectRec, @FT_Type, @FT_TypeRec + */ + typedef const struct FT_ClassRec_* FT_Class; + + + /************************************************************** + * + * @type: FT_Type + * + * @description: + * handle to a constant structure (of type @FT_TypeRec) used + * to describe a given @FT_Class type to the FreeType object + * sub-system. + */ + typedef const struct FT_TypeRec_* FT_Type; + + + + /************************************************************** + * + * @struct: FT_ObjectRec + * + * @description: + * a structure describing the root fields of all @FT_Object + * class instances in FreeType + * + * @fields: + * clazz :: handle to the object's class + * ref_count :: object's reference count. Starts at 1 + */ + typedef struct FT_ObjectRec_ + { + FT_Class clazz; + FT_Int ref_count; + + } FT_ObjectRec; + + + /************************************************************** + * + * @macro: FT_OBJECT (x) + * + * @description: + * a useful macro to type-cast anything to a @FT_Object + * handle. No check performed.. + */ +#define FT_OBJECT(x) ((FT_Object)(x)) + + + /************************************************************** + * + * @macro: FT_OBJECT_P (x) + * + * @description: + * a useful macro to type-cast anything to a pointer to + * @FT_Object handle. + */ +#define FT_OBJECT_P(x) ((FT_Object*)(x)) + + + /************************************************************** + * + * @macro: FT_OBJECT__CLASS (obj) + * + * @description: + * a useful macro to return the class of any object + */ +#define FT_OBJECT__CLASS(x) FT_OBJECT(x)->clazz + + + /************************************************************** + * + * @macro: FT_OBJECT__REF_COUNT (obj) + * + * @description: + * a useful macro to return the reference count of any object + */ +#define FT_OBJECT__REF_COUNT(x) FT_OBJECT(x)->ref_count + + + /************************************************************** + * + * @macro: FT_OBJECT__MEMORY (obj) + * + * @description: + * a useful macro to return a handle to the memory manager + * used to allocate a given object + */ +#define FT_OBJECT__MEMORY(x) FT_CLASS__MEMORY(FT_OBJECT(x)->clazz) + + + /************************************************************** + * + * @macro: FT_OBJECT__LIBRARY (obj) + * + * @description: + * a useful macro to return a handle to the library handle + * that owns the object + */ +#define FT_OBJECT__LIBRARY(x) FT_CLASS__LIBRARY(FT_OBJECT(x)->clazz) + + + /************************************************************** + * + * @functype: FT_Object_InitFunc + * + * @description: + * a function used to initialize a new object + * + * @input: + * object :: target object handle + * init_data :: optional pointer to initialization data + * + * @return: + * error code. 0 means success + */ + typedef FT_Error (*FT_Object_InitFunc)( FT_Object object, + FT_Pointer init_data ); + + /************************************************************** + * + * @functype: FT_Object_DoneFunc + * + * @description: + * a function used to finalize a given object + * + * @input: + * object :: handle to target object + */ + typedef void (*FT_Object_DoneFunc)( FT_Object object ); + + + /************************************************************** + * + * @struct: FT_ClassRec + * + * @description: + * a structure used to describe a given object class within + * FreeType + * + * @fields: + * object :: root @FT_ObjectRec fields, since each class is + * itself an object. (it's an instance of the + * "metaclass", a special object of the FreeType + * object sub-system.) + * + * magic :: a 32-bit magic number used for decoding + * super :: pointer to super class + * type :: the @FT_Type descriptor of this class + * memory :: the current memory manager handle + * library :: the current library handle + * info :: an opaque pointer to class-specific information + * managed by the FreeType object sub-system + * + * class_done :: the class destructor function + * + * obj_size :: size of class instances in bytes + * obj_init :: class instance constructor + * obj_done :: class instance destructor + */ + typedef struct FT_ClassRec_ + { + FT_ObjectRec object; + FT_UInt32 magic; + FT_Class super; + FT_Type type; + FT_Memory memory; + FT_Library library; + FT_Pointer info; + + FT_Object_DoneFunc class_done; + + FT_UInt obj_size; + FT_Object_InitFunc obj_init; + FT_Object_DoneFunc obj_done; + + } FT_ClassRec; + + + /************************************************************** + * + * @macro: FT_CLASS (x) + * + * @description: + * a useful macro to convert anything to a class handle + * without checks + */ +#define FT_CLASS(x) ((FT_Class)(x)) + + + /************************************************************** + * + * @macro: FT_CLASS_P (x) + * + * @description: + * a useful macro to convert anything to a pointer to a class + * handle without checks + */ +#define FT_CLASS_P(x) ((FT_Class*)(x)) + + + /************************************************************** + * + * @macro: FT_CLASS__MEMORY (clazz) + * + * @description: + * a useful macro to return the memory manager handle of a + * given class + */ +#define FT_CLASS__MEMORY(x) FT_CLASS(x)->memory + + + /************************************************************** + * + * @macro: FT_CLASS__LIBRARY (clazz) + * + * @description: + * a useful macro to return the library handle of a + * given class + */ +#define FT_CLASS__LIBRARY(x) FT_CLASS(x)->library + + + + /************************************************************** + * + * @macro: FT_CLASS__TYPE (clazz) + * + * @description: + * a useful macro to return the type of a given class + * given class + */ +#define FT_CLASS__TYPE(x) FT_CLASS(x)->type + + /* */ +#define FT_CLASS__INFO(x) FT_CLASS(x)->info +#define FT_CLASS__MAGIC(x) FT_CLASS(x)->magic + + + /************************************************************** + * + * @struct: FT_TypeRec + * + * @description: + * a structure used to describe a given class to the FreeType + * object sub-system. + * + * @fields: + * name :: class name. only used for debugging + * super :: type of super-class. NULL if none + * + * class_size :: size of class structure in bytes + * class_init :: class constructor + * class_done :: class finalizer + * + * obj_size :: instance size in bytes + * obj_init :: instance constructor. can be NULL + * obj_done :: instance destructor. can be NULL + * + * @note: + * if 'obj_init' is NULL, the class will use it's parent + * constructor, if any + * + * if 'obj_done' is NULL, the class will use it's parent + * finalizer, if any + * + * the object sub-system allocates a new class, copies + * the content of its super-class into the new structure, + * _then_ calls 'clazz_init'. + * + * 'class_init' and 'class_done' can be NULL, in which case + * the parent's class constructor and destructor wil be used + */ + typedef struct FT_TypeRec_ + { + const char* name; + FT_Type super; + + FT_UInt class_size; + FT_Object_InitFunc class_init; + FT_Object_DoneFunc class_done; + + FT_UInt obj_size; + FT_Object_InitFunc obj_init; + FT_Object_DoneFunc obj_done; + + } FT_TypeRec; + + + /************************************************************** + * + * @macro: FT_TYPE (x) + * + * @description: + * a useful macro to convert anything to a class type handle + * without checks + */ +#define FT_TYPE(x) ((FT_Type)(x)) + + + /************************************************************** + * + * @function: ft_object_check + * + * @description: + * checks that a handle points to a valid @FT_Object + * + * @input: + * obj :: handle/pointer + * + * @return: + * 1 iff the handle points to a valid object. 0 otherwise + */ + FT_BASE( FT_Int ) + ft_object_check( FT_Pointer obj ); + + + /************************************************************** + * + * @function: ft_object_is_a + * + * @description: + * checks that a handle points to a valid @FT_Object that + * is an instance of a given class (or of any of its sub-classes) + * + * @input: + * obj :: handle/pointer + * clazz :: class handle to check + * + * @return: + * 1 iff the handle points to a valid 'clazz' instance. 0 + * otherwise. + */ + FT_BASE( FT_Int ) + ft_object_is_a( FT_Pointer obj, + FT_Class clazz ); + + + /************************************************************** + * + * @function: ft_object_create + * + * @description: + * create a new object (class instance) + * + * @output: + * aobject :: new object handle. NULL in case of error + * + * @input: + * clazz :: object's class pointer + * init_data :: optional pointer to initialization data + * + * @return: + * error code. 0 means success + */ + FT_BASE( FT_Error ) + ft_object_create( FT_Object *aobject, + FT_Class clazz, + FT_Pointer init_data ); + + + /************************************************************** + * + * @function: ft_object_create_from_type + * + * @description: + * create a new object (class instance) from a @FT_Type + * + * @output: + * aobject :: new object handle. NULL in case of error + * + * @input: + * type :: object's type descriptor + * init_data :: optional pointer to initialization data + * + * @return: + * error code. 0 means success + * + * @note: + * this function is slower than @ft_object_create + * + * this is equivalent to calling @ft_class_from_type followed by + * @ft_object_create + */ + FT_BASE( FT_Error ) + ft_object_create_from_type( FT_Object *aobject, + FT_Type type, + FT_Pointer init_data, + FT_Library library ); + + + + /************************************************************** + * + * @macro FT_OBJ_CREATE (object,class,init) + * + * @description: + * a convenient macro used to create new objects. see + * @ft_object_create for details + */ +#define FT_OBJ_CREATE( _obj, _clazz, _init ) \ + ft_object_create( FT_OBJECT_P(&(_obj)), _clazz, _init ) + + + /************************************************************** + * + * @macro FT_CREATE (object,class,init) + * + * @description: + * a convenient macro used to create new objects. It also + * sets an _implicit_ local variable named "error" to the error + * code returned by the object constructor. + */ +#define FT_CREATE( _obj, _clazz, _init ) \ + FT_SET_ERROR( FT_OBJ_CREATE( _obj, _clazz, _init ) ) + + /************************************************************** + * + * @macro FT_OBJ_CREATE_FROM_TYPE (object,type,init) + * + * @description: + * a convenient macro used to create new objects. see + * @ft_object_create_from_type for details + */ +#define FT_OBJ_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) \ + ft_object_create_from_type( FT_OBJECT_P(&(_obj)), _type, _init, _lib ) + + + /************************************************************** + * + * @macro FT_CREATE_FROM_TYPE (object,type,init) + * + * @description: + * a convenient macro used to create new objects. It also + * sets an _implicit_ local variable named "error" to the error + * code returned by the object constructor. + */ +#define FT_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) \ + FT_SET_ERROR( FT_OBJ_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) ) + + + /* */ + + /************************************************************** + * + * @function: ft_class_from_type + * + * @description: + * retrieves the class object corresponding to a given type + * descriptor. The class is created when needed + * + * @output: + * aclass :: handle to corresponding class object. NULL in + * case of error + * + * @input: + * type :: type descriptor handle + * library :: library handle + * + * @return: + * error code. 0 means success + */ + FT_BASE( FT_Error ) + ft_class_from_type( FT_Class *aclass, + FT_Type type, + FT_Library library ); + + + /* */ + +#include FT_INTERNAL_HASH_H + + typedef struct FT_ClassHNodeRec_* FT_ClassHNode; + + typedef struct FT_ClassHNodeRec_ + { + FT_HashNodeRec hnode; + FT_Type type; + FT_Class clazz; + + } FT_ClassHNodeRec; + + typedef struct FT_MetaClassRec_ + { + FT_ClassRec clazz; /* the meta-class is a class itself */ + FT_HashRec type_to_class; /* the type => class hash table */ + + } FT_MetaClassRec, *FT_MetaClass; + + + /* initialize meta class */ + FT_BASE( FT_Error ) + ft_metaclass_init( FT_MetaClass meta, + FT_Library library ); + + /* finalize meta class - destroy all registered class objects */ + FT_BASE( void ) + ft_metaclass_done( FT_MetaClass meta ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_OBJECT_H__ */ diff --git a/lib/freetype/include/freetype/internal/ftobjs.h b/lib/freetype/include/freetype/internal/ftobjs.h new file mode 100644 index 0000000..9276150 --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftobjs.h @@ -0,0 +1,820 @@ +/***************************************************************************/ +/* */ +/* ftobjs.h */ +/* */ +/* The FreeType private base classes (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 contains the definition of all internal FreeType classes. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTOBJS_H__ +#define __FTOBJS_H__ + +#include <ft2build.h> +#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ +#include FT_RENDER_H +#include FT_SIZES_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_AUTOHINT_H +#include FT_INTERNAL_OBJECT_H + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#include FT_INCREMENTAL_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Some generic definitions. */ + /* */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + + /*************************************************************************/ + /* */ + /* 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 + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** V A L I D A T I O N ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to a validation object */ + typedef struct FT_ValidatorRec_* FT_Validator; + + + /*************************************************************************/ + /* */ + /* There are three distinct validation levels defined here: */ + /* */ + /* FT_VALIDATE_DEFAULT :: */ + /* A table that passes this validation level can be used reliably by */ + /* FreeType. It generally means that all offsets have been checked to */ + /* prevent out-of-bound reads, array counts are correct, etc. */ + /* */ + /* FT_VALIDATE_TIGHT :: */ + /* A table that passes this validation level can be used reliably and */ + /* doesn't contain invalid data. For example, a charmap table that */ + /* returns invalid glyph indices will not pass, even though it can */ + /* be used with FreeType in default mode (the library will simply */ + /* return an error later when trying to load the glyph). */ + /* */ + /* It also check that fields that must be a multiple of 2, 4, or 8 */ + /* dont' have incorrect values, etc. */ + /* */ + /* FT_VALIDATE_PARANOID :: */ + /* Only for font debugging. Checks that a table follows the */ + /* specification by 100%. Very few fonts will be able to pass this */ + /* level anyway but it can be useful for certain tools like font */ + /* editors/converters. */ + /* */ + typedef enum FT_ValidationLevel_ + { + FT_VALIDATE_DEFAULT = 0, + FT_VALIDATE_TIGHT, + FT_VALIDATE_PARANOID + + } FT_ValidationLevel; + + + /* validator structure */ + typedef struct FT_ValidatorRec_ + { + const FT_Byte* base; /* address of table in memory */ + const FT_Byte* limit; /* `base' + sizeof(table) in memory */ + FT_ValidationLevel level; /* validation level */ + FT_Error error; /* error returned. 0 means success */ + + ft_jmp_buf jump_buffer; /* used for exception handling */ + + } FT_ValidatorRec; + + +#define FT_VALIDATOR( x ) ((FT_Validator)( x )) + + + FT_BASE( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ); + + FT_BASE( FT_Int ) + ft_validator_run( FT_Validator valid ); + + /* Sets the error field in a validator, then calls `longjmp' to return */ + /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ + /* error checks within the validation routines. */ + /* */ + FT_BASE( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ); + + + /* Calls ft_validate_error. Assumes that the `valid' local variable */ + /* holds a pointer to the current validator object. */ + /* */ +#define FT_INVALID( _error ) ft_validator_error( valid, _error ) + + /* called when a broken table is detected */ +#define FT_INVALID_TOO_SHORT FT_INVALID( FT_Err_Invalid_Table ) + + /* called when an invalid offset is detected */ +#define FT_INVALID_OFFSET FT_INVALID( FT_Err_Invalid_Offset ) + + /* called when an invalid format/value is detected */ +#define FT_INVALID_FORMAT FT_INVALID( FT_Err_Invalid_Table ) + + /* called when an invalid glyph index is detected */ +#define FT_INVALID_GLYPH_ID FT_INVALID( FT_Err_Invalid_Glyph_Index ) + + /* called when an invalid field value is detected */ +#define FT_INVALID_DATA FT_INVALID( FT_Err_Invalid_Table ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R M A P S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to internal charmap object */ + typedef struct FT_CMapRec_* FT_CMap; + + /* handle to charmap class structure */ + typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; + + /* internal charmap object structure */ + typedef struct FT_CMapRec_ + { + FT_CharMapRec charmap; + FT_CMap_Class clazz; + + } FT_CMapRec; + + /* typecase any pointer to a charmap handle */ +#define FT_CMAP( x ) ((FT_CMap)( x )) + + /* obvious macros */ +#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id +#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id +#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding +#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face + + + /* class method definitions */ + typedef FT_Error + (*FT_CMap_InitFunc)( FT_CMap cmap, + FT_Pointer init_data ); + + typedef void + (*FT_CMap_DoneFunc)( FT_CMap cmap ); + + typedef FT_UInt + (*FT_CMap_CharIndexFunc)( FT_CMap cmap, + FT_UInt32 char_code ); + + typedef FT_UInt + (*FT_CMap_CharNextFunc)( FT_CMap cmap, + FT_UInt32 *achar_code ); + + + typedef struct FT_CMap_ClassRec_ + { + FT_UInt size; + FT_CMap_InitFunc init; + FT_CMap_DoneFunc done; + FT_CMap_CharIndexFunc char_index; + FT_CMap_CharNextFunc char_next; + + } FT_CMap_ClassRec; + + + /* create a new charmap and add it to charmap->face */ + FT_BASE( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ); + + /* destroy a charmap (don't remove it from face's list though) */ + FT_BASE( void ) + FT_CMap_Done( FT_CMap cmap ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Face_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Face */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* max_points :: The maximal number of points used to store the */ + /* vectorial outline of any glyph in this face. */ + /* If this value cannot be known in advance, or */ + /* if the face isn't scalable, this should be set */ + /* to 0. Only relevant for scalable formats. */ + /* */ + /* max_contours :: The maximal number of contours used to store */ + /* the vectorial outline of any glyph in this */ + /* face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this */ + /* should be set to 0. Only relevant for */ + /* scalable formats. */ + /* */ + /* transform_matrix :: A 2x2 matrix of 16.16 coefficients used to */ + /* transform glyph outlines after they are loaded */ + /* from the font. Only used by the convenience */ + /* functions. */ + /* */ + /* transform_delta :: A translation vector used to transform glyph */ + /* outlines after they are loaded from the font. */ + /* Only used by the convenience functions. */ + /* */ + /* transform_flags :: Some flags used to classify the transform. */ + /* Only used by the convenience functions. */ + /* */ + /* hint_flags :: Some flags used to change the hinters' */ + /* behaviour. Only used for debugging for now. */ + /* */ + /* postscript_name :: Postscript font name for this face. */ + /* */ + /* incremental_interface :: */ + /* If non-null, the interface through */ + /* which glyph data and metrics are loaded */ + /* incrementally for faces that do not provide */ + /* all of this data when first opened. */ + /* This field exists only if */ + /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ + /* */ + typedef struct FT_Face_InternalRec_ + { + FT_UShort max_points; + FT_Short max_contours; + + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; + + FT_UInt32 hint_flags; + + const char* postscript_name; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec* incremental_interface; +#endif + + } FT_Face_InternalRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Slot_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_GlyphSlot */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* loader :: The glyph loader object used to load outlines */ + /* into the glyph slot. */ + /* */ + /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ + /* must be transformed through a specific */ + /* font transformation. This is _not_ the same */ + /* as the face transform set through */ + /* FT_Set_Transform(). */ + /* */ + /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ + /* transformation, if necessary. */ + /* */ + /* glyph_delta :: The 2d translation vector corresponding to */ + /* the glyph transformation, if necessary. */ + /* */ + /* glyph_hints :: Format-specific glyph hints management. */ + /* */ + typedef struct FT_Slot_InternalRec_ + { + FT_GlyphLoader loader; + FT_Bool glyph_transformed; + FT_Matrix glyph_matrix; + FT_Vector glyph_delta; + void* glyph_hints; + + } FT_GlyphSlot_InternalRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ModuleRec */ + /* */ + /* <Description> */ + /* A module object instance. */ + /* */ + /* <Fields> */ + /* clazz :: A pointer to the module's class. */ + /* */ + /* library :: A handle to the parent library object. */ + /* */ + /* memory :: A handle to the memory manager. */ + /* */ + /* generic :: A generic structure for user-level extensibility (?). */ + /* */ + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + FT_Generic generic; + + } FT_ModuleRec; + + + /* typecast an object to a FT_Module */ +#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz +#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library +#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory + + +#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_font_driver ) + +#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_renderer ) + +#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_hinter ) + +#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_styler ) + +#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_driver_scalable ) + +#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_driver_no_outlines ) + +#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + ft_module_driver_has_hinter ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module_Interface */ + /* */ + /* <Description> */ + /* Finds a module and returns its specific interface as a typeless */ + /* pointer. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module-specific interface if available, 0 otherwise. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for, and what its interface is :-) */ + /* */ + FT_BASE( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + +#define FT_FACE( x ) ((FT_Face)(x)) +#define FT_SIZE( x ) ((FT_Size)(x)) +#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) + +#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver +#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library +#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory +#define FT_FACE_STREAM( x ) FT_FACE( x )->stream + +#define FT_SIZE_FACE( x ) FT_SIZE( x )->face +#define FT_SLOT_FACE( x ) FT_SLOT( x )->face + +#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph +#define FT_FACE_SIZE( x ) FT_FACE( x )->size + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_GlyphSlot */ + /* */ + /* <Description> */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_GlyphSlot */ + /* */ + /* <Description> */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* <Input> */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_BASE( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ); + + /* */ + + /* + * free the bitmap of a given glyphslot when needed + * (i.e. only when it was allocated with ft_glyphslot_alloc_bitmap) + */ + FT_BASE( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + + /* + * allocate a new bitmap buffer in a glyph slot + */ + FT_BASE( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ); + + /* + * set the bitmap buffer in a glyph slot to a given pointer. + * the buffer will not be freed by a later call to ft_glyphslot_free_bitmap + */ + FT_BASE( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Pointer buffer ); + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_RENDERER( x ) ((FT_Renderer)( x )) +#define FT_GLYPH( x ) ((FT_Glyph)( x )) +#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) + + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + FT_Glyph_Class glyph_class; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FT_Renderer_RenderFunc render; + + } FT_RendererRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* typecast a module into a driver easily */ +#define FT_DRIVER( x ) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ +#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_DriverRec */ + /* */ + /* <Description> */ + /* The root font driver class. A font driver is responsible for */ + /* managing and loading font files of a given format. */ + /* */ + /* <Fields> */ + /* root :: Contains the fields of the root module class. */ + /* */ + /* clazz :: A pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. `class' wasn't used */ + /* as it is a reserved word in C++. */ + /* */ + /* faces_list :: The list of faces currently opened by this */ + /* driver. */ + /* */ + /* extensions :: A typeless pointer to the driver's extensions */ + /* registry, if they are supported through the */ + /* configuration macro FT_CONFIG_OPTION_EXTENSIONS. */ + /* */ + /* glyph_loader :: The glyph loader for all faces managed by this */ + /* driver. This object isn't defined for unscalable */ + /* formats. */ + /* */ + typedef struct FT_DriverRec_ + { + FT_ModuleRec root; + FT_Driver_Class clazz; + + FT_ListRec faces_list; + void* extensions; + + FT_GlyphLoader glyph_loader; + + } FT_DriverRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R I E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_DEBUG_HOOK_TRUETYPE 0 +#define FT_DEBUG_HOOK_TYPE1 1 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_LibraryRec */ + /* */ + /* <Description> */ + /* The FreeType library class. This is the root of all FreeType */ + /* data. Use FT_New_Library() to create a library object, and */ + /* FT_Done_Library() to discard it and all child objects. */ + /* */ + /* <Fields> */ + /* memory :: The library's memory object. Manages memory */ + /* allocation. */ + /* */ + /* generic :: Client data variable. Used to extend the */ + /* Library class by higher levels and clients. */ + /* */ + /* num_modules :: The number of modules currently registered */ + /* within this library. This is set to 0 for new */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ + /* */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ + /* contains a list of its opened faces. */ + /* */ + /* renderers :: The list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: The current outline renderer. This is a */ + /* shortcut used to avoid parsing the list on */ + /* each call to FT_Outline_Render(). It is a */ + /* handle to the current renderer for the */ + /* FT_GLYPH_FORMAT_OUTLINE format. */ + /* */ + /* auto_hinter :: XXX */ + /* */ + /* raster_pool :: The raster object's render pool. This can */ + /* ideally be changed dynamically at run-time. */ + /* */ + /* raster_pool_size :: The size of the render pool in bytes. */ + /* */ + /* debug_hooks :: XXX */ + /* */ + typedef struct FT_LibraryRec_ + { + FT_Memory memory; /* library's memory manager */ + + FT_Generic generic; + + FT_Int version_major; + FT_Int version_minor; + FT_Int version_patch; + + FT_UInt num_modules; + FT_Module modules[FT_MAX_MODULES]; /* module objects */ + + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ + FT_Module auto_hinter; + + FT_Byte* raster_pool; /* scan-line conversion */ + /* render pool */ + FT_ULong raster_pool_size; /* size of render pool in bytes */ + + FT_DebugHook_Func debug_hooks[4]; + + FT_MetaClassRec meta_class; + + } FT_LibraryRec; + + + FT_BASE( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ); + + FT_BASE( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + typedef const char* + (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); + + typedef FT_Error + (*FT_Face_GetGlyphNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory */ + /* */ + /* <Description> */ + /* Creates a new memory object. */ + /* */ + /* <Return> */ + /* A pointer to the new memory object. 0 in case of error. */ + /* */ + FT_EXPORT( FT_Memory ) + FT_New_Memory( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Memory */ + /* */ + /* <Description> */ + /* Discards memory manager. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* */ + FT_EXPORT( void ) + FT_Done_Memory( FT_Memory memory ); + +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* Define default raster's interface. The default raster is located in */ + /* `src/base/ftraster.c'. */ + /* */ + /* Client applications can register new rasters through the */ + /* FT_Set_Raster() API. */ + +#ifndef FT_NO_DEFAULT_RASTER + FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; +#endif + + +FT_END_HEADER + +#endif /* __FTOBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/ftstream.h b/lib/freetype/include/freetype/internal/ftstream.h new file mode 100644 index 0000000..618f64a --- /dev/null +++ b/lib/freetype/include/freetype/internal/ftstream.h @@ -0,0 +1,498 @@ +/***************************************************************************/ +/* */ +/* ftstream.h */ +/* */ +/* Stream handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __FTSTREAM_H__ +#define __FTSTREAM_H__ + + +#include <ft2build.h> +#include FT_SYSTEM_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* format of an 8-bit frame_op value: */ + /* */ + /* bit 76543210 */ + /* xxxxxxes */ + /* */ + /* s is set to 1 if the value is signed. */ + /* e is set to 1 if the value is little-endian. */ + /* xxx is a command. */ + +#define FT_FRAME_OP_SHIFT 2 +#define FT_FRAME_OP_SIGNED 1 +#define FT_FRAME_OP_LITTLE 2 +#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) + +#define FT_MAKE_FRAME_OP( command, little, sign ) \ + ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) + +#define FT_FRAME_OP_END 0 +#define FT_FRAME_OP_START 1 /* start a new frame */ +#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ +#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ +#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ +#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ +#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ + + + typedef enum FT_Frame_Op_ + { + ft_frame_end = 0, + ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), + + ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), + ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), + + ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), + ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), + ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), + ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), + + ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), + ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), + ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), + ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), + + ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), + ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), + ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), + ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), + + ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), + ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) + + } FT_Frame_Op; + + + typedef struct FT_Frame_Field_ + { + FT_Byte value; + FT_Byte size; + FT_UShort offset; + + } FT_Frame_Field; + + + /* Construct an FT_Frame_Field out of a structure type and a field name. */ + /* The structure type must be set in the FT_STRUCTURE macro before */ + /* calling the FT_FRAME_START() macro. */ + /* */ +#define FT_FIELD_SIZE( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) + +#define FT_FIELD_SIZE_DELTA( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) + +#define FT_FIELD_OFFSET( f ) \ + (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) + +#define FT_FRAME_FIELD( frame_op, field ) \ + { \ + frame_op, \ + FT_FIELD_SIZE( field ), \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } + +#define FT_FRAME_START( size ) { ft_frame_start, 0, size } +#define FT_FRAME_END { ft_frame_end, 0, 0 } + +#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) +#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) +#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) +#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) +#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) +#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) + +#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) +#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) +#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) +#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) + +#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } +#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } +#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } + +#define FT_FRAME_BYTES( field, count ) \ + { \ + ft_frame_bytes, \ + count, \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } + + + /*************************************************************************/ + /* */ + /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ + /* type `char*' or equivalent (1-byte elements). */ + /* */ + +#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) +#define FT_INT8_( p, i ) ( ((const FT_Char*)(p))[(i)] ) + +#define FT_INT16( x ) ( (FT_Int16)(x) ) +#define FT_UINT16( x ) ( (FT_UInt16)(x) ) +#define FT_INT32( x ) ( (FT_Int32)(x) ) +#define FT_UINT32( x ) ( (FT_UInt32)(x) ) + +#define FT_BYTE_I16( p, i, s ) ( FT_INT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_I32( p, i, s ) ( FT_INT32( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + +#define FT_INT8_I16( p, i, s ) ( FT_INT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U16( p, i, s ) ( FT_UINT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_I32( p, i, s ) ( FT_INT32( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U32( p, i, s ) ( FT_UINT32( FT_INT8_( p, i ) ) << (s) ) + + +#define FT_PEEK_SHORT( p ) FT_INT16( FT_INT8_I16( p, 0, 8) | \ + FT_BYTE_I16( p, 1, 0) ) + +#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) + +#define FT_PEEK_LONG( p ) FT_INT32( FT_INT8_I32( p, 0, 24 ) | \ + FT_BYTE_I32( p, 1, 16 ) | \ + FT_BYTE_I32( p, 2, 8 ) | \ + FT_BYTE_I32( p, 3, 0 ) ) + +#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_OFF3( p ) FT_INT32( FT_INT8_I32( p, 0, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 2, 0 ) ) + +#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_INT8_I16( p, 1, 8 ) | \ + FT_BYTE_I16( p, 0, 0 ) ) + +#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_INT8_I32( p, 3, 24 ) | \ + FT_BYTE_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_INT8_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + + +#define FT_NEXT_CHAR( buffer ) \ + ( (signed char)*buffer++ ) + +#define FT_NEXT_BYTE( buffer ) \ + ( (unsigned char)*buffer++ ) + +#define FT_NEXT_SHORT( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) + +#define FT_NEXT_LONG( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) + + +#define FT_NEXT_SHORT_LE( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT_LE( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3_LE( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3_LE( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_LONG_LE( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG_LE( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) + + + /*************************************************************************/ + /* */ + /* Each GET_xxxx() macro uses an implicit `stream' variable. */ + /* */ +#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) + +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short ) +#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort ) +#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long ) +#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong ) +#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long ) +#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) +#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort ) +#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong ) + +#define FT_READ_MACRO( func, type, var ) \ + ( var = (type)func( stream, &error ), \ + error != FT_Err_Ok ) + +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var ) +#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var ) +#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var ) +#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var ) +#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var ) +#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var ) + +#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var ) +#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var ) +#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var ) +#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var ) + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /* initialize a stream for reading a regular system stream */ + FT_EXPORT( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ); + +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* initialize a stream for reading in-memory data */ + FT_BASE( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ); + + /* close a stream (does not destroy the stream structure) */ + FT_BASE( void ) + FT_Stream_Close( FT_Stream stream ); + + + /* seek within a stream. position is relative to start of stream */ + FT_BASE( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ); + + /* skip bytes in a stream */ + FT_BASE( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ); + + /* return current stream position */ + FT_BASE( FT_Long ) + FT_Stream_Pos( FT_Stream stream ); + + /* read bytes from a stream into a user-allocated buffer, returns an */ + /* error if not all bytes could be read. */ + FT_BASE( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* read bytes from a stream at a given position */ + FT_BASE( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ); + + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ + /* error if the frame could not be read/accessed. The caller can use */ + /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* error checks. */ + /* */ + /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* a stream frame! */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ); + + /* exit a stream frame */ + FT_BASE( void ) + FT_Stream_ExitFrame( FT_Stream stream ); + + /* Extract a stream frame. If the stream is disk-based, a heap block */ + /* is allocated and the frame bytes are read into it. If the stream */ + /* is memory-based, this function simply set a pointer to the data. */ + /* */ + /* Useful to optimize access to memory-based streams transparently. */ + /* */ + /* All extracted frames must be `freed` with a call to the function */ + /* FT_Stream_ReleaseFrame(). */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ); + + /* release an extract frame (see FT_Stream_ExtractFrame) */ + FT_BASE( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ); + + /* read a byte from an entered frame */ + FT_BASE( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ); + + /* read a 16-bit big-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShort( FT_Stream stream ); + + /* read a 24-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetOffset( FT_Stream stream ); + + /* read a 32-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLong( FT_Stream stream ); + + /* read a 16-bit little-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShortLE( FT_Stream stream ); + + /* read a 32-bit little-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLongLE( FT_Stream stream ); + + + /* read a byte from a stream */ + FT_BASE( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit big-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShort( FT_Stream stream, + FT_Error* error ); + + /* read a 24-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadOffset( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLong( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit little-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShortLE( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit little-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLongLE( FT_Stream stream, + FT_Error* error ); + + /* Read a structure from a stream. The structure must be described */ + /* by an array of FT_Frame_Field records. */ + FT_BASE( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ); + + +#define FT_STREAM_POS() \ + FT_Stream_Pos( stream ) + +#define FT_STREAM_SEEK( position ) \ + FT_SET_ERROR( FT_Stream_Seek( stream, position ) ) + +#define FT_STREAM_SKIP( distance ) \ + FT_SET_ERROR( FT_Stream_Skip( stream, distance ) ) + +#define FT_STREAM_READ( buffer, count ) \ + FT_SET_ERROR( FT_Stream_Read( stream, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_AT( position, buffer, count ) \ + FT_SET_ERROR( FT_Stream_ReadAt( stream, \ + position, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_FIELDS( fields, object ) \ + FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) + + +#define FT_FRAME_ENTER( size ) \ + FT_SET_ERROR( FT_Stream_EnterFrame( stream, size ) ) + +#define FT_FRAME_EXIT() \ + FT_Stream_ExitFrame( stream ) + +#define FT_FRAME_EXTRACT( size, bytes ) \ + FT_SET_ERROR( FT_Stream_ExtractFrame( stream, size, \ + (FT_Byte**)&(bytes) ) ) + +#define FT_FRAME_RELEASE( bytes ) \ + FT_Stream_ReleaseFrame( stream, (FT_Byte**)&(bytes) ) + + +FT_END_HEADER + +#endif /* __FTSTREAM_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/fttrace.h b/lib/freetype/include/freetype/internal/fttrace.h new file mode 100644 index 0000000..ffc0b14 --- /dev/null +++ b/lib/freetype/include/freetype/internal/fttrace.h @@ -0,0 +1,106 @@ +/***************************************************************************/ +/* */ +/* fttrace.h */ +/* */ +/* Tracing handling (specification only). */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + + +/* definitions of trace levels for FreeType 2 */ + +/* the first level must always be `trace_any' */ +FT_TRACE_DEF( any ) + +/* base components */ +FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ +FT_TRACE_DEF( list ) /* list management (ftlist.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ +FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ +FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ + +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ + +/* Cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc..) */ + +/* SFNT driver components */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ +FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ + +/* TrueType driver components */ +FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ +FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ +FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ +FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ + +/* Type 1 driver components */ +FT_TRACE_DEF( t1driver ) +FT_TRACE_DEF( t1gload ) +FT_TRACE_DEF( t1hint ) +FT_TRACE_DEF( t1load ) +FT_TRACE_DEF( t1objs ) +FT_TRACE_DEF( t1parse ) + +/* PostScript helper module `psaux' */ +FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( psobjs ) + +/* PostScript hinting module `pshinter' */ +FT_TRACE_DEF( pshrec ) +FT_TRACE_DEF( pshalgo1 ) +FT_TRACE_DEF( pshalgo2 ) + +/* Type 2 driver components */ +FT_TRACE_DEF( cffdriver ) +FT_TRACE_DEF( cffgload ) +FT_TRACE_DEF( cffload ) +FT_TRACE_DEF( cffobjs ) +FT_TRACE_DEF( cffparse ) + +/* Type 42 driver component */ +FT_TRACE_DEF( t42 ) + +/* CID driver components */ +FT_TRACE_DEF( cidafm ) +FT_TRACE_DEF( ciddriver ) +FT_TRACE_DEF( cidgload ) +FT_TRACE_DEF( cidload ) +FT_TRACE_DEF( cidobjs ) +FT_TRACE_DEF( cidparse ) + +/* Windows fonts component */ +FT_TRACE_DEF( winfnt ) + +/* PCF fonts components */ +FT_TRACE_DEF( pcfdriver ) +FT_TRACE_DEF( pcfread ) + +/* BDF fonts component */ +FT_TRACE_DEF( bdfdriver ) +FT_TRACE_DEF( bdflib ) + +/* PFR fonts component */ +FT_TRACE_DEF( pfr ) + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/internal.h b/lib/freetype/include/freetype/internal/internal.h new file mode 100644 index 0000000..872f6ac --- /dev/null +++ b/lib/freetype/include/freetype/internal/internal.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* internal.h */ +/* */ +/* Internal header files (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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 automatically included by `ft2build.h'. */ + /* Do not include it manually! */ + /* */ + /*************************************************************************/ + + +#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> +#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> +#define FT_INTERNAL_EXTENSION_H <freetype/internal/ftextend.h> +#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> +#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_EXTEND_H <freetype/internal/ftextend.h> +#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> +#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> +#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> +#define FT_INTERNAL_OBJECT_H <freetype/internal/ftobject.h> + +#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> +#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> +#define FT_INTERNAL_TYPE42_TYPES_H <freetype/internal/t42types.h> +#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h> +#define FT_INTERNAL_FNT_TYPES_H <freetype/internal/fnttypes.h> +#define FT_INTERNAL_BDF_TYPES_H <freetype/internal/bdftypes.h> +#define FT_INTERNAL_PFR_H <freetype/internal/pfr.h> + +#define FT_INTERNAL_POSTSCRIPT_NAMES_H <freetype/internal/psnames.h> +#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> +#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> +#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> + +#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/pcftypes.h b/lib/freetype/include/freetype/internal/pcftypes.h new file mode 100644 index 0000000..2c924d7 --- /dev/null +++ b/lib/freetype/include/freetype/internal/pcftypes.h @@ -0,0 +1,56 @@ +/* pcftypes.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000-2001 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __PCFTYPES_H__ +#define __PCFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct PCF_Public_FaceRec_ + { + FT_FaceRec root; + FT_StreamRec gzip_stream; + FT_Stream gzip_source; + + char* charset_encoding; + char* charset_registry; + + } PCF_Public_FaceRec, *PCF_Public_Face; + + +FT_END_HEADER + +#endif /* __PCFTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/pfr.h b/lib/freetype/include/freetype/internal/pfr.h new file mode 100644 index 0000000..cead078 --- /dev/null +++ b/lib/freetype/include/freetype/internal/pfr.h @@ -0,0 +1,36 @@ +#ifndef __FT_INTERNAL_PFR_H__ +#define __FT_INTERNAL_PFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +FT_BEGIN_HEADER + + typedef FT_Error (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + typedef struct FT_PFR_ServiceRec_ + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + } FT_PFR_ServiceRec, *FT_PFR_Service; + +#define FT_PFR_SERVICE_NAME "pfr" + +FT_END_HEADER + +#endif /* __FT_INTERNAL_PFR_H__ */ diff --git a/lib/freetype/include/freetype/internal/psaux.h b/lib/freetype/include/freetype/internal/psaux.h new file mode 100644 index 0000000..e79f83a --- /dev/null +++ b/lib/freetype/include/freetype/internal/psaux.h @@ -0,0 +1,717 @@ +/***************************************************************************/ +/* */ +/* psaux.h */ +/* */ +/* Auxiliary functions and data structures related to PostScript fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __PSAUX_H__ +#define __PSAUX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_TableRec_* PS_Table; + typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Table_FuncsRec */ + /* */ + /* <Description> */ + /* A set of function pointers to manage PS_Table objects. */ + /* */ + /* <Fields> */ + /* table_init :: Used to initialize a table. */ + /* */ + /* table_done :: Finalizes resp. destroy a given table. */ + /* */ + /* table_add :: Adds a new object to a table. */ + /* */ + /* table_release :: Releases table data, then finalizes it. */ + /* */ + typedef struct PS_Table_FuncsRec_ + { + FT_Error + (*init)( PS_Table table, + FT_Int count, + FT_Memory memory ); + + void + (*done)( PS_Table table ); + + FT_Error + (*add)( PS_Table table, + FT_Int index, + void* object, + FT_Int length ); + + void + (*release)( PS_Table table ); + + } PS_Table_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_TableRec */ + /* */ + /* <Description> */ + /* A PS_Table is a simple object used to store an array of objects in */ + /* a single memory block. */ + /* */ + /* <Fields> */ + /* block :: The address in memory of the growheap's block. This */ + /* can change between two object adds, due to */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + typedef struct PS_TableRec_ + { + FT_Byte* block; /* current memory block */ + FT_Offset cursor; /* current cursor in memory block */ + FT_Offset capacity; /* current size of memory block */ + FT_Long init; + + FT_Int max_elems; + FT_Int num_elems; + FT_Byte** elements; /* addresses of table elements */ + FT_Int* lengths; /* lengths of table elements */ + + FT_Memory memory; + PS_Table_FuncsRec funcs; + + } PS_TableRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PS_ParserRec_* PS_Parser; + + typedef struct T1_TokenRec_* T1_Token; + + typedef struct T1_FieldRec_* T1_Field; + + + /* simple enumeration type used to identify token types */ + typedef enum T1_TokenType_ + { + T1_TOKEN_TYPE_NONE = 0, + T1_TOKEN_TYPE_ANY, + T1_TOKEN_TYPE_STRING, + T1_TOKEN_TYPE_ARRAY, + + /* do not remove */ + T1_TOKEN_TYPE_MAX + + } T1_TokenType; + + + /* a simple structure used to identify tokens */ + typedef struct T1_TokenRec_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_TokenType type; /* type of token */ + + } T1_TokenRec; + + + /* enumeration type used to identify object fields */ + typedef enum T1_FieldType_ + { + T1_FIELD_TYPE_NONE = 0, + T1_FIELD_TYPE_BOOL, + T1_FIELD_TYPE_INTEGER, + T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_BBOX, + T1_FIELD_TYPE_INTEGER_ARRAY, + T1_FIELD_TYPE_FIXED_ARRAY, + T1_FIELD_TYPE_CALLBACK, + + /* do not remove */ + T1_FIELD_TYPE_MAX + + } T1_FieldType; + + + typedef enum T1_FieldLocation_ + { + T1_FIELD_LOCATION_CID_INFO, + T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_INFO, + T1_FIELD_LOCATION_PRIVATE, + T1_FIELD_LOCATION_BBOX, + + /* do not remove */ + T1_FIELD_LOCATION_MAX + + } T1_FieldLocation; + + + typedef void + (*T1_Field_ParseFunc)( FT_Face face, + FT_Pointer parser ); + + + /* structure type used to model object fields */ + typedef struct T1_FieldRec_ + { + const char* ident; /* field identifier */ + T1_FieldLocation location; + T1_FieldType type; /* type of field */ + T1_Field_ParseFunc reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximal number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays */ + } T1_FieldRec; + + +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0 \ + }, + +#define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \ + { \ + _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ + (T1_Field_ParseFunc)_reader, \ + 0, 0, \ + 0, 0 \ + }, + +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ) \ + }, + +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0 \ + }, + + +#define T1_FIELD_TYPE_BOOL( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname ) + +#define T1_FIELD_NUM( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname ) + +#define T1_FIELD_FIXED( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname ) + +#define T1_FIELD_STRING( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname ) + +#define T1_FIELD_BBOX( _ident, _fname ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname ) + + +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax ) + +#define T1_FIELD_CALLBACK( _ident, _name ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; + + typedef struct PS_Parser_FuncsRec_ + { + void + (*init)( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void + (*done)( PS_Parser parser ); + + void + (*skip_spaces)( PS_Parser parser ); + void + (*skip_alpha)( PS_Parser parser ); + + FT_Long + (*to_int)( PS_Parser parser ); + FT_Fixed + (*to_fixed)( PS_Parser parser, + FT_Int power_ten ); + FT_Int + (*to_coord_array)( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int + (*to_fixed_array)( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void + (*to_token)( PS_Parser parser, + T1_Token token ); + void + (*to_token_array)( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_Error + (*load_field)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error + (*load_field_table)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } PS_Parser_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_ParserRec */ + /* */ + /* <Description> */ + /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ + /* */ + /* <Fields> */ + /* cursor :: The current position in the text. */ + /* */ + /* base :: Start of the processed text. */ + /* */ + /* limit :: End of the processed text. */ + /* */ + /* error :: The last error returned. */ + /* */ + /* memory :: The object used for memory operations (alloc/realloc). */ + /* */ + /* funcs :: A table of functions for the parser. */ + /* */ + typedef struct PS_ParserRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + PS_Parser_FuncsRec funcs; + + } PS_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_BuilderRec_* T1_Builder; + + + typedef FT_Error + (*T1_Builder_Check_Points_Func)( T1_Builder builder, + FT_Int count ); + + typedef void + (*T1_Builder_Add_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef FT_Error + (*T1_Builder_Add_Point1_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error + (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); + + typedef FT_Error + (*T1_Builder_Start_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef void + (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); + + + typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; + + typedef struct T1_Builder_FuncsRec_ + { + void + (*init)( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Bool hinting ); + + void + (*done)( T1_Builder builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Point_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* T1_BuilderRec */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* max_points :: maximum points in builder outline */ + /* */ + /* max_contours :: Maximal number of contours in builder outline. */ + /* */ + /* last :: The last point position. */ + /* */ + /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ + /* */ + /* scale_y :: The vertical scale (FUnits to sub-pixels). */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* error :: An error code that is only used to report memory */ + /* allocation problems. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + typedef struct T1_BuilderRec_ + { + FT_Memory memory; + FT_Face face; + FT_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Vector last; + + FT_Fixed scale_x; + FT_Fixed scale_y; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + FT_Bool shift; + + FT_Error error; /* only used for memory errors */ + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + T1_Builder_FuncsRec funcs; + + } T1_BuilderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 0 + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 8 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 32 + +#endif /* 0 */ + + + typedef struct T1_Decoder_ZoneRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + } T1_Decoder_ZoneRec, *T1_Decoder_Zone; + + + typedef struct T1_DecoderRec_* T1_Decoder; + typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; + + + typedef FT_Error + (*T1_Decoder_Callback)( T1_Decoder decoder, + FT_UInt glyph_index ); + + + typedef struct T1_Decoder_FuncsRec_ + { + FT_Error + (*init)( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback callback ); + + void + (*done)( T1_Decoder decoder ); + + FT_Error + (*parse_charstrings)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + } T1_Decoder_FuncsRec; + + + typedef struct T1_DecoderRec_ + { + T1_BuilderRec builder; + + FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; + FT_Long* top; + + T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; + T1_Decoder_Zone zone; + + PSNames_Service psnames; /* for seac */ + FT_UInt num_glyphs; + FT_Byte** glyph_names; + + FT_Int lenIV; /* internal for sub routine calls */ + FT_UInt num_subrs; + FT_Byte** subrs; + FT_Int* subrs_len; /* array of subrs length (optional) */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + PS_Blend blend; /* for multiple master support */ + + FT_UInt32 hint_flags; + FT_Render_Mode hint_mode; + + T1_Decoder_Callback parse_callback; + T1_Decoder_FuncsRec funcs; + + } T1_DecoderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CHARMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; + + typedef struct T1_CMap_ClassesRec_ + { + FT_CMap_Class standard; + FT_CMap_Class expert; + FT_CMap_Class custom; + FT_CMap_Class unicode; + + } T1_CMap_ClassesRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSAux_ServiceRec_ + { + /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ + const PS_Table_FuncsRec* ps_table_funcs; + const PS_Parser_FuncsRec* ps_parser_funcs; + const T1_Builder_FuncsRec* t1_builder_funcs; + const T1_Decoder_FuncsRec* t1_decoder_funcs; + + void + (*t1_decrypt)( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + T1_CMap_Classes t1_cmap_classes; + + } PSAux_ServiceRec, *PSAux_Service; + + /* backwards-compatible type definition */ + typedef PSAux_ServiceRec PSAux_Interface; + +FT_END_HEADER + +#endif /* __PSAUX_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/pshints.h b/lib/freetype/include/freetype/internal/pshints.h new file mode 100644 index 0000000..15571d9 --- /dev/null +++ b/lib/freetype/include/freetype/internal/pshints.h @@ -0,0 +1,626 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Interface to Postscript-specific (Type 1 and Type 2) hints */ +/* recorders (specification only). These are used to support native */ +/* T1/T2 hints in the "type1", "cid" and "cff" font drivers. */ +/* */ +/* Copyright 2001, 2002 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 __PSHINTS_H__ +#define __PSHINTS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INTERNAL REPRESENTATION OF GLOBALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSH_GlobalsRec_* PSH_Globals; + + typedef FT_Error + (*PSH_Globals_NewFunc)( FT_Memory memory, + T1_Private* private_dict, + PSH_Globals* aglobals ); + + typedef FT_Error + (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + typedef void + (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); + + + typedef struct PSH_Globals_FuncsRec_ + { + PSH_Globals_NewFunc create; + PSH_Globals_SetScaleFunc set_scale; + PSH_Globals_DestroyFunc destroy; + + } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 1 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* @type: */ + /* T1_Hints */ + /* */ + /* @description: */ + /* This is a handle to an opaque structure used to record glyph hints */ + /* from a Type 1 character glyph character string. */ + /* */ + /* The methods used to operate on this object are defined by the */ + /* @T1_Hints_FuncsRec structure. Recording glyph hints is normally */ + /* achieved through the following scheme: */ + /* */ + /* - Open a new hint recording session by calling the "open" method. */ + /* This will rewind the recorder and prepare it for new input. */ + /* */ + /* - For each hint found in the glyph charstring, call the */ + /* corresponding method ("stem", "stem3", or "reset"). Note that */ + /* these functions do not return an error code. */ + /* */ + /* - Close the recording session by calling the "close" method. It */ + /* will return an error code if the hints were invalid or something */ + /* strange happened (e.g. memory shortage). */ + /* */ + /* The hints accumulated in the object can later be used by the */ + /* PostScript hinter. */ + /* */ + typedef struct T1_HintsRec_* T1_Hints; + + + /*************************************************************************/ + /* */ + /* @type: */ + /* T1_Hints_Funcs */ + /* */ + /* @description: */ + /* A pointer to the @T1_Hints_FuncsRec structure that defines the */ + /* API of a given @T1_Hints object. */ + /* */ + typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_OpenFunc */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to prepare it for a new */ + /* Type 1 hints recording session. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* @note: */ + /* You should always call the @T1_Hints_CloseFunc method in order to */ + /* close an opened recording session. */ + /* */ + typedef void + (*T1_Hints_OpenFunc)( T1_Hints hints ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_SetStemFunc */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to record a new horizontal or */ + /* vertical stem. This corresponds to the Type 1 "hstem" and "vstem" */ + /* operators. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* dimension :: 0 for horizontal stems (hstem), 1 for vertical ones */ + /* (vstem). */ + /* */ + /* coords :: Array of 2 integers, used as (position,length) stem */ + /* descriptor. */ + /* */ + /* @note: */ + /* Use vertical coordinates (y) for horizontal stems (dim=0). Use */ + /* horizontal coordinates (x) for vertical stems (dim=1). */ + /* */ + /* "coords[0]" is the absolute stem position (lowest coordinate); */ + /* "coords[1]" is the length. */ + /* */ + /* The length can be negative, in which case it must be either -20 or */ + /* -21. It will be interpreted as a "ghost" stem, according to */ + /* Type 1 specification. */ + /* */ + /* If the length is -21 (corresponding to a bottom ghost stem), then */ + /* the real stem position is "coords[0]+coords[1]". */ + /* */ + typedef void + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_SetStem3Func */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to record three */ + /* counter-controlled horizontal or vertical stems at once. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* dimension :: 0 for horizontal stems, 1 for vertical ones. */ + /* */ + /* coords :: An array of 6 integers, holding 3 (position,length) */ + /* pairs for the counter-controlled stems. */ + /* */ + /* @note: */ + /* Use vertical coordinates (y) for horizontal stems (dim=0). Use */ + /* horizontal coordinates (x) for vertical stems (dim=1). */ + /* */ + /* The lengths cannot be negative (ghost stems are never */ + /* counter-controlled). */ + /* */ + typedef void + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_ResetFunc */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to reset the stems hints in a */ + /* recording session. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* end_point :: The index of the last point in the input glyph in */ + /* which the previously defined hints apply. */ + /* */ + typedef void + (*T1_Hints_ResetFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_CloseFunc */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to close a hint recording */ + /* session. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* end_point :: The index of the last point in the input glyph. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* The error code will be set to indicate that an error occured */ + /* during the recording session. */ + /* */ + typedef FT_Error + (*T1_Hints_CloseFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T1_Hints_ApplyFunc */ + /* */ + /* @description: */ + /* A method of the @T1_Hints class used to apply hints to the */ + /* corresponding glyph outline. Must be called once all hints have */ + /* been recorded. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 1 hints recorder. */ + /* */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* globals :: The hinter globals for this font. */ + /* */ + /* hint_flags :: Hinter bit flags. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* On input, all points within the outline are in font coordinates. */ + /* On output, they are in 1/64th of pixels. */ + /* */ + /* The scaling transformation is taken from the "globals" object */ + /* which must correspond to the same font as the glyph. */ + /* */ + typedef FT_Error + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* T1_Hints_FuncsRec */ + /* */ + /* @description: */ + /* The structure used to provide the API to @T1_Hints objects. */ + /* */ + /* @fields: */ + /* hints :: A handle to the T1 Hints recorder. */ + /* */ + /* open :: The function to open a recording session. */ + /* */ + /* close :: The function to close a recording session. */ + /* */ + /* stem :: The function to set a simple stem. */ + /* */ + /* stem3 :: The function to set counter-controlled stems. */ + /* */ + /* reset :: The function to reset stem hints. */ + /* */ + /* apply :: The function to apply the hints to the corresponding */ + /* glyph outline. */ + /* */ + typedef struct T1_Hints_FuncsRec_ + { + T1_Hints hints; + T1_Hints_OpenFunc open; + T1_Hints_CloseFunc close; + T1_Hints_SetStemFunc stem; + T1_Hints_SetStem3Func stem3; + T1_Hints_ResetFunc reset; + T1_Hints_ApplyFunc apply; + + } T1_Hints_FuncsRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 2 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* @type: */ + /* T2_Hints */ + /* */ + /* @description: */ + /* This is a handle to an opaque structure used to record glyph hints */ + /* from a Type 2 character glyph character string. */ + /* */ + /* The methods used to operate on this object are defined by the */ + /* @T2_Hints_FuncsRec structure. Recording glyph hints is normally */ + /* achieved through the following scheme: */ + /* */ + /* - Open a new hint recording session by calling the "open" method. */ + /* This will rewind the recorder and prepare it for new input. */ + /* */ + /* - For each hint found in the glyph charstring, call the */ + /* corresponding method ("stems", "hintmask", "counters"). Note */ + /* that these functions do not return an error code. */ + /* */ + /* - Close the recording session by calling the "close" method. It */ + /* will return an error code if the hints were invalid or something */ + /* strange happened (e.g. memory shortage). */ + /* */ + /* The hints accumulated in the object can later be used by the */ + /* Postscript hinter. */ + /* */ + typedef struct T2_HintsRec_* T2_Hints; + + + /*************************************************************************/ + /* */ + /* @type: */ + /* T2_Hints_Funcs */ + /* */ + /* @description: */ + /* A pointer to the @T2_Hints_FuncsRec structure that defines the API */ + /* of a given @T2_Hints object. */ + /* */ + typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_OpenFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to prepare it for a new */ + /* Type 2 hints recording session. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* @note: */ + /* You should always call the @T2_Hints_CloseFunc method in order to */ + /* close an opened recording session. */ + /* */ + typedef void + (*T2_Hints_OpenFunc)( T2_Hints hints ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_StemsFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to set the table of stems in */ + /* either the vertical or horizontal dimension. Equivalent to the */ + /* "hstem", "vstem", "hstemhm", and "vstemhm" Type 2 operators. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* dimension :: 0 for horizontal stems (hstem), 1 for vertical ones */ + /* (vstem). */ + /* */ + /* count :: The number of stems. */ + /* */ + /* coords :: An array of "count" (position,length) pairs. */ + /* */ + /* @note: */ + /* Use vertical coordinates (y) for horizontal stems (dim=0). Use */ + /* horizontal coordinates (x) for vertical stems (dim=1). */ + /* */ + /* There are "2*count" elements in the "coords" aray. Each even */ + /* element is an absolute position in font units, each odd element is */ + /* a length in font units. */ + /* */ + /* A length can be negative, in which case it must be either -20 or */ + /* -21. It will be interpreted as a "ghost" stem, according to the */ + /* Type 1 specification. */ + /* */ + typedef void + (*T2_Hints_StemsFunc)( T2_Hints hints, + FT_UInt dimension, + FT_UInt count, + FT_Fixed* coordinates ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_MaskFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to set a given hintmask */ + /* (this corresponds to the "hintmask" Type 2 operator). */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* end_point :: The glyph index of the last point to which the */ + /* previously defined/activated hints apply. */ + /* */ + /* bit_count :: The number of bits in the hint mask. */ + /* */ + /* bytes :: An array of bytes modelling the hint mask. */ + /* */ + /* @note: */ + /* If the hintmask starts the charstring (before any glyph point */ + /* definition), the value of "end_point" should be 0. */ + /* */ + /* "bit_count" is the number of meaningful bits in the "bytes" array; */ + /* it must be equal to the total number of hints defined so far */ + /* (i.e. horizontal+verticals). */ + /* */ + /* The "bytes" array can come directly from the Type 2 charstring and */ + /* respects the same format. */ + /* */ + typedef void + (*T2_Hints_MaskFunc)( T2_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_CounterFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to set a given counter mask */ + /* (this corresponds to the "hintmask" Type 2 operator). */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* end_point :: A glyph index of the last point to which the */ + /* previously defined/active hints apply. */ + /* */ + /* bit_count :: The number of bits in the hint mask. */ + /* */ + /* bytes :: An array of bytes modelling the hint mask. */ + /* */ + /* @note: */ + /* If the hintmask starts the charstring (before any glyph point */ + /* definition), the value of "end_point" should be 0. */ + /* */ + /* "bit_count" is the number of meaningful bits in the "bytes" array; */ + /* it must be equal to the total number of hints defined so far */ + /* (i.e. horizontal+verticals). */ + /* */ + /* The "bytes" array can come directly from the Type 2 charstring and */ + /* respects the same format. */ + /* */ + typedef void + (*T2_Hints_CounterFunc)( T2_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_CloseFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to close a hint recording */ + /* session. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* end_point :: The index of the last point in the input glyph. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* The error code will be set to indicate that an error occured */ + /* during the recording session. */ + /* */ + typedef FT_Error + (*T2_Hints_CloseFunc)( T2_Hints hints, + FT_UInt end_point ); + + + /*************************************************************************/ + /* */ + /* @functype: */ + /* T2_Hints_ApplyFunc */ + /* */ + /* @description: */ + /* A method of the @T2_Hints class used to apply hints to the */ + /* corresponding glyph outline. Must be called after the "close" */ + /* method. */ + /* */ + /* @input: */ + /* hints :: A handle to the Type 2 hints recorder. */ + /* */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* globals :: The hinter globals for this font. */ + /* */ + /* hint_flags :: Hinter bit flags. */ + /* */ + /* @return: */ + /* FreeType error code. 0 means success. */ + /* */ + /* @note: */ + /* On input, all points within the outline are in font coordinates. */ + /* On output, they are in 1/64th of pixels. */ + /* */ + /* The scaling transformation is taken from the "globals" object */ + /* which must correspond to the same font than the glyph. */ + /* */ + typedef FT_Error + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /*************************************************************************/ + /* */ + /* @struct: */ + /* T2_Hints_FuncsRec */ + /* */ + /* @description: */ + /* The structure used to provide the API to @T2_Hints objects. */ + /* */ + /* @fields: */ + /* hints :: A handle to the T2 hints recorder object. */ + /* */ + /* open :: The function to open a recording session. */ + /* */ + /* close :: The function to close a recording session. */ + /* */ + /* stems :: The function to set the dimension's stems table. */ + /* */ + /* hintmask :: The function to set hint masks. */ + /* */ + /* counter :: The function to set counter masks. */ + /* */ + /* apply :: The function to apply the hints on the corresponding */ + /* glyph outline. */ + /* */ + typedef struct T2_Hints_FuncsRec_ + { + T2_Hints hints; + T2_Hints_OpenFunc open; + T2_Hints_CloseFunc close; + T2_Hints_StemsFunc stems; + T2_Hints_MaskFunc hintmask; + T2_Hints_CounterFunc counter; + T2_Hints_ApplyFunc apply; + + } T2_Hints_FuncsRec; + + + /* */ + + + typedef struct PSHinter_Interface_ + { + PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); + T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); + T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); + + } PSHinter_Interface; + + typedef PSHinter_Interface* PSHinter_Service; + + +FT_END_HEADER + +#endif /* __PSHINTS_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/psnames.h b/lib/freetype/include/freetype/internal/psnames.h new file mode 100644 index 0000000..0f4ec86 --- /dev/null +++ b/lib/freetype/include/freetype/internal/psnames.h @@ -0,0 +1,241 @@ +/***************************************************************************/ +/* */ +/* psnames.h */ +/* */ +/* High-level interface for the `PSNames' module (in charge of */ +/* various functions related to Postscript glyph names conversion). */ +/* */ +/* Copyright 1996-2001, 2002 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 __PSNAMES_H__ +#define __PSNAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* PS_Unicode_Value_Func */ + /* */ + /* <Description> */ + /* A function used to return the Unicode index corresponding to a */ + /* given glyph name. */ + /* */ + /* <Input> */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The Unicode character index resp. the non-Unicode value 0xFFFF if */ + /* the glyph name has no known Unicode meaning. */ + /* */ + /* <Note> */ + /* This function is able to map several different glyph names to the */ + /* same Unicode value, according to the rules defined in the Adobe */ + /* Glyph List table. */ + /* */ + /* This function will not be compiled if the configuration macro */ + /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ + /* */ + typedef FT_UInt32 + (*PS_Unicode_Value_Func)( const char* glyph_name ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* PS_Unicode_Index_Func */ + /* */ + /* <Description> */ + /* A function used to return the glyph index corresponding to a given */ + /* Unicode value. */ + /* */ + /* <Input> */ + /* num_glyphs :: The number of glyphs in the face. */ + /* */ + /* glyph_names :: An array of glyph name pointers. */ + /* */ + /* unicode :: The Unicode value. */ + /* */ + /* <Return> */ + /* The glyph index resp. 0xFFFF if no glyph corresponds to this */ + /* Unicode value. */ + /* */ + /* <Note> */ + /* This function is able to recognize several glyph names per Unicode */ + /* value, according to the Adobe Glyph List. */ + /* */ + /* This function will not be compiled if the configuration macro */ + /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ + /* */ + typedef FT_UInt + (*PS_Unicode_Index_Func)( FT_UInt num_glyphs, + const char** glyph_names, + FT_ULong unicode ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* PS_Macintosh_Name_Func */ + /* */ + /* <Description> */ + /* A function used to return the glyph name corresponding to an Apple */ + /* glyph name index. */ + /* */ + /* <Input> */ + /* name_index :: The index of the Mac name. */ + /* */ + /* <Return> */ + /* The glyph name, or 0 if the index is invalid. */ + /* */ + /* <Note> */ + /* This function will not be compiled if the configuration macro */ + /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ + /* */ + typedef const char* + (*PS_Macintosh_Name_Func)( FT_UInt name_index ); + + + typedef const char* + (*PS_Adobe_Std_Strings_Func)( FT_UInt string_index ); + + + typedef struct PS_UniMap_ + { + FT_UInt unicode; + FT_UInt glyph_index; + + } PS_UniMap; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Unicodes */ + /* */ + /* <Description> */ + /* A simple table used to map Unicode values to glyph indices. It is */ + /* built by the PS_Build_Unicodes table according to the glyphs */ + /* present in a font file. */ + /* */ + /* <Fields> */ + /* num_codes :: The number of glyphs in the font that match a given */ + /* Unicode value. */ + /* */ + /* unicodes :: An array of unicode values, sorted in increasing */ + /* order. */ + /* */ + /* gindex :: An array of glyph indices, corresponding to each */ + /* Unicode value. */ + /* */ + /* <Note> */ + /* Use the function PS_Lookup_Unicode() to retrieve the glyph index */ + /* corresponding to a given Unicode character code. */ + /* */ + typedef struct PS_Unicodes_ + { + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_Unicodes; + + + typedef FT_Error + (*PS_Build_Unicodes_Func)( FT_Memory memory, + FT_UInt num_glyphs, + const char** glyph_names, + PS_Unicodes* unicodes ); + + typedef FT_UInt + (*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes, + FT_UInt unicode ); + + typedef FT_ULong + (*PS_Next_Unicode_Func)( PS_Unicodes* unicodes, + FT_ULong unicode ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PSNames_Interface */ + /* */ + /* <Description> */ + /* This structure defines the PSNames interface. */ + /* */ + /* <Fields> */ + /* unicode_value :: A function used to convert a glyph name */ + /* into a Unicode character code. */ + /* */ + /* build_unicodes :: A function which builds up the Unicode */ + /* mapping table. */ + /* */ + /* lookup_unicode :: A function used to return the glyph index */ + /* corresponding to a given Unicode */ + /* character. */ + /* */ + /* macintosh_name :: A function used to return the standard */ + /* Apple glyph Postscript name corresponding */ + /* to a given string index (used by the */ + /* TrueType `post' table). */ + /* */ + /* adobe_std_strings :: A function that returns a pointer to a */ + /* Adobe Standard String for a given SID. */ + /* */ + /* adobe_std_encoding :: A table of 256 unsigned shorts that maps */ + /* character codes in the Adobe Standard */ + /* Encoding to SIDs. */ + /* */ + /* adobe_expert_encoding :: A table of 256 unsigned shorts that maps */ + /* character codes in the Adobe Expert */ + /* Encoding to SIDs. */ + /* */ + /* <Note> */ + /* `unicode_value' and `unicode_index' will be set to 0 if the */ + /* configuration macro FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is */ + /* undefined. */ + /* */ + /* `macintosh_name' will be set to 0 if the configuration macro */ + /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ + /* */ + typedef struct PSNames_Interface_ + { + PS_Unicode_Value_Func unicode_value; + PS_Build_Unicodes_Func build_unicodes; + PS_Lookup_Unicode_Func lookup_unicode; + PS_Macintosh_Name_Func macintosh_name; + + PS_Adobe_Std_Strings_Func adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + + PS_Next_Unicode_Func next_unicode; + + } PSNames_Interface; + + + typedef PSNames_Interface* PSNames_Service; + + +FT_END_HEADER + +#endif /* __PSNAMES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/sfnt.h b/lib/freetype/include/freetype/internal/sfnt.h new file mode 100644 index 0000000..c5f3bd3 --- /dev/null +++ b/lib/freetype/include/freetype/internal/sfnt.h @@ -0,0 +1,549 @@ +/***************************************************************************/ +/* */ +/* sfnt.h */ +/* */ +/* High-level `sfnt' driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __SFNT_H__ +#define __SFNT_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Init_Face_Func */ + /* */ + /* <Description> */ + /* First part of the SFNT face object initialization. This will find */ + /* the face in a SFNT file or collection, and load its format tag in */ + /* face->format_tag. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* Once the format tag has been validated by the font driver, it */ + /* should then call the TT_Load_Face_Func() callback to read the rest */ + /* of the SFNT tables in the object. */ + /* */ + typedef FT_Error + (*TT_Init_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Face_Func */ + /* */ + /* <Description> */ + /* Second part of the SFNT face object initialization. This will */ + /* load the common SFNT tables (head, OS/2, maxp, metrics, etc.) in */ + /* the face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function must be called after TT_Init_Face_Func(). */ + /* */ + typedef FT_Error + (*TT_Load_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Done_Face_Func */ + /* */ + /* <Description> */ + /* A callback used to delete the common SFNT data from a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Note> */ + /* This function does NOT destroy the face object. */ + /* */ + typedef void + (*TT_Done_Face_Func)( TT_Face face ); + + + typedef FT_Module_Interface + (*SFNT_Get_Interface_Func)( FT_Module module, + const char* func_interface ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SFNT_HeaderRec_Func */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. Supports collections. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* This function checks that the header is valid by looking at the */ + /* values of `search_range', `entry_selector', and `range_shift'. */ + /* */ + typedef FT_Error + (*TT_Load_SFNT_HeaderRec_Func)( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header sfnt ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Directory_Func */ + /* */ + /* <Description> */ + /* Loads the table directory into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be on the first byte after the 4-byte font */ + /* format tag. This is the case just after a call to */ + /* TT_Load_Format_Tag(). */ + /* */ + typedef FT_Error + (*TT_Load_Directory_Func)( TT_Face face, + FT_Stream stream, + SFNT_Header sfnt ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Any_Func */ + /* */ + /* <Description> */ + /* Loads any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The 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 :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Any_Func)( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte *buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Loads a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* x_ppem :: The horizontal resolution in points per EM. */ + /* */ + /* y_ppem :: The vertical resolution in points per EM. */ + /* */ + /* glyph_index :: The current glyph index. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* amap :: The target pixmap. */ + /* */ + /* ametrics :: A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Image_Func)( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *amap, + TT_SBit_MetricsRec *ametrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_Func */ + /* */ + /* <Description> */ + /* Selects an sbit strike for given horizontal and vertical ppem */ + /* values. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* x_ppem :: The horizontal resolution in points per EM. */ + /* */ + /* y_ppem :: The vertical resolution in points per EM. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_Func)( TT_Face face, + FT_Int x_ppem, + FT_Int y_ppem, + FT_ULong *astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_PS_Name_Func */ + /* */ + /* <Description> */ + /* Gets the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_PS_Name_Func)( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Metrics_Func */ + /* */ + /* <Description> */ + /* Loads the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Metrics_Func)( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Load_Func */ + /* */ + /* <Description> */ + /* Loads a given TrueType character map into memory. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* stream :: A handle to the current stream object. */ + /* */ + /* <InOut> */ + /* cmap :: A pointer to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function assumes that the stream is already in use (i.e., */ + /* opened). In case of error, all partially allocated tables are */ + /* released. */ + /* */ + typedef FT_Error + (*TT_CharMap_Load_Func)( TT_Face face, + TT_CMapTable cmap, + FT_Stream input ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Free_Func */ + /* */ + /* <Description> */ + /* Destroys a character mapping table. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* cmap :: A handle to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_CharMap_Free_Func)( TT_Face face, + TT_CMapTable cmap ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Loads a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function will use `face->goto_table' to seek the stream to */ + /* the start of the table. */ + /* */ + typedef FT_Error + (*TT_Load_Table_Func)( TT_Face face, + FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Free_Table_Func */ + /* */ + /* <Description> */ + /* Frees a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + typedef void + (*TT_Free_Table_Func)( TT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* SFNT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Loads a given SFNT table in memory */ + /* */ + typedef FT_Error + (*SFNT_Load_Table_Func)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_Interface */ + /* */ + /* <Description> */ + /* This structure holds pointers to the functions used to load and */ + /* free the basic tables that are required in a `sfnt' font file. */ + /* */ + /* <Fields> */ + /* Check the various xxx_Func() descriptions for details. */ + /* */ + typedef struct SFNT_Interface_ + { + TT_Loader_GotoTableFunc goto_table; + + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + SFNT_Get_Interface_Func get_interface; + + TT_Load_Any_Func load_any; + TT_Load_SFNT_HeaderRec_Func load_sfnt_header; + TT_Load_Directory_Func load_directory; + + /* these functions are called by `load_face' but they can also */ + /* be called from external modules, if there is a need to do so */ + TT_Load_Table_Func load_header; + TT_Load_Metrics_Func load_metrics; + TT_Load_Table_Func load_charmaps; + TT_Load_Table_Func load_max_profile; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_psnames; + + TT_Load_Table_Func load_names; + TT_Free_Table_Func free_names; + + /* optional tables */ + TT_Load_Table_Func load_hdmx; + TT_Free_Table_Func free_hdmx; + + TT_Load_Table_Func load_kerning; + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; + + /* see `ttload.h' */ + TT_Load_Table_Func load_bitmap_header; + + /* see `ttsbit.h' */ + TT_Set_SBit_Strike_Func set_sbit_strike; + TT_Load_Table_Func load_sbits; + TT_Load_SBit_Image_Func load_sbit_image; + TT_Free_Table_Func free_sbits; + + /* see `ttpost.h' */ + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; + + /* see `ttcmap.h' */ + TT_CharMap_Load_Func load_charmap; + TT_CharMap_Free_Func free_charmap; + + } SFNT_Interface; + + + /* transitional */ + typedef SFNT_Interface* SFNT_Service; + + +FT_END_HEADER + +#endif /* __SFNT_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/t1types.h b/lib/freetype/include/freetype/internal/t1types.h new file mode 100644 index 0000000..2625394 --- /dev/null +++ b/lib/freetype/include/freetype/internal/t1types.h @@ -0,0 +1,199 @@ +/***************************************************************************/ +/* */ +/* t1types.h */ +/* */ +/* Basic Type1/Type2 type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1TYPES_H__ +#define __T1TYPES_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_EncodingRec */ + /* */ + /* <Description> */ + /* A structure modeling a custom encoding. */ + /* */ + /* <Fields> */ + /* num_chars :: The number of character codes in the encoding. */ + /* Usually 256. */ + /* */ + /* code_first :: The lowest valid character code in the encoding. */ + /* */ + /* code_last :: The highest valid character code in the encoding. */ + /* */ + /* char_index :: An array of corresponding glyph indices. */ + /* */ + /* char_name :: An array of corresponding glyph names. */ + /* */ + typedef struct T1_EncodingRecRec_ + { + FT_Int num_chars; + FT_Int code_first; + FT_Int code_last; + + FT_UShort* char_index; + FT_String** char_name; + + } T1_EncodingRec, *T1_Encoding; + + + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + typedef struct T1_FontRec_ + { + PS_FontInfoRec font_info; /* font info dictionary */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ + + T1_EncodingType encoding_type; + T1_EncodingRec encoding; + + FT_Byte* subrs_block; + FT_Byte* charstrings_block; + FT_Byte* glyph_names_block; + + FT_Int num_subrs; + FT_Byte** subrs; + FT_Int* subrs_len; + + FT_Int num_glyphs; + FT_String** glyph_names; /* array of glyph names */ + FT_Byte** charstrings; /* array of glyph charstrings */ + FT_Int* charstrings_len; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_BBox font_bbox; + FT_Long font_id; + + FT_Int stroke_width; + + } T1_FontRec, *T1_Font; + + + typedef struct CID_SubrsRec_ + { + FT_UInt num_subrs; + FT_Byte** code; + + } CID_SubrsRec, *CID_Subrs; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ + /* are not shared between font drivers, and are thus defined normally in */ + /* `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + typedef struct T1_FaceRec_* T1_Face; + typedef struct CID_FaceRec_* CID_Face; + + + typedef struct T1_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + PS_Unicodes unicode_map; + + /* support for Multiple Masters fonts */ + PS_Blend blend; + + /* since FT 2.1 - interface to PostScript hinter */ + const void* pshinter; + + } T1_FaceRec; + + + typedef struct CID_FaceRec_ + { + FT_FaceRec root; + void* psnames; + void* psaux; + CID_FaceInfoRec cid; + void* afm_data; + CID_Subrs subrs; + + /* since FT 2.1 - interface to PostScript hinter */ + void* pshinter; + + } CID_FaceRec; + + +FT_END_HEADER + +#endif /* __T1TYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/t42types.h b/lib/freetype/include/freetype/internal/t42types.h new file mode 100644 index 0000000..7562252 --- /dev/null +++ b/lib/freetype/include/freetype/internal/t42types.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* t42types.h */ +/* */ +/* Type 42 font data types (specification only). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 __T42TYPES_H__ +#define __T42TYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + typedef struct T42_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_Byte* ttf_data; + FT_ULong ttf_size; + FT_Face ttf_face; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + PS_Unicodes unicode_map; + + } T42_FaceRec, *T42_Face; + + +FT_END_HEADER + +#endif /* __T1TYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/internal/tttypes.h b/lib/freetype/include/freetype/internal/tttypes.h new file mode 100644 index 0000000..4097ac8 --- /dev/null +++ b/lib/freetype/include/freetype/internal/tttypes.h @@ -0,0 +1,1669 @@ +/***************************************************************************/ +/* */ +/* tttypes.h */ +/* */ +/* Basic SFNT/TrueType type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTTYPES_H__ +#define __TTTYPES_H__ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TTC_HeaderRec */ + /* */ + /* <Description> */ + /* TrueType collection header. This table contains the offsets of */ + /* the font headers of each distinct TrueType face in the file. */ + /* */ + /* <Fields> */ + /* tag :: Must be `ttc ' to indicate a TrueType collection. */ + /* */ + /* version :: The version number. */ + /* */ + /* count :: The number of faces in the collection. The */ + /* specification says this should be an unsigned long, but */ + /* we use a signed long since we need the value -1 for */ + /* specific purposes. */ + /* */ + /* offsets :: The offsets of the font headers, one per face. */ + /* */ + typedef struct TTC_HeaderRec_ + { + FT_ULong tag; + FT_Fixed version; + FT_Long count; + FT_ULong* offsets; + + } TTC_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_HeaderRec */ + /* */ + /* <Description> */ + /* SFNT file format header. */ + /* */ + /* <Fields> */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of tables in file. */ + /* */ + /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ + /* */ + /* entry_selector :: Must be log2 of `search_range / 16'. */ + /* */ + /* range_shift :: Must be `num_tables * 16 - search_range'. */ + /* */ + typedef struct SFNT_HeaderRec_ + { + FT_ULong format_tag; + FT_UShort num_tables; + FT_UShort search_range; + FT_UShort entry_selector; + FT_UShort range_shift; + + FT_ULong offset; /* not in file */ + + } SFNT_HeaderRec, *SFNT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableDirRec */ + /* */ + /* <Description> */ + /* This structure models a TrueType table directory. It is used to */ + /* access the various tables of the font face. */ + /* */ + /* <Fields> */ + /* version :: The version number; starts with 0x00010000. */ + /* */ + /* numTables :: The number of tables. */ + /* */ + /* searchRange :: Unused. */ + /* */ + /* entrySelector :: Unused. */ + /* */ + /* rangeShift :: Unused. */ + /* */ + /* <Note> */ + /* This structure is only used during font opening. */ + /* */ + typedef struct TT_TableDirRec_ + { + FT_Fixed version; /* should be 0x10000 */ + FT_UShort numTables; /* number of tables */ + + FT_UShort searchRange; /* These parameters are only used */ + FT_UShort entrySelector; /* for a dichotomy search in the */ + FT_UShort rangeShift; /* directory. We ignore them. */ + + } TT_TableDirRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a TrueType font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* Offset :: The offset of the table from the start of the TrueType */ + /* font in its resource. */ + /* */ + /* Length :: The table length (in bytes). */ + /* */ + typedef struct TT_TableRec_ + { + FT_ULong Tag; /* table type */ + FT_ULong CheckSum; /* table checksum */ + FT_ULong Offset; /* table file offset */ + FT_ULong Length; /* table length */ + + } TT_TableRec, *TT_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapDirRec */ + /* */ + /* <Description> */ + /* This structure describes the directory of the `cmap' table, */ + /* containing the font's character mappings table. */ + /* */ + /* <Fields> */ + /* tableVersionNumber :: The version number. */ + /* */ + /* numCMaps :: The number of charmaps in the font. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_CMapDirRec_ + { + FT_UShort tableVersionNumber; + FT_UShort numCMaps; + + } TT_CMapDirRec, *TT_CMapDir; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapDirEntryRec */ + /* */ + /* <Description> */ + /* This structure describes a charmap in a TrueType font. */ + /* */ + /* <Fields> */ + /* platformID :: An ID used to specify for which platform this */ + /* charmap is defined (FreeType manages all platforms). */ + /* */ + /* encodingID :: A platform-specific ID used to indicate which source */ + /* encoding is used in this charmap. */ + /* */ + /* offset :: The offset of the charmap relative to the start of */ + /* the `cmap' table. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_CMapDirEntryRec_ + { + FT_UShort platformID; + FT_UShort platformEncodingID; + FT_Long offset; + + } TT_CMapDirEntryRec, *TT_CMapDirEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LongMetricsRec */ + /* */ + /* <Description> */ + /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ + /* TrueType tables. The values are expressed in font units. */ + /* */ + /* <Fields> */ + /* advance :: The advance width or height for the glyph. */ + /* */ + /* bearing :: The left-side or top-side bearing for the glyph. */ + /* */ + typedef struct TT_LongMetricsRec_ + { + FT_UShort advance; + FT_Short bearing; + + } TT_LongMetricsRec, *TT_LongMetrics; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_ShortMetrics */ + /* */ + /* <Description> */ + /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ + /* tables. */ + /* */ + typedef FT_Short TT_ShortMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameEntryRec */ + /* */ + /* <Description> */ + /* A structure modeling TrueType name records. Name records are used */ + /* to store important strings like family name, style name, */ + /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ + /* etc). */ + /* */ + /* <Fields> */ + /* platformID :: The ID of the name's encoding platform. */ + /* */ + /* encodingID :: The platform-specific ID for the name's encoding. */ + /* */ + /* languageID :: The platform-specific ID for the name's language. */ + /* */ + /* nameID :: The ID specifying what kind of name this is. */ + /* */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are usually UTF-16 encoded characters. */ + /* */ + typedef struct TT_NameEntryRec_ + { + FT_UShort platformID; + FT_UShort encodingID; + FT_UShort languageID; + FT_UShort nameID; + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_NameEntryRec, *TT_NameEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameTableRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType name table. */ + /* */ + /* <Fields> */ + /* format :: The format of the name table. */ + /* */ + /* numNameRecords :: The number of names in table. */ + /* */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ + /* */ + /* names :: An array of name records. */ + /* */ + /* stream :: the file's input stream. */ + /* */ + typedef struct TT_NameTableRec_ + { + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameEntryRec* names; + FT_Stream stream; + + } TT_NameTableRec, *TT_NameTable; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRangeRec */ + /* */ + /* <Description> */ + /* A tiny structure used to model a gasp range according to the */ + /* TrueType specification. */ + /* */ + /* <Fields> */ + /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ + /* */ + /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ + /* modes to be used. */ + /* */ + typedef struct TT_GaspRangeRec_ + { + FT_UShort maxPPEM; + FT_UShort gaspFlag; + + } TT_GaspRangeRec, *TT_GaspRange; + + +#define TT_GASP_GRIDFIT 0x01 +#define TT_GASP_DOGRAY 0x02 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType `gasp' table used to specify */ + /* grid-fitting and anti-aliasing behaviour. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numRanges :: The number of gasp ranges in table. */ + /* */ + /* gaspRanges :: An array of gasp ranges. */ + /* */ + typedef struct TT_Gasp_ + { + FT_UShort version; + FT_UShort numRanges; + TT_GaspRange gaspRanges; + + } TT_GaspRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxEntryRec */ + /* */ + /* <Description> */ + /* A small structure used to model the pre-computed widths of a given */ + /* size. They are found in the `hdmx' table. */ + /* */ + /* <Fields> */ + /* ppem :: The pixels per EM value at which these metrics apply. */ + /* */ + /* max_width :: The maximum advance width for this metric. */ + /* */ + /* widths :: An array of widths. Note: These are 8-bit bytes. */ + /* */ + typedef struct TT_HdmxEntryRec_ + { + FT_Byte ppem; + FT_Byte max_width; + FT_Byte* widths; + + } TT_HdmxEntryRec, *TT_HdmxEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxRec */ + /* */ + /* <Description> */ + /* A structure used to model the `hdmx' table, which contains */ + /* pre-computed widths for a set of given sizes/dimensions. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* num_records :: The number of hdmx records. */ + /* */ + /* records :: An array of hdmx records. */ + /* */ + typedef struct TT_HdmxRec_ + { + FT_UShort version; + FT_Short num_records; + TT_HdmxEntry records; + + } TT_HdmxRec, *TT_Hdmx; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Kern0_PairRec */ + /* */ + /* <Description> */ + /* A structure used to model a kerning pair for the kerning table */ + /* format 0. The engine now loads this table if it finds one in the */ + /* font file. */ + /* */ + /* <Fields> */ + /* left :: The index of the left glyph in pair. */ + /* */ + /* right :: The index of the right glyph in pair. */ + /* */ + /* value :: The kerning distance. A positive value spaces the */ + /* glyphs, a negative one makes them closer. */ + /* */ + typedef struct TT_Kern0_PairRec_ + { + FT_UShort left; /* index of left glyph in pair */ + FT_UShort right; /* index of right glyph in pair */ + FT_FWord value; /* kerning value */ + + } TT_Kern0_PairRec, *TT_Kern0_Pair; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BITMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_MetricsRec */ + /* */ + /* <Description> */ + /* 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' (Microsoft) or `bloc' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* horiBearingX :: The horizontal left bearing. */ + /* */ + /* horiBearingY :: The horizontal top bearing. */ + /* */ + /* horiAdvance :: The horizontal advance. */ + /* */ + /* vertBearingX :: The vertical left bearing. */ + /* */ + /* vertBearingY :: The vertical top bearing. */ + /* */ + /* vertAdvance :: The vertical advance. */ + /* */ + typedef struct TT_SBit_MetricsRec_ + { + FT_Byte height; + FT_Byte width; + + FT_Char horiBearingX; + FT_Char horiBearingY; + FT_Byte horiAdvance; + + FT_Char vertBearingX; + FT_Char vertBearingY; + FT_Byte vertAdvance; + + } TT_SBit_MetricsRec, *TT_SBit_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_SmallMetricsRec */ + /* */ + /* <Description> */ + /* 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' (Microsoft) or the `bdat' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* bearingX :: The left-side bearing. */ + /* */ + /* bearingY :: The top-side bearing. */ + /* */ + /* advance :: The advance width or height. */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + FT_Byte height; + FT_Byte width; + + FT_Char bearingX; + FT_Char bearingY; + FT_Byte advance; + + } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_LineMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to describe the text line metrics of a given */ + /* bitmap strike, for either a horizontal or vertical layout. */ + /* */ + /* <Fields> */ + /* ascender :: The ascender in pixels. */ + /* */ + /* descender :: The descender in pixels. */ + /* */ + /* max_width :: The 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 */ + /* */ + /* horizontal advance - */ + /* ( horiBearingX + width ) */ + /* */ + /* resp. */ + /* */ + /* vertical advance - */ + /* ( vertBearingY + height ) */ + /* */ + /* max_before_BL :: Maximum of horiBearingY (resp. */ + /* vertBearingY). */ + /* */ + /* min_after_BL :: Minimum of */ + /* */ + /* horiBearingY - height */ + /* */ + /* resp. */ + /* */ + /* vertBearingX - width */ + /* */ + /* pads :: Unused (to make the size of the record */ + /* a multiple of 32 bits. */ + /* */ + typedef struct TT_SBit_LineMetricsRec_ + { + FT_Char ascender; + FT_Char descender; + FT_Byte max_width; + FT_Char caret_slope_numerator; + FT_Char caret_slope_denominator; + FT_Char caret_offset; + FT_Char min_origin_SB; + FT_Char min_advance_SB; + FT_Char max_before_BL; + FT_Char min_after_BL; + FT_Char pads[2]; + + } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_RangeRec */ + /* */ + /* <Description> */ + /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* first_glyph :: The first glyph index in the range. */ + /* */ + /* last_glyph :: The last glyph index in the range. */ + /* */ + /* index_format :: The format of index table. Valid values are 1 */ + /* to 5. */ + /* */ + /* image_format :: The format of `EBDT' image data. */ + /* */ + /* image_offset :: The offset to image data in `EBDT'. */ + /* */ + /* image_size :: For index formats 2 and 5. This is the size in */ + /* bytes of each 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 :: The offset of the index table in the `EBLC' */ + /* table. Only used during strike loading. */ + /* */ + typedef struct TT_SBit_RangeRec + { + FT_UShort first_glyph; + FT_UShort last_glyph; + + FT_UShort index_format; + FT_UShort image_format; + FT_ULong image_offset; + + FT_ULong image_size; + TT_SBit_MetricsRec metrics; + FT_ULong num_glyphs; + + FT_ULong* glyph_offsets; + FT_UShort* glyph_codes; + + FT_ULong table_offset; + + } TT_SBit_RangeRec, *TT_SBit_Range; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_StrikeRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap strike in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* num_index_ranges :: The number of index ranges. */ + /* */ + /* index_ranges :: An array of glyph index ranges. */ + /* */ + /* color_ref :: Unused. `color_ref' is put in for future */ + /* enhancements, but these fields are already */ + /* in use by other platforms (e.g. Newton). */ + /* For details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + /* hori :: The line metrics for horizontal layouts. */ + /* */ + /* vert :: The line metrics for vertical layouts. */ + /* */ + /* start_glyph :: The lowest glyph index for this strike. */ + /* */ + /* end_glyph :: The highest glyph index for this strike. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ + /* and 8. */ + /* */ + /* flags :: Is this a vertical or horizontal strike? For */ + /* details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + typedef struct TT_SBit_StrikeRec_ + { + FT_Int num_ranges; + TT_SBit_Range sbit_ranges; + FT_ULong ranges_offset; + + FT_ULong color_ref; + + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_UShort start_glyph; + FT_UShort end_glyph; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte bit_depth; + FT_Char flags; + + } TT_SBit_StrikeRec, *TT_SBit_Strike; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ComponentRec */ + /* */ + /* <Description> */ + /* A simple structure to describe a compound sbit element. */ + /* */ + /* <Fields> */ + /* glyph_code :: The element's glyph index. */ + /* */ + /* x_offset :: The element's left bearing. */ + /* */ + /* y_offset :: The element's top bearing. */ + /* */ + typedef struct TT_SBit_ComponentRec_ + { + FT_UShort glyph_code; + FT_Char x_offset; + FT_Char y_offset; + + } TT_SBit_ComponentRec, *TT_SBit_Component; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ScaleRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap scaling table, as defined */ + /* in the `EBSC' table. */ + /* */ + /* <Fields> */ + /* hori :: The horizontal line metrics. */ + /* */ + /* vert :: The vertical line metrics. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* x_ppem_substitute :: Substitution x_ppem value. */ + /* */ + /* y_ppem_substitute :: Substitution y_ppem value. */ + /* */ + typedef struct TT_SBit_ScaleRec_ + { + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte x_ppem_substitute; + FT_Byte y_ppem_substitute; + + } TT_SBit_ScaleRec, *TT_SBit_Scale; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_20Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.0. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of named glyphs in the table. */ + /* */ + /* num_names :: The number of PS names stored in the table. */ + /* */ + /* glyph_indices :: The indices of the glyphs in the names arrays. */ + /* */ + /* glyph_names :: The PS names not in Mac Encoding. */ + /* */ + typedef struct TT_Post_20Rec_ + { + FT_UShort num_glyphs; + FT_UShort num_names; + FT_UShort* glyph_indices; + FT_Char** glyph_names; + + } TT_Post_20Rec, *TT_Post_20; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_25Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.5. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of glyphs in the table. */ + /* */ + /* offsets :: An array of signed offsets in a normal Mac */ + /* Postscript name encoding. */ + /* */ + typedef struct TT_Post_25_ + { + FT_UShort num_glyphs; + FT_Char* offsets; + + } TT_Post_25Rec, *TT_Post_25; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_NamesRec */ + /* */ + /* <Description> */ + /* Postscript names table, either format 2.0 or 2.5. */ + /* */ + /* <Fields> */ + /* loaded :: A flag to indicate whether the PS names are loaded. */ + /* */ + /* format_20 :: The sub-table used for format 2.0. */ + /* */ + /* format_25 :: The sub-table used for format 2.5. */ + /* */ + typedef struct TT_Post_NamesRec_ + { + FT_Bool loaded; + + union + { + TT_Post_20Rec format_20; + TT_Post_25Rec format_25; + + } names; + + } TT_Post_NamesRec, *TT_Post_Names; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** TRUETYPE CHARMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* format 0 */ + + typedef struct TT_CMap0_ + { + FT_ULong language; /* for Mac fonts (originally ushort) */ + + FT_Byte* glyphIdArray; + + } TT_CMap0Rec, *TT_CMap0; + + + /* format 2 */ + + typedef struct TT_CMap2SubHeaderRec_ + { + FT_UShort firstCode; /* first valid low byte */ + FT_UShort entryCount; /* number of valid low bytes */ + FT_Short idDelta; /* delta value to glyphIndex */ + FT_UShort idRangeOffset; /* offset from here to 1st code */ + + } TT_CMap2SubHeaderRec, *TT_CMap2SubHeader; + + + typedef struct TT_CMap2Rec_ + { + FT_ULong language; /* for Mac fonts (originally ushort) */ + + FT_UShort* subHeaderKeys; /* high byte mapping table */ + /* value = subHeader index * 8 */ + TT_CMap2SubHeader subHeaders; + FT_UShort* glyphIdArray; + FT_UShort numGlyphId; /* control value */ + + } TT_CMap2Rec, *TT_CMap2; + + + /* format 4 */ + + typedef struct TT_CMap4Segment_ + { + FT_UShort endCount; + FT_UShort startCount; + FT_Short idDelta; + FT_UShort idRangeOffset; + + } TT_CMap4SegmentRec, *TT_CMap4Segment; + + + typedef struct TT_CMap4Rec_ + { + FT_ULong language; /* for Mac fonts (originally ushort) */ + + FT_UShort segCountX2; /* number of segments * 2 */ + FT_UShort searchRange; /* these parameters can be used */ + FT_UShort entrySelector; /* for a binary search */ + FT_UShort rangeShift; + + TT_CMap4Segment segments; + FT_UShort* glyphIdArray; + FT_UShort numGlyphId; /* control value */ + + TT_CMap4Segment last_segment; /* last used segment; this is a small */ + /* cache to potentially increase speed */ + } TT_CMap4Rec, *TT_CMap4; + + + /* format 6 */ + + typedef struct TT_CMap6_ + { + FT_ULong language; /* for Mac fonts (originally ushort) */ + + FT_UShort firstCode; /* first character code of subrange */ + FT_UShort entryCount; /* number of character codes in subrange */ + + FT_UShort* glyphIdArray; + + } TT_CMap6Rec, *TT_CMap6; + + + /* auxiliary table for format 8 and 12 */ + + typedef struct TT_CMapGroupRec_ + { + FT_ULong startCharCode; + FT_ULong endCharCode; + FT_ULong startGlyphID; + + } TT_CMapGroupRec, *TT_CMapGroup; + + + /* FreeType handles format 8 and 12 identically. It is not necessary to + cover mixed 16bit and 32bit codes since FreeType always uses FT_ULong + for input character codes -- converting Unicode surrogates to 32bit + character codes must be done by the application. */ + + typedef struct TT_CMap8_12Rec_ + { + FT_ULong language; /* for Mac fonts */ + + FT_ULong nGroups; + TT_CMapGroup groups; + + TT_CMapGroup last_group; /* last used group; this is a small */ + /* cache to potentially increase speed */ + } TT_CMap8_12Rec, *TT_CMap8_12; + + + /* format 10 */ + + typedef struct TT_CMap10Rec_ + { + FT_ULong language; /* for Mac fonts */ + + FT_ULong startCharCode; /* first character covered */ + FT_ULong numChars; /* number of characters covered */ + + FT_UShort* glyphs; + + } TT_CMap10Rec, *TT_CMap10; + + + typedef struct TT_CMapTableRec_* TT_CMapTable; + + + typedef FT_UInt + (*TT_CharMap_Func)( TT_CMapTable charmap, + FT_ULong char_code ); + + typedef FT_ULong + (*TT_CharNext_Func)( TT_CMapTable charmap, + FT_ULong char_code ); + + + /* charmap table */ + typedef struct TT_CMapTableRec_ + { + FT_UShort platformID; + FT_UShort platformEncodingID; + FT_UShort format; + FT_ULong length; /* must be ulong for formats 8, 10, and 12 */ + + FT_Bool loaded; + FT_ULong offset; + + union + { + TT_CMap0Rec cmap0; + TT_CMap2Rec cmap2; + TT_CMap4Rec cmap4; + TT_CMap6Rec cmap6; + TT_CMap8_12Rec cmap8_12; + TT_CMap10Rec cmap10; + } c; + + TT_CharMap_Func get_index; + TT_CharNext_Func get_next_char; + + } TT_CMapTableRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CharMapRec */ + /* */ + /* <Description> */ + /* The TrueType character map object type. */ + /* */ + /* <Fields> */ + /* root :: The parent character map structure. */ + /* */ + /* cmap :: The used character map. */ + /* */ + typedef struct TT_CharMapRec_ + { + FT_CharMapRec root; + TT_CMapTableRec cmap; + + } TT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ + /* are not shared between font drivers, and are thus defined in */ + /* `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* A handle to a TrueType face/font object. A TT_Face encapsulates */ + /* the resolution and scaling independent parts of a TrueType font */ + /* resource. */ + /* */ + /* <Note> */ + /* The TT_Face structure is also used as a `parent class' for the */ + /* OpenType-CFF class (T2_Face). */ + /* */ + typedef struct TT_FaceRec_* TT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a TrueType character mapping object. */ + /* */ + typedef struct TT_CharMapRec_* TT_CharMap; + + + /* a function type used for the truetype bytecode interpreter hooks */ + typedef FT_Error + (*TT_Interpreter)( void* exec_context ); + + /* forward declaration */ + typedef struct TT_LoaderRec_* TT_Loader; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_GotoTableFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* tag :: A 4-byte tag used to name the table. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* length :: The length of the table in bytes. Set to 0 if not */ + /* needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + typedef FT_Error + (*TT_Loader_GotoTableFunc)( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_StartGlyphFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given glyph element, and opens a */ + /* frame for it. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* glyph index :: The index of the glyph to access. */ + /* */ + /* offset :: The offset of the glyph according to the */ + /* `locations' table. */ + /* */ + /* byte_count :: The size of the frame in bytes. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ + /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ + /* but alternative formats (e.g. compressed ones) might use something */ + /* different. */ + /* */ + typedef FT_Error + (*TT_Loader_StartGlyphFunc)( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_ReadGlyphFunc */ + /* */ + /* <Description> */ + /* Reads one glyph element (its header, a simple glyph, or a */ + /* composite) from the loader's current stream frame. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_EndGlyphFunc */ + /* */ + /* <Description> */ + /* Closes the current loader stream frame for the glyph. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + typedef void + (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* TrueType Face Type */ + /* */ + /* <Struct> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* The TrueType face class. These objects model the resolution and */ + /* point-size independent data found in a TrueType font file. */ + /* */ + /* <Fields> */ + /* root :: The base FT_Face structure, managed by the */ + /* base layer. */ + /* */ + /* ttc_header :: The TrueType collection header, used when */ + /* the file is a `ttc' rather than a `ttf'. */ + /* For ordinary font files, the field */ + /* `ttc_header.count' is set to 0. */ + /* */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of TrueType tables in this font */ + /* file. */ + /* */ + /* dir_tables :: The directory of TrueType tables for this */ + /* font file. */ + /* */ + /* header :: The font's font header (`head' table). */ + /* Read on font opening. */ + /* */ + /* horizontal :: The font's horizontal header (`hhea' */ + /* table). This field also contains the */ + /* associated horizontal metrics table */ + /* (`hmtx'). */ + /* */ + /* max_profile :: The font's maximum profile table. Read on */ + /* font opening. Note that some maximum */ + /* values cannot be taken directly from this */ + /* table. We thus define additional fields */ + /* below to hold the computed maxima. */ + /* */ + /* max_components :: The maximum number of glyph components */ + /* required to load any composite glyph from */ + /* this font. Used to size the load stack. */ + /* */ + /* vertical_info :: A boolean which is set when the font file */ + /* contains vertical metrics. If not, the */ + /* value of the `vertical' field is */ + /* undefined. */ + /* */ + /* vertical :: The font's vertical header (`vhea' table). */ + /* This field also contains the associated */ + /* vertical metrics table (`vmtx'), if found. */ + /* IMPORTANT: The contents of this field is */ + /* undefined if the `verticalInfo' field is */ + /* unset. */ + /* */ + /* num_names :: The number of name records within this */ + /* TrueType font. */ + /* */ + /* name_table :: The table of name records (`name'). */ + /* */ + /* os2 :: The font's OS/2 table (`OS/2'). */ + /* */ + /* postscript :: The font's PostScript table (`post' */ + /* table). The PostScript glyph names are */ + /* not loaded by the driver on face opening. */ + /* See the `ttpost' module for more details. */ + /* */ + /* cmap_table :: Address of the face's `cmap' SFNT table */ + /* in memory (it's an extracted frame). */ + /* */ + /* cmap_size :: The size in bytes of the `cmap_table' */ + /* described above. */ + /* */ + /* num_charmaps :: The number of character mappings in the */ + /* font. */ + /* */ + /* charmaps :: The array of charmap objects for this font */ + /* file. Note that this field is a typeless */ + /* pointer. The Reason is that the format of */ + /* charmaps varies with the underlying font */ + /* format and cannot be determined here. */ + /* */ + /* goto_table :: A function called by each TrueType table */ + /* loader to position a stream's cursor to */ + /* the start of a given table according to */ + /* its tag. It defaults to TT_Goto_Face but */ + /* can be different for strange formats (e.g. */ + /* Type 42). */ + /* */ + /* access_glyph_frame :: A function used to access the frame of a */ + /* given glyph within the face's font file. */ + /* */ + /* forget_glyph_frame :: A function used to forget the frame of a */ + /* given glyph when all data has been loaded. */ + /* */ + /* read_glyph_header :: A function used to read a glyph header. */ + /* It must be called between an `access' and */ + /* `forget'. */ + /* */ + /* read_simple_glyph :: A function used to read a simple glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* read_composite_glyph :: A function used to read a composite glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* sfnt :: A pointer to the SFNT `driver' interface. */ + /* */ + /* psnames :: A pointer to the `PSNames' module */ + /* interface. */ + /* */ + /* hdmx :: The face's horizontal device metrics */ + /* (`hdmx' table). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* gasp :: The grid-fitting and scaling properties */ + /* table (`gasp'). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* pclt :: The `pclt' SFNT table. */ + /* */ + /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ + /* sizes, embedded in this font. */ + /* */ + /* sbit_strikes :: An array of sbit strikes embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* num_sbit_scales :: The number of sbit scales for this font. */ + /* */ + /* sbit_scales :: Array of sbit scales embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* postscript_names :: A table used to store the Postscript names */ + /* of the glyphs for this font. See the */ + /* file `ttconfig.h' for comments on the */ + /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* font_program_size :: Size in bytecodes of the face's font */ + /* program. 0 if none defined. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* font_program :: The face's font program (bytecode stream) */ + /* executed at load time, also used during */ + /* glyph rendering. Comes from the `fpgm' */ + /* table. Ignored for Type 2 font fonts. */ + /* */ + /* cvt_program_size :: The size in bytecodes of the face's cvt */ + /* program. Ignored for Type 2 fonts. */ + /* */ + /* cvt_program :: The face's cvt program (bytecode stream) */ + /* executed each time an instance/size is */ + /* changed/reset. Comes from the `prep' */ + /* table. Ignored for Type 2 fonts. */ + /* */ + /* cvt_size :: Size of the control value table (in */ + /* entries). Ignored for Type 2 fonts. */ + /* */ + /* cvt :: The face's original control value table. */ + /* Coordinates are expressed in unscaled font */ + /* units. Comes from the `cvt ' table. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* num_kern_pairs :: The number of kerning pairs present in the */ + /* font file. The engine only loads the */ + /* first horizontal format 0 kern table it */ + /* finds in the font file. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* kern_table_index :: The index of the kerning table in the font */ + /* kerning directory. Ignored for Type 2 */ + /* fonts. */ + /* */ + /* interpreter :: A pointer to the TrueType bytecode */ + /* interpreters field is also used to hook */ + /* the debugger in `ttdebug'. */ + /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + typedef struct TT_FaceRec_ + { + FT_FaceRec root; + + TTC_HeaderRec ttc_header; + + FT_ULong format_tag; + FT_UShort num_tables; + TT_Table dir_tables; + + TT_Header header; /* TrueType header table */ + TT_HoriHeader horizontal; /* TrueType horizontal header */ + + TT_MaxProfile max_profile; + FT_ULong max_components; + + FT_Bool vertical_info; + TT_VertHeader vertical; /* TT Vertical header, if present */ + + FT_UShort num_names; /* number of name records */ + TT_NameTableRec name_table; /* name table */ + + TT_OS2 os2; /* TrueType OS/2 table */ + TT_Postscript postscript; /* TrueType Postscript table */ + + FT_Byte* cmap_table; /* extracted 'cmap' table */ + FT_ULong cmap_size; + + TT_Loader_GotoTableFunc goto_table; + + TT_Loader_StartGlyphFunc access_glyph_frame; + TT_Loader_EndGlyphFunc forget_glyph_frame; + TT_Loader_ReadGlyphFunc read_glyph_header; + TT_Loader_ReadGlyphFunc read_simple_glyph; + TT_Loader_ReadGlyphFunc read_composite_glyph; + + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ + void* sfnt; + + /* a typeless pointer to the PSNames_Interface table used to */ + /* handle glyph names <-> unicode & Mac values */ + void* psnames; + + /***********************************************************************/ + /* */ + /* Optional TrueType/OpenType tables */ + /* */ + /***********************************************************************/ + + /* horizontal device metrics */ + TT_HdmxRec hdmx; + + /* grid-fitting and scaling table */ + TT_GaspRec gasp; /* the `gasp' table */ + + /* PCL 5 table */ + TT_PCLT pclt; + + /* embedded bitmaps support */ + FT_ULong num_sbit_strikes; + TT_SBit_Strike sbit_strikes; + + FT_ULong num_sbit_scales; + TT_SBit_Scale sbit_scales; + + /* postscript names table */ + TT_Post_NamesRec postscript_names; + + + /***********************************************************************/ + /* */ + /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* */ + /***********************************************************************/ + + /* the glyph locations */ + FT_UShort num_locations; + FT_Long* glyph_locations; + + /* the font program, if any */ + FT_ULong font_program_size; + FT_Byte* font_program; + + /* the cvt program, if any */ + FT_ULong cvt_program_size; + FT_Byte* cvt_program; + + /* the original, unscaled, control value table */ + FT_ULong cvt_size; + FT_Short* cvt; + + /* the format 0 kerning table, if any */ + FT_Int num_kern_pairs; + FT_Int kern_table_index; + TT_Kern0_Pair kern_pairs; + + /* A pointer to the bytecode interpreter to use. This is also */ + /* used to hook the debugger for the `ttdebug' utility. */ + TT_Interpreter interpreter; + + + /***********************************************************************/ + /* */ + /* Other tables or fields. This is used by derivative formats like */ + /* OpenType. */ + /* */ + /***********************************************************************/ + + FT_Generic extra; + + } TT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GlyphZoneRec */ + /* */ + /* <Description> */ + /* A glyph zone is used to load, scale and hint glyph outline */ + /* coordinates. */ + /* */ + /* <Fields> */ + /* memory :: A handle to the memory manager. */ + /* */ + /* max_points :: The maximal size in points of the zone. */ + /* */ + /* max_contours :: Max size in links contours of thez one. */ + /* */ + /* n_points :: The current number of points in the zone. */ + /* */ + /* n_contours :: The current number of contours in the zone. */ + /* */ + /* org :: The original glyph coordinates (font */ + /* units/scaled). */ + /* */ + /* cur :: The current glyph coordinates (scaled/hinted). */ + /* */ + /* tags :: The point control tags. */ + /* */ + /* contours :: The contours end points. */ + /* */ + typedef struct TT_GlyphZoneRec_ + { + FT_Memory memory; + FT_UShort max_points; + FT_UShort max_contours; + FT_UShort n_points; /* number of points in zone */ + FT_Short n_contours; /* number of contours */ + + FT_Vector* org; /* original point coordinates */ + FT_Vector* cur; /* current point coordinates */ + + FT_Byte* tags; /* current touch flags */ + FT_UShort* contours; /* contour end points */ + + } TT_GlyphZoneRec, *TT_GlyphZone; + + + /* handle to execution context */ + typedef struct TT_ExecContextRec_* TT_ExecContext; + + /* glyph loader structure */ + typedef struct TT_LoaderRec_ + { + FT_Face face; + FT_Size size; + FT_GlyphSlot glyph; + FT_GlyphLoader gloader; + + FT_ULong load_flags; + FT_UInt glyph_index; + + FT_Stream stream; + FT_Int byte_len; + + FT_Short n_contours; + FT_BBox bbox; + FT_Int left_bearing; + FT_Int advance; + FT_Int linear; + FT_Bool linear_def; + FT_Bool preserve_pps; + FT_Vector pp1; + FT_Vector pp2; + + FT_ULong glyf_offset; + + /* the zone where we load our glyphs */ + TT_GlyphZoneRec base; + TT_GlyphZoneRec zone; + + TT_ExecContext exec; + FT_Byte* instructions; + FT_ULong ins_pos; + + /* for possible extensibility in other formats */ + void* other; + + } TT_LoaderRec; + + +FT_END_HEADER + +#endif /* __TTTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/t1tables.h b/lib/freetype/include/freetype/t1tables.h new file mode 100644 index 0000000..200ba9b --- /dev/null +++ b/lib/freetype/include/freetype/t1tables.h @@ -0,0 +1,391 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1TABLES_H__ +#define __T1TABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type 1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ + /* that for Multiple Master fonts, each instance has its own */ + /* FontInfo. */ + /* */ + typedef struct PS_FontInfoRec + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec, *PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type1/Type2 private dictionary. Note */ + /* that for Multiple Master fonts, each instance has its own Private */ + /* dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec, *PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blen dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + typedef enum + { + /*# required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /*# required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + /*# never remove */ + T1_BLEND_MAX + + } T1_Blend_Flags; + + + /*# backwards compatible definitions */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Fixed* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + } PS_BlendRec, *PS_Blend; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec, *CID_FaceDict; + + + /* backwards-compatible definition */ + typedef CID_FaceDictRec CID_FontDict; + + + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec, *CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + /* */ + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable Postscript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * Postscript font. + * + * @input: + * face :: + * Postscript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not Postscript-based, this function will + * return the @FT_Err_Invalid_Argument error code. + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfoRec *afont_info ); + + /* */ + + + +FT_END_HEADER + +#endif /* __T1TABLES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/ttnameid.h b/lib/freetype/include/freetype/ttnameid.h new file mode 100644 index 0000000..9428ac6 --- /dev/null +++ b/lib/freetype/include/freetype/ttnameid.h @@ -0,0 +1,1076 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2002 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 __TTNAMEID_H__ +#define __TTNAMEID_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharmapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify Unicode charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (@TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding.) + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only.) + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32 + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#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 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to symbol encodings. see @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to Microsoft SJIS Japanese encoding. + * See @FT_ENCODING_MS_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Microsoft Simplified Chinese as used in Mainland + * China. See @FT_ENCODING_MS_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Microsoft Traditional Chinese as used in Taiwan and + * Hong Kong. See @FT_ENCODING_MS_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Microsoft Korean Wansung encoding. See + * @FT_ENCODING_MS_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Microsoft Johab encoding. See @FT_ENCODING_MS_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added into + * OpenType specification as of version 1.4 (mid-2001.) + */ + +#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 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if 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_CYRILLIC_SCRIPT 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_MONGOLIAN_SCRIPT 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 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCID's used to be at */ + /* */ + /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt */ + /* */ + /* Now (2002-11-15), the Microsoft site directs to */ + /* */ + /* http://www.microsoft.com/globaldev/reference/loclanghome.asp */ + /* http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP */ + /* */ +#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 + +#if 1 /* this used to be this value (and it still is in many places) */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#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 + +#if 0 /* this seems to be an error that have been dropped */ +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0428 +#endif + +#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 + +#if 0 /* this seems to be a previous invertion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#endif + +#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 + + /* new as of 2001-01-01 */ +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c +#define TT_MS_LANGID_FRENCH_REUNION 0x200c +#define TT_MS_LANGID_FRENCH_CONGO 0x240c + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO + +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c +#define TT_MS_LANGID_FRENCH_MALI 0x340c +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 + + /* the following seems to be inconsistent; + here is the current "official" way: */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* and here is what is used by Passport SDK */ +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + /* end of inconsistency */ + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_MANIPURI_INDIA 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA 0x0459 + /* the following one is only encountered in Microsoft RTF specification */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN 0x0460 + /* the following one is not in the Passport list, looks like an omission */ +#define TT_MS_LANGID_KASHMIRI_INDIA 0x0860 +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 + + /* new as of 2001-03-01 (from Office Xp) */ +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO 0x045f +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES + /* for language codes from 0x0466 to 0x0471 see below */ +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA + + /* New additions from Windows Xp/Passport SDK 2001-11-10. */ + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a + /* The following two IDs blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40a +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40c + +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c +#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a + /* language codes from 0x046b to 0x046f are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + + + /*************************************************************************/ + /* */ + /* 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 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 02-Jul-2000. */ + /* */ + + /* General Scripts Area */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* 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 and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 is reserved (was: Greek Symbols and Coptic) */ + /* Bit 9 Cyrillic + */ + /* Cyrillic Supplementary */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* 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 + */ + /* Supplemental Arrows-A + */ + /* Supplemental Arrows-B */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* Bit 38 Mathematical Operators + */ + /* Supplemental Mathematical Operators + */ + /* Miscellaneous Mathematical Symbols-A + */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* 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 + */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo + */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Kanbun */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC + /* 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 High Surrogates + */ + /* High Private Use Surrogates + */ + /* Low Surrogates */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ + /* According to OpenType specs v.1.3+, setting bit 57 implies that there */ + /* is at least one codepoint beyond the Basic Multilingual Plane that is */ + /* supported by this font. So it really means: >= U+10000 */ + + /* Bit 58 is reserved for Unicode SubRanges */ + + /* CJK Ideographs Area */ + + /* Bit 59 CJK Unified Ideographs + */ + /* CJK Radicals Supplement + */ + /* Kangxi Radicals + */ + /* Ideographic Description Characters + */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension A + */ + /* CJK Unified Ideographs Extension B + */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + + /* 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 + */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* 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+FDFF */ + /* 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+FEFE */ + /* 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+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables + */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog + */ + /* Hanunoo + */ + /* Buhid + */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols + */ + /* Musical Symbols */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) + */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + + + /*************************************************************************/ + /* */ + /* 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 <dhoo@flash.net> 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 /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* __TTNAMEID_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/tttables.h b/lib/freetype/include/freetype/tttables.h new file mode 100644 index 0000000..4599632 --- /dev/null +++ b/lib/freetype/include/freetype/tttables.h @@ -0,0 +1,662 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2001 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 <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType-specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 10 reserved bytes. */ + /* */ + /* metric_Data_Format :: Always 0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8 reserved bytes. */ + /* */ + /* metric_Data_Format :: Always 0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_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; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. This is the long */ + /* table version. All fields comply to the TrueType specification. */ + /* */ + /* Note that we now support old Mac fonts which do not include an */ + /* OS/2 table. In this case, the `version' field is always set to */ + /* 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_Short fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 tables: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 tables: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType Postscript table. All fields */ + /* comply to the TrueType table. This structure does not reference */ + /* the Postscript glyph names, which can be nevertheless accessed */ + /* with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType table. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: An obscure value related to composite */ + /* glyphs definitions. */ + /* */ + /* maxComponentDepth :: An obscure value related to composite */ + /* glyphs definitions. Probably the maximum */ + /* number of simple glyphs in a composite. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /* */ + + typedef enum + { + ft_sfnt_head = 0, + ft_sfnt_maxp = 1, + ft_sfnt_os2 = 2, + ft_sfnt_hhea = 3, + ft_sfnt_vhea = 4, + ft_sfnt_post = 5, + ft_sfnt_pclt = 6, + + sfnt_max /* don't remove */ + + } FT_Sfnt_Tag; + + + /* internal use only */ + typedef void* + (*FT_Get_Sfnt_Table_Func)( FT_Face face, + FT_Sfnt_Tag tag ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Returns a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be 0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt/truetype/opentype drivers. See FT_Sfnt_Tag for a */ + /* list. */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + /************************************************************************** + * + * <Function> + * FT_Load_Sfnt_Table + * + * <Description> + * Loads any font table into client memory. + * + * <Input> + * face :: handle to source face. + * tag :: the 4-byte tag of the table to load. Use the value 0 if + * you want to access the whole font file. Else, you can use + * one of the definitions found in the @FT_TRUETYPE_TAGS_H + * file, or forge a new one with @FT_MAKE_TAG + * + * offset :: the starting offset in the table (or file if tag == 0) + * + * <Output> + * buffer :: target buffer address. client must ensure that there are + * enough bytes in it. + * + * <InOut> + * length :: if the 'length' parameter is NULL, then try to load the whole + * table, and return an error code if it fails. + * + * else, if '*length' is 0, then exit immediately while returning + * the table's (or file) full size in it. + * + * else, the number of bytes to read from the table or file, + * from the starting offset. + * + * <Return> + * error code. 0 means success + * + * <Note> + * if you need to determine the table's length you should first call this + * function with "*length" set to 0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face,tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* */ + + +FT_END_HEADER + +#endif /* __TTTABLES_H__ */ + + +/* END */ diff --git a/lib/freetype/include/freetype/tttags.h b/lib/freetype/include/freetype/tttags.h new file mode 100644 index 0000000..df09f2a --- /dev/null +++ b/lib/freetype/include/freetype/tttags.h @@ -0,0 +1,74 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType tables (specification only). */ +/* */ +/* Copyright 1996-2001 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 <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) + + +FT_END_HEADER + +#endif /* __TTAGS_H__ */ + + +/* END */ diff --git a/lib/freetype/include/ft2build.h b/lib/freetype/include/ft2build.h new file mode 100644 index 0000000..2ecfdea --- /dev/null +++ b/lib/freetype/include/ft2build.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001 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 corresponds to the default "ft2build.h" file for */ + /* FreeType 2. It uses the "freetype" include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#include <freetype/config/ftheader.h> + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/lib/freetype/install b/lib/freetype/install new file mode 100644 index 0000000..25e8cdf --- /dev/null +++ b/lib/freetype/install @@ -0,0 +1,2 @@ +#! /bin/sh +make install diff --git a/lib/freetype/objs/.cvsignore b/lib/freetype/objs/.cvsignore new file mode 100644 index 0000000..214a599 --- /dev/null +++ b/lib/freetype/objs/.cvsignore @@ -0,0 +1,5 @@ +*.lo +libfreetype.la +.libs +*.o +lib*.a \ No newline at end of file diff --git a/subsys/win32k/freetype/obj/README b/lib/freetype/objs/README similarity index 100% rename from subsys/win32k/freetype/obj/README rename to lib/freetype/objs/README diff --git a/lib/freetype/rosglue.c b/lib/freetype/rosglue.c new file mode 100644 index 0000000..f292833 --- /dev/null +++ b/lib/freetype/rosglue.c @@ -0,0 +1,172 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: FreeType implementation for ReactOS + * PURPOSE: Glue functions between FreeType + * FILE: thirdparty/freetype/rosglue.c + * PROGRAMMER: Ge van Geldorp (ge@gse.nl) + * NOTES: + */ + +#include <ddk/ntddk.h> +#include <ctype.h> +#include <errno.h> +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NDEBUG +#include <debug.h> + +#define TAG_FREETYPE TAG('F', 'T', 'Y', 'P') + +/* + * First some generic routines + */ + +void * +memcpy(void *Dest, const void *Source, size_t Size) +{ + RtlMoveMemory(Dest, Source, Size); + + return Dest; +} + + +int +memcmp(const void *p1, const void *p2, size_t Size) +{ + unsigned int i; + const char* s1; + const char* s2; + + s1 = (const char *) p1; + s2 = (const char *) p2; + for (i = 0; i < Size; i++) + { + if ((*s1) != (*s2)) + { + return((*s1) - (*s2)); + } + s1++; + s2++; + } + return(0); +} + +/* Hopefully we're only passed ASCII characters.... */ +int +isalnum(int c) +{ + assert(0x20 <= c && c <= 0x7f); + + return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')); +} + +long +labs(long j) +{ + return (j < 0 ? -j : j); +} + +/* + * Memory allocation + * + * Because of realloc, we need to keep track of the size of the allocated + * buffer (need to copy the old contents to the new buffer). So, allocate + * extra space for a size_t, store the allocated size in there and return + * the address just past it as the allocated buffer. + */ + +void * +malloc(size_t Size) +{ + void *Object; + + Object = ExAllocatePoolWithTag(NonPagedPool, sizeof(size_t) + Size, TAG_FREETYPE); + if (NULL != Object) + { + *((size_t *) Object) = Size; + Object = (void *)((size_t *) Object + 1); + } + + return Object; +} + +void * +realloc(void *Object, size_t Size) +{ + void *NewObject; + size_t CopySize; + + NewObject = ExAllocatePoolWithTag(NonPagedPool, sizeof(size_t) + Size, TAG_FREETYPE); + if (NULL != NewObject) + { + *((size_t *) NewObject) = Size; + NewObject = (void *)((size_t *) NewObject + 1); + CopySize = *((size_t *) Object - 1); + if (Size < CopySize) + { + CopySize = Size; + } + memcpy(NewObject, Object, CopySize); + ExFreePool((size_t *) Object - 1); + } + + return NewObject; +} + +void +free(void *Object) +{ + ExFreePool((size_t *) Object - 1); +} + +/* + * File I/O + * + * This is easy, we don't want FreeType to do any I/O. So return an + * error on each I/O attempt. Note that errno is not being set, it is + * not used by FreeType. + */ + +FILE * +fopen(const char *FileName, const char *Mode) +{ + DPRINT1("Freetype tries to open file %s\n", FileName); + + return NULL; +} + +int +fseek(FILE *Stream, long Offset, int Origin) +{ + DPRINT1("Doubleplus ungood: freetype shouldn't fseek!\n"); + + return -1; +} + +long +ftell(FILE *Stream) +{ + DPRINT1("Doubleplus ungood: freetype shouldn't ftell!\n"); + + return -1; +} + +size_t +fread(void *Buffer, size_t Size, size_t Count, FILE *Stream) +{ + DPRINT1("Doubleplus ungood: freetype shouldn't fread!\n"); + + return 0; +} + +int +fclose(FILE *Stream) +{ + DPRINT1("Doubleplus ungood: freetype shouldn't fclose!\n"); + + return EOF; +} diff --git a/lib/freetype/src/Jamfile b/lib/freetype/src/Jamfile new file mode 100644 index 0000000..e4d3575 --- /dev/null +++ b/lib/freetype/src/Jamfile @@ -0,0 +1,17 @@ +# FreeType 2 src Jamfile (c) 2001, 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) ; + +# The file <freetype/internal/internal.h> is used to define macros that are +# later used in #include statements. It needs to be parsed in order to +# record these definitions. +# +HDRMACRO [ FT2_SubDir $(FT2_INCLUDE_DIR) internal internal.h ] ; + +for xx in $(FT2_COMPONENTS) +{ + SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ; +} + +# end of src Jamfile diff --git a/lib/freetype/src/autohint/CatharonLicense.txt b/lib/freetype/src/autohint/CatharonLicense.txt new file mode 100644 index 0000000..789c8c9 --- /dev/null +++ b/lib/freetype/src/autohint/CatharonLicense.txt @@ -0,0 +1,123 @@ + The Catharon Open Source LICENSE + ---------------------------- + + 2000-Jul-04 + + Copyright (C) 2000 by Catharon Productions, Inc. + + + +Introduction +============ + + This license applies to source files distributed by Catharon + Productions, Inc. in several archive packages. This license + applies to all files found in such packages which do not fall + under their own explicit license. + + 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 + 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 have used the + Catharon Code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering the packages distributed by + Catharon Productions, Inc. and assume no liability related to + their use. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `Catharon Package', `package', + and `Catharon Code' refer to the set of files originally + distributed by Catharon Productions, Inc. + + `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 one of the + Catharon Packages'. + + This license applies to all files distributed in the original + Catharon Package(s), 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 Catharon Packages are copyright (C) 2000 by Catharon + Productions, Inc. All rights reserved except as specified below. + +1. No Warranty +-------------- + + THE CATHARON PACKAGES ARE PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS 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 OF OR THE INABILITY TO + USE THE CATHARON PACKAGE. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the Catharon Packages (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`license.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 on the work of + Catharon Productions, Inc. in the distribution documentation. + + These conditions apply to any software derived from or based on + the Catharon Packages, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither Catharon Productions, Inc. and contributors nor you shall + use the name of the other for commercial, advertising, or + promotional purposes without specific prior written permission. + + We suggest, but do not require, that you use the following phrase + to refer to this software in your documentation: 'this software is + based in part on the Catharon Typography Project'. + + As you have not signed this license, you are not required to + accept it. However, as the Catharon Packages are 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 Catharon + Packages, you indicate that you understand and accept all the + terms of this license. + +--- end of license.txt --- diff --git a/lib/freetype/src/autohint/Jamfile b/lib/freetype/src/autohint/Jamfile new file mode 100644 index 0000000..a129e5e --- /dev/null +++ b/lib/freetype/src/autohint/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/autohint Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) autohint ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ahangles ahglobal ahglyph ahhint ahmodule ; + } + else + { + _sources = autohint ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/autohint Jamfile diff --git a/lib/freetype/src/autohint/ahangles.c b/lib/freetype/src/autohint/ahangles.c new file mode 100644 index 0000000..ef5a88e --- /dev/null +++ b/lib/freetype/src/autohint/ahangles.c @@ -0,0 +1,147 @@ +/***************************************************************************/ +/* */ +/* ahangles.h */ +/* */ +/* A routine used to compute vector angles with limited accuracy */ +/* and very high speed (body). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "ahangles.h" + + + /* the following table has been automatically generated with */ + /* the `mather.py' Python script */ + + const AH_Angle ah_arctan[1L << AH_ATAN_BITS] = + { + 0, 0, 1, 1, 1, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 14, 14, 14, 14, 15, + 15, 15, 16, 16, 16, 17, 17, 17, + 18, 18, 18, 18, 19, 19, 19, 20, + 20, 20, 21, 21, 21, 21, 22, 22, + 22, 23, 23, 23, 24, 24, 24, 24, + 25, 25, 25, 26, 26, 26, 26, 27, + 27, 27, 28, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 30, 31, 31, 31, + 31, 32, 32, 32, 33, 33, 33, 33, + 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 38, + 38, 38, 38, 39, 39, 39, 39, 40, + 40, 40, 40, 41, 41, 41, 41, 42, + 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, + 46, 46, 46, 46, 46, 47, 47, 47, + 47, 48, 48, 48, 48, 48, 49, 49, + 49, 49, 50, 50, 50, 50, 50, 51, + 51, 51, 51, 51, 52, 52, 52, 52, + 52, 53, 53, 53, 53, 53, 54, 54, + 54, 54, 54, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 56, 57, 57, 57, + 57, 57, 57, 58, 58, 58, 58, 58, + 59, 59, 59, 59, 59, 59, 60, 60, + 60, 60, 60, 61, 61, 61, 61, 61, + 61, 62, 62, 62, 62, 62, 62, 63, + 63, 63, 63, 63, 63, 64, 64, 64 + }; + + + FT_LOCAL_DEF( AH_Angle ) + ah_angle( FT_Vector* v ) + { + FT_Pos dx, dy; + AH_Angle angle; + + + dx = v->x; + dy = v->y; + + /* check trivial cases */ + if ( dy == 0 ) + { + angle = 0; + if ( dx < 0 ) + angle = AH_PI; + return angle; + } + else if ( dx == 0 ) + { + angle = AH_HALF_PI; + if ( dy < 0 ) + angle = -AH_HALF_PI; + return angle; + } + + angle = 0; + if ( dx < 0 ) + { + dx = -v->x; + dy = -v->y; + angle = AH_PI; + } + + if ( dy < 0 ) + { + FT_Pos tmp; + + + tmp = dx; + dx = -dy; + dy = tmp; + angle -= AH_HALF_PI; + } + + if ( dx == 0 && dy == 0 ) + return 0; + + if ( dx == dy ) + angle += AH_PI / 4; + else if ( dx > dy ) + angle += ah_arctan[FT_DivFix( dy, dx ) >> ( 16 - AH_ATAN_BITS )]; + else + angle += AH_HALF_PI - + ah_arctan[FT_DivFix( dx, dy ) >> ( 16 - AH_ATAN_BITS )]; + + if ( angle > AH_PI ) + angle -= AH_2PI; + + return angle; + } + + + FT_LOCAL_DEF( AH_Angle ) + ah_angle_diff( AH_Angle angle1, + AH_Angle angle2 ) + { + AH_Angle delta; + + + delta = ( angle2 - angle1 ); + if ( delta < 0 ) + delta += AH_2PI; + + if ( delta > AH_PI ) + delta -= AH_2PI; + + return delta; + } + +/* END */ diff --git a/lib/freetype/src/autohint/ahangles.h b/lib/freetype/src/autohint/ahangles.h new file mode 100644 index 0000000..f46bfaa --- /dev/null +++ b/lib/freetype/src/autohint/ahangles.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* ahangles.h */ +/* */ +/* A routine used to compute vector angles with limited accuracy */ +/* and very high speed (specification). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHANGLES_H__ +#define __AHANGLES_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "ahtypes.h" + + +FT_BEGIN_HEADER + + + /* PI expressed in ah_angles -- we don't really need an important */ + /* precision, so 256 should be enough */ +#define AH_PI 256 +#define AH_2PI ( AH_PI * 2 ) +#define AH_HALF_PI ( AH_PI / 2 ) +#define AH_2PIMASK ( AH_2PI - 1 ) + + /* the number of bits used to express an arc tangent; */ + /* see the structure of the lookup table */ +#define AH_ATAN_BITS 8 + + extern + const AH_Angle ah_arctan[1L << AH_ATAN_BITS]; + + + FT_LOCAL( AH_Angle ) + ah_angle( FT_Vector* v ); + + + FT_LOCAL( AH_Angle ) + ah_angle_diff( AH_Angle angle1, + AH_Angle angle2 ); + + +FT_END_HEADER + +#endif /* __AHANGLES_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/aherrors.h b/lib/freetype/src/autohint/aherrors.h new file mode 100644 index 0000000..bce6107 --- /dev/null +++ b/lib/freetype/src/autohint/aherrors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* aherrors.h */ +/* */ +/* Autohinter error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the Autohinter error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __AHERRORS_H__ +#define __AHERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX AH_Err_ +#define FT_ERR_BASE FT_Mod_Err_Autohint + +#include FT_ERRORS_H + +#endif /* __AHERRORS_H__ */ + +/* END */ diff --git a/lib/freetype/src/autohint/ahglobal.c b/lib/freetype/src/autohint/ahglobal.c new file mode 100644 index 0000000..efce344 --- /dev/null +++ b/lib/freetype/src/autohint/ahglobal.c @@ -0,0 +1,398 @@ +/***************************************************************************/ +/* */ +/* ahglobal.c */ +/* */ +/* Routines used to compute global metrics automatically (body). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include "ahglobal.h" +#include "ahglyph.h" + + +#define MAX_TEST_CHARACTERS 12 + + static + const char* blue_chars[AH_BLUE_MAX] = + { + "THEZOCQS", + "HEZLOCUS", +#ifdef FT_CONFIG_CHESTER_SMALL_F + "fijkdbh", +#endif + "xzroesc", + "xzroesc", + "pqgjy" + }; + + + /* simple insertion sort */ + static void + sort_values( FT_Int count, + FT_Pos* table ) + { + FT_Int i, j; + FT_Pos swap; + + + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + if ( table[j] > table[j - 1] ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + + static FT_Error + ah_hinter_compute_blues( AH_Hinter hinter ) + { + AH_Blue blue; + AH_Globals globals = &hinter->globals->design; + FT_Pos flats [MAX_TEST_CHARACTERS]; + FT_Pos rounds[MAX_TEST_CHARACTERS]; + FT_Int num_flats; + FT_Int num_rounds; + + FT_Face face; + FT_GlyphSlot glyph; + FT_Error error; + FT_CharMap charmap; + + + face = hinter->face; + glyph = face->glyph; + + /* save current charmap */ + charmap = face->charmap; + + /* do we have a Unicode charmap in there? */ + error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); + if ( error ) + goto Exit; + + /* we compute the blues simply by loading each character from the */ + /* 'blue_chars[blues]' string, then compute its top-most and */ + /* bottom-most points */ + + AH_LOG(( "blue zones computation\n" )); + AH_LOG(( "------------------------------------------------\n" )); + + for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) + { + const char* p = blue_chars[blue]; + const char* limit = p + MAX_TEST_CHARACTERS; + FT_Pos *blue_ref, *blue_shoot; + + + AH_LOG(( "blue %3d: ", blue )); + + num_flats = 0; + num_rounds = 0; + + for ( ; p < limit; p++ ) + { + FT_UInt glyph_index; + FT_Vector* extremum; + FT_Vector* points; + FT_Vector* point_limit; + FT_Vector* point; + FT_Bool round; + + + /* exit if we reach the end of the string */ + if ( !*p ) + break; + + AH_LOG(( "`%c'", *p )); + + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); + if ( glyph_index == 0 ) + continue; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error || glyph->outline.n_points <= 0 ) + continue; + + /* now compute min or max point indices and coordinates */ + points = glyph->outline.points; + point_limit = points + glyph->outline.n_points; + point = points; + extremum = point; + point++; + + if ( AH_IS_TOP_BLUE( blue ) ) + { + for ( ; point < point_limit; point++ ) + if ( point->y > extremum->y ) + extremum = point; + } + else + { + for ( ; point < point_limit; point++ ) + if ( point->y < extremum->y ) + extremum = point; + } + + AH_LOG(( "%5d", (int)extremum->y )); + + /* now, check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then see its previous and next points */ + { + FT_Int idx = (FT_Int)( extremum - points ); + FT_Int n; + FT_Int first, last, prev, next, end; + FT_Pos dist; + + + last = -1; + first = 0; + + for ( n = 0; n < glyph->outline.n_contours; n++ ) + { + end = glyph->outline.contours[n]; + if ( end >= idx ) + { + last = end; + break; + } + first = end + 1; + } + + /* XXX: should never happen! */ + if ( last < 0 ) + continue; + + /* now look for the previous and next points that are not on the */ + /* same Y coordinate. Threshold the `closeness'... */ + + prev = idx; + next = prev; + + do + { + if ( prev > first ) + prev--; + else + prev = last; + + dist = points[prev].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( prev != idx ); + + do + { + if ( next < last ) + next++; + else + next = first; + + dist = points[next].y - extremum->y; + if ( dist < -5 || dist > 5 ) + break; + + } while ( next != idx ); + + /* now, set the `round' flag depending on the segment's kind */ + round = FT_BOOL( + FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_CURVE_TAG_ON || + FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_CURVE_TAG_ON ); + + AH_LOG(( "%c ", round ? 'r' : 'f' )); + } + + if ( round ) + rounds[num_rounds++] = extremum->y; + else + flats[num_flats++] = extremum->y; + } + + AH_LOG(( "\n" )); + + /* we have computed the contents of the `rounds' and `flats' tables, */ + /* now determine the reference and overshoot position of the blue; */ + /* we simply take the median value after a simple short */ + sort_values( num_rounds, rounds ); + sort_values( num_flats, flats ); + + blue_ref = globals->blue_refs + blue; + blue_shoot = globals->blue_shoots + blue; + if ( num_flats == 0 && num_rounds == 0 ) + { + *blue_ref = -10000; + *blue_shoot = -10000; + } + else if ( num_flats == 0 ) + { + *blue_ref = + *blue_shoot = rounds[num_rounds / 2]; + } + else if ( num_rounds == 0 ) + { + *blue_ref = + *blue_shoot = flats[num_flats / 2]; + } + else + { + *blue_ref = flats[num_flats / 2]; + *blue_shoot = rounds[num_rounds / 2]; + } + + /* there are sometimes problems: if the overshoot position of top */ + /* zones is under its reference position, or the opposite for bottom */ + /* zones. We must thus check everything there and correct the errors */ + if ( *blue_shoot != *blue_ref ) + { + FT_Pos ref = *blue_ref; + FT_Pos shoot = *blue_shoot; + FT_Bool over_ref = FT_BOOL( shoot > ref ); + + + if ( AH_IS_TOP_BLUE( blue ) ^ over_ref ) + *blue_shoot = *blue_ref = ( shoot + ref ) / 2; + } + + AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); + } + + /* reset original face charmap */ + FT_Set_Charmap( face, charmap ); + error = 0; + + Exit: + return error; + } + + + static FT_Error + ah_hinter_compute_widths( AH_Hinter hinter ) + { + /* scan the array of segments in each direction */ + AH_Outline outline = hinter->glyph; + AH_Segment segments; + AH_Segment limit; + AH_Globals globals = &hinter->globals->design; + FT_Pos* widths; + FT_Int dimension; + FT_Int* p_num_widths; + FT_Error error = 0; + FT_Pos edge_distance_threshold = 32000; + + + globals->num_widths = 0; + globals->num_heights = 0; + + /* For now, compute the standard width and height from the `o' */ + /* character. I started computing the stem width of the `i' and the */ + /* stem height of the "-", but it wasn't too good. Moreover, we now */ + /* have a single character that gives us standard width and height. */ + { + FT_UInt glyph_index; + + + glyph_index = FT_Get_Char_Index( hinter->face, 'o' ); + if ( glyph_index == 0 ) + return 0; + + error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE ); + if ( error ) + goto Exit; + + error = ah_outline_load( hinter->glyph, 0x10000L, 0x10000L, hinter->face ); + if ( error ) + goto Exit; + + ah_outline_compute_segments( hinter->glyph ); + ah_outline_link_segments( hinter->glyph ); + } + + segments = outline->horz_segments; + limit = segments + outline->num_hsegments; + widths = globals->heights; + p_num_widths = &globals->num_heights; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Segment seg = segments; + AH_Segment link; + FT_Int num_widths = 0; + + + for ( ; seg < limit; seg++ ) + { + link = seg->link; + /* we only consider stem segments there! */ + if ( link && link->link == seg && link > seg ) + { + FT_Pos dist; + + + dist = seg->pos - link->pos; + if ( dist < 0 ) + dist = -dist; + + if ( num_widths < AH_MAX_WIDTHS ) + widths[num_widths++] = dist; + } + } + + sort_values( num_widths, widths ); + *p_num_widths = num_widths; + + /* we will now try to find the smallest width */ + if ( num_widths > 0 && widths[0] < edge_distance_threshold ) + edge_distance_threshold = widths[0]; + + segments = outline->vert_segments; + limit = segments + outline->num_vsegments; + widths = globals->widths; + p_num_widths = &globals->num_widths; + } + + /* Now, compute the edge distance threshold as a fraction of the */ + /* smallest width in the font. Set it in `hinter.glyph' too! */ + if ( edge_distance_threshold == 32000 ) + edge_distance_threshold = 50; + + /* let's try 20% */ + hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + ah_hinter_compute_globals( AH_Hinter hinter ) + { + return ah_hinter_compute_widths( hinter ) || + ah_hinter_compute_blues ( hinter ); + } + + +/* END */ diff --git a/lib/freetype/src/autohint/ahglobal.h b/lib/freetype/src/autohint/ahglobal.h new file mode 100644 index 0000000..ef99a01 --- /dev/null +++ b/lib/freetype/src/autohint/ahglobal.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ahglobal.h */ +/* */ +/* Routines used to compute global metrics automatically */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHGLOBAL_H__ +#define __AHGLOBAL_H__ + + +#include <ft2build.h> +#include "ahtypes.h" +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#ifdef FT_CONFIG_CHESTER_SMALL_F + +# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \ + (b) == AH_BLUE_SMALL_F_TOP || \ + (b) == AH_BLUE_SMALL_TOP ) + +#else /* !CHESTER_SMALL_F */ + +# define AH_IS_TOP_BLUE( b ) ( (b) == AH_BLUE_CAPITAL_TOP || \ + (b) == AH_BLUE_SMALL_TOP ) + +#endif /* !CHESTER_SMALL_F */ + + + /* compute global metrics automatically */ + FT_LOCAL( FT_Error ) + ah_hinter_compute_globals( AH_Hinter hinter ); + + +FT_END_HEADER + +#endif /* __AHGLOBAL_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahglyph.c b/lib/freetype/src/autohint/ahglyph.c new file mode 100644 index 0000000..4f37504 --- /dev/null +++ b/lib/freetype/src/autohint/ahglyph.c @@ -0,0 +1,1595 @@ +/***************************************************************************/ +/* */ +/* ahglyph.c */ +/* */ +/* Routines used to load and analyze a given glyph before hinting */ +/* (body). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "ahglyph.h" +#include "ahangles.h" +#include "ahglobal.h" +#include "aherrors.h" + + +#ifdef AH_DEBUG + +#include <stdio.h> + + void + ah_dump_edges( AH_Outline outline ) + { + AH_Edge edges; + AH_Edge edge_limit; + AH_Segment segments; + FT_Int dimension; + + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + segments = outline->horz_segments; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Edge edge; + + + printf ( "Table of %s edges:\n", + !dimension ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link |" + " serif | blue | opos | pos ]\n" ); + + for ( edge = edges; edge < edge_limit; edge++ ) + { + printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", + edge - edges, + (int)edge->fpos, + edge->dir == AH_DIR_UP + ? "up" + : ( edge->dir == AH_DIR_DOWN + ? "down" + : ( edge->dir == AH_DIR_LEFT + ? "left" + : ( edge->dir == AH_DIR_RIGHT + ? "right" + : "none" ) ) ), + edge->link ? ( edge->link - edges ) : -1, + edge->serif ? ( edge->serif - edges ) : -1, + edge->blue_edge ? 'y' : 'n', + edge->opos / 64.0, + edge->pos / 64.0 ); + } + + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + segments = outline->vert_segments; + } + } + + + /* A function used to dump the array of linked segments */ + void + ah_dump_segments( AH_Outline outline ) + { + AH_Segment segments; + AH_Segment segment_limit; + AH_Point points; + FT_Int dimension; + + + points = outline->points; + segments = outline->horz_segments; + segment_limit = segments + outline->num_hsegments; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Segment seg; + + + printf ( "Table of %s segments:\n", + !dimension ? "vertical" : "horizontal" ); + printf ( " [ index | pos | dir | link | serif |" + " numl | first | start ]\n" ); + + for ( seg = segments; seg < segment_limit; seg++ ) + { + printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n", + seg - segments, + (int)seg->pos, + seg->dir == AH_DIR_UP + ? "up" + : ( seg->dir == AH_DIR_DOWN + ? "down" + : ( seg->dir == AH_DIR_LEFT + ? "left" + : ( seg->dir == AH_DIR_RIGHT + ? "right" + : "none" ) ) ), + seg->link ? (seg->link-segments) : -1, + seg->serif ? (seg->serif-segments) : -1, + (int)seg->num_linked, + seg->first - points, + seg->last - points ); + } + + segments = outline->vert_segments; + segment_limit = segments + outline->num_vsegments; + } + } + +#endif /* AH_DEBUG */ + + + /* compute the direction value of a given vector.. */ + static AH_Direction + ah_compute_direction( FT_Pos dx, + FT_Pos dy ) + { + AH_Direction dir; + FT_Pos ax = ABS( dx ); + FT_Pos ay = ABS( dy ); + + + dir = AH_DIR_NONE; + + /* test for vertical direction */ + if ( ax * 12 < ay ) + { + dir = dy > 0 ? AH_DIR_UP : AH_DIR_DOWN; + } + /* test for horizontal direction */ + else if ( ay * 12 < ax ) + { + dir = dx > 0 ? AH_DIR_RIGHT : AH_DIR_LEFT; + } + + return dir; + } + + + /* this function is used by ah_get_orientation (see below) to test */ + /* the fill direction of a given bbox extrema */ + static FT_Int + ah_test_extrema( FT_Outline* outline, + FT_Int n ) + { + FT_Vector *prev, *cur, *next; + FT_Pos product; + FT_Int first, last, c; + FT_Int retval; + + + /* we need to compute the `previous' and `next' point */ + /* for these extrema */ + cur = outline->points + n; + prev = cur - 1; + next = cur + 1; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + last = outline->contours[c]; + + if ( n == first ) + prev = outline->points + last; + + if ( n == last ) + next = outline->points + first; + + first = last + 1; + } + + product = FT_MulDiv( cur->x - prev->x, /* in.x */ + next->y - cur->y, /* out.y */ + 0x40 ) + - + FT_MulDiv( cur->y - prev->y, /* in.y */ + next->x - cur->x, /* out.x */ + 0x40 ); + + retval = 0; + if ( product ) + retval = product > 0 ? 2 : 1; + + return retval; + } + + + /* Compute the orientation of path filling. It differs between TrueType */ + /* and Type1 formats. We could use the `FT_OUTLINE_REVERSE_FILL' flag, */ + /* but it is better to re-compute it directly (it seems that this flag */ + /* isn't correctly set for some weird composite glyphs currently). */ + /* */ + /* We do this by computing bounding box points, and computing their */ + /* curvature. */ + /* */ + /* The function returns either 1 or -1. */ + /* */ + static FT_Int + ah_get_orientation( FT_Outline* outline ) + { + FT_BBox box; + FT_Int indices_xMin, indices_yMin, indices_xMax, indices_yMax; + FT_Int n, last; + + + indices_xMin = -1; + indices_yMin = -1; + indices_xMax = -1; + indices_yMax = -1; + + box.xMin = box.yMin = 32767L; + box.xMax = box.yMax = -32768L; + + /* is it empty? */ + if ( outline->n_contours < 1 ) + return 1; + + last = outline->contours[outline->n_contours - 1]; + + for ( n = 0; n <= last; n++ ) + { + FT_Pos x, y; + + + x = outline->points[n].x; + if ( x < box.xMin ) + { + box.xMin = x; + indices_xMin = n; + } + if ( x > box.xMax ) + { + box.xMax = x; + indices_xMax = n; + } + + y = outline->points[n].y; + if ( y < box.yMin ) + { + box.yMin = y; + indices_yMin = n; + } + if ( y > box.yMax ) + { + box.yMax = y; + indices_yMax = n; + } + } + + /* test orientation of the xmin */ + n = ah_test_extrema( outline, indices_xMin ); + if ( n ) + goto Exit; + + n = ah_test_extrema( outline, indices_yMin ); + if ( n ) + goto Exit; + + n = ah_test_extrema( outline, indices_xMax ); + if ( n ) + goto Exit; + + n = ah_test_extrema( outline, indices_yMax ); + if ( !n ) + n = 1; + + Exit: + return n; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_new */ + /* */ + /* <Description> */ + /* Creates a new and empty AH_OutlineRec object. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ah_outline_new( FT_Memory memory, + AH_Outline* aoutline ) + { + FT_Error error; + AH_Outline outline; + + + if ( !FT_NEW( outline ) ) + { + outline->memory = memory; + *aoutline = outline; + } + + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_done */ + /* */ + /* <Description> */ + /* Destroys a given AH_OutlineRec object. */ + /* */ + FT_LOCAL_DEF( void ) + ah_outline_done( AH_Outline outline ) + { + FT_Memory memory = outline->memory; + + + FT_FREE( outline->horz_edges ); + FT_FREE( outline->horz_segments ); + FT_FREE( outline->contours ); + FT_FREE( outline->points ); + + FT_FREE( outline ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_save */ + /* */ + /* <Description> */ + /* Saves the contents of a given AH_OutlineRec object into a face's */ + /* glyph slot. */ + /* */ + FT_LOCAL_DEF( void ) + ah_outline_save( AH_Outline outline, + AH_Loader gloader ) + { + AH_Point point = outline->points; + AH_Point point_limit = point + outline->num_points; + FT_Vector* vec = gloader->current.outline.points; + char* tag = gloader->current.outline.tags; + + + /* we assume that the glyph loader has already been checked for storage */ + for ( ; point < point_limit; point++, vec++, tag++ ) + { + vec->x = point->x; + vec->y = point->y; + + if ( point->flags & AH_FLAG_CONIC ) + tag[0] = FT_CURVE_TAG_CONIC; + else if ( point->flags & AH_FLAG_CUBIC ) + tag[0] = FT_CURVE_TAG_CUBIC; + else + tag[0] = FT_CURVE_TAG_ON; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_load */ + /* */ + /* <Description> */ + /* Loads an unscaled outline from a glyph slot into an AH_OutlineRec */ + /* object. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ah_outline_load( AH_Outline outline, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Face face ) + { + FT_Memory memory = outline->memory; + FT_Error error = AH_Err_Ok; + FT_Outline* source = &face->glyph->outline; + FT_Int num_points = source->n_points; + FT_Int num_contours = source->n_contours; + AH_Point points; + + + /* check arguments */ + if ( !face || + !face->size || + face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) + return AH_Err_Invalid_Argument; + + /* first of all, reallocate the contours array if necessary */ + if ( num_contours > outline->max_contours ) + { + FT_Int new_contours = ( num_contours + 3 ) & -4; + + + if ( FT_RENEW_ARRAY( outline->contours, + outline->max_contours, + new_contours ) ) + goto Exit; + + outline->max_contours = new_contours; + } + + /* then, reallocate the points, segments & edges arrays if needed -- */ + /* note that we reserved two additional point positions, used to */ + /* hint metrics appropriately */ + /* */ + if ( num_points + 2 > outline->max_points ) + { + FT_Int news = ( num_points + 2 + 7 ) & -8; + FT_Int max = outline->max_points; + + + if ( FT_RENEW_ARRAY( outline->points, max, news ) || + FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) || + FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) ) + goto Exit; + + /* readjust some pointers */ + outline->vert_edges = outline->horz_edges + news; + outline->vert_segments = outline->horz_segments + news; + outline->max_points = news; + } + + outline->num_points = num_points; + outline->num_contours = num_contours; + + outline->num_hedges = 0; + outline->num_vedges = 0; + outline->num_hsegments = 0; + outline->num_vsegments = 0; + + /* We can't rely on the value of `FT_Outline.flags' to know the fill */ + /* direction used for a glyph, given that some fonts are broken (e.g. */ + /* the Arphic ones). We thus recompute it each time we need to. */ + /* */ + outline->vert_major_dir = AH_DIR_UP; + outline->horz_major_dir = AH_DIR_LEFT; + + if ( ah_get_orientation( source ) > 1 ) + { + outline->vert_major_dir = AH_DIR_DOWN; + outline->horz_major_dir = AH_DIR_RIGHT; + } + + outline->x_scale = x_scale; + outline->y_scale = y_scale; + + points = outline->points; + if ( outline->num_points == 0 ) + goto Exit; + + { + /* do one thing at a time -- it is easier to understand, and */ + /* the code is clearer */ + AH_Point point; + AH_Point point_limit = points + outline->num_points; + + + /* compute coordinates */ + { + FT_Vector* vec = source->points; + + + for ( point = points; point < point_limit; vec++, point++ ) + { + point->fx = vec->x; + point->fy = vec->y; + point->ox = point->x = FT_MulFix( vec->x, x_scale ); + point->oy = point->y = FT_MulFix( vec->y, y_scale ); + + point->flags = 0; + } + } + + /* compute Bezier flags */ + { + char* tag = source->tags; + + + for ( point = points; point < point_limit; point++, tag++ ) + { + switch ( FT_CURVE_TAG( *tag ) ) + { + case FT_CURVE_TAG_CONIC: + point->flags = AH_FLAG_CONIC; break; + case FT_CURVE_TAG_CUBIC: + point->flags = AH_FLAG_CUBIC; break; + default: + ; + } + } + } + + /* compute `next' and `prev' */ + { + FT_Int contour_index; + AH_Point prev; + AH_Point first; + AH_Point end; + + + contour_index = 0; + + first = points; + end = points + source->contours[0]; + prev = end; + + for ( point = points; point < point_limit; point++ ) + { + point->prev = prev; + if ( point < end ) + { + point->next = point + 1; + prev = point; + } + else + { + point->next = first; + contour_index++; + if ( point + 1 < point_limit ) + { + end = points + source->contours[contour_index]; + first = point + 1; + prev = end; + } + } + } + } + + /* set-up the contours array */ + { + AH_Point* contour = outline->contours; + AH_Point* contour_limit = contour + outline->num_contours; + short* end = source->contours; + short idx = 0; + + + for ( ; contour < contour_limit; contour++, end++ ) + { + contour[0] = points + idx; + idx = (short)( end[0] + 1 ); + } + } + + /* compute directions of in & out vectors */ + { + for ( point = points; point < point_limit; point++ ) + { + AH_Point prev; + AH_Point next; + FT_Vector ivec, ovec; + + + prev = point->prev; + ivec.x = point->fx - prev->fx; + ivec.y = point->fy - prev->fy; + + point->in_dir = ah_compute_direction( ivec.x, ivec.y ); + + next = point->next; + ovec.x = next->fx - point->fx; + ovec.y = next->fy - point->fy; + + point->out_dir = ah_compute_direction( ovec.x, ovec.y ); + +#ifndef AH_OPTION_NO_WEAK_INTERPOLATION + if ( point->flags & (AH_FLAG_CONIC | AH_FLAG_CUBIC) ) + { + Is_Weak_Point: + point->flags |= AH_FLAG_WEAK_INTERPOLATION; + } + else if ( point->out_dir == point->in_dir ) + { + AH_Angle angle_in, angle_out, delta; + + + if ( point->out_dir != AH_DIR_NONE ) + goto Is_Weak_Point; + + angle_in = ah_angle( &ivec ); + angle_out = ah_angle( &ovec ); + delta = angle_in - angle_out; + + if ( delta > AH_PI ) + delta = AH_2PI - delta; + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 2 ) + goto Is_Weak_Point; + } + else if ( point->in_dir == -point->out_dir ) + goto Is_Weak_Point; +#endif + } + } + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + ah_setup_uv( AH_Outline outline, + AH_UV source ) + { + AH_Point point = outline->points; + AH_Point point_limit = point + outline->num_points; + + + for ( ; point < point_limit; point++ ) + { + FT_Pos u, v; + + + switch ( source ) + { + case AH_UV_FXY: + u = point->fx; + v = point->fy; + break; + case AH_UV_FYX: + u = point->fy; + v = point->fx; + break; + case AH_UV_OXY: + u = point->ox; + v = point->oy; + break; + case AH_UV_OYX: + u = point->oy; + v = point->ox; + break; + case AH_UV_YX: + u = point->y; + v = point->x; + break; + case AH_UV_OX: + u = point->x; + v = point->ox; + break; + case AH_UV_OY: + u = point->y; + v = point->oy; + break; + default: + u = point->x; + v = point->y; + break; + } + point->u = u; + point->v = v; + } + } + + + /* compute all inflex points in a given glyph */ + static void + ah_outline_compute_inflections( AH_Outline outline ) + { + AH_Point* contour = outline->contours; + AH_Point* contour_limit = contour + outline->num_contours; + + + /* load original coordinates in (u,v) */ + ah_setup_uv( outline, AH_UV_FXY ); + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + FT_Vector vec; + AH_Point point = contour[0]; + AH_Point first = point; + AH_Point start = point; + AH_Point end = point; + AH_Point before; + AH_Point after; + AH_Angle angle_in, angle_seg, angle_out; + AH_Angle diff_in, diff_out; + FT_Int finished = 0; + + + /* compute first segment in contour */ + first = point; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + } while ( end->u == first->u && end->v == first->v ); + + vec.x = end->u - start->u; + vec.y = end->v - start->v; + angle_seg = ah_angle( &vec ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( before->u == start->u && before->v == start->v ); + + vec.x = start->u - before->u; + vec.y = start->v - before->v; + angle_in = ah_angle( &vec ); + + } while ( angle_in == angle_seg ); + + first = start; + diff_in = ah_angle_diff( angle_in, angle_seg ); + + /* now, process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + } while ( end->u == after->u && end->v == after->v ); + + vec.x = after->u - end->u; + vec.y = after->v - end->v; + angle_out = ah_angle( &vec ); + + } while ( angle_out == angle_seg ); + + diff_out = ah_angle_diff( angle_seg, angle_out ); + + if ( ( diff_in ^ diff_out ) < 0 ) + { + /* diff_in and diff_out have different signs, we have */ + /* inflection points here... */ + + do + { + start->flags |= AH_FLAG_INFLECTION; + start = start->next; + + } while ( start != end ); + + start->flags |= AH_FLAG_INFLECTION; + } + + start = end; + end = after; + angle_seg = angle_out; + diff_in = diff_out; + + } while ( !finished ); + + Skip: + ; + } + } + + + FT_LOCAL_DEF( void ) + ah_outline_compute_segments( AH_Outline outline ) + { + int dimension; + AH_Segment segments; + FT_Int* p_num_segments; + AH_Direction segment_dir; + AH_Direction major_dir; + + + segments = outline->horz_segments; + p_num_segments = &outline->num_hsegments; + major_dir = AH_DIR_RIGHT; /* This value must be positive! */ + segment_dir = major_dir; + + /* set up (u,v) in each point */ + ah_setup_uv( outline, AH_UV_FYX ); + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Point* contour = outline->contours; + AH_Point* contour_limit = contour + outline->num_contours; + AH_Segment segment = segments; + FT_Int num_segments = 0; + +#ifdef AH_HINT_METRICS + AH_Point min_point = 0; + AH_Point max_point = 0; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; +#endif + + + /* do each contour separately */ + for ( ; contour < contour_limit; contour++ ) + { + AH_Point point = contour[0]; + AH_Point last = point->prev; + int on_edge = 0; + FT_Pos min_pos = +32000; /* minimum segment pos != min_coord */ + FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ + FT_Bool passed; + + +#ifdef AH_HINT_METRICS + if ( point->u < min_coord ) + { + min_coord = point->u; + min_point = point; + } + if ( point->u > max_coord ) + { + max_coord = point->u; + max_point = point; + } +#endif + + if ( point == last ) /* skip singletons -- just in case? */ + continue; + + if ( ABS( last->out_dir ) == major_dir && + ABS( point->out_dir ) == major_dir ) + { + /* we are already on an edge, try to locate its start */ + last = point; + + for (;;) + { + point = point->prev; + if ( ABS( point->out_dir ) != major_dir ) + { + point = point->next; + break; + } + if ( point == last ) + break; + } + } + + last = point; + passed = 0; + + for (;;) + { + FT_Pos u, v; + + + if ( on_edge ) + { + u = point->u; + if ( u < min_pos ) + min_pos = u; + if ( u > max_pos ) + max_pos = u; + + if ( point->out_dir != segment_dir || point == last ) + { + /* we are just leaving an edge; record a new segment! */ + segment->last = point; + segment->pos = ( min_pos + max_pos ) >> 1; + + /* a segment is round if either its first or last point */ + /* is a control point */ + if ( ( segment->first->flags | point->flags ) & + AH_FLAG_CONTROL ) + segment->flags |= AH_EDGE_ROUND; + + /* compute segment size */ + min_pos = max_pos = point->v; + + v = segment->first->v; + if ( v < min_pos ) + min_pos = v; + if ( v > max_pos ) + max_pos = v; + + segment->min_coord = min_pos; + segment->max_coord = max_pos; + + on_edge = 0; + num_segments++; + segment++; + /* fallthrough */ + } + } + + /* now exit if we are at the start/end point */ + if ( point == last ) + { + if ( passed ) + break; + passed = 1; + } + + if ( !on_edge && ABS( point->out_dir ) == major_dir ) + { + /* this is the start of a new segment! */ + segment_dir = point->out_dir; + + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AH_EDGE_NORMAL; + min_pos = max_pos = point->u; + segment->first = point; + segment->last = point; + segment->contour = contour; + on_edge = 1; + +#ifdef AH_HINT_METRICS + if ( point == max_point ) + max_point = 0; + + if ( point == min_point ) + min_point = 0; +#endif + } + + point = point->next; + } + + } /* contours */ + +#ifdef AH_HINT_METRICS + /* we need to ensure that there are edges on the left-most and */ + /* right-most points of the glyph in order to hint the metrics; */ + /* we do this by inserting fake segments when needed */ + if ( dimension == 0 ) + { + AH_Point point = outline->points; + AH_Point point_limit = point + outline->num_points; + + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; + + + min_point = 0; + max_point = 0; + + /* compute minimum and maximum points */ + for ( ; point < point_limit; point++ ) + { + FT_Pos x = point->fx; + + + if ( x < min_pos ) + { + min_pos = x; + min_point = point; + } + if ( x > max_pos ) + { + max_pos = x; + max_point = point; + } + } + + /* insert minimum segment */ + if ( min_point ) + { + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AH_EDGE_NORMAL; + segment->first = min_point; + segment->last = min_point; + segment->pos = min_pos; + + num_segments++; + segment++; + } + + /* insert maximum segment */ + if ( max_point ) + { + /* clear all segment fields */ + FT_ZERO( segment ); + + segment->dir = segment_dir; + segment->flags = AH_EDGE_NORMAL; + segment->first = max_point; + segment->last = max_point; + segment->pos = max_pos; + + num_segments++; + segment++; + } + } +#endif /* AH_HINT_METRICS */ + + *p_num_segments = num_segments; + + segments = outline->vert_segments; + major_dir = AH_DIR_UP; + p_num_segments = &outline->num_vsegments; + ah_setup_uv( outline, AH_UV_FXY ); + } + } + + + FT_LOCAL_DEF( void ) + ah_outline_link_segments( AH_Outline outline ) + { + AH_Segment segments; + AH_Segment segment_limit; + int dimension; + + + ah_setup_uv( outline, AH_UV_FYX ); + + segments = outline->horz_segments; + segment_limit = segments + outline->num_hsegments; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Segment seg1; + AH_Segment seg2; + + + /* now compare each segment to the others */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + FT_Pos best_score; + AH_Segment best_segment; + + + /* the fake segments are introduced to hint the metrics -- */ + /* we must never link them to anything */ + if ( seg1->first == seg1->last ) + continue; + + best_segment = seg1->link; + if ( best_segment ) + best_score = seg1->score; + else + best_score = 32000; + + for ( seg2 = segments; seg2 < segment_limit; seg2++ ) + if ( seg1 != seg2 && seg1->dir + seg2->dir == 0 ) + { + FT_Pos pos1 = seg1->pos; + FT_Pos pos2 = seg2->pos; + FT_Bool is_dir; + FT_Bool is_pos; + + + /* check that the segments are correctly oriented and */ + /* positioned to form a black distance */ + + is_dir = (FT_Bool)( seg1->dir == outline->horz_major_dir || + seg1->dir == outline->vert_major_dir ); + is_pos = (FT_Bool)( pos1 > pos2 ); + + if ( pos1 == pos2 || !(is_dir ^ is_pos) ) + continue; + + { + FT_Pos min = seg1->min_coord; + FT_Pos max = seg1->max_coord; + FT_Pos len, dist, score; + + + if ( min < seg2->min_coord ) + min = seg2->min_coord; + + if ( max > seg2->max_coord ) + max = seg2->max_coord; + + len = max - min; + if ( len >= 8 ) + { + dist = seg2->pos - seg1->pos; + if ( dist < 0 ) + dist = -dist; + + score = dist + 3000 / len; + + if ( score < best_score ) + { + best_score = score; + best_segment = seg2; + } + } + } + } + + if ( best_segment ) + { + seg1->link = best_segment; + seg1->score = best_score; + + best_segment->num_linked++; + } + + } /* edges 1 */ + + /* now, compute the `serif' segments */ + for ( seg1 = segments; seg1 < segment_limit; seg1++ ) + { + seg2 = seg1->link; + + if ( seg2 && seg2->link != seg1 ) + { + seg1->link = 0; + seg1->serif = seg2->link; + } + } + + ah_setup_uv( outline, AH_UV_FXY ); + + segments = outline->vert_segments; + segment_limit = segments + outline->num_vsegments; + } + } + + + static void + ah_outline_compute_edges( AH_Outline outline ) + { + AH_Edge edges; + AH_Segment segments; + AH_Segment segment_limit; + AH_Direction up_dir; + FT_Int* p_num_edges; + FT_Int dimension; + FT_Fixed scale; + FT_Pos edge_distance_threshold; + + + edges = outline->horz_edges; + segments = outline->horz_segments; + segment_limit = segments + outline->num_hsegments; + p_num_edges = &outline->num_hedges; + up_dir = AH_DIR_RIGHT; + scale = outline->y_scale; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Edge edge; + AH_Edge edge_limit; /* really == edge + num_edges */ + AH_Segment seg; + + + /*********************************************************************/ + /* */ + /* We will begin by generating a sorted table of edges for the */ + /* current direction. To do so, we simply scan each segment and try */ + /* to find an edge in our table that corresponds to its position. */ + /* */ + /* If no edge is found, we create and insert a new edge in the */ + /* sorted table. Otherwise, we simply add the segment to the edge's */ + /* list which will be processed in the second step to compute the */ + /* edge's properties. */ + /* */ + /* Note that the edges table is sorted along the segment/edge */ + /* position. */ + /* */ + /*********************************************************************/ + + edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold, + scale ); + if ( edge_distance_threshold > 64 / 4 ) + edge_distance_threshold = 64 / 4; + + edge_limit = edges; + for ( seg = segments; seg < segment_limit; seg++ ) + { + AH_Edge found = 0; + + + /* look for an edge corresponding to the segment */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, scale ); + if ( dist < edge_distance_threshold ) + { + found = edge; + break; + } + } + + if ( !found ) + { + /* insert a new edge in the list and */ + /* sort according to the position */ + while ( edge > edges && edge[-1].fpos > seg->pos ) + { + edge[0] = edge[-1]; + edge--; + } + edge_limit++; + + /* clear all edge fields */ + FT_MEM_ZERO( edge, sizeof ( *edge ) ); + + /* add the segment to the new edge's list */ + edge->first = seg; + edge->last = seg; + edge->fpos = seg->pos; + edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); + seg->edge_next = seg; + } + else + { + /* if an edge was found, simply add the segment to the edge's */ + /* list */ + seg->edge_next = edge->first; + edge->last->edge_next = seg; + edge->last = seg; + } + } + + *p_num_edges = (FT_Int)( edge_limit - edges ); + + + /*********************************************************************/ + /* */ + /* Good, we will now compute each edge's properties according to */ + /* segments found on its position. Basically, these are: */ + /* */ + /* - edge's main direction */ + /* - stem edge, serif edge or both (which defaults to stem then) */ + /* - rounded edge, straigth or both (which defaults to straight) */ + /* - link for edge */ + /* */ + /*********************************************************************/ + + /* first of all, set the `edge' field in each segment -- this is */ + /* required in order to compute edge links */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + seg = edge->first; + if ( seg ) + do + { + seg->edge = edge; + seg = seg->edge_next; + } + while ( seg != edge->first ); + } + + /* now, compute each edge properties */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Int is_round = 0; /* does it contain round segments? */ + FT_Int is_straight = 0; /* does it contain straight segments? */ + FT_Pos ups = 0; /* number of upwards segments */ + FT_Pos downs = 0; /* number of downwards segments */ + + + seg = edge->first; + + do + { + FT_Bool is_serif; + + + /* check for roundness of segment */ + if ( seg->flags & AH_EDGE_ROUND ) + is_round++; + else + is_straight++; + + /* check for segment direction */ + if ( seg->dir == up_dir ) + ups += seg->max_coord-seg->min_coord; + else + downs += seg->max_coord-seg->min_coord; + + /* check for links -- if seg->serif is set, then seg->link must */ + /* be ignored */ + is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge ); + + if ( seg->link || is_serif ) + { + AH_Edge edge2; + AH_Segment seg2; + + + edge2 = edge->link; + seg2 = seg->link; + + if ( is_serif ) + { + seg2 = seg->serif; + edge2 = edge->serif; + } + + if ( edge2 ) + { + FT_Pos edge_delta; + FT_Pos seg_delta; + + + edge_delta = edge->fpos - edge2->fpos; + if ( edge_delta < 0 ) + edge_delta = -edge_delta; + + seg_delta = seg->pos - seg2->pos; + if ( seg_delta < 0 ) + seg_delta = -seg_delta; + + if ( seg_delta < edge_delta ) + edge2 = seg2->edge; + } + else + edge2 = seg2->edge; + +#ifdef FT_CONFIG_CHESTER_SERIF + if ( is_serif ) + { + edge->serif = edge2; + edge2->flags |= AH_EDGE_SERIF; + } + else + edge->link = edge2; +#else /* !CHESTER_SERIF */ + if ( is_serif ) + edge->serif = edge2; + else + edge->link = edge2; +#endif + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + + /* set the round/straight flags */ + edge->flags = AH_EDGE_NORMAL; + + if ( is_round > 0 && is_round >= is_straight ) + edge->flags |= AH_EDGE_ROUND; + + /* set the edge's main direction */ + edge->dir = AH_DIR_NONE; + + if ( ups > downs ) + edge->dir = up_dir; + + else if ( ups < downs ) + edge->dir = - up_dir; + + else if ( ups == downs ) + edge->dir = 0; /* both up and down !! */ + + /* gets rid of serifs if link is set */ + /* XXX: This gets rid of many unpleasant artefacts! */ + /* Example: the `c' in cour.pfa at size 13 */ + + if ( edge->serif && edge->link ) + edge->serif = 0; + } + + edges = outline->vert_edges; + segments = outline->vert_segments; + segment_limit = segments + outline->num_vsegments; + p_num_edges = &outline->num_vedges; + up_dir = AH_DIR_UP; + scale = outline->x_scale; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_detect_features */ + /* */ + /* <Description> */ + /* Performs feature detection on a given AH_OutlineRec object. */ + /* */ + FT_LOCAL_DEF( void ) + ah_outline_detect_features( AH_Outline outline ) + { + ah_outline_compute_segments ( outline ); + ah_outline_link_segments ( outline ); + ah_outline_compute_edges ( outline ); + ah_outline_compute_inflections( outline ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_compute_blue_edges */ + /* */ + /* <Description> */ + /* Computes the `blue edges' in a given outline (i.e. those that must */ + /* be snapped to a blue zone edge (top or bottom). */ + /* */ + FT_LOCAL_DEF( void ) + ah_outline_compute_blue_edges( AH_Outline outline, + AH_Face_Globals face_globals ) + { + AH_Edge edge = outline->horz_edges; + AH_Edge edge_limit = edge + outline->num_hedges; + AH_Globals globals = &face_globals->design; + FT_Fixed y_scale = outline->y_scale; + + FT_Bool blue_active[AH_BLUE_MAX]; + + + /* compute which blue zones are active, i.e. have their scaled */ + /* size < 3/4 pixels */ + { + AH_Blue blue; + FT_Bool check = 0; + + + for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) + { + FT_Pos ref, shoot, dist; + + + ref = globals->blue_refs[blue]; + shoot = globals->blue_shoots[blue]; + dist = ref-shoot; + if ( dist < 0 ) + dist = -dist; + + blue_active[blue] = 0; + + if ( FT_MulFix( dist, y_scale ) < 48 ) + { + blue_active[blue] = 1; + check = 1; + } + } + + /* return immediately if no blue zone is active */ + if ( !check ) + return; + } + + /* compute for each horizontal edge, which blue zone is closer */ + for ( ; edge < edge_limit; edge++ ) + { + AH_Blue blue; + FT_Pos* best_blue = 0; + FT_Pos best_dist; /* initial threshold */ + + + /* compute the initial threshold as a fraction of the EM size */ + best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale ); + +#ifdef FT_CONFIG_CHESTER_SMALL_F + if ( best_dist > 64 / 2 ) + best_dist = 64 / 2; +#else + if ( best_dist > 64 / 4 ) + best_dist = 64 / 4; +#endif + + for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ ) + { + /* if it is a top zone, check for right edges -- if it is a bottom */ + /* zone, check for left edges */ + /* */ + /* of course, that's for TrueType XXX */ + FT_Bool is_top_blue = + FT_BOOL( AH_IS_TOP_BLUE( blue ) ); + FT_Bool is_major_dir = + FT_BOOL( edge->dir == outline->horz_major_dir ); + + if ( !blue_active[blue] ) + continue; + + /* if it is a top zone, the edge must be against the major */ + /* direction; if it is a bottom zone, it must be in the major */ + /* direction */ + if ( is_top_blue ^ is_major_dir ) + { + FT_Pos dist; + FT_Pos* blue_pos = globals->blue_refs + blue; + + + /* first of all, compare it to the reference position */ + dist = edge->fpos - *blue_pos; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, y_scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = blue_pos; + } + + /* now, compare it to the overshoot position if the edge is */ + /* rounded, and if the edge is over the reference position of a */ + /* top zone, or under the reference position of a bottom zone */ + if ( edge->flags & AH_EDGE_ROUND && dist != 0 ) + { + FT_Bool is_under_ref = FT_BOOL( edge->fpos < *blue_pos ); + + + if ( is_top_blue ^ is_under_ref ) + { + blue_pos = globals->blue_shoots + blue; + dist = edge->fpos - *blue_pos; + if ( dist < 0 ) + dist = -dist; + + dist = FT_MulFix( dist, y_scale ); + if ( dist < best_dist ) + { + best_dist = dist; + best_blue = blue_pos; + } + } + } + } + } + + if ( best_blue ) + edge->blue_edge = best_blue; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ah_outline_scale_blue_edges */ + /* */ + /* <Description> */ + /* This functions must be called before hinting in order to re-adjust */ + /* the contents of the detected edges (basically change the `blue */ + /* edge' pointer from `design units' to `scaled ones'). */ + /* */ + FT_LOCAL_DEF( void ) + ah_outline_scale_blue_edges( AH_Outline outline, + AH_Face_Globals globals ) + { + AH_Edge edge = outline->horz_edges; + AH_Edge edge_limit = edge + outline->num_hedges; + FT_Pos delta; + + + delta = globals->scaled.blue_refs - globals->design.blue_refs; + + for ( ; edge < edge_limit; edge++ ) + { + if ( edge->blue_edge ) + edge->blue_edge += delta; + } + } + + +/* END */ diff --git a/lib/freetype/src/autohint/ahglyph.h b/lib/freetype/src/autohint/ahglyph.h new file mode 100644 index 0000000..b346cbe --- /dev/null +++ b/lib/freetype/src/autohint/ahglyph.h @@ -0,0 +1,95 @@ +/***************************************************************************/ +/* */ +/* ahglyph.h */ +/* */ +/* Routines used to load and analyze a given glyph before hinting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHGLYPH_H__ +#define __AHGLYPH_H__ + + +#include <ft2build.h> +#include "ahtypes.h" + + +FT_BEGIN_HEADER + + + typedef enum AH_UV_ + { + AH_UV_FXY, + AH_UV_FYX, + AH_UV_OXY, + AH_UV_OYX, + AH_UV_OX, + AH_UV_OY, + AH_UV_YX, + AH_UV_XY /* should always be last! */ + + } AH_UV; + + + FT_LOCAL( void ) + ah_setup_uv( AH_Outline outline, + AH_UV source ); + + + /* AH_OutlineRec functions - they should be typically called in this order */ + + FT_LOCAL( FT_Error ) + ah_outline_new( FT_Memory memory, + AH_Outline* aoutline ); + + FT_LOCAL( FT_Error ) + ah_outline_load( AH_Outline outline, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Face face ); + + FT_LOCAL( void ) + ah_outline_compute_segments( AH_Outline outline ); + + FT_LOCAL( void ) + ah_outline_link_segments( AH_Outline outline ); + + FT_LOCAL( void ) + ah_outline_detect_features( AH_Outline outline ); + + FT_LOCAL( void ) + ah_outline_compute_blue_edges( AH_Outline outline, + AH_Face_Globals globals ); + + FT_LOCAL( void ) + ah_outline_scale_blue_edges( AH_Outline outline, + AH_Face_Globals globals ); + + FT_LOCAL( void ) + ah_outline_save( AH_Outline outline, + AH_Loader loader ); + + FT_LOCAL( void ) + ah_outline_done( AH_Outline outline ); + + +FT_END_HEADER + +#endif /* __AHGLYPH_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahhint.c b/lib/freetype/src/autohint/ahhint.c new file mode 100644 index 0000000..5814e37 --- /dev/null +++ b/lib/freetype/src/autohint/ahhint.c @@ -0,0 +1,1786 @@ +/***************************************************************************/ +/* */ +/* ahhint.c */ +/* */ +/* Glyph hinter (body). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include "ahhint.h" +#include "ahglyph.h" +#include "ahangles.h" +#include "aherrors.h" +#include FT_OUTLINE_H + + +#define FACE_GLOBALS( face ) ((AH_Face_Globals)(face)->autohint.data) + +#define AH_USE_IUP +#define OPTIM_STEM_SNAP + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** Hinting routines ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /* snap a given width in scaled coordinates to one of the */ + /* current standard widths */ + static FT_Pos + ah_snap_width( FT_Pos* widths, + FT_Int count, + FT_Pos width ) + { + int n; + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + FT_Pos scaled; + + + for ( n = 0; n < count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = widths[n]; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + scaled = (reference+32) & -64; + + if ( width >= reference ) + { + if ( width < scaled + 48 ) + width = reference; + } + else + { + if ( width > scaled - 48 ) + width = reference; + } + + return width; + } + + + /* compute the snapped width of a given stem */ +#ifdef FT_CONFIG_CHESTER_SERIF + static FT_Pos + ah_compute_stem_width( AH_Hinter hinter, + int vertical, + FT_Pos width, + AH_Edge_Flags base_flags, + AH_Edge_Flags stem_flags ) + { + AH_Globals globals = &hinter->globals->scaled; + FT_Pos dist = width; + FT_Int sign = 0; + + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( !hinter->do_stem_adjust ) + { + /* leave stem widths unchanged */ + } + else if ( ( vertical && !hinter->do_vert_snapping ) || + ( !vertical && !hinter->do_horz_snapping ) ) + { + /* smooth hinting process, very lightly quantize the stem width */ + /* */ + + /* leave the widths of serifs alone */ + + if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) ) + goto Done_Width; + + else if ( ( base_flags & AH_EDGE_ROUND ) ) + { + if ( dist < 80 ) + dist = 64; + } + else if ( dist < 56 ) + dist = 56; + + { + FT_Pos delta = dist - globals->stds[vertical]; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = globals->stds[vertical]; + if ( dist < 48 ) + dist = 48; + + goto Done_Width; + } + + if ( dist < 3 * 64 ) + { + delta = ( dist & 63 ); + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & -64; + } + } + else + { + /* strong hinting process, snap the stem width to integer pixels */ + /* */ + if ( vertical ) + { + dist = ah_snap_width( globals->heights, globals->num_heights, dist ); + + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + if ( dist >= 64 ) + dist = ( dist + 16 ) & -64; + else + dist = 64; + } + else + { + dist = ah_snap_width( globals->widths, globals->num_widths, dist ); + + if ( hinter->flags & AH_HINTER_MONOCHROME ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & -64; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & -64; + else + /* XXX: round otherwise, prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & -64; + } + } + } + + Done_Width: + if ( sign ) + dist = -dist; + + return dist; + } +#else /* !CHESTER_SERIF */ + static FT_Pos + ah_compute_stem_width( AH_Hinter hinter, + int vertical, + FT_Pos width ) + { + AH_Globals globals = &hinter->globals->scaled; + FT_Pos dist = width; + FT_Int sign = 0; + + + if ( dist < 0 ) + { + dist = -width; + sign = 1; + } + + if ( !hinter->do_stem_adjust ) + { + /* leave stem widths unchanged */ + } + else if ( ( vertical && !hinter->do_vert_snapping ) || + ( !vertical && !hinter->do_horz_snapping ) ) + { + /* smooth hinting process, very lightly quantize the stem width */ + /* */ + if ( dist < 64 ) + dist = 64; + + { + FT_Pos delta = dist - globals->stds[vertical]; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + dist = globals->stds[vertical]; + if ( dist < 48 ) + dist = 48; + } + + if ( dist < 3 * 64 ) + { + delta = ( dist & 63 ); + dist &= -64; + + if ( delta < 10 ) + dist += delta; + + else if ( delta < 32 ) + dist += 10; + + else if ( delta < 54 ) + dist += 54; + + else + dist += delta; + } + else + dist = ( dist + 32 ) & -64; + } + } + else + { + /* strong hinting process, snap the stem width to integer pixels */ + /* */ + if ( vertical ) + { + dist = ah_snap_width( globals->heights, globals->num_heights, dist ); + + /* in the case of vertical hinting, always round */ + /* the stem heights to integer pixels */ + if ( dist >= 64 ) + dist = ( dist + 16 ) & -64; + else + dist = 64; + } + else + { + dist = ah_snap_width( globals->widths, globals->num_widths, dist ); + + if ( hinter->flags & AH_HINTER_MONOCHROME ) + { + /* monochrome horizontal hinting: snap widths to integer pixels */ + /* with a different threshold */ + if ( dist < 64 ) + dist = 64; + else + dist = ( dist + 32 ) & -64; + } + else + { + /* for horizontal anti-aliased hinting, we adopt a more subtle */ + /* approach: we strengthen small stems, round stems whose size */ + /* is between 1 and 2 pixels to an integer, otherwise nothing */ + if ( dist < 48 ) + dist = ( dist + 64 ) >> 1; + + else if ( dist < 128 ) + dist = ( dist + 22 ) & -64; + else + /* XXX: round otherwise, prevent color fringes in LCD mode */ + dist = ( dist + 32 ) & -64; + } + } + } + + if ( sign ) + dist = -dist; + + return dist; + } +#endif /* !CHESTER_SERIF */ + + + /* align one stem edge relative to the previous stem edge */ + static void + ah_align_linked_edge( AH_Hinter hinter, + AH_Edge base_edge, + AH_Edge stem_edge, + int vertical ) + { + FT_Pos dist = stem_edge->opos - base_edge->opos; + +#ifdef FT_CONFIG_CHESTER_SERIF + FT_Pos fitted_width = ah_compute_stem_width( hinter, + vertical, + dist, + base_edge->flags, + stem_edge->flags ); + + stem_edge->pos = base_edge->pos + fitted_width; +#else + stem_edge->pos = base_edge->pos + + ah_compute_stem_width( hinter, vertical, dist ); +#endif + } + + + static void + ah_align_serif_edge( AH_Hinter hinter, + AH_Edge base, + AH_Edge serif, + int vertical ) + { + FT_Pos dist; + FT_Pos sign = 1; + + FT_UNUSED( hinter ); + FT_UNUSED( vertical ); + + dist = serif->opos - base->opos; + if ( dist < 0 ) + { + dist = -dist; + sign = -1; + } + + /* do not touch serifs widths !! */ +#if 0 + if ( base->flags & AH_EDGE_DONE ) + { + if ( dist >= 64 ) + dist = (dist+8) & -64; + + else if ( dist <= 32 && !vertical ) + dist = ( dist + 33 ) >> 1; + else + dist = 0; + } +#endif + + serif->pos = base->pos + sign * dist; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** E D G E H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* Another alternative edge hinting algorithm */ + static void + ah_hint_edges_3( AH_Hinter hinter ) + { + AH_Edge edges; + AH_Edge edge_limit; + AH_Outline outline = hinter->glyph; + FT_Int dimension; + + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Edge edge; + AH_Edge anchor = 0; + int has_serifs = 0; + + + if ( !hinter->do_horz_hints && !dimension ) + goto Next_Dimension; + + if ( !hinter->do_vert_hints && dimension ) + goto Next_Dimension; + + /* we begin by aligning all stems relative to the blue zone */ + /* if needed -- that's only for horizontal edges */ + if ( dimension ) + { + for ( edge = edges; edge < edge_limit; edge++ ) + { + FT_Pos* blue; + AH_EdgeRec *edge1, *edge2; + + + if ( edge->flags & AH_EDGE_DONE ) + continue; + + blue = edge->blue_edge; + edge1 = 0; + edge2 = edge->link; + + if ( blue ) + { + edge1 = edge; + } + else if (edge2 && edge2->blue_edge) + { + blue = edge2->blue_edge; + edge1 = edge2; + edge2 = edge; + } + + if ( !edge1 ) + continue; + + edge1->pos = blue[0]; + edge1->flags |= AH_EDGE_DONE; + + if ( edge2 && !edge2->blue_edge ) + { + ah_align_linked_edge( hinter, edge1, edge2, dimension ); + edge2->flags |= AH_EDGE_DONE; + } + + if ( !anchor ) + anchor = edge; + } + } + + /* now, we will align all stem edges, trying to maintain the */ + /* relative order of stems in the glyph.. */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AH_EdgeRec* edge2; + + + if ( edge->flags & AH_EDGE_DONE ) + continue; + + /* skip all non-stem edges */ + edge2 = edge->link; + if ( !edge2 ) + { + has_serifs++; + continue; + } + + /* now, align the stem */ + + /* this should not happen, but it's better to be safe. */ + if ( edge2->blue_edge || edge2 < edge ) + { + + ah_align_linked_edge( hinter, edge2, edge, dimension ); + edge->flags |= AH_EDGE_DONE; + continue; + } + + if ( !anchor ) + { +#ifdef FT_CONFIG_CHESTER_STEM + FT_Pos org_len, org_center, cur_len; + FT_Pos cur_pos1, error1, error2, u_off, d_off; + + org_len = edge2->opos - edge->opos; + cur_len = ah_compute_stem_width( hinter, dimension, org_len, + edge->flags, edge2->flags ); + + if (cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + if ( cur_len < 96 ) + { + org_center = edge->opos + ( org_len >> 1 ); + + cur_pos1 = ( org_center + 32 ) & -64; + + error1 = org_center - ( cur_pos1 - u_off ); + if ( error1 < 0 ) + error1 = -error1; + + error2 = org_center - ( cur_pos1 + d_off ); + if ( error2 < 0 ) + error2 = -error2; + + if ( error1 < error2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + + } + else + edge->pos = ( edge->opos + 32 ) & -64; + + anchor = edge; + + edge->flags |= AH_EDGE_DONE; + + ah_align_linked_edge( hinter, edge, edge2, dimension ); +#else /* !CHESTER_STEM */ + edge->pos = ( edge->opos + 32 ) & -64; + anchor = edge; + + edge->flags |= AH_EDGE_DONE; + + ah_align_linked_edge( hinter, edge, edge2, dimension ); +#endif /* !CHESTER_STEM */ + } + else + { + FT_Pos org_pos, org_len, org_center, cur_len; + FT_Pos cur_pos1, cur_pos2, delta1, delta2; + + + org_pos = anchor->pos + (edge->opos - anchor->opos); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + +#ifdef FT_CONFIG_CHESTER_SERIF + cur_len = ah_compute_stem_width( hinter, dimension, org_len, + edge->flags, edge2->flags ); +#else /* !CHESTER_SERIF */ + cur_len = ah_compute_stem_width( hinter, dimension, org_len ); +#endif /* !CHESTER_SERIF */ + +#ifdef FT_CONFIG_CHESTER_STEM + if ( cur_len < 96 ) + { + FT_Pos u_off, d_off; + + + cur_pos1 = ( org_center + 32 ) & -64; + + if (cur_len <= 64 ) + u_off = d_off = 32; + else + { + u_off = 38; + d_off = 26; + } + + delta1 = org_center - (cur_pos1 - u_off); + if ( delta1 < 0 ) + delta1 = -delta1; + + delta2 = org_center - (cur_pos1 + d_off); + if ( delta2 < 0 ) + delta2 = -delta2; + + if ( delta1 < delta2 ) + cur_pos1 -= u_off; + else + cur_pos1 += d_off; + + edge->pos = cur_pos1 - cur_len / 2; + edge2->pos = cur_pos1 + cur_len / 2; + } + else + { + + org_pos = anchor->pos + (edge->opos - anchor->opos); + org_len = edge2->opos - edge->opos; + org_center = org_pos + ( org_len >> 1 ); + + cur_len = ah_compute_stem_width( hinter, dimension, org_len, + edge->flags, edge2->flags ); + + cur_pos1 = ( org_pos + 32 ) & -64; + delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + } + +#else /* !CHESTER_STEM */ + + cur_pos1 = ( org_pos + 32 ) & -64; + delta1 = ( cur_pos1 + ( cur_len >> 1 ) - org_center ); + if ( delta1 < 0 ) + delta1 = -delta1; + + cur_pos2 = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len; + delta2 = ( cur_pos2 + ( cur_len >> 1 ) - org_center ); + if ( delta2 < 0 ) + delta2 = -delta2; + + edge->pos = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2; + edge2->pos = edge->pos + cur_len; + +#endif /* !CHESTER_STEM */ + + edge->flags |= AH_EDGE_DONE; + edge2->flags |= AH_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + } + } + + if ( !has_serifs ) + goto Next_Dimension; + + /* now, hint the remaining edges (serifs and single) in order */ + /* to complete our processing */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( edge->flags & AH_EDGE_DONE ) + continue; + + if ( edge->serif ) + ah_align_serif_edge( hinter, edge->serif, edge, dimension ); + else if ( !anchor ) + { + edge->pos = ( edge->opos + 32 ) & -64; + anchor = edge; + } + else + edge->pos = anchor->pos + + ( ( edge->opos-anchor->opos + 32 ) & -64 ); + + edge->flags |= AH_EDGE_DONE; + + if ( edge > edges && edge->pos < edge[-1].pos ) + edge->pos = edge[-1].pos; + + if ( edge + 1 < edge_limit && + edge[1].flags & AH_EDGE_DONE && + edge->pos > edge[1].pos ) + edge->pos = edge[1].pos; + } + + Next_Dimension: + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + } + } + + + FT_LOCAL_DEF( void ) + ah_hinter_hint_edges( AH_Hinter hinter ) + { + /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */ + /* reduce the problem of the disappearing eye in the `e' of Times... */ + /* also, creates some artifacts near the blue zones? */ + { + ah_hint_edges_3( hinter ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** P O I N T H I N T I N G ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + static void + ah_hinter_align_edge_points( AH_Hinter hinter ) + { + AH_Outline outline = hinter->glyph; + AH_Edge edges; + AH_Edge edge_limit; + FT_Int dimension; + + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Edge edge; + + + edge = edges; + for ( ; edge < edge_limit; edge++ ) + { + /* move the points of each segment */ + /* in each edge to the edge's position */ + AH_Segment seg = edge->first; + + + do + { + AH_Point point = seg->first; + + + for (;;) + { + if ( dimension ) + { + point->y = edge->pos; + point->flags |= AH_FLAG_TOUCH_Y; + } + else + { + point->x = edge->pos; + point->flags |= AH_FLAG_TOUCH_X; + } + + if ( point == seg->last ) + break; + + point = point->next; + } + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + } + } + + + /* hint the strong points -- this is equivalent to the TrueType `IP' */ + static void + ah_hinter_align_strong_points( AH_Hinter hinter ) + { + AH_Outline outline = hinter->glyph; + FT_Int dimension; + AH_Edge edges; + AH_Edge edge_limit; + AH_Point points; + AH_Point point_limit; + AH_Flags touch_flag; + + + points = outline->points; + point_limit = points + outline->num_points; + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + touch_flag = AH_FLAG_TOUCH_Y; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Point point; + AH_Edge edge; + + + if ( edges < edge_limit ) + for ( point = points; point < point_limit; point++ ) + { + FT_Pos u, ou, fu; /* point position */ + FT_Pos delta; + + + if ( point->flags & touch_flag ) + continue; + +#ifndef AH_OPTION_NO_WEAK_INTERPOLATION + /* if this point is candidate to weak interpolation, we will */ + /* interpolate it after all strong points have been processed */ + if ( ( point->flags & AH_FLAG_WEAK_INTERPOLATION ) && + !( point->flags & AH_FLAG_INFLECTION ) ) + continue; +#endif + + if ( dimension ) + { + u = point->fy; + ou = point->oy; + } + else + { + u = point->fx; + ou = point->ox; + } + + fu = u; + + /* is the point before the first edge? */ + edge = edges; + delta = edge->fpos - u; + if ( delta >= 0 ) + { + u = edge->pos - ( edge->opos - ou ); + goto Store_Point; + } + + /* is the point after the last edge ? */ + edge = edge_limit - 1; + delta = u - edge->fpos; + if ( delta >= 0 ) + { + u = edge->pos + ( ou - edge->opos ); + goto Store_Point; + } + + /* otherwise, interpolate the point in between */ + { + AH_Edge before = 0; + AH_Edge after = 0; + + + for ( edge = edges; edge < edge_limit; edge++ ) + { + if ( u == edge->fpos ) + { + u = edge->pos; + goto Store_Point; + } + if ( u < edge->fpos ) + break; + before = edge; + } + + for ( edge = edge_limit - 1; edge >= edges; edge-- ) + { + if ( u == edge->fpos ) + { + u = edge->pos; + goto Store_Point; + } + if ( u > edge->fpos ) + break; + after = edge; + } + + /* assert( before && after && before != after ) */ + u = before->pos + FT_MulDiv( fu - before->fpos, + after->pos - before->pos, + after->fpos - before->fpos ); + } + + Store_Point: + + /* save the point position */ + if ( dimension ) + point->y = u; + else + point->x = u; + + point->flags |= touch_flag; + } + + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + touch_flag = AH_FLAG_TOUCH_X; + } + } + + +#ifndef AH_OPTION_NO_WEAK_INTERPOLATION + + static void + ah_iup_shift( AH_Point p1, + AH_Point p2, + AH_Point ref ) + { + AH_Point p; + FT_Pos delta = ref->u - ref->v; + + + for ( p = p1; p < ref; p++ ) + p->u = p->v + delta; + + for ( p = ref + 1; p <= p2; p++ ) + p->u = p->v + delta; + } + + + static void + ah_iup_interp( AH_Point p1, + AH_Point p2, + AH_Point ref1, + AH_Point ref2 ) + { + AH_Point p; + FT_Pos u; + FT_Pos v1 = ref1->v; + FT_Pos v2 = ref2->v; + FT_Pos d1 = ref1->u - v1; + FT_Pos d2 = ref2->u - v2; + + + if ( p1 > p2 ) + return; + + if ( v1 == v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else + u += d2; + + p->u = u; + } + return; + } + + if ( v1 < v2 ) + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v1 ) + u += d1; + else if ( u >= v2 ) + u += d2; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + else + { + for ( p = p1; p <= p2; p++ ) + { + u = p->v; + + if ( u <= v2 ) + u += d2; + else if ( u >= v1 ) + u += d1; + else + u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); + + p->u = u; + } + } + } + + + /* interpolate weak points -- this is equivalent to the TrueType `IUP' */ + static void + ah_hinter_align_weak_points( AH_Hinter hinter ) + { + AH_Outline outline = hinter->glyph; + FT_Int dimension; + AH_Point points; + AH_Point point_limit; + AH_Point* contour_limit; + AH_Flags touch_flag; + + + points = outline->points; + point_limit = points + outline->num_points; + + /* PASS 1: Move segment points to edge positions */ + + touch_flag = AH_FLAG_TOUCH_Y; + + contour_limit = outline->contours + outline->num_contours; + + ah_setup_uv( outline, AH_UV_OY ); + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Point point; + AH_Point end_point; + AH_Point first_point; + AH_Point* contour; + + + point = points; + contour = outline->contours; + + for ( ; contour < contour_limit; contour++ ) + { + point = *contour; + end_point = point->prev; + first_point = point; + + while ( point <= end_point && !( point->flags & touch_flag ) ) + point++; + + if ( point <= end_point ) + { + AH_Point first_touched = point; + AH_Point cur_touched = point; + + + point++; + while ( point <= end_point ) + { + if ( point->flags & touch_flag ) + { + /* we found two successive touched points; we interpolate */ + /* all contour points between them */ + ah_iup_interp( cur_touched + 1, point - 1, + cur_touched, point ); + cur_touched = point; + } + point++; + } + + if ( cur_touched == first_touched ) + { + /* this is a special case: only one point was touched in the */ + /* contour; we thus simply shift the whole contour */ + ah_iup_shift( first_point, end_point, cur_touched ); + } + else + { + /* now interpolate after the last touched point to the end */ + /* of the contour */ + ah_iup_interp( cur_touched + 1, end_point, + cur_touched, first_touched ); + + /* if the first contour point isn't touched, interpolate */ + /* from the contour start to the first touched point */ + if ( first_touched > points ) + ah_iup_interp( first_point, first_touched - 1, + cur_touched, first_touched ); + } + } + } + + /* now save the interpolated values back to x/y */ + if ( dimension ) + { + for ( point = points; point < point_limit; point++ ) + point->y = point->u; + + touch_flag = AH_FLAG_TOUCH_X; + ah_setup_uv( outline, AH_UV_OX ); + } + else + { + for ( point = points; point < point_limit; point++ ) + point->x = point->u; + + break; /* exit loop */ + } + } + } + +#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */ + + + FT_LOCAL_DEF( void ) + ah_hinter_align_points( AH_Hinter hinter ) + { + ah_hinter_align_edge_points( hinter ); + +#ifndef AH_OPTION_NO_STRONG_INTERPOLATION + ah_hinter_align_strong_points( hinter ); +#endif + +#ifndef AH_OPTION_NO_WEAK_INTERPOLATION + ah_hinter_align_weak_points( hinter ); +#endif + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** H I N T E R O B J E C T M E T H O D S ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* scale and fit the global metrics */ + static void + ah_hinter_scale_globals( AH_Hinter hinter, + FT_Fixed x_scale, + FT_Fixed y_scale ) + { + FT_Int n; + AH_Face_Globals globals = hinter->globals; + AH_Globals design = &globals->design; + AH_Globals scaled = &globals->scaled; + + + /* copy content */ + *scaled = *design; + + /* scale the standard widths & heights */ + for ( n = 0; n < design->num_widths; n++ ) + scaled->widths[n] = FT_MulFix( design->widths[n], x_scale ); + + for ( n = 0; n < design->num_heights; n++ ) + scaled->heights[n] = FT_MulFix( design->heights[n], y_scale ); + + scaled->stds[0] = ( design->num_widths > 0 ) ? scaled->widths[0] : 32000; + scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000; + + /* scale the blue zones */ + for ( n = 0; n < AH_BLUE_MAX; n++ ) + { + FT_Pos delta, delta2; + + + delta = design->blue_shoots[n] - design->blue_refs[n]; + delta2 = delta; + if ( delta < 0 ) + delta2 = -delta2; + delta2 = FT_MulFix( delta2, y_scale ); + + if ( delta2 < 32 ) + delta2 = 0; + else if ( delta2 < 64 ) + delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 ); + else + delta2 = ( delta2 + 32 ) & -64; + + if ( delta < 0 ) + delta2 = -delta2; + + scaled->blue_refs[n] = + ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64; + scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2; + } + + globals->x_scale = x_scale; + globals->y_scale = y_scale; + } + + + static void + ah_hinter_align( AH_Hinter hinter ) + { + ah_hinter_align_edge_points( hinter ); + ah_hinter_align_points( hinter ); + } + + + /* finalize a hinter object */ + FT_LOCAL_DEF( void ) + ah_hinter_done( AH_Hinter hinter ) + { + if ( hinter ) + { + FT_Memory memory = hinter->memory; + + + ah_loader_done( hinter->loader ); + ah_outline_done( hinter->glyph ); + + /* note: the `globals' pointer is _not_ owned by the hinter */ + /* but by the current face object, we don't need to */ + /* release it */ + hinter->globals = 0; + hinter->face = 0; + + FT_FREE( hinter ); + } + } + + + /* create a new empty hinter object */ + FT_LOCAL_DEF( FT_Error ) + ah_hinter_new( FT_Library library, + AH_Hinter *ahinter ) + { + AH_Hinter hinter = 0; + FT_Memory memory = library->memory; + FT_Error error; + + + *ahinter = 0; + + /* allocate object */ + if ( FT_NEW( hinter ) ) + goto Exit; + + hinter->memory = memory; + hinter->flags = 0; + + /* allocate outline and loader */ + error = ah_outline_new( memory, &hinter->glyph ) || + ah_loader_new ( memory, &hinter->loader ) || + ah_loader_create_extra( hinter->loader ); + if ( error ) + goto Exit; + + *ahinter = hinter; + + Exit: + if ( error ) + ah_hinter_done( hinter ); + + return error; + } + + + /* create a face's autohint globals */ + FT_LOCAL_DEF( FT_Error ) + ah_hinter_new_face_globals( AH_Hinter hinter, + FT_Face face, + AH_Globals globals ) + { + FT_Error error; + FT_Memory memory = hinter->memory; + AH_Face_Globals face_globals; + + + if ( FT_NEW( face_globals ) ) + goto Exit; + + hinter->face = face; + hinter->globals = face_globals; + + if ( globals ) + face_globals->design = *globals; + else + ah_hinter_compute_globals( hinter ); + + face->autohint.data = face_globals; + face->autohint.finalizer = (FT_Generic_Finalizer) + ah_hinter_done_face_globals; + face_globals->face = face; + + Exit: + return error; + } + + + /* discard a face's autohint globals */ + FT_LOCAL_DEF( void ) + ah_hinter_done_face_globals( AH_Face_Globals globals ) + { + FT_Face face = globals->face; + FT_Memory memory = face->memory; + + + FT_FREE( globals ); + } + + + static FT_Error + ah_hinter_load( AH_Hinter hinter, + FT_UInt glyph_index, + FT_Int32 load_flags, + FT_UInt depth ) + { + FT_Face face = hinter->face; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal internal = slot->internal; + FT_Fixed x_scale = hinter->globals->x_scale; + FT_Fixed y_scale = hinter->globals->y_scale; + FT_Error error; + AH_Outline outline = hinter->glyph; + AH_Loader gloader = hinter->loader; + + + /* load the glyph */ + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */ + hinter->transformed = internal->glyph_transformed; + + if ( hinter->transformed ) + { + FT_Matrix imatrix; + + + imatrix = internal->glyph_matrix; + hinter->trans_delta = internal->glyph_delta; + hinter->trans_matrix = imatrix; + + FT_Matrix_Invert( &imatrix ); + FT_Vector_Transform( &hinter->trans_delta, &imatrix ); + } + + /* set linear horizontal metrics */ + slot->linearHoriAdvance = slot->metrics.horiAdvance; + slot->linearVertAdvance = slot->metrics.vertAdvance; + + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_OUTLINE: + + /* translate glyph outline if we need to */ + if ( hinter->transformed ) + { + FT_UInt n = slot->outline.n_points; + FT_Vector* point = slot->outline.points; + + + for ( ; n > 0; point++, n-- ) + { + point->x += hinter->trans_delta.x; + point->y += hinter->trans_delta.y; + } + } + + /* copy the outline points in the loader's current */ + /* extra points, which is used to keep original glyph coordinates */ + error = ah_loader_check_points( gloader, slot->outline.n_points + 2, + slot->outline.n_contours ); + if ( error ) + goto Exit; + + FT_MEM_COPY( gloader->current.extra_points, slot->outline.points, + slot->outline.n_points * sizeof ( FT_Vector ) ); + + FT_MEM_COPY( gloader->current.outline.contours, slot->outline.contours, + slot->outline.n_contours * sizeof ( short ) ); + + FT_MEM_COPY( gloader->current.outline.tags, slot->outline.tags, + slot->outline.n_points * sizeof ( char ) ); + + gloader->current.outline.n_points = slot->outline.n_points; + gloader->current.outline.n_contours = slot->outline.n_contours; + + /* compute original phantom points */ + hinter->pp1.x = 0; + hinter->pp1.y = 0; + hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale ); + hinter->pp2.y = 0; + + /* be sure to check for spacing glyphs */ + if ( slot->outline.n_points == 0 ) + goto Hint_Metrics; + + /* now, load the slot image into the auto-outline, and run the */ + /* automatic hinting process */ + error = ah_outline_load( outline, x_scale, y_scale, face ); + if ( error ) + goto Exit; + + /* perform feature detection */ + ah_outline_detect_features( outline ); + + if ( hinter->do_vert_hints ) + { + ah_outline_compute_blue_edges( outline, hinter->globals ); + ah_outline_scale_blue_edges( outline, hinter->globals ); + } + + /* perform alignment control */ + ah_hinter_hint_edges( hinter ); + ah_hinter_align( hinter ); + + /* now save the current outline into the loader's current table */ + ah_outline_save( outline, gloader ); + + /* we now need to hint the metrics according to the change in */ + /* width/positioning that occured during the hinting process */ + { + FT_Pos old_advance, old_rsb, old_lsb, new_lsb; + AH_Edge edge1 = outline->vert_edges; /* leftmost edge */ + AH_Edge edge2 = edge1 + + outline->num_vedges - 1; /* rightmost edge */ + + + old_advance = hinter->pp2.x; + old_rsb = old_advance - edge2->opos; + old_lsb = edge1->opos; + new_lsb = edge1->pos; + + hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; + hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64; + +#if 0 + /* try to fix certain bad advance computations */ + if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 ) + hinter->pp2.x += 64; +#endif + } + + /* good, we simply add the glyph to our loader's base */ + ah_loader_add( gloader ); + break; + + case FT_GLYPH_FORMAT_COMPOSITE: + { + FT_UInt nn, num_subglyphs = slot->num_subglyphs; + FT_UInt num_base_subgs, start_point; + FT_SubGlyph subglyph; + + + start_point = gloader->base.outline.n_points; + + /* first of all, copy the subglyph descriptors in the glyph loader */ + error = ah_loader_check_subglyphs( gloader, num_subglyphs ); + if ( error ) + goto Exit; + + FT_MEM_COPY( gloader->current.subglyphs, slot->subglyphs, + num_subglyphs * sizeof ( FT_SubGlyph ) ); + + gloader->current.num_subglyphs = num_subglyphs; + num_base_subgs = gloader->base.num_subglyphs; + + /* now, read each subglyph independently */ + for ( nn = 0; nn < num_subglyphs; nn++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + FT_UInt num_points, num_new_points, num_base_points; + + + /* gloader.current.subglyphs can change during glyph loading due */ + /* to re-allocation -- we must recompute the current subglyph on */ + /* each iteration */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + pp1 = hinter->pp1; + pp2 = hinter->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = ah_hinter_load( hinter, subglyph->index, + load_flags, depth + 1 ); + if ( error ) + goto Exit; + + /* recompute subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + nn; + + if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) + { + pp1 = hinter->pp1; + pp2 = hinter->pp2; + } + else + { + hinter->pp1 = pp1; + hinter->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + num_new_points = num_points - num_base_points; + + /* now perform the transform required for this subglyph */ + + if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | + FT_SUBGLYPH_FLAG_XY_SCALE | + FT_SUBGLYPH_FLAG_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* org = gloader->base.extra_points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++, org++ ) + { + FT_Vector_Transform( cur, &subglyph->transform ); + FT_Vector_Transform( org, &subglyph->transform ); + } + } + + /* apply offset */ + + if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) + { + FT_Int k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = AH_Err_Invalid_Composite; + goto Exit; + } + + l += num_base_points; + + /* for now, only use the current point coordinates */ + /* we may consider another approach in the near future */ + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = FT_MulFix( subglyph->arg1, x_scale ); + y = FT_MulFix( subglyph->arg2, y_scale ); + + x = ( x + 32 ) & -64; + y = ( y + 32 ) & -64; + } + + { + FT_Outline dummy = gloader->base.outline; + + + dummy.points += num_base_points; + dummy.n_points = (short)num_new_points; + + FT_Outline_Translate( &dummy, x, y ); + } + } + } + break; + + default: + /* we don't support other formats (yet?) */ + error = AH_Err_Unimplemented_Feature; + } + + Hint_Metrics: + if ( depth == 0 ) + { + FT_BBox bbox; + + + /* transform the hinted outline if needed */ + if ( hinter->transformed ) + FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix ); + + /* we must translate our final outline by -pp1.x, and compute */ + /* the new metrics */ + if ( hinter->pp1.x ) + FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 ); + + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); + bbox.xMin &= -64; + bbox.yMin &= -64; + bbox.xMax = ( bbox.xMax + 63 ) & -64; + bbox.yMax = ( bbox.yMax + 63 ) & -64; + + slot->metrics.width = bbox.xMax - bbox.xMin; + slot->metrics.height = bbox.yMax - bbox.yMin; + slot->metrics.horiBearingX = bbox.xMin; + slot->metrics.horiBearingY = bbox.yMax; + + /* for mono-width fonts (like Andale, Courier, etc.), we need */ + /* to keep the original rounded advance width */ + if ( !FT_IS_FIXED_WIDTH( slot->face ) ) + slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x; + else + slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, + x_scale ); + + slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64; + + /* now copy outline into glyph slot */ + ah_loader_rewind( slot->internal->loader ); + error = ah_loader_copy_points( slot->internal->loader, gloader ); + if ( error ) + goto Exit; + + slot->outline = slot->internal->loader->base.outline; + slot->format = FT_GLYPH_FORMAT_OUTLINE; + } + +#ifdef DEBUG_HINTER + ah_debug_hinter = hinter; +#endif + + Exit: + return error; + } + + + /* load and hint a given glyph */ + FT_LOCAL_DEF( FT_Error ) + ah_hinter_load_glyph( AH_Hinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Face face = slot->face; + FT_Error error; + FT_Fixed x_scale = size->metrics.x_scale; + FT_Fixed y_scale = size->metrics.y_scale; + AH_Face_Globals face_globals = FACE_GLOBALS( face ); + FT_Render_Mode hint_mode = FT_LOAD_TARGET_MODE(load_flags); + + + /* first of all, we need to check that we're using the correct face and */ + /* global hints to load the glyph */ + if ( hinter->face != face || hinter->globals != face_globals ) + { + hinter->face = face; + if ( !face_globals ) + { + error = ah_hinter_new_face_globals( hinter, face, 0 ); + if ( error ) + goto Exit; + + } + hinter->globals = FACE_GLOBALS( face ); + face_globals = FACE_GLOBALS( face ); + + } + +#ifdef FT_CONFIG_CHESTER_BLUE_SCALE + /* try to optimize the y_scale so that the top of non-capital letters + * is aligned on a pixel boundary whenever possible + */ + { + AH_Globals design = &face_globals->design; + FT_Pos shoot = design->blue_shoots[ AH_BLUE_SMALL_TOP ]; + + /* the value of 'shoot' will be -1000 if the font doesn't have */ + /* small latin letters; we simply check the sign here... */ + if ( shoot > 0 ) + { + FT_Pos scaled = FT_MulFix( shoot, y_scale ); + FT_Pos fitted = ( scaled + 32 ) & -64; + + if ( scaled != fitted ) + { + /* adjust y_scale + */ + y_scale = FT_MulDiv( y_scale, fitted, scaled ); + + /* adust x_scale + */ + if ( fitted < scaled ) + x_scale -= x_scale/50; /* x_scale*0.98 with integers */ + } + } + } +#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */ + + /* now, we must check the current character pixel size to see if we */ + /* need to rescale the global metrics */ + if ( face_globals->x_scale != x_scale || + face_globals->y_scale != y_scale ) + ah_hinter_scale_globals( hinter, x_scale, y_scale ); + + ah_loader_rewind( hinter->loader ); + + /* reset hinting flags according to load flags and current render target */ + hinter->do_horz_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) ); + hinter->do_vert_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) ); + +#ifdef DEBUG_HINTER + hinter->do_horz_hints = !ah_debug_disable_vert; /* not a bug, the meaning */ + hinter->do_vert_hints = !ah_debug_disable_horz; /* of h/v is inverted! */ +#endif + + /* we snap the width of vertical stems for the monochrome and */ + /* horizontal LCD rendering targets only. Corresponds to X snapping. */ + hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); + + /* we snap the width of horizontal stems for the monochrome and */ + /* vertical LCD rendering targets only. Corresponds to Y snapping. */ + hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); + + hinter->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + +#if 1 + load_flags = FT_LOAD_NO_SCALE + | FT_LOAD_IGNORE_TRANSFORM ; +#else + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE; +#endif + + error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); + + Exit: + return error; + } + + + /* retrieve a face's autohint globals for client applications */ + FT_LOCAL_DEF( void ) + ah_hinter_get_global_hints( AH_Hinter hinter, + FT_Face face, + void** global_hints, + long* global_len ) + { + AH_Globals globals = 0; + FT_Memory memory = hinter->memory; + FT_Error error; + + + /* allocate new master globals */ + if ( FT_NEW( globals ) ) + goto Fail; + + /* compute face globals if needed */ + if ( !FACE_GLOBALS( face ) ) + { + error = ah_hinter_new_face_globals( hinter, face, 0 ); + if ( error ) + goto Fail; + } + + *globals = FACE_GLOBALS( face )->design; + *global_hints = globals; + *global_len = sizeof( *globals ); + + return; + + Fail: + FT_FREE( globals ); + + *global_hints = 0; + *global_len = 0; + } + + + FT_LOCAL_DEF( void ) + ah_hinter_done_global_hints( AH_Hinter hinter, + void* global_hints ) + { + FT_Memory memory = hinter->memory; + + + FT_FREE( global_hints ); + } + + +/* END */ diff --git a/lib/freetype/src/autohint/ahhint.h b/lib/freetype/src/autohint/ahhint.h new file mode 100644 index 0000000..2c352d0 --- /dev/null +++ b/lib/freetype/src/autohint/ahhint.h @@ -0,0 +1,75 @@ +/***************************************************************************/ +/* */ +/* ahhint.h */ +/* */ +/* Glyph hinter (declaration). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHHINT_H__ +#define __AHHINT_H__ + + +#include <ft2build.h> +#include "ahglobal.h" + + +FT_BEGIN_HEADER + + +#define AH_HINT_DEFAULT 0 +#define AH_HINT_NO_ALIGNMENT 1 +#define AH_HINT_NO_HORZ_EDGES 0x200000L /* temporary hack */ +#define AH_HINT_NO_VERT_EDGES 0x400000L /* temporary hack */ + + + /* create a new empty hinter object */ + FT_LOCAL( FT_Error ) + ah_hinter_new( FT_Library library, + AH_Hinter* ahinter ); + + /* Load a hinted glyph in the hinter */ + FT_LOCAL( FT_Error ) + ah_hinter_load_glyph( AH_Hinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + /* finalize a hinter object */ + FT_LOCAL( void ) + ah_hinter_done( AH_Hinter hinter ); + + FT_LOCAL( void ) + ah_hinter_done_face_globals( AH_Face_Globals globals ); + + FT_LOCAL( void ) + ah_hinter_get_global_hints( AH_Hinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + FT_LOCAL( void ) + ah_hinter_done_global_hints( AH_Hinter hinter, + void* global_hints ); + + +FT_END_HEADER + +#endif /* __AHHINT_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahloader.h b/lib/freetype/src/autohint/ahloader.h new file mode 100644 index 0000000..c8e42ef --- /dev/null +++ b/lib/freetype/src/autohint/ahloader.h @@ -0,0 +1,61 @@ +/***************************************************************************/ +/* */ +/* ahloader.h */ +/* */ +/* Glyph loader for the auto-hinting module (declaration only). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This defines the AH_GlyphLoader type; it is simply a typedef to */ + /* FT_GlyphLoader. */ + /* */ + /*************************************************************************/ + + +#ifndef __AHLOADER_H__ +#define __AHLOADER_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + +#include FT_INTERNAL_GLYPH_LOADER_H + + #define AH_Load FT_GlyphLoad + #define AH_Loader FT_GlyphLoader + + #define ah_loader_new FT_GlyphLoader_New + #define ah_loader_done FT_GlyphLoader_Done + #define ah_loader_reset FT_GlyphLoader_Reset + #define ah_loader_rewind FT_GlyphLoader_Rewind + #define ah_loader_create_extra FT_GlyphLoader_CreateExtra + #define ah_loader_check_points FT_GlyphLoader_CheckPoints + #define ah_loader_check_subglyphs FT_GlyphLoader_CheckSubGlyphs + #define ah_loader_prepare FT_GlyphLoader_Prepare + #define ah_loader_add FT_GlyphLoader_Add + #define ah_loader_copy_points FT_GlyphLoader_CopyPoints + + +FT_END_HEADER + +#endif /* __AHLOADER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahmodule.c b/lib/freetype/src/autohint/ahmodule.c new file mode 100644 index 0000000..1819e9e --- /dev/null +++ b/lib/freetype/src/autohint/ahmodule.c @@ -0,0 +1,137 @@ +/***************************************************************************/ +/* */ +/* ahmodule.c */ +/* */ +/* Auto-hinting module implementation (declaration). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_MODULE_H +#include "ahhint.h" + + +#ifdef DEBUG_HINTER + AH_Hinter ah_debug_hinter = NULL; + FT_Bool ah_debug_disable_horz = 0; + FT_Bool ah_debug_disable_vert = 0; +#endif + + typedef struct FT_AutoHinterRec_ + { + FT_ModuleRec root; + AH_Hinter hinter; + + } FT_AutoHinterRec; + + + FT_CALLBACK_DEF( FT_Error ) + ft_autohinter_init( FT_AutoHinter module ) + { + FT_Error error; + + + error = ah_hinter_new( module->root.library, &module->hinter ); +#ifdef DEBUG_HINTER + if ( !error ) + ah_debug_hinter = module->hinter; +#endif + return error; + } + + + FT_CALLBACK_DEF( void ) + ft_autohinter_done( FT_AutoHinter module ) + { + ah_hinter_done( module->hinter ); + +#ifdef DEBUG_HINTER + ah_debug_hinter = NULL; +#endif + } + + + FT_CALLBACK_DEF( FT_Error ) + ft_autohinter_load_glyph( FT_AutoHinter module, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + return ah_hinter_load_glyph( module->hinter, + slot, size, glyph_index, load_flags ); + } + + + FT_CALLBACK_DEF( void ) + ft_autohinter_reset_globals( FT_AutoHinter module, + FT_Face face ) + { + FT_UNUSED( module ); + + if ( face->autohint.data ) + ah_hinter_done_face_globals( (AH_Face_Globals)(face->autohint.data) ); + } + + + FT_CALLBACK_DEF( void ) + ft_autohinter_get_globals( FT_AutoHinter module, + FT_Face face, + void** global_hints, + long* global_len ) + { + ah_hinter_get_global_hints( module->hinter, face, + global_hints, global_len ); + } + + + FT_CALLBACK_DEF( void ) + ft_autohinter_done_globals( FT_AutoHinter module, + void* global_hints ) + { + ah_hinter_done_global_hints( module->hinter, global_hints ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_AutoHinter_ServiceRec ft_autohinter_service = + { + ft_autohinter_reset_globals, + ft_autohinter_get_globals, + ft_autohinter_done_globals, + ft_autohinter_load_glyph + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class autohint_module_class = + { + ft_module_hinter, + sizeof ( FT_AutoHinterRec ), + + "autohinter", + 0x10000L, /* version 1.0 of the autohinter */ + 0x20000L, /* requires FreeType 2.0 or above */ + + (const void*) &ft_autohinter_service, + + (FT_Module_Constructor)ft_autohinter_init, + (FT_Module_Destructor) ft_autohinter_done, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/autohint/ahmodule.h b/lib/freetype/src/autohint/ahmodule.h new file mode 100644 index 0000000..43b1dbe --- /dev/null +++ b/lib/freetype/src/autohint/ahmodule.h @@ -0,0 +1,42 @@ +/***************************************************************************/ +/* */ +/* ahmodule.h */ +/* */ +/* Auto-hinting module (declaration). */ +/* */ +/* Copyright 2000-2001 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHMODULE_H__ +#define __AHMODULE_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const FT_Module_Class autohint_module_class; + + +FT_END_HEADER + +#endif /* __AHMODULE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahoptim.c b/lib/freetype/src/autohint/ahoptim.c new file mode 100644 index 0000000..8d10f4a --- /dev/null +++ b/lib/freetype/src/autohint/ahoptim.c @@ -0,0 +1,882 @@ +/***************************************************************************/ +/* */ +/* ahoptim.c */ +/* */ +/* FreeType auto hinting outline optimization (body). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This module is in charge of optimising the outlines produced by the */ + /* auto-hinter in direct mode. This is required at small pixel sizes in */ + /* order to ensure coherent spacing, among other things.. */ + /* */ + /* The technique used in this module is a simplified simulated */ + /* annealing. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H /* for FT_ALLOC_ARRAY() and FT_FREE() */ +#include "ahoptim.h" + + + /* define this macro to use brute force optimization -- this is slow, */ + /* but a good way to perfect the distortion function `by hand' through */ + /* tweaking */ +#define AH_BRUTE_FORCE + + +#define xxxAH_DEBUG_OPTIM + + +#undef LOG +#ifdef AH_DEBUG_OPTIM + +#define LOG( x ) optim_log ## x + +#else + +#define LOG( x ) + +#endif /* AH_DEBUG_OPTIM */ + + +#ifdef AH_DEBUG_OPTIM + +#include <stdarg.h> +#include <stdlib.h> + +#define FLOAT( x ) ( (float)( (x) / 64.0 ) ) + + + static void + optim_log( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + } + + + static void + AH_Dump_Stems( AH_Optimizer* optimizer ) + { + int n; + AH_Stem* stem; + + + stem = optimizer->stems; + for ( n = 0; n < optimizer->num_stems; n++, stem++ ) + { + LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}=" + "<%1.f..%1.f> force=%.1f speed=%.1f\n", + optimizer->vertical ? 'V' : 'H', n, + FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ), + FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ), + FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), + FLOAT( stem->force ), FLOAT( stem->velocity ) )); + } + } + + + static void + AH_Dump_Stems2( AH_Optimizer* optimizer ) + { + int n; + AH_Stem* stem; + + + stem = optimizer->stems; + for ( n = 0; n < optimizer->num_stems; n++, stem++ ) + { + LOG(( " %c%2d [%.1f]=<%1.f..%1.f> force=%.1f speed=%.1f\n", + optimizer->vertical ? 'V' : 'H', n, + FLOAT( stem->pos ), + FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), + FLOAT( stem->force ), FLOAT( stem->velocity ) )); + } + } + + + static void + AH_Dump_Springs( AH_Optimizer* optimizer ) + { + int n; + AH_Spring* spring; + AH_Stem* stems; + + + spring = optimizer->springs; + stems = optimizer->stems; + LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' )); + + for ( n = 0; n < optimizer->num_springs; n++, spring++ ) + { + LOG(( " [%d-%d:%.1f:%1.f:%.1f]", + spring->stem1 - stems, spring->stem2 - stems, + FLOAT( spring->owidth ), + FLOAT( spring->stem2->pos - + ( spring->stem1->pos + spring->stem1->width ) ), + FLOAT( spring->tension ) )); + } + + LOG(( "\n" )); + } + +#endif /* AH_DEBUG_OPTIM */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + static int + valid_stem_segments( AH_Segment seg1, + AH_Segment seg2 ) + { + return seg1->serif == 0 && + seg2 && + seg2->link == seg1 && + seg1->pos < seg2->pos && + seg1->min_coord <= seg2->max_coord && + seg2->min_coord <= seg1->max_coord; + } + + + /* compute all stems in an outline */ + static int + optim_compute_stems( AH_Optimizer* optimizer ) + { + AH_Outline outline = optimizer->outline; + FT_Fixed scale; + FT_Memory memory = optimizer->memory; + FT_Error error = 0; + FT_Int dimension; + AH_Edge edges; + AH_Edge edge_limit; + AH_Stem** p_stems; + FT_Int* p_num_stems; + + + edges = outline->horz_edges; + edge_limit = edges + outline->num_hedges; + scale = outline->y_scale; + + p_stems = &optimizer->horz_stems; + p_num_stems = &optimizer->num_hstems; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + AH_Stem* stems = 0; + FT_Int num_stems = 0; + AH_Edge edge; + + + /* first of all, count the number of stems in this direction */ + for ( edge = edges; edge < edge_limit; edge++ ) + { + AH_Segment seg = edge->first; + + + do + { + if (valid_stem_segments( seg, seg->link ) ) + num_stems++; + + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + + /* now allocate the stems and build their table */ + if ( num_stems > 0 ) + { + AH_Stem* stem; + + + if ( FT_NEW_ARRAY( stems, num_stems ) ) + goto Exit; + + stem = stems; + for ( edge = edges; edge < edge_limit; edge++ ) + { + AH_Segment seg = edge->first; + AH_Segment seg2; + + + do + { + seg2 = seg->link; + if ( valid_stem_segments( seg, seg2 ) ) + { + AH_Edge edge1 = seg->edge; + AH_Edge edge2 = seg2->edge; + + + stem->edge1 = edge1; + stem->edge2 = edge2; + stem->opos = edge1->opos; + stem->pos = edge1->pos; + stem->owidth = edge2->opos - edge1->opos; + stem->width = edge2->pos - edge1->pos; + + /* compute min_coord and max_coord */ + { + FT_Pos min_coord = seg->min_coord; + FT_Pos max_coord = seg->max_coord; + + + if ( seg2->min_coord > min_coord ) + min_coord = seg2->min_coord; + + if ( seg2->max_coord < max_coord ) + max_coord = seg2->max_coord; + + stem->min_coord = min_coord; + stem->max_coord = max_coord; + } + + /* compute minimum and maximum positions for stem -- */ + /* note that the left-most/bottom-most stem has always */ + /* a fixed position */ + if ( stem == stems || edge1->blue_edge || edge2->blue_edge ) + { + /* this stem cannot move; it is snapped to a blue edge */ + stem->min_pos = stem->pos; + stem->max_pos = stem->pos; + } + else + { + /* this edge can move; compute its min and max positions */ + FT_Pos pos1 = stem->opos; + FT_Pos pos2 = pos1 + stem->owidth - stem->width; + FT_Pos min1 = pos1 & -64; + FT_Pos min2 = pos2 & -64; + + + stem->min_pos = min1; + stem->max_pos = min1 + 64; + if ( min2 < min1 ) + stem->min_pos = min2; + else + stem->max_pos = min2 + 64; + + /* XXX: just to see what it does */ + stem->max_pos += 64; + + /* just for the case where direct hinting did some */ + /* incredible things (e.g. blue edge shifts) */ + if ( stem->min_pos > stem->pos ) + stem->min_pos = stem->pos; + + if ( stem->max_pos < stem->pos ) + stem->max_pos = stem->pos; + } + + stem->velocity = 0; + stem->force = 0; + + stem++; + } + seg = seg->edge_next; + + } while ( seg != edge->first ); + } + } + + *p_stems = stems; + *p_num_stems = num_stems; + + edges = outline->vert_edges; + edge_limit = edges + outline->num_vedges; + scale = outline->x_scale; + + p_stems = &optimizer->vert_stems; + p_num_stems = &optimizer->num_vstems; + } + + Exit: + +#ifdef AH_DEBUG_OPTIM + AH_Dump_Stems( optimizer ); +#endif + + return error; + } + + + /* returns the spring area between two stems, 0 if none */ + static FT_Pos + stem_spring_area( AH_Stem* stem1, + AH_Stem* stem2 ) + { + FT_Pos area1 = stem1->max_coord - stem1->min_coord; + FT_Pos area2 = stem2->max_coord - stem2->min_coord; + FT_Pos min = stem1->min_coord; + FT_Pos max = stem1->max_coord; + FT_Pos area; + + + /* order stems */ + if ( stem2->opos <= stem1->opos + stem1->owidth ) + return 0; + + if ( min < stem2->min_coord ) + min = stem2->min_coord; + + if ( max < stem2->max_coord ) + max = stem2->max_coord; + + area = ( max-min ); + if ( 2 * area < area1 && 2 * area < area2 ) + area = 0; + + return area; + } + + + /* compute all springs in an outline */ + static int + optim_compute_springs( AH_Optimizer* optimizer ) + { + /* basically, a spring exists between two stems if most of their */ + /* surface is aligned */ + FT_Memory memory = optimizer->memory; + + AH_Stem* stems; + AH_Stem* stem_limit; + AH_Stem* stem; + int dimension; + int error = 0; + + FT_Int* p_num_springs; + AH_Spring** p_springs; + + + stems = optimizer->horz_stems; + stem_limit = stems + optimizer->num_hstems; + + p_springs = &optimizer->horz_springs; + p_num_springs = &optimizer->num_hsprings; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + FT_Int num_springs = 0; + AH_Spring* springs = 0; + + + /* first of all, count stem springs */ + for ( stem = stems; stem + 1 < stem_limit; stem++ ) + { + AH_Stem* stem2; + + + for ( stem2 = stem+1; stem2 < stem_limit; stem2++ ) + if ( stem_spring_area( stem, stem2 ) ) + num_springs++; + } + + /* then allocate and build the springs table */ + if ( num_springs > 0 ) + { + AH_Spring* spring; + + + /* allocate table of springs */ + if ( FT_NEW_ARRAY( springs, num_springs ) ) + goto Exit; + + /* fill the springs table */ + spring = springs; + for ( stem = stems; stem+1 < stem_limit; stem++ ) + { + AH_Stem* stem2; + FT_Pos area; + + + for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ ) + { + area = stem_spring_area( stem, stem2 ); + if ( area ) + { + /* add a new spring here */ + spring->stem1 = stem; + spring->stem2 = stem2; + spring->owidth = stem2->opos - ( stem->opos + stem->owidth ); + spring->tension = 0; + + spring++; + } + } + } + } + *p_num_springs = num_springs; + *p_springs = springs; + + stems = optimizer->vert_stems; + stem_limit = stems + optimizer->num_vstems; + + p_springs = &optimizer->vert_springs; + p_num_springs = &optimizer->num_vsprings; + } + + Exit: + +#ifdef AH_DEBUG_OPTIM + AH_Dump_Springs( optimizer ); +#endif + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** OPTIMIZE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#ifndef AH_BRUTE_FORCE + + /* compute all spring tensions */ + static void + optim_compute_tensions( AH_Optimizer* optimizer ) + { + AH_Spring* spring = optimizer->springs; + AH_Spring* limit = spring + optimizer->num_springs; + + + for ( ; spring < limit; spring++ ) + { + AH_Stem* stem1 = spring->stem1; + AH_Stem* stem2 = spring->stem2; + FT_Int status; + + FT_Pos width; + FT_Pos tension; + FT_Pos sign; + + + /* compute the tension; it simply is -K*(new_width-old_width) */ + width = stem2->pos - ( stem1->pos + stem1->width ); + tension = width - spring->owidth; + + sign = 1; + if ( tension < 0 ) + { + sign = -1; + tension = -tension; + } + + if ( width <= 0 ) + tension = 32000; + else + tension = ( tension << 10 ) / width; + + tension = -sign * FT_MulFix( tension, optimizer->tension_scale ); + spring->tension = tension; + + /* now, distribute tension among the englobing stems, if they */ + /* are able to move */ + status = 0; + if ( stem1->pos <= stem1->min_pos ) + status |= 1; + if ( stem2->pos >= stem2->max_pos ) + status |= 2; + + if ( !status ) + tension /= 2; + + if ( ( status & 1 ) == 0 ) + stem1->force -= tension; + + if ( ( status & 2 ) == 0 ) + stem2->force += tension; + } + } + + + /* compute all stem movements -- returns 0 if nothing moved */ + static int + optim_compute_stem_movements( AH_Optimizer* optimizer ) + { + AH_Stem* stems = optimizer->stems; + AH_Stem* limit = stems + optimizer->num_stems; + AH_Stem* stem = stems; + int moved = 0; + + + /* set initial forces to velocity */ + for ( stem = stems; stem < limit; stem++ ) + { + stem->force = stem->velocity; + stem->velocity /= 2; /* XXX: Heuristics */ + } + + /* compute the sum of forces applied on each stem */ + optim_compute_tensions( optimizer ); + +#ifdef AH_DEBUG_OPTIM + AH_Dump_Springs( optimizer ); + AH_Dump_Stems2( optimizer ); +#endif + + /* now, see whether something can move */ + for ( stem = stems; stem < limit; stem++ ) + { + if ( stem->force > optimizer->tension_threshold ) + { + /* there is enough tension to move the stem to the right */ + if ( stem->pos < stem->max_pos ) + { + stem->pos += 64; + stem->velocity = stem->force / 2; + moved = 1; + } + else + stem->velocity = 0; + } + else if ( stem->force < optimizer->tension_threshold ) + { + /* there is enough tension to move the stem to the left */ + if ( stem->pos > stem->min_pos ) + { + stem->pos -= 64; + stem->velocity = stem->force / 2; + moved = 1; + } + else + stem->velocity = 0; + } + } + + /* return 0 if nothing moved */ + return moved; + } + +#endif /* AH_BRUTE_FORCE */ + + + /* compute current global distortion from springs */ + static FT_Pos + optim_compute_distortion( AH_Optimizer* optimizer ) + { + AH_Spring* spring = optimizer->springs; + AH_Spring* limit = spring + optimizer->num_springs; + FT_Pos distortion = 0; + + + for ( ; spring < limit; spring++ ) + { + AH_Stem* stem1 = spring->stem1; + AH_Stem* stem2 = spring->stem2; + FT_Pos width; + + width = stem2->pos - ( stem1->pos + stem1->width ); + width -= spring->owidth; + if ( width < 0 ) + width = -width; + + distortion += width; + } + + return distortion; + } + + + /* record stems configuration in `best of' history */ + static void + optim_record_configuration( AH_Optimizer* optimizer ) + { + FT_Pos distortion; + AH_Configuration* configs = optimizer->configs; + AH_Configuration* limit = configs + optimizer->num_configs; + AH_Configuration* config; + + + distortion = optim_compute_distortion( optimizer ); + LOG(( "config distortion = %.1f ", FLOAT( distortion * 64 ) )); + + /* check that we really need to add this configuration to our */ + /* sorted history */ + if ( limit > configs && limit[-1].distortion < distortion ) + { + LOG(( "ejected\n" )); + return; + } + + /* add new configuration at the end of the table */ + { + int n; + + + config = limit; + if ( optimizer->num_configs < AH_MAX_CONFIGS ) + optimizer->num_configs++; + else + config--; + + config->distortion = distortion; + + for ( n = 0; n < optimizer->num_stems; n++ ) + config->positions[n] = optimizer->stems[n].pos; + } + + /* move the current configuration towards the front of the list */ + /* when necessary -- yes this is slow bubble sort ;-) */ + while ( config > configs && config[0].distortion < config[-1].distortion ) + { + AH_Configuration temp; + + + config--; + temp = config[0]; + config[0] = config[1]; + config[1] = temp; + } + LOG(( "recorded!\n" )); + } + + +#ifdef AH_BRUTE_FORCE + + /* optimize outline in a single direction */ + static void + optim_compute( AH_Optimizer* optimizer ) + { + int n; + FT_Bool moved; + + AH_Stem* stem = optimizer->stems; + AH_Stem* limit = stem + optimizer->num_stems; + + + /* empty, exit */ + if ( stem >= limit ) + return; + + optimizer->num_configs = 0; + + stem = optimizer->stems; + for ( ; stem < limit; stem++ ) + stem->pos = stem->min_pos; + + do + { + /* record current configuration */ + optim_record_configuration( optimizer ); + + /* now change configuration */ + moved = 0; + for ( stem = optimizer->stems; stem < limit; stem++ ) + { + if ( stem->pos < stem->max_pos ) + { + stem->pos += 64; + moved = 1; + break; + } + + stem->pos = stem->min_pos; + } + } while ( moved ); + + /* now, set the best stem positions */ + for ( n = 0; n < optimizer->num_stems; n++ ) + { + AH_Stem* stem = optimizer->stems + n; + FT_Pos pos = optimizer->configs[0].positions[n]; + + + stem->edge1->pos = pos; + stem->edge2->pos = pos + stem->width; + + stem->edge1->flags |= AH_EDGE_DONE; + stem->edge2->flags |= AH_EDGE_DONE; + } + } + +#else /* AH_BRUTE_FORCE */ + + /* optimize outline in a single direction */ + static void + optim_compute( AH_Optimizer* optimizer ) + { + int n, counter, counter2; + + + optimizer->num_configs = 0; + optimizer->tension_scale = 0x80000L; + optimizer->tension_threshold = 64; + + /* record initial configuration threshold */ + optim_record_configuration( optimizer ); + + counter = 0; + for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- ) + { + if ( counter == 0 ) + counter = 2 * optimizer->num_stems; + + if ( !optim_compute_stem_movements( optimizer ) ) + break; + + optim_record_configuration( optimizer ); + + counter--; + if ( counter == 0 ) + optimizer->tension_scale /= 2; + } + + /* now, set the best stem positions */ + for ( n = 0; n < optimizer->num_stems; n++ ) + { + AH_Stem* stem = optimizer->stems + n; + FT_Pos pos = optimizer->configs[0].positions[n]; + + + stem->edge1->pos = pos; + stem->edge2->pos = pos + stem->width; + + stem->edge1->flags |= AH_EDGE_DONE; + stem->edge2->flags |= AH_EDGE_DONE; + } + } + +#endif /* AH_BRUTE_FORCE */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** HIGH-LEVEL OPTIMIZER API ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* releases the optimization data */ + void + AH_Optimizer_Done( AH_Optimizer* optimizer ) + { + if ( optimizer ) + { + FT_Memory memory = optimizer->memory; + + + FT_FREE( optimizer->horz_stems ); + FT_FREE( optimizer->vert_stems ); + FT_FREE( optimizer->horz_springs ); + FT_FREE( optimizer->vert_springs ); + FT_FREE( optimizer->positions ); + } + } + + + /* loads the outline into the optimizer */ + int + AH_Optimizer_Init( AH_Optimizer* optimizer, + AH_Outline outline, + FT_Memory memory ) + { + FT_Error error; + + + FT_MEM_ZERO( optimizer, sizeof ( *optimizer ) ); + optimizer->outline = outline; + optimizer->memory = memory; + + LOG(( "initializing new optimizer\n" )); + /* compute stems and springs */ + error = optim_compute_stems ( optimizer ) || + optim_compute_springs( optimizer ); + if ( error ) + goto Fail; + + /* allocate stem positions history and configurations */ + { + int n, max_stems; + + + max_stems = optimizer->num_hstems; + if ( max_stems < optimizer->num_vstems ) + max_stems = optimizer->num_vstems; + + if ( FT_NEW_ARRAY( optimizer->positions, max_stems * AH_MAX_CONFIGS ) ) + goto Fail; + + optimizer->num_configs = 0; + for ( n = 0; n < AH_MAX_CONFIGS; n++ ) + optimizer->configs[n].positions = optimizer->positions + + n * max_stems; + } + + return error; + + Fail: + AH_Optimizer_Done( optimizer ); + return error; + } + + + /* compute optimal outline */ + void + AH_Optimizer_Compute( AH_Optimizer* optimizer ) + { + optimizer->num_stems = optimizer->num_hstems; + optimizer->stems = optimizer->horz_stems; + optimizer->num_springs = optimizer->num_hsprings; + optimizer->springs = optimizer->horz_springs; + + if ( optimizer->num_springs > 0 ) + { + LOG(( "horizontal optimization ------------------------\n" )); + optim_compute( optimizer ); + } + + optimizer->num_stems = optimizer->num_vstems; + optimizer->stems = optimizer->vert_stems; + optimizer->num_springs = optimizer->num_vsprings; + optimizer->springs = optimizer->vert_springs; + + if ( optimizer->num_springs ) + { + LOG(( "vertical optimization --------------------------\n" )); + optim_compute( optimizer ); + } + } + + +/* END */ diff --git a/lib/freetype/src/autohint/ahoptim.h b/lib/freetype/src/autohint/ahoptim.h new file mode 100644 index 0000000..d7862ba --- /dev/null +++ b/lib/freetype/src/autohint/ahoptim.h @@ -0,0 +1,137 @@ +/***************************************************************************/ +/* */ +/* ahoptim.h */ +/* */ +/* FreeType auto hinting outline optimization (declaration). */ +/* */ +/* Copyright 2000-2001 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHOPTIM_H__ +#define __AHOPTIM_H__ + + +#include <ft2build.h> +#include "ahtypes.h" + + +FT_BEGIN_HEADER + + + /* the maximal number of stem configurations to record */ + /* during optimization */ +#define AH_MAX_CONFIGS 8 + + + typedef struct AH_Stem_ + { + FT_Pos pos; /* current position */ + FT_Pos velocity; /* current velocity */ + FT_Pos force; /* sum of current forces */ + FT_Pos width; /* normalized width */ + + FT_Pos min_pos; /* minimum grid position */ + FT_Pos max_pos; /* maximum grid position */ + + AH_Edge edge1; /* left/bottom edge */ + AH_Edge edge2; /* right/top edge */ + + FT_Pos opos; /* original position */ + FT_Pos owidth; /* original width */ + + FT_Pos min_coord; /* minimum coordinate */ + FT_Pos max_coord; /* maximum coordinate */ + + } AH_Stem; + + + /* A spring between two stems */ + typedef struct AH_Spring_ + { + AH_Stem* stem1; + AH_Stem* stem2; + FT_Pos owidth; /* original width */ + FT_Pos tension; /* current tension */ + + } AH_Spring; + + + /* A configuration records the position of each stem at a given time */ + /* as well as the associated distortion */ + typedef struct AH_Configuration_ + { + FT_Pos* positions; + FT_Long distortion; + + } AH_Configuration; + + + typedef struct AH_Optimizer_ + { + FT_Memory memory; + AH_Outline outline; + + FT_Int num_hstems; + AH_Stem* horz_stems; + + FT_Int num_vstems; + AH_Stem* vert_stems; + + FT_Int num_hsprings; + FT_Int num_vsprings; + AH_Spring* horz_springs; + AH_Spring* vert_springs; + + FT_Int num_configs; + AH_Configuration configs[AH_MAX_CONFIGS]; + FT_Pos* positions; + + /* during each pass, use these instead */ + FT_Int num_stems; + AH_Stem* stems; + + FT_Int num_springs; + AH_Spring* springs; + FT_Bool vertical; + + FT_Fixed tension_scale; + FT_Pos tension_threshold; + + } AH_Optimizer; + + + /* loads the outline into the optimizer */ + int + AH_Optimizer_Init( AH_Optimizer* optimizer, + AH_Outline outline, + FT_Memory memory ); + + + /* compute optimal outline */ + void + AH_Optimizer_Compute( AH_Optimizer* optimizer ); + + + /* release the optimization data */ + void + AH_Optimizer_Done( AH_Optimizer* optimizer ); + + +FT_END_HEADER + +#endif /* __AHOPTIM_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/ahtypes.h b/lib/freetype/src/autohint/ahtypes.h new file mode 100644 index 0000000..fb14586 --- /dev/null +++ b/lib/freetype/src/autohint/ahtypes.h @@ -0,0 +1,533 @@ +/***************************************************************************/ +/* */ +/* ahtypes.h */ +/* */ +/* General types and definitions for the auto-hint module */ +/* (specification only). */ +/* */ +/* Copyright 2000-2001, 2002 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#ifndef __AHTYPES_H__ +#define __AHTYPES_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + +#ifdef DEBUG_HINTER +#include <../src/autohint/ahloader.h> +#else +#include "ahloader.h" +#endif + + +#define xxAH_DEBUG + + +#ifdef AH_DEBUG + +#include <stdio.h> +#define AH_LOG( x ) printf ## x + +#else + +#define AH_LOG( x ) do ; while ( 0 ) /* nothing */ + +#endif /* AH_DEBUG */ + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** COMPILE-TIME BUILD OPTIONS ****/ + /**** ****/ + /**** Toggle these configuration macros to experiment with `features' ****/ + /**** of the auto-hinter. ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* If this option is defined, only strong interpolation will be used to */ + /* place the points between edges. Otherwise, `smooth' points are */ + /* detected and later hinted through weak interpolation to correct some */ + /* unpleasant artefacts. */ + /* */ +#undef AH_OPTION_NO_WEAK_INTERPOLATION + + + /*************************************************************************/ + /* */ + /* If this option is defined, only weak interpolation will be used to */ + /* place the points between edges. Otherwise, `strong' points are */ + /* detected and later hinted through strong interpolation to correct */ + /* some unpleasant artefacts. */ + /* */ +#undef AH_OPTION_NO_STRONG_INTERPOLATION + + + /*************************************************************************/ + /* */ + /* Undefine this macro if you don't want to hint the metrics. There is */ + /* no reason to do this (at least for non-CJK scripts), except for */ + /* experimentation. */ + /* */ +#undef AH_HINT_METRICS + + + /*************************************************************************/ + /* */ + /* Define this macro if you do not want to insert extra edges at a */ + /* glyph's x and y extremum (if there isn't one already available). */ + /* This helps to reduce a number of artefacts and allows hinting of */ + /* metrics. */ + /* */ +#undef AH_OPTION_NO_EXTREMUM_EDGES + + + /* don't touch for now */ +#define AH_MAX_WIDTHS 12 +#define AH_MAX_HEIGHTS 12 + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** TYPE DEFINITIONS ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* see agangles.h */ + typedef FT_Int AH_Angle; + + + /* hint flags */ +#define AH_FLAG_NONE 0 + + /* bezier control points flags */ +#define AH_FLAG_CONIC 1 +#define AH_FLAG_CUBIC 2 +#define AH_FLAG_CONTROL ( AH_FLAG_CONIC | AH_FLAG_CUBIC ) + + /* extrema flags */ +#define AH_FLAG_EXTREMA_X 4 +#define AH_FLAG_EXTREMA_Y 8 + + /* roundness */ +#define AH_FLAG_ROUND_X 16 +#define AH_FLAG_ROUND_Y 32 + + /* touched */ +#define AH_FLAG_TOUCH_X 64 +#define AH_FLAG_TOUCH_Y 128 + + /* weak interpolation */ +#define AH_FLAG_WEAK_INTERPOLATION 256 +#define AH_FLAG_INFLECTION 512 + + typedef FT_Int AH_Flags; + + + /* edge hint flags */ +#define AH_EDGE_NORMAL 0 +#define AH_EDGE_ROUND 1 +#define AH_EDGE_SERIF 2 +#define AH_EDGE_DONE 4 + + typedef FT_Int AH_Edge_Flags; + + + /* hint directions -- the values are computed so that two vectors are */ + /* in opposite directions iff `dir1+dir2 == 0' */ +#define AH_DIR_NONE 4 +#define AH_DIR_RIGHT 1 +#define AH_DIR_LEFT -1 +#define AH_DIR_UP 2 +#define AH_DIR_DOWN -2 + + typedef FT_Int AH_Direction; + + + typedef struct AH_PointRec_* AH_Point; + typedef struct AH_SegmentRec_* AH_Segment; + typedef struct AH_EdgeRec_* AH_Edge; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AH_PointRec */ + /* */ + /* <Description> */ + /* A structure used to model an outline point to the AH_OutlineRec */ + /* type. */ + /* */ + /* <Fields> */ + /* flags :: The current point hint flags. */ + /* */ + /* ox, oy :: The current original scaled coordinates. */ + /* */ + /* fx, fy :: The current coordinates in font units. */ + /* */ + /* x, y :: The current hinted coordinates. */ + /* */ + /* u, v :: Point coordinates -- meaning varies with context. */ + /* */ + /* in_dir :: The direction of the inwards vector (prev->point). */ + /* */ + /* out_dir :: The direction of the outwards vector (point->next). */ + /* */ + /* in_angle :: The angle of the inwards vector. */ + /* */ + /* out_angle :: The angle of the outwards vector. */ + /* */ + /* next :: The next point in same contour. */ + /* */ + /* prev :: The previous point in same contour. */ + /* */ + typedef struct AH_PointRec_ + { + AH_Flags flags; /* point flags used by hinter */ + FT_Pos ox, oy; + FT_Pos fx, fy; + FT_Pos x, y; + FT_Pos u, v; + + AH_Direction in_dir; /* direction of inwards vector */ + AH_Direction out_dir; /* direction of outwards vector */ + + AH_Angle in_angle; + AH_Angle out_angle; + + AH_Point next; /* next point in contour */ + AH_Point prev; /* previous point in contour */ + + } AH_PointRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AH_SegmentRec */ + /* */ + /* <Description> */ + /* A structure used to describe an edge segment to the auto-hinter. */ + /* A segment is simply a sequence of successive points located on the */ + /* same horizontal or vertical `position', in a given direction. */ + /* */ + /* <Fields> */ + /* flags :: The segment edge flags (straight, rounded, etc.). */ + /* */ + /* dir :: The segment direction. */ + /* */ + /* first :: The first point in the segment. */ + /* */ + /* last :: The last point in the segment. */ + /* */ + /* contour :: A pointer to the first point of the segment's */ + /* contour. */ + /* */ + /* pos :: The segment position in font units. */ + /* */ + /* size :: The segment size. */ + /* */ + /* edge :: The edge of the current segment. */ + /* */ + /* edge_next :: The next segment on the same edge. */ + /* */ + /* link :: The pairing segment for this edge. */ + /* */ + /* serif :: The primary segment for serifs. */ + /* */ + /* num_linked :: The number of other segments that link to this one. */ + /* */ + /* score :: Used to score the segment when selecting them. */ + /* */ + typedef struct AH_SegmentRec_ + { + AH_Edge_Flags flags; + AH_Direction dir; + + AH_Point first; /* first point in edge segment */ + AH_Point last; /* last point in edge segment */ + AH_Point* contour; /* ptr to first point of segment's contour */ + + FT_Pos pos; /* position of segment */ + FT_Pos min_coord; /* minimum coordinate of segment */ + FT_Pos max_coord; /* maximum coordinate of segment */ + + AH_Edge edge; + AH_Segment edge_next; + + AH_Segment link; /* link segment */ + AH_Segment serif; /* primary segment for serifs */ + FT_Pos num_linked; /* number of linked segments */ + FT_Pos score; + + } AH_SegmentRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AH_EdgeRec */ + /* */ + /* <Description> */ + /* A structure used to describe an edge, which really is a horizontal */ + /* or vertical coordinate to be hinted depending on the segments */ + /* located on it. */ + /* */ + /* <Fields> */ + /* flags :: The segment edge flags (straight, rounded, etc.). */ + /* */ + /* dir :: The main segment direction on this edge. */ + /* */ + /* first :: The first edge segment. */ + /* */ + /* last :: The last edge segment. */ + /* */ + /* fpos :: The original edge position in font units. */ + /* */ + /* opos :: The original scaled edge position. */ + /* */ + /* pos :: The hinted edge position. */ + /* */ + /* link :: The linked edge. */ + /* */ + /* serif :: The serif edge. */ + /* */ + /* num_paired :: The number of other edges that pair to this one. */ + /* */ + /* score :: Used to score the edge when selecting them. */ + /* */ + /* blue_edge :: Indicate the blue zone edge this edge is related to. */ + /* Only set for some of the horizontal edges in a Latin */ + /* font. */ + /* */ + typedef struct AH_EdgeRec_ + { + AH_Edge_Flags flags; + AH_Direction dir; + + AH_Segment first; + AH_Segment last; + + FT_Pos fpos; + FT_Pos opos; + FT_Pos pos; + + AH_Edge link; + AH_Edge serif; + FT_Int num_linked; + + FT_Int score; + FT_Pos* blue_edge; + + } AH_EdgeRec; + + + /* an outline as seen by the hinter */ + typedef struct AH_OutlineRec_ + { + FT_Memory memory; + + AH_Direction vert_major_dir; /* vertical major direction */ + AH_Direction horz_major_dir; /* horizontal major direction */ + + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Pos edge_distance_threshold; + + FT_Int max_points; + FT_Int num_points; + AH_Point points; + + FT_Int max_contours; + FT_Int num_contours; + AH_Point * contours; + + FT_Int num_hedges; + AH_Edge horz_edges; + + FT_Int num_vedges; + AH_Edge vert_edges; + + FT_Int num_hsegments; + AH_Segment horz_segments; + + FT_Int num_vsegments; + AH_Segment vert_segments; + + } AH_OutlineRec, *AH_Outline; + + +#ifdef FT_CONFIG_CHESTER_SMALL_F + +# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ +# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ +# define AH_BLUE_SMALL_F_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1 ) /* fijkdbh */ +# define AH_BLUE_SMALL_TOP ( AH_BLUE_SMALL_F_TOP + 1 ) /* xzroesc */ +# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ +# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ +# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) + +#else /* !CHESTER_SMALL_F */ + +# define AH_BLUE_CAPITAL_TOP 0 /* THEZOCQS */ +# define AH_BLUE_CAPITAL_BOTTOM ( AH_BLUE_CAPITAL_TOP + 1 ) /* HEZLOCUS */ +# define AH_BLUE_SMALL_TOP ( AH_BLUE_CAPITAL_BOTTOM + 1) /* xzroesc */ +# define AH_BLUE_SMALL_BOTTOM ( AH_BLUE_SMALL_TOP + 1 ) /* xzroesc */ +# define AH_BLUE_SMALL_MINOR ( AH_BLUE_SMALL_BOTTOM + 1 ) /* pqgjy */ +# define AH_BLUE_MAX ( AH_BLUE_SMALL_MINOR + 1 ) + +#endif /* !CHESTER_SMALL_F */ + + typedef FT_Int AH_Blue; + + +#define AH_HINTER_MONOCHROME 1 +#define AH_HINTER_OPTIMIZE 2 + + typedef FT_Int AH_Hinter_Flags; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AH_GlobalsRec */ + /* */ + /* <Description> */ + /* Holds the global metrics for a given font face (be it in design */ + /* units or scaled pixel values). */ + /* */ + /* <Fields> */ + /* num_widths :: The number of widths. */ + /* */ + /* num_heights :: The number of heights. */ + /* */ + /* widths :: Snap widths, including standard one. */ + /* */ + /* heights :: Snap height, including standard one. */ + /* */ + /* blue_refs :: The reference positions of blue zones. */ + /* */ + /* blue_shoots :: The overshoot positions of blue zones. */ + /* */ + typedef struct AH_GlobalsRec_ + { + FT_Int num_widths; + FT_Int num_heights; + + FT_Pos stds[2]; + + FT_Pos widths [AH_MAX_WIDTHS]; + FT_Pos heights[AH_MAX_HEIGHTS]; + + FT_Pos blue_refs [AH_BLUE_MAX]; + FT_Pos blue_shoots[AH_BLUE_MAX]; + + } AH_GlobalsRec, *AH_Globals; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AH_Face_GlobalsRec */ + /* */ + /* <Description> */ + /* Holds the complete global metrics for a given font face (i.e., the */ + /* design units version + a scaled version + the current scales */ + /* used). */ + /* */ + /* <Fields> */ + /* face :: A handle to the source face object */ + /* */ + /* design :: The globals in font design units. */ + /* */ + /* scaled :: Scaled globals in sub-pixel values. */ + /* */ + /* x_scale :: The current horizontal scale. */ + /* */ + /* y_scale :: The current vertical scale. */ + /* */ + typedef struct AH_Face_GlobalsRec_ + { + FT_Face face; + AH_GlobalsRec design; + AH_GlobalsRec scaled; + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Bool control_overshoot; + + } AH_Face_GlobalsRec, *AH_Face_Globals; + + + typedef struct AH_HinterRec + { + FT_Memory memory; + AH_Hinter_Flags flags; + + FT_Int algorithm; + FT_Face face; + + AH_Face_Globals globals; + + AH_Outline glyph; + + AH_Loader loader; + FT_Vector pp1; + FT_Vector pp2; + + FT_Bool transformed; + FT_Vector trans_delta; + FT_Matrix trans_matrix; + + FT_Bool do_horz_hints; /* disable X hinting */ + FT_Bool do_vert_hints; /* disable Y hinting */ + FT_Bool do_horz_snapping; /* disable X stem size snapping */ + FT_Bool do_vert_snapping; /* disable Y stem size snapping */ + FT_Bool do_stem_adjust; /* disable light stem snapping */ + + } AH_HinterRec, *AH_Hinter; + + +#ifdef DEBUG_HINTER + extern AH_Hinter ah_debug_hinter; + extern FT_Bool ah_debug_disable_horz; + extern FT_Bool ah_debug_disable_vert; +#else +#define ah_debug_disable_horz 0 +#define ah_debug_disable_vert 0 +#endif /* DEBUG_HINTER */ + + +FT_END_HEADER + +#endif /* __AHTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/src/autohint/autohint.c b/lib/freetype/src/autohint/autohint.c new file mode 100644 index 0000000..3783a82 --- /dev/null +++ b/lib/freetype/src/autohint/autohint.c @@ -0,0 +1,32 @@ +/***************************************************************************/ +/* */ +/* autohint.c */ +/* */ +/* Automatic Hinting wrapper (body only). */ +/* */ +/* Copyright 2000-2001 Catharon Productions Inc. */ +/* Author: David Turner */ +/* */ +/* This file is part of the Catharon Typography Project and shall only */ +/* be used, modified, and distributed under the terms of the Catharon */ +/* Open Source License that should come with this file under the name */ +/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ahangles.c" +#include "ahglyph.c" +#include "ahglobal.c" +#include "ahhint.c" +#include "ahmodule.c" + + +/* END */ diff --git a/lib/freetype/src/autohint/descrip.mms b/lib/freetype/src/autohint/descrip.mms new file mode 100644 index 0000000..72039cc --- /dev/null +++ b/lib/freetype/src/autohint/descrip.mms @@ -0,0 +1,25 @@ +# +# FreeType 2 auto-hinter module compilation rules for VMS +# + + +# Copyright 2001, 2002 Catharon Productions Inc. +# +# This file is part of the Catharon Typography Project and shall only +# be used, modified, and distributed under the terms of the Catharon +# Open Source License that should come with this file under the name +# `CatharonLicense.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 that this license is compatible with the FreeType license. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/incl=([--.include],[--.src.autohint]) + +OBJS=autohint.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/autohint/mather.py b/lib/freetype/src/autohint/mather.py new file mode 100644 index 0000000..8ad8b55 --- /dev/null +++ b/lib/freetype/src/autohint/mather.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# + +# +# autohint math table builder +# + + +# Copyright 1996-2000 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. + + +import math + +ag_pi = 256 + +def print_arctan( atan_bits ): + atan_base = 1 << atan_bits + + print " static AH_Angle ag_arctan[1L << AG_ATAN_BITS] =" + print " {" + + count = 0 + line = " " + + for n in range( atan_base ): + comma = "," + if ( n == atan_base - 1 ): + comma = "" + + angle = math.atan( n * 1.0 / atan_base ) / math.pi * ag_pi + line = line + " " + repr( int( angle + 0.5 ) ) + comma + count = count + 1; + if ( count == 8 ): + count = 0 + print line + line = " " + + if ( count > 0 ): + print line + print " };" + + +# This routine is not used currently. +# +def print_sines(): + print " static FT_Fixed ah_sines[AG_HALF_PI + 1] =" + print " {" + + count = 0 + line = " " + + for n in range( ag_pi / 2 ): + sinus = math.sin( n * math.pi / ag_pi ) + line = line + " " + repr( int( 65536.0 * sinus ) ) + "," + count = count + 1 + if ( count == 8 ): + count = 0 + print line + line = " " + + if ( count > 0 ): + print line + print " 65536" + print " };" + + +print_arctan( 8 ) +print + + +# END diff --git a/lib/freetype/src/autohint/module.mk b/lib/freetype/src/autohint/module.mk new file mode 100644 index 0000000..edc9f4e --- /dev/null +++ b/lib/freetype/src/autohint/module.mk @@ -0,0 +1,25 @@ +# +# FreeType 2 auto-hinter module definition +# + + +# Copyright 2000 Catharon Productions Inc. +# Author: David Turner +# +# This file is part of the Catharon Typography Project and shall only +# be used, modified, and distributed under the terms of the Catharon +# Open Source License that should come with this file under the name +# `CatharonLicense.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 that this license is compatible with the FreeType license. + + +make_module_list: add_autohint_module + +add_autohint_module: + $(OPEN_DRIVER)autohint_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)autohint $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/autohint/rules.mk b/lib/freetype/src/autohint/rules.mk new file mode 100644 index 0000000..6dcaa20 --- /dev/null +++ b/lib/freetype/src/autohint/rules.mk @@ -0,0 +1,78 @@ +# +# FreeType 2 auto-hinter module configuration rules +# + + +# Copyright 2000, 2001 Catharon Productions Inc. +# Author: David Turner +# +# This file is part of the Catharon Typography Project and shall only +# be used, modified, and distributed under the terms of the Catharon +# Open Source License that should come with this file under the name +# `CatharonLicense.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 that this license is compatible with the FreeType license. + + +# AUTO driver directory +# +AUTO_DIR := $(SRC_)autohint +AUTO_DIR_ := $(AUTO_DIR)$(SEP) + + +# compilation flags for the driver +# +AUTO_COMPILE := $(FT_COMPILE) $I$(AUTO_DIR) + + +# AUTO driver sources (i.e., C files) +# +AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c \ + $(AUTO_DIR_)ahglobal.c \ + $(AUTO_DIR_)ahglyph.c \ + $(AUTO_DIR_)ahhint.c \ + $(AUTO_DIR_)ahmodule.c + +# AUTO driver headers +# +AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \ + $(AUTO_DIR_)ahloader.h \ + $(AUTO_DIR_)ahtypes.h \ + $(AUTO_DIR_)aherrors.h + + +# AUTO driver object(s) +# +# AUTO_DRV_OBJ_M is used during `multi' builds. +# AUTO_DRV_OBJ_S is used during `single' builds. +# +AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR_)%.c=$(OBJ_)%.$O) +AUTO_DRV_OBJ_S := $(OBJ_)autohint.$O + +# AUTO driver source file for single build +# +AUTO_DRV_SRC_S := $(AUTO_DIR_)autohint.c + + +# AUTO driver - single object +# +$(AUTO_DRV_OBJ_S): $(AUTO_DRV_SRC_S) $(AUTO_DRV_SRC) \ + $(FREETYPE_H) $(AUTO_DRV_H) + $(AUTO_COMPILE) $T$@ $(AUTO_DRV_SRC_S) + + +# AUTO driver - multiple objects +# +$(OBJ_)%.$O: $(AUTO_DIR_)%.c $(FREETYPE_H) $(AUTO_DRV_H) + $(AUTO_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(AUTO_DRV_OBJ_S) +DRV_OBJS_M += $(AUTO_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/base/Jamfile b/lib/freetype/src/base/Jamfile new file mode 100644 index 0000000..5ebcd7c --- /dev/null +++ b/lib/freetype/src/base/Jamfile @@ -0,0 +1,37 @@ +# FreeType 2 src/base Jamfile (c) 2001, 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) base ; + + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln + ftobjs ftnames ; + } + else + { + _sources = ftbase ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# Add the optional/replaceable files. +# +Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c + ftbbox.c ftdebug.c ftxf86.c fttype1.c ftpfr.c + ftstroker.c ftwinfnt.c + ; + +# Add Macintosh-specific file to the library when necessary. +# +if $(MAC) +{ + Library $(FT2_LIB) : ftmac.c ; +} + +# end of src/base Jamfile diff --git a/lib/freetype/src/base/descrip.mms b/lib/freetype/src/base/descrip.mms new file mode 100644 index 0000000..02a806a --- /dev/null +++ b/lib/freetype/src/base/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 base layer compilation rules for VMS +# + + +# Copyright 2001 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base]) + +OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj,ftstroker.obj,ftwinfnt.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/base/ftapi.c b/lib/freetype/src/base/ftapi.c new file mode 100644 index 0000000..1ef3005 --- /dev/null +++ b/lib/freetype/src/base/ftapi.c @@ -0,0 +1,121 @@ +/***************************************************************************/ +/* */ +/* ftapi.c */ +/* */ +/* The FreeType compatibility functions (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TABLES_H +#include FT_OUTLINE_H + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C O M P A T I B I L I T Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* backwards compatibility API */ + + FT_BASE_DEF( void ) + FT_New_Memory_Stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream stream ) + { + FT_UNUSED( library ); + + FT_Stream_OpenMemory( stream, base, size ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Seek_Stream( FT_Stream stream, + FT_ULong pos ) + { + return FT_Stream_Seek( stream, pos ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Skip_Stream( FT_Stream stream, + FT_Long distance ) + { + return FT_Stream_Skip( stream, distance ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_Read( stream, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Read_Stream_At( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Extract_Frame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + return FT_Stream_ExtractFrame( stream, count, pbytes ); + } + + + FT_BASE_DEF( void ) + FT_Release_Frame( FT_Stream stream, + FT_Byte** pbytes ) + { + FT_Stream_ReleaseFrame( stream, pbytes ); + } + + FT_BASE_DEF( FT_Error ) + FT_Access_Frame( FT_Stream stream, + FT_ULong count ) + { + return FT_Stream_EnterFrame( stream, count ); + } + + + FT_BASE_DEF( void ) + FT_Forget_Frame( FT_Stream stream ) + { + FT_Stream_ExitFrame( stream ); + } + + +/* END */ diff --git a/lib/freetype/src/base/ftbase.c b/lib/freetype/src/base/ftbase.c new file mode 100644 index 0000000..4ea846d --- /dev/null +++ b/lib/freetype/src/base/ftbase.c @@ -0,0 +1,34 @@ +/***************************************************************************/ +/* */ +/* ftbase.c */ +/* */ +/* Single object library component (body only). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include "ftutil.c" +#include "ftdbgmem.c" +#include "ftstream.c" +#include "ftcalc.c" +#include "fttrigon.c" +#include "ftoutln.c" +#include "ftgloadr.c" +#include "ftobjs.c" +#include "ftnames.c" + + +/* END */ diff --git a/lib/freetype/src/base/ftbbox.c b/lib/freetype/src/base/ftbbox.c new file mode 100644 index 0000000..dd445d8 --- /dev/null +++ b/lib/freetype/src/base/ftbbox.c @@ -0,0 +1,653 @@ +/***************************************************************************/ +/* */ +/* ftbbox.c */ +/* */ +/* FreeType bbox computation (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_BBOX_H +#include FT_IMAGE_H +#include FT_OUTLINE_H +#include FT_INTERNAL_CALC_H + + + typedef struct TBBox_Rec_ + { + FT_Vector last; + FT_BBox bbox; + + } TBBox_Rec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Move_To */ + /* */ + /* <Description> */ + /* This function is used as a `move_to' and `line_to' emitter during */ + /* FT_Outline_Decompose(). It simply records the destination point */ + /* in `user->last'; no further computations are necessary since we */ + /* the cbox as the starting bbox which must be refined. */ + /* */ + /* <Input> */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: A pointer to the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + static int + BBox_Move_To( FT_Vector* to, + TBBox_Rec* user ) + { + user->last = *to; + + return 0; + } + + +#define CHECK_X( p, bbox ) \ + ( p->x < bbox.xMin || p->x > bbox.xMax ) + +#define CHECK_Y( p, bbox ) \ + ( p->y < bbox.yMin || p->y > bbox.yMax ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ + /* a bounding range. This version uses direct computation, as it */ + /* doesn't need square roots. */ + /* */ + /* <Input> */ + /* y1 :: The start coordinate. */ + /* y2 :: The coordinate of the control point. */ + /* y3 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* max :: The address of the current maximum. */ + /* */ + static void + BBox_Conic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos* min, + FT_Pos* max ) + { + if ( y1 <= y3 ) + { + if ( y2 == y1 ) /* Flat arc */ + goto Suite; + } + else if ( y1 < y3 ) + { + if ( y2 >= y1 && y2 <= y3 ) /* Ascending arc */ + goto Suite; + } + else + { + if ( y2 >= y3 && y2 <= y1 ) /* Descending arc */ + { + y2 = y1; + y1 = y3; + y3 = y2; + goto Suite; + } + } + + y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); + + Suite: + if ( y1 < *min ) *min = y1; + if ( y3 > *max ) *max = y3; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Conic_To */ + /* */ + /* <Description> */ + /* This function is used as a `conic_to' emitter during */ + /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control :: A pointer to a control point. */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we compute directly the */ + /* extremum coordinates, as it is sufficiently fast. */ + /* */ + static int + BBox_Conic_To( FT_Vector* control, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control, user->bbox ) ) + + BBox_Conic_Check( user->last.x, + control->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control, user->bbox ) ) + + BBox_Conic_Check( user->last.y, + control->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_Check */ + /* */ + /* <Description> */ + /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ + /* updates a bounding range. This version uses splitting because we */ + /* don't want to use square roots and extra accuracies. */ + /* */ + /* <Input> */ + /* p1 :: The start coordinate. */ + /* p2 :: The coordinate of the first control point. */ + /* p3 :: The coordinate of the second control point. */ + /* p4 :: The end coordinate. */ + /* */ + /* <InOut> */ + /* min :: The address of the current minimum. */ + /* max :: The address of the current maximum. */ + /* */ +#if 0 + static void + BBox_Cubic_Check( FT_Pos p1, + FT_Pos p2, + FT_Pos p3, + FT_Pos p4, + FT_Pos* min, + FT_Pos* max ) + { + FT_Pos stack[32*3 + 1], *arc; + + + arc = stack; + + arc[0] = p1; + arc[1] = p2; + arc[2] = p3; + arc[3] = p4; + + do + { + FT_Pos y1 = arc[0]; + FT_Pos y2 = arc[1]; + FT_Pos y3 = arc[2]; + FT_Pos y4 = arc[3]; + + + if ( y1 == y4 ) + { + if ( y1 == y2 && y1 == y3 ) /* Flat */ + goto Test; + } + else if ( y1 < y4 ) + { + if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* Ascending */ + goto Test; + } + else + { + if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* Descending */ + { + y2 = y1; + y1 = y4; + y4 = y2; + goto Test; + } + } + + /* Unknown direction -- split the arc in two */ + arc[6] = y4; + arc[1] = y1 = ( y1 + y2 ) / 2; + arc[5] = y4 = ( y4 + y3 ) / 2; + y2 = ( y2 + y3 ) / 2; + arc[2] = y1 = ( y1 + y2 ) / 2; + arc[4] = y4 = ( y4 + y2 ) / 2; + arc[3] = ( y1 + y4 ) / 2; + + arc += 3; + goto Suite; + + Test: + if ( y1 < *min ) *min = y1; + if ( y4 > *max ) *max = y4; + arc -= 3; + + Suite: + ; + } while ( arc >= stack ); + } +#else + + static void + test_cubic_extrema( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Fixed u, + FT_Pos* min, + FT_Pos* max ) + { + /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d = y1; + FT_Pos y; + FT_Fixed uu; + + FT_UNUSED ( y4 ); + + + /* The polynom is */ + /* */ + /* a*x^3 + 3b*x^2 + 3c*x + d . */ + /* */ + /* However, we also have */ + /* */ + /* dP/dx(u) = 0 , */ + /* */ + /* which implies that */ + /* */ + /* P(u) = b*u^2 + 2c*u + d */ + + if ( u > 0 && u < 0x10000L ) + { + uu = FT_MulFix( u, u ); + y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); + + if ( y < *min ) *min = y; + if ( y > *max ) *max = y; + } + } + + + static void + BBox_Cubic_Check( FT_Pos y1, + FT_Pos y2, + FT_Pos y3, + FT_Pos y4, + FT_Pos* min, + FT_Pos* max ) + { + /* always compare first and last points */ + if ( y1 < *min ) *min = y1; + else if ( y1 > *max ) *max = y1; + + if ( y4 < *min ) *min = y4; + else if ( y4 > *max ) *max = y4; + + /* now, try to see if there are split points here */ + if ( y1 <= y4 ) + { + /* flat or ascending arc test */ + if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) + return; + } + else /* y1 > y4 */ + { + /* descending arc test */ + if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) + return; + } + + /* There are some split points. Find them. */ + { + FT_Pos a = y4 - 3*y3 + 3*y2 - y1; + FT_Pos b = y3 - 2*y2 + y1; + FT_Pos c = y2 - y1; + FT_Pos d; + FT_Fixed t; + + + /* We need to solve "ax^2+2bx+c" here, without floating points! */ + /* The trick is to normalize to a different representation in order */ + /* to use our 16.16 fixed point routines. */ + /* */ + /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after the */ + /* the normalization. These values must fit into a single 16.16 */ + /* value. */ + /* */ + /* We normalize a, b, and c to "8.16" fixed float values to ensure */ + /* that their product is held in a "16.16" value. */ + /* */ + { + FT_ULong t1, t2; + int shift = 0; + + + /* Technical explanation of what's happening there. */ + /* */ + /* The following computation is based on the fact that for */ + /* any value "y", if "n" is the position of the most */ + /* significant bit of "abs(y)" (starting from 0 for the */ + /* least significant bit), then y is in the range */ + /* */ + /* "-2^n..2^n-1" */ + /* */ + /* We want to shift "a", "b" and "c" concurrently in order */ + /* to ensure that they all fit in 8.16 values, which maps */ + /* to the integer range "-2^23..2^23-1". */ + /* */ + /* Necessarily, we need to shift "a", "b" and "c" so that */ + /* the most significant bit of their absolute values is at */ + /* _most_ at position 23. */ + /* */ + /* We begin by computing "t1" as the bitwise "or" of the */ + /* absolute values of "a", "b", "c". */ + /* */ + t1 = (FT_ULong)((a >= 0) ? a : -a ); + t2 = (FT_ULong)((b >= 0) ? b : -b ); + t1 |= t2; + t2 = (FT_ULong)((c >= 0) ? c : -c ); + t1 |= t2; + + /* Now, the most significant bit of "t1" is sure to be the */ + /* msb of one of "a", "b", "c", depending on which one is */ + /* expressed in the greatest integer range. */ + /* */ + /* We now compute the "shift", by shifting "t1" as many */ + /* times as necessary to move its msb to position 23. */ + /* */ + /* This corresponds to a value of t1 that is in the range */ + /* 0x40_0000..0x7F_FFFF. */ + /* */ + /* Finally, we shift "a", "b" and "c" by the same amount. */ + /* This ensures that all values are now in the range */ + /* -2^23..2^23, i.e. that they are now expressed as 8.16 */ + /* fixed float numbers. */ + /* */ + /* This also means that we are using 24 bits of precision */ + /* to compute the zeros, independently of the range of */ + /* the original polynom coefficients. */ + /* */ + /* This should ensure reasonably accurate values for the */ + /* zeros. Note that the latter are only expressed with */ + /* 16 bits when computing the extrema (the zeros need to */ + /* be in 0..1 exclusive to be considered part of the arc). */ + /* */ + if ( t1 == 0 ) /* all coefficients are 0! */ + return; + + if ( t1 > 0x7FFFFFUL ) + { + do + { + shift++; + t1 >>= 1; + } while ( t1 > 0x7FFFFFUL ); + + /* losing some bits of precision, but we use 24 of them */ + /* for the computation anyway. */ + a >>= shift; + b >>= shift; + c >>= shift; + } + else if ( t1 < 0x400000UL ) + { + do + { + shift++; + t1 <<= 1; + } while ( t1 < 0x400000UL ); + + a <<= shift; + b <<= shift; + c <<= shift; + } + } + + /* handle a == 0 */ + if ( a == 0 ) + { + if ( b != 0 ) + { + t = - FT_DivFix( c, b ) / 2; + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + else + { + /* solve the equation now */ + d = FT_MulFix( b, b ) - FT_MulFix( a, c ); + if ( d < 0 ) + return; + + if ( d == 0 ) + { + /* there is a single split point at -b/a */ + t = - FT_DivFix( b, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + else + { + /* there are two solutions; we need to filter them though */ + d = FT_SqrtFixed( (FT_Int32)d ); + t = - FT_DivFix( b - d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + + t = - FT_DivFix( b + d, a ); + test_cubic_extrema( y1, y2, y3, y4, t, min, max ); + } + } + } + } + +#endif + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* BBox_Cubic_To */ + /* */ + /* <Description> */ + /* This function is used as a `cubic_to' emitter during */ + /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ + /* current bounding box, and computes its extrema if necessary to */ + /* update it. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first control point. */ + /* control2 :: A pointer to the second control point. */ + /* to :: A pointer to the destination vector. */ + /* */ + /* <InOut> */ + /* user :: The address of the current walk context. */ + /* */ + /* <Return> */ + /* Always 0. Needed for the interface only. */ + /* */ + /* <Note> */ + /* In the case of a non-monotonous arc, we don't compute directly */ + /* extremum coordinates, we subdivise instead. */ + /* */ + static int + BBox_Cubic_To( FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to, + TBBox_Rec* user ) + { + /* we don't need to check `to' since it is always an `on' point, thus */ + /* within the bbox */ + + if ( CHECK_X( control1, user->bbox ) || + CHECK_X( control2, user->bbox ) ) + + BBox_Cubic_Check( user->last.x, + control1->x, + control2->x, + to->x, + &user->bbox.xMin, + &user->bbox.xMax ); + + if ( CHECK_Y( control1, user->bbox ) || + CHECK_Y( control2, user->bbox ) ) + + BBox_Cubic_Check( user->last.y, + control1->y, + control2->y, + to->y, + &user->bbox.yMin, + &user->bbox.yMax ); + + user->last = *to; + + return 0; + } + + + /* documentation is in ftbbox.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ) + { + FT_BBox cbox; + FT_BBox bbox; + FT_Vector* vec; + FT_UShort n; + + + if ( !abbox ) + return FT_Err_Invalid_Argument; + + if ( !outline ) + return FT_Err_Invalid_Outline; + + /* if outline is empty, return (0,0,0,0) */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + { + abbox->xMin = abbox->xMax = 0; + abbox->yMin = abbox->yMax = 0; + return 0; + } + + /* We compute the control box as well as the bounding box of */ + /* all `on' points in the outline. Then, if the two boxes */ + /* coincide, we exit immediately. */ + + vec = outline->points; + bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; + bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; + vec++; + + for ( n = 1; n < outline->n_points; n++ ) + { + FT_Pos x = vec->x; + FT_Pos y = vec->y; + + + /* update control box */ + if ( x < cbox.xMin ) cbox.xMin = x; + if ( x > cbox.xMax ) cbox.xMax = x; + + if ( y < cbox.yMin ) cbox.yMin = y; + if ( y > cbox.yMax ) cbox.yMax = y; + + if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) + { + /* update bbox for `on' points only */ + if ( x < bbox.xMin ) bbox.xMin = x; + if ( x > bbox.xMax ) bbox.xMax = x; + + if ( y < bbox.yMin ) bbox.yMin = y; + if ( y > bbox.yMax ) bbox.yMax = y; + } + + vec++; + } + + /* test two boxes for equality */ + if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax || + cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax ) + { + /* the two boxes are different, now walk over the outline to */ + /* get the Bezier arc extrema. */ + + static const FT_Outline_Funcs bbox_interface = + { + (FT_Outline_MoveTo_Func) BBox_Move_To, + (FT_Outline_LineTo_Func) BBox_Move_To, + (FT_Outline_ConicTo_Func)BBox_Conic_To, + (FT_Outline_CubicTo_Func)BBox_Cubic_To, + 0, 0 + }; + + FT_Error error; + TBBox_Rec user; + + + user.bbox = bbox; + + error = FT_Outline_Decompose( outline, &bbox_interface, &user ); + if ( error ) + return error; + + *abbox = user.bbox; + } + else + *abbox = bbox; + + return FT_Err_Ok; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftbdf.c b/lib/freetype/src/base/ftbdf.c new file mode 100644 index 0000000..3e76e9f --- /dev/null +++ b/lib/freetype/src/base/ftbdf.c @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* ftbdf.c */ +/* */ +/* FreeType API for accessing BDF-specific strings (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_BDF_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + static FT_Bool + test_font_type( FT_Face face, const char* name ) + { + if ( face && face->driver ) + { + FT_Module driver = (FT_Module)face->driver; + + if ( driver->clazz && driver->clazz->module_name ) + { + if ( ft_strcmp( driver->clazz->module_name, name ) == 0 ) + return 1; + } + } + return 0; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ) + { + FT_Error error; + const char* encoding = NULL; + const char* registry = NULL; + + + error = FT_Err_Invalid_Argument; + + if ( test_font_type( face, "bdf" ) ) + { + BDF_Public_Face bdf_face = (BDF_Public_Face)face; + + + encoding = (const char*) bdf_face->charset_encoding; + registry = (const char*) bdf_face->charset_registry; + error = 0; + } + + if ( acharset_encoding ) + *acharset_encoding = encoding; + + if ( acharset_registry ) + *acharset_registry = registry; + + return error; + } + + + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + FT_Error error; + + error = FT_Err_Invalid_Argument; + + aproperty->type = BDF_PROPERTY_TYPE_NONE; + + if ( face != NULL && face->driver != NULL ) + { + FT_Driver driver = face->driver; + BDF_GetPropertyFunc func; + + func = (BDF_GetPropertyFunc) driver->root.clazz->get_interface( + FT_MODULE( driver ), "get_bdf_property" ); + if ( func ) + error = func( face, prop_name, aproperty ); + } + return error; + } + +/* END */ diff --git a/lib/freetype/src/base/ftcalc.c b/lib/freetype/src/base/ftcalc.c new file mode 100644 index 0000000..6b78bc3 --- /dev/null +++ b/lib/freetype/src/base/ftcalc.c @@ -0,0 +1,561 @@ +/***************************************************************************/ +/* */ +/* ftcalc.c */ +/* */ +/* Arithmetic computations (body). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Support for 1-complement arithmetic has been totally dropped in this */ + /* release. You can still write your own code if you need it. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Implementing basic computation routines. */ + /* */ + /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ + /* and FT_FloorFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + +/* we need to define a 64-bits data type here */ + +#ifdef FT_LONG64 + + typedef FT_INT64 FT_Int64; + +#else + + typedef struct FT_Int64_ + { + FT_UInt32 lo; + FT_UInt32 hi; + + } FT_Int64; + +#endif /* FT_LONG64 */ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_calc + + + /* The following three functions are available regardless of whether */ + /* FT_LONG64 is defined. */ + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_RoundFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0x8000L ) & -0x10000L + : -((-a + 0x8000L ) & -0x10000L ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_CeilFix( FT_Fixed a ) + { + return ( a >= 0 ) ? ( a + 0xFFFFL ) & -0x10000L + : -((-a + 0xFFFFL ) & -0x10000L ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_FloorFix( FT_Fixed a ) + { + return ( a >= 0 ) ? a & -0x10000L + : -((-a) & -0x10000L ); + } + + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_Sqrt32( FT_Int32 x ) + { + FT_ULong val, root, newroot, mask; + + + root = 0; + mask = 0x40000000L; + val = (FT_ULong)x; + + do + { + newroot = root + mask; + if ( newroot <= val ) + { + val -= newroot; + root = newroot + mask; + } + + root >>= 1; + mask >>= 2; + + } while ( mask != 0 ); + + return root; + } + + +#ifdef FT_LONG64 + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ) + { + FT_Int s; + FT_Long d; + + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + if ( c < 0 ) { c = -c; s = -s; } + + d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c + : 0x7FFFFFFFL ); + + return ( s > 0 ) ? d : -d; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { + FT_Int s = 1; + FT_Long c; + + + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + + c = (FT_Long)( ( (FT_Int64)a * b + 0x8000 ) >> 16 ); + return ( s > 0 ) ? c : -c ; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + s = 1; + if ( a < 0 ) { a = -a; s = -1; } + if ( b < 0 ) { b = -b; s = -s; } + + if ( b == 0 ) + /* check for division by 0 */ + q = 0x7FFFFFFFL; + else + /* compute result directly */ + q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b ); + + return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); + } + + +#else /* FT_LONG64 */ + + + static void + ft_multo64( FT_UInt32 x, + FT_UInt32 y, + FT_Int64 *z ) + { + FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; + + + lo1 = x & 0x0000FFFFU; hi1 = x >> 16; + lo2 = y & 0x0000FFFFU; hi2 = y >> 16; + + lo = lo1 * lo2; + i1 = lo1 * hi2; + i2 = lo2 * hi1; + hi = hi1 * hi2; + + /* Check carry overflow of i1 + i2 */ + i1 += i2; + hi += (FT_UInt32)( i1 < i2 ) << 16; + + hi += i1 >> 16; + i1 = i1 << 16; + + /* Check carry overflow of i1 + lo */ + lo += i1; + hi += ( lo < i1 ); + + z->lo = lo; + z->hi = hi; + } + + + static FT_UInt32 + ft_div64by32( FT_UInt32 hi, + FT_UInt32 lo, + FT_UInt32 y ) + { + FT_UInt32 r, q; + FT_Int i; + + + q = 0; + r = hi; + + if ( r >= y ) + return (FT_UInt32)0x7FFFFFFFL; + + i = 32; + do + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (FT_UInt32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } while ( --i ); + + return q; + } + + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( void ) + FT_Add64( FT_Int64* x, + FT_Int64* y, + FT_Int64 *z ) + { + register FT_UInt32 lo, hi, max; + + + max = x->lo > y->lo ? x->lo : y->lo; + lo = x->lo + y->lo; + hi = x->hi + y->hi + ( lo < max ); + + z->lo = lo; + z->hi = hi; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_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 <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) + { + a = ( a * b + ( c >> 1 ) ) / c; + } + else if ( c > 0 ) + { + FT_Int64 temp, temp2; + + + ft_multo64( a, b, &temp ); + + temp2.hi = 0; + temp2.lo = (FT_UInt32)(c >> 1); + FT_Add64( &temp, &temp2, &temp ); + a = ft_div64by32( temp.hi, temp.lo, c ); + } + else + a = 0x7FFFFFFFL; + + return ( s < 0 ? -a : a ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ) + { + FT_Long s; + FT_ULong ua, ub; + + + if ( a == 0 || b == 0x10000L ) + return a; + + s = a; a = ABS(a); + s ^= b; b = ABS(b); + + ua = (FT_ULong)a; + ub = (FT_ULong)b; + + if ( ua <= 2048 && ub <= 1048576L ) + { + ua = ( ua * ub + 0x8000 ) >> 16; + } + else + { + FT_ULong al = ua & 0xFFFF; + + + ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + + ( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 ); + } + + return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ) + { + FT_Int32 s; + FT_UInt32 q; + + + s = a; a = ABS(a); + s ^= b; b = ABS(b); + + if ( b == 0 ) + { + /* check for division by 0 */ + q = 0x7FFFFFFFL; + } + else if ( ( a >> 16 ) == 0 ) + { + /* compute result directly */ + q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b; + } + else + { + /* we need more bits; we have to do it by hand */ + FT_Int64 temp, temp2; + + temp.hi = (FT_Int32) (a >> 16); + temp.lo = (FT_UInt32)(a << 16); + temp2.hi = 0; + temp2.lo = (FT_UInt32)( b >> 1 ); + FT_Add64( &temp, &temp2, &temp ); + q = ft_div64by32( temp.hi, temp.lo, b ); + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + + /* documentation is in ftcalc.h */ + + FT_EXPORT_DEF( void ) + FT_MulTo64( FT_Int32 x, + FT_Int32 y, + FT_Int64 *z ) + { + FT_Int32 s; + + + s = x; x = ABS( x ); + s ^= y; y = ABS( y ); + + ft_multo64( x, y, z ); + + if ( s < 0 ) + { + z->lo = (FT_UInt32)-(FT_Int32)z->lo; + z->hi = ~z->hi + !( z->lo ); + } + } + + + /* documentation is in ftcalc.h */ + + /* apparently, the second version of this code is not compiled correctly */ + /* on Mac machines with the MPW C compiler.. tsss, tsss, tss... */ + +#if 1 + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q, r, i, lo; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = x->lo / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + r = x->hi; + lo = x->lo; + + if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ + return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); + /* Return Max/Min Int32 if division overflow. */ + /* This includes division by zero! */ + q = 0; + for ( i = 0; i < 32; i++ ) + { + r <<= 1; + q <<= 1; + r |= lo >> 31; + + if ( r >= (FT_UInt32)y ) + { + r -= y; + q |= 1; + } + lo <<= 1; + } + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#else /* 0 */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_Div64by32( FT_Int64* x, + FT_Int32 y ) + { + FT_Int32 s; + FT_UInt32 q; + + + s = x->hi; + if ( s < 0 ) + { + x->lo = (FT_UInt32)-(FT_Int32)x->lo; + x->hi = ~x->hi + !x->lo; + } + s ^= y; y = ABS( y ); + + /* Shortcut */ + if ( x->hi == 0 ) + { + if ( y > 0 ) + q = ( x->lo + ( y >> 1 ) ) / y; + else + q = 0x7FFFFFFFL; + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + + q = ft_div64by32( x->hi, x->lo, y ); + + return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); + } + +#endif /* 0 */ + + +#endif /* FT_LONG64 */ + + + /* a not-so-fast but working 16.16 fixed point square root function */ + + FT_EXPORT_DEF( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ) + { + FT_UInt32 root, rem_hi, rem_lo, test_div; + FT_Int count; + + + root = 0; + + if ( x > 0 ) + { + rem_hi = 0; + rem_lo = x; + count = 24; + do + { + rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); + rem_lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem_hi >= test_div ) + { + rem_hi -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftdbgmem.c b/lib/freetype/src/base/ftdbgmem.c new file mode 100644 index 0000000..15d186a --- /dev/null +++ b/lib/freetype/src/base/ftdbgmem.c @@ -0,0 +1,718 @@ +/***************************************************************************/ +/* */ +/* ftdbgmem.c */ +/* */ +/* Memory debugger (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +#ifdef FT_DEBUG_MEMORY + + +#include <stdio.h> +#include <stdlib.h> + + + typedef struct FT_MemNodeRec_* FT_MemNode; + typedef struct FT_MemTableRec_* FT_MemTable; + +#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr )) + + typedef struct FT_MemNodeRec_ + { + FT_Byte* address; + FT_Long size; /* < 0 if the block was freed */ + + const char* alloc_file_name; + FT_Long alloc_line_no; + + const char* free_file_name; + FT_Long free_line_no; + + FT_MemNode link; + + } FT_MemNodeRec; + + + typedef struct FT_MemTableRec_ + { + FT_ULong size; + FT_ULong nodes; + FT_MemNode* buckets; + + FT_ULong alloc_total; + FT_ULong alloc_current; + FT_ULong alloc_max; + FT_ULong alloc_count; + + FT_Bool bound_total; + FT_ULong alloc_total_max; + + FT_Bool bound_count; + FT_ULong alloc_count_max; + + const char* file_name; + FT_Long line_no; + + FT_Memory memory; + FT_Pointer memory_user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + + } FT_MemTableRec; + + +#define FT_MEM_SIZE_MIN 7 +#define FT_MEM_SIZE_MAX 13845163 + +#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") + + + static const FT_UInt ft_mem_primes[] = + { + 7, + 11, + 19, + 37, + 73, + 109, + 163, + 251, + 367, + 557, + 823, + 1237, + 1861, + 2777, + 4177, + 6247, + 9371, + 14057, + 21089, + 31627, + 47431, + 71143, + 106721, + 160073, + 240101, + 360163, + 540217, + 810343, + 1215497, + 1823231, + 2734867, + 4102283, + 6153409, + 9230113, + 13845163, + }; + + + + extern void + ft_mem_debug_panic( const char* fmt, ... ) + { + va_list ap; + + + printf( "FreeType.Debug: " ); + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + printf( "\n" ); + exit( EXIT_FAILURE ); + } + + + static FT_ULong + ft_mem_closest_prime( FT_ULong num ) + { + FT_UInt i; + + + for ( i = 0; + i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) + if ( ft_mem_primes[i] > num ) + return ft_mem_primes[i]; + + return FT_MEM_SIZE_MAX; + } + + + static FT_Pointer + ft_mem_table_alloc( FT_MemTable table, + FT_Long size ) + { + FT_Memory memory = table->memory; + FT_Pointer block; + + + memory->user = table->memory_user; + block = table->alloc( memory, size ); + memory->user = table; + + return block; + } + + + static void + ft_mem_table_free( FT_MemTable table, + FT_Pointer block ) + { + FT_Memory memory = table->memory; + + + memory->user = table->memory_user; + table->free( memory, block ); + memory->user = table; + } + + + static void + ft_mem_table_resize( FT_MemTable table ) + { + FT_ULong new_size; + + + new_size = ft_mem_closest_prime( table->nodes ); + if ( new_size != table->size ) + { + FT_MemNode* new_buckets ; + FT_ULong i; + + + new_buckets = (FT_MemNode *) + ft_mem_table_alloc( table, + new_size * sizeof ( FT_MemNode ) ); + if ( new_buckets == NULL ) + return; + + FT_MEM_ZERO( new_buckets, sizeof ( FT_MemNode ) * new_size ); + + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode node, next, *pnode; + FT_ULong hash; + + + node = table->buckets[i]; + while ( node ) + { + next = node->link; + hash = FT_MEM_VAL( node->address ) % new_size; + pnode = new_buckets + hash; + + node->link = pnode[0]; + pnode[0] = node; + + node = next; + } + } + + if ( table->buckets ) + ft_mem_table_free( table, table->buckets ); + + table->buckets = new_buckets; + table->size = new_size; + } + } + + + static FT_MemTable + ft_mem_table_new( FT_Memory memory ) + { + FT_MemTable table; + + + table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); + if ( table == NULL ) + goto Exit; + + FT_MEM_ZERO( table, sizeof ( *table ) ); + + table->size = FT_MEM_SIZE_MIN; + table->nodes = 0; + + table->memory = memory; + + table->memory_user = memory->user; + + table->alloc = memory->alloc; + table->realloc = memory->realloc; + table->free = memory->free; + + table->buckets = (FT_MemNode *) + memory->alloc( memory, + table->size * sizeof ( FT_MemNode ) ); + if ( table->buckets ) + FT_MEM_ZERO( table->buckets, sizeof ( FT_MemNode ) * table->size ); + else + { + memory->free( memory, table ); + table = NULL; + } + + Exit: + return table; + } + + + static void + ft_mem_table_destroy( FT_MemTable table ) + { + FT_ULong i; + + + if ( table ) + { + FT_Long leak_count = 0; + FT_ULong leaks = 0; + + + for ( i = 0; i < table->size; i++ ) + { + FT_MemNode *pnode = table->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = 0; + + if ( node->size > 0 ) + { + printf( + "leaked memory block at address %p, size %8ld in (%s:%ld)\n", + node->address, node->size, + FT_FILENAME( node->alloc_file_name ), + node->alloc_line_no ); + + leak_count++; + leaks += node->size; + + ft_mem_table_free( table, node->address ); + } + + node->address = NULL; + node->size = 0; + + free( node ); + node = next; + } + table->buckets[i] = 0; + } + ft_mem_table_free( table, table->buckets ); + table->buckets = NULL; + + table->size = 0; + table->nodes = 0; + + printf( + "FreeType: total memory allocations = %ld\n", table->alloc_total ); + printf( + "FreeType: maximum memory footprint = %ld\n", table->alloc_max ); + + free( table ); + + if ( leak_count > 0 ) + ft_mem_debug_panic( + "FreeType: %ld bytes of memory leaked in %ld blocks\n", + leaks, leak_count ); + printf( "FreeType: No memory leaks detected!\n" ); + } + } + + + static FT_MemNode* + ft_mem_table_get_nodep( FT_MemTable table, + FT_Byte* address ) + { + FT_ULong hash; + FT_MemNode *pnode, node; + + + hash = FT_MEM_VAL( address ); + pnode = table->buckets + ( hash % table->size ); + + for (;;) + { + node = pnode[0]; + if ( !node ) + break; + + if ( node->address == address ) + break; + + pnode = &node->link; + } + return pnode; + } + + + static void + ft_mem_table_set( FT_MemTable table, + FT_Byte* address, + FT_ULong size ) + { + FT_MemNode *pnode, node; + + + if ( table ) + { + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + if ( node->size < 0 ) + { + /* this block was already freed. This means that our memory is */ + /* now completely corrupted! */ + ft_mem_debug_panic( + "memory heap corrupted (allocating freed block)" ); + } + else + { + /* this block was already allocated. This means that our memory */ + /* is also corrupted! */ + ft_mem_debug_panic( + "memory heap corrupted (re-allocating allocated block)" ); + } + } + + /* we need to create a new node in this table */ + node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); + if ( node == NULL ) + ft_mem_debug_panic( "not enough memory to run memory tests" ); + + node->address = address; + node->size = size; + + node->alloc_file_name = table->file_name; + node->alloc_line_no = table->line_no; + + node->free_file_name = NULL; + node->free_line_no = 0; + + node->link = pnode[0]; + + pnode[0] = node; + table->nodes++; + + table->alloc_total += size; + table->alloc_current += size; + if ( table->alloc_current > table->alloc_max ) + table->alloc_max = table->alloc_current; + + if ( table->nodes * 3 < table->size || + table->size * 3 < table->nodes ) + ft_mem_table_resize( table ); + } + } + + + static void + ft_mem_table_remove( FT_MemTable table, + FT_Byte* address ) + { + if ( table ) + { + FT_MemNode *pnode, node; + + + pnode = ft_mem_table_get_nodep( table, address ); + node = *pnode; + if ( node ) + { + if ( node->size < 0 ) + ft_mem_debug_panic( + "freeing memory block at %p more than once at (%s:%ld)\n" + "block allocated at (%s:%ld) and released at (%s:%ld)", + address, + FT_FILENAME( table->file_name ), table->line_no, + FT_FILENAME( node->alloc_file_name ), node->alloc_line_no, + FT_FILENAME( node->free_file_name ), node->free_line_no ); + + /* we simply invert the node's size to indicate that the node */ + /* was freed. We also change its contents. */ + FT_MEM_SET( address, 0xF3, node->size ); + + table->alloc_current -= node->size; + node->size = -node->size; + node->free_file_name = table->file_name; + node->free_line_no = table->line_no; + } + else + ft_mem_debug_panic( + "trying to free unknown block at %p in (%s:%ld)\n", + address, + FT_FILENAME( table->file_name ), table->line_no ); + } + } + + + extern FT_Pointer + ft_mem_debug_alloc( FT_Memory memory, + FT_Long size ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_Byte* block; + + + if ( size <= 0 ) + ft_mem_debug_panic( "negative block size allocation (%ld)", size ); + + /* return NULL if the maximum number of allocations was reached */ + if ( table->bound_count && + table->alloc_count >= table->alloc_count_max ) + return NULL; + + /* return NULL if this allocation would overflow the maximum heap size */ + if ( table->bound_total && + table->alloc_current + (FT_ULong)size > table->alloc_total_max ) + return NULL; + + block = (FT_Byte *)ft_mem_table_alloc( table, size ); + if ( block ) + ft_mem_table_set( table, block, (FT_ULong)size ); + + table->alloc_count++; + + table->file_name = NULL; + table->line_no = 0; + + return (FT_Pointer) block; + } + + + extern void + ft_mem_debug_free( FT_Memory memory, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( block == NULL ) + ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", + FT_FILENAME( table->file_name ), + table->line_no ); + + ft_mem_table_remove( table, (FT_Byte*)block ); + + /* we never really free the block */ + table->file_name = NULL; + table->line_no = 0; + } + + + extern FT_Pointer + ft_mem_debug_realloc( FT_Memory memory, + FT_Long cur_size, + FT_Long new_size, + FT_Pointer block ) + { + FT_MemTable table = (FT_MemTable)memory->user; + FT_MemNode node, *pnode; + FT_Pointer new_block; + + const char* file_name = FT_FILENAME( table->file_name ); + FT_Long line_no = table->line_no; + + + if ( block == NULL || cur_size == 0 ) + ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", + file_name, line_no ); + + if ( new_size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", + block, cur_size, file_name, line_no ); + + /* check 'cur_size' value */ + pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); + node = *pnode; + if ( !node ) + ft_mem_debug_panic( + "trying to reallocate unknown block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size <= 0 ) + ft_mem_debug_panic( + "trying to reallocate freed block at %p in (%s:%ld)", + block, file_name, line_no ); + + if ( node->size != cur_size ) + ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " + "%ld instead of %ld in (%s:%ld)", + block, cur_size, node->size, file_name, line_no ); + + new_block = ft_mem_debug_alloc( memory, new_size ); + if ( new_block == NULL ) + return NULL; + + ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); + + table->file_name = file_name; + table->line_no = line_no; + + ft_mem_debug_free( memory, (FT_Byte*)block ); + + return new_block; + } + + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ) + { + FT_MemTable table; + FT_Int result = 0; + + + if ( getenv( "FT2_DEBUG_MEMORY" ) ) + { + table = ft_mem_table_new( memory ); + if ( table ) + { + const char* p; + + memory->user = table; + memory->alloc = ft_mem_debug_alloc; + memory->realloc = ft_mem_debug_realloc; + memory->free = ft_mem_debug_free; + + p = getenv( "FT2_ALLOC_TOTAL_MAX" ); + if ( p != NULL ) + { + FT_Long total_max = atol(p); + + if ( total_max > 0 ) + { + table->bound_total = 1; + table->alloc_total_max = (FT_ULong) total_max; + } + } + + p = getenv( "FT2_ALLOC_COUNT_MAX" ); + if ( p != NULL ) + { + FT_Long total_count = atol(p); + + if ( total_count > 0 ) + { + table->bound_count = 1; + table->alloc_count_max = (FT_ULong) total_count; + } + } + + result = 1; + } + } + return result; + } + + + extern void + ft_mem_debug_done( FT_Memory memory ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + memory->free = table->free; + memory->realloc = table->realloc; + memory->alloc = table->alloc; + + ft_mem_table_destroy( table ); + memory->user = NULL; + } + } + + + FT_BASE_DEF( FT_Error ) + FT_Alloc_Debug( FT_Memory memory, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + table->file_name = file_name; + table->line_no = line_no; + } + return FT_Alloc( memory, size, P ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Realloc_Debug( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + table->file_name = file_name; + table->line_no = line_no; + } + return FT_Realloc( memory, current, size, P ); + } + + + FT_BASE_DEF( void ) + FT_Free_Debug( FT_Memory memory, + FT_Pointer block, + const char* file_name, + FT_Long line_no ) + { + FT_MemTable table = (FT_MemTable)memory->user; + + + if ( table ) + { + table->file_name = file_name; + table->line_no = line_no; + } + FT_Free( memory, (void **)block ); + } + + +#else /* !FT_DEBUG_MEMORY */ + + /* ANSI C doesn't like empty source files */ + const FT_Byte _debug_mem_dummy = 0; + +#endif /* !FT_DEBUG_MEMORY */ + + +/* END */ diff --git a/lib/freetype/src/base/ftdebug.c b/lib/freetype/src/base/ftdebug.c new file mode 100644 index 0000000..48a2143 --- /dev/null +++ b/lib/freetype/src/base/ftdebug.c @@ -0,0 +1,197 @@ +/***************************************************************************/ +/* */ +/* ftdebug.c */ +/* */ +/* Debugging and logging component (body). */ +/* */ +/* Copyright 1996-2001 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). */ + /* */ + /* - error mode */ + /* */ + /* Only error messages are generated. */ + /* */ + /* - release mode: */ + /* */ + /* No error message is sent or generated. The code is free from any */ + /* debugging parts. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H + + +#if defined( FT_DEBUG_LEVEL_ERROR ) + + FT_EXPORT_DEF( void ) + FT_Message( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + } + + + FT_EXPORT_DEF( void ) + FT_Panic( const char* fmt, ... ) + { + va_list ap; + + + va_start( ap, fmt ); + vprintf( fmt, ap ); + va_end( ap ); + + exit( EXIT_FAILURE ); + } + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + +#ifdef FT_DEBUG_LEVEL_TRACE + + /* array of trace levels, initialized to 0 */ + int ft_trace_levels[trace_count]; + + /* define array of trace toggle names */ +#define FT_TRACE_DEF(x) #x , + + static const char* ft_trace_toggles[trace_count + 1] = + { +#include FT_INTERNAL_TRACE_H + NULL + }; + +#undef FT_TRACE_DEF + + + /*************************************************************************/ + /* */ + /* Initialize the tracing sub-system. This is done by retrieving the */ + /* value of the "FT2_DEBUG" environment variable. It must be a list of */ + /* toggles, separated by spaces, `;' or `,'. Example: */ + /* */ + /* "any:3 memory:6 stream:5" */ + /* */ + /* This will request that all levels be set to 3, except the trace level */ + /* for the memory and stream components which are set to 6 and 5, */ + /* respectively. */ + /* */ + /* See the file <freetype/internal/fttrace.h> for details of the */ + /* available toggle names. */ + /* */ + /* The level must be between 0 and 6; 0 means quiet (except for serious */ + /* runtime errors), and 6 means _very_ verbose. */ + /* */ + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + const char* ft2_debug = getenv( "FT2_DEBUG" ); + + if ( ft2_debug ) + { + const char* p = ft2_debug; + const char* q; + + + for ( ; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) + continue; + + /* read toggle name, followed by ':' */ + q = p; + while ( *p && *p != ':' ) + p++; + + if ( *p == ':' && p > q ) + { + FT_Int n, i, len = (FT_Int)(p - q); + FT_Int level = -1, found = -1; + + + for ( n = 0; n < trace_count; n++ ) + { + const char* toggle = ft_trace_toggles[n]; + + + for ( i = 0; i < len; i++ ) + { + if ( toggle[i] != q[i] ) + break; + } + + if ( i == len && toggle[i] == 0 ) + { + found = n; + break; + } + } + + /* read level */ + p++; + if ( *p ) + { + level = *p++ - '0'; + if ( level < 0 || level > 6 ) + level = -1; + } + + if ( found >= 0 && level >= 0 ) + { + if ( found == trace_any ) + { + /* special case for "any" */ + for ( n = 0; n < trace_count; n++ ) + ft_trace_levels[n] = level; + } + else + ft_trace_levels[found] = level; + } + } + } + } + } + +#else /* !FT_DEBUG_LEVEL_TRACE */ + + FT_BASE_DEF( void ) + ft_debug_init( void ) + { + /* nothing */ + } + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + +/* END */ diff --git a/lib/freetype/src/base/ftexcept.c b/lib/freetype/src/base/ftexcept.c new file mode 100644 index 0000000..1b93a99 --- /dev/null +++ b/lib/freetype/src/base/ftexcept.c @@ -0,0 +1,197 @@ +#include <ft2build.h> +#include FT_EXCEPT_H + + + FT_BASE_DEF( void ) + ft_cleanup_stack_init( FT_CleanupStack stack, + FT_Memory memory ) + { + stack->chunk = &stack->chunk_0; + stack->top = stack->chunk->items; + stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE; + stack->chunk_0.link = NULL; + + stack->memory = memory; + } + + + + FT_BASE_DEF( void ) + ft_cleanup_stack_done( FT_CleanupStack stack ) + { + FT_Memory memory = stack->memory; + FT_CleanupChunk chunk, next; + + for (;;) + { + chunk = stack->chunk; + if ( chunk == &stack->chunk_0 ) + break; + + stack->chunk = chunk->link; + + FT_Free( chunk, memory ); + } + + stack->memory = NULL; + } + + + + FT_BASE_DEF( void ) + ft_cleanup_stack_push( FT_CleanupStack stack, + FT_Pointer item, + FT_CleanupFunc item_func, + FT_Pointer item_data ) + { + FT_CleanupItem top; + + + FT_ASSERT( stack && stack->chunk && stack->top ); + FT_ASSERT( item && item_func ); + + top = stack->top; + + top->item = item; + top->item_func = item_func; + top->item_data = item_data; + + top ++; + + if ( top == stack->limit ) + { + FT_CleanupChunk chunk; + + chunk = FT_QAlloc( sizeof(*chunk), stack->memory ); + + chunk->link = stack->chunk; + stack->chunk = chunk; + stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; + top = chunk->items; + } + + stack->top = top; + } + + + + FT_BASE_DEF( void ) + ft_cleanup_stack_pop( FT_CleanupStack stack, + FT_Int destroy ) + { + FT_CleanupItem top; + + + FT_ASSERT( stack && stack->chunk && stack->top ); + top = stack->top; + + if ( top == stack->chunk->items ) + { + FT_CleanupChunk chunk; + + chunk = stack->chunk; + + if ( chunk == &stack->chunk_0 ) + { + FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" )); + ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack ); + } + + chunk = chunk->link; + FT_QFree( stack->chunk, stack->memory ); + + stack->chunk = chunk; + stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; + top = stack->limit; + } + + top --; + + if ( destroy ) + top->item_func( top->item, top->item_data ); + + top->item = NULL; + top->item_func = NULL; + top->item_data = NULL; + + stack->top = top; + } + + + + FT_BASE_DEF( FT_CleanupItem ) + ft_cleanup_stack_peek( FT_CleanupStack stack ) + { + FT_CleanupItem top; + FT_CleanupChunk chunk; + + + FT_ASSERT( stack && stack->chunk && stack->top ); + + top = stack->top; + chunk = stack->chunk; + + if ( top > chunk->items ) + top--; + else + { + chunk = chunk->link; + top = NULL; + if ( chunk != NULL ) + top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1; + } + return top; + } + + + + FT_BASE_DEF( void ) + ft_xhandler_enter( FT_XHandler xhandler, + FT_Memory memory ) + { + FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); + + xhandler->previous = stack->xhandler; + xhandler->cleanup = stack->top; + xhandler->error = 0; + stack->xhandler = xhandler; + } + + + + FT_BASE_DEF( void ) + ft_xhandler_exit( FT_XHandler xhandler ) + { + FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); + + stack->xhandler = xhandler->previous; + xhandler->previous = NULL; + xhandler->error = error; + xhandler->cleanup = NULL; + } + + + + FT_BASE_DEF( void ) + ft_cleanup_throw( FT_CleanupStack stack, + FT_Error error ) + { + FT_XHandler xhandler = stack->xhandler; + + if ( xhandler == NULL ) + { + /* no exception handler was registered. this */ + /* means that we have an un-handled exception */ + /* the only thing we can do is _PANIC_ and */ + /* halt the current program.. */ + /* */ + FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" )); + ft_exit(1); + } + + /* cleanup the stack until we reach the handler's */ + /* starting stack location.. */ + + xhandler->error = error; + longmp( xhandler->jump_buffer, 1 ); + } \ No newline at end of file diff --git a/lib/freetype/src/base/ftgloadr.c b/lib/freetype/src/base/ftgloadr.c new file mode 100644 index 0000000..5a2eb51 --- /dev/null +++ b/lib/freetype/src/base/ftgloadr.c @@ -0,0 +1,361 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.c */ +/* */ +/* The FreeType glyph loader (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_MEMORY_H + +#undef FT_COMPONENT +#define FT_COMPONENT trace_gloader + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** G L Y P H L O A D E R *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* The glyph loader is a simple object which is used to load a set of */ + /* glyphs easily. It is critical for the correct loading of composites. */ + /* */ + /* Ideally, one can see it as a stack of abstract `glyph' objects. */ + /* */ + /* loader.base Is really the bottom of the stack. It describes a */ + /* single glyph image made of the juxtaposition of */ + /* several glyphs (those `in the stack'). */ + /* */ + /* loader.current Describes the top of the stack, on which a new */ + /* glyph can be loaded. */ + /* */ + /* Rewind Clears the stack. */ + /* Prepare Set up `loader.current' for addition of a new glyph */ + /* image. */ + /* Add Add the `current' glyph image to the `base' one, */ + /* and prepare for another one. */ + /* */ + /* The glyph loader is now a base object. Each driver used to */ + /* re-implement it in one way or the other, which wasted code and */ + /* energy. */ + /* */ + /*************************************************************************/ + + + /* create a new glyph loader */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ) + { + FT_GlyphLoader loader; + FT_Error error; + + + if ( !FT_NEW( loader ) ) + { + loader->memory = memory; + *aloader = loader; + } + return error; + } + + + /* rewind the glyph loader - reset counters to 0 */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + base->outline.n_points = 0; + base->outline.n_contours = 0; + base->num_subglyphs = 0; + + *current = *base; + } + + + /* reset the glyph loader, frees all allocated tables */ + /* and starts from zero */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ) + { + FT_Memory memory = loader->memory; + + + FT_FREE( loader->base.outline.points ); + FT_FREE( loader->base.outline.tags ); + FT_FREE( loader->base.outline.contours ); + FT_FREE( loader->base.extra_points ); + FT_FREE( loader->base.subglyphs ); + + loader->max_points = 0; + loader->max_contours = 0; + loader->max_subglyphs = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + /* delete a glyph loader */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ) + { + if ( loader ) + { + FT_Memory memory = loader->memory; + + + FT_GlyphLoader_Reset( loader ); + FT_FREE( loader ); + } + } + + + /* re-adjust the `current' outline fields */ + static void + FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) + { + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + + + current->points = base->points + base->n_points; + current->tags = base->tags + base->n_points; + current->contours = base->contours + base->n_contours; + + /* handle extra points table - if any */ + if ( loader->use_extra ) + loader->current.extra_points = + loader->base.extra_points + base->n_points; + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) + { + FT_Error error; + FT_Memory memory = loader->memory; + + + if ( !FT_NEW_ARRAY( loader->base.extra_points, loader->max_points ) ) + { + loader->use_extra = 1; + FT_GlyphLoader_Adjust_Points( loader ); + } + return error; + } + + + /* re-adjust the `current' subglyphs field */ + static void + FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + current->subglyphs = base->subglyphs + base->num_subglyphs; + } + + + /* Ensure that we can add `n_points' and `n_contours' to our glyph. this */ + /* function reallocates its outline tables if necessary. Note that it */ + /* DOESN'T change the number of points within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_Outline* base = &loader->base.outline; + FT_Outline* current = &loader->current.outline; + FT_Bool adjust = 1; + + FT_UInt new_max, old_max; + + + /* check points & tags */ + new_max = base->n_points + current->n_points + n_points; + old_max = loader->max_points; + + if ( new_max > old_max ) + { + new_max = ( new_max + 7 ) & -8; + + if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || + FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) + goto Exit; + + if ( loader->use_extra && + FT_RENEW_ARRAY( loader->base.extra_points, old_max, new_max ) ) + goto Exit; + + adjust = 1; + loader->max_points = new_max; + } + + /* check contours */ + old_max = loader->max_contours; + new_max = base->n_contours + current->n_contours + + n_contours; + if ( new_max > old_max ) + { + new_max = ( new_max + 3 ) & -4; + if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) + goto Exit; + + adjust = 1; + loader->max_contours = new_max; + } + + if ( adjust ) + FT_GlyphLoader_Adjust_Points( loader ); + + Exit: + return error; + } + + + /* Ensure that we can add `n_subglyphs' to our glyph. this function */ + /* reallocates its subglyphs table if necessary. Note that it DOES */ + /* NOT change the number of subglyphs within the loader! */ + /* */ + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ) + { + FT_Memory memory = loader->memory; + FT_Error error = FT_Err_Ok; + FT_UInt new_max, old_max; + + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + + new_max = base->num_subglyphs + current->num_subglyphs + n_subs; + old_max = loader->max_subglyphs; + if ( new_max > old_max ) + { + new_max = ( new_max + 1 ) & -2; + if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) + goto Exit; + + loader->max_subglyphs = new_max; + + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + Exit: + return error; + } + + + /* prepare loader for the addition of a new glyph on top of the base one */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) + { + FT_GlyphLoad current = &loader->current; + + + current->outline.n_points = 0; + current->outline.n_contours = 0; + current->num_subglyphs = 0; + + FT_GlyphLoader_Adjust_Points ( loader ); + FT_GlyphLoader_Adjust_Subglyphs( loader ); + } + + + /* add current glyph to the base image - and prepare for another */ + FT_BASE_DEF( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ) + { + FT_GlyphLoad base = &loader->base; + FT_GlyphLoad current = &loader->current; + + FT_UInt n_curr_contours = current->outline.n_contours; + FT_UInt n_base_points = base->outline.n_points; + FT_UInt n; + + + base->outline.n_points = + (short)( base->outline.n_points + current->outline.n_points ); + base->outline.n_contours = + (short)( base->outline.n_contours + current->outline.n_contours ); + + base->num_subglyphs += current->num_subglyphs; + + /* adjust contours count in newest outline */ + for ( n = 0; n < n_curr_contours; n++ ) + current->outline.contours[n] = + (short)( current->outline.contours[n] + n_base_points ); + + /* prepare for another new glyph image */ + FT_GlyphLoader_Prepare( loader ); + } + + + FT_BASE_DEF( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ) + { + FT_Error error; + FT_UInt num_points = source->base.outline.n_points; + FT_UInt num_contours = source->base.outline.n_contours; + + + error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); + if ( !error ) + { + FT_Outline* out = &target->base.outline; + FT_Outline* in = &source->base.outline; + + + FT_MEM_COPY( out->points, in->points, + num_points * sizeof ( FT_Vector ) ); + FT_MEM_COPY( out->tags, in->tags, + num_points * sizeof ( char ) ); + FT_MEM_COPY( out->contours, in->contours, + num_contours * sizeof ( short ) ); + + /* do we need to copy the extra points? */ + if ( target->use_extra && source->use_extra ) + FT_MEM_COPY( target->base.extra_points, source->base.extra_points, + num_points * sizeof ( FT_Vector ) ); + + out->n_points = (short)num_points; + out->n_contours = (short)num_contours; + + FT_GlyphLoader_Adjust_Points( target ); + } + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftglyph.c b/lib/freetype/src/base/ftglyph.c new file mode 100644 index 0000000..dbd31ea --- /dev/null +++ b/lib/freetype/src/base/ftglyph.c @@ -0,0 +1,684 @@ +/***************************************************************************/ +/* */ +/* ftglyph.c */ +/* */ +/* FreeType convenience functions to handle glyphs (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_glyph + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** Convenience functions ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ) + { + FT_Fixed xx, xy, yx, yy; + + + if ( !a || !b ) + return; + + xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); + xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); + yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); + yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + + b->xx = xx; b->xy = xy; + b->yx = yx; b->yy = yy; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ) + { + FT_Pos delta, xx, yy; + + + if ( !matrix ) + return FT_Err_Invalid_Argument; + + /* compute discriminant */ + delta = FT_MulFix( matrix->xx, matrix->yy ) - + FT_MulFix( matrix->xy, matrix->yx ); + + if ( !delta ) + return FT_Err_Invalid_Argument; /* matrix can't be inverted */ + + matrix->xy = - FT_DivFix( matrix->xy, delta ); + matrix->yx = - FT_DivFix( matrix->yx, delta ); + + xx = matrix->xx; + yy = matrix->yy; + + matrix->xx = FT_DivFix( yy, delta ); + matrix->yy = FT_DivFix( xx, delta ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_BitmapGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + ft_bitmap_copy( FT_Memory memory, + FT_Bitmap* source, + FT_Bitmap* target ) + { + FT_Error error; + FT_Int pitch = source->pitch; + FT_ULong size; + + + *target = *source; + + if ( pitch < 0 ) + pitch = -pitch; + + size = (FT_ULong)( pitch * source->rows ); + + if ( !FT_ALLOC( target->buffer, size ) ) + FT_MEM_COPY( target->buffer, source->buffer, size ); + + return error; + } + + + static FT_Error + ft_bitmap_glyph_init( FT_BitmapGlyph glyph, + FT_GlyphSlot slot ) + { + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH(glyph)->library; + FT_Memory memory = library->memory; + + + if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + /* grab the bitmap in the slot - do lazy copying whenever possible */ + glyph->bitmap = slot->bitmap; + glyph->left = slot->bitmap_left; + glyph->top = slot->bitmap_top; + + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + slot->flags &= ~FT_GLYPH_OWN_BITMAP; + else + { + /* copy the bitmap into a new buffer */ + error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap ); + } + + Exit: + return error; + } + + + static FT_Error + ft_bitmap_glyph_copy( FT_BitmapGlyph source, + FT_BitmapGlyph target ) + { + FT_Memory memory = source->root.library->memory; + + + target->left = source->left; + target->top = source->top; + + return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap ); + } + + + static void + ft_bitmap_glyph_done( FT_BitmapGlyph glyph ) + { + FT_Memory memory = FT_GLYPH(glyph)->library->memory; + + + FT_FREE( glyph->bitmap.buffer ); + } + + + static void + ft_bitmap_glyph_bbox( FT_BitmapGlyph glyph, + FT_BBox* cbox ) + { + cbox->xMin = glyph->left << 6; + cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); + cbox->yMax = glyph->top << 6; + cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); + } + + + const FT_Glyph_Class ft_bitmap_glyph_class = + { + sizeof( FT_BitmapGlyphRec ), + FT_GLYPH_FORMAT_BITMAP, + + (FT_Glyph_InitFunc) ft_bitmap_glyph_init, + (FT_Glyph_DoneFunc) ft_bitmap_glyph_done, + (FT_Glyph_CopyFunc) ft_bitmap_glyph_copy, + (FT_Glyph_TransformFunc)0, + (FT_Glyph_GetBBoxFunc) ft_bitmap_glyph_bbox, + (FT_Glyph_PrepareFunc) 0 + }; + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_OutlineGlyph support ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ft_outline_glyph_init( FT_OutlineGlyph glyph, + FT_GlyphSlot slot ) + { + FT_Error error = FT_Err_Ok; + FT_Library library = FT_GLYPH(glyph)->library; + FT_Outline* source = &slot->outline; + FT_Outline* target = &glyph->outline; + + + /* check format in glyph slot */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + /* allocate new outline */ + error = FT_Outline_New( library, source->n_points, source->n_contours, + &glyph->outline ); + if ( error ) + goto Exit; + + /* copy it */ + FT_MEM_COPY( target->points, source->points, + source->n_points * sizeof ( FT_Vector ) ); + + FT_MEM_COPY( target->tags, source->tags, + source->n_points * sizeof ( FT_Byte ) ); + + FT_MEM_COPY( target->contours, source->contours, + source->n_contours * sizeof ( FT_Short ) ); + + /* copy all flags, except the `FT_OUTLINE_OWNER' one */ + target->flags = source->flags | FT_OUTLINE_OWNER; + + Exit: + return error; + } + + + static void + ft_outline_glyph_done( FT_OutlineGlyph glyph ) + { + FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); + } + + + static FT_Error + ft_outline_glyph_copy( FT_OutlineGlyph source, + FT_OutlineGlyph target ) + { + FT_Error error; + FT_Library library = FT_GLYPH( source )->library; + + + error = FT_Outline_New( library, source->outline.n_points, + source->outline.n_contours, &target->outline ); + if ( !error ) + FT_Outline_Copy( &source->outline, &target->outline ); + + return error; + } + + + static void + ft_outline_glyph_transform( FT_OutlineGlyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ) + { + if ( matrix ) + FT_Outline_Transform( &glyph->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); + } + + + static void + ft_outline_glyph_bbox( FT_OutlineGlyph glyph, + FT_BBox* bbox ) + { + FT_Outline_Get_CBox( &glyph->outline, bbox ); + } + + + static FT_Error + ft_outline_glyph_prepare( FT_OutlineGlyph glyph, + FT_GlyphSlot slot ) + { + slot->format = FT_GLYPH_FORMAT_OUTLINE; + slot->outline = glyph->outline; + slot->outline.flags &= ~FT_OUTLINE_OWNER; + + return FT_Err_Ok; + } + + + const FT_Glyph_Class ft_outline_glyph_class = + { + sizeof( FT_OutlineGlyphRec ), + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Glyph_InitFunc) ft_outline_glyph_init, + (FT_Glyph_DoneFunc) ft_outline_glyph_done, + (FT_Glyph_CopyFunc) ft_outline_glyph_copy, + (FT_Glyph_TransformFunc)ft_outline_glyph_transform, + (FT_Glyph_GetBBoxFunc) ft_outline_glyph_bbox, + (FT_Glyph_PrepareFunc) ft_outline_glyph_prepare + }; + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** FT_Glyph class and API ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + ft_new_glyph( FT_Library library, + const FT_Glyph_Class* clazz, + FT_Glyph* aglyph ) + { + FT_Memory memory = library->memory; + FT_Error error; + FT_Glyph glyph; + + + *aglyph = 0; + + if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) + { + glyph->library = library; + glyph->clazz = clazz; + glyph->format = clazz->glyph_format; + + *aglyph = glyph; + } + + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ) + { + FT_Glyph copy; + FT_Error error; + const FT_Glyph_Class* clazz; + + + /* check arguments */ + if ( !target || !source || !source->clazz ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + *target = 0; + + clazz = source->clazz; + error = ft_new_glyph( source->library, clazz, © ); + if ( error ) + goto Exit; + + copy->advance = source->advance; + copy->format = source->format; + + if ( clazz->glyph_copy ) + error = clazz->glyph_copy( source, copy ); + + if ( error ) + FT_Done_Glyph( copy ); + else + *target = copy; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ) + { + FT_Library library = slot->library; + FT_Error error; + FT_Glyph glyph; + + const FT_Glyph_Class* clazz = 0; + + + if ( !slot ) + return FT_Err_Invalid_Slot_Handle; + + if ( !aglyph ) + return FT_Err_Invalid_Argument; + + /* if it is a bitmap, that's easy :-) */ + if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) + clazz = &ft_bitmap_glyph_class; + + /* it it is an outline too */ + else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + clazz = &ft_outline_glyph_class; + + else + { + /* try to find a renderer that supports the glyph image format */ + FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); + + + if ( render ) + clazz = &render->glyph_class; + } + + if ( !clazz ) + { + error = FT_Err_Invalid_Glyph_Format; + goto Exit; + } + + /* create FT_Glyph object */ + error = ft_new_glyph( library, clazz, &glyph ); + if ( error ) + goto Exit; + + /* copy advance while converting it to 16.16 format */ + glyph->advance.x = slot->advance.x << 10; + glyph->advance.y = slot->advance.y << 10; + + /* now import the image from the glyph slot */ + error = clazz->glyph_init( glyph, slot ); + + /* if an error occurred, destroy the glyph */ + if ( error ) + FT_Done_Glyph( glyph ); + else + *aglyph = glyph; + + Exit: + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ) + { + const FT_Glyph_Class* clazz; + FT_Error error = FT_Err_Ok; + + + if ( !glyph || !glyph->clazz ) + error = FT_Err_Invalid_Argument; + else + { + clazz = glyph->clazz; + if ( clazz->glyph_transform ) + { + /* transform glyph image */ + clazz->glyph_transform( glyph, matrix, delta ); + + /* transform advance vector */ + if ( matrix ) + FT_Vector_Transform( &glyph->advance, matrix ); + } + else + error = FT_Err_Invalid_Glyph_Format; + } + return error; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ) + { + const FT_Glyph_Class* clazz; + + + if ( !acbox ) + return; + + acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; + + if ( !glyph || !glyph->clazz ) + return; + else + { + clazz = glyph->clazz; + if ( !clazz->glyph_bbox ) + return; + else + { + /* retrieve bbox in 26.6 coordinates */ + clazz->glyph_bbox( glyph, acbox ); + + /* perform grid fitting if needed */ + if ( bbox_mode & ft_glyph_bbox_gridfit ) + { + acbox->xMin &= -64; + acbox->yMin &= -64; + acbox->xMax = ( acbox->xMax + 63 ) & -64; + acbox->yMax = ( acbox->yMax + 63 ) & -64; + } + + /* convert to integer pixels if needed */ + if ( bbox_mode & ft_glyph_bbox_truncate ) + { + acbox->xMin >>= 6; + acbox->yMin >>= 6; + acbox->xMax >>= 6; + acbox->yMax >>= 6; + } + } + } + return; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ) + { + FT_GlyphSlotRec dummy; + FT_Error error = FT_Err_Ok; + FT_Glyph glyph; + FT_BitmapGlyph bitmap = NULL; + + const FT_Glyph_Class* clazz; + + + /* check argument */ + if ( !the_glyph ) + goto Bad; + + /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ + /* then calling FT_Render_Glyph_Internal() */ + + glyph = *the_glyph; + if ( !glyph ) + goto Bad; + + clazz = glyph->clazz; + + /* when called with a bitmap glyph, do nothing and return succesfully */ + if ( clazz == &ft_bitmap_glyph_class ) + goto Exit; + + if ( !clazz || !clazz->glyph_prepare ) + goto Bad; + + FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); + dummy.library = glyph->library; + dummy.format = clazz->glyph_format; + + /* create result bitmap glyph */ + error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, + (FT_Glyph*)&bitmap ); + if ( error ) + goto Exit; + +#if 0 + /* if `origin' is set, translate the glyph image */ + if ( origin ) + FT_Glyph_Transform( glyph, 0, origin ); +#else + FT_UNUSED( origin ); +#endif + + /* prepare dummy slot for rendering */ + error = clazz->glyph_prepare( glyph, &dummy ); + if ( !error ) + error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); + +#if 0 + if ( !destroy && origin ) + { + FT_Vector v; + + + v.x = -origin->x; + v.y = -origin->y; + FT_Glyph_Transform( glyph, 0, &v ); + } +#endif + + if ( error ) + goto Exit; + + /* in case of success, copy the bitmap to the glyph bitmap */ + error = ft_bitmap_glyph_init( bitmap, &dummy ); + if ( error ) + goto Exit; + + /* copy advance */ + bitmap->root.advance = glyph->advance; + + if ( destroy ) + FT_Done_Glyph( glyph ); + + *the_glyph = FT_GLYPH( bitmap ); + + Exit: + if ( error && bitmap ) + FT_Done_Glyph( FT_GLYPH( bitmap ) ); + + return error; + + Bad: + error = FT_Err_Invalid_Argument; + goto Exit; + } + + + /* documentation is in ftglyph.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Glyph( FT_Glyph glyph ) + { + if ( glyph ) + { + FT_Memory memory = glyph->library->memory; + const FT_Glyph_Class* clazz = glyph->clazz; + + + if ( clazz->glyph_done ) + clazz->glyph_done( glyph ); + + FT_FREE( glyph ); + } + } + + +/* END */ diff --git a/lib/freetype/src/base/fthash.c b/lib/freetype/src/base/fthash.c new file mode 100644 index 0000000..c42b1dc --- /dev/null +++ b/lib/freetype/src/base/fthash.c @@ -0,0 +1,246 @@ +#include <ft2build.h> +#include FT_TYPES_H +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H + +#define FT_HASH_MAX_LOAD 2 +#define FT_HASH_MIN_LOAD 1 +#define FT_HASH_SUB_LOAD (FT_HASH_MAX_LOAD-FT_HASH_MIN_LOAD) + +/* this one _must_ be a power of 2 !! */ +#define FT_HASH_INITIAL_SIZE 8 + + + FT_BASE_DEF( void ) + ft_hash_done( FT_Hash table, + FT_Hash_ForeachFunc node_func, + const FT_Pointer node_data ) + { + if ( table ) + { + FT_Memory memory = table->memory; + + if ( node_func ) + ft_hash_foreach( table, node_func, node_data ); + + FT_FREE( table->buckets ); + table->p = 0; + table->mask = 0; + table->slack = 0; + + table->node_equal = NULL; + } + } + + + FT_BASE_DEF( FT_UInt ) + ft_hash_get_size( FT_Hash table ) + { + FT_UInt result = 0; + + if ( table ) + result = (table->p + table->mask + 1)*FT_HASH_MAX_LOAD - table->slack; + + return result; + } + + + + FT_BASE_DEF( FT_Error ) + ft_hash_init( FT_Hash table, + FT_Hash_EqualFunc equal, + FT_Memory memory ) + { + FT_Error error; + + table->memory = memory; + table->p = 0; + table->mask = FT_HASH_INITIAL_SIZE-1; + table->slack = FT_HASH_INITIAL_SIZE*FT_HASH_MAX_LOAD; + table->node_equal = equal; + + (void)FT_NEW_ARRAY( table->buckets, FT_HASH_INITIAL_SIZE*2 ); + + return error; + } + + + + FT_BASE_DEF( void ) + ft_hash_foreach( FT_Hash table, + FT_Hash_ForeachFunc foreach_func, + const FT_Pointer foreach_data ) + { + FT_UInt count = table->p + table->mask + 1; + FT_HashNode* pnode = table->buckets; + FT_HashNode node, next; + + for ( ; count > 0; count--, pnode++ ) + { + node = *pnode; + while ( node ) + { + next = node->link; + foreach_func( node, foreach_data ); + node = next; + } + } + } + + + + FT_BASE_DEF( FT_HashLookup ) + ft_hash_lookup( FT_Hash table, + FT_HashNode keynode ) + { + FT_UInt index; + FT_UInt32 hash = keynode->hash; + FT_HashNode node, *pnode; + + index = (FT_UInt)(hash & table->mask); + if ( index < table->p ) + index = (FT_UInt)(hash & (2*table->mask+1)); + + pnode = &table->buckets[index]; + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash == hash && table->node_equal( node, keynode ) ) + break; + + pnode = &node->link; + } + + return pnode; + } + + + + + FT_BASE_DEF( FT_Error ) + ft_hash_add( FT_Hash table, + FT_HashLookup lookup, + FT_HashNode new_node ) + { + FT_Error error = 0; + + /* add it to the hash table */ + new_node->link = *lookup; + *lookup = new_node; + + if ( --table->slack < 0 ) + { + FT_UInt p = table->p; + FT_UInt mask = table->mask; + FT_HashNode new_list, node, *pnode; + + /* split a single bucket */ + new_list = NULL; + pnode = table->buckets + p; + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash & mask ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } + + table->buckets[ p + mask + 1 ] = new_list; + + table->slack += FT_HASH_MAX_LOAD; + + if ( p >= mask ) + { + FT_Memory memory = table->memory; + + + if (FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1)*4 )) + goto Exit; + + table->mask = 2*mask + 1; + table->p = 0; + } + else + table->p = p + 1; + } + Exit: + return error; + } + + + + FT_BASE_DEF( FT_Error ) + ft_hash_remove( FT_Hash table, + FT_HashLookup lookup ) + { + FT_HashNode node; + FT_UInt num_buckets; + FT_Error error = 0; + + FT_ASSERT( pnode != NULL && node != NULL ); + + node = *lookup; + *lookup = node->link; + node->link = NULL; + + num_buckets = ( table->p + table->mask + 1) ; + + if ( ++ table->slack > (FT_Long)num_buckets*FT_HASH_SUB_LOAD ) + { + FT_UInt p = table->p; + FT_UInt mask = table->mask; + FT_UInt old_index = p + mask; + FT_HashNode* pnode; + FT_HashNode* pold; + + if ( old_index < FT_HASH_INITIAL_SIZE ) + goto Exit; + + if ( p == 0 ) + { + FT_Memory memory = table->memory; + + table->mask >>= 1; + p = table->mask; + + if ( FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1) ) ) + { + /* this should never happen normally, but who knows :-) */ + /* we need to re-inject the node in the hash table before */ + /* returning there, since it's safer */ + pnode = table->buckets; + node->link = *pnode; + *pnode = node; + + goto Exit; + } + } + else + p--; + + pnode = table->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = table->buckets + old_index; + *pnode = *pold; + *pold = NULL; + + table->slack -= FT_HASH_MAX_LOAD; + table->p = p; + } + Exit: + return error; + } diff --git a/lib/freetype/src/base/ftinit.c b/lib/freetype/src/base/ftinit.c new file mode 100644 index 0000000..79ba9f0 --- /dev/null +++ b/lib/freetype/src/base/ftinit.c @@ -0,0 +1,161 @@ +/***************************************************************************/ +/* */ +/* ftinit.c */ +/* */ +/* FreeType initialization layer (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 purpose of this file is to implement the following two */ + /* functions: */ + /* */ + /* FT_Add_Default_Modules(): */ + /* This function is used to add the set of default modules to a */ + /* fresh new library object. The set is taken from the header file */ + /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ + /* Build System' for more information. */ + /* */ + /* FT_Init_FreeType(): */ + /* This function creates a system object for the current platform, */ + /* builds a library out of it, then calls FT_Default_Drivers(). */ + /* */ + /* Note that even if FT_Init_FreeType() uses the implementation of the */ + /* system object defined at build time, client applications are still */ + /* able to provide their own `ftsystem.c'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_MODULE_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_init + +#undef FT_USE_MODULE +#ifdef __cplusplus +#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class* x; +#else +#define FT_USE_MODULE( x ) extern const FT_Module_Class* x; +#endif + + +#include FT_CONFIG_MODULES_H + + +#undef FT_USE_MODULE +#define FT_USE_MODULE( x ) (const FT_Module_Class*)&x, + + static + const FT_Module_Class* const ft_default_modules[] = + { +#include FT_CONFIG_MODULES_H + 0 + }; + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( void ) + FT_Add_Default_Modules( FT_Library library ) + { + FT_Error error; + const FT_Module_Class* const* cur; + + + /* test for valid `library' delayed to FT_Add_Module() */ + + cur = ft_default_modules; + while ( *cur ) + { + error = FT_Add_Module( library, *cur ); + /* notify errors, but don't stop */ + if ( error ) + { + FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n", + (*cur)->module_name, error )); + } + cur++; + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ) + { + FT_Error error; + FT_Memory memory; + + + /* First of all, allocate a new system object -- this function is part */ + /* of the system-specific component, i.e. `ftsystem.c'. */ + + memory = FT_New_Memory(); + if ( !memory ) + { + FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); + return FT_Err_Unimplemented_Feature; + } + + /* build a library out of it, then fill it with the set of */ + /* default drivers. */ + + error = FT_New_Library( memory, alibrary ); + if ( !error ) + { + (*alibrary)->version_major = FREETYPE_MAJOR; + (*alibrary)->version_minor = FREETYPE_MINOR; + (*alibrary)->version_patch = FREETYPE_PATCH; + + FT_Add_Default_Modules( *alibrary ); + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_FreeType( FT_Library library ) + { + if ( library ) + { + FT_Memory memory = library->memory; + + + /* Discard the library object */ + FT_Done_Library( library ); + + /* discard memory manager */ + FT_Done_Memory( memory ); + } + + return FT_Err_Ok; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftlist.c b/lib/freetype/src/base/ftlist.c new file mode 100644 index 0000000..52687b3 --- /dev/null +++ b/lib/freetype/src/base/ftlist.c @@ -0,0 +1,217 @@ +/***************************************************************************/ +/* */ +/* ftlist.c */ +/* */ +/* Generic list support for FreeType (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 implements functions relative to list processing. Its */ + /* data structures are defined in `freetype/internal/ftlist.h'. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_LIST_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_list + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + if ( cur->data == data ) + return cur; + + cur = cur->next; + } + + return (FT_ListNode)0; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Add( FT_List list, + FT_ListNode node ) + { + FT_ListNode before = list->tail; + + + node->next = 0; + node->prev = before; + + if ( before ) + before->next = node; + else + list->head = node; + + list->tail = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ) + { + FT_ListNode after = list->head; + + + node->next = after; + node->prev = 0; + + if ( !after ) + list->tail = node; + else + after->prev = node; + + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + if ( before ) + before->next = after; + else + list->head = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Up( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + /* check whether we are already on top of the list */ + if ( !before ) + return; + + before->next = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + + node->prev = 0; + node->next = list->head; + list->head->prev = node; + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) + { + FT_ListNode cur = list->head; + FT_Error error = FT_Err_Ok; + + + while ( cur ) + { + FT_ListNode next = cur->next; + + + error = iterator( cur, user ); + if ( error ) + break; + + cur = next; + } + + return error; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + FT_ListNode next = cur->next; + void* data = cur->data; + + + if ( destroy ) + destroy( memory, data, user ); + + FT_FREE( cur ); + cur = next; + } + + list->head = 0; + list->tail = 0; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftmac.c b/lib/freetype/src/base/ftmac.c new file mode 100644 index 0000000..2d37d39 --- /dev/null +++ b/lib/freetype/src/base/ftmac.c @@ -0,0 +1,919 @@ +/***************************************************************************/ +/* */ +/* ftmac.c */ +/* */ +/* Mac FOND support. Written by just@letterror.com. */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* Just van Rossum, 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 + + Mac suitcase files can (and often do!) contain multiple fonts. To + support this I use the face_index argument of FT_(Open|New)_Face() + functions, and pretend the suitcase file is a collection. + + Warning: Although the FOND driver sets face->num_faces field to the + number of available fonts, but the Type 1 driver sets it to 1 anyway. + So this field is currently not reliable, and I don't see a clean way + to resolve that. The face_index argument translates to + + Get1IndResource( 'FOND', face_index + 1 ); + + so clients should figure out the resource index of the FOND. + (I'll try to provide some example code for this at some point.) + + The Mac FOND support works roughly like this: + + - Check whether the offered stream points to a Mac suitcase file. + This is done by checking the file type: it has to be 'FFIL' or 'tfil'. + The stream that gets passed to our init_face() routine is a stdio + stream, which isn't usable for us, since the FOND resources live + in the resource fork. So we just grab the stream->pathname field. + + - Read the FOND resource into memory, then check whether there is + a TrueType font and/or(!) a Type 1 font available. + + - If there is a Type 1 font available (as a separate 'LWFN' file), + read its data into memory, massage it slightly so it becomes + PFB data, wrap it into a memory stream, load the Type 1 driver + and delegate the rest of the work to it by calling FT_Open_Face(). + (XXX TODO: after this has been done, the kerning data from the FOND + resource should be appended to the face: On the Mac there are usually + no AFM files available. However, this is tricky since we need to map + Mac char codes to ps glyph names to glyph ID's...) + + - If there is a TrueType font (an 'sfnt' resource), read it into + memory, wrap it into a memory stream, load the TrueType driver + and delegate the rest of the work to it, by calling FT_Open_Face(). + */ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_STREAM_H +#include "truetype/ttobjs.h" +#include "type1/t1objs.h" + +#include <Resources.h> +#include <Fonts.h> +#include <Errors.h> +#include <Files.h> +#include <TextUtils.h> + + +#include FT_MAC_H + + + /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over + TrueType in case *both* are available (this is not common, + but it *is* possible). */ +#ifndef PREFER_LWFN +#define PREFER_LWFN 1 +#endif + + /* Given a pathname, fill in a file spec. */ + static int + file_spec_from_path( const char* pathname, + FSSpec* spec ) + { +#if TARGET_API_MAC_CARBON + + OSErr e; + FSRef ref; + + + e = FSPathMakeRef( (UInt8 *)pathname, &ref, false /* not a directory */ ); + if ( e == noErr ) + e = FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL, spec, NULL ); + + return ( e == noErr ) ? 0 : (-1); + +#else + + Str255 p_path; + FT_ULong path_len; + + + /* convert path to a pascal string */ + path_len = ft_strlen( pathname ); + if ( path_len > 255 ) + return -1; + p_path[0] = (unsigned char)path_len; + ft_strncpy( (char*)p_path + 1, pathname, path_len ); + + if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr ) + return -1; + else + return 0; + +#endif + } + + + /* Return the file type of the file specified by spec. */ + static OSType + get_file_type( FSSpec* spec ) + { + FInfo finfo; + + + if ( FSpGetFInfo( spec, &finfo ) != noErr ) + return 0; /* file might not exist */ + + return finfo.fdType; + } + + +#if TARGET_API_MAC_CARBON + + /* is this a Mac OS X .dfont file */ + static Boolean + is_dfont( FSSpec* spec ) + { + int nameLen = spec->name[0]; + + + return nameLen >= 6 && + !memcmp( spec->name + nameLen - 5, ".dfont", 6 ); + } + +#endif + + + /* Given a PostScript font name, create the Macintosh LWFN file name. */ + static void + create_lwfn_name( char* ps_name, + Str255 lwfn_file_name ) + { + int max = 5, count = 0; + FT_Byte* p = lwfn_file_name; + FT_Byte* q = (FT_Byte*)ps_name; + + + lwfn_file_name[0] = 0; + + while ( *q ) + { + if ( isupper( *q ) ) + { + if ( count ) + max = 3; + count = 0; + } + if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) ) + { + *++p = *q; + lwfn_file_name[0]++; + count++; + } + q++; + } + } + + + /* Given a file reference, answer its location as a vRefNum + and a dirID. */ + static FT_Error + get_file_location( short ref_num, + short* v_ref_num, + long* dir_id, + unsigned char* file_name ) + { + FCBPBRec pb; + OSErr error; + + + pb.ioNamePtr = file_name; + pb.ioVRefNum = 0; + pb.ioRefNum = ref_num; + pb.ioFCBIndx = 0; + + error = PBGetFCBInfoSync( &pb ); + if ( error == noErr ) + { + *v_ref_num = pb.ioFCBVRefNum; + *dir_id = pb.ioFCBParID; + } + return error; + } + + + /* Make a file spec for an LWFN file from a FOND resource and + a file name. */ + static FT_Error + make_lwfn_spec( Handle fond, + unsigned char* file_name, + FSSpec* spec ) + { + FT_Error error; + short ref_num, v_ref_num; + long dir_id; + Str255 fond_file_name; + + + ref_num = HomeResFile( fond ); + + error = ResError(); + if ( !error ) + error = get_file_location( ref_num, &v_ref_num, + &dir_id, fond_file_name ); + if ( !error ) + error = FSMakeFSSpec( v_ref_num, dir_id, file_name, spec ); + + return error; + } + + + /* Look inside the FOND data, answer whether there should be an SFNT + resource, and answer the name of a possible LWFN Type 1 file. + + Thanks to Paul Miller (paulm@profoundeffects.com) for the fix + to load a face OTHER than the first one in the FOND! + */ + static void + parse_fond( char* fond_data, + short* have_sfnt, + short* sfnt_id, + Str255 lwfn_file_name, + short face_index ) + { + AsscEntry* assoc; + AsscEntry* base_assoc; + FamRec* fond; + + + *sfnt_id = 0; + *have_sfnt = 0; + lwfn_file_name[0] = 0; + + fond = (FamRec*)fond_data; + assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); + base_assoc = assoc; + assoc += face_index; /* add on the face_index! */ + + /* if the face at this index is not scalable, + fall back to the first one (old behavior) */ + if ( assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = assoc->fontID; + } + else if ( base_assoc->fontSize == 0 ) + { + *have_sfnt = 1; + *sfnt_id = base_assoc->fontID; + } + + if ( fond->ffStylOff ) + { + unsigned char* p = (unsigned char*)fond_data; + StyleTable* style; + unsigned short string_count; + char ps_name[256]; + unsigned char* names[64]; + int i; + + + p += fond->ffStylOff; + style = (StyleTable*)p; + p += sizeof ( StyleTable ); + string_count = *(unsigned short*)(p); + p += sizeof ( short ); + + for ( i = 0 ; i < string_count && i < 64; i++ ) + { + names[i] = p; + p += names[i][0]; + p++; + } + + { + size_t ps_name_len = (size_t)names[0][0]; + + + if ( ps_name_len != 0 ) + { + memcpy(ps_name, names[0] + 1, ps_name_len); + ps_name[ps_name_len] = 0; + } + if ( style->indexes[0] > 1 ) + { + unsigned char* suffixes = names[style->indexes[0] - 1]; + + + for ( i = 1; i < suffixes[0]; i++ ) + { + unsigned char* s; + size_t j = suffixes[i] - 1; + + + if ( j < string_count && ( s = names[j] ) != NULL ) + { + size_t s_len = (size_t)s[0]; + + + if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) + { + memcpy( ps_name + ps_name_len, s + 1, s_len ); + ps_name_len += s_len; + ps_name[ps_name_len] = 0; + } + } + } + } + } + + create_lwfn_name( ps_name, lwfn_file_name ); + } + } + + + /* Read Type 1 data from the POST resources inside the LWFN file, + return a PFB buffer. This is somewhat convoluted because the FT2 + PFB parser wants the ASCII header as one chunk, and the LWFN + chunks are often not organized that way, so we'll glue chunks + of the same type together. */ + static FT_Error + read_lwfn( FT_Memory memory, + FSSpec* lwfn_spec, + FT_Byte** pfb_data, + FT_ULong* size ) + { + FT_Error error = FT_Err_Ok; + short res_ref, res_id; + unsigned char *buffer, *p, *size_p = NULL; + FT_ULong total_size = 0; + FT_ULong post_size, pfb_chunk_size; + Handle post_data; + char code, last_code; + + + res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm ); + if ( ResError() ) + return FT_Err_Out_Of_Memory; + UseResFile( res_ref ); + + /* First pass: load all POST resources, and determine the size of + the output buffer. */ + res_id = 501; + last_code = -1; + + for (;;) + { + post_data = Get1Resource( 'POST', res_id++ ); + if ( post_data == NULL ) + break; /* we're done */ + + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( code == 5 ) + total_size += 2; /* just the end code */ + else + total_size += 6; /* code + 4 bytes chunk length */ + } + + total_size += GetHandleSize( post_data ) - 2; + last_code = code; + } + + if ( FT_ALLOC( buffer, (FT_Long)total_size ) ) + goto Error; + + /* Second pass: append all POST data to the buffer, add PFB fields. + Glue all consecutive chunks of the same type together. */ + p = buffer; + res_id = 501; + last_code = -1; + pfb_chunk_size = 0; + + for (;;) + { + post_data = Get1Resource( 'POST', res_id++ ); + if ( post_data == NULL ) + break; /* we're done */ + + post_size = (FT_ULong)GetHandleSize( post_data ) - 2; + code = (*post_data)[0]; + + if ( code != last_code ) + { + if ( last_code != -1 ) + { + /* we're done adding a chunk, fill in the size field */ + if ( size_p != NULL ) + { + *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF ); + *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF ); + } + pfb_chunk_size = 0; + } + + *p++ = 0x80; + if ( code == 5 ) + *p++ = 0x03; /* the end */ + else if ( code == 2 ) + *p++ = 0x02; /* binary segment */ + else + *p++ = 0x01; /* ASCII segment */ + + if ( code != 5 ) + { + size_p = p; /* save for later */ + p += 4; /* make space for size field */ + } + } + + ft_memcpy( p, *post_data + 2, post_size ); + pfb_chunk_size += post_size; + p += post_size; + last_code = code; + } + + *pfb_data = buffer; + *size = total_size; + + Error: + CloseResFile( res_ref ); + return error; + } + + + /* Finalizer for a memory stream; gets called by FT_Done_Face(). + It frees the memory it uses. */ + static void + memory_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = 0; + stream->close = 0; + } + + + /* Create a new memory stream from a buffer and a size. */ + static FT_Error + new_memory_stream( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Stream_CloseFunc close, + FT_Stream *astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !base ) + return FT_Err_Invalid_Argument; + + *astream = 0; + memory = library->memory; + if ( FT_NEW( stream ) ) + goto Exit; + + FT_Stream_OpenMemory( stream, base, size ); + + stream->close = close; + + *astream = stream; + + Exit: + return error; + } + + + /* Create a new FT_Face given a buffer and a driver name. */ + static FT_Error + open_face_from_buffer( FT_Library library, + FT_Byte* base, + FT_ULong size, + FT_Long face_index, + char* driver_name, + FT_Face *aface ) + { + FT_Open_Args args; + FT_Error error; + FT_Stream stream; + FT_Memory memory = library->memory; + + + error = new_memory_stream( library, + base, + size, + memory_stream_close, + &stream ); + if ( error ) + { + FT_FREE( base ); + return error; + } + + args.flags = FT_OPEN_STREAM; + args.stream = stream; + if ( driver_name ) + { + args.flags = args.flags | FT_OPEN_DRIVER; + args.driver = FT_Get_Module( library, driver_name ); + } + + error = FT_Open_Face( library, &args, face_index, aface ); + if ( error == FT_Err_Ok ) + (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + else + { + FT_Stream_CloseFunc( stream ); + FT_FREE( stream ); + } + + return error; + } + + + /* Create a new FT_Face from a file spec to an LWFN file. */ + static FT_Error + FT_New_Face_From_LWFN( FT_Library library, + FSSpec* spec, + FT_Long face_index, + FT_Face *aface ) + { + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + + + error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size ); + if ( error ) + return error; + + return open_face_from_buffer( library, + pfb_data, + pfb_size, + face_index, + "type1", + aface ); + } + + + /* Create a new FT_Face from an SFNT resource, specified by res ID. */ + static FT_Error + FT_New_Face_From_SFNT( FT_Library library, + short sfnt_id, + FT_Long face_index, + FT_Face *aface ) + { + Handle sfnt = NULL; + FT_Byte* sfnt_data; + size_t sfnt_size; + FT_Error error = 0; + FT_Memory memory = library->memory; + + + sfnt = GetResource( 'sfnt', sfnt_id ); + if ( ResError() ) + return FT_Err_Invalid_Handle; + + sfnt_size = (FT_ULong)GetHandleSize( sfnt ); + if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) + { + ReleaseResource( sfnt ); + return error; + } + + HLock( sfnt ); + ft_memcpy( sfnt_data, *sfnt, sfnt_size ); + HUnlock( sfnt ); + ReleaseResource( sfnt ); + + return open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + "truetype", + aface ); + } + + + /* Create a new FT_Face from a file spec to a suitcase file. */ + static FT_Error + FT_New_Face_From_Suitcase( FT_Library library, + FSSpec* spec, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error = FT_Err_Ok; + short res_ref, res_index; + Handle fond; + + + res_ref = FSpOpenResFile( spec, fsRdPerm ); + if ( ResError() ) + return FT_Err_Cannot_Open_Resource; + UseResFile( res_ref ); + + /* face_index may be -1, in which case we + just need to do a sanity check */ + if ( face_index < 0 ) + res_index = 1; + else + { + res_index = (short)( face_index + 1 ); + face_index = 0; + } + fond = Get1IndResource( 'FOND', res_index ); + if ( ResError() ) + { + error = FT_Err_Cannot_Open_Resource; + goto Error; + } + + error = FT_New_Face_From_FOND( library, fond, face_index, aface ); + + Error: + CloseResFile( res_ref ); + return error; + } + + +#if TARGET_API_MAC_CARBON + + /* Create a new FT_Face from a file spec to a suitcase file. */ + static FT_Error + FT_New_Face_From_dfont( FT_Library library, + FSSpec* spec, + FT_Long face_index, + FT_Face* aface ) + { + FT_Error error = FT_Err_Ok; + short res_ref, res_index; + Handle fond; + FSRef hostContainerRef; + + + error = FSpMakeFSRef( spec, &hostContainerRef ); + if ( error == noErr ) + error = FSOpenResourceFile( &hostContainerRef, + 0, NULL, fsRdPerm, &res_ref ); + + if ( error != noErr ) + return FT_Err_Cannot_Open_Resource; + + UseResFile( res_ref ); + + /* face_index may be -1, in which case we + just need to do a sanity check */ + if ( face_index < 0 ) + res_index = 1; + else + { + res_index = (short)( face_index + 1 ); + face_index = 0; + } + fond = Get1IndResource( 'FOND', res_index ); + if ( ResError() ) + { + error = FT_Err_Cannot_Open_Resource; + goto Error; + } + + error = FT_New_Face_From_FOND( library, fond, face_index, aface ); + + Error: + CloseResFile( res_ref ); + return error; + } + +#endif + + + /* documentation is in ftmac.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + { + short sfnt_id, have_sfnt, have_lwfn = 0; + Str255 lwfn_file_name; + short fond_id; + OSType fond_type; + Str255 fond_name; + FSSpec lwfn_spec; + + + GetResInfo( fond, &fond_id, &fond_type, fond_name ); + if ( ResError() != noErr || fond_type != 'FOND' ) + return FT_Err_Invalid_File_Format; + + HLock( fond ); + parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); + HUnlock( fond ); + + if ( lwfn_file_name[0] ) + { + if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) + have_lwfn = 1; /* yeah, we got one! */ + else + have_lwfn = 0; /* no LWFN file found */ + } + + if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) + return FT_New_Face_From_LWFN( library, + &lwfn_spec, + face_index, + aface ); + else if ( have_sfnt ) + return FT_New_Face_From_SFNT( library, + sfnt_id, + face_index, + aface ); + + return FT_Err_Unknown_File_Format; + } + + + /* documentation is in ftmac.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_GetFile_From_Mac_Name( char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + { + OptionBits options = kFMUseGlobalScopeOption; + + FMFontFamilyIterator famIter; + OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, + options, + &famIter ); + FMFont the_font = NULL; + FMFontFamily family = NULL; + + + *face_index = 0; + while ( status == 0 && !the_font ) + { + status = FMGetNextFontFamily( &famIter, &family ); + if ( status == 0 ) + { + int stat2; + FMFontFamilyInstanceIterator instIter; + Str255 famNameStr; + char famName[256]; + + + /* get the family name */ + FMGetFontFamilyName( family, famNameStr ); + CopyPascalStringToC( famNameStr, famName ); + + /* iterate through the styles */ + FMCreateFontFamilyInstanceIterator( family, &instIter ); + + *face_index = 0; + stat2 = 0; + while ( stat2 == 0 && !the_font ) + { + FMFontStyle style; + FMFontSize size; + FMFont font; + + + stat2 = FMGetNextFontFamilyInstance( &instIter, &font, + &style, &size ); + if ( stat2 == 0 && size == 0 ) + { + char fullName[256]; + + + /* build up a complete face name */ + ft_strcpy( fullName, famName ); + if ( style & bold ) + strcat( fullName, " Bold" ); + if ( style & italic ) + strcat( fullName, " Italic" ); + + /* compare with the name we are looking for */ + if ( ft_strcmp( fullName, fontName ) == 0 ) + { + /* found it! */ + the_font = font; + } + else + ++(*face_index); + } + } + + FMDisposeFontFamilyInstanceIterator( &instIter ); + } + } + + FMDisposeFontFamilyIterator( &famIter ); + + if ( the_font ) + { + FMGetFontContainer( the_font, pathSpec ); + return FT_Err_Ok; + } + else + return FT_Err_Unknown_File_Format; + } + + + static long + ResourceForkSize(FSSpec* spec) + { + long len; + short refNum; + OSErr e; + + + e = FSpOpenRF( spec, fsRdPerm, &refNum ); /* I.M. Files 2-155 */ + if ( e == noErr ) + { + e = GetEOF( refNum, &len ); + FSClose( refNum ); + } + + return ( e == noErr ) ? len : 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This is the Mac-specific implementation of FT_New_Face. In */ + /* addition to the standard FT_New_Face() functionality, it also */ + /* accepts pathnames to Mac suitcase files. For further */ + /* documentation see the original FT_New_Face() in freetype.h. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + FSSpec spec; + OSType file_type; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_Err_Invalid_Argument; + + if ( file_spec_from_path( pathname, &spec ) ) + return FT_Err_Invalid_Argument; + + /* Regardless of type, don't try to use the resource fork if it is */ + /* empty. Some TTF fonts have type `FFIL', for example, but they */ + /* only have data forks. */ + + if ( ResourceForkSize( &spec ) != 0 ) + { + file_type = get_file_type( &spec ); + if ( file_type == 'FFIL' || file_type == 'tfil' ) + return FT_New_Face_From_Suitcase( library, &spec, face_index, aface ); + + if ( file_type == 'LWFN' ) + return FT_New_Face_From_LWFN( library, &spec, face_index, aface ); + } + +#if TARGET_API_MAC_CARBON + + if ( is_dfont( &spec ) ) + return FT_New_Face_From_dfont( library, &spec, face_index, aface ); + +#endif + + /* let it fall through to normal loader (.ttf, .otf, etc.) */ + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); + } + + +/* END */ diff --git a/lib/freetype/src/base/ftmm.c b/lib/freetype/src/base/ftmm.c new file mode 100644 index 0000000..229a043 --- /dev/null +++ b/lib/freetype/src/base/ftmm.c @@ -0,0 +1,126 @@ +/***************************************************************************/ +/* */ +/* ftmm.c */ +/* */ +/* Multiple Master font support (body). */ +/* */ +/* Copyright 1996-2001 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 <ft2build.h> +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_OBJECTS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_mm + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ) + { + FT_Error error; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + error = FT_Err_Invalid_Argument; + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_Driver driver = face->driver; + FT_Get_MM_Func func; + + + func = (FT_Get_MM_Func)driver->root.clazz->get_interface( + FT_MODULE( driver ), "get_mm" ); + if ( func ) + error = func( face, amaster ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + FT_Error error; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + error = FT_Err_Invalid_Argument; + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_Driver driver = face->driver; + FT_Set_MM_Design_Func func; + + + func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface( + FT_MODULE( driver ), "set_mm_design" ); + if ( func ) + error = func( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + error = FT_Err_Invalid_Argument; + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_Driver driver = face->driver; + FT_Set_MM_Blend_Func func; + + + func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface( + FT_MODULE( driver ), "set_mm_blend" ); + if ( func ) + error = func( face, num_coords, coords ); + } + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftnames.c b/lib/freetype/src/base/ftnames.c new file mode 100644 index 0000000..7fde5c4 --- /dev/null +++ b/lib/freetype/src/base/ftnames.c @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftnames.c */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (body). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_SFNT_NAMES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_STREAM_H + + +#ifdef TT_CONFIG_OPTION_SFNT_NAMES + + + /* documentation is in ftnames.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ) + { + return (face && FT_IS_SFNT( face )) ? ((TT_Face)face)->num_names : 0; + } + + + /* documentation is in ftnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + if ( aname && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( idx < (FT_UInt)ttface->num_names ) + { + TT_NameEntryRec* entry = ttface->name_table.names + idx; + + + /* load name on demand */ + if ( entry->stringLength > 0 && entry->string == NULL ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + aname->platform_id = entry->platformID; + aname->encoding_id = entry->encodingID; + aname->language_id = entry->languageID; + aname->name_id = entry->nameID; + aname->string = (FT_Byte*)entry->string; + aname->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + +#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ + + +/* END */ diff --git a/lib/freetype/src/base/ftobject.c b/lib/freetype/src/base/ftobject.c new file mode 100644 index 0000000..34e41e9 --- /dev/null +++ b/lib/freetype/src/base/ftobject.c @@ -0,0 +1,396 @@ +#include <ft2build.h> +#include FT_INTERNAL_OBJECT_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H + +#define FT_MAGIC_DEATH 0xDEADdead +#define FT_MAGIC_CLASS 0x12345678 + +#define FT_TYPE_HASH(x) (( (FT_UInt32)(x) >> 2 )^( (FT_UInt32)(x) >> 10 )) + +#define FT_OBJECT_CHECK(o) \ + ( FT_OBJECT(o) != NULL && \ + FT_OBJECT(o)->clazz != NULL && \ + FT_OBJECT(o)->ref_count >= 1 && \ + FT_OBJECT(o)->clazz->magic == FT_MAGIC_CLASS ) + +#define FT_CLASS_CHECK(c) \ + ( FT_CLASS(c) != NULL && FT_CLASS(c)->magic == FT_MAGIC_CLASS ) + +#define FT_ASSERT_IS_CLASS(c) FT_ASSERT( FT_CLASS_CHECK(c) ) + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** *****/ + /***** M E T A - C L A S S *****/ + /***** *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + /* forward declaration */ + FT_BASE_DEF( FT_Error ) + ft_metaclass_init( FT_MetaClass meta, + FT_Library library ); + + /* forward declaration */ + FT_BASE_DEF( void ) + ft_metaclass_done( FT_MetaClass meta ); + + + /* class type for the meta-class itself */ + static const FT_TypeRec ft_meta_class_type = + { + "FT2.MetaClass", + NULL, + + sizeof( FT_MetaClassRec ), + (FT_Object_InitFunc) ft_metaclass_init, + (FT_Object_DoneFunc) ft_metaclass_done, + + sizeof( FT_ClassRec ), + (FT_Object_InitFunc) NULL, + (FT_Object_DoneFunc) NULL + }; + + + + + /* destroy a given class */ + static void + ft_class_hnode_destroy( FT_ClassHNode node ) + { + FT_Class clazz = node->clazz; + FT_Memory memory = clazz->memory; + + if ( clazz->class_done ) + clazz->class_done( (FT_Object) clazz ); + + FT_FREE( clazz ); + + node->clazz = NULL; + node->type = NULL; + + FT_FREE( node ); + } + + + static FT_Int + ft_type_equal( FT_Type type1, + FT_Type type2 ) + { + if ( type1 == type2 ) + goto Ok; + + if ( type1 == NULL || type2 == NULL ) + goto Fail; + + /* compare parent types */ + if ( type1->super != type2->super ) + { + if ( type1->super == NULL || + type2->super == NULL || + !ft_type_equal( type1, type2 ) ) + goto Fail; + } + + /* compare type names */ + if ( type1->name != type2->name ) + { + if ( type1->name == NULL || + type2->name == NULL || + ft_strcmp( type1->name, type2->name ) != 0 ) + goto Fail; + } + + /* compare the other type fields */ + if ( type1->class_size != type2->class_size || + type1->class_init != type2->class_init || + type1->class_done != type2->class_done || + type1->obj_size != type2->obj_size || + type1->obj_init != type2->obj_init || + type1->obj_done != type2->obj_done ) + goto Fail; + + Ok: + return 1; + + Fail: + return 0; + } + + + static FT_Int + ft_class_hnode_equal( const FT_ClassHNode node1, + const FT_ClassHNode node2 ) + { + FT_Type type1 = node1->type; + FT_Type type2 = node2->type; + + /* comparing the pointers should work in 99% of cases */ + return ( type1 == type2 ) ? 1 : ft_type_equal( type1, type2 ); + } + + + FT_BASE_DEF( void ) + ft_metaclass_done( FT_MetaClass meta ) + { + /* clear all classes */ + ft_hash_done( &meta->type_to_class, + (FT_Hash_ForeachFunc) ft_class_hnode_destroy, + NULL ); + + meta->clazz.object.clazz = NULL; + meta->clazz.object.ref_count = 0; + meta->clazz.magic = FT_MAGIC_DEATH; + } + + + FT_BASE_DEF( FT_Error ) + ft_metaclass_init( FT_MetaClass meta, + FT_Library library ) + { + FT_ClassRec* clazz = (FT_ClassRec*) &meta->clazz; + + /* the meta-class is its OWN class !! */ + clazz->object.clazz = (FT_Class) clazz; + clazz->object.ref_count = 1; + clazz->magic = FT_MAGIC_CLASS; + clazz->library = library; + clazz->memory = library->memory; + clazz->type = &ft_meta_class_type; + clazz->info = NULL; + + clazz->class_done = (FT_Object_DoneFunc) ft_metaclass_done; + + clazz->obj_size = sizeof( FT_ClassRec ); + clazz->obj_init = NULL; + clazz->obj_done = NULL; + + return ft_hash_init( &meta->type_to_class, + (FT_Hash_EqualFunc) ft_class_hnode_equal, + library->memory ); + } + + + /* find or create the class corresponding to a given type */ + /* note that this function will retunr NULL in case of */ + /* memory overflow */ + /* */ + static FT_Class + ft_metaclass_get_class( FT_MetaClass meta, + FT_Type ctype ) + { + FT_ClassHNodeRec keynode, *node, **pnode; + FT_Memory memory; + FT_ClassRec* clazz; + FT_Class parent; + FT_Error error; + + keynode.hnode.hash = FT_TYPE_HASH( ctype ); + keynode.type = ctype; + + pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class, + (FT_HashNode) &keynode ); + node = *pnode; + if ( node != NULL ) + { + clazz = (FT_ClassRec*) node->clazz; + goto Exit; + } + + memory = FT_CLASS__MEMORY(meta); + clazz = NULL; + parent = NULL; + if ( ctype->super != NULL ) + { + FT_ASSERT( ctype->super->class_size <= ctype->class_size ); + FT_ASSERT( ctype->super->obj_size <= ctype->obj_size ); + + parent = ft_metaclass_get_class( meta, ctype->super ); + } + + if ( !FT_NEW( node ) ) + { + if ( !FT_ALLOC( clazz, ctype->class_size ) ) + { + if ( parent ) + FT_MEM_COPY( (FT_ClassRec*)clazz, parent, parent->type->class_size ); + + clazz->object.clazz = (FT_Class) meta; + clazz->object.ref_count = 1; + + clazz->memory = memory; + clazz->library = FT_CLASS__LIBRARY(meta); + clazz->super = parent; + clazz->type = ctype; + clazz->info = NULL; + clazz->magic = FT_MAGIC_CLASS; + + clazz->class_done = ctype->class_done; + clazz->obj_size = ctype->obj_size; + clazz->obj_init = ctype->obj_init; + clazz->obj_done = ctype->obj_done; + + if ( parent ) + { + if ( clazz->class_done == NULL ) + clazz->class_done = parent->class_done; + + if ( clazz->obj_init == NULL ) + clazz->obj_init = parent->obj_init; + + if ( clazz->obj_done == NULL ) + clazz->obj_done = parent->obj_done; + } + + /* find class initializer, if any */ + { + FT_Type ztype = ctype; + FT_Object_InitFunc cinit = NULL; + + do + { + cinit = ztype->class_init; + if ( cinit != NULL ) + break; + + ztype = ztype->super; + } + while ( ztype != NULL ); + + /* then call it when needed */ + if ( cinit != NULL ) + error = cinit( (FT_Object) clazz, NULL ); + } + } + + if (error) + { + if ( clazz ) + { + /* we always call the class destructor when */ + /* an error was detected in the constructor !! */ + if ( clazz->class_done ) + clazz->class_done( (FT_Object) clazz ); + + FT_FREE( clazz ); + } + FT_FREE( node ); + } + } + + Exit: + return (FT_Class) clazz; + } + + + + + + + + + + + + + + + FT_BASE_DEF( FT_Int ) + ft_object_check( FT_Pointer obj ) + { + return FT_OBJECT_CHECK(obj); + } + + + FT_BASE_DEF( FT_Int ) + ft_object_is_a( FT_Pointer obj, + FT_Class clazz ) + { + if ( FT_OBJECT_CHECK(obj) ) + { + FT_Class c = FT_OBJECT__CLASS(obj); + + do + { + if ( c == clazz ) + return 1; + + c = c->super; + } + while ( c == NULL ); + + return (clazz == NULL); + } + return 0; + } + + + FT_BASE_DEF( FT_Error ) + ft_object_create( FT_Object *pobject, + FT_Class clazz, + FT_Pointer init_data ) + { + FT_Memory memory; + FT_Error error; + FT_Object obj; + + FT_ASSERT_IS_CLASS(clazz); + + memory = FT_CLASS__MEMORY(clazz); + if ( !FT_ALLOC( obj, clazz->obj_size ) ) + { + obj->clazz = clazz; + obj->ref_count = 1; + + if ( clazz->obj_init ) + { + error = clazz->obj_init( obj, init_data ); + if ( error ) + { + /* IMPORTANT: call the destructor when an error */ + /* was detected in the constructor !! */ + if ( clazz->obj_done ) + clazz->obj_done( obj ); + + FT_FREE( obj ); + } + } + } + *pobject = obj; + return error; + } + + + FT_BASE_DEF( FT_Class ) + ft_class_find_by_type( FT_Type type, + FT_Library library ) + { + FT_MetaClass meta = &library->meta_class; + + return ft_metaclass_get_class( meta, type ); + } + + + FT_BASE_DEF( FT_Error ) + ft_object_create_from_type( FT_Object *pobject, + FT_Type type, + FT_Pointer init_data, + FT_Library library ) + { + FT_Class clazz; + FT_Error error; + + clazz = ft_class_find_by_type( type, library ); + if ( clazz ) + error = ft_object_create( pobject, clazz, init_data ); + else + { + *pobject = NULL; + error = FT_Err_Out_Of_Memory; + } + + return error; + } diff --git a/lib/freetype/src/base/ftobjs.c b/lib/freetype/src/base/ftobjs.c new file mode 100644 index 0000000..40fd286 --- /dev/null +++ b/lib/freetype/src/base/ftobjs.c @@ -0,0 +1,2667 @@ +/***************************************************************************/ +/* */ +/* ftobjs.c */ +/* */ +/* The FreeType private base classes (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_LIST_H +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ +#include FT_TRUETYPE_TABLES_H +#include FT_TRUETYPE_IDS_H +#include FT_OUTLINE_H + + + FT_BASE_DEF( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ) + { + valid->base = base; + valid->limit = limit; + valid->level = level; + valid->error = 0; + } + + + FT_BASE_DEF( FT_Int ) + ft_validator_run( FT_Validator valid ) + { + int result; + + + result = ft_setjmp( valid->jump_buffer ); + return result; + } + + + FT_BASE_DEF( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ) + { + valid->error = error; + ft_longjmp( valid->jump_buffer, 1 ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S T R E A M ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* create a new input stream from a FT_Open_Args structure */ + /* */ + static FT_Error + ft_input_stream_new( FT_Library library, + const FT_Open_Args* args, + FT_Stream* astream ) + { + FT_Error error; + FT_Memory memory; + FT_Stream stream; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !args ) + return FT_Err_Invalid_Argument; + + *astream = 0; + memory = library->memory; + + if ( FT_NEW( stream ) ) + goto Exit; + + stream->memory = memory; + + if ( args->flags & FT_OPEN_MEMORY ) + { + /* create a memory-based stream */ + FT_Stream_OpenMemory( stream, + (const FT_Byte*)args->memory_base, + args->memory_size ); + } + else if ( args->flags & FT_OPEN_PATHNAME ) + { + /* create a normal system stream */ + error = FT_Stream_Open( stream, args->pathname ); + stream->pathname.pointer = args->pathname; + } + else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) + { + /* use an existing, user-provided stream */ + + /* in this case, we do not need to allocate a new stream object */ + /* since the caller is responsible for closing it himself */ + FT_FREE( stream ); + stream = args->stream; + } + else + error = FT_Err_Invalid_Argument; + + if ( error ) + FT_FREE( stream ); + else + stream->memory = memory; /* just to be certain */ + + *astream = stream; + + Exit: + return error; + } + + + static void + ft_input_stream_free( FT_Stream stream, + FT_Int external ) + { + if ( stream ) + { + FT_Memory memory = stream->memory; + + + FT_Stream_Close( stream ); + + if ( !external ) + FT_FREE( stream ); + } + } + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_objs + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ft_glyphslot_init( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + FT_Error error = FT_Err_Ok; + FT_Slot_Internal internal; + + + slot->library = driver->root.library; + + if ( FT_NEW( internal ) ) + goto Exit; + + slot->internal = internal; + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + error = FT_GlyphLoader_New( memory, &internal->loader ); + + if ( !error && clazz->init_slot ) + error = clazz->init_slot( slot ); + + Exit: + return error; + } + + FT_BASE_DEF( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) + { + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + + + FT_FREE( slot->bitmap.buffer ); + slot->flags &= ~FT_GLYPH_OWN_BITMAP; + } + else + { + /* assume that the bitmap buffer was stolen or not */ + /* allocated from the heap */ + slot->bitmap.buffer = NULL; + } + } + + + FT_BASE_DEF( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Pointer buffer ) + { + ft_glyphslot_free_bitmap( slot ); + + slot->bitmap.buffer = buffer; + + FT_ASSERT( (slot->flags & FT_GLYPH_OWN_BITMAP) == 0 ); + } + + + FT_BASE_DEF( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ) + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + + + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + FT_FREE( slot->bitmap.buffer ); + else + slot->flags |= FT_GLYPH_OWN_BITMAP; + + return FT_MEM_ALLOC( slot->bitmap.buffer, size ); + } + + + static void + ft_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + + slot->bitmap.width = 0; + slot->bitmap.rows = 0; + slot->bitmap.pitch = 0; + slot->bitmap.pixel_mode = 0; + /* don't touch 'slot->bitmap.buffer' !! */ + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + } + + + static void + ft_glyphslot_done( FT_GlyphSlot slot ) + { + FT_Driver driver = slot->face->driver; + FT_Driver_Class clazz = driver->clazz; + FT_Memory memory = driver->root.memory; + + + if ( clazz->done_slot ) + clazz->done_slot( slot ); + + /* free bitmap buffer if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* free glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + FT_GlyphLoader_Done( slot->internal->loader ); + slot->internal->loader = 0; + } + + FT_FREE( slot->internal ); + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ) + { + FT_Error error; + FT_Driver driver; + FT_Driver_Class clazz; + FT_Memory memory; + FT_GlyphSlot slot; + + + if ( !face || !aslot || !face->driver ) + return FT_Err_Invalid_Argument; + + *aslot = 0; + + driver = face->driver; + clazz = driver->clazz; + memory = driver->root.memory; + + FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); + if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) + { + slot->face = face; + + error = ft_glyphslot_init( slot ); + if ( error ) + { + ft_glyphslot_done( slot ); + FT_FREE( slot ); + goto Exit; + } + + *aslot = slot; + } + + Exit: + FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ) + { + if ( slot ) + { + FT_Driver driver = slot->face->driver; + FT_Memory memory = driver->root.memory; + FT_GlyphSlot* parent; + FT_GlyphSlot cur; + + + /* Remove slot from its parent face's list */ + parent = &slot->face->glyph; + cur = *parent; + + while ( cur ) + { + if ( cur == slot ) + { + *parent = cur->next; + ft_glyphslot_done( slot ); + FT_FREE( slot ); + break; + } + cur = cur->next; + } + } + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Face_Internal internal; + + + if ( !face ) + return; + + internal = face->internal; + + internal->transform_flags = 0; + + if ( !matrix ) + { + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + matrix = &internal->transform_matrix; + } + else + internal->transform_matrix = *matrix; + + /* set transform_flags bit flag 0 if `matrix' isn't the identity */ + if ( ( matrix->xy | matrix->yx ) || + matrix->xx != 0x10000L || + matrix->yy != 0x10000L ) + internal->transform_flags |= 1; + + if ( !delta ) + { + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + delta = &internal->transform_delta; + } + else + internal->transform_delta = *delta; + + /* set transform_flags bit flag 1 if `delta' isn't the null vector */ + if ( delta->x | delta->y ) + internal->transform_flags |= 2; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Hint_Flags( FT_Face face, + FT_ULong flags ) + { + FT_Face_Internal internal; + + if ( !face ) + return; + + internal = face->internal; + + internal->hint_flags = (FT_UInt)flags; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ); + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + FT_Driver driver; + FT_GlyphSlot slot; + FT_Library library; + FT_Bool autohint; + FT_Module hinter; + + + if ( !face || !face->size || !face->glyph ) + return FT_Err_Invalid_Face_Handle; + + if ( glyph_index > (FT_UInt)face->num_glyphs ) + return FT_Err_Invalid_Argument; + + slot = face->glyph; + ft_glyphslot_clear( slot ); + + driver = face->driver; + + /* if the flag NO_RECURSE is set, we disable hinting and scaling */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + /* disable scaling, hinting, and transformation */ + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP | + FT_LOAD_IGNORE_TRANSFORM; + + /* disable bitmap rendering */ + load_flags &= ~FT_LOAD_RENDER; + } + + /* do we need to load the glyph through the auto-hinter? */ + library = driver->root.library; + hinter = library->auto_hinter; + autohint = + FT_BOOL( hinter && + !( load_flags & ( FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_NO_AUTOHINT ) ) && + FT_DRIVER_IS_SCALABLE( driver ) && + FT_DRIVER_USES_OUTLINES( driver ) ); + if ( autohint ) + { + if ( FT_DRIVER_HAS_HINTER( driver ) && + !( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) + autohint = 0; + } + + if ( autohint ) + { + FT_AutoHinter_Service hinting; + + + /* try to load embedded bitmaps first if available */ + /* */ + /* XXX: This is really a temporary hack that should disappear */ + /* promptly with FreeType 2.1! */ + /* */ + if ( FT_HAS_FIXED_SIZES( face ) && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + { + error = driver->clazz->load_glyph( slot, face->size, + glyph_index, + load_flags | FT_LOAD_SBITS_ONLY ); + + if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) + goto Load_Ok; + } + + /* load auto-hinted outline */ + hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; + + error = hinting->load_glyph( (FT_AutoHinter)hinter, + slot, face->size, + glyph_index, load_flags ); + } + else + { + error = driver->clazz->load_glyph( slot, + face->size, + glyph_index, + load_flags ); + if ( error ) + goto Exit; + + /* check that the loaded outline is correct */ + error = FT_Outline_Check( &slot->outline ); + if ( error ) + goto Exit; + } + + Load_Ok: + /* compute the advance */ + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + slot->advance.x = 0; + slot->advance.y = slot->metrics.vertAdvance; + } + else + { + slot->advance.x = slot->metrics.horiAdvance; + slot->advance.y = 0; + } + + /* compute the linear advance in 16.16 pixels */ + if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 ) + { + FT_UInt EM = face->units_per_EM; + FT_Size_Metrics* metrics = &face->size->metrics; + + + slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, + (FT_Long)metrics->x_ppem << 16, EM ); + + slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, + (FT_Long)metrics->y_ppem << 16, EM ); + } + + if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) + { + FT_Face_Internal internal = face->internal; + + + /* now, transform the glyph image if needed */ + if ( internal->transform_flags ) + { + /* get renderer */ + FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); + + + if ( renderer ) + error = renderer->clazz->transform_glyph( + renderer, slot, + &internal->transform_matrix, + &internal->transform_delta ); + /* transform advance */ + FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); + } + } + + /* do we need to render the image now? */ + if ( !error && + slot->format != FT_GLYPH_FORMAT_BITMAP && + slot->format != FT_GLYPH_FORMAT_COMPOSITE && + load_flags & FT_LOAD_RENDER ) + { + FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + + + if ( mode == FT_RENDER_MODE_NORMAL && + (load_flags & FT_LOAD_MONOCHROME ) ) + mode = FT_RENDER_MODE_MONO; + + error = FT_Render_Glyph( slot, mode ); + } + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ) + { + FT_UInt glyph_index; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + glyph_index = (FT_UInt)char_code; + if ( face->charmap ) + glyph_index = FT_Get_Char_Index( face, char_code ); + + return FT_Load_Glyph( face, glyph_index, load_flags ); + } + + + /* destructor for sizes list */ + static void + destroy_size( FT_Memory memory, + FT_Size size, + FT_Driver driver ) + { + /* finalize client-specific data */ + if ( size->generic.finalizer ) + size->generic.finalizer( size ); + + /* finalize format-specific stuff */ + if ( driver->clazz->done_size ) + driver->clazz->done_size( size ); + + FT_FREE( size->internal ); + FT_FREE( size ); + } + + + /* destructor for faces list */ + static void + destroy_face( FT_Memory memory, + FT_Face face, + FT_Driver driver ) + { + FT_Driver_Class clazz = driver->clazz; + + + /* discard auto-hinting data */ + if ( face->autohint.finalizer ) + face->autohint.finalizer( face->autohint.data ); + + /* Discard glyph slots for this face. */ + /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ + while ( face->glyph ) + FT_Done_GlyphSlot( face->glyph ); + + /* discard all sizes for this face */ + FT_List_Finalize( &face->sizes_list, + (FT_List_Destructor)destroy_size, + memory, + driver ); + face->size = 0; + + /* now discard client data */ + if ( face->generic.finalizer ) + face->generic.finalizer( face ); + + /* discard charmaps */ + { + FT_Int n; + + + for ( n = 0; n < face->num_charmaps; n++ ) + { + FT_CMap cmap = FT_CMAP( face->charmaps[n] ); + + + FT_CMap_Done( cmap ); + + face->charmaps[n] = NULL; + } + + FT_FREE( face->charmaps ); + face->num_charmaps = 0; + } + + + /* finalize format-specific stuff */ + if ( clazz->done_face ) + clazz->done_face( face ); + + /* close the stream for this face if needed */ + ft_input_stream_free( + face->stream, + ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->stream = 0; + + /* get rid of it */ + if ( face->internal ) + { + FT_FREE( face->internal->postscript_name ); + FT_FREE( face->internal ); + } + FT_FREE( face ); + } + + + static void + Destroy_Driver( FT_Driver driver ) + { + FT_List_Finalize( &driver->faces_list, + (FT_List_Destructor)destroy_face, + driver->root.memory, + driver ); + + /* check whether we need to drop the driver's glyph loader */ + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_unicode_charmap */ + /* */ + /* <Description> */ + /* This function finds a Unicode charmap, if there is one. */ + /* And if there is more than one, it tries to favour the more */ + /* extensive one, i.e. one that supports UCS-4 against those which */ + /* are limited to the BMP (said UCS-2 encoding.) */ + /* */ + /* This function is called from open_face() (just below), and also */ + /* from FT_Select_Charmap( , FT_ENCODING_UNICODE). */ + /* */ + static FT_Error + find_unicode_charmap( FT_Face face ) + { + FT_CharMap* first; + FT_CharMap* cur; + FT_CharMap* unicmap = NULL; /* some UCS-2 map, if we found it */ + + + /* caller should have already checked that `face' is valid */ + FT_ASSERT ( face ); + + first = face->charmaps; + + if ( !first ) + return FT_Err_Invalid_CharMap_Handle; + + /* + * the original TrueType specification(s) only specified charmap + * formats that are capable of mapping 8 or 16 bit character codes to + * glyph indices. + * + * however, recent updates to the Apple and OpenType specifications + * introduced new formats that are capable of mapping 32-bit character + * codes as well. And these are already used on some fonts, mainly to + * map non-BMP Asian ideographs as defined in Unicode. + * + * for compatibility purposes, these fonts generally come with + * *several* Unicode charmaps: + * + * - one of them in the "old" 16-bit format, that cannot access + * all glyphs in the font + * + * - another one in the "new" 32-bit format, that can access all + * the glyphs. + * + * this function has been written to always favor a 32-bit charmap + * when found. Otherwise, a 16-bit one is returned when found + */ + + /* since the `interesting' table, with id's 3,10, is normally the */ + /* last one, we loop backwards. This looses with type1 fonts with */ + /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ + /* chars (.01% ?), and this is the same about 99.99% of the time! */ + + cur = first + face->num_charmaps; /* points after the last one */ + + for ( ; --cur >= first; ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + unicmap = cur; /* record we found a Unicode charmap */ + + /* XXX If some new encodings to represent UCS-4 are added, */ + /* they should be added here. */ + if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) + + /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ + { + face->charmap = cur[0]; + return 0; + } + } + } + + /* We do not have any UCS-4 charmap. Sigh. */ + /* Let's see if we have some other kind of Unicode charmap, though. */ + if ( unicmap != NULL ) + { + face->charmap = unicmap[0]; + return 0; + } + + /* Chou blanc! */ + return FT_Err_Invalid_CharMap_Handle; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* open_face */ + /* */ + /* <Description> */ + /* This function does some work for FT_Open_Face(). */ + /* */ + static FT_Error + open_face( FT_Driver driver, + FT_Stream stream, + FT_Long face_index, + FT_Int num_params, + FT_Parameter* params, + FT_Face* aface ) + { + FT_Memory memory; + FT_Driver_Class clazz; + FT_Face face = 0; + FT_Error error, error2; + FT_Face_Internal internal; + + + clazz = driver->clazz; + memory = driver->root.memory; + + /* allocate the face object and perform basic initialization */ + if ( FT_ALLOC( face, clazz->face_object_size ) ) + goto Fail; + + if ( FT_NEW( internal ) ) + goto Fail; + + face->internal = internal; + + face->driver = driver; + face->memory = memory; + face->stream = stream; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + { + int i; + + + face->internal->incremental_interface = 0; + for ( i = 0; i < num_params && !face->internal->incremental_interface; + i++ ) + if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) + face->internal->incremental_interface = params[i].data; + } +#endif + + error = clazz->init_face( stream, + face, + (FT_Int)face_index, + num_params, + params ); + if ( error ) + goto Fail; + + /* select Unicode charmap by default */ + error2 = find_unicode_charmap( face ); + + /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle is + * returned. + */ + + /* no error should happen, but we want to play safe. */ + if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle ) + { + error = error2; + goto Fail; + } + + *aface = face; + + Fail: + if ( error ) + { + clazz->done_face( face ); + FT_FREE( face->internal ); + FT_FREE( face ); + *aface = 0; + } + + return error; + } + + + /* there's a Mac-specific extended implementation of FT_New_Face() */ + /* in src/base/ftmac.c */ + +#ifndef FT_MACINTOSH + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Face( FT_Library library, + const char* pathname, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `aface' delayed to FT_Open_Face() */ + if ( !pathname ) + return FT_Err_Invalid_Argument; + + args.flags = FT_OPEN_PATHNAME; + args.pathname = (char*)pathname; + + return FT_Open_Face( library, &args, face_index, aface ); + } + +#endif /* !FT_MACINTOSH */ + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ) + { + FT_Open_Args args; + + + /* test for valid `library' and `face' delayed to FT_Open_Face() */ + if ( !file_base ) + return FT_Err_Invalid_Argument; + + args.flags = FT_OPEN_MEMORY; + args.memory_base = file_base; + args.memory_size = file_size; + + return FT_Open_Face( library, &args, face_index, aface ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + FT_Face face = 0; + FT_ListNode node = 0; + FT_Bool external_stream; + + + /* test for valid `library' delayed to */ + /* ft_input_stream_new() */ + + if ( !aface || !args ) + return FT_Err_Invalid_Argument; + + *aface = 0; + + external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && + args->stream ); + + /* create input stream */ + error = ft_input_stream_new( library, args, &stream ); + if ( error ) + goto Exit; + + memory = library->memory; + + /* If the font driver is specified in the `args' structure, use */ + /* it. Otherwise, we scan the list of registered drivers. */ + if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) + { + driver = FT_DRIVER( args->driver ); + + /* not all modules are drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( driver ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + } + else + error = FT_Err_Invalid_Handle; + + ft_input_stream_free( stream, external_stream ); + goto Fail; + } + else + { + /* check each font driver for an appropriate format */ + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + /* not all modules are font drivers, so check... */ + if ( FT_MODULE_IS_DRIVER( cur[0] ) ) + { + FT_Int num_params = 0; + FT_Parameter* params = 0; + + + driver = FT_DRIVER( cur[0] ); + + if ( args->flags & FT_OPEN_PARAMS ) + { + num_params = args->num_params; + params = args->params; + } + + error = open_face( driver, stream, face_index, + num_params, params, &face ); + if ( !error ) + goto Success; + + if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) + goto Fail2; + } + } + + /* no driver is able to handle this format */ + error = FT_Err_Unknown_File_Format; + + Fail2: + ft_input_stream_free( stream, external_stream ); + goto Fail; + } + + Success: + FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); + + /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ + if ( external_stream ) + face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; + + /* add the face object to its driver's list */ + if ( FT_NEW( node ) ) + goto Fail; + + node->data = face; + /* don't assume driver is the same as face->driver, so use */ + /* face->driver instead. */ + FT_List_Add( &face->driver->faces_list, node ); + + /* now allocate a glyph slot object for the face */ + { + FT_GlyphSlot slot; + + + FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); + + error = FT_New_GlyphSlot( face, &slot ); + if ( error ) + goto Fail; + + face->glyph = slot; + } + + /* finally, allocate a size object for the face */ + { + FT_Size size; + + + FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); + + error = FT_New_Size( face, &size ); + if ( error ) + goto Fail; + + face->size = size; + } + + /* initialize internal face data */ + { + FT_Face_Internal internal = face->internal; + + + internal->transform_matrix.xx = 0x10000L; + internal->transform_matrix.xy = 0; + internal->transform_matrix.yx = 0; + internal->transform_matrix.yy = 0x10000L; + + internal->transform_delta.x = 0; + internal->transform_delta.y = 0; + } + + *aface = face; + goto Exit; + + Fail: + FT_Done_Face( face ); + + Exit: + FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ) + { + FT_Open_Args open; + + + /* test for valid `face' delayed to FT_Attach_Stream() */ + + if ( !filepathname ) + return FT_Err_Invalid_Argument; + + open.flags = FT_OPEN_PATHNAME; + open.pathname = (char*)filepathname; + + return FT_Attach_Stream( face, &open ); + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ) + { + FT_Stream stream; + FT_Error error; + FT_Driver driver; + + FT_Driver_Class clazz; + + + /* test for valid `parameters' delayed to ft_input_stream_new() */ + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + if ( !driver ) + return FT_Err_Invalid_Driver_Handle; + + error = ft_input_stream_new( driver->root.library, parameters, &stream ); + if ( error ) + goto Exit; + + /* we implement FT_Attach_Stream in each driver through the */ + /* `attach_file' interface */ + + error = FT_Err_Unimplemented_Feature; + clazz = driver->clazz; + if ( clazz->attach_file ) + error = clazz->attach_file( face, stream ); + + /* close the attached stream */ + ft_input_stream_free( stream, + (FT_Bool)( parameters->stream && + ( parameters->flags & FT_OPEN_STREAM ) ) ); + + Exit: + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Face( FT_Face face ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_ListNode node; + + + error = FT_Err_Invalid_Face_Handle; + if ( face && face->driver ) + { + driver = face->driver; + memory = driver->root.memory; + + /* find face in driver's list */ + node = FT_List_Find( &driver->faces_list, face ); + if ( node ) + { + /* remove face object from the driver's list */ + FT_List_Remove( &driver->faces_list, node ); + FT_FREE( node ); + + /* now destroy the object proper */ + destroy_face( memory, face, driver ); + error = FT_Err_Ok; + } + } + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size *asize ) + { + FT_Error error; + FT_Memory memory; + FT_Driver driver; + FT_Driver_Class clazz; + + FT_Size size = 0; + FT_ListNode node = 0; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !asize ) + return FT_Err_Invalid_Size_Handle; + + if ( !face->driver ) + return FT_Err_Invalid_Driver_Handle; + + *asize = 0; + + driver = face->driver; + clazz = driver->clazz; + memory = face->memory; + + /* Allocate new size object and perform basic initialisation */ + if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) + goto Exit; + + size->face = face; + + /* for now, do not use any internal fields in size objects */ + size->internal = 0; + + if ( clazz->init_size ) + error = clazz->init_size( size ); + + /* in case of success, add to the face's list */ + if ( !error ) + { + *asize = size; + node->data = size; + FT_List_Add( &face->sizes_list, node ); + } + + Exit: + if ( error ) + { + FT_FREE( node ); + FT_FREE( size ); + } + + return error; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Size( FT_Size size ) + { + FT_Error error; + FT_Driver driver; + FT_Memory memory; + FT_Face face; + FT_ListNode node; + + + if ( !size ) + return FT_Err_Invalid_Size_Handle; + + face = size->face; + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + if ( !driver ) + return FT_Err_Invalid_Driver_Handle; + + memory = driver->root.memory; + + error = FT_Err_Ok; + node = FT_List_Find( &face->sizes_list, size ); + if ( node ) + { + FT_List_Remove( &face->sizes_list, node ); + FT_FREE( node ); + + if ( face->size == size ) + { + face->size = 0; + if ( face->sizes_list.head ) + face->size = (FT_Size)(face->sizes_list.head->data); + } + + destroy_size( memory, size, driver ); + } + else + error = FT_Err_Invalid_Size_Handle; + + return error; + } + + + static void + ft_recompute_scaled_metrics( FT_Face face, + FT_Size_Metrics* metrics ) + { + /* Compute root ascender, descender, test height, and max_advance */ + + metrics->ascender = ( FT_MulFix( face->ascender, + metrics->y_scale ) + 63 ) & -64; + + metrics->descender = ( FT_MulFix( face->descender, + metrics->y_scale ) + 0 ) & -64; + + metrics->height = ( FT_MulFix( face->height, + metrics->y_scale ) + 32 ) & -64; + + metrics->max_advance = ( FT_MulFix( face->max_advance_width, + metrics->x_scale ) + 32 ) & -64; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) + { + FT_Error error = FT_Err_Ok; + FT_Driver driver; + FT_Driver_Class clazz; + FT_Size_Metrics* metrics; + FT_Long dim_x, dim_y; + + + if ( !face || !face->size || !face->driver ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + metrics = &face->size->metrics; + + if ( !char_width ) + char_width = char_height; + + else if ( !char_height ) + char_height = char_width; + + if ( !horz_resolution ) + horz_resolution = 72; + + if ( !vert_resolution ) + vert_resolution = 72; + + driver = face->driver; + clazz = driver->clazz; + + /* default processing -- this can be overridden by the driver */ + if ( char_width < 1 * 64 ) + char_width = 1 * 64; + if ( char_height < 1 * 64 ) + char_height = 1 * 64; + + /* Compute pixel sizes in 26.6 units. we use rounding + */ + dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; + dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + + metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); + metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); + + metrics->x_scale = 0x10000L; + metrics->y_scale = 0x10000L; + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + { + metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM ); + metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM ); + + ft_recompute_scaled_metrics( face, metrics ); + } + + if ( clazz->set_char_sizes ) + error = clazz->set_char_sizes( face->size, + char_width, + char_height, + horz_resolution, + vert_resolution ); + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ) + { + FT_Error error = FT_Err_Ok; + FT_Driver driver; + FT_Driver_Class clazz; + FT_Size_Metrics* metrics = &face->size->metrics; + + + if ( !face || !face->size || !face->driver ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + clazz = driver->clazz; + + /* default processing -- this can be overridden by the driver */ + if ( pixel_width == 0 ) + pixel_width = pixel_height; + + else if ( pixel_height == 0 ) + pixel_height = pixel_width; + + if ( pixel_width < 1 ) + pixel_width = 1; + if ( pixel_height < 1 ) + pixel_height = 1; + + metrics->x_ppem = (FT_UShort)pixel_width; + metrics->y_ppem = (FT_UShort)pixel_height; + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + { + metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, + face->units_per_EM ); + + metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, + face->units_per_EM ); + + ft_recompute_scaled_metrics( face, metrics ); + } + + if ( clazz->set_pixel_sizes ) + error = clazz->set_pixel_sizes( face->size, + pixel_width, + pixel_height ); + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ) + { + FT_Error error = FT_Err_Ok; + FT_Driver driver; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + if ( !akerning ) + return FT_Err_Invalid_Argument; + + driver = face->driver; + + akerning->x = 0; + akerning->y = 0; + + if ( driver->clazz->get_kerning ) + { + error = driver->clazz->get_kerning( face, + left_glyph, + right_glyph, + akerning ); + if ( !error ) + { + if ( kern_mode != FT_KERNING_UNSCALED ) + { + akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); + akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); + + if ( kern_mode != FT_KERNING_UNFITTED ) + { + akerning->x = ( akerning->x + 32 ) & -64; + akerning->y = ( akerning->y + 32 ) & -64; + } + } + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ + /* charmap available, i.e. one with UCS-4 characters, if possible. */ + /* */ + /* This is done by find_unicode_charmap() above, to share code. */ + if ( encoding == FT_ENCODING_UNICODE ) + return find_unicode_charmap( face ); + + cur = face->charmaps; + if ( !cur ) + return FT_Err_Invalid_CharMap_Handle; + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0]->encoding == encoding ) + { + face->charmap = cur[0]; + return 0; + } + } + + return FT_Err_Invalid_Argument; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ) + { + FT_CharMap* cur; + FT_CharMap* limit; + + + if ( !face ) + return FT_Err_Invalid_Face_Handle; + + cur = face->charmaps; + if ( !cur ) + return FT_Err_Invalid_CharMap_Handle; + + limit = cur + face->num_charmaps; + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == charmap ) + { + face->charmap = cur[0]; + return 0; + } + } + return FT_Err_Invalid_Argument; + } + + + FT_BASE_DEF( void ) + FT_CMap_Done( FT_CMap cmap ) + { + if ( cmap ) + { + FT_CMap_Class clazz = cmap->clazz; + FT_Face face = cmap->charmap.face; + FT_Memory memory = FT_FACE_MEMORY(face); + + + if ( clazz->done ) + clazz->done( cmap ); + + FT_FREE( cmap ); + } + } + + + FT_BASE_DEF( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ) + { + FT_Error error = 0; + FT_Face face; + FT_Memory memory; + FT_CMap cmap; + + + if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + return FT_Err_Invalid_Argument; + + face = charmap->face; + memory = FT_FACE_MEMORY(face); + + if ( !FT_ALLOC( cmap, clazz->size ) ) + { + cmap->charmap = *charmap; + cmap->clazz = clazz; + + if ( clazz->init ) + { + error = clazz->init( cmap, init_data ); + if ( error ) + goto Fail; + } + + /* add it to our list of charmaps */ + if ( FT_RENEW_ARRAY( face->charmaps, + face->num_charmaps, + face->num_charmaps+1 ) ) + goto Fail; + + face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; + } + + Exit: + if ( acmap ) + *acmap = cmap; + + return error; + + Fail: + FT_CMap_Done( cmap ); + cmap = NULL; + goto Exit; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ) + { + FT_UInt result = 0; + + + if ( face && face->charmap ) + { + FT_CMap cmap = FT_CMAP( face->charmap ); + + + result = cmap->clazz->char_index( cmap, charcode ); + } + return result; + } + + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap ) + { + gindex = FT_Get_Char_Index( face, 0 ); + if ( gindex == 0 ) + result = FT_Get_Next_Char( face, 0, &gindex ); + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + /* documentation is in freetype.h */ + + + FT_EXPORT_DEF( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong charcode, + FT_UInt *agindex ) + { + FT_ULong result = 0; + FT_UInt gindex = 0; + + + if ( face && face->charmap ) + { + FT_UInt32 code = (FT_UInt32)charcode; + FT_CMap cmap = FT_CMAP( face->charmap ); + + + gindex = cmap->clazz->char_next( cmap, &code ); + result = ( gindex == 0 ) ? 0 : code; + } + + if ( agindex ) + *agindex = gindex; + + return result; + } + + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ) + { + FT_UInt result = 0; + + + if ( face && FT_HAS_GLYPH_NAMES( face ) ) + { + /* now, lookup for glyph name */ + FT_Driver driver = face->driver; + FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + + + if ( clazz->get_interface ) + { + FT_Face_GetGlyphNameIndexFunc requester; + + + requester = (FT_Face_GetGlyphNameIndexFunc)clazz->get_interface( + FT_MODULE( driver ), "name_index" ); + if ( requester ) + result = requester( face, glyph_name ); + } + } + + return result; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_Error error = FT_Err_Invalid_Argument; + + + /* clean up buffer */ + if ( buffer && buffer_max > 0 ) + ((FT_Byte*)buffer)[0] = 0; + + if ( face && + glyph_index <= (FT_UInt)face->num_glyphs && + FT_HAS_GLYPH_NAMES( face ) ) + { + /* now, lookup for glyph name */ + FT_Driver driver = face->driver; + FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + + + if ( clazz->get_interface ) + { + FT_Face_GetGlyphNameFunc requester; + + + requester = (FT_Face_GetGlyphNameFunc)clazz->get_interface( + FT_MODULE( driver ), "glyph_name" ); + if ( requester ) + error = requester( face, glyph_index, buffer, buffer_max ); + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( const char* ) + FT_Get_Postscript_Name( FT_Face face ) + { + const char* result = NULL; + + + if ( !face ) + goto Exit; + + result = face->internal->postscript_name; + if ( !result ) + { + /* now, look up glyph name */ + FT_Driver driver = face->driver; + FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); + + + if ( clazz->get_interface ) + { + FT_Face_GetPostscriptNameFunc requester; + + + requester = (FT_Face_GetPostscriptNameFunc)clazz->get_interface( + FT_MODULE( driver ), "postscript_name" ); + if ( requester ) + result = requester( face ); + } + } + Exit: + return result; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ) + { + void* table = 0; + FT_Get_Sfnt_Table_Func func; + FT_Driver driver; + + + if ( !face || !FT_IS_SFNT( face ) ) + goto Exit; + + driver = face->driver; + func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface( + FT_MODULE( driver ), "get_sfnt" ); + if ( func ) + table = func( face, tag ); + + Exit: + return table; + } + + + /* documentation is in tttables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + SFNT_Load_Table_Func func; + FT_Driver driver; + + + if ( !face || !FT_IS_SFNT( face ) ) + return FT_Err_Invalid_Face_Handle; + + driver = face->driver; + func = (SFNT_Load_Table_Func) driver->root.clazz->get_interface( + FT_MODULE( driver ), "load_sfnt" ); + if ( !func ) + return FT_Err_Unimplemented_Feature; + + return func( face, tag, offset, buffer, length ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Activate_Size( FT_Size size ) + { + FT_Face face; + + + if ( size == NULL ) + return FT_Err_Bad_Argument; + + face = size->face; + if ( face == NULL || face->driver == NULL ) + return FT_Err_Bad_Argument; + + /* we don't need anything more complex than that; all size objects */ + /* are already listed by the face */ + face->size = size; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* lookup a renderer by glyph format in the library's list */ + FT_BASE_DEF( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ) + { + FT_ListNode cur; + FT_Renderer result = 0; + + + if ( !library ) + goto Exit; + + cur = library->renderers.head; + + if ( node ) + { + if ( *node ) + cur = (*node)->next; + *node = 0; + } + + while ( cur ) + { + FT_Renderer renderer = FT_RENDERER( cur->data ); + + + if ( renderer->glyph_format == format ) + { + if ( node ) + *node = cur; + + result = renderer; + break; + } + cur = cur->next; + } + + Exit: + return result; + } + + + static FT_Renderer + ft_lookup_glyph_renderer( FT_GlyphSlot slot ) + { + FT_Face face = slot->face; + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Renderer result = library->cur_renderer; + + + if ( !result || result->glyph_format != slot->format ) + result = FT_Lookup_Renderer( library, slot->format, 0 ); + + return result; + } + + + static void + ft_set_current_renderer( FT_Library library ) + { + FT_Renderer renderer; + + + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); + library->cur_renderer = renderer; + } + + + static FT_Error + ft_add_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_Error error; + FT_ListNode node; + + + if ( FT_NEW( node ) ) + goto Exit; + + { + FT_Renderer render = FT_RENDERER( module ); + FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; + + + render->clazz = clazz; + render->glyph_format = clazz->glyph_format; + + /* allocate raster object if needed */ + if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && + clazz->raster_class->raster_new ) + { + error = clazz->raster_class->raster_new( memory, &render->raster ); + if ( error ) + goto Fail; + + render->raster_render = clazz->raster_class->raster_render; + render->render = clazz->render_glyph; + } + + /* add to list */ + node->data = module; + FT_List_Add( &library->renderers, node ); + + ft_set_current_renderer( library ); + } + + Fail: + if ( error ) + FT_FREE( node ); + + Exit: + return error; + } + + + static void + ft_remove_renderer( FT_Module module ) + { + FT_Library library = module->library; + FT_Memory memory = library->memory; + FT_ListNode node; + + + node = FT_List_Find( &library->renderers, module ); + if ( node ) + { + FT_Renderer render = FT_RENDERER( module ); + + + /* release raster object, if any */ + if ( render->raster ) + render->clazz->raster_class->raster_done( render->raster ); + + /* remove from list */ + FT_List_Remove( &library->renderers, node ); + FT_FREE( node ); + + ft_set_current_renderer( library ); + } + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ) + { + /* test for valid `library' delayed to FT_Lookup_Renderer() */ + + return FT_Lookup_Renderer( library, format, 0 ); + } + + + /* documentation is in ftrender.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ) + { + FT_ListNode node; + FT_Error error = FT_Err_Ok; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !renderer ) + return FT_Err_Invalid_Argument; + + node = FT_List_Find( &library->renderers, renderer ); + if ( !node ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + FT_List_Up( &library->renderers, node ); + + if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) + library->cur_renderer = renderer; + + if ( num_params > 0 ) + { + FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; + + + for ( ; num_params > 0; num_params-- ) + { + error = set_mode( renderer, parameters->tag, parameters->data ); + if ( error ) + break; + } + } + + Exit: + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Error error = FT_Err_Ok; + FT_Renderer renderer; + + + /* if it is already a bitmap, no need to do anything */ + switch ( slot->format ) + { + case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ + break; + + default: + { + FT_ListNode node = 0; + FT_Bool update = 0; + + + /* small shortcut for the very common case */ + if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) + { + renderer = library->cur_renderer; + node = library->renderers.head; + } + else + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + + error = FT_Err_Unimplemented_Feature; + while ( renderer ) + { + error = renderer->render( renderer, slot, render_mode, NULL ); + if ( !error || + FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format. */ + + /* now, look for another renderer that supports the same */ + /* format. */ + renderer = FT_Lookup_Renderer( library, slot->format, &node ); + update = 1; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + } + } + + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ) + { + FT_Library library; + + + if ( !slot ) + return FT_Err_Invalid_Argument; + + library = FT_FACE_LIBRARY( slot->face ); + + return FT_Render_Glyph_Internal( library, slot, render_mode ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Destroy_Module */ + /* */ + /* <Description> */ + /* Destroys a given module object. For drivers, this also destroys */ + /* all child faces. */ + /* */ + /* <InOut> */ + /* module :: A handle to the target driver object. */ + /* */ + /* <Note> */ + /* The driver _must_ be LOCKED! */ + /* */ + static void + Destroy_Module( FT_Module module ) + { + FT_Memory memory = module->memory; + FT_Module_Class* clazz = module->clazz; + FT_Library library = module->library; + + + /* finalize client-data - before anything else */ + if ( module->generic.finalizer ) + module->generic.finalizer( module ); + + if ( library && library->auto_hinter == module ) + library->auto_hinter = 0; + + /* if the module is a renderer */ + if ( FT_MODULE_IS_RENDERER( module ) ) + ft_remove_renderer( module ); + + /* if the module is a font driver, add some steps */ + if ( FT_MODULE_IS_DRIVER( module ) ) + Destroy_Driver( FT_DRIVER( module ) ); + + /* finalize the module object */ + if ( clazz->module_done ) + clazz->module_done( module ); + + /* discard it */ + FT_FREE( module ); + } + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ) + { + FT_Error error; + FT_Memory memory; + FT_Module module; + FT_UInt nn; + + +#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ + FREETYPE_MINOR ) + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !clazz ) + return FT_Err_Invalid_Argument; + + /* check freetype version */ + if ( clazz->module_requires > FREETYPE_VER_FIXED ) + return FT_Err_Invalid_Version; + + /* look for a module with the same name in the library's table */ + for ( nn = 0; nn < library->num_modules; nn++ ) + { + module = library->modules[nn]; + if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) + { + /* this installed module has the same name, compare their versions */ + if ( clazz->module_version <= module->clazz->module_version ) + return FT_Err_Lower_Module_Version; + + /* remove the module from our list, then exit the loop to replace */ + /* it by our new version.. */ + FT_Remove_Module( library, module ); + break; + } + } + + memory = library->memory; + error = FT_Err_Ok; + + if ( library->num_modules >= FT_MAX_MODULES ) + { + error = FT_Err_Too_Many_Drivers; + goto Exit; + } + + /* allocate module object */ + if ( FT_ALLOC( module, clazz->module_size ) ) + goto Exit; + + /* base initialization */ + module->library = library; + module->memory = memory; + module->clazz = (FT_Module_Class*)clazz; + + /* check whether the module is a renderer - this must be performed */ + /* before the normal module initialization */ + if ( FT_MODULE_IS_RENDERER( module ) ) + { + /* add to the renderers list */ + error = ft_add_renderer( module ); + if ( error ) + goto Fail; + } + + /* is the module a auto-hinter? */ + if ( FT_MODULE_IS_HINTER( module ) ) + library->auto_hinter = module; + + /* if the module is a font driver */ + if ( FT_MODULE_IS_DRIVER( module ) ) + { + /* allocate glyph loader if needed */ + FT_Driver driver = FT_DRIVER( module ); + + + driver->clazz = (FT_Driver_Class)module->clazz; + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + { + error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); + if ( error ) + goto Fail; + } + } + + if ( clazz->module_init ) + { + error = clazz->module_init( module ); + if ( error ) + goto Fail; + } + + /* add module to the library's table */ + library->modules[library->num_modules++] = module; + + Exit: + return error; + + Fail: + if ( FT_MODULE_IS_DRIVER( module ) ) + { + FT_Driver driver = FT_DRIVER( module ); + + + if ( FT_DRIVER_USES_OUTLINES( driver ) ) + FT_GlyphLoader_Done( driver->glyph_loader ); + } + + if ( FT_MODULE_IS_RENDERER( module ) ) + { + FT_Renderer renderer = FT_RENDERER( module ); + + + if ( renderer->raster ) + renderer->clazz->raster_class->raster_done( renderer->raster ); + } + + FT_FREE( module ); + goto Exit; + } + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ) + { + FT_Module result = 0; + FT_Module* cur; + FT_Module* limit; + + + if ( !library || !module_name ) + return result; + + cur = library->modules; + limit = cur + library->num_modules; + + for ( ; cur < limit; cur++ ) + if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) + { + result = cur[0]; + break; + } + + return result; + } + + + /* documentation is in ftobjs.h */ + + FT_BASE_DEF( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ) + { + FT_Module module; + + + /* test for valid `library' delayed to FT_Get_Module() */ + + module = FT_Get_Module( library, mod_name ); + + return module ? module->clazz->module_interface : 0; + } + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ) + { + /* try to find the module from the table, then remove it from there */ + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( module ) + { + FT_Module* cur = library->modules; + FT_Module* limit = cur + library->num_modules; + + + for ( ; cur < limit; cur++ ) + { + if ( cur[0] == module ) + { + /* remove it from the table */ + library->num_modules--; + limit--; + while ( cur < limit ) + { + cur[0] = cur[1]; + cur++; + } + limit[0] = 0; + + /* destroy the module */ + Destroy_Module( module ); + + return FT_Err_Ok; + } + } + } + return FT_Err_Invalid_Driver_Handle; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ) + { + FT_Library library = 0; + FT_Error error; + + + if ( !memory ) + return FT_Err_Invalid_Argument; + +#ifdef FT_DEBUG_LEVEL_ERROR + /* init debugging support */ + ft_debug_init(); +#endif + + /* first of all, allocate the library object */ + if ( FT_NEW( library ) ) + return error; + + library->memory = memory; + + /* allocate the render pool */ + library->raster_pool_size = FT_RENDER_POOL_SIZE; + if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) + goto Fail; + + /* That's ok now */ + *alibrary = library; + + return FT_Err_Ok; + + Fail: + FT_FREE( library ); + return error; + } + + + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ) + { + FT_Int major = 0; + FT_Int minor = 0; + FT_Int patch = 0; + + + if ( library ) + { + major = library->version_major; + minor = library->version_minor; + patch = library->version_patch; + } + + if ( amajor ) + *amajor = major; + + if ( aminor ) + *aminor = minor; + + if ( apatch ) + *apatch = patch; + } + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_Library( FT_Library library ) + { + FT_Memory memory; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + memory = library->memory; + + /* Discard client-data */ + if ( library->generic.finalizer ) + library->generic.finalizer( library ); + + /* Close all modules in the library */ +#if 1 + while ( library->num_modules > 0 ) + FT_Remove_Module( library, library->modules[0] ); +#else + { + FT_UInt n; + + + for ( n = 0; n < library->num_modules; n++ ) + { + FT_Module module = library->modules[n]; + + + if ( module ) + { + Destroy_Module( module ); + library->modules[n] = 0; + } + } + } +#endif + + /* Destroy raster objects */ + FT_FREE( library->raster_pool ); + library->raster_pool_size = 0; + + FT_FREE( library ); + return FT_Err_Ok; + } + + + /* documentation is in ftmodule.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ) + { + if ( library && debug_hook && + hook_index < + ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) + library->debug_hooks[hook_index] = debug_hook; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftoutln.c b/lib/freetype/src/base/ftoutln.c new file mode 100644 index 0000000..c59043b --- /dev/null +++ b/lib/freetype/src/base/ftoutln.c @@ -0,0 +1,658 @@ +/***************************************************************************/ +/* */ +/* ftoutln.c */ +/* */ +/* FreeType outline management (body). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* All functions are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_INTERNAL_OBJECTS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_outline + + + static + const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#define SCALED( x ) ( ( (x) << shift ) - delta ) + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + + FT_Int shift; + FT_Pos delta; + + + if ( !outline || !func_interface ) + return FT_Err_Invalid_Argument; + + shift = func_interface->shift; + delta = func_interface->delta; + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_Int last; /* index of last point in contour */ + + + last = outline->contours[n]; + limit = outline->points + last; + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); + v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); + vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + return 0; + + Exit: + return error; + + Invalid_Outline: + return FT_Err_Invalid_Outline; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + FT_Error error; + + + if ( !anoutline || !memory ) + return FT_Err_Invalid_Argument; + + *anoutline = null_outline; + + if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || + FT_NEW_ARRAY( anoutline->tags, numPoints ) || + FT_NEW_ARRAY( anoutline->contours, numContours ) ) + goto Fail; + + anoutline->n_points = (FT_UShort)numPoints; + anoutline->n_contours = (FT_Short)numContours; + anoutline->flags |= FT_OUTLINE_OWNER; + + return FT_Err_Ok; + + Fail: + anoutline->flags |= FT_OUTLINE_OWNER; + FT_Outline_Done_Internal( memory, anoutline ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ) + { + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + return FT_Outline_New_Internal( library->memory, numPoints, + numContours, anoutline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Check( FT_Outline* outline ) + { + if ( outline ) + { + FT_Int n_points = outline->n_points; + FT_Int n_contours = outline->n_contours; + FT_Int end0, end; + FT_Int n; + + + /* empty glyph? */ + if ( n_points == 0 && n_contours == 0 ) + return 0; + + /* check point and contour counts */ + if ( n_points <= 0 || n_contours <= 0 ) + goto Bad; + + end0 = end = -1; + for ( n = 0; n < n_contours; n++ ) + { + end = outline->contours[n]; + + /* note that we don't accept empty contours */ + if ( end <= end0 || end >= n_points ) + goto Bad; + + end0 = end; + } + + if ( end != n_points - 1 ) + goto Bad; + + /* XXX: check the tags array */ + return 0; + } + + Bad: + return FT_Err_Invalid_Argument; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Copy( FT_Outline* source, + FT_Outline *target ) + { + FT_Int is_owner; + + + if ( !source || !target || + source->n_points != target->n_points || + source->n_contours != target->n_contours ) + return FT_Err_Invalid_Argument; + + FT_MEM_COPY( target->points, source->points, + source->n_points * sizeof ( FT_Vector ) ); + + FT_MEM_COPY( target->tags, source->tags, + source->n_points * sizeof ( FT_Byte ) ); + + FT_MEM_COPY( target->contours, source->contours, + source->n_contours * sizeof ( FT_Short ) ); + + /* copy all flags, except the `FT_OUTLINE_OWNER' one */ + is_owner = target->flags & FT_OUTLINE_OWNER; + target->flags = source->flags; + + target->flags &= ~FT_OUTLINE_OWNER; + target->flags |= is_owner; + + return FT_Err_Ok; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ) + { + if ( outline ) + { + if ( outline->flags & FT_OUTLINE_OWNER ) + { + FT_FREE( outline->points ); + FT_FREE( outline->tags ); + FT_FREE( outline->contours ); + } + *outline = null_outline; + + return FT_Err_Ok; + } + else + return FT_Err_Invalid_Argument; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ) + { + /* check for valid `outline' in FT_Outline_Done_Internal() */ + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + return FT_Outline_Done_Internal( library->memory, outline ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Get_CBox( FT_Outline* outline, + FT_BBox *acbox ) + { + FT_Pos xMin, yMin, xMax, yMax; + + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + FT_Pos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Translate( FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ) + { + FT_UShort n; + FT_Vector* vec = outline->points; + + + for ( n = 0; n < outline->n_points; n++ ) + { + vec->x += xOffset; + vec->y += yOffset; + vec++; + } + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Reverse( FT_Outline* outline ) + { + FT_UShort n; + FT_Int first, last; + + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + last = outline->contours[n]; + + /* reverse point table */ + { + FT_Vector* p = outline->points + first; + FT_Vector* q = outline->points + last; + FT_Vector swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + /* reverse tags table */ + { + char* p = outline->tags + first; + char* q = outline->tags + last; + char swap; + + + while ( p < q ) + { + swap = *p; + *p = *q; + *q = swap; + p++; + q--; + } + } + + first = last + 1; + } + + outline->flags ^= FT_OUTLINE_REVERSE_FILL; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ) + { + FT_Error error; + FT_Bool update = 0; + FT_Renderer renderer; + FT_ListNode node; + + + if ( !library ) + return FT_Err_Invalid_Library_Handle; + + if ( !params ) + return FT_Err_Invalid_Argument; + + renderer = library->cur_renderer; + node = library->renderers.head; + + params->source = (void*)outline; + + error = FT_Err_Cannot_Render_Glyph; + while ( renderer ) + { + error = renderer->raster_render( renderer->raster, params ); + if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) + break; + + /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ + /* is unsupported by the current renderer for this glyph image */ + /* format */ + + /* now, look for another renderer that supports the same */ + /* format */ + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, + &node ); + update = 1; + } + + /* if we changed the current renderer for the glyph image format */ + /* we need to select it as the next current one */ + if ( !error && update && renderer ) + FT_Set_Renderer( library, renderer, 0, 0 ); + + return error; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + FT_Bitmap *abitmap ) + { + FT_Raster_Params params; + + + if ( !abitmap ) + return FT_Err_Invalid_Argument; + + /* other checks are delayed to FT_Outline_Render() */ + + params.target = abitmap; + params.flags = 0; + + if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD || + abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) + params.flags |= FT_RASTER_FLAG_AA; + + return FT_Outline_Render( library, outline, ¶ms ); + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Transform( FT_Vector* vector, + FT_Matrix* matrix ) + { + FT_Pos xz, yz; + + + if ( !vector || !matrix ) + return; + + xz = FT_MulFix( vector->x, matrix->xx ) + + FT_MulFix( vector->y, matrix->xy ); + + yz = FT_MulFix( vector->x, matrix->yx ) + + FT_MulFix( vector->y, matrix->yy ); + + vector->x = xz; + vector->y = yz; + } + + + /* documentation is in ftoutln.h */ + + FT_EXPORT_DEF( void ) + FT_Outline_Transform( FT_Outline* outline, + FT_Matrix* matrix ) + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + for ( ; vec < limit; vec++ ) + FT_Vector_Transform( vec, matrix ); + } + + +/* END */ diff --git a/lib/freetype/src/base/ftpfr.c b/lib/freetype/src/base/ftpfr.c new file mode 100644 index 0000000..bf2c2a2 --- /dev/null +++ b/lib/freetype/src/base/ftpfr.c @@ -0,0 +1,105 @@ +/***************************************************************************/ +/* */ +/* ftpfr.c */ +/* */ +/* FreeType API for accessing PFR-specific data */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_PFR_H +#include FT_INTERNAL_OBJECTS_H + + + /* check the format */ + static FT_Error + ft_pfr_check( FT_Face face, + FT_PFR_Service *aservice ) + { + FT_Error error = FT_Err_Bad_Argument; + + if ( face && face->driver ) + { + FT_Module module = (FT_Module) face->driver; + const char* name = module->clazz->module_name; + + if ( name[0] == 'p' && + name[1] == 'f' && + name[2] == 'r' && + name[4] == 0 ) + { + *aservice = (FT_PFR_Service) module->clazz->module_interface; + error = 0; + } + } + return error; + } + + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_metrics( face, + aoutline_resolution, + ametrics_resolution, + ametrics_x_scale, + ametrics_y_scale ); + } + return error; + } + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_kerning( face, left, right, avector ); + } + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error; + FT_PFR_Service service; + + error = ft_pfr_check( face, &service ); + if ( !error ) + { + error = service->get_advance( face, gindex, aadvance ); + } + return error; + } + +/* END */ diff --git a/lib/freetype/src/base/ftstream.c b/lib/freetype/src/base/ftstream.c new file mode 100644 index 0000000..60e7856 --- /dev/null +++ b/lib/freetype/src/base/ftstream.c @@ -0,0 +1,803 @@ +/***************************************************************************/ +/* */ +/* ftstream.c */ +/* */ +/* I/O stream support (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_stream + + + FT_BASE_DEF( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ) + { + stream->base = (FT_Byte*) base; + stream->size = size; + stream->pos = 0; + stream->cursor = 0; + stream->read = 0; + stream->close = 0; + } + + + FT_BASE_DEF( void ) + FT_Stream_Close( FT_Stream stream ) + { + if ( stream && stream->close ) + { + stream->close( stream ); + stream->close = NULL; + } + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ) + { + FT_Error error = FT_Err_Ok; + + + stream->pos = pos; + + if ( stream->read ) + { + if ( stream->read( stream, pos, 0, 0 ) ) + { + FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + } + } + /* note that seeking to the first position after the file is valid */ + else if ( pos > stream->size ) + { + FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + } + + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ) + { + return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_Pos( FT_Stream stream ) + { + return stream->pos; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ) + { + return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + if ( pos >= stream->size ) + { + FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + + return FT_Err_Invalid_Stream_Operation; + } + + if ( stream->read ) + read_bytes = stream->read( stream, pos, buffer, count ); + else + { + read_bytes = stream->size - pos; + if ( read_bytes > count ) + read_bytes = count; + + FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); + } + + stream->pos = pos + read_bytes; + + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_ReadAt:" )); + FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + error = FT_Err_Invalid_Stream_Operation; + } + + return error; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ) + { + FT_Error error; + + + error = FT_Stream_EnterFrame( stream, count ); + if ( !error ) + { + *pbytes = (FT_Byte*)stream->cursor; + + /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ + stream->cursor = 0; + stream->limit = 0; + } + + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ) + { + if ( stream->read ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( *pbytes ); + } + *pbytes = 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ) + { + FT_Error error = FT_Err_Ok; + FT_ULong read_bytes; + + + /* check for nested frame access */ + FT_ASSERT( stream && stream->cursor == 0 ); + + if ( stream->read ) + { + /* allocate the frame in memory */ + FT_Memory memory = stream->memory; + + + if ( FT_ALLOC( stream->base, count ) ) + goto Exit; + + /* read it */ + read_bytes = stream->read( stream, stream->pos, + stream->base, count ); + if ( read_bytes < count ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" )); + FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", + count, read_bytes )); + + FT_FREE( stream->base ); + error = FT_Err_Invalid_Stream_Operation; + } + stream->cursor = stream->base; + stream->limit = stream->cursor + count; + stream->pos += read_bytes; + } + else + { + /* check current and new position */ + if ( stream->pos >= stream->size || + stream->pos + count > stream->size ) + { + FT_ERROR(( "FT_Stream_EnterFrame:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", + stream->pos, count, stream->size )); + + error = FT_Err_Invalid_Stream_Operation; + goto Exit; + } + + /* set cursor */ + stream->cursor = stream->base + stream->pos; + stream->limit = stream->cursor + count; + stream->pos += count; + } + + Exit: + return error; + } + + + FT_BASE_DEF( void ) + FT_Stream_ExitFrame( FT_Stream stream ) + { + /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ + /* that it is possible to access a frame of length 0 in */ + /* some weird fonts (usually, when accessing an array of */ + /* 0 records, like in some strange kern tables). */ + /* */ + /* In this case, the loader code handles the 0-length table */ + /* gracefully; however, stream.cursor is really set to 0 by the */ + /* FT_Stream_EnterFrame() call, and this is not an error. */ + /* */ + FT_ASSERT( stream ); + + if ( stream->read ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + } + stream->cursor = 0; + stream->limit = 0; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ) + { + FT_Char result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + if ( stream->cursor < stream->limit ) + result = *stream->cursor++; + + return result; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_GetShort( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_SHORT( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_GetShortLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = FT_NEXT_SHORT_LE( p ); + stream->cursor = p; + + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetOffset( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 2 < stream->limit ) + result = FT_NEXT_OFF3( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetLong( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_LONG( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_GetLongLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_ASSERT( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = FT_NEXT_LONG_LE( p ); + stream->cursor = p; + return result; + } + + + FT_BASE_DEF( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ) + { + FT_Byte result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) + goto Fail; + } + else + { + if ( stream->pos < stream->size ) + result = stream->base[stream->pos]; + else + goto Fail; + } + stream->pos++; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_ReadShort( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_SHORT( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadShort:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Short ) + FT_Stream_ReadShortLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_SHORT_LE( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadShortLE:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadOffset( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[3]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 2 < stream->size ) + { + if ( stream->read ) + { + if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_OFF3( p ); + } + else + goto Fail; + + stream->pos += 3; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Stream_ReadOffset:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadLong( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_LONG( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + *error = FT_Err_Invalid_Stream_Operation; + + return 0; + } + + + FT_BASE_DEF( FT_Long ) + FT_Stream_ReadLongLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_ASSERT( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = FT_NEXT_LONG_LE( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + FT_ERROR(( "FT_Stream_ReadLongLE:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + *error = FT_Err_Invalid_Stream_Operation; + + return 0; + } + + + FT_BASE_DEF( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ) + { + FT_Error error; + FT_Bool frame_accessed = 0; + FT_Byte* cursor = stream->cursor; + + + if ( !fields || !stream ) + return FT_Err_Invalid_Argument; + + error = FT_Err_Ok; + do + { + FT_ULong value; + FT_Int sign_shift; + FT_Byte* p; + + + switch ( fields->value ) + { + case ft_frame_start: /* access a new frame */ + error = FT_Stream_EnterFrame( stream, fields->offset ); + if ( error ) + goto Exit; + + frame_accessed = 1; + cursor = stream->cursor; + fields++; + continue; /* loop! */ + + case ft_frame_bytes: /* read a byte sequence */ + case ft_frame_skip: /* skip some bytes */ + { + FT_UInt len = fields->size; + + + if ( cursor + len > stream->limit ) + { + error = FT_Err_Invalid_Stream_Operation; + goto Exit; + } + + if ( fields->value == ft_frame_bytes ) + { + p = (FT_Byte*)structure + fields->offset; + FT_MEM_COPY( p, cursor, len ); + } + cursor += len; + fields++; + continue; + } + + case ft_frame_byte: + case ft_frame_schar: /* read a single byte */ + value = FT_NEXT_BYTE(cursor); + sign_shift = 24; + break; + + case ft_frame_short_be: + case ft_frame_ushort_be: /* read a 2-byte big-endian short */ + value = FT_NEXT_USHORT(cursor); + sign_shift = 16; + break; + + case ft_frame_short_le: + case ft_frame_ushort_le: /* read a 2-byte little-endian short */ + value = FT_NEXT_USHORT_LE(cursor); + sign_shift = 16; + break; + + case ft_frame_long_be: + case ft_frame_ulong_be: /* read a 4-byte big-endian long */ + value = FT_NEXT_ULONG(cursor); + sign_shift = 0; + break; + + case ft_frame_long_le: + case ft_frame_ulong_le: /* read a 4-byte little-endian long */ + value = FT_NEXT_ULONG_LE(cursor); + sign_shift = 0; + break; + + case ft_frame_off3_be: + case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ + value = FT_NEXT_UOFF3(cursor); + sign_shift = 8; + break; + + case ft_frame_off3_le: + case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ + value = FT_NEXT_UOFF3_LE(cursor); + sign_shift = 8; + break; + + default: + /* otherwise, exit the loop */ + stream->cursor = cursor; + goto Exit; + } + + /* now, compute the signed value is necessary */ + if ( fields->value & FT_FRAME_OP_SIGNED ) + value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); + + /* finally, store the value in the object */ + + p = (FT_Byte*)structure + fields->offset; + switch ( fields->size ) + { + case 1: + *(FT_Byte*)p = (FT_Byte)value; + break; + + case 2: + *(FT_UShort*)p = (FT_UShort)value; + break; + + case 4: + *(FT_UInt32*)p = (FT_UInt32)value; + break; + + default: /* for 64-bit systems */ + *(FT_ULong*)p = (FT_ULong)value; + } + + /* go to next field */ + fields++; + } + while ( 1 ); + + Exit: + /* close the frame if it was opened by this read */ + if ( frame_accessed ) + FT_Stream_ExitFrame( stream ); + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftstroker.c b/lib/freetype/src/base/ftstroker.c new file mode 100644 index 0000000..712020e --- /dev/null +++ b/lib/freetype/src/base/ftstroker.c @@ -0,0 +1,1577 @@ +#include <ft2build.h> +#include FT_STROKER_H +#include FT_TRIGONOMETRY_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** BEZIER COMPUTATIONS *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + +#define FT_SMALL_CONIC_THRESHOLD (FT_ANGLE_PI/6) +#define FT_SMALL_CUBIC_THRESHOLD (FT_ANGLE_PI/6) +#define FT_EPSILON 2 + +#define FT_IS_SMALL(x) ((x) > -FT_EPSILON && (x) < FT_EPSILON) + + static FT_Pos + ft_pos_abs( FT_Pos x ) + { + return x >= 0 ? x : -x ; + } + + static void + ft_conic_split( FT_Vector* base ) + { + FT_Pos 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; + } + + + static FT_Bool + ft_conic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_out ) + { + FT_Vector d1, d2; + FT_Angle theta; + FT_Int close1, close2; + + d1.x = base[1].x - base[2].x; + d1.y = base[1].y - base[2].y; + d2.x = base[0].x - base[1].x; + d2.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); + close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); + + if (close1) + { + if (close2) + *angle_in = *angle_out = 0; + else + *angle_in = *angle_out = FT_Atan2( d2.x, d2.y ); + } + else if (close2) + { + *angle_in = *angle_out = FT_Atan2( d1.x, d1.y ); + } + else + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d2.x, d2.y ); + } + + theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) ); + + return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD ); + } + + + static void + ft_cubic_split( FT_Vector* base ) + { + FT_Pos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c )/2; + base[5].x = b = ( base[3].x + d )/2; + c = ( c + d )/2; + base[2].x = a = ( a + c )/2; + base[4].x = b = ( b + c )/2; + base[3].x = ( a + b )/2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c )/2; + base[5].y = b = ( base[3].y + d )/2; + c = ( c + d )/2; + base[2].y = a = ( a + c )/2; + base[4].y = b = ( b + c )/2; + base[3].y = ( a + b )/2; + } + + + static FT_Bool + ft_cubic_is_small_enough( FT_Vector* base, + FT_Angle *angle_in, + FT_Angle *angle_mid, + FT_Angle *angle_out ) + { + FT_Vector d1, d2, d3; + FT_Angle theta1, theta2; + FT_Int close1, close2, close3; + + d1.x = base[2].x - base[3].x; + d1.y = base[2].y - base[3].y; + d2.x = base[1].x - base[2].x; + d2.y = base[1].y - base[2].y; + d3.x = base[0].x - base[1].x; + d3.y = base[0].y - base[1].y; + + close1 = FT_IS_SMALL(d1.x) && FT_IS_SMALL(d1.y); + close2 = FT_IS_SMALL(d2.x) && FT_IS_SMALL(d2.y); + close3 = FT_IS_SMALL(d3.x) && FT_IS_SMALL(d3.y); + + if (close1 || close3) + { + if (close2) + { + /* basically a point */ + *angle_in = *angle_out = *angle_mid = 0; + } + else if (close1) + { + *angle_in = *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + else /* close2 */ + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y ); + } + } + else if (close2) + { + *angle_in = *angle_mid = FT_Atan2( d1.x, d1.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + else + { + *angle_in = FT_Atan2( d1.x, d1.y ); + *angle_mid = FT_Atan2( d2.x, d2.y ); + *angle_out = FT_Atan2( d3.x, d3.y ); + } + theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); + theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); + + return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD && + theta2 < FT_SMALL_CUBIC_THRESHOLD ); + } + + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** STROKE BORDERS *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + + typedef enum + { + FT_STROKE_TAG_ON = 1, /* on-curve point */ + FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ + FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ + FT_STROKE_TAG_END = 8 /* sub-path end */ + + } FT_StrokeTags; + + + typedef struct FT_StrokeBorderRec_ + { + FT_UInt num_points; + FT_UInt max_points; + FT_Vector* points; + FT_Byte* tags; + FT_Bool movable; + FT_Int start; /* index of current sub-path start point */ + FT_Memory memory; + + } FT_StrokeBorderRec, *FT_StrokeBorder; + + + static FT_Error + ft_stroke_border_grow( FT_StrokeBorder border, + FT_UInt new_points ) + { + FT_UInt old_max = border->max_points; + FT_UInt new_max = border->num_points + new_points; + FT_Error error = 0; + + if ( new_max > old_max ) + { + FT_UInt cur_max = old_max; + FT_Memory memory = border->memory; + + while ( cur_max < new_max ) + cur_max += (cur_max >> 1) + 16; + + if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || + FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) + goto Exit; + + border->max_points = cur_max; + } + Exit: + return error; + } + + static void + ft_stroke_border_close( FT_StrokeBorder border ) + { + FT_ASSERT( border->start >= 0 ); + + /* don't record empty paths !! */ + if ( border->num_points > (FT_UInt)border->start ) + { + border->tags[ border->start ] |= FT_STROKE_TAG_BEGIN; + border->tags[ border->num_points-1 ] |= FT_STROKE_TAG_END; + } + + border->start = -1; + border->movable = 0; + } + + + static FT_Error + ft_stroke_border_lineto( FT_StrokeBorder border, + FT_Vector* to, + FT_Bool movable ) + { + FT_Error error = 0; + + FT_ASSERT( border->start >= 0 ); + + if ( border->movable ) + { + /* move last point */ + border->points[ border->num_points-1 ] = *to; + } + else + { + /* add one point */ + error = ft_stroke_border_grow( border, 1 ); + if (!error) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + vec[0] = *to; + tag[0] = FT_STROKE_TAG_ON; + + border->num_points += 1; + } + } + border->movable = movable; + return error; + } + + + static FT_Error + ft_stroke_border_conicto( FT_StrokeBorder border, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error; + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 2 ); + if (!error) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + vec[0] = *control; + vec[1] = *to; + + tag[0] = 0; + tag[1] = FT_STROKE_TAG_ON; + + border->num_points += 2; + } + border->movable = 0; + return error; + } + + + static FT_Error + ft_stroke_border_cubicto( FT_StrokeBorder border, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error; + + FT_ASSERT( border->start >= 0 ); + + error = ft_stroke_border_grow( border, 3 ); + if (!error) + { + FT_Vector* vec = border->points + border->num_points; + FT_Byte* tag = border->tags + border->num_points; + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + + tag[0] = FT_STROKE_TAG_CUBIC; + tag[1] = FT_STROKE_TAG_CUBIC; + tag[2] = FT_STROKE_TAG_ON; + + border->num_points += 3; + } + border->movable = 0; + return error; + } + + +#define FT_ARC_CUBIC_ANGLE (FT_ANGLE_PI/2) + + + static FT_Error + ft_stroke_border_arcto( FT_StrokeBorder border, + FT_Vector* center, + FT_Fixed radius, + FT_Angle angle_start, + FT_Angle angle_diff ) + { + FT_Angle total, angle, step, rotate, next, theta; + FT_Vector a, b, a2, b2; + FT_Fixed length; + FT_Error error = 0; + + /* compute start point */ + FT_Vector_From_Polar( &a, radius, angle_start ); + a.x += center->x; + a.y += center->y; + + total = angle_diff; + angle = angle_start; + rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; + + while (total != 0) + { + step = total; + if ( step > FT_ARC_CUBIC_ANGLE ) + step = FT_ARC_CUBIC_ANGLE; + + else if ( step < -FT_ARC_CUBIC_ANGLE ) + step = -FT_ARC_CUBIC_ANGLE; + + next = angle + step; + theta = step; + if ( theta < 0 ) + theta = -theta; + + theta >>= 1; + + /* compute end point */ + FT_Vector_From_Polar( &b, radius, next ); + b.x += center->x; + b.y += center->y; + + /* compute first and second control points */ + length = FT_MulDiv( radius, FT_Sin(theta)*4, + (0x10000L + FT_Cos(theta))*3 ); + + FT_Vector_From_Polar( &a2, length, angle + rotate ); + a2.x += a.x; + a2.y += a.y; + + FT_Vector_From_Polar( &b2, length, next - rotate ); + b2.x += b.x; + b2.y += b.y; + + /* add cubic arc */ + error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); + if (error) break; + + /* process the rest of the arc ?? */ + a = b; + total -= step; + angle = next; + } + return error; + } + + + static FT_Error + ft_stroke_border_moveto( FT_StrokeBorder border, + FT_Vector* to ) + { + /* close current open path if any ? */ + if ( border->start >= 0 ) + ft_stroke_border_close( border ); + + border->start = border->num_points; + border->movable = 0; + + return ft_stroke_border_lineto( border, to, 0 ); + } + + + static void + ft_stroke_border_init( FT_StrokeBorder border, + FT_Memory memory ) + { + border->memory = memory; + border->points = NULL; + border->tags = NULL; + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + } + + + static void + ft_stroke_border_reset( FT_StrokeBorder border ) + { + border->num_points = 0; + border->start = -1; + } + + + static void + ft_stroke_border_done( FT_StrokeBorder border ) + { + FT_Memory memory = border->memory; + + FT_FREE( border->points ); + FT_FREE( border->tags ); + + border->num_points = 0; + border->max_points = 0; + border->start = -1; + } + + + static FT_Error + ft_stroke_border_get_counts( FT_StrokeBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_Error error = 0; + FT_UInt num_points = 0; + FT_UInt num_contours = 0; + + FT_UInt count = border->num_points; + FT_Vector* point = border->points; + FT_Byte* tags = border->tags; + FT_Int in_contour = 0; + + for ( ; count > 0; count--, num_points++, point++, tags++ ) + { + if ( tags[0] & FT_STROKE_TAG_BEGIN ) + { + if ( in_contour != 0 ) + goto Fail; + + in_contour = 1; + } + else if ( in_contour == 0 ) + goto Fail; + + if ( tags[0] & FT_STROKE_TAG_END ) + { + if ( in_contour == 0 ) + goto Fail; + + in_contour = 0; + num_contours++; + } + } + if ( in_contour != 0 ) + goto Fail; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + + Fail: + num_points = 0; + num_contours = 0; + goto Exit; + } + + + static void + ft_stroke_border_export( FT_StrokeBorder border, + FT_Outline* outline ) + { + /* copy point locations */ + FT_MEM_COPY( outline->points + outline->n_points, + border->points, + border->num_points * sizeof(FT_Vector) ); + + /* copy tags */ + { + FT_UInt count = border->num_points; + FT_Byte* read = border->tags; + FT_Byte* write = (FT_Byte*) outline->tags + outline->n_points; + + for ( ; count > 0; count--, read++, write++ ) + { + if ( *read & FT_STROKE_TAG_ON ) + *write = FT_CURVE_TAG_ON; + else if ( *read & FT_STROKE_TAG_CUBIC ) + *write = FT_CURVE_TAG_CUBIC; + else + *write = FT_CURVE_TAG_CONIC; + } + } + + /* copy contours */ + { + FT_UInt count = border->num_points; + FT_Byte* tags = border->tags; + FT_Short* write = outline->contours + outline->n_contours; + FT_Short index = (FT_Short) outline->n_points; + + for ( ; count > 0; count--, tags++, index++ ) + { + if ( *tags & FT_STROKE_TAG_END ) + { + *write++ = index; + outline->n_contours++; + } + } + } + + outline->n_points = (short)( outline->n_points + border->num_points ); + + FT_ASSERT( FT_Outline_Check( outline ) == 0 ); + } + + + /***************************************************************************/ + /***************************************************************************/ + /***** *****/ + /***** STROKER *****/ + /***** *****/ + /***************************************************************************/ + /***************************************************************************/ + +#define FT_SIDE_TO_ROTATE(s) (FT_ANGLE_PI2 - (s)*FT_ANGLE_PI) + + typedef struct FT_StrokerRec_ + { + FT_Angle angle_in; + FT_Angle angle_out; + FT_Vector center; + FT_Bool first_point; + FT_Bool subpath_open; + FT_Angle subpath_angle; + FT_Vector subpath_start; + + FT_Stroker_LineCap line_cap; + FT_Stroker_LineJoin line_join; + FT_Fixed miter_limit; + FT_Fixed radius; + + FT_Bool valid; + FT_StrokeBorderRec borders[2]; + FT_Memory memory; + + } FT_StrokerRec; + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_New( FT_Memory memory, + FT_Stroker *astroker ) + { + FT_Error error; + FT_Stroker stroker; + + if ( !FT_NEW( stroker ) ) + { + stroker->memory = memory; + + ft_stroke_border_init( &stroker->borders[0], memory ); + ft_stroke_border_init( &stroker->borders[1], memory ); + } + *astroker = stroker; + return error; + } + + + FT_EXPORT_DEF( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ) + { + stroker->radius = radius; + stroker->line_cap = line_cap; + stroker->line_join = line_join; + stroker->miter_limit = miter_limit; + + stroker->valid = 0; + + ft_stroke_border_reset( &stroker->borders[0] ); + ft_stroke_border_reset( &stroker->borders[1] ); + } + + + FT_EXPORT_DEF( void ) + FT_Stroker_Done( FT_Stroker stroker ) + { + if ( stroker ) + { + FT_Memory memory = stroker->memory; + + ft_stroke_border_done( &stroker->borders[0] ); + ft_stroke_border_done( &stroker->borders[1] ); + + stroker->memory = NULL; + FT_FREE( stroker ); + } + } + + + + /* creates a circular arc at a corner or cap */ + static FT_Error + ft_stroker_arcto( FT_Stroker stroker, + FT_Int side ) + { + FT_Angle total, rotate; + FT_Fixed radius = stroker->radius; + FT_Error error = 0; + FT_StrokeBorder border = stroker->borders + side; + + rotate = FT_SIDE_TO_ROTATE(side); + + total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if (total == FT_ANGLE_PI) + total = -rotate*2; + + error = ft_stroke_border_arcto( border, + &stroker->center, + radius, + stroker->angle_in + rotate, + total ); + border->movable = 0; + return error; + } + + + /* adds a cap at the end of an opened path */ + static FT_Error + ft_stroker_cap( FT_Stroker stroker, + FT_Angle angle, + FT_Int side ) + { + FT_Error error = 0; + + if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) + { + /* add a round cap */ + stroker->angle_in = angle; + stroker->angle_out = angle + FT_ANGLE_PI; + error = ft_stroker_arcto( stroker, side ); + } + else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) + { + /* add a square cap */ + FT_Vector delta, delta2; + FT_Angle rotate = FT_SIDE_TO_ROTATE(side); + FT_Fixed radius = stroker->radius; + FT_StrokeBorder border = stroker->borders + side; + + FT_Vector_From_Polar( &delta2, radius, angle+rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += stroker->center.x + delta2.x; + delta.y += stroker->center.y + delta2.y; + + error = ft_stroke_border_lineto( border, &delta, 0 ); + if (error) goto Exit; + + FT_Vector_From_Polar( &delta2, radius, angle-rotate ); + FT_Vector_From_Polar( &delta, radius, angle ); + + delta.x += delta2.x + stroker->center.x; + delta.y += delta2.y + stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, 0 ); + } + Exit: + return error; + } + + + + /* process an inside corner, i.e. compute intersection */ + static FT_Error + ft_stroker_inside( FT_Stroker stroker, + FT_Int side) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Angle phi, theta, rotate; + FT_Fixed length, thcos, sigma; + FT_Vector delta; + FT_Error error = 0; + + + rotate = FT_SIDE_TO_ROTATE(side); + + /* compute median angle */ + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if ( theta == FT_ANGLE_PI ) + theta = rotate; + else + theta = theta/2; + + phi = stroker->angle_in + theta; + + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); + + if ( sigma < 0x10000L ) + { + FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + border->movable = 0; + } + else + { + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + } + + error = ft_stroke_border_lineto( border, &delta, 0 ); + + return error; + } + + + /* process an outside corner, i.e. compute bevel/miter/round */ + static FT_Error + ft_stroker_outside( FT_Stroker stroker, + FT_Int side ) + { + FT_StrokeBorder border = stroker->borders + side; + FT_Error error; + FT_Angle rotate; + + if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) + { + error = ft_stroker_arcto( stroker, side ); + } + else + { + /* this is a mitered or beveled corner */ + FT_Fixed sigma, radius = stroker->radius; + FT_Angle theta, phi; + FT_Fixed thcos; + FT_Bool miter; + + rotate = FT_SIDE_TO_ROTATE(side); + miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); + + theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + if (theta == FT_ANGLE_PI) + { + theta = rotate; + phi = stroker->angle_in; + } + else + { + theta = theta/2; + phi = stroker->angle_in + theta + rotate; + } + + thcos = FT_Cos( theta ); + sigma = FT_MulFix( stroker->miter_limit, thcos ); + + if ( sigma >= 0x10000L ) + miter = 0; + + + if (miter) /* this is a miter (broken angle) */ + { + FT_Vector middle, delta; + FT_Fixed length; + + /* compute middle point */ + FT_Vector_From_Polar( &middle, FT_MulFix( radius, stroker->miter_limit ), + phi ); + middle.x += stroker->center.x; + middle.y += stroker->center.y; + + /* compute first angle point */ + length = FT_MulFix( radius, FT_DivFix( 0x10000L - sigma, + ft_pos_abs( FT_Sin( theta ) ) ) ); + + FT_Vector_From_Polar( &delta, length, phi + rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, 0 ); + if (error) goto Exit; + + /* compute second angle point */ + FT_Vector_From_Polar( &delta, length, phi - rotate ); + delta.x += middle.x; + delta.y += middle.y; + + error = ft_stroke_border_lineto( border, &delta, 0 ); + if (error) goto Exit; + + /* finally, add a movable end point */ + FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, 1 ); + } + else /* this is a bevel (intersection) */ + { + FT_Fixed length; + FT_Vector delta; + + length = FT_DivFix( stroker->radius, thcos ); + + FT_Vector_From_Polar( &delta, length, phi ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, 0 ); + if (error) goto Exit; + + /* now add end point */ + FT_Vector_From_Polar( &delta, stroker->radius, stroker->angle_out + rotate ); + delta.x += stroker->center.x; + delta.y += stroker->center.y; + + error = ft_stroke_border_lineto( border, &delta, 1 ); + } + } + Exit: + return error; + } + + + static FT_Error + ft_stroker_process_corner( FT_Stroker stroker ) + { + FT_Error error = 0; + FT_Angle turn; + FT_Int inside_side; + + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if (turn == 0) + goto Exit; + + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if (turn < 0) + inside_side = 1; + + /* process the inside side */ + error = ft_stroker_inside( stroker, inside_side ); + if (error) goto Exit; + + /* process the outside side */ + error = ft_stroker_outside( stroker, 1-inside_side ); + + Exit: + return error; + } + + + /* add two points to the left and right borders corresponding to the */ + /* start of the subpath.. */ + static FT_Error + ft_stroker_subpath_start( FT_Stroker stroker, + FT_Angle start_angle ) + { + FT_Vector delta; + FT_Vector point; + FT_Error error; + FT_StrokeBorder border; + + FT_Vector_From_Polar( &delta, stroker->radius, start_angle + FT_ANGLE_PI2 ); + + point.x = stroker->center.x + delta.x; + point.y = stroker->center.y + delta.y; + + border = stroker->borders; + error = ft_stroke_border_moveto( border, &point ); + if (error) goto Exit; + + point.x = stroker->center.x - delta.x; + point.y = stroker->center.y - delta.y; + + border++; + error = ft_stroke_border_moveto( border, &point ); + + /* save angle for last cap */ + stroker->subpath_angle = start_angle; + stroker->first_point = 0; + + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ) + { + FT_Error error = 0; + FT_StrokeBorder border; + FT_Vector delta; + FT_Angle angle; + FT_Int side; + + delta.x = to->x - stroker->center.x; + delta.y = to->y - stroker->center.y; + + angle = FT_Atan2( delta.x, delta.y ); + FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 ); + + /* process corner if necessary */ + if ( stroker->first_point ) + { + /* this is the first segment of a subpath. We need to */ + /* add a point to each border at their respective starting */ + /* point locations.. */ + error = ft_stroker_subpath_start( stroker, angle ); + if (error) goto Exit; + } + else + { + /* process the current corner */ + stroker->angle_out = angle; + error = ft_stroker_process_corner( stroker ); + if (error) goto Exit; + } + + /* now add a line segment to both the "inside" and "outside" paths */ + + for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) + { + FT_Vector point; + + point.x = to->x + delta.x; + point.y = to->y + delta.y; + + error = ft_stroke_border_lineto( border, &point, 1 ); + if (error) goto Exit; + + delta.x = -delta.x; + delta.y = -delta.y; + } + + stroker->angle_in = angle; + stroker->center = *to; + + Exit: + return error; + } + + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ) + { + FT_Error error = 0; + FT_Vector bez_stack[34]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 30; + FT_Angle start_angle; + FT_Bool first_arc = 1; + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control; + arc[2] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_out; + + angle_in = angle_out = 0; /* remove compiler warnings */ + + if ( arc < limit && + !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) + { + ft_conic_split( arc ); + arc += 2; + continue; + } + + if ( first_arc ) + { + first_arc = 0; + + start_angle = angle_in; + + /* process corner if necessary */ + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, start_angle ); + else + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + } + + /* the arc's angle is small enough, we can add it directly to each */ + /* border.. */ + { + FT_Vector ctrl, end; + FT_Angle theta, phi, rotate; + FT_Fixed length; + FT_Int side; + + theta = FT_Angle_Diff( angle_in, angle_out )/2; + phi = angle_in + theta; + length = FT_DivFix( stroker->radius, FT_Cos(theta) ); + + for ( side = 0; side <= 1; side++ ) + { + rotate = FT_SIDE_TO_ROTATE(side); + + /* compute control point */ + FT_Vector_From_Polar( &ctrl, length, phi + rotate ); + ctrl.x += arc[1].x; + ctrl.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + error = ft_stroke_border_conicto( stroker->borders + side, &ctrl, &end ); + if (error) goto Exit; + } + } + + arc -= 2; + + if (arc < bez_stack) + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_Error error = 0; + FT_Vector bez_stack[37]; + FT_Vector* arc; + FT_Vector* limit = bez_stack + 32; + FT_Angle start_angle; + FT_Bool first_arc = 1; + + arc = bez_stack; + arc[0] = *to; + arc[1] = *control2; + arc[2] = *control1; + arc[3] = stroker->center; + + while ( arc >= bez_stack ) + { + FT_Angle angle_in, angle_mid, angle_out; + + /* remove compiler warnings */ + angle_in = angle_out = angle_mid = 0; + + if ( arc < limit && + !ft_cubic_is_small_enough( arc, &angle_in, &angle_mid, &angle_out ) ) + { + ft_cubic_split( arc ); + arc += 3; + continue; + } + + if ( first_arc ) + { + first_arc = 0; + + /* process corner if necessary */ + start_angle = angle_in; + + if ( stroker->first_point ) + error = ft_stroker_subpath_start( stroker, start_angle ); + else + { + stroker->angle_out = start_angle; + error = ft_stroker_process_corner( stroker ); + } + if (error) goto Exit; + } + + /* the arc's angle is small enough, we can add it directly to each */ + /* border.. */ + { + FT_Vector ctrl1, ctrl2, end; + FT_Angle theta1, phi1, theta2, phi2, rotate; + FT_Fixed length1, length2; + FT_Int side; + + theta1 = ft_pos_abs( angle_mid - angle_in )/2; + theta2 = ft_pos_abs( angle_out - angle_mid )/2; + phi1 = (angle_mid+angle_in)/2; + phi2 = (angle_mid+angle_out)/2; + length1 = FT_DivFix( stroker->radius, FT_Cos(theta1) ); + length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); + + for ( side = 0; side <= 1; side++ ) + { + rotate = FT_SIDE_TO_ROTATE(side); + + /* compute control points */ + FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); + ctrl1.x += arc[2].x; + ctrl1.y += arc[2].y; + + FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate ); + ctrl2.x += arc[1].x; + ctrl2.y += arc[1].y; + + /* compute end point */ + FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); + end.x += arc[0].x; + end.y += arc[0].y; + + error = ft_stroke_border_cubicto( stroker->borders + side, &ctrl1, &ctrl2, &end ); + if (error) goto Exit; + } + } + + arc -= 3; + if (arc < bez_stack) + stroker->angle_in = angle_out; + } + + stroker->center = *to; + + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ) + { + /* we cannot process the first point, because there is not enough */ + /* information regarding its corner/cap. The latter will be processed */ + /* in the "end_subpath" routine */ + /* */ + stroker->first_point = 1; + stroker->center = *to; + stroker->subpath_open = open; + + /* record the subpath start point index for each border */ + stroker->subpath_start = *to; + return 0; + } + + + static + FT_Error ft_stroker_add_reverse_left( FT_Stroker stroker, + FT_Bool open ) + { + FT_StrokeBorder right = stroker->borders + 0; + FT_StrokeBorder left = stroker->borders + 1; + FT_Int new_points; + FT_Error error = 0; + + FT_ASSERT( left->start >= 0 ); + + new_points = left->num_points - left->start; + if ( new_points > 0 ) + { + error = ft_stroke_border_grow( right, (FT_UInt)new_points ); + if (error) goto Exit; + { + FT_Vector* dst_point = right->points + right->num_points; + FT_Byte* dst_tag = right->tags + right->num_points; + FT_Vector* src_point = left->points + left->num_points - 1; + FT_Byte* src_tag = left->tags + left->num_points - 1; + + while ( src_point >= left->points + left->start ) + { + *dst_point = *src_point; + *dst_tag = *src_tag; + + if (open) + dst_tag[0] &= ~(FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + else + { + /* switch begin/end tags if necessary.. */ + if (dst_tag[0] & (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END)) + dst_tag[0] ^= (FT_STROKE_TAG_BEGIN | FT_STROKE_TAG_END); + } + + src_point--; + src_tag--; + dst_point++; + dst_tag++; + } + } + left->num_points = left->start; + right->num_points += new_points; + + right->movable = 0; + left->movable = 0; + } + Exit: + return error; + } + + + /* there's a lot of magic in this function !! */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ) + { + FT_Error error = 0; + + if ( stroker->subpath_open ) + { + FT_StrokeBorder right = stroker->borders; + + /* all right, this is an opened path, we need to add a cap between */ + /* right & left, add the reverse of left, then add a final cap between */ + /* left & right.. */ + error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); + if (error) goto Exit; + + /* add reversed points from "left" to "right" */ + error = ft_stroker_add_reverse_left( stroker, 1 ); + if (error) goto Exit; + + /* now add the final cap */ + stroker->center = stroker->subpath_start; + error = ft_stroker_cap( stroker, stroker->subpath_angle+FT_ANGLE_PI, 0 ); + if (error) goto Exit; + + /* now, end the right subpath accordingly. the left one is */ + /* rewind and doesn't need further processing.. */ + ft_stroke_border_close( right ); + } + else + { + FT_Angle turn; + FT_Int inside_side; + + /* process the corner ... */ + stroker->angle_out = stroker->subpath_angle; + turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); + + /* no specific corner processing is required if the turn is 0 */ + if (turn != 0) + { + /* when we turn to the right, the inside side is 0 */ + inside_side = 0; + + /* otherwise, the inside side is 1 */ + if (turn < 0) + inside_side = 1; + + /* IMPORTANT: WE DO NOT PROCESS THE INSIDE BORDER HERE !! */ + /* process the inside side */ + /* error = ft_stroker_inside( stroker, inside_side ); + if (error) goto Exit; */ + + /* process the outside side */ + error = ft_stroker_outside( stroker, 1-inside_side ); + if (error) goto Exit; + } + + /* we will first end our two subpaths */ + ft_stroke_border_close( stroker->borders + 0 ); + ft_stroke_border_close( stroker->borders + 1 ); + + /* now, add the reversed left subpath to "right" */ + error = ft_stroker_add_reverse_left( stroker, 0 ); + if (error) goto Exit; + } + + Exit: + return error; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ) + { + FT_UInt count1, count2, num_points = 0; + FT_UInt count3, count4, num_contours = 0; + FT_Error error; + + error = ft_stroke_border_get_counts( stroker->borders+0, &count1, &count2 ); + if (error) goto Exit; + + error = ft_stroke_border_get_counts( stroker->borders+1, &count3, &count4 ); + if (error) goto Exit; + + num_points = count1 + count3; + num_contours = count2 + count4; + + stroker->valid = 1; + + Exit: + *anum_points = num_points; + *anum_contours = num_contours; + return error; + } + + + FT_EXPORT_DEF( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ) + { + if ( stroker->valid ) + { + ft_stroke_border_export( stroker->borders+0, outline ); + ft_stroke_border_export( stroker->borders+1, outline ); + } + } + + + + + + /* + * the following is very similar to FT_Outline_Decompose, except + * that we do support opened paths, and do not scale the outline + */ + FT_EXPORT_DEF( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + FT_Error error; + + FT_Int n; /* index of contour in outline */ + FT_UInt first; /* index of first point in contour */ + FT_Int tag; /* current point's state */ + FT_Int in_path; + + if ( !outline || !stroker ) + return FT_Err_Invalid_Argument; + + first = 0; + + in_path = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + FT_Int last; /* index of last point in contour */ + + + last = outline->contours[n]; + limit = outline->points + last; + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + error = FT_Stroker_BeginSubPath( stroker, &v_start, opened ); + if ( error ) + goto Exit; + + in_path = 1; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = point->x; + vec.y = point->y; + + error = FT_Stroker_LineTo( stroker, &vec ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec = point[0]; + + if ( tag == FT_CURVE_TAG_ON ) + { + error = FT_Stroker_ConicTo( stroker, &v_control, &vec ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = FT_Stroker_ConicTo( stroker, &v_control, &v_start ); + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1 = point[-2]; + vec2 = point[-1]; + + if ( point <= limit ) + { + FT_Vector vec; + + + vec = point[0]; + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec ); + if ( error ) + goto Exit; + continue; + } + + error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start ); + goto Close; + } + } + } + + Close: + if ( error ) + goto Exit; + + error = FT_Stroker_EndSubPath( stroker ); + if ( error ) + goto Exit; + + first = last + 1; + } + + return 0; + + Exit: + return error; + + Invalid_Outline: + return FT_Err_Invalid_Outline; + } diff --git a/lib/freetype/src/base/ftsynth.c b/lib/freetype/src/base/ftsynth.c new file mode 100644 index 0000000..45459f3 --- /dev/null +++ b/lib/freetype/src/base/ftsynth.c @@ -0,0 +1,286 @@ +/***************************************************************************/ +/* */ +/* ftsynth.c */ +/* */ +/* FreeType synthesizing code for emboldening and slanting (body). */ +/* */ +/* Copyright 2000-2001 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CALC_H +#include FT_OUTLINE_H +#include FT_TRIGONOMETRY_H +#include FT_SYNTHESIS_H + + +#define FT_BOLD_THRESHOLD 0x0100 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) + { + FT_Matrix transform; + FT_Outline* outline = &slot->outline; + + + /* only oblique outline glyphs */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + return; + + /* we don't touch the advance width */ + + /* For italic, simply apply a shear transform, with an angle */ + /* of about 12 degrees. */ + + transform.xx = 0x10000L; + transform.yx = 0x00000L; + + transform.xy = 0x06000L; + transform.yy = 0x10000L; + + FT_Outline_Transform( outline, &transform ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + + static int + ft_test_extrema( FT_Outline* outline, + int n ) + { + FT_Vector *prev, *cur, *next; + FT_Pos product; + FT_Int c, first, last; + + + /* we need to compute the `previous' and `next' point */ + /* for these extrema. */ + cur = outline->points + n; + prev = cur - 1; + next = cur + 1; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + last = outline->contours[c]; + + if ( n == first ) + prev = outline->points + last; + + if ( n == last ) + next = outline->points + first; + + first = last + 1; + } + + product = FT_MulDiv( cur->x - prev->x, /* in.x */ + next->y - cur->y, /* out.y */ + 0x40 ) + - + FT_MulDiv( cur->y - prev->y, /* in.y */ + next->x - cur->x, /* out.x */ + 0x40 ); + + if ( product ) + product = product > 0 ? 1 : -1; + + return product; + } + + + /* Compute the orientation of path filling. It differs between TrueType */ + /* and Type1 formats. We could use the `FT_OUTLINE_REVERSE_FILL' flag, */ + /* but it is better to re-compute it directly (it seems that this flag */ + /* isn't correctly set for some weird composite glyphs currently). */ + /* */ + /* We do this by computing bounding box points, and computing their */ + /* curvature. */ + /* */ + /* The function returns either 1 or -1. */ + /* */ + static int + ft_get_orientation( FT_Outline* outline ) + { + FT_BBox box; + FT_BBox indices; + int n, last; + + + indices.xMin = -1; + indices.yMin = -1; + indices.xMax = -1; + indices.yMax = -1; + + box.xMin = box.yMin = 32767; + box.xMax = box.yMax = -32768; + + /* is it empty ? */ + if ( outline->n_contours < 1 ) + return 1; + + last = outline->contours[outline->n_contours - 1]; + + for ( n = 0; n <= last; n++ ) + { + FT_Pos x, y; + + + x = outline->points[n].x; + if ( x < box.xMin ) + { + box.xMin = x; + indices.xMin = n; + } + if ( x > box.xMax ) + { + box.xMax = x; + indices.xMax = n; + } + + y = outline->points[n].y; + if ( y < box.yMin ) + { + box.yMin = y; + indices.yMin = n; + } + if ( y > box.yMax ) + { + box.yMax = y; + indices.yMax = n; + } + } + + /* test orientation of the xmin */ + n = ft_test_extrema( outline, indices.xMin ); + if ( n ) + goto Exit; + + n = ft_test_extrema( outline, indices.yMin ); + if ( n ) + goto Exit; + + n = ft_test_extrema( outline, indices.xMax ); + if ( n ) + goto Exit; + + n = ft_test_extrema( outline, indices.yMax ); + if ( !n ) + n = 1; + + Exit: + return n; + } + + + FT_EXPORT_DEF( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) + { + FT_Vector* points; + FT_Vector v_prev, v_first, v_next, v_cur; + FT_Pos distance; + FT_Outline* outline = &slot->outline; + FT_Face face = FT_SLOT_FACE( slot ); + FT_Angle rotate, angle_in, angle_out; + FT_Int c, n, first, orientation; + + + /* only embolden outline glyph images */ + if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + return; + + /* compute control distance */ + distance = FT_MulFix( face->units_per_EM / 60, + face->size->metrics.y_scale ); + + orientation = ft_get_orientation( outline ); + rotate = FT_ANGLE_PI2*orientation; + + points = outline->points; + + first = 0; + for ( c = 0; c < outline->n_contours; c++ ) + { + int last = outline->contours[c]; + + + v_first = points[first]; + v_prev = points[last]; + v_cur = v_first; + + for ( n = first; n <= last; n++ ) + { + FT_Pos d; + FT_Vector in, out; + FT_Fixed scale; + FT_Angle angle_diff; + + + if ( n < last ) v_next = points[n + 1]; + else v_next = v_first; + + /* compute the in and out vectors */ + in.x = v_cur.x - v_prev.x; + in.y = v_cur.y - v_prev.y; + + out.x = v_next.x - v_cur.x; + out.y = v_next.y - v_cur.y; + + angle_in = FT_Atan2( in.x, in.y ); + angle_out = FT_Atan2( out.x, out.y ); + angle_diff = FT_Angle_Diff( angle_in, angle_out ); + scale = FT_Cos( angle_diff/2 ); + + if ( scale < 0x400L && scale > -0x400L ) + { + if ( scale >= 0 ) + scale = 0x400L; + else + scale = -0x400L; + } + + d = FT_DivFix( distance, scale ); + + FT_Vector_From_Polar( &in, d, angle_in + angle_diff/2 - rotate ); + + outline->points[n].x = v_cur.x + distance + in.x; + outline->points[n].y = v_cur.y + distance + in.y; + + v_prev = v_cur; + v_cur = v_next; + } + + first = last + 1; + } + + slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + distance*4 ) & -64; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftsysio.c b/lib/freetype/src/base/ftsysio.c new file mode 100644 index 0000000..344ee51 --- /dev/null +++ b/lib/freetype/src/base/ftsysio.c @@ -0,0 +1,131 @@ +#include <ft2build.h> +#include FT_SYSTEM_STREAM_H + +#include <stdio.h> + + /* the ISO/ANSI standard stream object */ + typedef struct FT_StdStreamRec_ + { + FT_StreamRec stream; + FILE* file; + const char* pathname; + + } FT_StdStreamRec, *FT_StdStream; + + + + /* read bytes from a standard stream */ + static FT_ULong + ft_std_stream_read( FT_StdStream stream, + FT_Byte* buffer, + FT_ULong size ) + { + long read_bytes; + + read_bytes = fread( buffer, 1, size, stream->file ); + if ( read_bytes < 0 ) + read_bytes = 0; + + return (FT_ULong) read_bytes; + } + + + /* seek the standard stream to a new position */ + static FT_Error + ft_std_stream_seek( FT_StdStream stream, + FT_ULong pos ) + { + return ( fseek( stream->file, pos, SEEK_SET ) < 0 ) + ? FT_Err_Stream_Seek + : FT_Err_Ok; + } + + + /* close a standard stream */ + static void + ft_std_stream_done( FT_StdStream stream ) + { + fclose( stream->file ); + stream->file = NULL; + stream->pathname = NULL; + } + + + /* open a standard stream from a given pathname */ + static void + ft_std_stream_init( FT_StdStream stream, + const char* pathname ) + { + FT_ASSERT( pathname != NULL ); + + stream->file = fopen( pathname, "rb" ); + if ( stream->file == NULL ) + { + FT_ERROR(( "iso.stream.init: could not open '%s'\n", pathname )); + FT_XTHROW( FT_Err_Stream_Open ); + } + + /* compute total size in bytes */ + fseek( file, 0, SEEK_END ); + FT_STREAM__SIZE(stream) = ftell( file ); + fseek( file, 0, SEEK_SET ); + + stream->pathname = pathname; + stream->pos = 0; + + FT_TRACE1(( "iso.stream.init: opened '%s' (%ld bytes) succesfully\n", + pathname, FT_STREAM__SIZE(stream) )); + } + + + static void + ft_std_stream_class_init( FT_ClassRec* _clazz ) + { + FT_StreamClassRec* clazz = FT_STREAM_CLASS(_clazz); + + clazz->stream_read = (FT_Stream_ReadFunc) ft_std_stream_read; + clazz->stream_seek = (FT_Stream_SeekFunc) ft_std_stream_seek; + } + + + static const FT_TypeRec ft_std_stream_type; + { + "StreamClass", + NULL, + + sizeof( FT_ClassRec ), + ft_stream_class_init, + NULL, + + sizeof( FT_StdStreamRec ), + ft_std_stream_init, + ft_std_stream_done, + NULL, + }; + + + + FT_EXPORT_DEF( FT_Stream ) + ft_std_stream_new( FT_Memory memory, + const char* pathname ) + { + FT_Class clazz; + + clazz = ft_class_from_type( memory, &ft_std_stream_type ); + + return (FT_Stream) ft_object_new( clazz, pathname ); + } + + + FT_EXPORT_DEF( void ) + ft_std_stream_create( FT_Memory memory, + const char* pathname, + FT_Stream* astream ) + { + FT_Class clazz; + + clazz = ft_class_from_type( memory, &ft_std_stream_type ); + + ft_object_create( clazz, pathname, FT_OBJECT_P(astream) ); + } + diff --git a/lib/freetype/src/base/ftsysmem.c b/lib/freetype/src/base/ftsysmem.c new file mode 100644 index 0000000..6a34f69 --- /dev/null +++ b/lib/freetype/src/base/ftsysmem.c @@ -0,0 +1,30 @@ +#include <ft2build.h> +#include FT_SYSTEM_MEMORY_H + + static FT_Memory + ft_memory_new_default( FT_ULong size ) + { + return (FT_Memory) ft_malloc( size ); + } + + static void + ft_memory_destroy_default( FT_Memory memory ) + { + ft_free( memory ); + } + + + /* notice that in normal builds, we use the ISO C library functions */ + /* 'malloc', 'free' and 'realloc' directly.. */ + /* */ + static const FT_Memory_FuncsRec ft_memory_funcs_default_rec = + { + (FT_Memory_CreateFunc) ft_memory_new_iso, + (FT_Memory_DestroyFunc) ft_memory_destroy_iso, + (FT_Memory_AllocFunc) ft_malloc, + (FT_Memory_FreeFunc) ft_free, + (FT_Memory_ReallocFunc) ft_realloc + }; + + FT_APIVAR_DEF( const FT_Memory_Funcs ) + ft_memory_funcs_default = &ft_memory_funcs_defaults_rec; diff --git a/lib/freetype/src/base/ftsystem.c b/lib/freetype/src/base/ftsystem.c new file mode 100644 index 0000000..2365de2 --- /dev/null +++ b/lib/freetype/src/base/ftsystem.c @@ -0,0 +1,303 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* ANSI-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 contains the default interface used by FreeType to access */ + /* low-level, i.e. memory management, i/o access as well as thread */ + /* synchronisation. It can be replaced by user-specific routines if */ + /* necessary. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + +#include <stdio.h> +#include <stdlib.h> + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* It is not necessary to do any error checking for the */ + /* allocation-related functions. This will be done by the higher level */ + /* routines like FT_Alloc() or FT_Realloc(). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_alloc */ + /* */ + /* <Description> */ + /* The memory allocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* <Return> */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return malloc( size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_realloc */ + /* */ + /* <Description> */ + /* The memory reallocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* <Return> */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return realloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_free */ + /* */ + /* <Description> */ + /* The memory release function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + free( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_close */ + /* */ + /* <Description> */ + /* The function to close a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_ansi_stream_close( FT_Stream stream ) + { + fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_io */ + /* */ + /* <Description> */ + /* The function to open a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + /* offset :: The position in the data stream to start reading. */ + /* */ + /* buffer :: The address of buffer to store the read data. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* <Return> */ + /* The number of bytes actually read. */ + /* */ + FT_CALLBACK_DEF( unsigned long ) + ft_ansi_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FILE* file; + + + file = STREAM_FILE( stream ); + + fseek( file, offset, SEEK_SET ); + + return (unsigned long)fread( buffer, 1, count, file ); + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + FILE* file; + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + + file = fopen( filepathname, "rb" ); + if ( !file ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + + fseek( file, 0, SEEK_END ); + stream->size = ftell( file ); + fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->pathname.pointer = (char*)filepathname; + stream->pos = 0; + + stream->read = ft_ansi_stream_io; + stream->close = ft_ansi_stream_close; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)malloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif + memory->free( memory, memory ); + } + + +/* END */ diff --git a/lib/freetype/src/base/fttrigon.c b/lib/freetype/src/base/fttrigon.c new file mode 100644 index 0000000..c16fa24 --- /dev/null +++ b/lib/freetype/src/base/fttrigon.c @@ -0,0 +1,487 @@ +/***************************************************************************/ +/* */ +/* fttrigon.c */ +/* */ +/* FreeType trigonometric functions (body). */ +/* */ +/* Copyright 2001 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 <ft2build.h> +#include FT_TRIGONOMETRY_H + + + /* the following is 0.2715717684432231 * 2^30 */ +#define FT_TRIG_COSCALE 0x11616E8EUL + + /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ +#define FT_TRIG_MAX_ITERS 23 + + static const FT_Fixed + ft_trig_arctan_table[24] = + { + 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L, + 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, + 57L, 29L, 14L, 7L, 4L, 2L, 1L + }; + + /* the Cordic shrink factor, multiplied by 2^32 */ +#define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */ + + +#ifdef FT_CONFIG_HAS_INT64 + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_Int64 v; + + + s = val; + val = ( val >= 0 ) ? val : -val; + + v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; + val = (FT_Fixed)( v >> 32 ); + + return ( s >= 0 ) ? val : -val; + } + +#else /* !FT_CONFIG_HAS_INT64 */ + + /* multiply a given value by the CORDIC shrink factor */ + static FT_Fixed + ft_trig_downscale( FT_Fixed val ) + { + FT_Fixed s; + FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; + + + s = val; + val = ( val >= 0 ) ? val : -val; + + v1 = (FT_UInt32)val >> 16; + v2 = (FT_UInt32)val & 0xFFFF; + + k1 = FT_TRIG_SCALE >> 16; /* constant */ + k2 = FT_TRIG_SCALE & 0xFFFF; /* constant */ + + hi = k1 * v1; + lo1 = k1 * v2 + k2 * v1; /* can't overflow */ + + lo2 = ( k2 * v2 ) >> 16; + lo3 = ( lo1 >= lo2 ) ? lo1 : lo2; + lo1 += lo2; + + hi += lo1 >> 16; + if ( lo1 < lo3 ) + hi += 0x10000UL; + + val = (FT_Fixed)hi; + + return ( s >= 0 ) ? val : -val; + } + +#endif /* !FT_CONFIG_HAS_INT64 */ + + + static FT_Int + ft_trig_prenorm( FT_Vector* vec ) + { + FT_Fixed x, y, z; + FT_Int shift; + + + x = vec->x; + y = vec->y; + + z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); + shift = 0; + + if ( z < ( 1L << 27 ) ) + { + do + { + shift++; + z <<= 1; + } while ( z < ( 1L << 27 ) ); + + vec->x = x << shift; + vec->y = y << shift; + } + else if ( z > ( 1L << 28 ) ) + { + do + { + shift++; + z >>= 1; + } while ( z > ( 1L << 28 ) ); + + vec->x = x >> shift; + vec->y = y >> shift; + shift = -shift; + } + return shift; + } + + + static void + ft_trig_pseudo_rotate( FT_Vector* vec, + FT_Angle theta ) + { + FT_Int i; + FT_Fixed x, y, xtemp; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get angle between -90 and 90 degrees */ + while ( theta <= -FT_ANGLE_PI2 ) + { + x = -x; + y = -y; + theta += FT_ANGLE_PI; + } + + while ( theta > FT_ANGLE_PI2 ) + { + x = -x; + y = -y; + theta -= FT_ANGLE_PI; + } + + /* Initial pseudorotation, with left shift */ + arctanptr = ft_trig_arctan_table; + + if ( theta < 0 ) + { + xtemp = x + ( y << 1 ); + y = y - ( x << 1 ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( y << 1 ); + y = y + ( x << 1 ); + x = xtemp; + theta -= *arctanptr++; + } + + /* Subsequent pseudorotations, with right shifts */ + i = 0; + do + { + if ( theta < 0 ) + { + xtemp = x + ( y >> i ); + y = y - ( x >> i ); + x = xtemp; + theta += *arctanptr++; + } + else + { + xtemp = x - ( y >> i ); + y = y + ( x >> i ); + x = xtemp; + theta -= *arctanptr++; + } + } while ( ++i < FT_TRIG_MAX_ITERS ); + + vec->x = x; + vec->y = y; + } + + + static void + ft_trig_pseudo_polarize( FT_Vector* vec ) + { + FT_Fixed theta; + FT_Fixed yi, i; + FT_Fixed x, y; + const FT_Fixed *arctanptr; + + + x = vec->x; + y = vec->y; + + /* Get the vector into the right half plane */ + theta = 0; + if ( x < 0 ) + { + x = -x; + y = -y; + theta = 2 * FT_ANGLE_PI2; + } + + if ( y > 0 ) + theta = - theta; + + arctanptr = ft_trig_arctan_table; + + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x << 1 ); + x = x - ( y << 1 ); + y = yi; + theta -= *arctanptr++; /* Subtract angle */ + } + else + { + /* Rotate negative */ + yi = y - ( x << 1 ); + x = x + ( y << 1 ); + y = yi; + theta += *arctanptr++; /* Add angle */ + } + + i = 0; + do + { + if ( y < 0 ) + { + /* Rotate positive */ + yi = y + ( x >> i ); + x = x - ( y >> i ); + y = yi; + theta -= *arctanptr++; + } + else + { + /* Rotate negative */ + yi = y - ( x >> i ); + x = x + ( y >> i ); + y = yi; + theta += *arctanptr++; + } + } while ( ++i < FT_TRIG_MAX_ITERS ); + + /* round theta */ + if ( theta >= 0 ) + theta = ( theta + 16 ) & -32; + else + theta = - (( -theta + 16 ) & -32); + + vec->x = x; + vec->y = theta; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Cos( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_COSCALE >> 2; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return v.x / ( 1 << 12 ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Sin( FT_Angle angle ) + { + return FT_Cos( FT_ANGLE_PI2 - angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Tan( FT_Angle angle ) + { + FT_Vector v; + + + v.x = FT_TRIG_COSCALE >> 2; + v.y = 0; + ft_trig_pseudo_rotate( &v, angle ); + + return FT_DivFix( v.y, v.x ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Atan2( FT_Fixed dx, + FT_Fixed dy ) + { + FT_Vector v; + + + if ( dx == 0 && dy == 0 ) + return 0; + + v.x = dx; + v.y = dy; + ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + return v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ) + { + vec->x = FT_TRIG_COSCALE >> 2; + vec->y = 0; + ft_trig_pseudo_rotate( vec, angle ); + vec->x >>= 12; + vec->y >>= 12; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ) + { + FT_Int shift; + FT_Vector v; + + + v.x = vec->x; + v.y = vec->y; + + if ( angle && ( v.x != 0 || v.y != 0 ) ) + { + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_rotate( &v, angle ); + v.x = ft_trig_downscale( v.x ); + v.y = ft_trig_downscale( v.y ); + + if ( shift >= 0 ) + { + vec->x = v.x >> shift; + vec->y = v.y >> shift; + } + else + { + shift = -shift; + vec->x = v.x << shift; + vec->y = v.y << shift; + } + } + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + /* handle trivial cases */ + if ( v.x == 0 ) + { + return ( v.y >= 0 ) ? v.y : -v.y; + } + else if ( v.y == 0 ) + { + return ( v.x >= 0 ) ? v.x : -v.x; + } + + /* general case */ + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + if ( shift > 0 ) + return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; + + return v.x << -shift; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ) + { + FT_Int shift; + FT_Vector v; + + + v = *vec; + + if ( v.x == 0 && v.y == 0 ) + return; + + shift = ft_trig_prenorm( &v ); + ft_trig_pseudo_polarize( &v ); + + v.x = ft_trig_downscale( v.x ); + + *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift ); + *angle = v.y; + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ) + { + vec->x = length; + vec->y = 0; + + FT_Vector_Rotate( vec, angle ); + } + + + /* documentation is in fttrigon.h */ + + FT_EXPORT_DEF( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ) + { + FT_Angle delta = angle2 - angle1; + + delta %= FT_ANGLE_2PI; + if ( delta < 0 ) + delta += FT_ANGLE_2PI; + + if ( delta > FT_ANGLE_PI ) + delta -= FT_ANGLE_2PI; + + return delta; + } + + +/* END */ diff --git a/lib/freetype/src/base/fttype1.c b/lib/freetype/src/base/fttype1.c new file mode 100644 index 0000000..d8b1886 --- /dev/null +++ b/lib/freetype/src/base/fttype1.c @@ -0,0 +1,87 @@ +/***************************************************************************/ +/* */ +/* fttype1.c */ +/* */ +/* FreeType utility file for PS names support (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_TYPE42_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfoRec* afont_info ) + { + PS_FontInfo font_info = NULL; + FT_Error error = FT_Err_Invalid_Argument; + const char* driver_name; + + + if ( face && face->driver && face->driver->root.clazz ) + { + driver_name = face->driver->root.clazz->module_name; + if ( ft_strcmp( driver_name, "type1" ) == 0 ) + font_info = &((T1_Face)face)->type1.font_info; + else if ( ft_strcmp( driver_name, "t1cid" ) == 0 ) + font_info = &((CID_Face)face)->cid.font_info; + else if ( ft_strcmp( driver_name, "type42" ) == 0 ) + font_info = &((T42_Face)face)->type1.font_info; + } + if ( font_info != NULL ) + { + *afont_info = *font_info; + error = FT_Err_Ok; + } + + return error; + } + + + /* XXX: Bad hack, but I didn't want to change several drivers here. */ + + /* documentation is in t1tables.h */ + + FT_EXPORT_DEF( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ) + { + FT_Int result = 0; + const char* driver_name; + + + if ( face && face->driver && face->driver->root.clazz ) + { + /* Currently, only the type1, type42, and cff drivers provide */ + /* reliable glyph names... */ + + /* We could probably hack the TrueType driver to recognize */ + /* certain cases where the glyph names are most certainly */ + /* correct (e.g. using a 20 or 22 format `post' table), but */ + /* this will probably happen later... */ + + driver_name = face->driver->root.clazz->module_name; + result = ( ft_strcmp( driver_name, "type1" ) == 0 || + ft_strcmp( driver_name, "type42" ) == 0 || + ft_strcmp( driver_name, "cff" ) == 0 ); + } + + return result; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftutil.c b/lib/freetype/src/base/ftutil.c new file mode 100644 index 0000000..451bee5 --- /dev/null +++ b/lib/freetype/src/base/ftutil.c @@ -0,0 +1,330 @@ +/***************************************************************************/ +/* */ +/* ftutil.c */ +/* */ +/* FreeType utility file for memory and list management (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_MEMORY_H +#include FT_LIST_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_memory + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** M E M O R Y M A N A G E M E N T *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* documentation is in ftmemory.h */ + + FT_BASE_DEF( FT_Error ) + FT_Alloc( FT_Memory memory, + FT_Long size, + void* *P ) + { + FT_ASSERT( P != 0 ); + + if ( size > 0 ) + { + *P = memory->alloc( memory, size ); + if ( !*P ) + { + FT_ERROR(( "FT_Alloc:" )); + FT_ERROR(( " Out of memory? (%ld requested)\n", + size )); + + return FT_Err_Out_Of_Memory; + } + FT_MEM_ZERO( *P, size ); + } + else + *P = NULL; + + FT_TRACE7(( "FT_Alloc:" )); + FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", + size, *P, P )); + + return FT_Err_Ok; + } + + + /* documentation is in ftmemory.h */ + + FT_BASE_DEF( FT_Error ) + FT_Realloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void** P ) + { + void* Q; + + + FT_ASSERT( P != 0 ); + + /* if the original pointer is NULL, call FT_Alloc() */ + if ( !*P ) + return FT_Alloc( memory, size, P ); + + /* if the new block if zero-sized, clear the current one */ + if ( size <= 0 ) + { + FT_Free( memory, P ); + return FT_Err_Ok; + } + + Q = memory->realloc( memory, current, size, *P ); + if ( !Q ) + goto Fail; + + if ( size > current ) + FT_MEM_ZERO( (char*)Q + current, size - current ); + + *P = Q; + return FT_Err_Ok; + + Fail: + FT_ERROR(( "FT_Realloc:" )); + FT_ERROR(( " Failed (current %ld, requested %ld)\n", + current, size )); + return FT_Err_Out_Of_Memory; + } + + + /* documentation is in ftmemory.h */ + + FT_BASE_DEF( void ) + FT_Free( FT_Memory memory, + void** P ) + { + FT_TRACE7(( "FT_Free:" )); + FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n", + P, P ? *P : (void*)0 )); + + if ( P && *P ) + { + memory->free( memory, *P ); + *P = 0; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** *****/ + /***** D O U B L Y L I N K E D L I S T S *****/ + /***** *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + +#undef FT_COMPONENT +#define FT_COMPONENT trace_list + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + if ( cur->data == data ) + return cur; + + cur = cur->next; + } + + return (FT_ListNode)0; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Add( FT_List list, + FT_ListNode node ) + { + FT_ListNode before = list->tail; + + + node->next = 0; + node->prev = before; + + if ( before ) + before->next = node; + else + list->head = node; + + list->tail = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ) + { + FT_ListNode after = list->head; + + + node->next = after; + node->prev = 0; + + if ( !after ) + list->tail = node; + else + after->prev = node; + + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + if ( before ) + before->next = after; + else + list->head = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Up( FT_List list, + FT_ListNode node ) + { + FT_ListNode before, after; + + + before = node->prev; + after = node->next; + + /* check whether we are already on top of the list */ + if ( !before ) + return; + + before->next = after; + + if ( after ) + after->prev = before; + else + list->tail = before; + + node->prev = 0; + node->next = list->head; + list->head->prev = node; + list->head = node; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ) + { + FT_ListNode cur = list->head; + FT_Error error = FT_Err_Ok; + + + while ( cur ) + { + FT_ListNode next = cur->next; + + + error = iterator( cur, user ); + if ( error ) + break; + + cur = next; + } + + return error; + } + + + /* documentation is in ftlist.h */ + + FT_EXPORT_DEF( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ) + { + FT_ListNode cur; + + + cur = list->head; + while ( cur ) + { + FT_ListNode next = cur->next; + void* data = cur->data; + + + if ( destroy ) + destroy( memory, data, user ); + + FT_FREE( cur ); + cur = next; + } + + list->head = 0; + list->tail = 0; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftwinfnt.c b/lib/freetype/src/base/ftwinfnt.c new file mode 100644 index 0000000..88644e9 --- /dev/null +++ b/lib/freetype/src/base/ftwinfnt.c @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.c */ +/* */ +/* FreeType API for accessing Windows FNT specific info (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_WINFONTS_H +#include FT_INTERNAL_FNT_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + + FT_EXPORT_DEF( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *header ) + { + FT_Error error; + + error = FT_Err_Invalid_Argument; + + if ( face != NULL && face->driver != NULL ) + { + FT_Module driver = (FT_Module) face->driver; + + + if ( driver->clazz && driver->clazz->module_name && + ft_strcmp( driver->clazz->module_name, "winfonts" ) == 0 ) + { + FNT_Size size = (FNT_Size)face->size; + FNT_Font font = size->font; + + if (font) + { + FT_MEM_COPY( header, &font->header, sizeof(*header) ); + error = 0; + } + } + } + return error; + } + + +/* END */ diff --git a/lib/freetype/src/base/ftxf86.c b/lib/freetype/src/base/ftxf86.c new file mode 100644 index 0000000..6fd7722 --- /dev/null +++ b/lib/freetype/src/base/ftxf86.c @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* ftxf86.c */ +/* */ +/* FreeType utility file for X11 support (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_XFREE86_H +#include FT_INTERNAL_OBJECTS_H + + /* XXX: This really is a sad hack, but I didn't want to change every */ + /* driver just to support this at the moment, since other important */ + /* changes are coming anyway. */ + + typedef struct FT_FontFormatRec_ + { + const char* driver_name; + const char* format_name; + + } FT_FontFormatRec; + + + FT_EXPORT_DEF( const char* ) + FT_Get_X11_Font_Format( FT_Face face ) + { + static const FT_FontFormatRec font_formats[] = + { + { "type1", "Type 1" }, + { "truetype", "TrueType" }, + { "bdf", "BDF" }, + { "pcf", "PCF" }, + { "type42", "Type 42" }, + { "cidtype1", "CID Type 1" }, + { "cff", "CFF" }, + { "pfr", "PFR" }, + { "winfonts", "Windows FNT" } + }; + + const char* result = NULL; + + + if ( face && face->driver ) + { + FT_Module driver = (FT_Module)face->driver; + + + if ( driver->clazz && driver->clazz->module_name ) + { + FT_Int n; + FT_Int count = sizeof( font_formats ) / sizeof ( font_formats[0] ); + + + result = driver->clazz->module_name; + + for ( n = 0; n < count; n++ ) + if ( ft_strcmp( result, font_formats[n].driver_name ) == 0 ) + { + result = font_formats[n].format_name; + break; + } + } + } + + return result; + } + + +/* END */ diff --git a/lib/freetype/src/base/rules.mk b/lib/freetype/src/base/rules.mk new file mode 100644 index 0000000..da345dd --- /dev/null +++ b/lib/freetype/src/base/rules.mk @@ -0,0 +1,94 @@ +# +# FreeType 2 base layer configuration rules +# + + +# Copyright 1996-2000, 2002 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. + + +# It sets the following variables which are used by the master Makefile +# after the call: +# +# BASE_OBJ_S: The single-object base layer. +# BASE_OBJ_M: A list of all objects for a multiple-objects build. +# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found +# in `freetype/src/base' which are not compiled within the +# base layer proper. +# +# BASE_H is defined in freetype.mk to simplify the dependency rules. + + +BASE_COMPILE := $(FT_COMPILE) $I$(SRC_)base + + +# Base layer sources +# +# ftsystem, ftinit, and ftdebug are handled by freetype.mk +# +BASE_SRC := $(BASE_)ftcalc.c \ + $(BASE_)fttrigon.c \ + $(BASE_)ftutil.c \ + $(BASE_)ftstream.c \ + $(BASE_)ftgloadr.c \ + $(BASE_)ftoutln.c \ + $(BASE_)ftobjs.c \ + $(BASE_)ftapi.c \ + $(BASE_)ftnames.c \ + $(BASE_)ftdbgmem.c + +# Base layer `extensions' sources +# +# An extension is added to the library file (.a or .lib) as a separate +# object. It will then be linked to the final executable only if one of its +# symbols is used by the application. +# +BASE_EXT_SRC := $(BASE_)ftglyph.c \ + $(BASE_)ftmm.c \ + $(BASE_)ftbdf.c \ + $(BASE_)fttype1.c \ + $(BASE_)ftxf86.c \ + $(BASE_)ftpfr.c \ + $(BASE_)ftstroker.c \ + $(BASE_)ftwinfnt.c \ + $(BASE_)ftbbox.c + +# Default extensions objects +# +BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O) + + +# Base layer object(s) +# +# BASE_OBJ_M is used during `multi' builds (each base source file compiles +# to a single object file). +# +# BASE_OBJ_S is used during `single' builds (the whole base layer is +# compiled as a single object file using ftbase.c). +# +BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O) +BASE_OBJ_S := $(OBJ_)ftbase.$O + +# Base layer root source file for single build +# +BASE_SRC_S := $(BASE_)ftbase.c + + +# Base layer - single object build +# +$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) + $(BASE_COMPILE) $T$@ $(BASE_SRC_S) + + +# Multiple objects build + extensions +# +$(OBJ_)%.$O: $(BASE_)%.c $(FREETYPE_H) + $(BASE_COMPILE) $T$@ $< + +# EOF diff --git a/lib/freetype/src/bdf/Jamfile b/lib/freetype/src/bdf/Jamfile new file mode 100644 index 0000000..8b1714d --- /dev/null +++ b/lib/freetype/src/bdf/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/bdf Jamfile (c) 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) bdf ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = bdfdrivr bdflib ; + } + else + { + _sources = bdf ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/bdf Jamfile diff --git a/lib/freetype/src/bdf/README b/lib/freetype/src/bdf/README new file mode 100644 index 0000000..d45e4fb --- /dev/null +++ b/lib/freetype/src/bdf/README @@ -0,0 +1,148 @@ + FreeType font driver for BDF fonts + + Francesco Zappa Nardelli + <francesco.zappa.nardelli@ens.fr> + + +Introduction +************ + +BDF (Bitmap Distribution Format) is a bitmap font format defined by Adobe, +which is intended to be easily understood by both humans and computers. +This code implements a BDF driver for the FreeType library, following the +Adobe Specification V 2.2. The specification of the BDF font format is +available from Adobe's web site: + + http://partners.adobe.com/asn/developer/PDFS/TN/5005.BDF_Spec.pdf + +Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org). +They do not define vertical metrics, because the X Consortium BDF +specification has removed them. + + +Encodings +********* + +The variety of encodings that accompanies bdf fonts appears to encompass the +small set defined in freetype.h. On the other hand, two properties that +specify encoding and registry are usually defined in bdf fonts. + +I decided to make these two properties directly accessible, leaving to the +client application the work of interpreting them. For instance: + + + #include FT_INTERNAL_BDF_TYPES_H + + FT_Face face; + BDF_Public_Face bdfface; + + + FT_New_Face( library, ..., &face ); + + bdfface = (BDF_Public_Face)face; + + if ( ( bdfface->charset_registry == "ISO10646" ) && + ( bdfface->charset_encoding == "1" ) ) + [..] + + +Thus the driver always exports `ft_encoding_none' as face->charmap.encoding. +FT_Get_Char_Index's behavior is unmodified, that is, it converts the ULong +value given as argument into the corresponding glyph number. + +If the two properties are not available, Adobe Standard Encoding should be +assumed. + + +Anti-Aliased Bitmaps +******************** + +The driver supports an extension to the BDF format as used in Mark Leisher's +xmbdfed bitmap font editor. Microsoft's SBIT tool expects bitmap fonts in +that format for adding anti-aliased them to TrueType fonts. It introduces a +fourth field to the `SIZE' keyword which gives the bpp value (bits per +pixel) of the glyph data in the font. Possible values are 1 (the default), +2 (four gray levels), 4 (16 gray levels), and 8 (256 gray levels). The +driver returns either a bitmap with 1 bit per pixel or a pixmap with 8bits +per pixel (using 4, 16, and 256 gray levels, respectively). + + +Known problems +************** + +- A font is entirely loaded into memory. Obviously, this is not the Right + Thing(TM). If you have big fonts I suggest you convert them into PCF + format (using the bdftopcf utility): the PCF font drive of FreeType can + perform incremental glyph loading. + +When I have some time, I will implement on-demand glyph parsing. + +- Except for encodings properties, client applications have no visibility of + the PCF_Face object. This means that applications cannot directly access + font tables and must trust FreeType. + +- Currently, glyph names are ignored. + + I plan to give full visibility of the BDF_Face object in an upcoming + revision of the driver, thus implementing also glyph names. + +- As I have never seen a BDF font that defines vertical metrics, vertical + metrics are (parsed and) discarded. If you own a BDF font that defines + vertical metrics, please let me know (I will implement them in 5-10 + minutes). + + +License +******* + +Copyright (C) 2001-2002 by Francesco Zappa Nardelli + +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 AUTHORS OR COPYRIGHT HOLDERS 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. + +*** Portions of the driver (that is, bdflib.c and bdf.h): + +Copyright 2000 Computing Research Labs, New Mexico State University +Copyright 2001-2002 Francesco Zappa Nardelli + +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. + + +Credits +******* + +This driver is based on excellent Mark Leisher's bdf library. If you +find something good in this driver you should probably thank him, not +me. diff --git a/lib/freetype/src/bdf/bdf.c b/lib/freetype/src/bdf/bdf.c new file mode 100644 index 0000000..9c82885 --- /dev/null +++ b/lib/freetype/src/bdf/bdf.c @@ -0,0 +1,34 @@ +/* bdf.c + + FreeType font driver for bdf files + + Copyright (C) 2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "bdflib.c" +#include "bdfdrivr.c" + + +/* END */ diff --git a/lib/freetype/src/bdf/bdf.h b/lib/freetype/src/bdf/bdf.h new file mode 100644 index 0000000..6a4bb82 --- /dev/null +++ b/lib/freetype/src/bdf/bdf.h @@ -0,0 +1,295 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001, 2002 Francesco Zappa Nardelli + * + * 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 __BDF_H__ +#define __BDF_H__ + + +/* + * Based on bdf.h,v 1.16 2000/03/16 20:08:51 mleisher + */ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + +/* Imported from bdfP.h */ + +#define _bdf_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] & ( 1 << ( (e) & 31 ) ) ) +#define _bdf_set_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] |= ( 1 << ( (e) & 31 ) ) ) +#define _bdf_clear_glyph_modified( map, e ) \ + ( (map)[(e) >> 5] &= ~( 1 << ( (e) & 31 ) ) ) + +/* end of bdfP.h */ + + + /*************************************************************************/ + /* */ + /* BDF font options macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_CORRECT_METRICS 0x01 /* Correct invalid metrics when loading. */ +#define BDF_KEEP_COMMENTS 0x02 /* Preserve the font comments. */ +#define BDF_KEEP_UNENCODED 0x04 /* Keep the unencoded glyphs. */ +#define BDF_PROPORTIONAL 0x08 /* Font has proportional spacing. */ +#define BDF_MONOWIDTH 0x10 /* Font has mono width. */ +#define BDF_CHARCELL 0x20 /* Font has charcell spacing. */ + +#define BDF_ALL_SPACING ( BDF_PROPORTIONAL | \ + BDF_MONOWIDTH | \ + BDF_CHARCELL ) + +#define BDF_DEFAULT_LOAD_OPTIONS ( BDF_CORRECT_METRICS | \ + BDF_KEEP_COMMENTS | \ + BDF_KEEP_UNENCODED | \ + BDF_PROPORTIONAL ) + + + typedef struct bdf_options_t_ + { + int correct_metrics; + int keep_unencoded; + int keep_comments; + int font_spacing; + + } bdf_options_t; + + + /* Callback function type for unknown configuration options. */ + typedef int + (*bdf_options_callback_t)( bdf_options_t* opts, + char** params, + unsigned long nparams, + void* client_data ); + + + /*************************************************************************/ + /* */ + /* BDF font property macros and types. */ + /* */ + /*************************************************************************/ + + +#define BDF_ATOM 1 +#define BDF_INTEGER 2 +#define BDF_CARDINAL 3 + + + /* This structure represents a particular property of a font. */ + /* There are a set of defaults and each font has their own. */ + typedef struct bdf_property_t_ + { + char* name; /* Name of the property. */ + int format; /* Format of the property. */ + int builtin; /* A builtin property. */ + union + { + char* atom; + long int32; + unsigned long card32; + + } value; /* Value of the property. */ + + } bdf_property_t; + + + /*************************************************************************/ + /* */ + /* BDF font metric and glyph types. */ + /* */ + /*************************************************************************/ + + + typedef struct bdf_bbx_t_ + { + unsigned short width; + unsigned short height; + + short x_offset; + short y_offset; + + short ascent; + short descent; + + } bdf_bbx_t; + + + typedef struct bdf_glyph_t_ + { + char* name; /* Glyph name. */ + long encoding; /* Glyph encoding. */ + unsigned short swidth; /* Scalable width. */ + unsigned short dwidth; /* Device width. */ + bdf_bbx_t bbx; /* Glyph bounding box. */ + unsigned char* bitmap; /* Glyph bitmap. */ + unsigned long bpr; /* Number of bytes used per row. */ + unsigned short bytes; /* Number of bytes used for the bitmap. */ + + } bdf_glyph_t; + + + typedef struct _hashnode_ + { + char* key; + void* data; + + } _hashnode, *hashnode; + + + typedef struct hashtable_ + { + int limit; + int size; + int used; + hashnode* table; + + } hashtable; + + + typedef struct bdf_glyphlist_t_ + { + unsigned short pad; /* Pad to 4-byte boundary. */ + unsigned short bpp; /* Bits per pixel. */ + long start; /* Beginning encoding value of glyphs. */ + long end; /* Ending encoding value of glyphs. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_bbx_t bbx; /* Overall bounding box of glyphs. */ + + } bdf_glyphlist_t; + + + typedef struct bdf_font_t_ + { + char* name; /* Name of the font. */ + bdf_bbx_t bbx; /* Font bounding box. */ + + long point_size; /* Point size of the font. */ + unsigned long resolution_x; /* Font horizontal resolution. */ + unsigned long resolution_y; /* Font vertical resolution. */ + + int spacing; /* Font spacing value. */ + + unsigned short monowidth; /* Logical width for monowidth font. */ + + long default_glyph; /* Encoding of the default glyph. */ + + long font_ascent; /* Font ascent. */ + long font_descent; /* Font descent. */ + + unsigned long glyphs_size; /* Glyph structures allocated. */ + unsigned long glyphs_used; /* Glyph structures used. */ + bdf_glyph_t* glyphs; /* Glyphs themselves. */ + + unsigned long unencoded_size; /* Unencoded glyph struct. allocated. */ + unsigned long unencoded_used; /* Unencoded glyph struct. used. */ + bdf_glyph_t* unencoded; /* Unencoded glyphs themselves. */ + + unsigned long props_size; /* Font properties allocated. */ + unsigned long props_used; /* Font properties used. */ + bdf_property_t* props; /* Font properties themselves. */ + + char* comments; /* Font comments. */ + unsigned long comments_len; /* Length of comment string. */ + + bdf_glyphlist_t overflow; /* Storage used for glyph insertion. */ + + void* internal; /* Internal data for the font. */ + + unsigned long nmod[2048]; /* Bitmap indicating modified glyphs. */ + unsigned long umod[2048]; /* Bitmap indicating modified */ + /* unencoded glyphs. */ + unsigned short modified; /* Boolean indicating font modified. */ + unsigned short bpp; /* Bits per pixel. */ + + FT_Memory memory; + + bdf_property_t* user_props; + unsigned long nuser_props; + hashtable proptbl; + + } bdf_font_t; + + + /*************************************************************************/ + /* */ + /* Types for load/save callbacks. */ + /* */ + /*************************************************************************/ + + + /* Error codes. */ +#define BDF_MISSING_START -1 +#define BDF_MISSING_FONTNAME -2 +#define BDF_MISSING_SIZE -3 +#define BDF_MISSING_CHARS -4 +#define BDF_MISSING_STARTCHAR -5 +#define BDF_MISSING_ENCODING -6 +#define BDF_MISSING_BBX -7 + +#define BDF_OUT_OF_MEMORY -20 + +#define BDF_INVALID_LINE -100 + + + /*************************************************************************/ + /* */ + /* BDF font API. */ + /* */ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory memory, + bdf_options_t* opts, + bdf_font_t* *font ); + + FT_LOCAL( void ) + bdf_free_font( bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ); + + FT_LOCAL( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + char* name ); + + +FT_END_HEADER + + +#endif /* __BDF_H__ */ + + +/* END */ diff --git a/lib/freetype/src/bdf/bdfdrivr.c b/lib/freetype/src/bdf/bdfdrivr.c new file mode 100644 index 0000000..4f60266 --- /dev/null +++ b/lib/freetype/src/bdf/bdfdrivr.c @@ -0,0 +1,725 @@ +/* bdfdrivr.c + + FreeType font driver for bdf files + + Copyright (C) 2001-2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_BDF_H + +#include "bdf.h" +#include "bdfdrivr.h" + +#include "bdferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_bdfdriver + + + typedef struct BDF_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_encodings; + BDF_encoding_el* encodings; + + } BDF_CMapRec, *BDF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + bdf_cmap_init( BDF_CMap cmap ) + { + BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); + + + cmap->num_encodings = face->bdffont->glyphs_used; + cmap->encodings = face->en_table; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + bdf_cmap_done( BDF_CMap cmap ) + { + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_index( BDF_CMap cmap, + FT_UInt32 charcode ) + { + BDF_encoding_el* encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_UInt32 code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + bdf_cmap_char_next( BDF_CMap cmap, + FT_UInt32 *acharcode ) + { + BDF_encoding_el* encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt32 charcode = *acharcode + 1; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_UInt32 code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + *acharcode = charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec bdf_cmap_class = + { + sizeof( BDF_CMapRec ), + (FT_CMap_InitFunc) bdf_cmap_init, + (FT_CMap_DoneFunc) bdf_cmap_done, + (FT_CMap_CharIndexFunc)bdf_cmap_char_index, + (FT_CMap_CharNextFunc) bdf_cmap_char_next + }; + + + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Face_Done( BDF_Face face ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + bdf_free_font( face->bdffont ); + + FT_FREE( face->en_table ); + + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + FT_FREE( face->root.family_name ); + + FT_FREE( face->root.available_sizes ); + + FT_FREE( face->bdffont ); + + FT_TRACE4(( "BDF_Face_Done: done face\n" )); + + return BDF_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + BDF_Face_Init( FT_Stream stream, + BDF_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error = BDF_Err_Ok; + FT_Memory memory = FT_FACE_MEMORY( face ); + + bdf_font_t* font; + bdf_options_t options; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + options.correct_metrics = 1; /* FZ XXX: options semantics */ + options.keep_unencoded = 1; + options.keep_comments = 0; + options.font_spacing = BDF_PROPORTIONAL; + + error = bdf_load_font( stream, memory, &options, &font ); + if ( error == BDF_Err_Missing_Startfont_Field ) + { + FT_TRACE2(( "[not a valid BDF file]\n" )); + goto Fail; + } + else if ( error ) + goto Exit; + + /* we have a bdf font: let's construct the face object */ + face->bdffont = font; + { + FT_Face root = FT_FACE( face ); + bdf_property_t* prop = NULL; + + + FT_TRACE4(( "number of glyphs: %d (%d)\n", + font->glyphs_size, + font->glyphs_used )); + FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n", + font->unencoded_size, + font->unencoded_used )); + + root->num_faces = 1; + root->face_index = 0; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + prop = bdf_get_font_property( font, (char *)"SPACING" ); + if ( prop != NULL ) + if ( prop->format == BDF_ATOM ) + if ( prop->value.atom != NULL ) + if ( ( *(prop->value.atom) == 'M' ) || + ( *(prop->value.atom) == 'C' ) ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ + /* FZ XXX: I need a font to implement this */ + + root->style_flags = 0; + prop = bdf_get_font_property( font, (char *)"SLANT" ); + if ( prop != NULL ) + if ( prop->format == BDF_ATOM ) + if ( prop->value.atom != NULL ) + if ( ( *(prop->value.atom) == 'O' ) || + ( *(prop->value.atom) == 'I' ) ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + if ( prop != NULL ) + if ( prop->format == BDF_ATOM ) + if ( prop->value.atom != NULL ) + if ( *(prop->value.atom) == 'B' ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + prop = bdf_get_font_property( font, (char *)"FAMILY_NAME" ); + if ( ( prop != NULL ) && ( prop->value.atom != NULL ) ) + { + int l = ft_strlen( prop->value.atom ) + 1; + + + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + ft_strcpy( root->family_name, prop->value.atom ); + } + else + root->family_name = 0; + + root->style_name = (char *)"Regular"; + if ( root->style_flags & FT_STYLE_FLAG_BOLD ) + { + if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Bold Italic"; + else + root->style_name = (char *)"Bold"; + } + else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Italic"; + + root->num_glyphs = font->glyphs_size; /* unencoded included */ + + root->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Exit; + + prop = bdf_get_font_property( font, (char *)"AVERAGE_WIDTH" ); + if ( ( prop != NULL ) && ( prop->value.int32 >= 10 ) ) + root->available_sizes->width = (short)( prop->value.int32 / 10 ); + + prop = bdf_get_font_property( font, (char *)"PIXEL_SIZE" ); + if ( prop != NULL ) + root->available_sizes->height = (short) prop->value.int32; + else + { + prop = bdf_get_font_property( font, (char *)"POINT_SIZE" ); + if ( prop != NULL ) + { + bdf_property_t *yres; + + + yres = bdf_get_font_property( font, (char *)"RESOLUTION_Y" ); + if ( yres != NULL ) + { + FT_TRACE4(( "POINT_SIZE: %d RESOLUTION_Y: %d\n", + prop->value.int32, yres->value.int32 )); + root->available_sizes->height = + (FT_Short)( prop->value.int32 * yres->value.int32 / 720 ); + } + } + } + + if ( root->available_sizes->width == 0 ) + { + if ( root->available_sizes->height == 0 ) + { + /* some fonts have broken SIZE declaration (jiskan24.bdf) */ + FT_ERROR(( "BDF_Face_Init: reading size\n" )); + root->available_sizes->width = (FT_Short)font->point_size; + } + else + root->available_sizes->width = root->available_sizes->height; + } + if ( root->available_sizes->height == 0 ) + root->available_sizes->height = root->available_sizes->width; + + /* encoding table */ + { + bdf_glyph_t* cur = font->glyphs; + unsigned long n; + + + if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) + goto Exit; + + for ( n = 0; n < font->glyphs_size; n++ ) + { + (face->en_table[n]).enc = cur[n].encoding; + FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding )); + (face->en_table[n]).glyph = (FT_Short)n; + } + } + + /* charmaps */ + { + bdf_property_t *charset_registry = 0, *charset_encoding = 0; + FT_Bool unicode_charmap = 0; + + + charset_registry = + bdf_get_font_property( font, (char *)"CHARSET_REGISTRY" ); + charset_encoding = + bdf_get_font_property( font, (char *)"CHARSET_ENCODING" ); + if ( ( charset_registry != NULL ) && ( charset_encoding != NULL ) ) + { + if ( ( charset_registry->format == BDF_ATOM ) && + ( charset_encoding->format == BDF_ATOM ) && + ( charset_registry->value.atom != NULL ) && + ( charset_encoding->value.atom != NULL ) ) + { + if ( FT_NEW_ARRAY( face->charset_encoding, + strlen( charset_encoding->value.atom ) + 1 ) ) + goto Exit; + if ( FT_NEW_ARRAY( face->charset_registry, + strlen( charset_registry->value.atom ) + 1 ) ) + goto Exit; + ft_strcpy( face->charset_registry, charset_registry->value.atom ); + ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); + if ( !ft_strcmp( face->charset_registry, "ISO10646" ) || + ( !ft_strcmp( face->charset_registry, "ISO8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = 3; + charmap.encoding_id = 1; + } + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + + goto Exit; + } + } + + /* otherwise assume Adobe standard encoding */ + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.platform_id = 7; + charmap.encoding_id = 0; + + error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); + + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; + } + } + } + + Exit: + return error; + + Fail: + BDF_Face_Done( face ); + return BDF_Err_Unknown_File_Format; + } + + + static FT_Error + BDF_Set_Pixel_Size( FT_Size size ) + { + BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); + FT_Face root = FT_FACE( face ); + + + FT_TRACE4(( "rec %d - pres %d\n", + size->metrics.y_ppem, root->available_sizes->height )); + + if ( size->metrics.y_ppem == root->available_sizes->height ) + { + size->metrics.ascender = face->bdffont->bbx.ascent << 6; + size->metrics.descender = face->bdffont->bbx.descent * ( -64 ); + size->metrics.height = face->bdffont->bbx.height << 6; + + return BDF_Err_Ok; + } + else + return BDF_Err_Invalid_Pixel_Size; + } + + + static FT_Error + BDF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); + FT_Error error = BDF_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + bdf_glyph_t glyph; + int bpp = face->bdffont->bpp; + int i, j, count; + unsigned char *p, *pp; + + FT_UNUSED( load_flags ); + + + if ( !face ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + if ( glyph_index > 0 ) + glyph_index--; + + /* slot, bitmap => freetype, glyph => bdflib */ + glyph = face->bdffont->glyphs[glyph_index]; + + bitmap->rows = glyph.bbx.height; + bitmap->width = glyph.bbx.width; + + if ( bpp == 1 ) + { + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + bitmap->pitch = glyph.bpr; + + /* note: we don't allocate a new array to hold the bitmap, we */ + /* can simply point to it */ + ft_glyphslot_set_bitmap( slot, glyph.bitmap ); + } + else + { + /* blow up pixmap to have 8 bits per pixel */ + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->pitch = bitmap->width; + + error = ft_glyphslot_alloc_bitmap( slot, bitmap->rows * bitmap->pitch ); + if ( error ) + goto Exit; + + switch ( bpp ) + { + case 2: + bitmap->num_grays = 4; + + count = 0; + p = glyph.bitmap; + + for ( i = 0; i < bitmap->rows; i++ ) + { + pp = p; + + /* get the full bytes */ + for ( j = 0; j < ( bitmap->width >> 2 ); j++ ) + { + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 ); + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 ); + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 ); + bitmap->buffer[count++] = (FT_Byte)( *pp & 0x03 ); + + pp++; + } + + /* get remaining pixels (if any) */ + switch ( bitmap->width & 3 ) + { + case 3: + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xC0 ) >> 6 ); + /* fall through */ + case 2: + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x30 ) >> 4 ); + /* fall through */ + case 1: + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0x0C ) >> 2 ); + /* fall through */ + case 0: + break; + } + + p += glyph.bpr; + } + break; + + case 4: + bitmap->num_grays = 16; + + count = 0; + p = glyph.bitmap; + + for ( i = 0; i < bitmap->rows; i++ ) + { + pp = p; + + /* get the full bytes */ + for ( j = 0; j < ( bitmap->width >> 1 ); j++ ) + { + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 ); + bitmap->buffer[count++] = (FT_Byte)( *pp & 0x0F ); + + pp++; + } + + /* get remaining pixel (if any) */ + switch ( bitmap->width & 1 ) + { + case 1: + bitmap->buffer[count++] = (FT_Byte)( ( *pp & 0xF0 ) >> 4 ); + /* fall through */ + case 0: + break; + } + + p += glyph.bpr; + } + break; + + case 8: + bitmap->num_grays = 256; + + FT_MEM_COPY( bitmap->buffer, glyph.bitmap, + bitmap->rows * bitmap->pitch ); + break; + } + } + + slot->bitmap_left = 0; + slot->bitmap_top = glyph.bbx.ascent; + + /* FZ XXX: TODO: vertical metrics */ + slot->metrics.horiAdvance = glyph.dwidth << 6; + slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; + slot->metrics.horiBearingY = ( glyph.bbx.y_offset + + glyph.bbx.height ) << 6; + slot->metrics.width = bitmap->width << 6; + slot->metrics.height = bitmap->rows << 6; + + slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + Exit: + return error; + } + + + static FT_Error + bdf_get_bdf_property( BDF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + bdf_property_t* prop; + + FT_ASSERT( face && face->bdffont ); + + prop = bdf_get_font_property( face->bdffont, (char*)prop_name ); + if ( prop != NULL ) + { + switch ( prop->format ) + { + case BDF_ATOM: + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + break; + + case BDF_INTEGER: + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = prop->value.int32; + break; + + case BDF_CARDINAL: + aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; + aproperty->u.cardinal = prop->value.card32; + break; + + default: + goto Fail; + } + return 0; + } + Fail: + return FT_Err_Invalid_Argument; + } + + + static FT_Module_Interface + bdf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 ) + return (FT_Module_Interface) bdf_get_bdf_property; + + return NULL; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec bdf_driver_class = + { + { + ft_module_font_driver, + sizeof ( FT_DriverRec ), + + "bdf", + 0x10000L, + 0x20000L, + + 0, + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) bdf_driver_requester + }, + + sizeof ( BDF_FaceRec ), + sizeof ( FT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + (FT_Face_InitFunc) BDF_Face_Init, + (FT_Face_DoneFunc) BDF_Face_Done, + (FT_Size_InitFunc) 0, + (FT_Size_DoneFunc) 0, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, + + (FT_Size_ResetPointsFunc) BDF_Set_Pixel_Size, + (FT_Size_ResetPixelsFunc) BDF_Set_Pixel_Size, + + (FT_Slot_LoadFunc) BDF_Glyph_Load, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/bdf/bdfdrivr.h b/lib/freetype/src/bdf/bdfdrivr.h new file mode 100644 index 0000000..5c58964 --- /dev/null +++ b/lib/freetype/src/bdf/bdfdrivr.h @@ -0,0 +1,74 @@ +/* bdfdrivr.h + + FreeType font driver for bdf fonts + + Copyright (C) 2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __BDFDRIVR_H__ +#define __BDFDRIVR_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +#include "bdf.h" + + +FT_BEGIN_HEADER + + + typedef struct BDF_encoding_el_ + { + FT_ULong enc; + FT_Short glyph; + + } BDF_encoding_el; + + + typedef struct BDF_FaceRec_ + { + FT_FaceRec root; + + char* charset_encoding; + char* charset_registry; + + bdf_font_t* bdffont; + + BDF_encoding_el* en_table; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } BDF_FaceRec, *BDF_Face; + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) bdf_driver_class; + + +FT_END_HEADER + + +#endif /* __BDFDRIVR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/bdf/bdferror.h b/lib/freetype/src/bdf/bdferror.h new file mode 100644 index 0000000..b27fa33 --- /dev/null +++ b/lib/freetype/src/bdf/bdferror.h @@ -0,0 +1,44 @@ +/* + * Copyright 2001, 2002 Francesco Zappa Nardelli + * + * 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 file is used to define the BDF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __BDFERROR_H__ +#define __BDFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX BDF_Err_ +#define FT_ERR_BASE FT_Mod_Err_BDF + +#include FT_ERRORS_H + +#endif /* __BDFERROR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/bdf/bdflib.c b/lib/freetype/src/bdf/bdflib.c new file mode 100644 index 0000000..7496e60 --- /dev/null +++ b/lib/freetype/src/bdf/bdflib.c @@ -0,0 +1,2436 @@ +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001, 2002 Francesco Zappa Nardelli + * + * 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 file is based on bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "bdf.h" +#include "bdferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_bdflib + + + /*************************************************************************/ + /* */ + /* Default BDF font options. */ + /* */ + /*************************************************************************/ + + + static const bdf_options_t _bdf_opts = + { + 1, /* Correct metrics. */ + 1, /* Preserve unencoded glyphs. */ + 0, /* Preserve comments. */ + BDF_PROPORTIONAL /* Default spacing. */ + }; + + + /*************************************************************************/ + /* */ + /* Builtin BDF font properties. */ + /* */ + /*************************************************************************/ + + /* List of most properties that might appear in a font. Doesn't include */ + /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts. */ + + static const bdf_property_t _bdf_properties[] = + { + { (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, + { (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"COMMENT", BDF_ATOM, 1, { 0 } }, + { (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } }, + { (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } }, + { (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT", BDF_ATOM, 1, { 0 } }, + { (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } }, + { (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"NOTICE", BDF_ATOM, 1, { 0 } }, + { (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } }, + { (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, + { (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, + { (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"SLANT", BDF_ATOM, 1, { 0 } }, + { (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SPACING", BDF_ATOM, 1, { 0 } }, + { (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, + { (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, + { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, + }; + + static unsigned long + _num_bdf_properties = sizeof ( _bdf_properties ) / + sizeof ( _bdf_properties[0] ); + + + /*************************************************************************/ + /* */ + /* Hash table utilities for the properties. */ + /* */ + /*************************************************************************/ + + /* XXX: Replace this with FreeType's hash functions */ + + +#define INITIAL_HT_SIZE 241 + + typedef void + (*hash_free_func)( hashnode node ); + + static hashnode* + hash_bucket( char* key, + hashtable* ht ) + { + char* kp = key; + unsigned long res = 0; + hashnode* bp = ht->table, *ndp; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + *kp++; + + ndp = bp + ( res % ht->size ); + while ( *ndp ) + { + kp = (*ndp)->key; + if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) + break; + ndp--; + if ( ndp < bp ) + ndp = bp + ( ht->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( hashtable* ht, + FT_Memory memory ) + { + hashnode* obp = ht->table, *bp, *nbp; + int i, sz = ht->size; + FT_Error error = BDF_Err_Ok; + + + ht->size <<= 1; + ht->limit = ht->size / 3; + + if ( FT_NEW_ARRAY( ht->table, ht->size ) ) + goto Exit; + FT_MEM_ZERO( ht->table, sizeof ( hashnode ) * ht->size ); + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, ht ); + *nbp = *bp; + } + } + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( hashtable* ht, + FT_Memory memory ) + { + int sz = INITIAL_HT_SIZE; + FT_Error error = BDF_Err_Ok; + + + ht->size = sz; + ht->limit = sz / 3; + ht->used = 0; + + if ( FT_NEW_ARRAY( ht->table, sz ) ) + goto Exit; + FT_MEM_ZERO( ht->table, sizeof ( hashnode ) * sz ); + + Exit: + return error; + } + + + static void + hash_free( hashtable* ht, + FT_Memory memory ) + { + if ( ht != 0 ) + { + int i, sz = ht->size; + hashnode* bp = ht->table; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( ht->table ); + } + } + + + static FT_Error + hash_insert( char* key, + void* data, + hashtable* ht, + FT_Memory memory ) + { + hashnode nn, *bp = hash_bucket( key, ht ); + FT_Error error = BDF_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( ht->used >= ht->limit ) + { + error = hash_rehash( ht, memory ); + if ( error ) + goto Exit; + } + ht->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + static hashnode + hash_lookup( char* key, + hashtable* ht ) + { + hashnode *np = hash_bucket( key, ht ); + + + return *np; + } + + + /*************************************************************************/ + /* */ + /* Utility types and functions. */ + /* */ + /*************************************************************************/ + + + /* Function type for parsing lines of a BDF font. */ + + typedef FT_Error + (*_bdf_line_func_t)( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ); + + + /* List structure for splitting lines into fields. */ + + typedef struct _bdf_list_t_ + { + char** field; + unsigned long size; + unsigned long used; + + } _bdf_list_t; + + + /* Structure used while loading BDF fonts. */ + + typedef struct _bdf_parse_t_ + { + unsigned long flags; + unsigned long cnt; + unsigned long row; + + short minlb; + short maxlb; + short maxrb; + short maxas; + short maxds; + + short rbearing; + + char* glyph_name; + long glyph_enc; + + bdf_font_t* font; + bdf_options_t* opts; + + unsigned long have[2048]; + _bdf_list_t list; + + FT_Memory memory; + + } _bdf_parse_t; + + +#define setsbit( m, cc ) ( m[(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) ) +#define sbitset( m, cc ) ( m[(cc) >> 3] & ( 1 << ( (cc) & 7 ) ) ) + + + /* An empty string for empty fields. */ + + static char empty[1] = { 0 }; /* XXX eliminate this */ + + + /* Assume the line is NULL-terminated and that the `list' parameter */ + /* was initialized the first time it was used. */ + + static FT_Error + _bdf_split( char* separators, + char* line, + unsigned long linelen, + _bdf_list_t* list, + FT_Memory memory ) + { + int mult, final_empty; + char *sp, *ep, *end; + char seps[32]; + FT_Error error = BDF_Err_Ok; + + + /* Initialize the list. */ + list->used = 0; + + /* If the line is empty, then simply return. */ + if ( linelen == 0 || line[0] == 0 ) + goto Exit; + + /* In the original code, if the `separators' parameter is NULL or */ + /* empty, the list is split into individual bytes. We don't need */ + /* this, so an error is signaled. */ + if ( separators == 0 || *separators == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + /* Prepare the separator bitmap. */ + FT_MEM_ZERO( seps, 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 && !sbitset( seps, *ep ); ep++ ) + ; + + /* Resize the list if necessary. */ + if ( list->used == list->size ) + { + if ( list->size == 0 ) + { + if ( FT_NEW_ARRAY( list->field, 5 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY ( list->field , + list->size, + list->size + 5 ) ) + goto Exit; + } + + list->size += 5; + } + + /* 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 && sbitset( seps, *ep ); ep++ ) + *ep = 0; + } + else if ( *ep != 0 ) + /* 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 ) + { + if ( FT_NEW_ARRAY( list->field, 5 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( list->field, + list->size, + list->size + 5 ) ) + goto Exit; + } + + list->size += 5; + } + } + + if ( final_empty ) + list->field[list->used++] = empty; + + if ( list->used == list->size ) + { + if ( list->size == 0 ) + { + if ( FT_NEW_ARRAY( list->field, 5 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( list->field, + list->size, + list->size + 5 ) ) + goto Exit; + } + + list->size += 5; + } + + list->field[list->used] = 0; + + Exit: + return error; + } + + + static void + _bdf_shift( unsigned long n, + _bdf_list_t* list ) + { + unsigned long i, u; + + + if ( list == 0 || list->used == 0 || n == 0 ) + return; + + if ( n >= list->used ) + { + list->used = 0; + return; + } + + for ( u = n, i = 0; u < list->used; i++, u++ ) + list->field[i] = list->field[u]; + list->used -= n; + } + + + static char * + _bdf_join( int c, + unsigned long* len, + _bdf_list_t* list ) + { + unsigned long i, j; + char *fp, *dp; + + + if ( list == 0 || list->used == 0 ) + return 0; + + *len = 0; + + dp = list->field[0]; + for ( i = j = 0; i < list->used; i++ ) + { + fp = list->field[i]; + while ( *fp ) + dp[j++] = *fp++; + + if ( i + 1 < list->used ) + dp[j++] = (char)c; + } + dp[j] = 0; + + *len = j; + return dp; + } + + + /* High speed file reader that passes each line to a callback. */ + static FT_Error + bdf_internal_readstream( FT_Stream stream, + char* buffer, + int count, + int *read_bytes ) + { + int rbytes; + unsigned long pos = stream->pos; + FT_Error error = BDF_Err_Ok; + + + if ( pos > stream->size ) + { + FT_ERROR(( "bdf_internal_readstream:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + pos, stream->size )); + error = BDF_Err_Invalid_Stream_Operation; + goto Exit; + } + + if ( stream->read ) + rbytes = stream->read( stream, pos, + (unsigned char *)buffer, count ); + else + { + rbytes = stream->size - pos; + if ( rbytes > count ) + rbytes = count; + + FT_MEM_COPY( buffer, stream->base + pos, rbytes ); + } + + stream->pos = pos + rbytes; + + *read_bytes = rbytes; + + Exit: + return error; + } + + + static FT_Error + _bdf_readstream( FT_Stream stream, + _bdf_line_func_t callback, + void* client_data, + unsigned long *lno ) + { + _bdf_line_func_t cb; + unsigned long lineno; + int n, res, done, refill, bytes, hold; + char *ls, *le, *pp, *pe, *hp; + char *buf = 0; + FT_Memory memory = stream->memory; + FT_Error error = BDF_Err_Ok; + + + if ( callback == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + if ( FT_NEW_ARRAY( buf, 65536L ) ) + goto Exit; + + cb = callback; + lineno = 1; + buf[0] = 0; + + res = done = 0; + pp = ls = le = buf; + + bytes = 65536L; + + while ( !done ) + { + error = bdf_internal_readstream( stream, pp, bytes, &n ); + if ( error ) + goto Exit; + + if ( n == 0 ) + break; + + /* 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; + + FT_MEM_COPY( buf, pp, n ); + + pp = buf + n; + bytes = 65536L - n; + refill = 1; + } + else + { + /* Temporarily NULL-terminate the line. */ + hp = le; + hold = *le; + *le = 0; + + /* XXX: Use encoding independent value for 0x1a */ + if ( *ls != '#' && *ls != 0x1a && + le > ls && + ( error = (*cb)( ls, le - ls, lineno, (void *)&cb, + client_data ) ) != BDF_Err_Ok ) + 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. */ + lineno++; + + /* Restore the character at the end of the line. */ + *hp = (char)hold; + } + } + } + + *lno = lineno; + + Exit: + FT_FREE( buf ); + return error; + } + + + /* XXX: make this work with EBCDIC also */ + + static const 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 const 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 const 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 const 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 ) ) ) + + + /* Routine to convert an ASCII string into an unsigned long integer. */ + static unsigned long + _bdf_atoul( char* s, + char** end, + int base ) + { + unsigned long v; + const 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; + } + + + /* Routine to convert an ASCII string into an signed long integer. */ + static long + _bdf_atol( char* s, + char** end, + int base ) + { + long v, neg; + const 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 a minus sign. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* 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 ( !neg ) ? v : -v; + } + + + /* Routine to convert an ASCII string into an signed short integer. */ + static short + _bdf_atos( char* s, + char** end, + int base ) + { + short v, neg; + const 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 a minus. */ + neg = 0; + if ( *s == '-' ) + { + s++; + neg = 1; + } + + /* 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 = (short)( v * base + a2i[(int)*s] ); + + if ( end != 0 ) + *end = s; + + return (short)( ( !neg ) ? v : -v ); + } + + + /* Routine to compare two glyphs by encoding so they can be sorted. */ + static int + by_encoding( const void* a, + const void* b ) + { + bdf_glyph_t *c1, *c2; + + + c1 = (bdf_glyph_t *)a; + c2 = (bdf_glyph_t *)b; + + if ( c1->encoding < c2->encoding ) + return -1; + else if ( c1->encoding > c2->encoding ) + return 1; + + return 0; + } + + + static FT_Error + bdf_create_property( char* name, + int format, + bdf_font_t* font ) + { + unsigned long n; + bdf_property_t* p; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + /* First check to see if the property has */ + /* already been added or not. If it has, then */ + /* simply ignore it. */ + if ( hash_lookup( name, &(font->proptbl) ) ) + goto Exit; + + if ( font->nuser_props == 0 ) + { + if ( FT_NEW_ARRAY( font->user_props, 1 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->user_props, + font->nuser_props, + font->nuser_props + 1 ) ) + goto Exit; + } + + p = font->user_props + font->nuser_props; + FT_MEM_ZERO( p, sizeof ( bdf_property_t ) ); + + n = (unsigned long)( ft_strlen( name ) + 1 ); + if ( FT_NEW_ARRAY( p->name, n ) ) + goto Exit; + + FT_MEM_COPY( (char *)p->name, name, n ); + + p->format = format; + p->builtin = 0; + + n = _num_bdf_properties + font->nuser_props; + + error = hash_insert( p->name, (void *)n, &(font->proptbl), memory ); + if ( error ) + goto Exit; + + font->nuser_props++; + + Exit: + return error; + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_property( char* name, + bdf_font_t* font ) + { + hashnode hn; + unsigned long propid; + + + if ( name == 0 || *name == 0 ) + return 0; + + if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + return 0; + + propid = (unsigned long)hn->data; + if ( propid >= _num_bdf_properties ) + return font->user_props + ( propid - _num_bdf_properties ); + + return (bdf_property_t*)_bdf_properties + propid; + } + + + /*************************************************************************/ + /* */ + /* BDF font file parsing flags and functions. */ + /* */ + /*************************************************************************/ + + + /* Parse flags. */ + +#define _BDF_START 0x0001 +#define _BDF_FONT_NAME 0x0002 +#define _BDF_SIZE 0x0004 +#define _BDF_FONT_BBX 0x0008 +#define _BDF_PROPS 0x0010 +#define _BDF_GLYPHS 0x0020 +#define _BDF_GLYPH 0x0040 +#define _BDF_ENCODING 0x0080 +#define _BDF_SWIDTH 0x0100 +#define _BDF_DWIDTH 0x0200 +#define _BDF_BBX 0x0400 +#define _BDF_BITMAP 0x0800 + +#define _BDF_SWIDTH_ADJ 0x1000 + +#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ + _BDF_ENCODING | \ + _BDF_SWIDTH | \ + _BDF_DWIDTH | \ + _BDF_BBX | \ + _BDF_BITMAP ) + +#define _BDF_GLYPH_WIDTH_CHECK 0x40000000L +#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000L + + + /* Auto correction messages. */ +#define ACMSG1 "FONT_ASCENT property missing. " \ + "Added \"FONT_ASCENT %hd\".\n" +#define ACMSG2 "FONT_DESCENT property missing. " \ + "Added \"FONT_DESCENT %hd\".\n" +#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n" +#define ACMSG4 "Font left bearing != actual left bearing. " \ + "Old: %hd New: %hd.\n" +#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n" +#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n" +#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n" +#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n" +#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n" +#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n" +#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n" +#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n" +#define ACMSG13 "Glyph %ld extra rows removed.\n" +#define ACMSG14 "Glyph %ld extra columns removed.\n" +#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" + + /* Error messages. */ +#define ERRMSG1 "[line %ld] Missing \"%s\" line.\n" +#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n" +#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n" + + + static FT_Error + _bdf_add_comment( bdf_font_t* font, + char* comment, + unsigned long len ) + { + char* cp; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + if ( font->comments_len == 0 ) + { + if ( FT_NEW_ARRAY( font->comments, len + 1 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->comments, + font->comments_len, + font->comments_len + len + 1 ) ) + goto Exit; + } + + cp = font->comments + font->comments_len; + FT_MEM_COPY( cp, comment, len ); + cp += len; + *cp++ = '\n'; + font->comments_len += len + 1; + + Exit: + return error; + } + + + /* Set the spacing from the font name if it exists, or set it to the */ + /* default specified in the options. */ + static FT_Error + _bdf_set_default_spacing( bdf_font_t* font, + bdf_options_t* opts ) + { + unsigned long len; + char name[128]; + _bdf_list_t list; + FT_Memory memory; + FT_Error error = BDF_Err_Ok; + + + if ( font == 0 || font->name == 0 || font->name[0] == 0 ) + { + error = BDF_Err_Invalid_Argument; + goto Exit; + } + + memory = font->memory; + + font->spacing = opts->font_spacing; + + len = (unsigned long)( ft_strlen( font->name ) + 1 ); + FT_MEM_COPY( name, font->name, len ); + + list.size = list.used = 0; + + error = _bdf_split( (char *)"-", name, len, &list, memory ); + if ( error ) + goto Exit; + + if ( list.used == 15 ) + { + switch ( list.field[11][0] ) + { + case 'C': + case 'c': + font->spacing = BDF_CHARCELL; + break; + case 'M': + case 'm': + font->spacing = BDF_MONOWIDTH; + break; + case 'P': + case 'p': + font->spacing = BDF_PROPORTIONAL; + break; + } + } + + FT_FREE( list.field ); + + Exit: + return error; + } + + + /* Determine whether the property is an atom or not. If it is, then */ + /* clean it up so the double quotes are removed if they exist. */ + static int + _bdf_is_atom( char* line, + unsigned long linelen, + char** name, + char** value, + bdf_font_t* font ) + { + int hold; + char *sp, *ep; + bdf_property_t* p; + + + *name = sp = ep = line; + + while ( *ep && *ep != ' ' && *ep != '\t' ) + ep++; + + hold = -1; + if ( *ep ) + { + hold = *ep; + *ep = 0; + } + + p = bdf_get_property( sp, font ); + + /* Restore the character that was saved before any return can happen. */ + if ( hold != -1 ) + *ep = (char)hold; + + /* If the property exists and is not an atom, just return here. */ + if ( p && p->format != BDF_ATOM ) + return 0; + + /* The property is an atom. Trim all leading and trailing whitespace */ + /* and double quotes for the atom value. */ + sp = ep; + ep = line + linelen; + + /* Trim the leading whitespace if it exists. */ + *sp++ = 0; + while ( *sp && + ( *sp == ' ' || *sp == '\t' ) ) + sp++; + + /* Trim the leading double quote if it exists. */ + if ( *sp == '"' ) + sp++; + *value = sp; + + /* Trim the trailing whitespace if it exists. */ + while ( ep > sp && + ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) ) + *--ep = 0; + + /* Trim the trailing double quote if it exists. */ + if ( ep > sp && *( ep - 1 ) == '"' ) + *--ep = 0; + + return 1; + } + + + static FT_Error + _bdf_add_property( bdf_font_t* font, + char* name, + char* value ) + { + unsigned long propid; + hashnode hn; + int len; + bdf_property_t *prop, *fp; + FT_Memory memory = font->memory; + FT_Error error = BDF_Err_Ok; + + + /* First, check to see if the property already exists in the font. */ + if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + { + /* The property already exists in the font, so simply replace */ + /* the value of the property with the current value. */ + fp = font->props + (unsigned long)hn->data; + + switch ( fp->format ) + { + case BDF_ATOM: + /* Delete the current atom if it exists. */ + FT_FREE( fp->value.atom ); + + if ( value == 0 ) + len = 1; + else + len = ft_strlen( value ) + 1; + + if ( len > 1 ) + { + if ( FT_NEW_ARRAY( fp->value.atom, len ) ) + goto Exit; + FT_MEM_COPY( fp->value.atom, value, len ); + } + else + fp->value.atom = 0; + break; + + case BDF_INTEGER: + fp->value.int32 = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.card32 = _bdf_atoul( value, 0, 10 ); + break; + + default: + ; + } + + goto Exit; + } + + /* See whether this property type exists yet or not. */ + /* If not, create it. */ + hn = hash_lookup( name, &(font->proptbl) ); + if ( hn == 0 ) + { + error = bdf_create_property( name, BDF_ATOM, font ); + if ( error ) + goto Exit; + hn = hash_lookup( name, &(font->proptbl) ); + } + + /* Allocate another property if this is overflow. */ + if ( font->props_used == font->props_size ) + { + if ( font->props_size == 0 ) + { + if ( FT_NEW_ARRAY( font->props, 1 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->props, + font->props_size, + font->props_size + 1 ) ) + goto Exit; + } + + fp = font->props + font->props_size; + FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); + font->props_size++; + } + + propid = (unsigned long)hn->data; + if ( propid >= _num_bdf_properties ) + prop = font->user_props + ( propid - _num_bdf_properties ); + else + prop = (bdf_property_t*)_bdf_properties + propid; + + fp = font->props + font->props_used; + + fp->name = prop->name; + fp->format = prop->format; + fp->builtin = prop->builtin; + + switch ( prop->format ) + { + case BDF_ATOM: + if ( value == 0 ) + len = 1; + else + len = ft_strlen( value ) + 1; + + if ( len > 1 ) + { + if ( FT_NEW_ARRAY( fp->value.atom, len ) ) + goto Exit; + FT_MEM_COPY( fp->value.atom, value, len ); + } + else + fp->value.atom = 0; + break; + + case BDF_INTEGER: + fp->value.int32 = _bdf_atol( value, 0, 10 ); + break; + + case BDF_CARDINAL: + fp->value.card32 = _bdf_atoul( value, 0, 10 ); + break; + } + + /* If the property happens to be a comment, then it doesn't need */ + /* to be added to the internal hash table. */ + if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) { + /* Add the property to the font property table. */ + error = hash_insert( fp->name, + (void *)font->props_used, + (hashtable *)font->internal, + memory ); + if ( error ) + goto Exit; + } + + font->props_used++; + + /* Some special cases need to be handled here. The DEFAULT_CHAR */ + /* property needs to be located if it exists in the property list, the */ + /* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */ + /* present, and the SPACING property should override the default */ + /* spacing. */ + if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 ) + font->default_glyph = fp->value.int32; + else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 ) + font->font_ascent = fp->value.int32; + else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 ) + font->font_descent = fp->value.int32; + else if ( ft_memcmp( name, "SPACING", 7 ) == 0 ) + { + if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' ) + font->spacing = BDF_PROPORTIONAL; + else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' ) + font->spacing = BDF_MONOWIDTH; + else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' ) + font->spacing = BDF_CHARCELL; + } + + Exit: + return error; + } + + + static const unsigned char nibble_mask[8] = + { + 0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE + }; + + + /* Actually parse the glyph info and bitmaps. */ + static FT_Error + _bdf_parse_glyphs( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + int c, mask_index; + char* s; + unsigned char* bp; + unsigned long i, slen, nibbles; + + _bdf_line_func_t* next; + _bdf_parse_t* p; + bdf_glyph_t* glyph; + bdf_font_t* font; + + FT_Memory memory; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + font = p->font; + memory = font->memory; + + /* Check for a comment. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + error = _bdf_add_comment( p->font, s, linelen ); + goto Exit; + } + + /* The very first thing expected is the number of glyphs. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + { + if ( ft_memcmp( line, "CHARS", 5 ) != 0 ) + { + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" )); + error = BDF_Err_Missing_Chars_Field; + goto Exit; + } + + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + /* Make sure the number of glyphs is non-zero. */ + if ( p->cnt == 0 ) + font->glyphs_size = 64; + + if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) + goto Exit; + + p->flags |= _BDF_GLYPHS; + + goto Exit; + } + + /* Check for the ENDFONT field. */ + if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 ) + { + /* Sort the glyphs by encoding. */ + ft_qsort( (char *)font->glyphs, + font->glyphs_used, + sizeof ( bdf_glyph_t ), + by_encoding ); + + p->flags &= ~_BDF_START; + + goto Exit; + } + + /* Check for the ENDCHAR field. */ + if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 ) + { + p->glyph_enc = 0; + p->flags &= ~_BDF_GLYPH_BITS; + + goto Exit; + } + + /* Check to see whether a glyph is being scanned but should be */ + /* ignored because it is an unencoded glyph. */ + if ( ( p->flags & _BDF_GLYPH ) && + p->glyph_enc == -1 && + p->opts->keep_unencoded == 0 ) + goto Exit; + + /* Check for the STARTCHAR field. */ + if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 ) + { + /* Set the character name in the parse info first until the */ + /* encoding can be checked for an unencoded character. */ + FT_FREE( p->glyph_name ); + + error = _bdf_split( (char *)" +", line, linelen, &p->list,memory ); + if ( error ) + goto Exit; + _bdf_shift( 1, &p->list ); + + s = _bdf_join( ' ', &slen, &p->list ); + + if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) + goto Exit; + FT_MEM_COPY( p->glyph_name, s, slen + 1 ); + + p->flags |= _BDF_GLYPH; + + goto Exit; + } + + /* Check for the ENCODING field. */ + if ( ft_memcmp( line, "ENCODING", 8 ) == 0 ) + { + if ( !( p->flags & _BDF_GLYPH ) ) + { + /* Missing STARTCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); + error = BDF_Err_Missing_Startchar_Field; + goto Exit; + } + + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + + /* Check to see whether this encoding has already been encountered. */ + /* If it has then change it to unencoded so it gets added if */ + /* indicated. */ + if ( p->glyph_enc >= 0 ) + { + if ( _bdf_glyph_modified( p->have, p->glyph_enc ) ) + { + /* Emit a message saying a glyph has been moved to the */ + /* unencoded area. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12, + p->glyph_enc, p->glyph_name )); + p->glyph_enc = -1; + font->modified = 1; + } + else + _bdf_set_glyph_modified( p->have, p->glyph_enc ); + } + + if ( p->glyph_enc >= 0 ) + { + /* Make sure there are enough glyphs allocated in case the */ + /* number of characters happen to be wrong. */ + if ( font->glyphs_used == font->glyphs_size ) + { + if ( FT_RENEW_ARRAY( font->glyphs, + font->glyphs_size, + font->glyphs_size + 64 ) ) + goto Exit; + FT_MEM_ZERO( font->glyphs + font->glyphs_size, + sizeof ( bdf_glyph_t ) * 64 ); /* FZ inutile */ + font->glyphs_size += 64; + } + + glyph = font->glyphs + font->glyphs_used++; + glyph->name = p->glyph_name; + glyph->encoding = p->glyph_enc; + + /* Reset the initial glyph info. */ + p->glyph_name = 0; + } + else + { + /* Unencoded glyph. Check to see whether it should */ + /* be added or not. */ + if ( p->opts->keep_unencoded != 0 ) + { + /* Allocate the next unencoded glyph. */ + if ( font->unencoded_used == font->unencoded_size ) + { + if ( font->unencoded_size == 0 ) + { + if ( FT_NEW_ARRAY( font->unencoded, 4 ) ) + goto Exit; + } + else + { + if ( FT_RENEW_ARRAY( font->unencoded , + font->unencoded_size, + font->unencoded_size + 4 ) ) + goto Exit; + } + font->unencoded_size += 4; + } + + glyph = font->unencoded + font->unencoded_used; + glyph->name = p->glyph_name; + glyph->encoding = font->unencoded_used++; + } + else + /* Free up the glyph name if the unencoded shouldn't be */ + /* kept. */ + FT_FREE( p->glyph_name ); + + p->glyph_name = 0; + } + + /* Clear the flags that might be added when width and height are */ + /* checked for consistency. */ + p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + + p->flags |= _BDF_ENCODING; + + goto Exit; + } + + /* Point at the glyph being constructed. */ + if ( p->glyph_enc == -1 ) + glyph = font->unencoded + ( font->unencoded_used - 1 ); + else + glyph = font->glyphs + ( font->glyphs_used - 1 ); + + /* Check to see whether a bitmap is being constructed. */ + if ( p->flags & _BDF_BITMAP ) + { + /* If there are more rows than are specified in the glyph metrics, */ + /* ignore the remaining lines. */ + if ( p->row >= (unsigned long)glyph->bbx.height ) + { + if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); + p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + font->modified = 1; + } + + goto Exit; + } + + /* Only collect the number of nibbles indicated by the glyph */ + /* metrics. If there are more columns, they are simply ignored. */ + nibbles = glyph->bpr << 1; + bp = glyph->bitmap + p->row * glyph->bpr; + + for ( i = 0, *bp = 0; i < nibbles; i++ ) + { + c = line[i]; + *bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] ); + if ( i + 1 < nibbles && ( i & 1 ) ) + *++bp = 0; + } + + /* Remove possible garbage at the right. */ + mask_index = ( glyph->bbx.width * p->font->bpp ) & 7; + *bp &= nibble_mask[mask_index]; + + /* If any line has extra columns, indicate they have been removed. */ + if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) && + !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + { + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); + p->flags |= _BDF_GLYPH_WIDTH_CHECK; + font->modified = 1; + } + + p->row++; + goto Exit; + } + + /* Expect the SWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 ) + { + if ( !( p->flags & _BDF_ENCODING ) ) + { + /* Missing ENCODING field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" )); + error = BDF_Err_Missing_Encoding_Field; + goto Exit; + } + + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + p->flags |= _BDF_SWIDTH; + + goto Exit; + } + + /* Expect the DWIDTH (scalable width) field next. */ + if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) + { + error = _bdf_split( (char *)" +", line, linelen, &p->list,memory ); + if ( error ) + goto Exit; + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + + if ( !( p->flags & _BDF_SWIDTH ) ) + { + /* Missing SWIDTH field. Emit an auto correction message and set */ + /* the scalable width from the device width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno )); + + glyph->swidth = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + } + + p->flags |= _BDF_DWIDTH; + goto Exit; + } + + /* Expect the BBX field next. */ + if ( ft_memcmp( line, "BBX", 3 ) == 0 ) + { + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + + glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + /* Generate the ascent and descent of the character. */ + glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); + glyph->bbx.descent = (short)( -glyph->bbx.y_offset ); + + /* Determine the overall font bounding box as the characters are */ + /* loaded so corrections can be done later if indicated. */ + p->maxas = (short)MAX( glyph->bbx.ascent, p->maxas ); + p->maxds = (short)MAX( glyph->bbx.descent, p->maxds ); + + p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset ); + + p->maxrb = (short)MAX( p->rbearing, p->maxrb ); + p->minlb = (short)MIN( glyph->bbx.x_offset, p->minlb ); + p->maxlb = (short)MAX( glyph->bbx.x_offset, p->maxlb ); + + if ( !( p->flags & _BDF_DWIDTH ) ) + { + /* Missing DWIDTH field. Emit an auto correction message and set */ + /* the device width to the glyph width. */ + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno )); + glyph->dwidth = glyph->bbx.width; + } + + /* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */ + /* value if necessary. */ + if ( p->opts->correct_metrics != 0 ) + { + /* Determine the point size of the glyph. */ + unsigned short sw = (unsigned short)FT_MulDiv( + glyph->dwidth, 72000L, + (FT_Long)( font->point_size * + font->resolution_x ) ); + + + if ( sw != glyph->swidth ) + { + glyph->swidth = sw; + + if ( p->glyph_enc == -1 ) + _bdf_set_glyph_modified( font->umod, + font->unencoded_used - 1 ); + else + _bdf_set_glyph_modified( font->nmod, glyph->encoding ); + + p->flags |= _BDF_SWIDTH_ADJ; + font->modified = 1; + } + } + + p->flags |= _BDF_BBX; + goto Exit; + } + + /* And finally, gather up the bitmap. */ + if ( ft_memcmp( line, "BITMAP", 6 ) == 0 ) + { + if ( !( p->flags & _BDF_BBX ) ) + { + /* Missing BBX field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); + error = BDF_Err_Missing_Bbx_Field; + goto Exit; + } + + /* Allocate enough space for the bitmap. */ + glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3; + glyph->bytes = (unsigned short)( glyph->bpr * glyph->bbx.height ); + + if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) ) + goto Exit; + + p->row = 0; + p->flags |= _BDF_BITMAP; + + goto Exit; + } + + error = BDF_Err_Invalid_File_Format; + + Exit: + return error; + } + + + /* Load the font properties. */ + static FT_Error + _bdf_parse_properties( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long vlen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + char* name; + char* value; + char nbuf[128]; + FT_Memory memory; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( lineno ); + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + memory = p->font->memory; + + /* Check for the end of the properties. */ + if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 ) + { + /* If the FONT_ASCENT or FONT_DESCENT properties have not been */ + /* encountered yet, then make sure they are added as properties and */ + /* make sure they are set from the font bounding box info. */ + /* */ + /* This is *always* done regardless of the options, because X11 */ + /* requires these two fields to compile fonts. */ + if ( bdf_get_font_property( p->font, (char *)"FONT_ASCENT" ) == 0 ) + { + p->font->font_ascent = p->font->bbx.ascent; + ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); + error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent )); + p->font->modified = 1; + } + + if ( bdf_get_font_property( p->font, (char *)"FONT_DESCENT" ) == 0 ) + { + p->font->font_descent = p->font->bbx.descent; + ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); + error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf ); + if ( error ) + goto Exit; + + FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent )); + p->font->modified = 1; + } + + p->flags &= ~_BDF_PROPS; + *next = _bdf_parse_glyphs; + + goto Exit; + } + + /* Ignore the _XFREE86_GLYPH_RANGES properties. */ + if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 ) + goto Exit; + + /* Handle COMMENT fields and properties in a special way to preserve */ + /* the spacing. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + name = value = line; + value += 7; + if ( *value ) + *value++ = 0; + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) ) + { + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + else + { + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + name = p->list.field[0]; + + _bdf_shift( 1, &p->list ); + value = _bdf_join( ' ', &vlen, &p->list ); + + error = _bdf_add_property( p->font, name, value ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + /* Load the font header. */ + static FT_Error + _bdf_parse_start( char* line, + unsigned long linelen, + unsigned long lineno, + void* call_data, + void* client_data ) + { + unsigned long slen; + _bdf_line_func_t* next; + _bdf_parse_t* p; + bdf_font_t* font; + char *s; + + FT_Memory memory = NULL; + FT_Error error = BDF_Err_Ok; + + FT_UNUSED( lineno ); /* only used in debug mode */ + + + next = (_bdf_line_func_t *)call_data; + p = (_bdf_parse_t *) client_data; + + if ( p->font ) + memory = p->font->memory; + + /* Check for a comment. This is done to handle those fonts that have */ + /* comments before the STARTFONT line for some reason. */ + if ( ft_memcmp( line, "COMMENT", 7 ) == 0 ) + { + if ( p->opts->keep_comments != 0 && p->font != 0 ) + { + linelen -= 7; + + s = line + 7; + if ( *s != 0 ) + { + s++; + linelen--; + } + + error = _bdf_add_comment( p->font, s, linelen ); + if ( error ) + goto Exit; + /* here font is not defined! */ + } + + goto Exit; + } + + if ( !( p->flags & _BDF_START ) ) + { + memory = p->memory; + + if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 ) + { + /* No STARTFONT field is a good indication of a problem. */ + error = BDF_Err_Missing_Startfont_Field; + goto Exit; + } + + p->flags = _BDF_START; + font = p->font = 0; + + if ( FT_NEW( font ) ) + goto Exit; + p->font = font; + + font->memory = p->memory; + p->memory = 0; + + { /* setup */ + unsigned long i; + bdf_property_t* prop; + + + error = hash_init( &(font->proptbl), memory ); + if ( error ) + goto Exit; + for ( i = 0, prop = (bdf_property_t*)_bdf_properties; + i < _num_bdf_properties; i++, prop++ ) + { + error = hash_insert( prop->name, (void *)i, + &(font->proptbl), memory ); + if ( error ) + goto Exit; + } + } + + if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + goto Exit; + error = hash_init( (hashtable *)p->font->internal,memory ); + if ( error ) + goto Exit; + p->font->spacing = p->opts->font_spacing; + p->font->default_glyph = -1; + + goto Exit; + } + + /* Check for the start of the properties. */ + if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 ) + { + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + + if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) + goto Exit; + + p->flags |= _BDF_PROPS; + *next = _bdf_parse_properties; + + goto Exit; + } + + /* Check for the FONTBOUNDINGBOX field. */ + if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) + { + if ( !(p->flags & _BDF_SIZE ) ) + { + /* Missing the SIZE field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); + error = BDF_Err_Missing_Size_Field; + goto Exit; + } + + error = _bdf_split( (char *)" +", line, linelen, &p->list , memory ); + if ( error ) + goto Exit; + + p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); + p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); + + p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + + p->font->bbx.ascent = (short)( p->font->bbx.height + + p->font->bbx.y_offset ); + + p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); + + p->flags |= _BDF_FONT_BBX; + + goto Exit; + } + + /* The next thing to check for is the FONT field. */ + if ( ft_memcmp( line, "FONT", 4 ) == 0 ) + { + error = _bdf_split( (char *)" +", line, linelen, &p->list , memory ); + if ( error ) + goto Exit; + _bdf_shift( 1, &p->list ); + + s = _bdf_join( ' ', &slen, &p->list ); + if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) + goto Exit; + FT_MEM_COPY( p->font->name, s, slen + 1 ); + + /* If the font name is an XLFD name, set the spacing to the one in */ + /* the font name. If there is no spacing fall back on the default. */ + error = _bdf_set_default_spacing( p->font, p->opts ); + if ( error ) + goto Exit; + + p->flags |= _BDF_FONT_NAME; + + goto Exit; + } + + /* Check for the SIZE field. */ + if ( ft_memcmp( line, "SIZE", 4 ) == 0 ) + { + if ( !( p->flags & _BDF_FONT_NAME ) ) + { + /* Missing the FONT field. */ + FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); + error = BDF_Err_Missing_Font_Field; + goto Exit; + } + + error = _bdf_split( (char *)" +", line, linelen, &p->list, memory ); + if ( error ) + goto Exit; + + p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); + p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + + /* Check for the bits per pixel field. */ + if ( p->list.used == 5 ) + { + unsigned short bitcount, i, shift; + + + p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + + /* Only values 1, 2, 4, 8 are allowed. */ + shift = p->font->bpp; + bitcount = 0; + for ( i = 0; shift > 0; i++ ) + { + if ( shift & 1 ) + bitcount = i; + shift >>= 1; + } + + shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) ); + + if ( p->font->bpp > shift || p->font->bpp != shift ) + { + /* select next higher value */ + p->font->bpp = (unsigned short)( shift << 1 ); + FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp )); + } + } + else + p->font->bpp = 1; + + p->flags |= _BDF_SIZE; + + goto Exit; + } + + error = BDF_Err_Invalid_File_Format; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* API. */ + /* */ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + bdf_load_font( FT_Stream stream, + FT_Memory extmemory, + bdf_options_t* opts, + bdf_font_t* *font ) + { + unsigned long lineno; + _bdf_parse_t *p; + + FT_Memory memory = extmemory; + FT_Error error = BDF_Err_Ok; + + + if ( FT_ALLOC( p, sizeof ( _bdf_parse_t ) ) ) + goto Exit; + + memory = NULL; + p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); + p->minlb = 32767; + p->memory = extmemory; /* only during font creation */ + + error = _bdf_readstream( stream, _bdf_parse_start, + (void *)p, &lineno ); + if ( error ) + goto Exit; + + if ( p->font != 0 ) + { + /* If the font is not proportional, set the font's monowidth */ + /* field to the width of the font bounding box. */ + memory = p->font->memory; + + if ( p->font->spacing != BDF_PROPORTIONAL ) + p->font->monowidth = p->font->bbx.width; + + /* If the number of glyphs loaded is not that of the original count, */ + /* indicate the difference. */ + if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, + p->font->glyphs_used + p->font->unencoded_used )); + p->font->modified = 1; + } + + /* Once the font has been loaded, adjust the overall font metrics if */ + /* necessary. */ + if ( p->opts->correct_metrics != 0 && + ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) ) + { + if ( p->maxrb - p->minlb != p->font->bbx.width ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG3, + p->font->bbx.width, p->maxrb - p->minlb )); + p->font->bbx.width = (unsigned short)( p->maxrb - p->minlb ); + p->font->modified = 1; + } + + if ( p->font->bbx.x_offset != p->minlb ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG4, + p->font->bbx.x_offset, p->minlb )); + p->font->bbx.x_offset = p->minlb; + p->font->modified = 1; + } + + if ( p->font->bbx.ascent != p->maxas ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG5, + p->font->bbx.ascent, p->maxas )); + p->font->bbx.ascent = p->maxas; + p->font->modified = 1; + } + + if ( p->font->bbx.descent != p->maxds ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG6, + p->font->bbx.descent, p->maxds )); + p->font->bbx.descent = p->maxds; + p->font->bbx.y_offset = (short)( -p->maxds ); + p->font->modified = 1; + } + + if ( p->maxas + p->maxds != p->font->bbx.height ) + { + FT_TRACE2(( "bdf_load_font: " ACMSG7, + p->font->bbx.height, p->maxas + p->maxds )); + p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); + } + + if ( p->flags & _BDF_SWIDTH_ADJ ) + FT_TRACE2(( "bdf_load_font: " ACMSG8 )); + } + } + + if ( p->flags & _BDF_START ) + { + { + /* The ENDFONT field was never reached or did not exist. */ + if ( !( p->flags & _BDF_GLYPHS ) ) + /* Error happened while parsing header. */ + FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); + else + /* Error happened when parsing glyphs. */ + FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); + } + } + + /* Free up the list used during the parsing. */ + if ( memory != NULL ) + FT_FREE( p->list.field ); + + if ( p->font != 0 ) + { + /* Make sure the comments are NULL terminated if they exist. */ + memory = p->font->memory; + + if ( p->font->comments_len > 0 ) { + if ( FT_RENEW_ARRAY( p->font->comments, + p->font->comments_len, + p->font->comments_len + 1 ) ) + goto Exit; + + p->font->comments[p->font->comments_len] = 0; + } + } + else if ( error == BDF_Err_Ok ) + error = BDF_Err_Invalid_File_Format; + + *font = p->font; + + Exit: + if ( p ) + { + memory = extmemory; + FT_FREE( p ); + } + + return error; + } + + + FT_LOCAL_DEF( void ) + bdf_free_font( bdf_font_t* font ) + { + bdf_property_t* prop; + unsigned long i; + bdf_glyph_t* glyphs; + FT_Memory memory; + + + if ( font == 0 ) + return; + + memory = font->memory; + + FT_FREE( font->name ); + + /* Free up the internal hash table of property names. */ + if ( font->internal ) + { + hash_free( (hashtable *)font->internal, memory ); + FT_FREE( font->internal ); + } + + /* Free up the comment info. */ + FT_FREE( font->comments ); + + /* Free up the properties. */ + for ( i = 0; i < font->props_size; i++ ) + { + if ( font->props[i].format == BDF_ATOM ) + FT_FREE( font->props[i].value.atom ); + } + + FT_FREE( font->props ); + + /* Free up the character info. */ + for ( i = 0, glyphs = font->glyphs; + i < font->glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + for ( i = 0, glyphs = font->unencoded; i < font->unencoded_used; + i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->glyphs ); + FT_FREE( font->unencoded ); + + /* Free up the overflow storage if it was used. */ + for ( i = 0, glyphs = font->overflow.glyphs; + i < font->overflow.glyphs_used; i++, glyphs++ ) + { + FT_FREE( glyphs->name ); + FT_FREE( glyphs->bitmap ); + } + + FT_FREE( font->overflow.glyphs ); + + /* bdf_cleanup */ + hash_free( &(font->proptbl), memory ); + + /* Free up the user defined properties. */ + for (prop = font->user_props, i = 0; + i < font->nuser_props; i++, prop++ ) + { + FT_FREE( prop->name ); + if ( prop->format == BDF_ATOM ) + FT_FREE( prop->value.atom ); + } + + FT_FREE( font->user_props ); + + /* FREE( font ); */ /* XXX Fixme */ + } + + + FT_LOCAL_DEF( bdf_property_t * ) + bdf_get_font_property( bdf_font_t* font, + char* name ) + { + hashnode hn; + + + if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) + return 0; + + hn = hash_lookup( name, (hashtable *)font->internal ); + + return hn ? ( font->props + (unsigned long)hn->data ) : 0; + } + + +/* END */ diff --git a/lib/freetype/src/bdf/descrip.mms b/lib/freetype/src/bdf/descrip.mms new file mode 100644 index 0000000..4c32dc4 --- /dev/null +++ b/lib/freetype/src/bdf/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 BDF driver compilation rules for VMS +# + + +# Copyright 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.bdf]) + +OBJS=bdf.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/bdf/module.mk b/lib/freetype/src/bdf/module.mk new file mode 100644 index 0000000..24115e7 --- /dev/null +++ b/lib/freetype/src/bdf/module.mk @@ -0,0 +1,31 @@ +# +# FreeType 2 BDF module definition +# + +# Copyright 2001, 2002 by +# Francesco Zappa Nardelli +# +# 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 +# AUTHORS OR COPYRIGHT HOLDERS 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. + +make_module_list: add_bdf_driver + +add_bdf_driver: + $(OPEN_DRIVER)bdf_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)bdf $(ECHO_DRIVER_DESC)bdf bitmap fonts$(ECHO_DRIVER_DONE) + diff --git a/lib/freetype/src/bdf/rules.mk b/lib/freetype/src/bdf/rules.mk new file mode 100644 index 0000000..b1a3ed9 --- /dev/null +++ b/lib/freetype/src/bdf/rules.mk @@ -0,0 +1,79 @@ +# +# FreeType 2 bdf driver configuration rules +# + + +# Copyright (C) 2001, 2002 by +# Francesco Zappa Nardelli +# +# 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 +# AUTHORS OR COPYRIGHT HOLDERS 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. + + + + +# bdf driver directory +# +BDF_DIR := $(SRC_)bdf +BDF_DIR_ := $(BDF_DIR)$(SEP) + + +BDF_COMPILE := $(FT_COMPILE) $I$(BDF_DIR) + + +# bdf driver sources (i.e., C files) +# +BDF_DRV_SRC := $(BDF_DIR_)bdflib.c $(BDF_DIR_)bdfdrivr.c + + +# bdf driver headers +# +BDF_DRV_H := $(BDF_DIR_)bdf.h \ + $(BDF_DIR_)bdfdrivr.h + +# bdf driver object(s) +# +# BDF_DRV_OBJ_M is used during `multi' builds +# BDF_DRV_OBJ_S is used during `single' builds +# +BDF_DRV_OBJ_M := $(BDF_DRV_SRC:$(BDF_DIR_)%.c=$(OBJ_)%.$O) +BDF_DRV_OBJ_S := $(OBJ_)bdf.$O + +# bdf driver source file for single build +# +BDF_DRV_SRC_S := $(BDF_DIR_)bdf.c + + +# bdf driver - single object +# +$(BDF_DRV_OBJ_S): $(BDF_DRV_SRC_S) $(BDF_DRV_SRC) $(FREETYPE_H) $(BDF_DRV_H) + $(BDF_COMPILE) $T$@ $(BDF_DRV_SRC_S) + + +# bdf driver - multiple objects +# +$(OBJ_)%.$O: $(BDF_DIR_)%.c $(FREETYPE_H) $(BDF_DRV_H) + $(BDF_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(BDF_DRV_OBJ_S) +DRV_OBJS_M += $(BDF_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/cache/Jamfile b/lib/freetype/src/cache/Jamfile new file mode 100644 index 0000000..099fd5e --- /dev/null +++ b/lib/freetype/src/cache/Jamfile @@ -0,0 +1,27 @@ +# FreeType 2 src/cache Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) cache ; + +# The file <freetype/ftcache.h> contains some macro definitions that are +# later used in #include statements related to the cache sub-system. It +# needs to be parsed through a HDRMACRO rule for macro definitions. +# +HDRMACRO [ FT2_SubDir include ftcache.h ] ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftlru ftcmanag ftccache ftcglyph ftcsbits ftcimage ftccmap ; + } + else + { + _sources = ftcache ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cache Jamfile diff --git a/lib/freetype/src/cache/descrip.mms b/lib/freetype/src/cache/descrip.mms new file mode 100644 index 0000000..ea12f2e --- /dev/null +++ b/lib/freetype/src/cache/descrip.mms @@ -0,0 +1,26 @@ +# +# FreeType 2 Cache compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cache]) + +OBJS=ftcache.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +ftcache.obj : ftcache.c ftlru.c ftcmanag.c ftccache.c ftcglyph.c ftcimage.c \ + ftcsbits.c ftccmap.c + +# EOF diff --git a/lib/freetype/src/cache/ftcache.c b/lib/freetype/src/cache/ftcache.c new file mode 100644 index 0000000..07e85e1 --- /dev/null +++ b/lib/freetype/src/cache/ftcache.c @@ -0,0 +1,31 @@ +/***************************************************************************/ +/* */ +/* ftcache.c */ +/* */ +/* The FreeType Caching sub-system (body only). */ +/* */ +/* Copyright 2000-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftlru.c" +#include "ftcmanag.c" +#include "ftccache.c" +#include "ftcglyph.c" +#include "ftcimage.c" +#include "ftcsbits.c" +#include "ftccmap.c" + + +/* END */ diff --git a/lib/freetype/src/cache/ftccache.c b/lib/freetype/src/cache/ftccache.c new file mode 100644 index 0000000..a12fedc --- /dev/null +++ b/lib/freetype/src/cache/ftccache.c @@ -0,0 +1,807 @@ +/***************************************************************************/ +/* */ +/* ftccache.c */ +/* */ +/* The FreeType internal cache interface (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_CACHE_MANAGER_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + +#define FTC_HASH_MAX_LOAD 2 +#define FTC_HASH_MIN_LOAD 1 +#define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) + +/* this one _must_ be a power of 2! */ +#define FTC_HASH_INITIAL_SIZE 8 + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE NODE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_EXPORT_DEF( void ) + ftc_node_done( FTC_Node node, + FTC_Cache cache ) + { + FTC_Family family; + FTC_FamilyEntry entry; + + + entry = cache->manager->families.entries + node->fam_index; + family = entry->family; + + /* remove from parent set table - eventually destroy the set */ + if ( --family->num_nodes == 0 ) + FT_LruList_Remove( cache->families, (FT_LruNode) family ); + } + + + /* add a new node to the head of the manager's circular MRU list */ + static void + ftc_node_mru_link( FTC_Node node, + FTC_Manager manager ) + { + FTC_Node first = manager->nodes_list; + + + if ( first ) + { + FTC_Node last = first->mru_prev; + + + FT_ASSERT( last->mru_next == first ); + + node->mru_prev = last; + node->mru_next = first; + + last->mru_next = node; + first->mru_prev = node; + } + else + { + FT_ASSERT( manager->num_nodes == 0 ); + + node->mru_next = node; + node->mru_prev = node; + } + + manager->nodes_list = node; + manager->num_nodes++; + } + + + /* remove a node from the manager's MRU list */ + static void + ftc_node_mru_unlink( FTC_Node node, + FTC_Manager manager ) + { + FTC_Node first = manager->nodes_list; + FTC_Node prev = node->mru_prev; + FTC_Node next = node->mru_next; + + + FT_ASSERT( first != NULL && manager->num_nodes > 0 ); + FT_ASSERT( next->mru_prev == node ); + FT_ASSERT( prev->mru_next == node ); + + next->mru_prev = prev; + prev->mru_next = next; + + if ( node == first ) + { + /* this is the last node in the list; update its head pointer */ + if ( node == next ) + manager->nodes_list = NULL; + else + manager->nodes_list = next; + } + + node->mru_next = NULL; + node->mru_prev = NULL; + manager->num_nodes--; + } + + + /* move a node to the head of the manager's MRU list */ + static void + ftc_node_mru_up( FTC_Node node, + FTC_Manager manager ) + { + FTC_Node first = manager->nodes_list; + + + if ( node != first ) + { + FTC_Node prev = node->mru_prev; + FTC_Node next = node->mru_next; + FTC_Node last; + + + prev->mru_next = next; + next->mru_prev = prev; + + last = first->mru_prev; + node->mru_next = first; + node->mru_prev = last; + first->mru_prev = node; + last->mru_next = node; + + manager->nodes_list = node; + } + } + + + /* remove a node from its cache's hash table */ + static FT_Error + ftc_node_hash_unlink( FTC_Node node, + FTC_Cache cache ) + { + FT_Error error = 0; + FTC_Node *pnode; + FT_UInt idx, num_buckets; + + + idx = (FT_UInt)( node->hash & cache->mask ); + if ( idx < cache->p ) + idx = (FT_UInt)( node->hash & ( 2 * cache->mask + 1 ) ); + + pnode = cache->buckets + idx; + + for (;;) + { + if ( *pnode == NULL ) + { + FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); + return FT_Err_Ok; + } + + if ( *pnode == node ) + { + *pnode = node->link; + node->link = NULL; + break; + } + + pnode = &(*pnode)->link; + } + + num_buckets = ( cache->p + cache->mask + 1 ); + + if ( ++cache->slack > (FT_Long)num_buckets * FTC_HASH_SUB_LOAD ) + { + FT_UInt p = cache->p; + FT_UInt mask = cache->mask; + FT_UInt old_index = p + mask; + FTC_Node* pold; + + + if ( old_index+1 <= FTC_HASH_INITIAL_SIZE ) + goto Exit; + + if ( p == 0 ) + { + FT_Memory memory = cache->memory; + + + cache->mask >>= 1; + p = cache->mask; + + if ( FT_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, (mask+1) ) ) + { + FT_ERROR(( "ftc_node_hash_unlink: couldn't shunk buckets!\n" )); + goto Exit; + } + } + else + p--; + + pnode = cache->buckets + p; + while ( *pnode ) + pnode = &(*pnode)->link; + + pold = cache->buckets + old_index; + *pnode = *pold; + *pold = NULL; + + cache->slack -= FTC_HASH_MAX_LOAD; + cache->p = p; + } + + Exit: + return error; + } + + + + /* add a node to the "top" of its cache's hash table */ + static FT_Error + ftc_node_hash_link( FTC_Node node, + FTC_Cache cache ) + { + FTC_Node *pnode; + FT_UInt idx; + FT_Error error = 0; + + + idx = (FT_UInt)( node->hash & cache->mask ); + if ( idx < cache->p ) + idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) ); + + pnode = cache->buckets + idx; + + node->link = *pnode; + *pnode = node; + + if ( --cache->slack < 0 ) + { + FT_UInt p = cache->p; + FT_UInt mask = cache->mask; + FTC_Node new_list; + + + /* split a single bucket */ + new_list = NULL; + pnode = cache->buckets + p; + + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash & ( mask + 1 ) ) + { + *pnode = node->link; + node->link = new_list; + new_list = node; + } + else + pnode = &node->link; + } + + cache->buckets[p + mask + 1] = new_list; + + cache->slack += FTC_HASH_MAX_LOAD; + + if ( p >= mask ) + { + FT_Memory memory = cache->memory; + + + if ( FT_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) + { + FT_ERROR(( "ftc_node_hash_link: couldn't expand buckets!\n" )); + goto Exit; + } + + cache->mask = 2 * mask + 1; + cache->p = 0; + } + else + cache->p = p + 1; + } + + Exit: + return error; + } + + + + + /* remove a node from the cache manager */ + FT_EXPORT_DEF( void ) + ftc_node_destroy( FTC_Node node, + FTC_Manager manager ) + { + FT_Memory memory = manager->library->memory; + FTC_Cache cache; + FTC_FamilyEntry entry; + FTC_Cache_Class clazz; + + +#ifdef FT_DEBUG_ERROR + /* find node's cache */ + if ( node->fam_index >= manager->families.count ) + { + FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + entry = manager->families.entries + node->fam_index; + cache = entry->cache; + +#ifdef FT_DEBUG_ERROR + if ( cache == NULL ) + { + FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); + return; + } +#endif + + clazz = cache->clazz; + + manager->cur_weight -= clazz->node_weight( node, cache ); + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* remove node from cache's hash table */ + ftc_node_hash_unlink( node, cache ); + + /* now finalize it */ + if ( clazz->node_done ) + clazz->node_done( node, cache ); + + FT_FREE( node ); + +#if 0 + /* check, just in case of general corruption :-) */ + if ( manager->num_nodes == 0 ) + FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n", + manager->num_nodes )); +#endif + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE FAMILY DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_EXPORT_DEF( FT_Error ) + ftc_family_init( FTC_Family family, + FTC_Query query, + FTC_Cache cache ) + { + FT_Error error; + FTC_Manager manager = cache->manager; + FT_Memory memory = manager->library->memory; + FTC_FamilyEntry entry; + + + family->cache = cache; + family->num_nodes = 0; + + /* now add to manager's family table */ + error = ftc_family_table_alloc( &manager->families, memory, &entry ); + if ( !error ) + { + entry->cache = cache; + entry->family = family; + family->fam_index = entry->index; + + query->family = family; /* save family in query */ + } + + return error; + } + + + FT_EXPORT_DEF( void ) + ftc_family_done( FTC_Family family ) + { + if ( family && family->cache ) + { + FTC_Manager manager = family->cache->manager; + + + /* remove from manager's family table */ + ftc_family_table_free( &manager->families, family->fam_index ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** ABSTRACT CACHE CLASS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + + FT_EXPORT_DEF( FT_Error ) + ftc_cache_init( FTC_Cache cache ) + { + FT_Memory memory = cache->memory; + FTC_Cache_Class clazz = cache->clazz; + FT_Error error; + + + cache->p = 0; + cache->mask = FTC_HASH_INITIAL_SIZE - 1; + cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; + + if ( FT_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ) + goto Exit; + + /* now, initialize the lru list of families for this cache */ + if ( clazz->family_size > 0 ) + { + FT_LruList_ClassRec* lru_class = &cache->family_class; + + + lru_class->list_size = sizeof( FT_LruListRec ); + lru_class->list_init = NULL; + lru_class->list_done = NULL; + + lru_class->node_size = clazz->family_size; + lru_class->node_init = (FT_LruNode_InitFunc) clazz->family_init; + lru_class->node_done = (FT_LruNode_DoneFunc) clazz->family_done; + lru_class->node_flush = (FT_LruNode_FlushFunc) NULL; + lru_class->node_compare = (FT_LruNode_CompareFunc)clazz->family_compare; + + error = FT_LruList_New( (FT_LruList_Class) lru_class, + 0, /* max items == 0 => unbounded list */ + cache, + memory, + &cache->families ); + if ( error ) + FT_FREE( cache->buckets ); + } + + Exit: + return error; + } + + + FT_EXPORT_DEF( void ) + ftc_cache_clear( FTC_Cache cache ) + { + if ( cache ) + { + FT_Memory memory = cache->memory; + FTC_Cache_Class clazz = cache->clazz; + FTC_Manager manager = cache->manager; + FT_UFast i; + FT_UInt count; + + count = cache->p + cache->mask + 1; + + for ( i = 0; i < count; i++ ) + { + FTC_Node *pnode = cache->buckets + i, next, node = *pnode; + + + while ( node ) + { + next = node->link; + node->link = NULL; + + /* remove node from mru list */ + ftc_node_mru_unlink( node, manager ); + + /* now finalize it */ + manager->cur_weight -= clazz->node_weight( node, cache ); + + if ( clazz->node_done ) + clazz->node_done( node, cache ); + + FT_FREE( node ); + node = next; + } + cache->buckets[i] = NULL; + } + + cache->p = 0; + + /* destroy the families */ + if ( cache->families ) + FT_LruList_Reset( cache->families ); + } + } + + + FT_EXPORT_DEF( void ) + ftc_cache_done( FTC_Cache cache ) + { + if ( cache ) + { + FT_Memory memory = cache->memory; + + + ftc_cache_clear( cache ); + + FT_FREE( cache->buckets ); + cache->mask = 0; + cache->slack = 0; + + if ( cache->families ) + { + FT_LruList_Destroy( cache->families ); + cache->families = NULL; + } + } + } + + + /* Look up a node in "top" of its cache's hash table. */ + /* If not found, create a new node. */ + /* */ + FT_EXPORT_DEF( FT_Error ) + ftc_cache_lookup( FTC_Cache cache, + FTC_Query query, + FTC_Node *anode ) + { + FT_Error error = FT_Err_Ok; + FTC_Manager manager; + FT_LruNode lru; + FT_UInt free_count = 0; + + + if ( !cache || !query || !anode ) + return FTC_Err_Invalid_Argument; + + *anode = NULL; + + query->hash = 0; + query->family = NULL; + + manager = cache->manager; + + /* here's a small note explaining what's hapenning in the code below. + * + * we need to deal intelligently with out-of-memory (OOM) conditions + * when trying to create a new family or cache node during the lookup. + * + * when an OOM is detected, we'll try to free one or more "old" nodes + * from the cache, then try again. it may be necessary to do that several + * times, so a loop is needed. + * + * the local variable "free_count" holds the number of "old" nodes to + * discard on each attempt. it starts at 1 and doubles on each iteration. + * the loop stops when: + * + * - a non-OOM error is detected + * - a succesful lookup is performed + * - there are no more unused nodes in the cache + * + * for the record, remember that all used nodes appear _before_ + * unused ones in the manager's MRU node list. + */ + + for (;;) + { + { + /* first of all, find the relevant family */ + FT_LruList list = cache->families; + FT_LruNode fam, *pfam; + FT_LruNode_CompareFunc compare = list->clazz->node_compare; + + pfam = &list->nodes; + for (;;) + { + fam = *pfam; + if ( fam == NULL ) + { + error = FT_LruList_Lookup( list, query, &lru ); + if ( error ) + goto Fail; + + goto Skip; + } + + if ( compare( fam, query, list->data ) ) + break; + + pfam = &fam->next; + } + + FT_ASSERT( fam != NULL ); + + /* move to top of list when needed */ + if ( fam != list->nodes ) + { + *pfam = fam->next; + fam->next = list->nodes; + list->nodes = fam; + } + + lru = fam; + + Skip: + ; + } + + { + FTC_Manager manager = cache->manager; + FTC_Family family = (FTC_Family) lru; + FT_UFast hash = query->hash; + FTC_Node* bucket; + FT_UInt idx; + + + idx = hash & cache->mask; + if ( idx < cache->p ) + idx = hash & ( cache->mask * 2 + 1 ); + + bucket = cache->buckets + idx; + + + if ( query->family != family || + family->fam_index >= manager->families.size ) + { + FT_ERROR(( + "ftc_cache_lookup: invalid query (bad 'family' field)\n" )); + error = FTC_Err_Invalid_Argument; + goto Exit; + } + + if ( *bucket ) + { + FTC_Node* pnode = bucket; + FTC_Node_CompareFunc compare = cache->clazz->node_compare; + + + for ( ;; ) + { + FTC_Node node; + + + node = *pnode; + if ( node == NULL ) + break; + + if ( node->hash == hash && + (FT_UInt)node->fam_index == family->fam_index && + compare( node, query, cache ) ) + { + /* move to head of bucket list */ + if ( pnode != bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } + + /* move to head of MRU list */ + if ( node != manager->nodes_list ) + ftc_node_mru_up( node, manager ); + + *anode = node; + goto Exit; + } + + pnode = &node->link; + } + } + + /* didn't find a node, create a new one */ + { + FTC_Cache_Class clazz = cache->clazz; + FT_Memory memory = cache->memory; + FTC_Node node; + + + if ( FT_ALLOC( node, clazz->node_size ) ) + goto Fail; + + node->fam_index = (FT_UShort) family->fam_index; + node->hash = query->hash; + node->ref_count = 0; + + error = clazz->node_init( node, query, cache ); + if ( error ) + { + FT_FREE( node ); + goto Fail; + } + + error = ftc_node_hash_link( node, cache ); + if ( error ) + { + clazz->node_done( node, cache ); + FT_FREE( node ); + goto Fail; + } + + ftc_node_mru_link( node, cache->manager ); + + cache->manager->cur_weight += clazz->node_weight( node, cache ); + + /* now try to compress the node pool when necessary */ + if ( manager->cur_weight >= manager->max_weight ) + { + node->ref_count++; + FTC_Manager_Compress( manager ); + node->ref_count--; + } + + *anode = node; + } + + /* all is well, exit now + */ + goto Exit; + } + + Fail: + if ( error != FT_Err_Out_Of_Memory ) + goto Exit; + + /* there is not enough memory, try to release some unused nodes + * from the cache to make room for a new one. + */ + { + FT_UInt new_count; + + new_count = 1 + free_count*2; + + /* check overflow and bounds */ + if ( new_count < free_count || free_count > manager->num_nodes ) + goto Exit; + + free_count = new_count; + + /* try to remove "new_count" nodes from the list */ + { + FTC_Node first = manager->nodes_list; + FTC_Node node; + + if ( first == NULL ) /* empty list ! */ + goto Exit; + + /* go to last node - it's a circular list */ + node = first->mru_prev; + for ( ; node && new_count > 0; new_count-- ) + { + FTC_Node prev = node->mru_prev; + + /* used nodes always appear before unused one in the MRU + * list. if we find one here, we'd better stop right now + * our iteration + */ + if ( node->ref_count > 0 ) + { + /* if there are no unused nodes in the list, we'd better exit */ + if ( new_count == free_count ) + goto Exit; + + break; + } + + ftc_node_destroy( node, manager ); + + if ( node == first ) + break; + + node = prev; + } + } + } + } + + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftccache.i b/lib/freetype/src/cache/ftccache.i new file mode 100644 index 0000000..bb6e631 --- /dev/null +++ b/lib/freetype/src/cache/ftccache.i @@ -0,0 +1,157 @@ +/***************************************************************************/ +/* */ +/* ftccache.i */ +/* */ +/* FreeType template for generic cache. */ +/* */ +/* Copyright 2002 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 GEN_CACHE_FAMILY_COMPARE +#error "GEN_CACHE_FAMILY_COMPARE not defined in template instantiation" +#endif + +#ifndef GEN_CACHE_NODE_COMPARE +#error "GEN_CACHE_NODE_COMPARE not defined in template instantiation" +#endif + + + static FT_Error + GEN_CACHE_LOOKUP( FTC_Cache cache, + FTC_Query query, + FTC_Node *anode ) + { + FT_LruNode lru; + FTC_Family family; + FT_UFast hash; + + + query->hash = 0; + query->family = NULL; + + /* XXX: we break encapsulation for the sake of speed! */ + { + /* first of all, find the relevant family */ + FT_LruList list = cache->families; + FT_LruNode fam, *pfam; + + + pfam = &list->nodes; + for (;;) + { + fam = *pfam; + if ( fam == NULL ) + goto Normal; + + if ( GEN_CACHE_FAMILY_COMPARE( fam, query, list->data ) ) + break; + + pfam = &fam->next; + } + + FT_ASSERT( fam != NULL ); + + /* move to top of list when needed */ + if ( fam != list->nodes ) + { + *pfam = fam->next; + fam->next = list->nodes; + list->nodes = fam; + } + + lru = fam; + } + + { + FTC_Node node, *pnode, *bucket; + + + family = (FTC_Family)lru; + hash = query->hash; + + { + FT_UInt idx; + + + idx = hash & cache->mask; + if ( idx < cache->p ) + idx = hash & ( cache->mask * 2 + 1 ); + + bucket = cache->buckets + idx; + } + + pnode = bucket; + + for ( ;; ) + { + node = *pnode; + if ( node == NULL ) + goto Normal; + + if ( node->hash == hash && + (FT_UInt)node->fam_index == family->fam_index && + GEN_CACHE_NODE_COMPARE( node, query, cache ) ) + { + /* we place the following out of the loop to make it */ + /* as small as possible... */ + goto Found; + } + + pnode = &node->link; + } + + Normal: + return ftc_cache_lookup( cache, query, anode ); + + Found: + /* move to head of bucket list */ + if ( pnode != bucket ) + { + *pnode = node->link; + node->link = *bucket; + *bucket = node; + } + + /* move to head of MRU list */ + if ( node != cache->manager->nodes_list ) + { + /* XXX: again, this is an inlined version of ftc_node_mru_up */ + FTC_Manager manager = cache->manager; + FTC_Node first = manager->nodes_list; + FTC_Node prev = node->mru_prev; + FTC_Node next = node->mru_next; + FTC_Node last; + + + prev->mru_next = next; + next->mru_prev = prev; + + last = first->mru_prev; + node->mru_next = first; + node->mru_prev = last; + first->mru_prev = node; + last->mru_next = node; + + manager->nodes_list = node; + } + + *anode = node; + return 0; + } + } + +#undef GEN_CACHE_NODE_COMPARE +#undef GEN_CACHE_FAMILY_COMPARE +#undef GEN_CACHE_LOOKUP + + +/* END */ diff --git a/lib/freetype/src/cache/ftccmap.c b/lib/freetype/src/cache/ftccmap.c new file mode 100644 index 0000000..8366ce5 --- /dev/null +++ b/lib/freetype/src/cache/ftccmap.c @@ -0,0 +1,459 @@ +/***************************************************************************/ +/* */ +/* ftccmap.c */ +/* */ +/* FreeType CharMap cache (body) */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_FREETYPE_H +#include FT_CACHE_H +#include FT_CACHE_CHARMAP_H +#include FT_CACHE_MANAGER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRUETYPE_IDS_H + +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + /*************************************************************************/ + /* */ + /* Each FTC_CMapNode contains a simple array to map a range of character */ + /* codes to equivalent glyph indices. */ + /* */ + /* For now, the implementation is very basic: Each node maps a range of */ + /* 128 consecutive character codes to their corresponding glyph indices. */ + /* */ + /* We could do more complex things, but I don't think it is really very */ + /* useful. */ + /* */ + /*************************************************************************/ + + + /* number of glyph indices / character code per node */ +#define FTC_CMAP_INDICES_MAX 128 + + + typedef struct FTC_CMapNodeRec_ + { + FTC_NodeRec node; + FT_UInt32 first; /* first character in node */ + FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ + + } FTC_CMapNodeRec, *FTC_CMapNode; + + +#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) + + + /* compute node hash value from cmap family and "requested" glyph index */ +#define FTC_CMAP_HASH( cfam, cquery ) \ + ( (cfam)->hash + ( (cquery)->char_code / FTC_CMAP_INDICES_MAX ) ) + + /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ + /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ +#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) + + + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_QueryRec query; + FTC_CMapDesc desc; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; + + +#define FTC_CMAP_QUERY( x ) ( (FTC_CMapQuery)( x ) ) + + + /* the charmap family */ + typedef struct FTC_CMapFamilyRec_ + { + FTC_FamilyRec family; + FT_UInt32 hash; + FTC_CMapDescRec desc; + FT_UInt index; + + } FTC_CMapFamilyRec, *FTC_CMapFamily; + + +#define FTC_CMAP_FAMILY( x ) ( (FTC_CMapFamily)( x ) ) +#define FTC_CMAP_FAMILY_MEMORY( x ) FTC_FAMILY( x )->memory + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHARMAP NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* no need for specific finalizer; we use "ftc_node_done" directly */ + + /* initialize a new cmap node */ + FT_CALLBACK_DEF( FT_Error ) + ftc_cmap_node_init( FTC_CMapNode cnode, + FTC_CMapQuery cquery, + FTC_Cache cache ) + { + FT_UInt32 first; + FT_UInt n; + FT_UNUSED( cache ); + + + first = ( cquery->char_code / FTC_CMAP_INDICES_MAX ) * + FTC_CMAP_INDICES_MAX; + + cnode->first = first; + for ( n = 0; n < FTC_CMAP_INDICES_MAX; n++ ) + cnode->indices[n] = FTC_CMAP_UNKNOWN; + + return 0; + } + + + /* compute the weight of a given cmap node */ + FT_CALLBACK_DEF( FT_ULong ) + ftc_cmap_node_weight( FTC_CMapNode cnode ) + { + FT_UNUSED( cnode ); + + return sizeof ( *cnode ); + } + + + /* compare a cmap node to a given query */ + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_compare( FTC_CMapNode cnode, + FTC_CMapQuery cquery ) + { + FT_UInt32 offset = (FT_UInt32)( cquery->char_code - cnode->first ); + + + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHARMAP FAMILY *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + ftc_cmap_family_init( FTC_CMapFamily cfam, + FTC_CMapQuery cquery, + FTC_Cache cache ) + { + FTC_Manager manager = cache->manager; + FTC_CMapDesc desc = cquery->desc; + FT_UInt32 hash = 0; + FT_Error error; + FT_Face face; + + + /* setup charmap descriptor */ + cfam->desc = *desc; + + /* let's see whether the rest is correct too */ + error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face ); + if ( !error ) + { + FT_UInt count = face->num_charmaps; + FT_UInt idx = count; + FT_CharMap* cur = face->charmaps; + + + switch ( desc->type ) + { + case FTC_CMAP_BY_INDEX: + idx = desc->u.index; + hash = idx * 33; + break; + + case FTC_CMAP_BY_ENCODING: + if (desc->u.encoding == FT_ENCODING_UNICODE) + { + /* since the `interesting' table, with id's 3,10, is normally the + * last one, we loop backwards. This looses with type1 fonts with + * non-BMP characters (<.0001%), this wins with .ttf with non-BMP + * chars (.01% ?), and this is the same about 99.99% of the time! + */ + + FT_UInt unicmap_idx = count; /* some UCS-2 map, if we found it */ + + cur += count - 1; + + for ( idx = 0; idx < count; idx++, cur-- ) + { + if ( cur[0]->encoding == FT_ENCODING_UNICODE ) + { + unicmap_idx = idx; /* record we found a Unicode charmap */ + + /* XXX If some new encodings to represent UCS-4 are added, + * they should be added here. + */ + if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && + cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || + ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && + cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) + + /* Hurray! We found a UCS-4 charmap. We can stop the scan! */ + { + idx = count - 1 - idx; + goto Found_idx_for_FTC_CMAP_BY_ENCODING; + } + } + } + + /* We do not have any UCS-4 charmap. Sigh. + * Let's see if we have some other kind of Unicode charmap, though. + */ + if ( unicmap_idx < count ) + idx = count - 1 - unicmap_idx; + } + else + { + for ( idx = 0; idx < count; idx++, cur++ ) + if ( cur[0]->encoding == desc->u.encoding ) + break; + } + + Found_idx_for_FTC_CMAP_BY_ENCODING: + hash = idx * 67; + break; + + case FTC_CMAP_BY_ID: + for ( idx = 0; idx < count; idx++, cur++ ) + { + if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform && + (FT_UInt)cur[0]->encoding_id == desc->u.id.encoding ) + { + hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7; + break; + } + } + break; + + default: + ; + } + + if ( idx >= count ) + goto Bad_Descriptor; + + /* compute hash value, both in family and query */ + cfam->index = idx; + cfam->hash = hash ^ FTC_FACE_ID_HASH( desc->face_id ); + FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); + + error = ftc_family_init( FTC_FAMILY( cfam ), + FTC_QUERY( cquery ), cache ); + } + + return error; + + Bad_Descriptor: + FT_TRACE1(( "ftp_cmap_family_init: invalid charmap descriptor\n" )); + return FTC_Err_Invalid_Argument; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_family_compare( FTC_CMapFamily cfam, + FTC_CMapQuery cquery ) + { + FT_Int result = 0; + + + /* first, compare face id and type */ + if ( cfam->desc.face_id != cquery->desc->face_id || + cfam->desc.type != cquery->desc->type ) + goto Exit; + + switch ( cfam->desc.type ) + { + case FTC_CMAP_BY_INDEX: + result = ( cfam->desc.u.index == cquery->desc->u.index ); + break; + + case FTC_CMAP_BY_ENCODING: + result = ( cfam->desc.u.encoding == cquery->desc->u.encoding ); + break; + + case FTC_CMAP_BY_ID: + result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform && + cfam->desc.u.id.encoding == cquery->desc->u.id.encoding ); + break; + + default: + ; + } + + if ( result ) + { + /* when found, update the 'family' and 'hash' field of the query */ + FTC_QUERY( cquery )->family = FTC_FAMILY( cfam ); + FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); + } + + Exit: + return FT_BOOL( result ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE_DEF + const FTC_Cache_ClassRec ftc_cmap_cache_class = + { + sizeof ( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_ClearFunc)ftc_cache_clear, + (FTC_Cache_DoneFunc) ftc_cache_done, + + sizeof ( FTC_CMapFamilyRec ), + (FTC_Family_InitFunc) ftc_cmap_family_init, + (FTC_Family_CompareFunc)ftc_cmap_family_compare, + (FTC_Family_DoneFunc) ftc_family_done, + + sizeof ( FTC_CMapNodeRec ), + (FTC_Node_InitFunc) ftc_cmap_node_init, + (FTC_Node_WeightFunc) ftc_cmap_node_weight, + (FTC_Node_CompareFunc)ftc_cmap_node_compare, + (FTC_Node_DoneFunc) ftc_node_done + }; + + + /* documentation is in ftccmap.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ) + { + return FTC_Manager_Register_Cache( + manager, + (FTC_Cache_Class)&ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); + } + + +#ifdef FTC_CACHE_USE_INLINE + +#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ + ftc_cmap_family_compare( (FTC_CMapFamily)(f), (FTC_CMapQuery)(q) ) + +#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ + ftc_cmap_node_compare( (FTC_CMapNode)(n), (FTC_CMapQuery)(q) ) + +#define GEN_CACHE_LOOKUP ftc_cmap_cache_lookup + +#include "ftccache.i" + +#else /* !FTC_CACHE_USE_INLINE */ + +#define ftc_cmap_cache_lookup ftc_cache_lookup + +#endif /* !FTC_CACHE_USE_INLINE */ + + + /* documentation is in ftccmap.h */ + + FT_EXPORT_DEF( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_CMapDesc desc, + FT_UInt32 char_code ) + { + FTC_CMapQueryRec cquery; + FTC_CMapNode node; + FT_Error error; + FT_UInt gindex = 0; + + + if ( !cache || !desc ) + { + FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); + return 0; + } + + cquery.desc = desc; + cquery.char_code = char_code; + + error = ftc_cmap_cache_lookup( FTC_CACHE( cache ), + FTC_QUERY( &cquery ), + (FTC_Node*)&node ); + if ( !error ) + { + FT_UInt offset = (FT_UInt)( char_code - node->first ); + + + FT_ASSERT( offset < FTC_CMAP_INDICES_MAX ); + + gindex = node->indices[offset]; + if ( gindex == FTC_CMAP_UNKNOWN ) + { + FT_Face face; + + + /* we need to use FT_Get_Char_Index */ + gindex = 0; + + error = FTC_Manager_Lookup_Face( FTC_CACHE(cache)->manager, + desc->face_id, + &face ); + if ( !error ) + { + FT_CharMap old, cmap = NULL; + FT_UInt cmap_index; + + + /* save old charmap, select new one */ + old = face->charmap; + cmap_index = FTC_CMAP_FAMILY( FTC_QUERY( &cquery )->family )->index; + cmap = face->charmaps[cmap_index]; + + FT_Set_Charmap( face, cmap ); + + /* perform lookup */ + gindex = FT_Get_Char_Index( face, char_code ); + node->indices[offset] = (FT_UInt16)gindex; + + /* restore old charmap */ + FT_Set_Charmap( face, old ); + } + } + } + + return gindex; + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftcerror.h b/lib/freetype/src/cache/ftcerror.h new file mode 100644 index 0000000..5998d42 --- /dev/null +++ b/lib/freetype/src/cache/ftcerror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ftcerror.h */ +/* */ +/* Caching sub-system error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the caching sub-system error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTCERROR_H__ +#define __FTCERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX FTC_Err_ +#define FT_ERR_BASE FT_Mod_Err_Cache + +#include FT_ERRORS_H + +#endif /* __FTCERROR_H__ */ + +/* END */ diff --git a/lib/freetype/src/cache/ftcglyph.c b/lib/freetype/src/cache/ftcglyph.c new file mode 100644 index 0000000..aa21228 --- /dev/null +++ b/lib/freetype/src/cache/ftcglyph.c @@ -0,0 +1,115 @@ +/***************************************************************************/ +/* */ +/* ftcglyph.c */ +/* */ +/* FreeType Glyph Image (FT_Glyph) cache (body). */ +/* */ +/* Copyright 2000-2001 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 <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_ERRORS_H +#include FT_LIST_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + /* create a new chunk node, setting its cache index and ref count */ + FT_EXPORT_DEF( void ) + ftc_glyph_node_init( FTC_GlyphNode gnode, + FT_UInt gindex, + FTC_GlyphFamily gfam ) + { + FT_UInt len; + FT_UInt start = FTC_GLYPH_FAMILY_START( gfam, gindex ); + + + gnode->item_start = (FT_UShort)start; + + len = gfam->item_total - start; + if ( len > gfam->item_count ) + len = gfam->item_count; + + gnode->item_count = (FT_UShort)len; + gfam->family.num_nodes++; + } + + + FT_EXPORT_DEF( void ) + ftc_glyph_node_done( FTC_GlyphNode gnode, + FTC_Cache cache ) + { + /* finalize the node */ + gnode->item_count = 0; + gnode->item_start = 0; + + ftc_node_done( FTC_NODE( gnode ), cache ); + } + + + FT_EXPORT_DEF( FT_Bool ) + ftc_glyph_node_compare( FTC_GlyphNode gnode, + FTC_GlyphQuery gquery ) + { + FT_UInt start = (FT_UInt)gnode->item_start; + FT_UInt count = (FT_UInt)gnode->item_count; + + return FT_BOOL( (FT_UInt)( gquery->gindex - start ) < count ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHUNK SETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_EXPORT_DEF( FT_Error ) + ftc_glyph_family_init( FTC_GlyphFamily gfam, + FT_UInt32 hash, + FT_UInt item_count, + FT_UInt item_total, + FTC_GlyphQuery gquery, + FTC_Cache cache ) + { + FT_Error error; + + + error = ftc_family_init( FTC_FAMILY( gfam ), FTC_QUERY( gquery ), cache ); + if ( !error ) + { + gfam->hash = hash; + gfam->item_total = item_total; + gfam->item_count = item_count; + + FTC_GLYPH_FAMILY_FOUND( gfam, gquery ); + } + + return error; + } + + + FT_EXPORT_DEF( void ) + ftc_glyph_family_done( FTC_GlyphFamily gfam ) + { + ftc_family_done( FTC_FAMILY( gfam ) ); + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftcimage.c b/lib/freetype/src/cache/ftcimage.c new file mode 100644 index 0000000..fa1b6ac --- /dev/null +++ b/lib/freetype/src/cache/ftcimage.c @@ -0,0 +1,399 @@ +/***************************************************************************/ +/* */ +/* ftcimage.c */ +/* */ +/* FreeType Image cache (body). */ +/* */ +/* Copyright 2000-2001 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 <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_IMAGE_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_INTERNAL_MEMORY_H + +#include "ftcerror.h" + + + /* the FT_Glyph image node type */ + typedef struct FTC_ImageNodeRec_ + { + FTC_GlyphNodeRec gnode; + FT_Glyph glyph; + + } FTC_ImageNodeRec, *FTC_ImageNode; + + +#define FTC_IMAGE_NODE( x ) ( (FTC_ImageNode)( x ) ) +#define FTC_IMAGE_NODE_GINDEX( x ) FTC_GLYPH_NODE_GINDEX( x ) + + + /* the glyph image query */ + typedef struct FTC_ImageQueryRec_ + { + FTC_GlyphQueryRec gquery; + FTC_ImageTypeRec type; + + } FTC_ImageQueryRec, *FTC_ImageQuery; + + +#define FTC_IMAGE_QUERY( x ) ( (FTC_ImageQuery)( x ) ) + + + /* the glyph image set type */ + typedef struct FTC_ImageFamilyRec_ + { + FTC_GlyphFamilyRec gfam; + FTC_ImageTypeRec type; + + } FTC_ImageFamilyRec, *FTC_ImageFamily; + + +#define FTC_IMAGE_FAMILY( x ) ( (FTC_ImageFamily)( x ) ) +#define FTC_IMAGE_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &(x)->gfam ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* finalize a given glyph image node */ + FT_CALLBACK_DEF( void ) + ftc_image_node_done( FTC_ImageNode inode, + FTC_Cache cache ) + { + if ( inode->glyph ) + { + FT_Done_Glyph( inode->glyph ); + inode->glyph = NULL; + } + + ftc_glyph_node_done( FTC_GLYPH_NODE( inode ), cache ); + } + + + /* initialize a new glyph image node */ + FT_CALLBACK_DEF( FT_Error ) + ftc_image_node_init( FTC_ImageNode inode, + FTC_GlyphQuery gquery, + FTC_Cache cache ) + { + FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); + FT_Error error; + FT_Face face; + FT_Size size; + + + /* initialize its inner fields */ + ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), + gquery->gindex, + FTC_GLYPH_FAMILY( ifam ) ); + + /* we will now load the glyph image */ + error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager, + &ifam->type.font, + &face, &size ); + if ( !error ) + { + FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode ); + + + error = FT_Load_Glyph( face, gindex, ifam->type.flags ); + if ( !error ) + { + if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || + face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) + { + /* ok, copy it */ + FT_Glyph glyph; + + + error = FT_Get_Glyph( face->glyph, &glyph ); + if ( !error ) + { + inode->glyph = glyph; + goto Exit; + } + } + else + error = FTC_Err_Invalid_Argument; + } + } + + /* in case of error */ + ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); + + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_ULong ) + ftc_image_node_weight( FTC_ImageNode inode ) + { + FT_ULong size = 0; + FT_Glyph glyph = inode->glyph; + + + switch ( glyph->format ) + { + case FT_GLYPH_FORMAT_BITMAP: + { + FT_BitmapGlyph bitg; + + + bitg = (FT_BitmapGlyph)glyph; + size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) + + sizeof ( *bitg ); + } + break; + + case FT_GLYPH_FORMAT_OUTLINE: + { + FT_OutlineGlyph outg; + + + outg = (FT_OutlineGlyph)glyph; + size = outg->outline.n_points * + ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + + outg->outline.n_contours * sizeof ( FT_Short ) + + sizeof ( *outg ); + } + break; + + default: + ; + } + + size += sizeof ( *inode ); + return size; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE SETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + ftc_image_family_init( FTC_ImageFamily ifam, + FTC_ImageQuery iquery, + FTC_Cache cache ) + { + FTC_Manager manager = cache->manager; + FT_Error error; + FT_Face face; + + + ifam->type = iquery->type; + + /* we need to compute "iquery.item_total" now */ + error = FTC_Manager_Lookup_Face( manager, + iquery->type.font.face_id, + &face ); + if ( !error ) + { + error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ), + FTC_IMAGE_TYPE_HASH( &ifam->type ), + 1, + face->num_glyphs, + FTC_GLYPH_QUERY( iquery ), + cache ); + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_image_family_compare( FTC_ImageFamily ifam, + FTC_ImageQuery iquery ) + { + FT_Bool result; + + + result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) ); + if ( result ) + FTC_GLYPH_FAMILY_FOUND( ifam, iquery ); + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + + FT_CALLBACK_TABLE_DEF + const FTC_Cache_ClassRec ftc_image_cache_class = + { + sizeof ( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_ClearFunc)ftc_cache_clear, + (FTC_Cache_DoneFunc) ftc_cache_done, + + sizeof ( FTC_ImageFamilyRec ), + (FTC_Family_InitFunc) ftc_image_family_init, + (FTC_Family_CompareFunc)ftc_image_family_compare, + (FTC_Family_DoneFunc) ftc_glyph_family_done, + + sizeof ( FTC_ImageNodeRec ), + (FTC_Node_InitFunc) ftc_image_node_init, + (FTC_Node_WeightFunc) ftc_image_node_weight, + (FTC_Node_CompareFunc)ftc_glyph_node_compare, + (FTC_Node_DoneFunc) ftc_image_node_done + }; + + + /* documentation is in ftcimage.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ) + { + return FTC_Manager_Register_Cache( + manager, + (FTC_Cache_Class)&ftc_image_cache_class, + FTC_CACHE_P( acache ) ); + } + + + /* documentation is in ftcimage.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ) + { + FTC_ImageQueryRec iquery; + FTC_ImageNode node; + FT_Error error; + + + /* some argument checks are delayed to ftc_cache_lookup */ + if ( !aglyph ) + return FTC_Err_Invalid_Argument; + + if ( anode ) + *anode = NULL; + + iquery.gquery.gindex = gindex; + iquery.type = *type; + + error = ftc_cache_lookup( FTC_CACHE( cache ), + FTC_QUERY( &iquery ), + (FTC_Node*)&node ); + if ( !error ) + { + *aglyph = node->glyph; + + if ( anode ) + { + *anode = (FTC_Node)node; + FTC_NODE( node )->ref_count++; + } + } + + return error; + } + + + /* backwards-compatibility functions */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Image_Cache_New( FTC_Manager manager, + FTC_Image_Cache *acache ) + { + return FTC_ImageCache_New( manager, (FTC_ImageCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_Image_Cache_Lookup( FTC_Image_Cache icache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FT_Glyph *aglyph ) + { + FTC_ImageTypeRec type0; + + + if ( !desc ) + return FTC_Err_Invalid_Argument; + + type0.font = desc->font; + + /* convert image type flags to load flags */ + { + FT_UInt load_flags = FT_LOAD_DEFAULT; + FT_UInt type = desc->image_type; + + + /* determine load flags, depending on the font description's */ + /* image type */ + + if ( ftc_image_format( type ) == ftc_image_format_bitmap ) + { + if ( type & ftc_image_flag_monochrome ) + load_flags |= FT_LOAD_MONOCHROME; + + /* disable embedded bitmaps loading if necessary */ + if ( type & ftc_image_flag_no_sbits ) + load_flags |= FT_LOAD_NO_BITMAP; + } + else + { + /* we want an outline, don't load embedded bitmaps */ + load_flags |= FT_LOAD_NO_BITMAP; + + if ( type & ftc_image_flag_unscaled ) + load_flags |= FT_LOAD_NO_SCALE; + } + + /* always render glyphs to bitmaps */ + load_flags |= FT_LOAD_RENDER; + + if ( type & ftc_image_flag_unhinted ) + load_flags |= FT_LOAD_NO_HINTING; + + if ( type & ftc_image_flag_autohinted ) + load_flags |= FT_LOAD_FORCE_AUTOHINT; + + type0.flags = load_flags; + } + + return FTC_ImageCache_Lookup( (FTC_ImageCache)icache, + &type0, + gindex, + aglyph, + NULL ); + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftcmanag.c b/lib/freetype/src/cache/ftcmanag.c new file mode 100644 index 0000000..7cdb8f9 --- /dev/null +++ b/lib/freetype/src/cache/ftcmanag.c @@ -0,0 +1,765 @@ +/***************************************************************************/ +/* */ +/* ftcmanag.c */ +/* */ +/* FreeType Cache Manager (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_MANAGER_H +#include FT_CACHE_INTERNAL_LRU_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_SIZES_H + +#include "ftcerror.h" + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + +#define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE LRU IMPLEMENTATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct FTC_FaceNodeRec_* FTC_FaceNode; + typedef struct FTC_SizeNodeRec_* FTC_SizeNode; + + + typedef struct FTC_FaceNodeRec_ + { + FT_LruNodeRec lru; + FT_Face face; + + } FTC_FaceNodeRec; + + + typedef struct FTC_SizeNodeRec_ + { + FT_LruNodeRec lru; + FT_Size size; + + } FTC_SizeNodeRec; + + + FT_CALLBACK_DEF( FT_Error ) + ftc_face_node_init( FTC_FaceNode node, + FTC_FaceID face_id, + FTC_Manager manager ) + { + FT_Error error; + + + error = manager->request_face( face_id, + manager->library, + manager->request_data, + &node->face ); + if ( !error ) + { + /* destroy initial size object; it will be re-created later */ + if ( node->face->size ) + FT_Done_Size( node->face->size ); + } + + return error; + } + + + /* helper function for ftc_face_node_done() */ + FT_CALLBACK_DEF( FT_Bool ) + ftc_size_node_select( FTC_SizeNode node, + FT_Face face ) + { + return FT_BOOL( node->size->face == face ); + } + + + FT_CALLBACK_DEF( void ) + ftc_face_node_done( FTC_FaceNode node, + FTC_Manager manager ) + { + FT_Face face = node->face; + + + /* we must begin by removing all sizes for the target face */ + /* from the manager's list */ + FT_LruList_Remove_Selection( manager->sizes_list, + (FT_LruNode_SelectFunc)ftc_size_node_select, + face ); + + /* all right, we can discard the face now */ + FT_Done_Face( face ); + node->face = NULL; + } + + + FT_CALLBACK_TABLE_DEF + const FT_LruList_ClassRec ftc_face_list_class = + { + sizeof ( FT_LruListRec ), + (FT_LruList_InitFunc)0, + (FT_LruList_DoneFunc)0, + + sizeof ( FTC_FaceNodeRec ), + (FT_LruNode_InitFunc) ftc_face_node_init, + (FT_LruNode_DoneFunc) ftc_face_node_done, + (FT_LruNode_FlushFunc) 0, /* no flushing needed */ + (FT_LruNode_CompareFunc)0, /* direct comparison of FTC_FaceID handles */ + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ) + { + FT_Error error; + FTC_FaceNode node; + + + if ( aface == NULL ) + return FTC_Err_Bad_Argument; + + *aface = NULL; + + if ( !manager ) + return FTC_Err_Invalid_Cache_Handle; + + error = FT_LruList_Lookup( manager->faces_list, + (FT_LruKey)face_id, + (FT_LruNode*)&node ); + if ( !error ) + *aface = node->face; + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SIZES LRU IMPLEMENTATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct FTC_SizeQueryRec_ + { + FT_Face face; + FT_UInt width; + FT_UInt height; + + } FTC_SizeQueryRec, *FTC_SizeQuery; + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_init( FTC_SizeNode node, + FTC_SizeQuery query ) + { + FT_Face face = query->face; + FT_Size size; + FT_Error error; + + + node->size = NULL; + error = FT_New_Size( face, &size ); + if ( !error ) + { + FT_Activate_Size( size ); + error = FT_Set_Pixel_Sizes( query->face, + query->width, + query->height ); + if ( error ) + FT_Done_Size( size ); + else + node->size = size; + } + return error; + } + + + FT_CALLBACK_DEF( void ) + ftc_size_node_done( FTC_SizeNode node ) + { + if ( node->size ) + { + FT_Done_Size( node->size ); + node->size = NULL; + } + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_size_node_flush( FTC_SizeNode node, + FTC_SizeQuery query ) + { + FT_Size size = node->size; + FT_Error error; + + + if ( size->face == query->face ) + { + FT_Activate_Size( size ); + error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); + if ( error ) + { + FT_Done_Size( size ); + node->size = NULL; + } + } + else + { + FT_Done_Size( size ); + node->size = NULL; + + error = ftc_size_node_init( node, query ); + } + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_size_node_compare( FTC_SizeNode node, + FTC_SizeQuery query ) + { + FT_Size size = node->size; + + + return FT_BOOL( size->face == query->face && + (FT_UInt)size->metrics.x_ppem == query->width && + (FT_UInt)size->metrics.y_ppem == query->height ); + } + + + FT_CALLBACK_TABLE_DEF + const FT_LruList_ClassRec ftc_size_list_class = + { + sizeof ( FT_LruListRec ), + (FT_LruList_InitFunc)0, + (FT_LruList_DoneFunc)0, + + sizeof ( FTC_SizeNodeRec ), + (FT_LruNode_InitFunc) ftc_size_node_init, + (FT_LruNode_DoneFunc) ftc_size_node_done, + (FT_LruNode_FlushFunc) ftc_size_node_flush, + (FT_LruNode_CompareFunc)ftc_size_node_compare + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ) + { + FT_Error error; + + + /* check for valid `manager' delayed to FTC_Manager_Lookup_Face() */ + if ( aface ) + *aface = 0; + + if ( asize ) + *asize = 0; + + error = FTC_Manager_Lookup_Face( manager, font->face_id, aface ); + if ( !error ) + { + FTC_SizeQueryRec query; + FTC_SizeNode node; + + + query.face = *aface; + query.width = font->pix_width; + query.height = font->pix_height; + + error = FT_LruList_Lookup( manager->sizes_list, + (FT_LruKey)&query, + (FT_LruNode*)&node ); + if ( !error ) + { + /* select the size as the current one for this face */ + FT_Activate_Size( node->size ); + + if ( asize ) + *asize = node->size; + } + } + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SET TABLE MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + ftc_family_table_init( FTC_FamilyTable table ) + { + table->count = 0; + table->size = 0; + table->entries = NULL; + table->free = FTC_FAMILY_ENTRY_NONE; + } + + + static void + ftc_family_table_done( FTC_FamilyTable table, + FT_Memory memory ) + { + FT_FREE( table->entries ); + table->free = 0; + table->count = 0; + table->size = 0; + } + + + FT_EXPORT_DEF( FT_Error ) + ftc_family_table_alloc( FTC_FamilyTable table, + FT_Memory memory, + FTC_FamilyEntry *aentry ) + { + FTC_FamilyEntry entry; + FT_Error error = 0; + + + /* re-allocate table size when needed */ + if ( table->free == FTC_FAMILY_ENTRY_NONE && table->count >= table->size ) + { + FT_UInt old_size = table->size; + FT_UInt new_size, idx; + + + if ( old_size == 0 ) + new_size = 8; + else + { + new_size = old_size * 2; + + /* check for (unlikely) overflow */ + if ( new_size < old_size ) + new_size = 65534; + } + + if ( FT_RENEW_ARRAY( table->entries, old_size, new_size ) ) + return error; + + table->size = new_size; + + entry = table->entries + old_size; + table->free = old_size; + + for ( idx = old_size; idx + 1 < new_size; idx++, entry++ ) + { + entry->link = idx + 1; + entry->index = idx; + } + + entry->link = FTC_FAMILY_ENTRY_NONE; + entry->index = idx; + } + + if ( table->free != FTC_FAMILY_ENTRY_NONE ) + { + entry = table->entries + table->free; + table->free = entry->link; + } + else if ( table->count < table->size ) + { + entry = table->entries + table->count++; + } + else + { + FT_ERROR(( "ftc_family_table_alloc: internal bug!" )); + return FTC_Err_Invalid_Argument; + } + + entry->link = FTC_FAMILY_ENTRY_NONE; + table->count++; + + *aentry = entry; + return error; + } + + + FT_EXPORT_DEF( void ) + ftc_family_table_free( FTC_FamilyTable table, + FT_UInt idx ) + { + /* simply add it to the linked list of free entries */ + if ( idx < table->count ) + { + FTC_FamilyEntry entry = table->entries + idx; + + + if ( entry->link != FTC_FAMILY_ENTRY_NONE ) + FT_ERROR(( "ftc_family_table_free: internal bug!\n" )); + else + { + entry->link = table->free; + table->free = entry->index; + table->count--; + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ) + { + FT_Error error; + FT_Memory memory; + FTC_Manager manager = 0; + + + if ( !library ) + return FTC_Err_Invalid_Library_Handle; + + memory = library->memory; + + if ( FT_NEW( manager ) ) + goto Exit; + + if ( max_faces == 0 ) + max_faces = FTC_MAX_FACES_DEFAULT; + + if ( max_sizes == 0 ) + max_sizes = FTC_MAX_SIZES_DEFAULT; + + if ( max_bytes == 0 ) + max_bytes = FTC_MAX_BYTES_DEFAULT; + + error = FT_LruList_New( &ftc_face_list_class, + max_faces, + manager, + memory, + &manager->faces_list ); + if ( error ) + goto Exit; + + error = FT_LruList_New( &ftc_size_list_class, + max_sizes, + manager, + memory, + &manager->sizes_list ); + if ( error ) + goto Exit; + + manager->library = library; + manager->max_weight = max_bytes; + manager->cur_weight = 0; + + manager->request_face = requester; + manager->request_data = req_data; + + ftc_family_table_init( &manager->families ); + + *amanager = manager; + + Exit: + if ( error && manager ) + { + FT_LruList_Destroy( manager->faces_list ); + FT_LruList_Destroy( manager->sizes_list ); + FT_FREE( manager ); + } + + return error; + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Done( FTC_Manager manager ) + { + FT_Memory memory; + FT_UInt idx; + + + if ( !manager || !manager->library ) + return; + + memory = manager->library->memory; + + /* now discard all caches */ + for (idx = 0; idx < FTC_MAX_CACHES; idx++ ) + { + FTC_Cache cache = manager->caches[idx]; + + + if ( cache ) + { + cache->clazz->cache_done( cache ); + FT_FREE( cache ); + manager->caches[idx] = 0; + } + } + + /* discard families table */ + ftc_family_table_done( &manager->families, memory ); + + /* discard faces and sizes */ + FT_LruList_Destroy( manager->faces_list ); + manager->faces_list = 0; + + FT_LruList_Destroy( manager->sizes_list ); + manager->sizes_list = 0; + + FT_FREE( manager ); + } + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Reset( FTC_Manager manager ) + { + if ( manager ) + { + FT_LruList_Reset( manager->sizes_list ); + FT_LruList_Reset( manager->faces_list ); + } + /* XXX: FIXME: flush the caches? */ + } + + +#ifdef FT_DEBUG_ERROR + + FT_EXPORT_DEF( void ) + FTC_Manager_Check( FTC_Manager manager ) + { + FTC_Node node, first; + + + first = manager->nodes_list; + + /* check node weights */ + if ( first ) + { + FT_ULong weight = 0; + + + node = first; + + do + { + FTC_FamilyEntry entry = manager->families.entries + node->fam_index; + FTC_Cache cache; + + if ( (FT_UInt)node->fam_index >= manager->families.count || + entry->link != FTC_FAMILY_ENTRY_NONE ) + FT_ERROR(( "FTC_Manager_Check: invalid node (family index = %ld\n", + node->fam_index )); + else + { + cache = entry->cache; + weight += cache->clazz->node_weight( node, cache ); + } + + node = node->mru_next; + + } while ( node != first ); + + if ( weight != manager->cur_weight ) + FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", + manager->cur_weight, weight )); + } + + /* check circular list */ + if ( first ) + { + FT_UFast count = 0; + + + node = first; + do + { + count++; + node = node->mru_next; + + } while ( node != first ); + + if ( count != manager->num_nodes ) + FT_ERROR(( + "FTC_Manager_Check: invalid cache node count %d instead of %d\n", + manager->num_nodes, count )); + } + } + +#endif /* FT_DEBUG_ERROR */ + + + /* `Compress' the manager's data, i.e., get rid of old cache nodes */ + /* that are not referenced anymore in order to limit the total */ + /* memory used by the cache. */ + + /* documentation is in ftcmanag.h */ + + FT_EXPORT_DEF( void ) + FTC_Manager_Compress( FTC_Manager manager ) + { + FTC_Node node, first; + + + if ( !manager ) + return; + + first = manager->nodes_list; + +#ifdef FT_DEBUG_ERROR + FTC_Manager_Check( manager ); + + FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n", + manager->cur_weight, manager->max_weight, + manager->num_nodes )); +#endif + + if ( manager->cur_weight < manager->max_weight || first == NULL ) + return; + + /* go to last node - it's a circular list */ + node = first->mru_prev; + do + { + FTC_Node prev = node->mru_prev; + + + prev = ( node == first ) ? NULL : node->mru_prev; + + if ( node->ref_count <= 0 ) + ftc_node_destroy( node, manager ); + + node = prev; + + } while ( node && manager->cur_weight > manager->max_weight ); + } + + + /* documentation is in ftcmanag.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_Manager_Register_Cache( FTC_Manager manager, + FTC_Cache_Class clazz, + FTC_Cache *acache ) + { + FT_Error error = FTC_Err_Invalid_Argument; + FTC_Cache cache = NULL; + + + if ( manager && clazz && acache ) + { + FT_Memory memory = manager->library->memory; + FT_UInt idx = 0; + + + /* check for an empty cache slot in the manager's table */ + for ( idx = 0; idx < FTC_MAX_CACHES; idx++ ) + { + if ( manager->caches[idx] == 0 ) + break; + } + + /* return an error if there are too many registered caches */ + if ( idx >= FTC_MAX_CACHES ) + { + error = FTC_Err_Too_Many_Caches; + FT_ERROR(( "FTC_Manager_Register_Cache:" )); + FT_ERROR(( " too many registered caches\n" )); + goto Exit; + } + + if ( !FT_ALLOC( cache, clazz->cache_size ) ) + { + cache->manager = manager; + cache->memory = memory; + cache->clazz = clazz; + + /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ + /* IF IT IS NOT SET CORRECTLY */ + cache->cache_index = idx; + + if ( clazz->cache_init ) + { + error = clazz->cache_init( cache ); + if ( error ) + { + if ( clazz->cache_done ) + clazz->cache_done( cache ); + + FT_FREE( cache ); + goto Exit; + } + } + + manager->caches[idx] = cache; + } + } + + Exit: + *acache = cache; + return error; + } + + + /* documentation is in ftcmanag.h */ + + FT_EXPORT_DEF( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ) + { + if ( node && (FT_UInt)node->fam_index < manager->families.count && + manager->families.entries[node->fam_index].cache ) + { + node->ref_count--; + } + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftcsbits.c b/lib/freetype/src/cache/ftcsbits.c new file mode 100644 index 0000000..5840382 --- /dev/null +++ b/lib/freetype/src/cache/ftcsbits.c @@ -0,0 +1,557 @@ +/***************************************************************************/ +/* */ +/* ftcsbits.c */ +/* */ +/* FreeType sbits manager (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_SMALL_BITMAPS_H +#include FT_CACHE_INTERNAL_GLYPH_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_ERRORS_H + +#include "ftcerror.h" + + +#define FTC_SBIT_ITEMS_PER_NODE 16 + + + typedef struct FTC_SBitNodeRec_* FTC_SBitNode; + + typedef struct FTC_SBitNodeRec_ + { + FTC_GlyphNodeRec gnode; + FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; + + } FTC_SBitNodeRec; + + +#define FTC_SBIT_NODE( x ) ( (FTC_SBitNode)( x ) ) + + + typedef struct FTC_SBitQueryRec_ + { + FTC_GlyphQueryRec gquery; + FTC_ImageTypeRec type; + + } FTC_SBitQueryRec, *FTC_SBitQuery; + + +#define FTC_SBIT_QUERY( x ) ( (FTC_SBitQuery)( x ) ) + + + typedef struct FTC_SBitFamilyRec_* FTC_SBitFamily; + + /* sbit family structure */ + typedef struct FTC_SBitFamilyRec_ + { + FTC_GlyphFamilyRec gfam; + FTC_ImageTypeRec type; + + } FTC_SBitFamilyRec; + + +#define FTC_SBIT_FAMILY( x ) ( (FTC_SBitFamily)( x ) ) +#define FTC_SBIT_FAMILY_MEMORY( x ) FTC_GLYPH_FAMILY_MEMORY( &( x )->cset ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SBIT CACHE NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + ftc_sbit_copy_bitmap( FTC_SBit sbit, + FT_Bitmap* bitmap, + FT_Memory memory ) + { + FT_Error error; + FT_Int pitch = bitmap->pitch; + FT_ULong size; + + + if ( pitch < 0 ) + pitch = -pitch; + + size = (FT_ULong)( pitch * bitmap->rows ); + + if ( !FT_ALLOC( sbit->buffer, size ) ) + FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); + + return error; + } + + + FT_CALLBACK_DEF( void ) + ftc_sbit_node_done( FTC_SBitNode snode, + FTC_Cache cache ) + { + FTC_SBit sbit = snode->sbits; + FT_UInt count = FTC_GLYPH_NODE( snode )->item_count; + FT_Memory memory = cache->memory; + + + for ( ; count > 0; sbit++, count-- ) + FT_FREE( sbit->buffer ); + + ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); + } + + + static FT_Error + ftc_sbit_node_load( FTC_SBitNode snode, + FTC_Manager manager, + FTC_SBitFamily sfam, + FT_UInt gindex, + FT_ULong *asize ) + { + FT_Error error; + FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); + FT_Memory memory; + FT_Face face; + FT_Size size; + FTC_SBit sbit; + + + if ( gindex < (FT_UInt)gnode->item_start || + gindex >= (FT_UInt)gnode->item_start + gnode->item_count ) + { + FT_ERROR(( "ftc_sbit_node_load: invalid glyph index" )); + return FTC_Err_Invalid_Argument; + } + + memory = manager->library->memory; + + sbit = snode->sbits + ( gindex - gnode->item_start ); + + error = FTC_Manager_Lookup_Size( manager, &sfam->type.font, + &face, &size ); + if ( !error ) + { + /* by default, indicates a `missing' glyph */ + sbit->buffer = 0; + + error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER ); + if ( !error ) + { + FT_Int temp; + FT_GlyphSlot slot = face->glyph; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Int xadvance, yadvance; + + + /* check that our values fit into 8-bit containers! */ + /* If this is not the case, our bitmap is too large */ + /* and we will leave it as `missing' with sbit.buffer = 0 */ + +#define CHECK_CHAR( d ) ( temp = (FT_Char)d, temp == d ) +#define CHECK_BYTE( d ) ( temp = (FT_Byte)d, temp == d ) + + /* XXX: FIXME: add support for vertical layouts maybe */ + + /* horizontal advance in pixels */ + xadvance = ( slot->metrics.horiAdvance + 32 ) >> 6; + yadvance = ( slot->metrics.vertAdvance + 32 ) >> 6; + + if ( CHECK_BYTE( bitmap->rows ) && + CHECK_BYTE( bitmap->width ) && + CHECK_CHAR( bitmap->pitch ) && + CHECK_CHAR( slot->bitmap_left ) && + CHECK_CHAR( slot->bitmap_top ) && + CHECK_CHAR( xadvance ) && + CHECK_CHAR( yadvance ) ) + { + sbit->width = (FT_Byte)bitmap->width; + sbit->height = (FT_Byte)bitmap->rows; + sbit->pitch = (FT_Char)bitmap->pitch; + sbit->left = (FT_Char)slot->bitmap_left; + sbit->top = (FT_Char)slot->bitmap_top; + sbit->xadvance = (FT_Char)xadvance; + sbit->yadvance = (FT_Char)yadvance; + sbit->format = (FT_Byte)bitmap->pixel_mode; + sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); + +#if 0 /* this doesn't work well with embedded bitmaps !! */ + + /* grab the bitmap when possible - this is a hack! */ + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + { + slot->flags &= ~FT_GLYPH_OWN_BITMAP; + sbit->buffer = bitmap->buffer; + } + else +#endif + { + /* copy the bitmap into a new buffer -- ignore error */ + error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); + } + + /* now, compute size */ + if ( asize ) + *asize = ABS( sbit->pitch ) * sbit->height; + + } /* glyph dimensions ok */ + + } /* glyph loading successful */ + + /* ignore the errors that might have occurred -- */ + /* we mark unloaded glyphs with `sbit.buffer == 0' */ + /* and 'width == 255', 'height == 0' */ + /* */ + if ( error && error != FT_Err_Out_Of_Memory ) + { + sbit->width = 255; + error = 0; + /* sbit->buffer == NULL too! */ + } + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + ftc_sbit_node_init( FTC_SBitNode snode, + FTC_GlyphQuery gquery, + FTC_Cache cache ) + { + FT_Error error; + + + ftc_glyph_node_init( FTC_GLYPH_NODE( snode ), + gquery->gindex, + FTC_GLYPH_FAMILY( gquery->query.family ) ); + + error = ftc_sbit_node_load( snode, + cache->manager, + FTC_SBIT_FAMILY( FTC_QUERY( gquery )->family ), + gquery->gindex, + NULL ); + if ( error ) + ftc_glyph_node_done( FTC_GLYPH_NODE( snode ), cache ); + + return error; + } + + + FT_CALLBACK_DEF( FT_ULong ) + ftc_sbit_node_weight( FTC_SBitNode snode ) + { + FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); + FT_UInt count = gnode->item_count; + FTC_SBit sbit = snode->sbits; + FT_Int pitch; + FT_ULong size; + + + /* the node itself */ + size = sizeof ( *snode ); + + /* the sbit records */ + size += FTC_GLYPH_NODE( snode )->item_count * sizeof ( FTC_SBitRec ); + + for ( ; count > 0; count--, sbit++ ) + { + if ( sbit->buffer ) + { + pitch = sbit->pitch; + if ( pitch < 0 ) + pitch = -pitch; + + /* add the size of a given glyph image */ + size += pitch * sbit->height; + } + } + + return size; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_sbit_node_compare( FTC_SBitNode snode, + FTC_SBitQuery squery, + FTC_Cache cache ) + { + FTC_GlyphQuery gquery = FTC_GLYPH_QUERY( squery ); + FTC_GlyphNode gnode = FTC_GLYPH_NODE( snode ); + FT_Bool result; + + + result = ftc_glyph_node_compare( gnode, gquery ); + if ( result ) + { + /* check if we need to load the glyph bitmap now */ + FT_UInt gindex = gquery->gindex; + FTC_SBit sbit = snode->sbits + ( gindex - gnode->item_start ); + + + if ( sbit->buffer == NULL && sbit->width != 255 ) + { + FT_ULong size; + + + /* yes, it's safe to ignore errors here */ + ftc_sbit_node_load( snode, + cache->manager, + FTC_SBIT_FAMILY( FTC_QUERY( squery )->family ), + gindex, + &size ); + + cache->manager->cur_weight += size; + } + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SBITS FAMILIES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + ftc_sbit_family_init( FTC_SBitFamily sfam, + FTC_SBitQuery squery, + FTC_Cache cache ) + { + FTC_Manager manager = cache->manager; + FT_Error error; + FT_Face face; + + + sfam->type = squery->type; + + /* we need to compute "cquery.item_total" now */ + error = FTC_Manager_Lookup_Face( manager, + squery->type.font.face_id, + &face ); + if ( !error ) + { + error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ), + FTC_IMAGE_TYPE_HASH( &sfam->type ), + FTC_SBIT_ITEMS_PER_NODE, + face->num_glyphs, + FTC_GLYPH_QUERY( squery ), + cache ); + } + + return error; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_sbit_family_compare( FTC_SBitFamily sfam, + FTC_SBitQuery squery ) + { + FT_Bool result; + + + /* we need to set the "cquery.cset" field or our query for */ + /* faster glyph comparisons in ftc_sbit_node_compare */ + /* */ + result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) ); + if ( result ) + FTC_GLYPH_FAMILY_FOUND( sfam, squery ); + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SBITS CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE_DEF + const FTC_Cache_ClassRec ftc_sbit_cache_class = + { + sizeof ( FTC_CacheRec ), + (FTC_Cache_InitFunc) ftc_cache_init, + (FTC_Cache_ClearFunc)ftc_cache_clear, + (FTC_Cache_DoneFunc) ftc_cache_done, + + sizeof ( FTC_SBitFamilyRec ), + (FTC_Family_InitFunc) ftc_sbit_family_init, + (FTC_Family_CompareFunc)ftc_sbit_family_compare, + (FTC_Family_DoneFunc) ftc_glyph_family_done, + + sizeof ( FTC_SBitNodeRec ), + (FTC_Node_InitFunc) ftc_sbit_node_init, + (FTC_Node_WeightFunc) ftc_sbit_node_weight, + (FTC_Node_CompareFunc)ftc_sbit_node_compare, + (FTC_Node_DoneFunc) ftc_sbit_node_done + }; + + + /* documentation is in ftcsbits.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ) + { + return FTC_Manager_Register_Cache( manager, + &ftc_sbit_cache_class, + (FTC_Cache*)acache ); + } + + + /* documentation is in ftcsbits.h */ + +#ifdef FTC_CACHE_USE_INLINE + +#define GEN_CACHE_FAMILY_COMPARE( f, q, c ) \ + ftc_sbit_family_compare( (FTC_SBitFamily)(f), (FTC_SBitQuery)(q) ) + +#define GEN_CACHE_NODE_COMPARE( n, q, c ) \ + ftc_sbit_node_compare( (FTC_SBitNode)(n), (FTC_SBitQuery)(q), c ) + +#define GEN_CACHE_LOOKUP ftc_sbit_cache_lookup +#include "ftccache.i" + +#else /* !FTC_CACHE_USE_INLINE */ + +#define ftc_sbit_cache_lookup ftc_cache_lookup + +#endif /* !FTC_CACHE_USE_INLINE */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *ansbit, + FTC_Node *anode ) + { + FT_Error error; + FTC_SBitQueryRec squery; + FTC_SBitNode node; + + + /* other argument checks delayed to ftc_cache_lookup */ + if ( !ansbit ) + return FTC_Err_Invalid_Argument; + + *ansbit = NULL; + + if ( anode ) + *anode = NULL; + + squery.gquery.gindex = gindex; + squery.type = *type; + + error = ftc_sbit_cache_lookup( FTC_CACHE( cache ), + FTC_QUERY( &squery ), + (FTC_Node*)&node ); + if ( !error ) + { + *ansbit = node->sbits + ( gindex - FTC_GLYPH_NODE( node )->item_start ); + + if ( anode ) + { + *anode = FTC_NODE( node ); + FTC_NODE( node )->ref_count++; + } + } + return error; + } + + + /* backwards-compatibility functions */ + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_New( FTC_Manager manager, + FTC_SBit_Cache *acache ) + { + return FTC_SBitCache_New( manager, (FTC_SBitCache*)acache ); + } + + + FT_EXPORT_DEF( FT_Error ) + FTC_SBit_Cache_Lookup( FTC_SBit_Cache cache, + FTC_Image_Desc* desc, + FT_UInt gindex, + FTC_SBit *ansbit ) + { + FTC_ImageTypeRec type0; + + + if ( !desc ) + return FTC_Err_Invalid_Argument; + + type0.font = desc->font; + type0.flags = 0; + + /* convert image type flags to load flags */ + { + FT_UInt load_flags = FT_LOAD_DEFAULT; + FT_UInt type = desc->image_type; + + + /* determine load flags, depending on the font description's */ + /* image type */ + + if ( ftc_image_format( type ) == ftc_image_format_bitmap ) + { + if ( type & ftc_image_flag_monochrome ) + load_flags |= FT_LOAD_MONOCHROME; + + /* disable embedded bitmaps loading if necessary */ + if ( type & ftc_image_flag_no_sbits ) + load_flags |= FT_LOAD_NO_BITMAP; + } + else + { + /* we want an outline, don't load embedded bitmaps */ + load_flags |= FT_LOAD_NO_BITMAP; + + if ( type & ftc_image_flag_unscaled ) + load_flags |= FT_LOAD_NO_SCALE; + } + + /* always render glyphs to bitmaps */ + load_flags |= FT_LOAD_RENDER; + + if ( type & ftc_image_flag_unhinted ) + load_flags |= FT_LOAD_NO_HINTING; + + if ( type & ftc_image_flag_autohinted ) + load_flags |= FT_LOAD_FORCE_AUTOHINT; + + type0.flags = load_flags; + } + + return FTC_SBitCache_Lookup( (FTC_SBitCache)cache, + &type0, + gindex, + ansbit, + NULL ); + } + + +/* END */ diff --git a/lib/freetype/src/cache/ftlru.c b/lib/freetype/src/cache/ftlru.c new file mode 100644 index 0000000..4eab0d9 --- /dev/null +++ b/lib/freetype/src/cache/ftlru.c @@ -0,0 +1,394 @@ +/***************************************************************************/ +/* */ +/* ftlru.c */ +/* */ +/* Simple LRU list-cache (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_CACHE_H +#include FT_CACHE_INTERNAL_LRU_H +#include FT_LIST_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H + +#include "ftcerror.h" + + + FT_EXPORT_DEF( FT_Error ) + FT_LruList_New( FT_LruList_Class clazz, + FT_UInt max_nodes, + FT_Pointer user_data, + FT_Memory memory, + FT_LruList *alist ) + { + FT_Error error; + FT_LruList list; + + + if ( !alist || !clazz ) + return FTC_Err_Invalid_Argument; + + *alist = NULL; + if ( !FT_ALLOC( list, clazz->list_size ) ) + { + /* initialize common fields */ + list->clazz = clazz; + list->memory = memory; + list->max_nodes = max_nodes; + list->data = user_data; + + if ( clazz->list_init ) + { + error = clazz->list_init( list ); + if ( error ) + { + if ( clazz->list_done ) + clazz->list_done( list ); + + FT_FREE( list ); + } + } + + *alist = list; + } + + return error; + } + + + FT_EXPORT_DEF( void ) + FT_LruList_Destroy( FT_LruList list ) + { + FT_Memory memory; + FT_LruList_Class clazz; + + + if ( !list ) + return; + + memory = list->memory; + clazz = list->clazz; + + FT_LruList_Reset( list ); + + if ( clazz->list_done ) + clazz->list_done( list ); + + FT_FREE( list ); + } + + + FT_EXPORT_DEF( void ) + FT_LruList_Reset( FT_LruList list ) + { + FT_LruNode node; + FT_LruList_Class clazz; + FT_Memory memory; + + + if ( !list ) + return; + + node = list->nodes; + clazz = list->clazz; + memory = list->memory; + + while ( node ) + { + FT_LruNode next = node->next; + + + if ( clazz->node_done ) + clazz->node_done( node, list->data ); + + FT_FREE( node ); + node = next; + } + + list->nodes = NULL; + list->num_nodes = 0; + } + + + FT_EXPORT_DEF( FT_Error ) + FT_LruList_Lookup( FT_LruList list, + FT_LruKey key, + FT_LruNode *anode ) + { + FT_Error error = 0; + FT_LruNode node, *pnode; + FT_LruList_Class clazz; + FT_LruNode* plast; + FT_LruNode result = NULL; + FT_Memory memory; + + + if ( !list || !key || !anode ) + return FTC_Err_Invalid_Argument; + + pnode = &list->nodes; + plast = pnode; + node = NULL; + clazz = list->clazz; + memory = list->memory; + + if ( clazz->node_compare ) + { + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( clazz->node_compare( node, key, list->data ) ) + break; + + plast = pnode; + pnode = &(*pnode)->next; + } + } + else + { + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( node->key == key ) + break; + + plast = pnode; + pnode = &(*pnode)->next; + } + } + + if ( node ) + { + /* move element to top of list */ + if ( list->nodes != node ) + { + *pnode = node->next; + node->next = list->nodes; + list->nodes = node; + } + result = node; + goto Exit; + } + + /* since we haven't found the relevant element in our LRU list, + * we're going to "create" a new one. + * + * the following code is a bit special, because it tries to handle + * out-of-memory conditions (OOM) in an intelligent way. + * + * more precisely, if not enough memory is available to create a + * new node or "flush" an old one, we need to remove the oldest + * elements from our list, and try again. since several tries may + * be necessary, a loop is needed + * + * this loop will only exit when: + * + * - a new node was succesfully created, or an old node flushed + * - an error other than FT_Err_Out_Of_Memory is detected + * - the list of nodes is empty, and it isn't possible to create + * new nodes + * + * on each unsucesful attempt, one node will be removed from the list + * + */ + + { + FT_Int drop_last = ( list->max_nodes > 0 && + list->num_nodes >= list->max_nodes ); + + for (;;) + { + node = NULL; + + /* when "drop_last" is true, we should free the last node in + * the list to make room for a new one. note that we re-use + * its memory block to save allocation calls. + */ + if ( drop_last ) + { + /* find the last node in the list + */ + pnode = &list->nodes; + node = *pnode; + + if ( node == NULL ) + { + FT_ASSERT( list->nodes == 0 ); + error = FT_Err_Out_Of_Memory; + goto Exit; + } + + FT_ASSERT( list->num_nodes > 0 ); + + while ( node->next ) + { + pnode = &node->next; + node = *pnode; + } + + /* remove it from the list, and try to "flush" it. doing this will + * save a significant number of dynamic allocations compared to + * a classic destroy/create cycle + */ + *pnode = NULL; + list->num_nodes -= 1; + + if ( clazz->node_flush ) + { + error = clazz->node_flush( node, key, list->data ); + if ( !error ) + goto Success; + + /* note that if an error occured during the flush, we need to + * finalize it since it is potentially in incomplete state. + */ + } + + /* we finalize, but do not destroy the last node, we + * simply re-use its memory block ! + */ + if ( clazz->node_done ) + clazz->node_done( node, list->data ); + + FT_MEM_ZERO( node, clazz->node_size ); + } + else + { + /* try to allocate a new node when "drop_last" is not TRUE + * this usually happens on the first pass, when the LRU list + * is not already full. + */ + if ( FT_ALLOC( node, clazz->node_size ) ) + goto Fail; + } + + FT_ASSERT( node != NULL ); + + node->key = key; + error = clazz->node_init( node, key, list->data ); + if ( error ) + { + if ( clazz->node_done ) + clazz->node_done( node, list->data ); + + FT_FREE( node ); + goto Fail; + } + + Success: + result = node; + + node->next = list->nodes; + list->nodes = node; + list->num_nodes++; + goto Exit; + + Fail: + if ( error != FT_Err_Out_Of_Memory ) + goto Exit; + + drop_last = 1; + continue; + } + } + + Exit: + *anode = result; + return error; + } + + + + FT_EXPORT_DEF( void ) + FT_LruList_Remove( FT_LruList list, + FT_LruNode node ) + { + FT_LruNode *pnode; + + + if ( !list || !node ) + return; + + pnode = &list->nodes; + for (;;) + { + if ( *pnode == node ) + { + FT_Memory memory = list->memory; + FT_LruList_Class clazz = list->clazz; + + + *pnode = node->next; + node->next = NULL; + + if ( clazz->node_done ) + clazz->node_done( node, list->data ); + + FT_FREE( node ); + list->num_nodes--; + break; + } + + pnode = &(*pnode)->next; + } + } + + + FT_EXPORT_DEF( void ) + FT_LruList_Remove_Selection( FT_LruList list, + FT_LruNode_SelectFunc select_func, + FT_Pointer select_data ) + { + FT_LruNode *pnode, node; + FT_LruList_Class clazz; + FT_Memory memory; + + + if ( !list || !select_func ) + return; + + memory = list->memory; + clazz = list->clazz; + pnode = &list->nodes; + + for (;;) + { + node = *pnode; + if ( node == NULL ) + break; + + if ( select_func( node, select_data, list->data ) ) + { + *pnode = node->next; + node->next = NULL; + + if ( clazz->node_done ) + clazz->node_done( node, list ); + + FT_FREE( node ); + } + else + pnode = &(*pnode)->next; + } + } + + +/* END */ diff --git a/lib/freetype/src/cache/rules.mk b/lib/freetype/src/cache/rules.mk new file mode 100644 index 0000000..a74e780 --- /dev/null +++ b/lib/freetype/src/cache/rules.mk @@ -0,0 +1,80 @@ +# +# FreeType 2 Cache configuration rules +# + + +# Copyright 2000, 2001 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. + + +# Cache driver directory +# +CACHE_DIR := $(SRC_)cache +CACHE_DIR_ := $(CACHE_DIR)$(SEP) + +CACHE_H_DIR := $(PUBLIC_)cache +CACHE_H_DIR_ := $(CACHE_H_DIR)$(SEP) + +# compilation flags for the driver +# +Cache_COMPILE := $(FT_COMPILE) $I$(CACHE_DIR) + + +# Cache driver sources (i.e., C files) +# +Cache_DRV_SRC := $(CACHE_DIR_)ftlru.c \ + $(CACHE_DIR_)ftcmanag.c \ + $(CACHE_DIR_)ftccache.c \ + $(CACHE_DIR_)ftcglyph.c \ + $(CACHE_DIR_)ftcsbits.c \ + $(CACHE_DIR_)ftcimage.c \ + $(CACHE_DIR_)ftccmap.c + +# Cache driver headers +# +Cache_DRV_H := $(CACHE_H_DIR_)ftlru.h \ + $(CACHE_H_DIR_)ftcmanag.h \ + $(CACHE_H_DIR_)ftcglyph.h \ + $(CACHE_H_DIR_)ftcimage.h \ + $(CACHE_DIR_)ftcerror.h + + +# Cache driver object(s) +# +# Cache_DRV_OBJ_M is used during `multi' builds. +# Cache_DRV_OBJ_S is used during `single' builds. +# +Cache_DRV_OBJ_M := $(Cache_DRV_SRC:$(CACHE_DIR_)%.c=$(OBJ_)%.$O) +Cache_DRV_OBJ_S := $(OBJ_)ftcache.$O + +# Cache driver source file for single build +# +Cache_DRV_SRC_S := $(CACHE_DIR_)ftcache.c + + +# Cache driver - single object +# +$(Cache_DRV_OBJ_S): $(Cache_DRV_SRC_S) $(Cache_DRV_SRC) \ + $(FREETYPE_H) $(Cache_DRV_H) + $(Cache_COMPILE) $T$@ $(Cache_DRV_SRC_S) + + +# Cache driver - multiple objects +# +$(OBJ_)%.$O: $(CACHE_DIR_)%.c $(FREETYPE_H) $(Cache_DRV_H) + $(Cache_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(Cache_DRV_OBJ_S) +DRV_OBJS_M += $(Cache_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/cff/Jamfile b/lib/freetype/src/cff/Jamfile new file mode 100644 index 0000000..cf7cf63 --- /dev/null +++ b/lib/freetype/src/cff/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/cff Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) cff ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = cffdrivr cffgload cffload cffobjs cffparse cffcmap ; + } + else + { + _sources = cff ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cff Jamfile diff --git a/lib/freetype/src/cff/cff.c b/lib/freetype/src/cff/cff.c new file mode 100644 index 0000000..013c329 --- /dev/null +++ b/lib/freetype/src/cff/cff.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* cff.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "cffdrivr.c" +#include "cffparse.c" +#include "cffload.c" +#include "cffobjs.c" +#include "cffgload.c" +#include "cffcmap.c" + +/* END */ diff --git a/lib/freetype/src/cff/cffcmap.c b/lib/freetype/src/cff/cffcmap.c new file mode 100644 index 0000000..5beb6ae --- /dev/null +++ b/lib/freetype/src/cff/cffcmap.c @@ -0,0 +1,326 @@ +/***************************************************************************/ +/* */ +/* cffcmap.c */ +/* */ +/* CFF character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002 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 "cffcmap.h" +#include "cffload.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_encoding_init( CFF_CMapStd cmap ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Encoding encoding = &cff->encoding; + + + cmap->count = encoding->count; + cmap->gids = encoding->codes; + + return 0; + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_encoding_done( CFF_CMapStd cmap ) + { + cmap->count = 0; + cmap->gids = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_encoding_char_index( CFF_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < cmap->count ) + result = cmap->gids[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_encoding_char_next( CFF_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + *pchar_code = 0; + + if ( char_code < cmap->count ) + { + FT_UInt code = (FT_UInt)(char_code + 1); + + + for (;;) + { + if ( code >= cmap->count ) + break; + + result = cmap->gids[code]; + if ( result != 0 ) + { + *pchar_code = code; + break; + } + + code++; + } + } + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + cff_cmap_encoding_class_rec = + { + sizeof ( CFF_CMapStdRec ), + + (FT_CMap_InitFunc) cff_cmap_encoding_init, + (FT_CMap_DoneFunc) cff_cmap_encoding_done, + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Int ) + cff_cmap_uni_pair_compare( const void* pair1, + const void* pair2 ) + { + FT_UInt32 u1 = ((CFF_CMapUniPair)pair1)->unicode; + FT_UInt32 u2 = ((CFF_CMapUniPair)pair2)->unicode; + + + if ( u1 < u2 ) + return -1; + + if ( u1 > u2 ) + return +1; + + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + cff_cmap_unicode_init( CFF_CMapUnicode cmap ) + { + FT_Error error; + FT_UInt count; + TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + CFF_Font cff = (CFF_Font)face->extra.data; + CFF_Charset charset = &cff->charset; + PSNames_Service psnames = (PSNames_Service)cff->psnames; + + + cmap->num_pairs = 0; + cmap->pairs = NULL; + + count = (FT_UInt)face->root.num_glyphs; + + if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) + { + FT_UInt n, new_count; + CFF_CMapUniPair pair; + FT_UInt32 uni_code; + + + pair = cmap->pairs; + for ( n = 0; n < count; n++ ) + { + FT_UInt sid = charset->sids[n]; + const char* gname; + + + gname = cff_index_get_sid_string( &cff->string_index, sid, psnames ); + + /* build unsorted pair table by matching glyph names */ + if ( gname ) + { + uni_code = psnames->unicode_value( gname ); + + if ( uni_code != 0 ) + { + pair->unicode = uni_code; + pair->gindex = n; + pair++; + } + + FT_FREE( gname ); + } + } + + new_count = (FT_UInt)( pair - cmap->pairs ); + if ( new_count == 0 ) + { + /* there are no unicode characters in here! */ + FT_FREE( cmap->pairs ); + error = FT_Err_Invalid_Argument; + } + else + { + /* re-allocate if the new array is much smaller than the original */ + /* one */ + if ( new_count != count && new_count < count / 2 ) + { + (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); + error = 0; + } + + /* sort the pairs table to allow efficient binary searches */ + ft_qsort( cmap->pairs, + new_count, + sizeof ( CFF_CMapUniPairRec ), + cff_cmap_uni_pair_compare ); + + cmap->num_pairs = new_count; + } + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + cff_cmap_unicode_done( CFF_CMapUnicode cmap ) + { + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( cmap->pairs ); + cmap->num_pairs = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_unicode_char_index( CFF_CMapUnicode cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_pairs; + FT_UInt mid; + CFF_CMapUniPair pair; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + pair = cmap->pairs + mid; + + if ( pair->unicode == char_code ) + return pair->gindex; + + if ( pair->unicode < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + cff_cmap_unicode_char_next( CFF_CMapUnicode cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_pairs; + FT_UInt mid; + CFF_CMapUniPair pair; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + pair = cmap->pairs + mid; + + if ( pair->unicode == char_code ) + { + result = pair->gindex; + if ( result != 0 ) + goto Exit; + + char_code++; + goto Restart; + } + + if ( pair->unicode < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_pairs ) + { + pair = cmap->pairs + min; + result = pair->gindex; + if ( result != 0 ) + char_code = pair->unicode; + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + cff_cmap_unicode_class_rec = + { + sizeof ( CFF_CMapUnicodeRec ), + + (FT_CMap_InitFunc) cff_cmap_unicode_init, + (FT_CMap_DoneFunc) cff_cmap_unicode_done, + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next + }; + + +/* END */ diff --git a/lib/freetype/src/cff/cffcmap.h b/lib/freetype/src/cff/cffcmap.h new file mode 100644 index 0000000..e136d29 --- /dev/null +++ b/lib/freetype/src/cff/cffcmap.h @@ -0,0 +1,88 @@ +/***************************************************************************/ +/* */ +/* cffcmap.h */ +/* */ +/* CFF character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002 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 __CFFCMAP_H__ +#define __CFFCMAP_H__ + +#include "cffobjs.h" + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct CFF_CMapStdRec_* CFF_CMapStd; + + typedef struct CFF_CMapStdRec_ + { + FT_CMapRec cmap; + FT_UInt count; + FT_UShort* gids; /* up to 256 elements */ + + } CFF_CMapStdRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + cff_cmap_encoding_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (synthetic) cmaps */ + typedef struct CFF_CMapUnicodeRec_* CFF_CMapUnicode; + + typedef struct CFF_CMapUniPairRec_ + { + FT_UInt32 unicode; + FT_UInt gindex; + + } CFF_CMapUniPairRec, *CFF_CMapUniPair; + + + typedef struct CFF_CMapUnicodeRec_ + { + FT_CMapRec cmap; + FT_UInt num_pairs; + CFF_CMapUniPair pairs; + + } CFF_CMapUnicodeRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + cff_cmap_unicode_class_rec; + + +FT_END_HEADER + +#endif /* __CFFCMAP_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cffdrivr.c b/lib/freetype/src/cff/cffdrivr.c new file mode 100644 index 0000000..34ed2bf --- /dev/null +++ b/lib/freetype/src/cff/cffdrivr.c @@ -0,0 +1,420 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.c */ +/* */ +/* OpenType font driver implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_IDS_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +#include "cffdrivr.h" +#include "cffgload.h" +#include "cffload.h" + +#include "cfferrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffdriver + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Get_Kerning */ + /* */ + /* <Description> */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* <Output> */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + Get_Kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Kern0_Pair pair; + + + if ( !face ) + return CFF_Err_Invalid_Face_Handle; + + kerning->x = 0; + kerning->y = 0; + + if ( face->kern_pairs ) + { + /* there are some kerning pairs in this font file! */ + FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); + FT_Long left, right; + + + left = 0; + right = face->num_kern_pairs - 1; + + while ( left <= right ) + { + FT_Long middle = left + ( ( right - left ) >> 1 ); + FT_ULong cur_pair; + + + pair = face->kern_pairs + middle; + cur_pair = PAIR_TAG( pair->left, pair->right ); + + if ( cur_pair == search_tag ) + goto Found; + + if ( cur_pair < search_tag ) + left = middle + 1; + else + right = middle - 1; + } + } + + Exit: + return CFF_Err_Ok; + + Found: + kerning->x = pair->value; + goto Exit; + } + + +#undef PAIR_TAG + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Load_Glyph */ + /* */ + /* <Description> */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FTLOAD_??? constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_Glyph( CFF_GlyphSlot slot, + CFF_Size size, + FT_UShort glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + + + if ( !slot ) + return CFF_Err_Invalid_Slot_Handle; + + /* check whether we want a scaled outline or bitmap */ + if ( !size ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_SCALE ) + size = NULL; + + /* reset the size object if necessary */ + if ( size ) + { + /* these two object must have the same parent */ + if ( size->face != slot->root.face ) + return CFF_Err_Invalid_Face_Handle; + } + + /* now load the glyph outline if necessary */ + error = cff_slot_load( slot, size, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R A C T E R M A P P I N G S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + cff_get_glyph_name( CFF_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + CFF_Font font = (CFF_Font)face->extra.data; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* gname; + FT_UShort sid; + PSNames_Service psnames; + FT_Error error; + + + psnames = (PSNames_Service)FT_Get_Module_Interface( + face->root.driver->root.library, "psnames" ); + + if ( !psnames ) + { + FT_ERROR(( "cff_get_glyph_name:" )); + FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " " )); + FT_ERROR(( " without the `PSNames' module\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + /* first, locate the sid in the charset table */ + sid = font->charset.sids[glyph_index]; + + /* now, lookup the name itself */ + gname = cff_index_get_sid_string( &font->string_index, sid, psnames ); + + if ( buffer_max > 0 ) + { + FT_UInt len = (FT_UInt)ft_strlen( gname ); + + + if ( len >= buffer_max ) + len = buffer_max - 1; + + FT_MEM_COPY( buffer, gname, len ); + ((FT_Byte*)buffer)[len] = 0; + } + + FT_FREE ( gname ); + error = CFF_Err_Ok; + + Exit: + return error; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_get_name_index */ + /* */ + /* <Description> */ + /* Uses the psnames module and the CFF font's charset to to return a */ + /* a given glyph name's glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* Glyph index. 0 means `undefined character code'. */ + /* */ + static FT_UInt + cff_get_name_index( CFF_Face face, + FT_String* glyph_name ) + { + CFF_Font cff; + CFF_Charset charset; + PSNames_Service psnames; + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_String* name; + FT_UShort sid; + FT_UInt i; + FT_Int result; + + + cff = (CFF_FontRec *)face->extra.data; + charset = &cff->charset; + + psnames = (PSNames_Service)FT_Get_Module_Interface( + face->root.driver->root.library, "psnames" ); + + for ( i = 0; i < cff->num_glyphs; i++ ) + { + sid = charset->sids[i]; + + if ( sid > 390 ) + name = cff_index_get_name( &cff->string_index, sid - 391 ); + else + name = (FT_String *)psnames->adobe_std_strings( sid ); + + result = ft_strcmp( glyph_name, name ); + + if ( sid > 390 ) + FT_FREE( name ); + + if ( !result ) + return i; + } + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Module_Interface + cff_get_interface( CFF_Driver driver, + const char* module_interface ) + { + FT_Module sfnt; + + +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + + if ( ft_strcmp( (const char*)module_interface, "glyph_name" ) == 0 ) + return (FT_Module_Interface)cff_get_glyph_name; + + if ( ft_strcmp( (const char*)module_interface, "name_index" ) == 0 ) + return (FT_Module_Interface)cff_get_name_index; + +#endif + + /* we simply pass our request to the `sfnt' module */ + sfnt = FT_Get_Module( driver->root.root.library, "sfnt" ); + + return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec cff_driver_class = + { + /* begin with the FT_Module_Class fields */ + { + ft_module_font_driver | + ft_module_driver_scalable | + ft_module_driver_has_hinter, + + sizeof( CFF_DriverRec ), + "cff", + 0x10000L, + 0x20000L, + + 0, /* module-specific interface */ + + (FT_Module_Constructor)cff_driver_init, + (FT_Module_Destructor) cff_driver_done, + (FT_Module_Requester) cff_get_interface, + }, + + /* now the specific driver fields */ + sizeof( TT_FaceRec ), + sizeof( FT_SizeRec ), + sizeof( CFF_GlyphSlotRec ), + + (FT_Face_InitFunc) cff_face_init, + (FT_Face_DoneFunc) cff_face_done, + (FT_Size_InitFunc) cff_size_init, + (FT_Size_DoneFunc) cff_size_done, + (FT_Slot_InitFunc) cff_slot_init, + (FT_Slot_DoneFunc) cff_slot_done, + + (FT_Size_ResetPointsFunc)cff_size_reset, + (FT_Size_ResetPixelsFunc)cff_size_reset, + + (FT_Slot_LoadFunc) Load_Glyph, + + (FT_Face_GetKerningFunc) Get_Kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc)0, + }; + + +/* END */ diff --git a/lib/freetype/src/cff/cffdrivr.h b/lib/freetype/src/cff/cffdrivr.h new file mode 100644 index 0000000..553848c --- /dev/null +++ b/lib/freetype/src/cff/cffdrivr.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* cffdrivr.h */ +/* */ +/* High-level OpenType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFDRIVER_H__ +#define __CFFDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const FT_Driver_ClassRec cff_driver_class; + + +FT_END_HEADER + +#endif /* __CFFDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cfferrs.h b/lib/freetype/src/cff/cfferrs.h new file mode 100644 index 0000000..1b2a5c9 --- /dev/null +++ b/lib/freetype/src/cff/cfferrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* cfferrs.h */ +/* */ +/* CFF error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the CFF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CFFERRS_H__ +#define __CFFERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX CFF_Err_ +#define FT_ERR_BASE FT_Mod_Err_CFF + + +#include FT_ERRORS_H + +#endif /* __CFFERRS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cffgload.c b/lib/freetype/src/cff/cffgload.c new file mode 100644 index 0000000..0432aa0 --- /dev/null +++ b/lib/freetype/src/cff/cffgload.c @@ -0,0 +1,2504 @@ +/***************************************************************************/ +/* */ +/* cffgload.c */ +/* */ +/* OpenType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_OUTLINE_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + +#include "cffobjs.h" +#include "cffload.h" +#include "cffgload.h" + +#include "cfferrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffgload + + + typedef enum CFF_Operator_ + { + cff_op_unknown = 0, + + cff_op_rmoveto, + cff_op_hmoveto, + cff_op_vmoveto, + + cff_op_rlineto, + cff_op_hlineto, + cff_op_vlineto, + + cff_op_rrcurveto, + cff_op_hhcurveto, + cff_op_hvcurveto, + cff_op_rcurveline, + cff_op_rlinecurve, + cff_op_vhcurveto, + cff_op_vvcurveto, + + cff_op_flex, + cff_op_hflex, + cff_op_hflex1, + cff_op_flex1, + + cff_op_endchar, + + cff_op_hstem, + cff_op_vstem, + cff_op_hstemhm, + cff_op_vstemhm, + + cff_op_hintmask, + cff_op_cntrmask, + cff_op_dotsection, /* deprecated, acts as no-op */ + + cff_op_abs, + cff_op_add, + cff_op_sub, + cff_op_div, + cff_op_neg, + cff_op_random, + cff_op_mul, + cff_op_sqrt, + + cff_op_blend, + + cff_op_drop, + cff_op_exch, + cff_op_index, + cff_op_roll, + cff_op_dup, + + cff_op_put, + cff_op_get, + cff_op_store, + cff_op_load, + + cff_op_and, + cff_op_or, + cff_op_not, + cff_op_eq, + cff_op_ifelse, + + cff_op_callsubr, + cff_op_callgsubr, + cff_op_return, + + /* do not remove */ + cff_op_max + + } CFF_Operator; + + +#define CFF_COUNT_CHECK_WIDTH 0x80 +#define CFF_COUNT_EXACT 0x40 +#define CFF_COUNT_CLEAR_STACK 0x20 + + + static const FT_Byte cff_argument_counts[] = + { + 0, /* unknown */ + + 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + + 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 13, /* flex */ + 7, + 9, + 11, + + 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ + + 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + + 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ + 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ + 0, /* dotsection */ + + 1, /* abs */ + 2, + 2, + 2, + 1, + 0, + 2, + 1, + + 1, /* blend */ + + 1, /* drop */ + 2, + 1, + 2, + 1, + + 2, /* put */ + 1, + 4, + 3, + + 2, /* and */ + 2, + 1, + 2, + 4, + + 1, /* callsubr */ + 1, + 0 + }; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** GENERIC CHARSTRING PARSING *********/ + /********** *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + static void + cff_builder_init( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->path_begun = 0; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->root.memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->root.internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hint_flags = FT_FACE(face)->internal->hint_flags; + builder->hints_globals = 0; + builder->hints_funcs = 0; + + if ( hinting && size ) + { + builder->hints_globals = size->internal; + builder->hints_funcs = glyph->root.internal->glyph_hints; + } + } + + if ( size ) + { + builder->scale_x = size->metrics.x_scale; + builder->scale_y = size->metrics.y_scale; + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + static void + cff_builder_done( CFF_Builder* builder ) + { + CFF_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_compute_bias */ + /* */ + /* <Description> */ + /* Computes the bias value in dependence of the number of glyph */ + /* subroutines. */ + /* */ + /* <Input> */ + /* num_subrs :: The number of glyph subroutines. */ + /* */ + /* <Return> */ + /* The bias value. */ + static FT_Int + cff_compute_bias( FT_UInt num_subrs ) + { + FT_Int result; + + + if ( num_subrs < 1240 ) + result = 107; + else if ( num_subrs < 33900U ) + result = 1131; + else + result = 32768U; + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph decoder. */ + /* */ + /* <InOut> */ + /* decoder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* slot :: The current glyph object. */ + /* */ + FT_LOCAL_DEF( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + /* clear everything */ + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* initialize builder */ + cff_builder_init( &decoder->builder, face, size, slot, hinting ); + + /* initialize Type2 decoder */ + decoder->num_globals = cff->num_global_subrs; + decoder->globals = cff->global_subrs; + decoder->globals_bias = cff_compute_bias( decoder->num_globals ); + + decoder->hint_mode = hint_mode; + } + + + /* this function is used to select the locals subrs array */ + FT_LOCAL_DEF( void ) + cff_decoder_prepare( CFF_Decoder* decoder, + FT_UInt glyph_index ) + { + CFF_Font cff = (CFF_Font)decoder->builder.face->extra.data; + CFF_SubFont sub = &cff->top_font; + + + /* manage CID fonts */ + if ( cff->num_subfonts >= 1 ) + { + FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); + + + sub = cff->subfonts[fd_index]; + } + + decoder->num_locals = sub->num_local_subrs; + decoder->locals = sub->local_subrs; + decoder->locals_bias = cff_compute_bias( decoder->num_locals ); + + decoder->glyph_width = sub->private_dict.default_width; + decoder->nominal_width = sub->private_dict.nominal_width; + } + + + /* check that there is enough room for `count' more points */ + static FT_Error + check_points( CFF_Builder* builder, + FT_Int count ) + { + return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + static void + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + + + point->x = x >> 16; + point->y = y >> 16; + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + + builder->last = *point; + } + + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + static FT_Error + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = check_points( builder, 1 ); + if ( !error ) + cff_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check room for a new contour, then add it */ + static FT_Error + cff_builder_add_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return CFF_Err_Ok; + } + + error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + static FT_Error + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = 0; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = cff_builder_add_contour( builder ); + if ( !error ) + error = cff_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + static void + cff_builder_close_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + + + /* XXXX: We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Int first = 0; + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + if ( outline->n_contours > 1 ) + { + first = outline->contours[outline->n_contours - 2] + 1; + p1 = outline->points + first; + } + + /* `delete' last point only if it coincides with the first */ + /* point and if it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + + + static FT_Int + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ) + { + FT_UInt n; + FT_UShort glyph_sid; + + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + /* Get code to SID mapping from `cff_standard_encoding'. */ + glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode ); + + for ( n = 0; n < cff->num_glyphs; n++ ) + { + if ( cff->charset.sids[n] == glyph_sid ) + return n; + } + + return -1; + } + + + static FT_Error + cff_get_glyph_data( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + FT_Error error = + face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &data ); + + + *pointer = (FT_Byte*)data.pointer; + *length = data.length; + + return error; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + return cff_index_access_element( &cff->charstrings_index, glyph_index, + pointer, length ); + } + } + + + static void + cff_free_glyph_data( TT_Face face, + FT_Byte** pointer, + FT_ULong length ) + { +#ifndef FT_CONFIG_OPTION_INCREMENTAL + FT_UNUSED( length ); +#endif + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + + + data.pointer = *pointer; + data.length = length; + + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object,&data ); + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + cff_index_forget_element( &cff->charstrings_index, pointer ); + } + } + + + static FT_Error + cff_operator_seac( CFF_Decoder* decoder, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + FT_Int bchar_index, achar_index, n_base_points; + FT_Outline* base = decoder->builder.base; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( face->root.internal->incremental_interface ) + { + bchar_index = bchar; + achar_index = achar; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); + achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "cff_operator_seac:" )); + FT_ERROR(( " invalid seac character code arguments\n" )); + return CFF_Err_Syntax_Error; + } + + /* If we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( decoder->builder.no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)adx; + subg->arg2 = (FT_Int)ady; + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + } + + /* First load `bchar' in builder */ + error = cff_get_glyph_data( face, bchar_index, + &charstring, &charstring_len ); + if ( !error ) + { + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + + if ( error ) + goto Exit; + + cff_free_glyph_data( face, &charstring, charstring_len ); + } + + n_base_points = base->n_points; + + /* Save the left bearing and width of the base character */ + /* as they will be erased by the next load. */ + + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + /* Now load `achar' on top of the base outline. */ + error = cff_get_glyph_data( face, achar_index, + &charstring, &charstring_len ); + if ( !error ) + { + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len ); + + if ( error ) + goto Exit; + + cff_free_glyph_data( face, &charstring, charstring_len ); + } + + /* Restore the left side bearing and advance width */ + /* of the base character. */ + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + /* Finally, move the accent. */ + if ( decoder->builder.load_points ) + { + FT_Outline dummy; + + + dummy.n_points = (short)( base->n_points - n_base_points ); + dummy.points = base->points + n_base_points; + + FT_Outline_Translate( &dummy, adx, ady ); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 2 charstrings program. */ + /* */ + /* <InOut> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* <Input> */ + /* charstring_base :: The base of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ) + { + FT_Error error; + CFF_Decoder_Zone* zone; + FT_Byte* ip; + FT_Byte* limit; + CFF_Builder* builder = &decoder->builder; + FT_Pos x, y; + FT_Fixed seed; + FT_Fixed* stack; + + T2_Hints_Funcs hinter; + + + /* set default width */ + decoder->num_hints = 0; + decoder->read_width = 1; + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)(char*)&seed ^ + (FT_Fixed)(char*)&decoder ^ + (FT_Fixed)(char*)&charstring_base; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFF; + if ( seed == 0 ) + seed = 0x7384; + + /* initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + stack = decoder->top; + + hinter = (T2_Hints_Funcs) builder->hints_funcs; + + builder->path_begun = 0; + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = CFF_Err_Ok; + + x = builder->pos_x; + y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + /* now, execute loop */ + while ( ip < limit ) + { + CFF_Operator op; + FT_Byte v; + + + /********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + v = *ip++; + if ( v >= 32 || v == 28 ) + { + FT_Int shift = 16; + FT_Int32 val; + + + /* this is an operand, push it on the stack */ + if ( v == 28 ) + { + if ( ip + 1 >= limit ) + goto Syntax_Error; + val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] ); + ip += 2; + } + else if ( v < 247 ) + val = (FT_Long)v - 139; + else if ( v < 251 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108; + } + else if ( v < 255 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108; + } + else + { + if ( ip + 3 >= limit ) + goto Syntax_Error; + val = ( (FT_Int32)ip[0] << 24 ) | + ( (FT_Int32)ip[1] << 16 ) | + ( (FT_Int32)ip[2] << 8 ) | + ip[3]; + ip += 4; + shift = 0; + } + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + val <<= shift; + *decoder->top++ = val; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( val & 0xFFFF ) ) + FT_TRACE4(( " %d", (FT_Int32)( val >> 16 ) )); + else + FT_TRACE4(( " %.2f", val / 65536.0 )); +#endif + + } + else + { + FT_Fixed* args = decoder->top; + FT_Int num_args = (FT_Int)( args - decoder->stack ); + FT_Int req_args; + + + /* find operator */ + op = cff_op_unknown; + + switch ( v ) + { + case 1: + op = cff_op_hstem; + break; + case 3: + op = cff_op_vstem; + break; + case 4: + op = cff_op_vmoveto; + break; + case 5: + op = cff_op_rlineto; + break; + case 6: + op = cff_op_hlineto; + break; + case 7: + op = cff_op_vlineto; + break; + case 8: + op = cff_op_rrcurveto; + break; + case 10: + op = cff_op_callsubr; + break; + case 11: + op = cff_op_return; + break; + case 12: + { + if ( ip >= limit ) + goto Syntax_Error; + v = *ip++; + + switch ( v ) + { + case 0: + op = cff_op_dotsection; + break; + case 3: + op = cff_op_and; + break; + case 4: + op = cff_op_or; + break; + case 5: + op = cff_op_not; + break; + case 8: + op = cff_op_store; + break; + case 9: + op = cff_op_abs; + break; + case 10: + op = cff_op_add; + break; + case 11: + op = cff_op_sub; + break; + case 12: + op = cff_op_div; + break; + case 13: + op = cff_op_load; + break; + case 14: + op = cff_op_neg; + break; + case 15: + op = cff_op_eq; + break; + case 18: + op = cff_op_drop; + break; + case 20: + op = cff_op_put; + break; + case 21: + op = cff_op_get; + break; + case 22: + op = cff_op_ifelse; + break; + case 23: + op = cff_op_random; + break; + case 24: + op = cff_op_mul; + break; + case 26: + op = cff_op_sqrt; + break; + case 27: + op = cff_op_dup; + break; + case 28: + op = cff_op_exch; + break; + case 29: + op = cff_op_index; + break; + case 30: + op = cff_op_roll; + break; + case 34: + op = cff_op_hflex; + break; + case 35: + op = cff_op_flex; + break; + case 36: + op = cff_op_hflex1; + break; + case 37: + op = cff_op_flex1; + break; + default: + /* decrement ip for syntax error message */ + ip--; + } + } + break; + case 14: + op = cff_op_endchar; + break; + case 16: + op = cff_op_blend; + break; + case 18: + op = cff_op_hstemhm; + break; + case 19: + op = cff_op_hintmask; + break; + case 20: + op = cff_op_cntrmask; + break; + case 21: + op = cff_op_rmoveto; + break; + case 22: + op = cff_op_hmoveto; + break; + case 23: + op = cff_op_vstemhm; + break; + case 24: + op = cff_op_rcurveline; + break; + case 25: + op = cff_op_rlinecurve; + break; + case 26: + op = cff_op_vvcurveto; + break; + case 27: + op = cff_op_hhcurveto; + break; + case 29: + op = cff_op_callgsubr; + break; + case 30: + op = cff_op_vhcurveto; + break; + case 31: + op = cff_op_hvcurveto; + break; + default: + ; + } + if ( op == cff_op_unknown ) + goto Syntax_Error; + + /* check arguments */ + req_args = cff_argument_counts[op]; + if ( req_args & CFF_COUNT_CHECK_WIDTH ) + { + args = stack; + + if ( num_args > 0 && decoder->read_width ) + { + /* If `nominal_width' is non-zero, the number is really a */ + /* difference against `nominal_width'. Else, the number here */ + /* is truly a width, not a difference against `nominal_width'. */ + /* If the font does not set `nominal_width', then */ + /* `nominal_width' defaults to zero, and so we can set */ + /* `glyph_width' to `nominal_width' plus number on the stack */ + /* -- for either case. */ + + FT_Int set_width_ok; + + + switch ( op ) + { + case cff_op_hmoveto: + case cff_op_vmoveto: + set_width_ok = num_args & 2; + break; + + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + case cff_op_rmoveto: + set_width_ok = num_args & 1; + break; + + case cff_op_endchar: + /* If there is a width specified for endchar, we either have */ + /* 1 argument or 5 arguments. We like to argue. */ + set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) ); + break; + + default: + set_width_ok = 0; + break; + } + + if ( set_width_ok ) + { + decoder->glyph_width = decoder->nominal_width + + ( stack[0] >> 16 ); + + /* Consumed an argument. */ + num_args--; + args++; + } + } + + decoder->read_width = 0; + req_args = 0; + } + + req_args &= 15; + if ( num_args < req_args ) + goto Stack_Underflow; + args -= req_args; + num_args -= req_args; + + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + /* the number of arguments is always even here */ + FT_TRACE4(( op == cff_op_hstem ? " hstem" : + ( op == cff_op_vstem ? " vstem" : + ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); + + if ( hinter ) + hinter->stems( hinter->hints, + ( op == cff_op_hstem || op == cff_op_hstemhm ), + num_args / 2, + args ); + + decoder->num_hints += num_args / 2; + args = stack; + break; + + case cff_op_hintmask: + case cff_op_cntrmask: + FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); + + /* implement vstem when needed -- */ + /* the specification doesn't say it, but this also works */ + /* with the 'cntrmask' operator */ + /* */ + if ( num_args > 0 ) + { + if ( hinter ) + hinter->stems( hinter->hints, + 0, + num_args / 2, + args ); + + decoder->num_hints += num_args / 2; + } + + if ( hinter ) + { + if ( op == cff_op_hintmask ) + hinter->hintmask( hinter->hints, + builder->current->n_points, + decoder->num_hints, + ip ); + else + hinter->counter( hinter->hints, + decoder->num_hints, + ip ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt maskbyte; + + + FT_TRACE4(( " " )); + + for ( maskbyte = 0; + maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3); + maskbyte++, ip++ ) + FT_TRACE4(( "%02X", *ip )); + } +#else + ip += ( decoder->num_hints + 7 ) >> 3; +#endif + if ( ip >= limit ) + goto Syntax_Error; + args = stack; + break; + + case cff_op_rmoveto: + FT_TRACE4(( " rmoveto" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[0]; + y += args[1]; + args = stack; + break; + + case cff_op_vmoveto: + FT_TRACE4(( " vmoveto" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + y += args[0]; + args = stack; + break; + + case cff_op_hmoveto: + FT_TRACE4(( " hmoveto" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x += args[0]; + args = stack; + break; + + case cff_op_rlineto: + FT_TRACE4(( " rlineto" )); + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_args / 2 ) ) + goto Memory_Error; + + if ( num_args < 2 || num_args & 1 ) + goto Stack_Underflow; + + args = stack; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + } + args = stack; + break; + + case cff_op_hlineto: + case cff_op_vlineto: + { + FT_Int phase = ( op == cff_op_hlineto ); + + + FT_TRACE4(( op == cff_op_hlineto ? " hlineto" + : " vlineto" )); + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_args ) ) + goto Memory_Error; + + args = stack; + while (args < decoder->top ) + { + if ( phase ) + x += args[0]; + else + y += args[0]; + + if ( cff_builder_add_point1( builder, x, y ) ) + goto Memory_Error; + + args++; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rrcurveto: + FT_TRACE4(( " rrcurveto" )); + + /* check number of arguments; must be a multiple of 6 */ + if ( num_args % 6 != 0 ) + goto Stack_Underflow; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_args / 2 ) ) + goto Memory_Error; + + args = stack; + while ( args < decoder->top ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + } + args = stack; + break; + + case cff_op_vvcurveto: + FT_TRACE4(( " vvcurveto" )); + + if ( cff_builder_start_point ( builder, x, y ) ) + goto Memory_Error; + + args = stack; + if ( num_args & 1 ) + { + x += args[0]; + args++; + num_args--; + } + + if ( num_args % 4 != 0 ) + goto Stack_Underflow; + + if ( check_points( builder, 3 * ( num_args / 4 ) ) ) + goto Memory_Error; + + while ( args < decoder->top ) + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + break; + + case cff_op_hhcurveto: + FT_TRACE4(( " hhcurveto" )); + + if ( cff_builder_start_point ( builder, x, y ) ) + goto Memory_Error; + + args = stack; + if ( num_args & 1 ) + { + y += args[0]; + args++; + num_args--; + } + + if ( num_args % 4 != 0 ) + goto Stack_Underflow; + + if ( check_points( builder, 3 * ( num_args / 4 ) ) ) + goto Memory_Error; + + while ( args < decoder->top ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + args += 4; + } + args = stack; + break; + + case cff_op_vhcurveto: + case cff_op_hvcurveto: + { + FT_Int phase; + + + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto" + : " hvcurveto" )); + + if ( cff_builder_start_point ( builder, x, y ) ) + goto Memory_Error; + + args = stack; + if (num_args < 4 || ( num_args % 4 ) > 1 ) + goto Stack_Underflow; + + if ( check_points( builder, ( num_args / 4 ) * 3 ) ) + goto Stack_Underflow; + + phase = ( op == cff_op_hvcurveto ); + + while ( num_args >= 4 ) + { + num_args -= 4; + if ( phase ) + { + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + y += args[3]; + if ( num_args == 1 ) + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + else + { + y += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[3]; + if ( num_args == 1 ) + y += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + } + args += 4; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rlinecurve: + { + FT_Int num_lines = ( num_args - 6 ) / 2; + + + FT_TRACE4(( " rlinecurve" )); + + if ( num_args < 8 || ( num_args - 6 ) & 1 ) + goto Stack_Underflow; + + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, num_lines + 3 ) ) + goto Memory_Error; + + args = stack; + + /* first, add the line segments */ + while ( num_lines > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + num_lines--; + } + + /* then the curve */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_rcurveline: + { + FT_Int num_curves = ( num_args - 2 ) / 6; + + + FT_TRACE4(( " rcurveline" )); + + if ( num_args < 8 || ( num_args - 2 ) % 6 ) + goto Stack_Underflow; + + if ( cff_builder_start_point ( builder, x, y ) || + check_points( builder, num_curves*3 + 2 ) ) + goto Memory_Error; + + args = stack; + + /* first, add the curves */ + while ( num_curves > 0 ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + x += args[4]; + y += args[5]; + cff_builder_add_point( builder, x, y, 1 ); + args += 6; + num_curves--; + } + + /* then the final line */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 1 ); + args = stack; + } + break; + + case cff_op_hflex1: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex1" )); + + args = stack; + + /* adding five more points; 4 control points, 1 on-curve point */ + /* make sure we have enough space for the start point if it */ + /* needs to be added.. */ + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Memory_Error; + + /* Record the starting point's y postion for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[2]; + y += args[3]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[5]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[6]; + y += args[7]; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start */ + x += args[8]; + y = start_y; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_hflex: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex" )); + + args = stack; + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + check_points ( builder, 6 ) ) + goto Memory_Error; + + /* record the starting point's y-position for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[1]; + y += args[2]; + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[3]; + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[4]; + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[5]; + y = start_y; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start point's */ + /* y-value -- we don't add this point, though */ + x += args[6]; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex1: + { + FT_Pos start_x, start_y; /* record start x, y values for alter */ + /* use */ + FT_Int dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + + + FT_TRACE4(( " flex1" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Memory_Error; + + /* record the starting point's x, y postion for later use */ + start_x = x; + start_y = y; + + /* XXX: figure out whether this is supposed to be a horizontal */ + /* or vertical flex; the Type 2 specification is vague... */ + + args = stack; + + /* grab up to the last argument */ + for ( count = 5; count > 0; count-- ) + { + dx += (FT_Int)args[0]; + dy += (FT_Int)args[1]; + args += 2; + } + + /* rewind */ + args = stack; + + if ( dx < 0 ) dx = -dx; + if ( dy < 0 ) dy = -dy; + + /* strange test, but here it is... */ + horizontal = ( dx > dy ); + + for ( count = 5; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) ); + args += 2; + } + + /* is last operand an x- or y-delta? */ + if ( horizontal ) + { + x += args[0]; + y = start_y; + } + else + { + x = start_x; + y += args[0]; + } + + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex: + { + FT_UInt count; + + + FT_TRACE4(( " flex" )); + + if ( cff_builder_start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Memory_Error; + + args = stack; + for ( count = 6; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 || count == 0 ) ); + args += 2; + } + + args = stack; + } + break; + + case cff_op_endchar: + FT_TRACE4(( " endchar" )); + + /* We are going to emulate the seac operator. */ + if ( num_args == 4 ) + { + error = cff_operator_seac( decoder, + args[0] >> 16, + args[1] >> 16, + (FT_Int)( args[2] >> 16 ), + (FT_Int)( args[3] >> 16 ) ); + args += 4; + } + + if ( !error ) + error = CFF_Err_Ok; + + cff_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if (hinter->close( hinter->hints, builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + builder->hint_flags ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n\n" )); + return error; + + case cff_op_abs: + FT_TRACE4(( " abs" )); + + if ( args[0] < 0 ) + args[0] = -args[0]; + args++; + break; + + case cff_op_add: + FT_TRACE4(( " add" )); + + args[0] += args[1]; + args++; + break; + + case cff_op_sub: + FT_TRACE4(( " sub" )); + + args[0] -= args[1]; + args++; + break; + + case cff_op_div: + FT_TRACE4(( " div" )); + + args[0] = FT_DivFix( args[0], args[1] ); + args++; + break; + + case cff_op_neg: + FT_TRACE4(( " neg" )); + + args[0] = -args[0]; + args++; + break; + + case cff_op_random: + { + FT_Fixed Rand; + + + FT_TRACE4(( " rand" )); + + Rand = seed; + if ( Rand >= 0x8000 ) + Rand++; + + args[0] = Rand; + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + args++; + } + break; + + case cff_op_mul: + FT_TRACE4(( " mul" )); + + args[0] = FT_MulFix( args[0], args[1] ); + args++; + break; + + case cff_op_sqrt: + FT_TRACE4(( " sqrt" )); + + if ( args[0] > 0 ) + { + FT_Int count = 9; + FT_Fixed root = args[0]; + FT_Fixed new_root; + + + for (;;) + { + new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; + if ( new_root == root || count <= 0 ) + break; + root = new_root; + } + args[0] = new_root; + } + else + args[0] = 0; + args++; + break; + + case cff_op_drop: + /* nothing */ + FT_TRACE4(( " drop" )); + + break; + + case cff_op_exch: + { + FT_Fixed tmp; + + + FT_TRACE4(( " exch" )); + + tmp = args[0]; + args[0] = args[1]; + args[1] = tmp; + args += 2; + } + break; + + case cff_op_index: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " index" )); + + if ( idx < 0 ) + idx = 0; + else if ( idx > num_args - 2 ) + idx = num_args - 2; + args[0] = args[-( idx + 1 )]; + args++; + } + break; + + case cff_op_roll: + { + FT_Int count = (FT_Int)( args[0] >> 16 ); + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " roll" )); + + if ( count <= 0 ) + count = 1; + + args -= count; + if ( args < stack ) + goto Stack_Underflow; + + if ( idx >= 0 ) + { + while ( idx > 0 ) + { + FT_Fixed tmp = args[count - 1]; + FT_Int i; + + + for ( i = count - 2; i >= 0; i-- ) + args[i + 1] = args[i]; + args[0] = tmp; + idx--; + } + } + else + { + while ( idx < 0 ) + { + FT_Fixed tmp = args[0]; + FT_Int i; + + + for ( i = 0; i < count - 1; i++ ) + args[i] = args[i + 1]; + args[count - 1] = tmp; + idx++; + } + } + args += count; + } + break; + + case cff_op_dup: + FT_TRACE4(( " dup" )); + + args[1] = args[0]; + args++; + break; + + case cff_op_put: + { + FT_Fixed val = args[0]; + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " put" )); + + if ( idx >= 0 && idx < decoder->len_buildchar ) + decoder->buildchar[idx] = val; + } + break; + + case cff_op_get: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + FT_Fixed val = 0; + + + FT_TRACE4(( " get" )); + + if ( idx >= 0 && idx < decoder->len_buildchar ) + val = decoder->buildchar[idx]; + + args[0] = val; + args++; + } + break; + + case cff_op_store: + FT_TRACE4(( " store ")); + + goto Unimplemented; + + case cff_op_load: + FT_TRACE4(( " load" )); + + goto Unimplemented; + + case cff_op_dotsection: + /* this operator is deprecated and ignored by the parser */ + FT_TRACE4(( " dotsection" )); + break; + + case cff_op_and: + { + FT_Fixed cond = args[0] && args[1]; + + + FT_TRACE4(( " and" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_or: + { + FT_Fixed cond = args[0] || args[1]; + + + FT_TRACE4(( " or" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = !args[0]; + + + FT_TRACE4(( " eq" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_ifelse: + { + FT_Fixed cond = (args[2] <= args[3]); + + + FT_TRACE4(( " ifelse" )); + + if ( !cond ) + args[0] = args[1]; + args++; + } + break; + + case cff_op_callsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->locals_bias ); + + + FT_TRACE4(( " callsubr(%d)", idx )); + + if ( idx >= decoder->num_locals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" )); + FT_ERROR(( " invalid local subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->locals[idx]; + zone->limit = decoder->locals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs!\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_callgsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->globals_bias ); + + + FT_TRACE4(( " callgsubr(%d)", idx )); + + if ( idx >= decoder->num_globals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" )); + FT_ERROR(( " invalid global subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->globals[idx]; + zone->limit = decoder->globals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs!\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_return: + FT_TRACE4(( " return" )); + + if ( decoder->zone <= decoder->zones ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + decoder->zone--; + zone = decoder->zone; + ip = zone->cursor; + limit = zone->limit; + break; + + default: + Unimplemented: + FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); + + if ( ip[-1] == 12 ) + FT_ERROR(( " %d", ip[0] )); + FT_ERROR(( "\n" )); + + return CFF_Err_Unimplemented_Feature; + } + + decoder->top = args; + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + return error; + + Syntax_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" )); + return CFF_Err_Invalid_File_Format; + + Stack_Underflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" )); + return CFF_Err_Too_Few_Arguments; + + Stack_Overflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" )); + return CFF_Err_Stack_Overflow; + + Memory_Error: + return builder->error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#if 0 /* unused until we support pure CFF fonts */ + + + FT_LOCAL_DEF( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ) + { + FT_Error error = 0; + CFF_Decoder decoder; + FT_Int glyph_index; + CFF_Font cff = (CFF_Font)face->other; + + + *max_advance = 0; + + /* Initialize load decoder */ + cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + /* For each glyph, parse the glyph charstring and extract */ + /* the advance width. */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + FT_Byte* charstring; + FT_ULong charstring_len; + + + /* now get load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( !error ) + { + cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_parse_charstrings( &decoder, + charstring, charstring_len ); + + cff_free_glyph_data( face, &charstring, &charstring_len ); + } + + /* ignore the error if one has occurred -- skip to next glyph */ + error = 0; + } + + *max_advance = decoder.builder.advance.x; + + return CFF_Err_Ok; + } + + +#endif /* 0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** UNHINTED GLYPH LOADER *********/ + /********** *********/ + /********** The following code is in charge of loading a *********/ + /********** single outline. It completely ignores hinting *********/ + /********** and is used when FT_LOAD_NO_HINTING is set. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + CFF_Decoder decoder; + TT_Face face = (TT_Face)glyph->root.face; + FT_Bool hinting; + CFF_Font cff = (CFF_Font)face->extra.data; + + FT_Matrix font_matrix; + FT_Vector font_offset; + + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = 0x10000L; + glyph->y_scale = 0x10000L; + if ( size ) + { + glyph->x_scale = size->metrics.x_scale; + glyph->y_scale = size->metrics.y_scale; + } + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */ + + { + FT_Byte* charstring; + FT_ULong charstring_len; + + + cff_decoder_init( &decoder, face, size, glyph, hinting, + FT_LOAD_TARGET_MODE(load_flags) ); + + decoder.builder.no_recurse = + (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + + /* now load the unscaled outline */ + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); + if ( !error ) + { + cff_decoder_prepare( &decoder, glyph_index ); + error = cff_decoder_parse_charstrings( &decoder, + charstring, charstring_len ); + + cff_free_glyph_data( face, &charstring, charstring_len ); + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Control data and length may not be available for incremental */ + /* fonts. */ + if ( face->root.internal->incremental_interface ) + { + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* We set control_data and control_len if charstrings is loaded. */ + /* See how charstring loads at cff_index_access_element() in */ + /* cffload.c. */ + { + CFF_IndexRec csindex = cff->charstrings_index; + + + glyph->root.control_data = + csindex.bytes + csindex.offsets[glyph_index] - 1; + glyph->root.control_len = + charstring_len; + } + } + + /* save new glyph tables */ + cff_builder_done( &decoder.builder ); + } + + #ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && + face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + metrics.bearing_x = decoder.builder.left_bearing.x; + metrics.bearing_y = decoder.builder.left_bearing.y; + metrics.advance = decoder.builder.advance.x; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + decoder.builder.left_bearing.x = metrics.bearing_x; + decoder.builder.left_bearing.y = metrics.bearing_y; + decoder.builder.advance.x = metrics.advance; + decoder.builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + font_matrix = cff->top_font.font_dict.font_matrix; + font_offset = cff->top_font.font_dict.font_offset; + + /* Now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax. */ + if ( !error ) + { + /* For composite glyphs, return only left side bearing and */ + /* advance width. */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.glyph_width; + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.glyph_width; + glyph->root.linearHoriAdvance = decoder.glyph_width; + glyph->root.internal->glyph_transformed = 0; + + /* make up vertical metrics */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + + glyph->root.linearVertAdvance = 0; + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + glyph->root.outline.flags = 0; + if ( size && size->metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* apply the font matrix */ + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = &glyph->root.outline; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points */ + if ( !hinting ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + + metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); + metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; + metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + + metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; + metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + } + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* grid fit the bounding box if necessary */ + if ( hinting ) + { + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax + 63 ) & -64; + cbox.yMax = ( cbox.yMax + 63 ) & -64; + } + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + } + } + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/cff/cffgload.h b/lib/freetype/src/cff/cffgload.h new file mode 100644 index 0000000..a1be92c --- /dev/null +++ b/lib/freetype/src/cff/cffgload.h @@ -0,0 +1,214 @@ +/***************************************************************************/ +/* */ +/* cffgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFGLOAD_H__ +#define __CFFGLOAD_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include "cffobjs.h" + + +FT_BEGIN_HEADER + + +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 32 + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* CFF_Builder */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: The current glyph loader. */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* last :: The last point position. */ + /* */ + /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ + /* */ + /* scale_y :: The vertical scale (FUnits to sub-pixels). */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* error :: An error code that is only used to report memory */ + /* allocation problems. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* hints_funcs :: Auxiliary pointer for hinting. */ + /* */ + /* hints_globals :: Auxiliary pointer for hinting. */ + /* */ + typedef struct CFF_Builder_ + { + FT_Memory memory; + TT_Face face; + CFF_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Vector last; + + FT_Fixed scale_x; + FT_Fixed scale_y; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Error error; /* only used for memory errors */ + FT_Bool metrics_only; + + FT_UInt32 hint_flags; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + } CFF_Builder; + + + /* execution context charstring zone */ + + typedef struct CFF_Decoder_Zone_ + { + FT_Byte* base; + FT_Byte* limit; + FT_Byte* cursor; + + } CFF_Decoder_Zone; + + + typedef struct CFF_Decoder_ + { + CFF_Builder builder; + CFF_Font cff; + + FT_Fixed stack[CFF_MAX_OPERANDS + 1]; + FT_Fixed* top; + + CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; + CFF_Decoder_Zone* zone; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + FT_Pos glyph_width; + FT_Pos nominal_width; + + FT_Bool read_width; + FT_Int num_hints; + FT_Fixed* buildchar; + FT_Int len_buildchar; + + FT_UInt num_locals; + FT_UInt num_globals; + + FT_Int locals_bias; + FT_Int globals_bias; + + FT_Byte** locals; + FT_Byte** globals; + + FT_Byte** glyph_names; /* for pure CFF fonts only */ + FT_UInt num_glyphs; /* number of glyphs in font */ + + FT_Render_Mode hint_mode; + + } CFF_Decoder; + + + FT_LOCAL( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode ); + + FT_LOCAL( void ) + cff_decoder_prepare( CFF_Decoder* decoder, + FT_UInt glyph_index ); + +#if 0 /* unused until we support pure CFF fonts */ + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cff_compute_max_advance( TT_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + + FT_LOCAL( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + + FT_LOCAL( FT_Error ) + cff_slot_load( CFF_GlyphSlot glyph, + CFF_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CFFGLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cffload.c b/lib/freetype/src/cff/cffload.c new file mode 100644 index 0000000..66af469 --- /dev/null +++ b/lib/freetype/src/cff/cffload.c @@ -0,0 +1,2267 @@ +/***************************************************************************/ +/* */ +/* cffload.c */ +/* */ +/* OpenType and CFF data/program tables loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_TRUETYPE_TAGS_H + +#include "cffload.h" +#include "cffparse.h" + +#include "cfferrs.h" + + +#if 1 + static const FT_UShort cff_isoadobe_charset[229] = + { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228 + }; + + static const FT_UShort cff_expert_charset[166] = + { + 0, + 1, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 13, + 14, + 15, + 99, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 27, + 28, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 109, + 110, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 158, + 155, + 163, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 150, + 164, + 169, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378 + }; + + static const FT_UShort cff_expertsubset_charset[87] = + { + 0, + 1, + 231, + 232, + 235, + 236, + 237, + 238, + 13, + 14, + 15, + 99, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 27, + 28, + 249, + 250, + 251, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 109, + 110, + 267, + 268, + 269, + 270, + 272, + 300, + 301, + 302, + 305, + 314, + 315, + 158, + 155, + 163, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 150, + 164, + 169, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346 + }; + + static const FT_UShort cff_standard_encoding[256] = + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 0, + 111, + 112, + 113, + 114, + 0, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 0, + 123, + 0, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 0, + 132, + 133, + 0, + 134, + 135, + 136, + 137, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 138, + 0, + 139, + 0, + 0, + 0, + 0, + 140, + 141, + 142, + 143, + 0, + 0, + 0, + 0, + 0, + 144, + 0, + 0, + 0, + 145, + 0, + 0, + 146, + 147, + 148, + 149, + 0, + 0, + 0, + 0 + }; + + static const FT_UShort cff_expert_encoding[256] = + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 229, + 230, + 0, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 13, + 14, + 15, + 99, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 27, + 28, + 249, + 250, + 251, + 252, + 0, + 253, + 254, + 255, + 256, + 257, + 0, + 0, + 0, + 258, + 0, + 0, + 259, + 260, + 261, + 262, + 0, + 0, + 263, + 264, + 265, + 0, + 266, + 109, + 110, + 267, + 268, + 269, + 0, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 304, + 305, + 306, + 0, + 0, + 307, + 308, + 309, + 310, + 311, + 0, + 312, + 0, + 0, + 312, + 0, + 0, + 314, + 315, + 0, + 0, + 316, + 317, + 318, + 0, + 0, + 0, + 158, + 155, + 163, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 0, + 0, + 326, + 150, + 164, + 169, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378 + }; +#endif + + + FT_LOCAL_DEF( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ) + { + return (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0); + } + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffload + + + /* read a CFF offset from memory */ + static FT_ULong + cff_get_offset( FT_Byte* p, + FT_Byte off_size ) + { + FT_ULong result; + + + for ( result = 0; off_size > 0; off_size-- ) + { + result <<= 8; + result |= *p++; + } + + return result; + } + + + static FT_Error + cff_new_index( CFF_Index idx, + FT_Stream stream, + FT_Bool load ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UShort count; + + + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + + idx->stream = stream; + if ( !FT_READ_USHORT( count ) && + count > 0 ) + { + FT_Byte* p; + FT_Byte offsize; + FT_ULong data_size; + FT_ULong* poff; + + + /* there is at least one element; read the offset size, */ + /* then access the offset table to compute the index's total size */ + if ( FT_READ_BYTE( offsize ) ) + goto Exit; + + idx->stream = stream; + idx->count = count; + idx->off_size = offsize; + data_size = (FT_ULong)( count + 1 ) * offsize; + + if ( FT_NEW_ARRAY( idx->offsets, count + 1 ) || + FT_FRAME_ENTER( data_size ) ) + goto Exit; + + poff = idx->offsets; + p = (FT_Byte*)stream->cursor; + + for ( ; (FT_Short)count >= 0; count-- ) + { + poff[0] = cff_get_offset( p, offsize ); + poff++; + p += offsize; + } + + FT_FRAME_EXIT(); + + idx->data_offset = FT_STREAM_POS(); + data_size = poff[-1] - 1; + + if ( load ) + { + /* load the data */ + if ( FT_FRAME_EXTRACT( data_size, idx->bytes ) ) + goto Exit; + } + else + { + /* skip the data */ + if ( FT_STREAM_SKIP( data_size ) ) + goto Exit; + } + } + + Exit: + if ( error ) + FT_FREE( idx->offsets ); + + return error; + } + + + static void + cff_done_index( CFF_Index idx ) + { + if ( idx->stream ) + { + FT_Stream stream = idx->stream; + FT_Memory memory = stream->memory; + + + if ( idx->bytes ) + FT_FRAME_RELEASE( idx->bytes ); + + FT_FREE( idx->offsets ); + FT_MEM_ZERO( idx, sizeof ( *idx ) ); + } + } + + + /* allocate a table containing pointers to an index's elements */ + static FT_Error + cff_index_get_pointers( CFF_Index idx, + FT_Byte*** table ) + { + FT_Error error = 0; + FT_Memory memory = idx->stream->memory; + FT_ULong n, offset, old_offset; + FT_Byte** t; + + + *table = 0; + + if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) ) + { + old_offset = 1; + for ( n = 0; n <= idx->count; n++ ) + { + offset = idx->offsets[n]; + if ( !offset ) + offset = old_offset; + + t[n] = idx->bytes + offset - 1; + + old_offset = offset; + } + *table = t; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ) + { + FT_Error error = 0; + + + if ( idx && idx->count > element ) + { + /* compute start and end offsets */ + FT_ULong off1, off2 = 0; + + + off1 = idx->offsets[element]; + if ( off1 ) + { + do + { + element++; + off2 = idx->offsets[element]; + + } while ( off2 == 0 && element < idx->count ); + + if ( !off2 ) + off1 = 0; + } + + /* access element */ + if ( off1 ) + { + *pbyte_len = off2 - off1; + + if ( idx->bytes ) + { + /* this index was completely loaded in memory, that's easy */ + *pbytes = idx->bytes + off1 - 1; + } + else + { + /* this index is still on disk/file, access it through a frame */ + FT_Stream stream = idx->stream; + + + if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || + FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) + goto Exit; + } + } + else + { + /* empty index element */ + *pbytes = 0; + *pbyte_len = 0; + } + } + else + error = CFF_Err_Invalid_Argument; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ) + { + if ( idx->bytes == 0 ) + { + FT_Stream stream = idx->stream; + + + FT_FRAME_RELEASE( *pbytes ); + } + } + + + FT_LOCAL_DEF( FT_String* ) + cff_index_get_name( CFF_Index idx, + FT_UInt element ) + { + FT_Memory memory = idx->stream->memory; + FT_Byte* bytes; + FT_ULong byte_len; + FT_Error error; + FT_String* name = 0; + + + error = cff_index_access_element( idx, element, &bytes, &byte_len ); + if ( error ) + goto Exit; + + if ( !FT_ALLOC( name, byte_len + 1 ) ) + { + FT_MEM_COPY( name, bytes, byte_len ); + name[byte_len] = 0; + } + cff_index_forget_element( idx, &bytes ); + + Exit: + return name; + } + + + FT_LOCAL_DEF( FT_String* ) + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + PSNames_Service psnames_service ) + { + /* if it is not a standard string, return it */ + if ( sid > 390 ) + return cff_index_get_name( idx, sid - 391 ); + + /* that's a standard string, fetch a copy from the PSName module */ + { + FT_String* name = 0; + const char* adobe_name = psnames_service->adobe_std_strings( sid ); + FT_UInt len; + + + if ( adobe_name ) + { + FT_Memory memory = idx->stream->memory; + FT_Error error; + + + len = (FT_UInt)ft_strlen( adobe_name ); + if ( !FT_ALLOC( name, len + 1 ) ) + { + FT_MEM_COPY( name, adobe_name, len ); + name[len] = 0; + } + + FT_UNUSED( error ); + } + + return name; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** FD Select table support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + + static void + CFF_Done_FD_Select( CFF_FDSelect fdselect, + FT_Stream stream ) + { + if ( fdselect->data ) + FT_FRAME_RELEASE( fdselect->data ); + + fdselect->data_size = 0; + fdselect->format = 0; + fdselect->range_count = 0; + } + + + static FT_Error + CFF_Load_FD_Select( CFF_FDSelect fdselect, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong offset ) + { + FT_Error error; + FT_Byte format; + FT_UInt num_ranges; + + + /* read format */ + if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) + goto Exit; + + fdselect->format = format; + fdselect->cache_count = 0; /* clear cache */ + + switch ( format ) + { + case 0: /* format 0, that's simple */ + fdselect->data_size = num_glyphs; + goto Load_Data; + + case 3: /* format 3, a tad more complex */ + if ( FT_READ_USHORT( num_ranges ) ) + goto Exit; + + fdselect->data_size = num_ranges * 3 + 2; + + Load_Data: + if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) + goto Exit; + break; + + default: /* hmm... that's wrong */ + error = CFF_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Byte ) + cff_fd_select_get( CFF_FDSelect fdselect, + FT_UInt glyph_index ) + { + FT_Byte fd = 0; + + + switch ( fdselect->format ) + { + case 0: + fd = fdselect->data[glyph_index]; + break; + + case 3: + /* first, compare to cache */ + if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < + fdselect->cache_count ) + { + fd = fdselect->cache_fd; + break; + } + + /* then, lookup the ranges array */ + { + FT_Byte* p = fdselect->data; + FT_Byte* p_limit = p + fdselect->data_size; + FT_Byte fd2; + FT_UInt first, limit; + + + first = FT_NEXT_USHORT( p ); + do + { + if ( glyph_index < first ) + break; + + fd2 = *p++; + limit = FT_NEXT_USHORT( p ); + + if ( glyph_index < limit ) + { + fd = fd2; + + /* update cache */ + fdselect->cache_first = first; + fdselect->cache_count = limit-first; + fdselect->cache_fd = fd2; + break; + } + first = limit; + + } while ( p < p_limit ); + } + break; + + default: + ; + } + + return fd; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** CFF font support ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + + static void + cff_charset_done( CFF_Charset charset, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( charset->sids ); + charset->format = 0; + charset->offset = 0; + } + + + static FT_Error + cff_charset_load( CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Memory memory = stream->memory; + FT_Error error = 0; + FT_UShort glyph_sid; + + + /* If the the offset is greater than 2, we have to parse the */ + /* charset table. */ + if ( offset > 2 ) + { + FT_UInt j; + + + charset->offset = base_offset + offset; + + /* Get the format of the table. */ + if ( FT_STREAM_SEEK( charset->offset ) || + FT_READ_BYTE( charset->format ) ) + goto Exit; + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* assign the .notdef glyph */ + charset->sids[0] = 0; + + switch ( charset->format ) + { + case 0: + if ( num_glyphs > 0 ) + { + if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) + goto Exit; + + for ( j = 1; j < num_glyphs; j++ ) + charset->sids[j] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + } + break; + + case 1: + case 2: + { + FT_UInt nleft; + FT_UInt i; + + + j = 1; + + while ( j < num_glyphs ) + { + + /* Read the first glyph sid of the range. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Read the number of glyphs in the range. */ + if ( charset->format == 2 ) + { + if ( FT_READ_USHORT( nleft ) ) + goto Exit; + } + else + { + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + } + + /* Fill in the range of sids -- `nleft + 1' glyphs. */ + for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) + charset->sids[j] = glyph_sid; + } + } + break; + + default: + FT_ERROR(( "cff_charset_load: invalid table format!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + else + { + /* Parse default tables corresponding to offset == 0, 1, or 2. */ + /* CFF specification intimates the following: */ + /* */ + /* In order to use a predefined charset, the following must be */ + /* true: The charset constructed for the glyphs in the font's */ + /* charstrings dictionary must match the predefined charset in */ + /* the first num_glyphs */ + + charset->offset = offset; /* record charset type */ + + switch ( (FT_UInt)offset ) + { + case 0: + if ( num_glyphs > 229 ) + { + FT_ERROR(("cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe ISO-Latin)!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_MEM_COPY( charset->sids, cff_isoadobe_charset, + num_glyphs * sizeof ( FT_UShort ) ); + + break; + + case 1: + if ( num_glyphs > 166 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert)!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_MEM_COPY( charset->sids, cff_expert_charset, + num_glyphs * sizeof ( FT_UShort ) ); + + break; + + case 2: + if ( num_glyphs > 87 ) + { + FT_ERROR(( "cff_charset_load: implicit charset larger than\n" + "predefined charset (Adobe Expert Subset)!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Allocate memory for sids. */ + if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) + goto Exit; + + /* Copy the predefined charset into the allocated memory. */ + FT_MEM_COPY( charset->sids, cff_expertsubset_charset, + num_glyphs * sizeof ( FT_UShort ) ); + + break; + + default: + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + + Exit: + + /* Clean up if there was an error. */ + if ( error ) + if ( charset->sids ) + { + FT_FREE( charset->sids ); + charset->format = 0; + charset->offset = 0; + charset->sids = 0; + } + + return error; + } + + + + static void + cff_encoding_done( CFF_Encoding encoding ) + { + encoding->format = 0; + encoding->offset = 0; + encoding->count = 0; + } + + + + static FT_Error + cff_encoding_load( CFF_Encoding encoding, + CFF_Charset charset, + FT_UInt num_glyphs, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Error error = 0; + FT_UInt count; + FT_UInt j; + FT_UShort glyph_sid; + FT_UInt glyph_code; + + + /* Check for charset->sids. If we do not have this, we fail. */ + if ( !charset->sids ) + { + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Zero out the code to gid/sid mappings. */ + for ( j = 0; j < 256; j++ ) + { + encoding->sids [j] = 0; + encoding->codes[j] = 0; + } + + /* Note: The encoding table in a CFF font is indexed by glyph index, */ + /* where the first encoded glyph index is 1. Hence, we read the char */ + /* code (`glyph_code') at index j and make the assignment: */ + /* */ + /* encoding->codes[glyph_code] = j + 1 */ + /* */ + /* We also make the assignment: */ + /* */ + /* encoding->sids[glyph_code] = charset->sids[j + 1] */ + /* */ + /* This gives us both a code to GID and a code to SID mapping. */ + + if ( offset > 1 ) + { + + encoding->offset = base_offset + offset; + + /* we need to parse the table to determine its size */ + if ( FT_STREAM_SEEK( encoding->offset ) || + FT_READ_BYTE( encoding->format ) || + FT_READ_BYTE( count ) ) + goto Exit; + + switch ( encoding->format & 0x7F ) + { + case 0: + { + FT_Byte* p; + + /* by convention, GID 0 is always ".notdef" and is never */ + /* coded in the font. Hence, the number of codes found */ + /* in the table is 'count+1' */ + /* */ + encoding->count = count + 1; + + if ( FT_FRAME_ENTER( count ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + + for ( j = 1; j <= count; j++ ) + { + glyph_code = *p++; + + /* Make sure j is not too big. */ + if ( j < num_glyphs ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)j; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[j]; + } + } + + FT_FRAME_EXIT(); + } + break; + + case 1: + { + FT_Byte nleft; + FT_UInt i = 1; + FT_UInt k; + + + encoding->count = 0; + + /* Parse the Format1 ranges. */ + for ( j = 0; j < count; j++, i += nleft ) + { + /* Read the first glyph code of the range. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the number of codes in the range. */ + if ( FT_READ_BYTE( nleft ) ) + goto Exit; + + /* Increment nleft, so we read `nleft + 1' codes/sids. */ + nleft++; + + /* compute max number of character codes */ + if ( (FT_UInt)nleft > encoding->count ) + encoding->count = nleft; + + /* Fill in the range of codes/sids. */ + for ( k = i; k < nleft + i; k++, glyph_code++ ) + { + /* Make sure k is not too big. */ + if ( k < num_glyphs && glyph_code < 256 ) + { + /* Assign code to GID mapping. */ + encoding->codes[glyph_code] = (FT_UShort)k; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = charset->sids[k]; + } + } + } + + /* simple check, one never knows what can be found in a font */ + if ( encoding->count > 256 ) + encoding->count = 256; + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + + /* Parse supplemental encodings, if any. */ + if ( encoding->format & 0x80 ) + { + FT_UInt gindex; + + + /* count supplements */ + if ( FT_READ_BYTE( count ) ) + goto Exit; + + for ( j = 0; j < count; j++ ) + { + /* Read supplemental glyph code. */ + if ( FT_READ_BYTE( glyph_code ) ) + goto Exit; + + /* Read the SID associated with this glyph code. */ + if ( FT_READ_USHORT( glyph_sid ) ) + goto Exit; + + /* Assign code to SID mapping. */ + encoding->sids[glyph_code] = glyph_sid; + + /* First, lookup GID which has been assigned to */ + /* SID glyph_sid. */ + for ( gindex = 0; gindex < num_glyphs; gindex++ ) + { + if ( charset->sids[gindex] == glyph_sid ) + { + encoding->codes[glyph_code] = (FT_UShort) gindex; + break; + } + } + } + } + } + else + { + FT_UInt i; + + + /* We take into account the fact a CFF font can use a predefined */ + /* encoding without containing all of the glyphs encoded by this */ + /* encoding (see the note at the end of section 12 in the CFF */ + /* specification). */ + + switch ( (FT_UInt)offset ) + { + case 0: + /* First, copy the code to SID mapping. */ + FT_MEM_COPY( encoding->sids, cff_standard_encoding, + 256 * sizeof ( FT_UShort ) ); + + goto Populate; + + case 1: + /* First, copy the code to SID mapping. */ + FT_MEM_COPY( encoding->sids, cff_expert_encoding, + 256 * sizeof ( FT_UShort ) ); + + Populate: + /* Construct code to GID mapping from code to SID mapping */ + /* and charset. */ + + encoding->count = 0; + + + for ( j = 0; j < 256; j++ ) + { + /* If j is encoded, find the GID for it. */ + if ( encoding->sids[j] ) + { + for ( i = 1; i < num_glyphs; i++ ) + /* We matched, so break. */ + if ( charset->sids[i] == encoding->sids[j] ) + break; + + /* i will be equal to num_glyphs if we exited the above */ + /* loop without a match. In this case, we also have to */ + /* fix the code to SID mapping. */ + if ( i == num_glyphs ) + { + encoding->codes[j] = 0; + encoding->sids [j] = 0; + } + else + { + encoding->codes[j] = (FT_UShort)i; + + /* update encoding count */ + if ( encoding->count < j+1 ) + encoding->count = j+1; + } + } + } + break; + + default: + FT_ERROR(( "cff_encoding_load: invalid table format!\n" )); + error = CFF_Err_Invalid_File_Format; + goto Exit; + } + } + + Exit: + + /* Clean up if there was an error. */ + return error; + } + + + static FT_Error + cff_subfont_load( CFF_SubFont font, + CFF_Index idx, + FT_UInt font_index, + FT_Stream stream, + FT_ULong base_offset ) + { + FT_Error error; + CFF_ParserRec parser; + FT_Byte* dict; + FT_ULong dict_len; + CFF_FontRecDict top = &font->font_dict; + CFF_Private priv = &font->private_dict; + + + cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict ); + + /* set defaults */ + FT_MEM_ZERO( top, sizeof ( *top ) ); + + top->underline_position = -100; + top->underline_thickness = 50; + top->charstring_type = 2; + top->font_matrix.xx = 0x10000L; + top->font_matrix.yy = 0x10000L; + top->cid_count = 8720; + + error = cff_index_access_element( idx, font_index, &dict, &dict_len ) || + cff_parser_run( &parser, dict, dict + dict_len ); + + cff_index_forget_element( idx, &dict ); + + if ( error ) + goto Exit; + + /* if it is a CID font, we stop there */ + if ( top->cid_registry ) + goto Exit; + + /* parse the private dictionary, if any */ + if ( top->private_offset && top->private_size ) + { + /* set defaults */ + FT_MEM_ZERO( priv, sizeof ( *priv ) ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L; + priv->blue_scale = (FT_Fixed)0.039625 * 0x10000L; + + cff_parser_init( &parser, CFF_CODE_PRIVATE, priv ); + + if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || + FT_FRAME_ENTER( font->font_dict.private_size ) ) + goto Exit; + + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + } + + /* read the local subrs, if any */ + if ( priv->local_subrs_offset ) + { + if ( FT_STREAM_SEEK( base_offset + top->private_offset + + priv->local_subrs_offset ) ) + goto Exit; + + error = cff_new_index( &font->local_subrs_index, stream, 1 ); + if ( error ) + goto Exit; + + font->num_local_subrs = font->local_subrs_index.count; + error = cff_index_get_pointers( &font->local_subrs_index, + &font->local_subrs ); + if ( error ) + goto Exit; + } + + Exit: + return error; + } + + + static void + cff_subfont_done( FT_Memory memory, + CFF_SubFont subfont ) + { + if ( subfont ) + { + cff_done_index( &subfont->local_subrs_index ); + FT_FREE( subfont->local_subrs ); + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_font_load( FT_Stream stream, + FT_Int face_index, + CFF_Font font ) + { + static const FT_Frame_Field cff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRec + + FT_FRAME_START( 4 ), + FT_FRAME_BYTE( version_major ), + FT_FRAME_BYTE( version_minor ), + FT_FRAME_BYTE( header_size ), + FT_FRAME_BYTE( absolute_offsize ), + FT_FRAME_END + }; + + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong base_offset; + CFF_FontRecDict dict; + + FT_ZERO( font ); + + font->stream = stream; + font->memory = memory; + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + + /* read CFF font header */ + if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) + goto Exit; + + /* check format */ + if ( font->version_major != 1 || + font->header_size < 4 || + font->absolute_offsize > 4 ) + { + FT_TRACE2(( "[not a CFF font header!]\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + /* skip the rest of the header */ + if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + goto Exit; + + /* read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_new_index( &font->name_index, stream, 0 )) || + FT_SET_ERROR( cff_new_index( &font->font_dict_index, stream, 0 )) || + FT_SET_ERROR( cff_new_index( &font->string_index, stream, 0 )) || + FT_SET_ERROR( cff_new_index( &font->global_subrs_index, stream, 1 )) ) + goto Exit; + + /* well, we don't really forget the `disabled' fonts... */ + font->num_faces = font->name_index.count; + if ( face_index >= (FT_Int)font->num_faces ) + { + FT_ERROR(( "cff_font_load: incorrect face index = %d\n", + face_index )); + error = CFF_Err_Invalid_Argument; + } + + /* in case of a font format check, simply exit now */ + if ( face_index < 0 ) + goto Exit; + + /* now, parse the top-level font dictionary */ + error = cff_subfont_load( &font->top_font, + &font->font_dict_index, + face_index, + stream, + base_offset ); + if ( error ) + goto Exit; + + /* now, check for a CID font */ + if ( dict->cid_registry ) + { + CFF_IndexRec fd_index; + CFF_SubFont sub; + FT_UInt idx; + + + /* this is a CID-keyed font, we must now allocate a table of */ + /* sub-fonts, then load each of them separately */ + if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) + goto Exit; + + error = cff_new_index( &fd_index, stream, 0 ); + if ( error ) + goto Exit; + + if ( fd_index.count > CFF_MAX_CID_FONTS ) + { + FT_ERROR(( "cff_font_load: FD array too large in CID font\n" )); + goto Fail_CID; + } + + /* allocate & read each font dict independently */ + font->num_subfonts = fd_index.count; + if ( FT_NEW_ARRAY( sub, fd_index.count ) ) + goto Fail_CID; + + /* setup pointer table */ + for ( idx = 0; idx < fd_index.count; idx++ ) + font->subfonts[idx] = sub + idx; + + /* now load each sub font independently */ + for ( idx = 0; idx < fd_index.count; idx++ ) + { + sub = font->subfonts[idx]; + error = cff_subfont_load( sub, &fd_index, idx, + stream, base_offset ); + if ( error ) + goto Fail_CID; + } + + /* now load the FD Select array */ + error = CFF_Load_FD_Select( &font->fd_select, + (FT_UInt)dict->cid_count, + stream, + base_offset + dict->cid_fd_select_offset ); + + Fail_CID: + cff_done_index( &fd_index ); + + if ( error ) + goto Exit; + } + else + font->num_subfonts = 0; + + /* read the charstrings index now */ + if ( dict->charstrings_offset == 0 ) + { + FT_ERROR(( "cff_font_load: no charstrings offset!\n" )); + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) + goto Exit; + + error = cff_new_index( &font->charstrings_index, stream, 0 ); + if ( error ) + goto Exit; + + /* explicit the global subrs */ + font->num_global_subrs = font->global_subrs_index.count; + font->num_glyphs = font->charstrings_index.count; + + error = cff_index_get_pointers( &font->global_subrs_index, + &font->global_subrs ) ; + + if ( error ) + goto Exit; + + /* read the Charset and Encoding tables when available */ + if ( font->num_glyphs > 0 ) + { + error = cff_charset_load( &font->charset, font->num_glyphs, stream, + base_offset, dict->charset_offset ); + if ( error ) + goto Exit; + + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } + + /* get the font name */ + font->font_name = cff_index_get_name( &font->name_index, face_index ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_font_done( CFF_Font font ) + { + FT_Memory memory = font->memory; + FT_UInt idx; + + + cff_done_index( &font->global_subrs_index ); + cff_done_index( &font->string_index ); + cff_done_index( &font->font_dict_index ); + cff_done_index( &font->name_index ); + cff_done_index( &font->charstrings_index ); + + /* release font dictionaries, but only if working with */ + /* a CID keyed CFF font */ + if ( font->num_subfonts > 0 ) + { + for ( idx = 0; idx < font->num_subfonts; idx++ ) + cff_subfont_done( memory, font->subfonts[idx] ); + + FT_FREE( font->subfonts ); + } + + cff_encoding_done( &font->encoding ); + cff_charset_done( &font->charset, font->stream ); + + cff_subfont_done( memory, &font->top_font ); + + CFF_Done_FD_Select( &font->fd_select, font->stream ); + + FT_FREE( font->global_subrs ); + FT_FREE( font->font_name ); + } + + +/* END */ diff --git a/lib/freetype/src/cff/cffload.h b/lib/freetype/src/cff/cffload.h new file mode 100644 index 0000000..4cadfe6 --- /dev/null +++ b/lib/freetype/src/cff/cffload.h @@ -0,0 +1,74 @@ +/***************************************************************************/ +/* */ +/* cffload.h */ +/* */ +/* OpenType & CFF data/program tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFLOAD_H__ +#define __CFFLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_CFF_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + + +FT_BEGIN_HEADER + + FT_LOCAL( FT_UShort ) + cff_get_standard_encoding( FT_UInt charcode ); + + + FT_LOCAL( FT_String* ) + cff_index_get_name( CFF_Index idx, + FT_UInt element ); + + FT_LOCAL( FT_String* ) + cff_index_get_sid_string( CFF_Index idx, + FT_UInt sid, + PSNames_Service psnames_interface ); + + + FT_LOCAL( FT_Error ) + cff_index_access_element( CFF_Index idx, + FT_UInt element, + FT_Byte** pbytes, + FT_ULong* pbyte_len ); + + FT_LOCAL( void ) + cff_index_forget_element( CFF_Index idx, + FT_Byte** pbytes ); + + + FT_LOCAL( FT_Error ) + cff_font_load( FT_Stream stream, + FT_Int face_index, + CFF_Font font ); + + FT_LOCAL( void ) + cff_font_done( CFF_Font font ); + + + FT_LOCAL( FT_Byte ) + cff_fd_select_get( CFF_FDSelect select, + FT_UInt glyph_index ); + + +FT_END_HEADER + +#endif /* __CFFLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cffobjs.c b/lib/freetype/src/cff/cffobjs.c new file mode 100644 index 0000000..830f462 --- /dev/null +++ b/lib/freetype/src/cff/cffobjs.c @@ -0,0 +1,575 @@ +/***************************************************************************/ +/* */ +/* cffobjs.c */ +/* */ +/* OpenType objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_ERRORS_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include "cffobjs.h" +#include "cffload.h" +#include "cffcmap.h" +#include "cfferrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffobjs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* Note that we store the global hints in the size's "internal" root */ + /* field. */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cff_size_get_globals_funcs( CFF_Size size ) + { + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_FontRec *)face->extra.data; + PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cff_size_done( CFF_Size size ) + { + if ( size->internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cff_size_get_globals_funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)size->internal ); + + size->internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_size_init( CFF_Size size ) + { + FT_Error error = 0; + PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + CFF_Face face = (CFF_Face)size->face; + CFF_Font font = (CFF_FontRec *)face->extra.data; + CFF_SubFont subfont = &font->top_font; + + CFF_Private cpriv = &subfont->private_dict; + PS_PrivateRec priv; + + + /* IMPORTANT: The CFF and Type1 private dictionaries have */ + /* slightly different structures; we need to */ + /* synthetize a type1 dictionary on the fly here. */ + + { + FT_UInt n, count; + + + FT_MEM_ZERO( &priv, sizeof ( priv ) ); + + count = priv.num_blue_values = cpriv->num_blue_values; + for ( n = 0; n < count; n++ ) + priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; + + count = priv.num_other_blues = cpriv->num_other_blues; + for ( n = 0; n < count; n++ ) + priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; + + count = priv.num_family_blues = cpriv->num_family_blues; + for ( n = 0; n < count; n++ ) + priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; + + count = priv.num_family_other_blues = cpriv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; + + priv.blue_scale = cpriv->blue_scale; + priv.blue_shift = (FT_Int)cpriv->blue_shift; + priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; + + priv.standard_width[0] = (FT_UShort)cpriv->standard_width; + priv.standard_height[0] = (FT_UShort)cpriv->standard_height; + + count = priv.num_snap_widths = cpriv->num_snap_widths; + for ( n = 0; n < count; n++ ) + priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; + + count = priv.num_snap_heights = cpriv->num_snap_heights; + for ( n = 0; n < count; n++ ) + priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; + + priv.force_bold = cpriv->force_bold; + priv.language_group = cpriv->language_group; + priv.lenIV = cpriv->lenIV; + } + + error = funcs->create( size->face->memory, &priv, &globals ); + if ( !error ) + size->internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_size_reset( CFF_Size size ) + { + PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); + FT_Error error = 0; + + + if ( funcs ) + error = funcs->set_scale( (PSH_Globals)size->internal, + size->metrics.x_scale, + size->metrics.y_scale, + 0, 0 ); + return error; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cff_slot_done( CFF_GlyphSlot slot ) + { + slot->root.internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cff_slot_init( CFF_GlyphSlot slot ) + { + CFF_Face face = (CFF_Face)slot->root.face; + CFF_Font font = (CFF_FontRec *)face->extra.data; + PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; + + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->root.face->driver->root.library, + "pshinter" ); + if ( module ) + { + T2_Hints_Funcs funcs; + + + funcs = pshinter->get_t2_funcs( module ); + slot->root.internal->glyph_hints = (void*)funcs; + } + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + static FT_String* + cff_strcpy( FT_Memory memory, + const FT_String* source ) + { + FT_Error error; + FT_String* result = 0; + FT_Int len = (FT_Int)ft_strlen( source ); + + + if ( !FT_ALLOC( result, len + 1 ) ) + { + FT_MEM_COPY( result, source, len ); + result[len] = 0; + } + + FT_UNUSED( error ); + + return result; + } + + + + + FT_LOCAL_DEF( FT_Error ) + cff_face_init( FT_Stream stream, + CFF_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + SFNT_Service sfnt; + PSNames_Service psnames; + PSHinter_Service pshinter; + FT_Bool pure_cff = 1; + FT_Bool sfnt_format = 0; + + + sfnt = (SFNT_Service)FT_Get_Module_Interface( + face->root.driver->root.library, "sfnt" ); + if ( !sfnt ) + goto Bad_Format; + + psnames = (PSNames_Service)FT_Get_Module_Interface( + face->root.driver->root.library, "psnames" ); + + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + face->root.driver->root.library, "pshinter" ); + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check that we have a valid OpenType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( !error ) + { + if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ + { + FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); + goto Bad_Format; + } + + /* if we are performing a simple font format check, exit immediately */ + if ( face_index < 0 ) + return CFF_Err_Ok; + + sfnt_format = 1; + + /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ + /* font in the later case; it doesn't have a `head' table */ + error = face->goto_table( face, TTAG_head, stream, 0 ); + if ( !error ) + { + pure_cff = 0; + + /* load font directory */ + error = sfnt->load_face( stream, face, + face_index, num_params, params ); + if ( error ) + goto Exit; + } + else + { + /* load the `cmap' table by hand */ + error = sfnt->load_charmaps( face, stream ); + if ( error ) + goto Exit; + + /* XXX: we don't load the GPOS table, as OpenType Layout */ + /* support will be added later to a layout library on top of */ + /* FreeType 2 */ + } + + /* now, load the CFF part of the file */ + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) + goto Exit; + } + else + { + /* rewind to start of file; we are going to load a pure-CFF font */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + error = CFF_Err_Ok; + } + + /* now load and parse the CFF table in the file */ + { + CFF_Font cff; + FT_Memory memory = face->root.memory; + FT_Face root; + FT_Int32 flags; + + + if ( FT_NEW( cff ) ) + goto Exit; + + face->extra.data = cff; + error = cff_font_load( stream, face_index, cff ); + if ( error ) + goto Exit; + + cff->pshinter = pshinter; + cff->psnames = psnames; + + /* Complement the root flags with some interesting information. */ + /* Note that this is only necessary for pure CFF and CEF fonts. */ + + root = &face->root; + root->num_glyphs = cff->num_glyphs; + + if ( pure_cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + /* we need the `PSNames' module for pure-CFF and CEF formats */ + if ( !psnames ) + { + FT_ERROR(( "cff_face_init:" )); + FT_ERROR(( " cannot open CFF & CEF fonts\n" )); + FT_ERROR(( " " )); + FT_ERROR(( " without the `PSNames' module\n" )); + goto Bad_Format; + } + + /* Set up num_faces. */ + root->num_faces = cff->num_faces; + + /* compute number of glyphs */ + if ( dict->cid_registry ) + root->num_glyphs = dict->cid_count; + else + root->num_glyphs = cff->charstrings_index.count; + + /* set global bbox, as well as EM size */ + root->bbox.xMin = dict->font_bbox.xMin >> 16; + root->bbox.yMin = dict->font_bbox.yMin >> 16; + root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; + + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + root->height = (FT_Short)( + ( ( root->ascender - root->descender ) * 12 ) / 10 ); + + if ( dict->units_per_em ) + root->units_per_EM = dict->units_per_em; + else + root->units_per_EM = 1000; + + /* retrieve font family & style name */ + root->family_name = cff_index_get_name( &cff->name_index, face_index ); + if ( dict->cid_registry ) + root->style_name = cff_strcpy( memory, "Regular" ); /* XXXX */ + else + root->style_name = cff_index_get_sid_string( &cff->string_index, + dict->weight, + psnames ); + + /*******************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ + FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ + + if ( sfnt_format ) + flags |= FT_FACE_FLAG_SFNT; + + /* fixed width font? */ + if ( dict->is_fixed_pitch ) + flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ +#if 0 + /* kerning available? */ + if ( face->kern_pairs ) + flags |= FT_FACE_FLAG_KERNING; +#endif + +#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES + flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + root->face_flags = flags; + + /*******************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + flags = 0; + + if ( dict->italic_angle ) + flags |= FT_STYLE_FLAG_ITALIC; + + /* XXX: may not be correct */ + if ( cff->top_font.private_dict.force_bold ) + flags |= FT_STYLE_FLAG_BOLD; + + root->style_flags = flags; + } + + /*******************************************************************/ + /* */ + /* Compute char maps. */ + /* */ + + /* Try to synthetize a Unicode charmap if there is none available */ + /* already. If an OpenType font contains a Unicode "cmap", we */ + /* will use it, whatever be in the CFF part of the file. */ + { + FT_CharMapRec cmaprec; + FT_CharMap cmap; + FT_UInt nn; + CFF_Encoding encoding = &cff->encoding; + + + for ( nn = 0; nn < (FT_UInt) root->num_charmaps; nn++ ) + { + cmap = root->charmaps[nn]; + + /* Windows Unicode (3,1)? */ + if ( cmap->platform_id == 3 && cmap->encoding_id == 1 ) + goto Skip_Unicode; + + /* Deprecated Unicode platform id? */ + if ( cmap->platform_id == 0 ) + goto Skip_Unicode; /* Standard Unicode (deprecated) */ + } + + /* we didn't find a Unicode charmap, synthetize one */ + cmaprec.face = root; + cmaprec.platform_id = 3; + cmaprec.encoding_id = 1; + cmaprec.encoding = FT_ENCODING_UNICODE; + + nn = (FT_UInt) root->num_charmaps; + + FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); + + /* if no Unicode charmap was previously selected, select this one */ + if ( root->charmap == NULL && nn != (FT_UInt) root->num_charmaps ) + root->charmap = root->charmaps[nn]; + + Skip_Unicode: + if ( encoding->count > 0 ) + { + FT_CMap_Class clazz; + + + cmaprec.face = root; + cmaprec.platform_id = 7; /* Adobe platform id */ + + if ( encoding->offset == 0 ) + { + cmaprec.encoding_id = 0; + cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; + clazz = &cff_cmap_encoding_class_rec; + } + else if ( encoding->offset == 1 ) + { + cmaprec.encoding_id = 1; + cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; + clazz = &cff_cmap_encoding_class_rec; + } + else + { + cmaprec.encoding_id = 3; + cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; + clazz = &cff_cmap_encoding_class_rec; + } + + FT_CMap_New( clazz, NULL, &cmaprec, NULL ); + } + + } + } + + Exit: + return error; + + Bad_Format: + error = CFF_Err_Unknown_File_Format; + goto Exit; + } + + + FT_LOCAL_DEF( void ) + cff_face_done( CFF_Face face ) + { + FT_Memory memory = face->root.memory; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + if ( sfnt ) + sfnt->done_face( face ); + + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + if ( cff ) + { + cff_font_done( cff ); + FT_FREE( face->extra.data ); + } + } + } + + + FT_LOCAL_DEF( FT_Error ) + cff_driver_init( CFF_Driver driver ) + { + FT_UNUSED( driver ); + + return CFF_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + cff_driver_done( CFF_Driver driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/lib/freetype/src/cff/cffobjs.h b/lib/freetype/src/cff/cffobjs.h new file mode 100644 index 0000000..cf60ecf --- /dev/null +++ b/lib/freetype/src/cff/cffobjs.h @@ -0,0 +1,160 @@ +/***************************************************************************/ +/* */ +/* cffobjs.h */ +/* */ +/* OpenType objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFFOBJS_H__ +#define __CFFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CFF_TYPES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Driver */ + /* */ + /* <Description> */ + /* A handle to an OpenType driver object. */ + /* */ + typedef struct CFF_DriverRec_* CFF_Driver; + + typedef TT_Face CFF_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Size */ + /* */ + /* <Description> */ + /* A handle to an OpenType size object. */ + /* */ + typedef FT_Size CFF_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to an OpenType glyph slot object. */ + /* */ + typedef struct CFF_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CFF_GlyphSlotRec, *CFF_GlyphSlot; + + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct CFF_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } CFF_Transform; + + + /* this is only used in the case of a pure CFF font with no charmap */ + typedef struct CFF_CharMapRec_ + { + TT_CharMapRec root; + PS_Unicodes unicodes; + + } CFF_CharMapRec, *CFF_CharMap; + + + /***********************************************************************/ + /* */ + /* TrueType driver class. */ + /* */ + typedef struct CFF_DriverRec_ + { + FT_DriverRec root; + void* extension_component; + + } CFF_DriverRec; + + + FT_LOCAL( FT_Error ) + cff_size_init( CFF_Size size ); + + FT_LOCAL( void ) + cff_size_done( CFF_Size size ); + + FT_LOCAL( FT_Error ) + cff_size_reset( CFF_Size size ); + + FT_LOCAL( void ) + cff_slot_done( CFF_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cff_slot_init( CFF_GlyphSlot slot ); + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_face_init( FT_Stream stream, + CFF_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + cff_face_done( CFF_Face face ); + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + cff_driver_init( CFF_Driver driver ); + + FT_LOCAL( void ) + cff_driver_done( CFF_Driver driver ); + + +FT_END_HEADER + +#endif /* __CFFOBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cffparse.c b/lib/freetype/src/cff/cffparse.c new file mode 100644 index 0000000..3e1f840 --- /dev/null +++ b/lib/freetype/src/cff/cffparse.c @@ -0,0 +1,681 @@ +/***************************************************************************/ +/* */ +/* cffparse.c */ +/* */ +/* CFF token stream parser (body) */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include "cffparse.h" +#include FT_INTERNAL_STREAM_H + +#include "cfferrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffparse + + + enum + { + cff_kind_none = 0, + cff_kind_num, + cff_kind_fixed, + cff_kind_string, + cff_kind_bool, + cff_kind_delta, + cff_kind_callback, + + cff_kind_max /* do not remove */ + }; + + + /* now generate handlers for the most simple fields */ + typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); + + typedef struct CFF_Field_Handler_ + { + int kind; + int code; + FT_UInt offset; + FT_Byte size; + CFF_Field_Reader reader; + FT_UInt array_max; + FT_UInt count_offset; + + } CFF_Field_Handler; + + + FT_LOCAL_DEF( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object ) + { + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + + parser->top = parser->stack; + parser->object_code = code; + parser->object = object; + } + + + /* read an integer */ + static FT_Long + cff_parse_integer( FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Int v = *p++; + FT_Long val = 0; + + + if ( v == 28 ) + { + if ( p + 2 > limit ) + goto Bad; + + val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] ); + p += 2; + } + else if ( v == 29 ) + { + if ( p + 4 > limit ) + goto Bad; + + val = ( (FT_Long)p[0] << 24 ) | + ( (FT_Long)p[1] << 16 ) | + ( (FT_Long)p[2] << 8 ) | + p[3]; + p += 4; + } + else if ( v < 247 ) + { + val = v - 139; + } + else if ( v < 251 ) + { + if ( p + 1 > limit ) + goto Bad; + + val = ( v - 247 ) * 256 + p[0] + 108; + p++; + } + else + { + if ( p + 1 > limit ) + goto Bad; + + val = -( v - 251 ) * 256 - p[0] - 108; + p++; + } + + Exit: + return val; + + Bad: + val = 0; + goto Exit; + } + + + /* read a real */ + static FT_Fixed + cff_parse_real( FT_Byte* start, + FT_Byte* limit, + FT_Int power_ten ) + { + FT_Byte* p = start; + FT_Long num, divider, result, exp; + FT_Int sign = 0, exp_sign = 0; + FT_UInt nib; + FT_UInt phase; + + + result = 0; + num = 0; + divider = 1; + + /* first of all, read the integer part */ + phase = 4; + + for (;;) + { + /* If we entered this iteration with phase == 4, we need to */ + /* read a new byte. This also skips past the intial 0x1E. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + + if ( nib == 0xE ) + sign = 1; + else if ( nib > 9 ) + break; + else + result = result * 10 + nib; + } + + /* read decimal part, if any */ + if ( nib == 0xa ) + for (;;) + { + /* If we entered this iteration with phase == 4, we need */ + /* to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + if ( divider < 10000000L ) + { + num = num * 10 + nib; + divider *= 10; + } + } + + /* read exponent, if any */ + if ( nib == 12 ) + { + exp_sign = 1; + nib = 11; + } + + if ( nib == 11 ) + { + exp = 0; + + for (;;) + { + /* If we entered this iteration with phase == 4, we need */ + /* to read a new byte. */ + if ( phase ) + { + p++; + + /* Make sure we don't read past the end. */ + if ( p >= limit ) + goto Bad; + } + + /* Get the nibble. */ + nib = ( p[0] >> phase ) & 0xF; + phase = 4 - phase; + if ( nib >= 10 ) + break; + + exp = exp * 10 + nib; + } + + if ( exp_sign ) + exp = -exp; + + power_ten += (FT_Int)exp; + } + + /* raise to power of ten if needed */ + while ( power_ten > 0 ) + { + result = result * 10; + num = num * 10; + + power_ten--; + } + + while ( power_ten < 0 ) + { + result = result / 10; + divider = divider * 10; + + power_ten++; + } + + /* Move the integer part into the high 16 bits. */ + result <<= 16; + + /* Place the decimal part into the low 16 bits. */ + if ( num ) + result |= FT_DivFix( num, divider ); + + if ( sign ) + result = -result; + + Exit: + return result; + + Bad: + result = 0; + goto Exit; + } + + + /* read a number, either integer or real */ + static FT_Long + cff_parse_num( FT_Byte** d ) + { + return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 ) + : cff_parse_integer( d[0], d[1] ) ); + } + + + /* read a floating point number, either integer or real */ + static FT_Fixed + cff_parse_fixed( FT_Byte** d ) + { + return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 ) + : cff_parse_integer( d[0], d[1] ) << 16 ); + } + + /* read a floating point number, either integer or real, */ + /* but return 1000 times the number read in. */ + static FT_Fixed + cff_parse_fixed_thousand( FT_Byte** d ) + { + return **d == + 30 ? cff_parse_real ( d[0], d[1], 3 ) + : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 ); + } + + static FT_Error + cff_parse_font_matrix( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Matrix* matrix = &dict->font_matrix; + FT_Vector* offset = &dict->font_offset; + FT_UShort* upm = &dict->units_per_em; + FT_Byte** data = parser->stack; + FT_Error error; + FT_Fixed temp; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 6 ) + { + matrix->xx = cff_parse_fixed_thousand( data++ ); + matrix->yx = cff_parse_fixed_thousand( data++ ); + matrix->xy = cff_parse_fixed_thousand( data++ ); + matrix->yy = cff_parse_fixed_thousand( data++ ); + offset->x = cff_parse_fixed_thousand( data++ ); + offset->y = cff_parse_fixed_thousand( data ); + + temp = ABS( matrix->yy ); + + *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) ); + + if ( temp != 0x10000L ) + { + matrix->xx = FT_DivFix( matrix->xx, temp ); + matrix->yx = FT_DivFix( matrix->yx, temp ); + matrix->xy = FT_DivFix( matrix->xy, temp ); + matrix->yy = FT_DivFix( matrix->yy, temp ); + offset->x = FT_DivFix( offset->x, temp ); + offset->y = FT_DivFix( offset->y, temp ); + } + + /* note that the offsets must be expressed in integer font units */ + offset->x >>= 16; + offset->y >>= 16; + + error = CFF_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_font_bbox( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_BBox* bbox = &dict->font_bbox; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 4 ) + { + bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + error = CFF_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_private_dict( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 2 ) + { + dict->private_size = cff_parse_num( data++ ); + dict->private_offset = cff_parse_num( data ); + error = CFF_Err_Ok; + } + + return error; + } + + + static FT_Error + cff_parse_cid_ros( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error; + + + error = CFF_Err_Stack_Underflow; + + if ( parser->top >= parser->stack + 3 ) + { + dict->cid_registry = (FT_UInt)cff_parse_num ( data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ ); + dict->cid_supplement = (FT_ULong)cff_parse_num( data ); + error = CFF_Err_Ok; + } + + return error; + } + + +#define CFF_FIELD_NUM( code, name ) \ + CFF_FIELD( code, name, cff_kind_num ) +#define CFF_FIELD_FIXED( code, name ) \ + CFF_FIELD( code, name, cff_kind_fixed ) +#define CFF_FIELD_STRING( code, name ) \ + CFF_FIELD( code, name, cff_kind_string ) +#define CFF_FIELD_BOOL( code, name ) \ + CFF_FIELD( code, name, cff_kind_bool ) +#define CFF_FIELD_DELTA( code, name, max ) \ + CFF_FIELD( code, name, cff_kind_delta ) + +#define CFF_FIELD_CALLBACK( code, name ) \ + { \ + cff_kind_callback, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_ ## name, \ + 0, 0 \ + }, + +#undef CFF_FIELD +#define CFF_FIELD( code, name, kind ) \ + { \ + kind, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE( name ), \ + 0, 0, 0 \ + }, + +#undef CFF_FIELD_DELTA +#define CFF_FIELD_DELTA( code, name, max ) \ + { \ + cff_kind_delta, \ + code | CFFCODE, \ + FT_FIELD_OFFSET( name ), \ + FT_FIELD_SIZE_DELTA( name ), \ + 0, \ + max, \ + FT_FIELD_OFFSET( num_ ## name ) \ + }, + +#define CFFCODE_TOPDICT 0x1000 +#define CFFCODE_PRIVATE 0x2000 + + static const CFF_Field_Handler cff_field_handlers[] = + { + +#include "cfftoken.h" + + { 0, 0, 0, 0, 0, 0, 0 } + }; + + + FT_LOCAL_DEF( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ) + { + FT_Byte* p = start; + FT_Error error = CFF_Err_Ok; + + + parser->top = parser->stack; + parser->start = start; + parser->limit = limit; + parser->cursor = start; + + while ( p < limit ) + { + FT_UInt v = *p; + + + if ( v >= 27 && v != 31 ) + { + /* it's a number; we will push its position on the stack */ + if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + goto Stack_Overflow; + + *parser->top ++ = p; + + /* now, skip it */ + if ( v == 30 ) + { + /* skip real number */ + p++; + for (;;) + { + if ( p >= limit ) + goto Syntax_Error; + v = p[0] >> 4; + if ( v == 15 ) + break; + v = p[0] & 0xF; + if ( v == 15 ) + break; + p++; + } + } + else if ( v == 28 ) + p += 2; + else if ( v == 29 ) + p += 4; + else if ( v > 246 ) + p += 1; + } + else + { + /* This is not a number, hence it's an operator. Compute its code */ + /* and look for it in our current list. */ + + FT_UInt code; + FT_UInt num_args = (FT_UInt) + ( parser->top - parser->stack ); + const CFF_Field_Handler* field; + + + *parser->top = p; + code = v; + if ( v == 12 ) + { + /* two byte operator */ + p++; + if ( p >= limit ) + goto Syntax_Error; + + code = 0x100 | p[0]; + } + code = code | parser->object_code; + + for ( field = cff_field_handlers; field->kind; field++ ) + { + if ( field->code == (FT_Int)code ) + { + /* we found our field's handler; read it */ + FT_Long val; + FT_Byte* q = (FT_Byte*)parser->object + field->offset; + + + /* check that we have enough arguments -- except for */ + /* delta encoded arrays, which can be empty */ + if ( field->kind != cff_kind_delta && num_args < 1 ) + goto Stack_Underflow; + + switch ( field->kind ) + { + case cff_kind_bool: + case cff_kind_string: + case cff_kind_num: + val = cff_parse_num( parser->stack ); + goto Store_Number; + + case cff_kind_fixed: + val = cff_parse_fixed( parser->stack ); + + Store_Number: + switch ( field->size ) + { + case 1: + *(FT_Byte*)q = (FT_Byte)val; + break; + + case 2: + *(FT_Short*)q = (FT_Short)val; + break; + + case 4: + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems where long is 8 bytes */ + *(FT_Long*)q = val; + } + break; + + case cff_kind_delta: + { + FT_Byte* qcount = (FT_Byte*)parser->object + + field->count_offset; + + FT_Byte** data = parser->stack; + + + if ( num_args > field->array_max ) + num_args = field->array_max; + + /* store count */ + *qcount = (FT_Byte)num_args; + + val = 0; + while ( num_args > 0 ) + { + val += cff_parse_num( data++ ); + switch ( field->size ) + { + case 1: + *(FT_Byte*)q = (FT_Byte)val; + break; + + case 2: + *(FT_Short*)q = (FT_Short)val; + break; + + case 4: + *(FT_Int32*)q = (FT_Int)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + + q += field->size; + num_args--; + } + } + break; + + default: /* callback */ + error = field->reader( parser ); + if ( error ) + goto Exit; + } + goto Found; + } + } + + /* this is an unknown operator, or it is unsupported; */ + /* we will ignore it for now. */ + + Found: + /* clear stack */ + parser->top = parser->stack; + } + p++; + } + + Exit: + return error; + + Stack_Overflow: + error = CFF_Err_Invalid_Argument; + goto Exit; + + Stack_Underflow: + error = CFF_Err_Invalid_Argument; + goto Exit; + + Syntax_Error: + error = CFF_Err_Invalid_Argument; + goto Exit; + } + + +/* END */ diff --git a/lib/freetype/src/cff/cffparse.h b/lib/freetype/src/cff/cffparse.h new file mode 100644 index 0000000..2de95a2 --- /dev/null +++ b/lib/freetype/src/cff/cffparse.h @@ -0,0 +1,69 @@ +/***************************************************************************/ +/* */ +/* cffparse.h */ +/* */ +/* CFF token stream parser (specification) */ +/* */ +/* Copyright 1996-2001, 2002 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 __CFF_PARSE_H__ +#define __CFF_PARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_CFF_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define CFF_MAX_STACK_DEPTH 96 + +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 + + + typedef struct CFF_ParserRec_ + { + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; + + FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; + FT_Byte** top; + + FT_UInt object_code; + void* object; + + } CFF_ParserRec, *CFF_Parser; + + + FT_LOCAL( void ) + cff_parser_init( CFF_Parser parser, + FT_UInt code, + void* object ); + + FT_LOCAL( FT_Error ) + cff_parser_run( CFF_Parser parser, + FT_Byte* start, + FT_Byte* limit ); + + +FT_END_HEADER + + +#endif /* __CFF_PARSE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cff/cfftoken.h b/lib/freetype/src/cff/cfftoken.h new file mode 100644 index 0000000..2cbb837 --- /dev/null +++ b/lib/freetype/src/cff/cfftoken.h @@ -0,0 +1,97 @@ +/***************************************************************************/ +/* */ +/* cfftoken.h */ +/* */ +/* CFF token definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec + +#undef CFFCODE +#define CFFCODE CFFCODE_TOPDICT + + CFF_FIELD_STRING ( 0, version ) + CFF_FIELD_STRING ( 1, notice ) + CFF_FIELD_STRING ( 0x100, copyright ) + CFF_FIELD_STRING ( 2, full_name ) + CFF_FIELD_STRING ( 3, family_name ) + CFF_FIELD_STRING ( 4, weight ) + CFF_FIELD_BOOL ( 0x101, is_fixed_pitch ) + CFF_FIELD_FIXED ( 0x102, italic_angle ) + CFF_FIELD_NUM ( 0x103, underline_position ) + CFF_FIELD_NUM ( 0x104, underline_thickness ) + CFF_FIELD_NUM ( 0x105, paint_type ) + CFF_FIELD_NUM ( 0x106, charstring_type ) + CFF_FIELD_CALLBACK( 0x107, font_matrix ) + CFF_FIELD_NUM ( 13, unique_id ) + CFF_FIELD_CALLBACK( 5, font_bbox ) + CFF_FIELD_NUM ( 0x108, stroke_width ) + CFF_FIELD_NUM ( 15, charset_offset ) + CFF_FIELD_NUM ( 16, encoding_offset ) + CFF_FIELD_NUM ( 17, charstrings_offset ) + CFF_FIELD_CALLBACK( 18, private_dict ) + CFF_FIELD_NUM ( 0x114, synthetic_base ) + CFF_FIELD_STRING ( 0x115, postscript ) + CFF_FIELD_STRING ( 0x116, base_font_name ) + +#if 0 + CFF_FIELD_DELTA ( 0x117, base_font_blend, 16 ) + CFF_FIELD_CALLBACK( 0x118, multiple_master ) + CFF_FIELD_CALLBACK( 0x119, blend_axit_types ) +#endif + + CFF_FIELD_CALLBACK( 0x11E, cid_ros ) + CFF_FIELD_NUM ( 0x11F, cid_font_version ) + CFF_FIELD_NUM ( 0x120, cid_font_revision ) + CFF_FIELD_NUM ( 0x121, cid_font_type ) + CFF_FIELD_NUM ( 0x122, cid_count ) + CFF_FIELD_NUM ( 0x123, cid_uid_base ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset ) + CFF_FIELD_STRING ( 0x126, cid_font_name ) + +#if 0 + CFF_FIELD_NUM ( 0x127, chameleon ) +#endif + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFFCODE_PRIVATE + + CFF_FIELD_DELTA( 6, blue_values, 14 ) + CFF_FIELD_DELTA( 7, other_blues, 10 ) + CFF_FIELD_DELTA( 8, family_blues, 14 ) + CFF_FIELD_DELTA( 9, family_other_blues, 10 ) + CFF_FIELD_FIXED( 0x109, blue_scale ) + CFF_FIELD_NUM ( 0x10A, blue_shift ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz ) + CFF_FIELD_NUM ( 10, standard_width ) + CFF_FIELD_NUM ( 11, standard_height ) + CFF_FIELD_DELTA( 0x10C, snap_widths, 13 ) + CFF_FIELD_DELTA( 0x10D, snap_heights, 13 ) + CFF_FIELD_BOOL ( 0x10E, force_bold ) + CFF_FIELD_FIXED( 0x10F, force_bold_threshold ) + CFF_FIELD_NUM ( 0x110, lenIV ) + CFF_FIELD_NUM ( 0x111, language_group ) + CFF_FIELD_FIXED( 0x112, expansion_factor ) + CFF_FIELD_NUM ( 0x113, initial_random_seed ) + CFF_FIELD_NUM ( 19, local_subrs_offset ) + CFF_FIELD_NUM ( 20, default_width ) + CFF_FIELD_NUM ( 21, nominal_width ) + + +/* END */ diff --git a/lib/freetype/src/cff/descrip.mms b/lib/freetype/src/cff/descrip.mms new file mode 100644 index 0000000..2401f2e --- /dev/null +++ b/lib/freetype/src/cff/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 OpenType/CFF driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cff]) + +OBJS=cff.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/cff/module.mk b/lib/freetype/src/cff/module.mk new file mode 100644 index 0000000..68789c9 --- /dev/null +++ b/lib/freetype/src/cff/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 CFF module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_cff_driver + +add_cff_driver: + $(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/cff/rules.mk b/lib/freetype/src/cff/rules.mk new file mode 100644 index 0000000..b53fdd8 --- /dev/null +++ b/lib/freetype/src/cff/rules.mk @@ -0,0 +1,71 @@ +# +# FreeType 2 OpenType/CFF driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# OpenType driver directory +# +CFF_DIR := $(SRC_)cff +CFF_DIR_ := $(CFF_DIR)$(SEP) + + +CFF_COMPILE := $(FT_COMPILE) $I$(CFF_DIR) + + +# CFF driver sources (i.e., C files) +# +CFF_DRV_SRC := $(CFF_DIR_)cffobjs.c \ + $(CFF_DIR_)cffload.c \ + $(CFF_DIR_)cffgload.c \ + $(CFF_DIR_)cffparse.c \ + $(CFF_DIR_)cffcmap.c \ + $(CFF_DIR_)cffdrivr.c + +# CFF driver headers +# +CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ + $(CFF_DIR_)cfftoken.h \ + $(CFF_DIR_)cfferrs.h + + +# CFF driver object(s) +# +# CFF_DRV_OBJ_M is used during `multi' builds +# CFF_DRV_OBJ_S is used during `single' builds +# +CFF_DRV_OBJ_M := $(CFF_DRV_SRC:$(CFF_DIR_)%.c=$(OBJ_)%.$O) +CFF_DRV_OBJ_S := $(OBJ_)cff.$O + +# CFF driver source file for single build +# +CFF_DRV_SRC_S := $(CFF_DIR_)cff.c + + +# CFF driver - single object +# +$(CFF_DRV_OBJ_S): $(CFF_DRV_SRC_S) $(CFF_DRV_SRC) $(FREETYPE_H) $(CFF_DRV_H) + $(CFF_COMPILE) $T$@ $(CFF_DRV_SRC_S) + + +# CFF driver - multiple objects +# +$(OBJ_)%.$O: $(CFF_DIR_)%.c $(FREETYPE_H) $(CFF_DRV_H) + $(CFF_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(CFF_DRV_OBJ_S) +DRV_OBJS_M += $(CFF_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/cid/Jamfile b/lib/freetype/src/cid/Jamfile new file mode 100644 index 0000000..a505e3c --- /dev/null +++ b/lib/freetype/src/cid/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/cid Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) cid ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = cidobjs cidload cidgload cidriver cidparse ; + } + else + { + _sources = type1cid ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/cid Jamfile diff --git a/lib/freetype/src/cid/ciderrs.h b/lib/freetype/src/cid/ciderrs.h new file mode 100644 index 0000000..01813e1 --- /dev/null +++ b/lib/freetype/src/cid/ciderrs.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* ciderrs.h */ +/* */ +/* CID error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the CID error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __CIDERRS_H__ +#define __CIDERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX CID_Err_ +#define FT_ERR_BASE FT_Mod_Err_CID + +#include FT_ERRORS_H + +#endif /* __CIDERRS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidgload.c b/lib/freetype/src/cid/cidgload.c new file mode 100644 index 0000000..15231f8 --- /dev/null +++ b/lib/freetype/src/cid/cidgload.c @@ -0,0 +1,435 @@ +/***************************************************************************/ +/* */ +/* cidgload.c */ +/* */ +/* CID-keyed Type1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include "cidload.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidgload + + + FT_CALLBACK_DEF( FT_Error ) + cid_load_glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + CID_Face face = (CID_Face)decoder->builder.face; + CID_FaceInfo cid = &face->cid; + FT_Byte* p; + FT_UInt fd_select; + FT_Stream stream = face->root.stream; + FT_Error error = 0; + FT_Byte* charstring = 0; + FT_Memory memory = face->root.memory; + FT_UInt glyph_length = 0; + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using */ + /* the callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data glyph_data; + + + error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, + &glyph_data ); + if ( error ) + goto Exit; + + p = (FT_Byte*)glyph_data.pointer; + fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + + if ( glyph_data.length != 0 ) + { + glyph_length = glyph_data.length - cid->fd_bytes; + FT_ALLOC( charstring, glyph_length ); + if ( !error ) + ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, + glyph_length ); + } + + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + + if ( error ) + goto Exit; + } + + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts read the CID font dictionary index */ + /* and charstring offset from the CIDMap. */ + { + FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + FT_ULong off1; + + + if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + + glyph_index * entry_len ) || + FT_FRAME_ENTER( 2 * entry_len ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + glyph_length = (FT_UInt) cid_get_offset( + &p, (FT_Byte)cid->gd_bytes ) - off1; + FT_FRAME_EXIT(); + + if ( glyph_length == 0 ) + goto Exit; + if ( FT_ALLOC( charstring, glyph_length ) ) + goto Exit; + if ( FT_STREAM_READ_AT( cid->data_offset + off1, + charstring, glyph_length ) ) + goto Exit; + } + + /* Now set up the subrs array and parse the charstrings. */ + { + CID_FaceDict dict; + CID_Subrs cid_subrs = face->subrs + fd_select; + FT_Int cs_offset; + + + /* Set up subrs */ + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + + /* Set up font matrix */ + dict = cid->font_dicts + fd_select; + + decoder->font_matrix = dict->font_matrix; + decoder->font_offset = dict->font_offset; + decoder->lenIV = dict->private_dict.lenIV; + + /* Decode the charstring. */ + + /* Adjustment for seed bytes. */ + cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + + /* Decrypt only if lenIV >= 0. */ + if ( decoder->lenIV >= 0 ) + cid_decrypt( charstring, glyph_length, 4330 ); + + error = decoder->funcs.parse_charstrings( decoder, + charstring + cs_offset, + glyph_length - cs_offset ); + } + + FT_FREE( charstring ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && + face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + metrics.bearing_x = decoder->builder.left_bearing.x; + metrics.bearing_y = decoder->builder.left_bearing.y; + metrics.advance = decoder->builder.advance.x; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + decoder->builder.left_bearing.x = metrics.bearing_x; + decoder->builder.left_bearing.y = metrics.bearing_y; + decoder->builder.advance.x = metrics.advance; + decoder->builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + Exit: + return error; + } + + +#if 0 + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + *max_advance = 0; + + /* Initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + 0, /* glyph names! XXX */ + 0, /* blend == 0 */ + 0, /* hinting == 0 */ + cid_load_glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < face->root.num_glyphs; + glyph_index++ ) + { + /* now get load the unscaled outline */ + error = cid_load_glyph( &decoder, glyph_index ); + /* ignore the error if one occurred - skip to next glyph */ + } + + *max_advance = decoder.builder.advance.x; + + return CID_Err_Ok; + } + + +#endif /* 0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** UNHINTED GLYPH LOADER *********/ + /********** *********/ + /********** The following code is in charge of loading a *********/ + /********** single outline. It completely ignores hinting *********/ + /********** and is used when FT_LOAD_NO_HINTING is set. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_load_glyph( CID_GlyphSlot glyph, + CID_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T1_DecoderRec decoder; + CID_Face face = (CID_Face)glyph->root.face; + FT_Bool hinting; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_Matrix font_matrix; + FT_Vector font_offset; + + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + { + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + (FT_Size)size, + (FT_GlyphSlot)glyph, + 0, /* glyph names -- XXX */ + 0, /* blend == 0 */ + hinting, + FT_LOAD_TARGET_MODE(load_flags), + cid_load_glyph ); + + /* set up the decoder */ + decoder.builder.no_recurse = FT_BOOL( + ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); + + error = cid_load_glyph( &decoder, glyph_index ); + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* save new glyph tables */ + psaux->t1_decoder_funcs->done( &decoder ); + } + + /* now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax */ + if ( !error ) + { + glyph->root.outline.flags &= FT_OUTLINE_OWNER; + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.builder.advance.x; + + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.builder.advance.x; + glyph->root.linearHoriAdvance = decoder.builder.advance.x; + glyph->root.internal->glyph_transformed = 0; + + /* make up vertical metrics */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + + glyph->root.linearVertAdvance = 0; + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + /* apply the font matrix */ + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points */ + if ( !hinting ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + + metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); + metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; + metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + + metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; + metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + } + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* grid fit the bounding box if necessary */ + if ( hinting ) + { + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax + 63 ) & -64; + cbox.yMax = ( cbox.yMax + 63 ) & -64; + } + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + } + } + return error; + } + + +/* END */ diff --git a/lib/freetype/src/cid/cidgload.h b/lib/freetype/src/cid/cidgload.h new file mode 100644 index 0000000..93858e8 --- /dev/null +++ b/lib/freetype/src/cid/cidgload.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* cidgload.h */ +/* */ +/* OpenType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDGLOAD_H__ +#define __CIDGLOAD_H__ + + +#include <ft2build.h> +#include "cidobjs.h" + + +FT_BEGIN_HEADER + + +#if 0 + + /* Compute the maximum advance width of a font through quick parsing */ + FT_LOCAL( FT_Error ) + cid_face_compute_max_advance( CID_Face face, + FT_Int* max_advance ); + +#endif /* 0 */ + + FT_LOCAL( FT_Error ) + cid_slot_load_glyph( CID_GlyphSlot glyph, + CID_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __CIDGLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidload.c b/lib/freetype/src/cid/cidload.c new file mode 100644 index 0000000..19cfab5 --- /dev/null +++ b/lib/freetype/src/cid/cidload.c @@ -0,0 +1,546 @@ +/***************************************************************************/ +/* */ +/* cidload.c */ +/* */ +/* CID-keyed Type1 font loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +#include "cidload.h" + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidload + + + /* read a single offset */ + FT_LOCAL_DEF( FT_Long ) + cid_get_offset( FT_Byte** start, + FT_Byte offsize ) + { + FT_Long result; + FT_Byte* p = *start; + + + for ( result = 0; offsize > 0; offsize-- ) + { + result <<= 8; + result |= *p++; + } + + *start = p; + return result; + } + + + FT_LOCAL_DEF( void ) + cid_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ) + { + while ( length > 0 ) + { + FT_Byte plain; + + + plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) ); + seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 ); + *buffer++ = plain; + length--; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Error + cid_load_keyword( CID_Face face, + CID_Loader* loader, + const T1_Field keyword ) + { + FT_Error error; + CID_Parser* parser = &loader->parser; + FT_Byte* object; + void* dummy_object; + CID_FaceInfo cid = &face->cid; + + + /* if the keyword has a dedicated callback, call it */ + if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) + { + keyword->reader( (FT_Face)face, parser ); + error = parser->root.error; + goto Exit; + } + + /* we must now compute the address of our target object */ + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_CID_INFO: + object = (FT_Byte*)cid; + break; + + case T1_FIELD_LOCATION_FONT_INFO: + object = (FT_Byte*)&cid->font_info; + break; + + default: + { + CID_FaceDict dict; + + + if ( parser->num_dict < 0 ) + { + FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", + keyword->ident )); + error = CID_Err_Syntax_Error; + goto Exit; + } + + dict = cid->font_dicts + parser->num_dict; + switch ( keyword->location ) + { + case T1_FIELD_LOCATION_PRIVATE: + object = (FT_Byte*)&dict->private_dict; + break; + + default: + object = (FT_Byte*)dict; + } + } + } + + dummy_object = object; + + /* now, load the keyword data in the object's field(s) */ + if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || + keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = cid_parser_load_field_table( &loader->parser, keyword, + &dummy_object ); + else + error = cid_parser_load_field( &loader->parser, keyword, &dummy_object ); + Exit: + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_font_bbox( CID_Face face, + CID_Parser* parser ) + { + FT_Fixed temp[4]; + FT_BBox* bbox = &face->cid.font_bbox; + + + (void)cid_parser_to_fixed_array( parser, 4, temp, 0 ); + bbox->xMin = FT_RoundFix( temp[0] ); + bbox->yMin = FT_RoundFix( temp[1] ); + bbox->xMax = FT_RoundFix( temp[2] ); + bbox->yMax = FT_RoundFix( temp[3] ); + + return CID_Err_Ok; /* this is a callback function; */ + /* we must return an error code */ + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_font_matrix( CID_Face face, + CID_Parser* parser ) + { + FT_Matrix* matrix; + FT_Vector* offset; + CID_FaceDict dict; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + if ( parser->num_dict >= 0 ) + { + dict = face->cid.font_dicts + parser->num_dict; + matrix = &dict->font_matrix; + offset = &dict->font_offset; + + (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + + temp_scale = ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* `1000/temp_scale', because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed(), from psobjs.c). */ + root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L, + FT_DivFix( temp_scale, 1000 ) ) ); + + /* we need to scale the values by 1.0/temp[3] */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the font offsets are expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + return CID_Err_Ok; /* this is a callback function; */ + /* we must return an error code */ + } + + + FT_CALLBACK_DEF( FT_Error ) + parse_fd_array( CID_Face face, + CID_Parser* parser ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Error error = CID_Err_Ok; + FT_Long num_dicts; + + + num_dicts = cid_parser_to_int( parser ); + + if ( !cid->font_dicts ) + { + FT_Int n; + + + if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) + goto Exit; + + cid->num_dicts = (FT_UInt)num_dicts; + + /* don't forget to set a few defaults */ + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + /* default value for lenIV */ + dict->private_dict.lenIV = 4; + } + } + + Exit: + return error; + } + + + static + const T1_FieldRec cid_field_records[] = + { + +#include "cidtoken.h" + + T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) + T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + }; + + + static int + is_alpha( char c ) + { + return ( ft_isalnum( (int)c ) || + c == '.' || + c == '_' ); + } + + + static FT_Error + cid_parse_dict( CID_Face face, + CID_Loader* loader, + FT_Byte* base, + FT_Long size ) + { + CID_Parser* parser = &loader->parser; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = 0; + + { + FT_Byte* cur = base; + FT_Byte* limit = cur + size; + + + for ( ;cur < limit; cur++ ) + { + /* look for `%ADOBeginFontDict' */ + if ( *cur == '%' && cur + 20 < limit && + ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) + { + cur += 17; + + /* if /FDArray was found, then cid->num_dicts is > 0, and */ + /* we can start increasing parser->num_dict */ + if ( face->cid.num_dicts > 0 ) + parser->num_dict++; + } + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_Byte* cur2; + FT_Int len; + + + cur++; + + cur2 = cur; + while ( cur2 < limit && is_alpha( *cur2 ) ) + cur2++; + + len = (FT_Int)( cur2 - cur ); + if ( len > 0 && len < 22 ) + { + /* now compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field) cid_field_records; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == (FT_Int)ft_strlen( (const char*)name ) ) + { + FT_Int n; + + + for ( n = 1; n < len; n++ ) + if ( cur[n] != name[n] ) + break; + + if ( n >= len ) + { + /* we found it - run the parsing callback */ + parser->root.cursor = cur2; + cid_parser_skip_spaces( parser ); + parser->root.error = cid_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + + cur = parser->root.cursor; + break; + } + } + keyword++; + } + } + } + } + } + return parser->root.error; + } + + + /* read the subrmap and the subrs of each font dict */ + static FT_Error + cid_read_subrs( CID_Face face ) + { + CID_FaceInfo cid = &face->cid; + FT_Memory memory = face->root.memory; + FT_Stream stream = face->root.stream; + FT_Error error; + FT_Int n; + CID_Subrs subr; + FT_UInt max_offsets = 0; + FT_ULong* offsets = 0; + + + if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) + goto Exit; + + subr = face->subrs; + for ( n = 0; n < cid->num_dicts; n++, subr++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + FT_Int lenIV = dict->private_dict.lenIV; + FT_UInt count, num_subrs = dict->num_subrs; + FT_ULong data_len; + FT_Byte* p; + + + /* reallocate offsets array if needed */ + if ( num_subrs + 1 > max_offsets ) + { + FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4; + + + if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) + goto Fail; + + max_offsets = new_max; + } + + /* read the subrmap's offsets */ + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + goto Fail; + + p = (FT_Byte*)stream->cursor; + for ( count = 0; count <= num_subrs; count++ ) + offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); + + FT_FRAME_EXIT(); + + /* now, compute the size of subrs charstrings, */ + /* allocate, and read them */ + data_len = offsets[num_subrs] - offsets[0]; + + if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || + FT_ALLOC( subr->code[0], data_len ) ) + goto Fail; + + if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || + FT_STREAM_READ( subr->code[0], data_len ) ) + goto Fail; + + /* set up pointers */ + for ( count = 1; count <= num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count] - offsets[count - 1]; + subr->code[count] = subr->code[count - 1] + len; + } + + /* decrypt subroutines, but only if lenIV >= 0 */ + if ( lenIV >= 0 ) + { + for ( count = 0; count < num_subrs; count++ ) + { + FT_ULong len; + + + len = offsets[count + 1] - offsets[count]; + cid_decrypt( subr->code[count], len, 4330 ); + } + } + + subr->num_subrs = num_subrs; + } + + Exit: + FT_FREE( offsets ); + return error; + + Fail: + if ( face->subrs ) + { + for ( n = 0; n < cid->num_dicts; n++ ) + { + if ( face->subrs[n].code ) + FT_FREE( face->subrs[n].code[0] ); + + FT_FREE( face->subrs[n].code ); + } + FT_FREE( face->subrs ); + } + goto Exit; + } + + + static void + t1_init_loader( CID_Loader* loader, + CID_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + } + + + static void + t1_done_loader( CID_Loader* loader ) + { + CID_Parser* parser = &loader->parser; + + + /* finalize parser */ + cid_parser_done( parser ); + } + + + FT_LOCAL_DEF( FT_Error ) + cid_face_open( CID_Face face ) + { + CID_Loader loader; + CID_Parser* parser; + FT_Error error; + + + t1_init_loader( &loader, face ); + + parser = &loader.parser; + error = cid_parser_new( parser, face->root.stream, face->root.memory, + (PSAux_Service)face->psaux ); + if ( error ) + goto Exit; + + error = cid_parse_dict( face, &loader, + parser->postscript, + parser->postscript_len ); + if ( error ) + goto Exit; + + face->cid.data_offset = loader.parser.data_offset; + error = cid_read_subrs( face ); + + Exit: + t1_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/lib/freetype/src/cid/cidload.h b/lib/freetype/src/cid/cidload.h new file mode 100644 index 0000000..8fc577d --- /dev/null +++ b/lib/freetype/src/cid/cidload.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* cidload.h */ +/* */ +/* CID-keyed Type1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDLOAD_H__ +#define __CIDLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include "cidparse.h" + + +FT_BEGIN_HEADER + + + typedef struct CID_Loader_ + { + CID_Parser parser; /* parser used to read the stream */ + FT_Int num_chars; /* number of characters in encoding */ + + } CID_Loader; + + + FT_LOCAL( FT_Long ) + cid_get_offset( FT_Byte** start, + FT_Byte offsize ); + + FT_LOCAL( void ) + cid_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + FT_LOCAL( FT_Error ) + cid_face_open( CID_Face face ); + + +FT_END_HEADER + +#endif /* __CIDLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidobjs.c b/lib/freetype/src/cid/cidobjs.c new file mode 100644 index 0000000..ac5f16e --- /dev/null +++ b/lib/freetype/src/cid/cidobjs.c @@ -0,0 +1,448 @@ +/***************************************************************************/ +/* */ +/* cidobjs.c */ +/* */ +/* CID objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include "cidgload.h" +#include "cidload.h" +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidobjs + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + cid_slot_done( CID_GlyphSlot slot ) + { + slot->root.internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_slot_init( CID_GlyphSlot slot ) + { + CID_Face face; + PSHinter_Service pshinter; + + + face = (CID_Face)slot->root.face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->root.face->driver->root.library, + "pshinter" ); + if ( module ) + { + T1_Hints_Funcs funcs; + + + funcs = pshinter->get_t1_funcs( module ); + slot->root.internal->glyph_hints = (void*)funcs; + } + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + cid_size_get_globals_funcs( CID_Size size ) + { + CID_Face face = (CID_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0; + } + + + FT_LOCAL_DEF( void ) + cid_size_done( CID_Size size ) + { + if ( size->root.internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = cid_size_get_globals_funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)size->root.internal ); + + size->root.internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + cid_size_init( CID_Size size ) + { + FT_Error error = 0; + PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + CID_Face face = (CID_Face)size->root.face; + CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; + PS_Private priv = &dict->private_dict; + + + error = funcs->create( size->root.face->memory, priv, &globals ); + if ( !error ) + size->root.internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + cid_size_reset( CID_Size size ) + { + PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); + FT_Error error = 0; + + + if ( funcs ) + error = funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); + return error; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_done */ + /* */ + /* <Description> */ + /* Finalizes a given face object. */ + /* */ + /* <Input> */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + cid_face_done( CID_Face face ) + { + FT_Memory memory; + + + if ( face ) + { + CID_FaceInfo cid = &face->cid; + PS_FontInfo info = &cid->font_info; + + + memory = face->root.memory; + + /* release subrs */ + if ( face->subrs ) + { + FT_Int n; + + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_Subrs subr = face->subrs + n; + + + if ( subr->code ) + { + FT_FREE( subr->code[0] ); + FT_FREE( subr->code ); + } + } + + FT_FREE( face->subrs ); + } + + /* release FontInfo strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release font dictionaries */ + FT_FREE( cid->font_dicts ); + cid->num_dicts = 0; + + /* release other strings */ + FT_FREE( cid->cid_font_name ); + FT_FREE( cid->registry ); + FT_FREE( cid->ordering ); + + face->root.family_name = 0; + face->root.style_name = 0; + } + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_face_init */ + /* */ + /* <Description> */ + /* Initializes a given CID face object. */ + /* */ + /* <Input> */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* <InOut> */ + /* face :: The newly built face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_face_init( FT_Stream stream, + CID_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + PSNames_Service psnames; + PSAux_Service psaux; + PSHinter_Service pshinter; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + FT_UNUSED( stream ); + + + face->root.num_faces = 1; + + psnames = (PSNames_Service)face->psnames; + if ( !psnames ) + { + psnames = (PSNames_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "psnames" ); + + face->psnames = psnames; + } + + psaux = (PSAux_Service)face->psaux; + if ( !psaux ) + { + psaux = (PSAux_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "psaux" ); + + face->psaux = psaux; + } + + pshinter = (PSHinter_Service)face->pshinter; + if ( !pshinter ) + { + pshinter = (PSHinter_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY( face ), "pshinter" ); + + face->pshinter = pshinter; + } + + /* open the tokenizer; this will also check the font format */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + error = cid_face_open( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index != 0 ) + { + FT_ERROR(( "cid_face_init: invalid face index\n" )); + error = CID_Err_Invalid_Argument; + goto Exit; + } + + /* Now, load the font program into the face object */ + { + /* Init the face object fields */ + /* Now set up root face fields */ + { + FT_Face root = (FT_Face)&face->root; + + + root->num_glyphs = face->cid.cid_count; + root->num_charmaps = 0; + + root->face_index = face_index; + root->face_flags = FT_FACE_FLAG_SCALABLE; + + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + + if ( face->cid.font_info.is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: TODO: add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a /FontName dictionary entry! */ + root->family_name = face->cid.font_info.family_name; + if ( root->family_name ) + { + char* full = face->cid.font_info.full_name; + char* family = root->family_name; + + while ( *family && *full == *family ) + { + family++; + full++; + } + + root->style_name = ( *full == ' ' ) ? full + 1 + : (char *)"Regular"; + } + else + { + /* do we have a `/FontName'? */ + if ( face->cid.cid_font_name ) + { + root->family_name = face->cid.cid_font_name; + root->style_name = (char *)"Regular"; + } + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox.xMin = face->cid.font_bbox.xMin >> 16; + root->bbox.yMin = face->cid.font_bbox.yMin >> 16; + root->bbox.xMax = ( face->cid.font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( face->cid.font_bbox.yMax + 0xFFFFU ) >> 16; + + if ( !root->units_per_EM ) + root->units_per_EM = 1000; + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + root->height = (FT_Short)( + ( ( root->ascender + root->descender ) * 12 ) / 10 ); + + root->underline_position = face->cid.font_info.underline_position; + root->underline_thickness = face->cid.font_info.underline_thickness; + + root->internal->max_points = 0; + root->internal->max_contours = 0; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_init */ + /* */ + /* <Description> */ + /* Initializes a given CID driver object. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target driver object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cid_driver_init( CID_Driver driver ) + { + FT_UNUSED( driver ); + + return CID_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cid_driver_done */ + /* */ + /* <Description> */ + /* Finalizes a given CID driver. */ + /* */ + /* <Input> */ + /* driver :: A handle to the target CID driver. */ + /* */ + FT_LOCAL_DEF( void ) + cid_driver_done( CID_Driver driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/lib/freetype/src/cid/cidobjs.h b/lib/freetype/src/cid/cidobjs.h new file mode 100644 index 0000000..2d72d73 --- /dev/null +++ b/lib/freetype/src/cid/cidobjs.h @@ -0,0 +1,158 @@ +/***************************************************************************/ +/* */ +/* cidobjs.h */ +/* */ +/* CID objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDOBJS_H__ +#define __CIDOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct CID_Size_Hints_ CID_Size_Hints; + typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Driver */ + /* */ + /* <Description> */ + /* A handle to a Type 1 driver object. */ + /* */ + typedef struct CID_DriverRec_* CID_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_Size */ + /* */ + /* <Description> */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct CID_SizeRec_* CID_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CID_CharMap */ + /* */ + /* <Description> */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* <Note> */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct CID_CharMapRec_* CID_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + typedef struct CID_SizeRec_ + { + FT_SizeRec root; + FT_Bool valid; + + } CID_SizeRec; + + + typedef struct CID_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CID_GlyphSlotRec; + + + FT_LOCAL( void ) + cid_slot_done( CID_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + cid_slot_init( CID_GlyphSlot slot ); + + + FT_LOCAL( void ) + cid_size_done( CID_Size size ); + + + FT_LOCAL( FT_Error ) + cid_size_init( CID_Size size ); + + + FT_LOCAL( FT_Error ) + cid_size_reset( CID_Size size ); + + + FT_LOCAL( FT_Error ) + cid_face_init( FT_Stream stream, + CID_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + FT_LOCAL( void ) + cid_face_done( CID_Face face ); + + + FT_LOCAL( FT_Error ) + cid_driver_init( CID_Driver driver ); + + + FT_LOCAL( void ) + cid_driver_done( CID_Driver driver ); + + +FT_END_HEADER + +#endif /* __CIDOBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidparse.c b/lib/freetype/src/cid/cidparse.c new file mode 100644 index 0000000..397a66f --- /dev/null +++ b/lib/freetype/src/cid/cidparse.c @@ -0,0 +1,155 @@ +/***************************************************************************/ +/* */ +/* cidparse.c */ +/* */ +/* CID-keyed Type1 parser (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H + +#include "cidparse.h" + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cidparse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_ULong base_offset, offset, ps_len; + FT_Byte buffer[256 + 10]; + FT_Int buff_len; + + + FT_MEM_ZERO( parser, sizeof ( *parser ) ); + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + + base_offset = FT_STREAM_POS(); + + /* first of all, check the font format in the header */ + if ( FT_FRAME_ENTER( 31 ) ) + goto Exit; + + if ( ft_strncmp( (char *)stream->cursor, + "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) + { + FT_TRACE2(( "[not a valid CID-keyed font]\n" )); + error = CID_Err_Unknown_File_Format; + } + + FT_FRAME_EXIT(); + if ( error ) + goto Exit; + + /* now, read the rest of the file, until we find a `StartData' */ + buff_len = 256; + for (;;) + { + FT_Byte *p, *limit = buffer + 256; + FT_ULong top_position; + + + /* fill input buffer */ + buff_len -= 256; + if ( buff_len > 0 ) + FT_MEM_MOVE( buffer, limit, buff_len ); + + p = buffer + buff_len; + + if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) ) + goto Exit; + + top_position = FT_STREAM_POS() - buff_len; + buff_len = 256 + 10; + + /* look for `StartData' */ + for ( p = buffer; p < limit; p++ ) + { + if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) + { + /* save offset of binary data after `StartData' */ + offset = (FT_ULong)( top_position - ( limit - p ) + 10 ); + goto Found; + } + } + } + + Found: + /* we have found the start of the binary data. We will now */ + /* rewind and extract the frame of corresponding to the Postscript */ + /* section */ + + ps_len = offset - base_offset; + if ( FT_STREAM_SEEK( base_offset ) || + FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) + goto Exit; + + parser->data_offset = offset; + parser->postscript_len = ps_len; + parser->root.base = parser->postscript; + parser->root.cursor = parser->postscript; + parser->root.limit = parser->root.cursor + ps_len; + parser->num_dict = -1; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cid_parser_done( CID_Parser* parser ) + { + /* always free the private dictionary */ + if ( parser->postscript ) + { + FT_Stream stream = parser->stream; + + + FT_FRAME_RELEASE( parser->postscript ); + } + parser->root.funcs.done( &parser->root ); + } + + +/* END */ diff --git a/lib/freetype/src/cid/cidparse.h b/lib/freetype/src/cid/cidparse.h new file mode 100644 index 0000000..1b3e0b9 --- /dev/null +++ b/lib/freetype/src/cid/cidparse.h @@ -0,0 +1,116 @@ +/***************************************************************************/ +/* */ +/* cidparse.h */ +/* */ +/* CID-keyed Type1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDPARSE_H__ +#define __CIDPARSE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Parser */ + /* */ + /* <Description> */ + /* A CID_Parser is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* <Fields> */ + /* root :: The root PS_ParserRec fields. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* postscript :: A pointer to the data to be parsed. */ + /* */ + /* postscript_len :: The length of the data to be parsed. */ + /* */ + /* data_offset :: The start position of the binary data (i.e., the */ + /* end of the data to be parsed. */ + /* */ + /* cid :: A structure which holds the information about */ + /* the current font. */ + /* */ + /* num_dict :: The number of font dictionaries. */ + /* */ + typedef struct CID_Parser_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* postscript; + FT_Long postscript_len; + + FT_ULong data_offset; + + CID_FaceInfo cid; + FT_Int num_dict; + + } CID_Parser; + + + FT_LOCAL( FT_Error ) + cid_parser_new( CID_Parser* parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + cid_parser_done( CID_Parser* parser ); + + + /*************************************************************************/ + /* */ + /* PARSING ROUTINES */ + /* */ + /*************************************************************************/ + +#define cid_parser_skip_spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define cid_parser_skip_alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) + +#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root ) +#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define cid_parser_to_coord_array( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define cid_parser_to_fixed_array( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define cid_parser_to_token( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define cid_parser_to_token_array( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define cid_parser_load_field( p, f, o ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, 0, 0 ) +#define cid_parser_load_field_table( p, f, o ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, 0, 0 ) + + +FT_END_HEADER + +#endif /* __CIDPARSE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidriver.c b/lib/freetype/src/cid/cidriver.c new file mode 100644 index 0000000..4d6f442 --- /dev/null +++ b/lib/freetype/src/cid/cidriver.c @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* cidriver.c */ +/* */ +/* CID driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include "cidriver.h" +#include "cidgload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +#include "ciderrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ciddriver + + + static const char* + cid_get_postscript_name( CID_Face face ) + { + const char* result = face->cid.cid_font_name; + + + if ( result && result[0] == '/' ) + result++; + + return result; + } + + + static FT_Module_Interface + cid_get_interface( FT_Driver driver, + const FT_String* cid_interface ) + { + FT_UNUSED( driver ); + FT_UNUSED( cid_interface ); + + if ( ft_strcmp( (const char*)cid_interface, "postscript_name" ) == 0 ) + return (FT_Module_Interface)cid_get_postscript_name; + + return 0; + } + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1cid_driver_class = + { + /* first of all, the FT_Module_Class fields */ + { + ft_module_font_driver | + ft_module_driver_scalable | + ft_module_driver_has_hinter , + + sizeof( FT_DriverRec ), + "t1cid", /* module name */ + 0x10000L, /* version 1.0 of driver */ + 0x20000L, /* requires FreeType 2.0 */ + + 0, + + (FT_Module_Constructor)cid_driver_init, + (FT_Module_Destructor) cid_driver_done, + (FT_Module_Requester) cid_get_interface + }, + + /* then the other font drivers fields */ + sizeof( CID_FaceRec ), + sizeof( CID_SizeRec ), + sizeof( CID_GlyphSlotRec ), + + (FT_Face_InitFunc) cid_face_init, + (FT_Face_DoneFunc) cid_face_done, + + (FT_Size_InitFunc) cid_size_init, + (FT_Size_DoneFunc) cid_size_done, + (FT_Slot_InitFunc) cid_slot_init, + (FT_Slot_DoneFunc) cid_slot_done, + + (FT_Size_ResetPointsFunc)cid_size_reset, + (FT_Size_ResetPixelsFunc)cid_size_reset, + + (FT_Slot_LoadFunc) cid_slot_load_glyph, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + + (FT_Face_GetAdvancesFunc)0, + }; + + +/* END */ diff --git a/lib/freetype/src/cid/cidriver.h b/lib/freetype/src/cid/cidriver.h new file mode 100644 index 0000000..d5a80f6 --- /dev/null +++ b/lib/freetype/src/cid/cidriver.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* cidriver.h */ +/* */ +/* High-level CID driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __CIDRIVER_H__ +#define __CIDRIVER_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const FT_Driver_ClassRec t1cid_driver_class; + + +FT_END_HEADER + +#endif /* __CIDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/cid/cidtoken.h b/lib/freetype/src/cid/cidtoken.h new file mode 100644 index 0000000..f0dac92 --- /dev/null +++ b/lib/freetype/src/cid/cidtoken.h @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* cidtoken.h */ +/* */ +/* CID token definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_CID_INFO + + T1_FIELD_STRING( "CIDFontName", cid_font_name ) + T1_FIELD_NUM ( "CIDFontVersion", cid_version ) + T1_FIELD_NUM ( "CIDFontType", cid_font_type ) + T1_FIELD_STRING( "Registry", registry ) + T1_FIELD_STRING( "Ordering", ordering ) + T1_FIELD_NUM ( "Supplement", supplement ) + T1_FIELD_NUM ( "UIDBase", uid_base ) + T1_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) + T1_FIELD_NUM ( "FDBytes", fd_bytes ) + T1_FIELD_NUM ( "GDBytes", gd_bytes ) + T1_FIELD_NUM ( "CIDCount", cid_count ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING ( "version", version ) + T1_FIELD_STRING ( "Notice", notice ) + T1_FIELD_STRING ( "FullName", full_name ) + T1_FIELD_STRING ( "FamilyName", family_name ) + T1_FIELD_STRING ( "Weight", weight ) + T1_FIELD_FIXED ( "ItalicAngle", italic_angle ) + T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CID_FaceDictRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_NUM ( "PaintType", paint_type ) + T1_FIELD_NUM ( "FontType", font_type ) + T1_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) + T1_FIELD_NUM ( "SDBytes", sd_bytes ) + T1_FIELD_NUM ( "SubrCount", num_subrs ) + T1_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) + T1_FIELD_FIXED( "ForceBoldThreshold", forcebold_threshold ) + T1_FIELD_FIXED( "ExpansionFactor", expansion_factor ) + T1_FIELD_NUM ( "StrokeWidth", stroke_width ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + T1_FIELD_NUM ( "UniqueID", unique_id ) + T1_FIELD_NUM ( "lenIV", lenIV ) + T1_FIELD_NUM ( "LanguageGroup", language_group ) + T1_FIELD_NUM ( "password", password ) + + T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_NUM ( "BlueShift", blue_shift ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) + + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) + + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + + +/* END */ diff --git a/lib/freetype/src/cid/descrip.mms b/lib/freetype/src/cid/descrip.mms new file mode 100644 index 0000000..592fd58 --- /dev/null +++ b/lib/freetype/src/cid/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 CID driver compilation rules for VMS +# + + +# Copyright 2001 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.cid]) + +OBJS=type1cid.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/cid/module.mk b/lib/freetype/src/cid/module.mk new file mode 100644 index 0000000..f59d8a9 --- /dev/null +++ b/lib/freetype/src/cid/module.mk @@ -0,0 +1,21 @@ +# +# FreeType 2 CID module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_type1cid_driver + +add_type1cid_driver: + $(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) +# EOF diff --git a/lib/freetype/src/cid/rules.mk b/lib/freetype/src/cid/rules.mk new file mode 100644 index 0000000..809b20a --- /dev/null +++ b/lib/freetype/src/cid/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 CID driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# CID driver directory +# +CID_DIR := $(SRC_)cid +CID_DIR_ := $(CID_DIR)$(SEP) + + +CID_COMPILE := $(FT_COMPILE) $I$(CID_DIR) + + +# CID driver sources (i.e., C files) +# +CID_DRV_SRC := $(CID_DIR_)cidparse.c \ + $(CID_DIR_)cidload.c \ + $(CID_DIR_)cidriver.c \ + $(CID_DIR_)cidgload.c \ + $(CID_DIR_)cidobjs.c + +# CID driver headers +# +CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ + $(CID_DIR_)cidtoken.h \ + $(CID_DIR_)ciderrs.h + + +# CID driver object(s) +# +# CID_DRV_OBJ_M is used during `multi' builds +# CID_DRV_OBJ_S is used during `single' builds +# +CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR_)%.c=$(OBJ_)%.$O) +CID_DRV_OBJ_S := $(OBJ_)type1cid.$O + +# CID driver source file for single build +# +CID_DRV_SRC_S := $(CID_DIR_)type1cid.c + + +# CID driver - single object +# +$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) + $(CID_COMPILE) $T$@ $(CID_DRV_SRC_S) + + +# CID driver - multiple objects +# +$(OBJ_)%.$O: $(CID_DIR_)%.c $(FREETYPE_H) $(CID_DRV_H) + $(CID_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(CID_DRV_OBJ_S) +DRV_OBJS_M += $(CID_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/cid/type1cid.c b/lib/freetype/src/cid/type1cid.c new file mode 100644 index 0000000..0b866e9 --- /dev/null +++ b/lib/freetype/src/cid/type1cid.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* type1cid.c */ +/* */ +/* FreeType OpenType driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "cidparse.c" +#include "cidload.c" +#include "cidobjs.c" +#include "cidriver.c" +#include "cidgload.c" + + +/* END */ diff --git a/lib/freetype/src/gzip/Jamfile b/lib/freetype/src/gzip/Jamfile new file mode 100644 index 0000000..e461cf1 --- /dev/null +++ b/lib/freetype/src/gzip/Jamfile @@ -0,0 +1,8 @@ +# FreeType 2 src/gzip Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) gzip ; + +Library $(FT2_LIB) : ftgzip.c ; + +# end of src/pcf Jamfile diff --git a/lib/freetype/src/gzip/adler32.c b/lib/freetype/src/gzip/adler32.c new file mode 100644 index 0000000..706da26 --- /dev/null +++ b/lib/freetype/src/gzip/adler32.c @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +ZEXPORT(uLong) adler32( /* adler, buf, len) */ + uLong adler, + const Bytef *buf, + uInt len ) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff --git a/lib/freetype/src/gzip/descrip.mms b/lib/freetype/src/gzip/descrip.mms new file mode 100644 index 0000000..68d7a87 --- /dev/null +++ b/lib/freetype/src/gzip/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 GZip support compilation rules for VMS +# + + +# Copyright 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.gzip]) + +OBJS=ftgzip.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/gzip/ftgzip.c b/lib/freetype/src/gzip/ftgzip.c new file mode 100644 index 0000000..45f934b --- /dev/null +++ b/lib/freetype/src/gzip/ftgzip.c @@ -0,0 +1,564 @@ +/***************************************************************************/ +/* */ +/* ftgzip.c */ +/* */ +/* FreeType support for .gz compressed fileds */ +/* */ +/* this optional component relies on zlib. It should mainly be used to */ +/* parse compressed PCF fonts, as found with many X11 server */ +/* distributions. */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_DEBUG_H +#include <string.h> + +#ifdef FT_CONFIG_OPTION_USE_ZLIB + +#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB + +# include <zlib.h> + +#else /* !SYSTEM_ZLIB */ + + /* in this case, we include our own modified sources of the ZLib */ + /* within the "ftgzip" component. The modifications were necessary */ + /* to #include all files without conflicts, as well as preventing */ + /* the definition of "extern" functions that may cause linking */ + /* conflicts when a program is linked with both FreeType and the */ + /* original ZLib */ + +# define NO_DUMMY_DECL +# define BUILDFIXED /* save code size */ +# define MY_ZCALLOC + +# include "zlib.h" + +# undef SLOW +# define SLOW 1 /* we can't use asm-optimized sources here !! */ + +# include "zutil.c" +# include "inftrees.c" +# include "infcodes.c" +# include "infutil.c" +# include "infblock.c" +# include "inflate.c" +# include "adler32.c" + +#endif /* !SYSTEM_ZLIB */ + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** Z L I B M E M O R Y M A N A G E M E N T *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + /* it's better to use FreeType memory routines instead of raw 'malloc/free' */ + + + static voidpf + ft_gzip_alloc( FT_Memory memory, + uInt items, + uInt size ) + { + FT_ULong sz = (FT_ULong)size * items; + FT_Pointer p; + + FT_MEM_ALLOC( p, sz ); + + return (voidpf) p; + } + + + static void + ft_gzip_free( FT_Memory memory, + voidpf address ) + { + FT_MEM_FREE( address ); + } + + +#ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB + + local voidpf + zcalloc ( /* opaque, items, size) */ + voidpf opaque, + unsigned items, + unsigned size ) + { + return ft_gzip_alloc( opaque, items, size ); + } + + local void + zcfree( voidpf opaque, + voidpf ptr ) + { + ft_gzip_free( opaque, ptr ); + } + +#endif /* !SYSTEM_ZLIB */ + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** Z L I B F I L E D E S C R I P T O R *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + +#define FT_GZIP_BUFFER_SIZE 4096 + + typedef struct FT_GZipFileRec_ + { + FT_Stream source; /* parent/source stream */ + FT_Stream stream; /* embedding stream */ + FT_Memory memory; /* memory allocator */ + z_stream zstream; /* zlib input stream */ + + FT_ULong start; /* starting position, after .gz header */ + FT_Byte input[ FT_GZIP_BUFFER_SIZE ]; /* input read buffer */ + + FT_Byte buffer[ FT_GZIP_BUFFER_SIZE ]; /* output buffer */ + FT_ULong pos; /* position in output */ + FT_Byte* cursor; + FT_Byte* limit; + + } FT_GZipFileRec, *FT_GZipFile; + + +/* gzip flag byte */ +#define FT_GZIP_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define FT_GZIP_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define FT_GZIP_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define FT_GZIP_ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define FT_GZIP_COMMENT 0x10 /* bit 4 set: file comment present */ +#define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ + + + /* check and skip .gz header - we don't support "transparent" compression */ + static FT_Error + ft_gzip_check_header( FT_Stream stream ) + { + FT_Error error; + FT_Byte head[4]; + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ( head, 4 ) ) + goto Exit; + + /* head[0] && head[1] are the magic numbers */ + /* head[2] is the method, and head[3] the flags */ + if ( head[0] != 0x1f || + head[1] != 0x8b || + head[2] != Z_DEFLATED || + (head[3] & FT_GZIP_RESERVED) ) + { + error = FT_Err_Invalid_File_Format; + goto Exit; + } + + /* skip time, xflags and os code */ + (void)FT_STREAM_SKIP( 6 ); + + /* skip the extra field */ + if ( head[3] & FT_GZIP_EXTRA_FIELD ) + { + FT_UInt len; + + if ( FT_READ_USHORT_LE( len ) || + FT_STREAM_SKIP( len ) ) + goto Exit; + } + + /* skip original file name */ + if ( head[3] & FT_GZIP_ORIG_NAME ) + for (;;) + { + FT_UInt c; + + if ( FT_READ_BYTE( c) ) + goto Exit; + + if ( c == 0 ) + break; + } + + /* skip .gz comment */ + if ( head[3] & FT_GZIP_COMMENT ) + for (;;) + { + FT_UInt c; + + if ( FT_READ_BYTE( c) ) + goto Exit; + + if ( c == 0 ) + break; + } + + /* skip CRC */ + if ( head[3] & FT_GZIP_HEAD_CRC ) + if ( FT_STREAM_SKIP( 2 ) ) + goto Exit; + + Exit: + return error; + } + + + + static FT_Error + ft_gzip_file_init( FT_GZipFile zip, + FT_Stream stream, + FT_Stream source ) + { + z_stream* zstream = &zip->zstream; + FT_Error error = 0; + + zip->stream = stream; + zip->source = source; + zip->memory = stream->memory; + + zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + + /* check and skip .gz header */ + { + stream = source; + + error = ft_gzip_check_header( stream ); + if (error) + goto Exit; + + zip->start = FT_STREAM_POS(); + } + + /* initialize zlib - there is no zlib header in the compressed stream */ + zstream->zalloc = (alloc_func) ft_gzip_alloc; + zstream->zfree = (free_func) ft_gzip_free; + zstream->opaque = stream->memory; + + zstream->avail_in = 0; + zstream->next_in = zip->buffer; + + if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || + zstream->next_in == NULL ) + { + error = FT_Err_Invalid_File_Format; + goto Exit; + } + + Exit: + return error; + } + + + + static void + ft_gzip_file_done( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + + inflateEnd( zstream ); + + /* clear the rest */ + zstream->zalloc = NULL; + zstream->zfree = NULL; + zstream->opaque = NULL; + zstream->next_in = NULL; + zstream->next_out = NULL; + zstream->avail_in = 0; + zstream->avail_out = 0; + + zip->memory = NULL; + zip->source = NULL; + zip->stream = NULL; + } + + + static FT_Error + ft_gzip_file_reset( FT_GZipFile zip ) + { + FT_Stream stream = zip->source; + FT_Error error; + + if ( !FT_STREAM_SEEK( zip->start ) ) + { + z_stream* zstream = &zip->zstream; + + inflateReset( zstream ); + + zstream->avail_in = 0; + zstream->next_in = zip->input; + zstream->avail_out = 0; + zstream->next_out = zip->buffer; + + zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; + zip->cursor = zip->limit; + zip->pos = 0; + } + return error; + } + + + static FT_Error + ft_gzip_file_fill_input( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + FT_Stream stream = zip->source; + FT_ULong size; + + if ( stream->read ) + { + size = stream->read( stream, stream->pos, zip->input, FT_GZIP_BUFFER_SIZE ); + if ( size == 0 ) + return FT_Err_Invalid_Stream_Operation; + } + else + { + size = stream->size - stream->pos; + if ( size > FT_GZIP_BUFFER_SIZE ) + size = FT_GZIP_BUFFER_SIZE; + + if ( size == 0 ) + return FT_Err_Invalid_Stream_Operation; + + FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); + } + stream->pos += size; + + zstream->next_in = zip->input; + zstream->avail_in = size; + + return 0; + } + + + + static FT_Error + ft_gzip_file_fill_output( FT_GZipFile zip ) + { + z_stream* zstream = &zip->zstream; + FT_Error error = 0; + + zip->cursor = zip->buffer; + zstream->next_out = zip->cursor; + zstream->avail_out = FT_GZIP_BUFFER_SIZE; + + while ( zstream->avail_out > 0 ) + { + int err; + + if ( zstream->avail_in == 0 ) + { + error = ft_gzip_file_fill_input( zip ); + if ( error ) + break; + } + + err = inflate( zstream, Z_NO_FLUSH ); + + if ( err == Z_STREAM_END ) + { + zip->limit = zstream->next_out; + error = FT_Err_Invalid_Stream_Operation; + break; + } + else if ( err != Z_OK ) + { + error = FT_Err_Invalid_Stream_Operation; + break; + } + } + return error; + } + + + /* fill output buffer, 'count' must be <= FT_GZIP_BUFFER_SIZE */ + static FT_Error + ft_gzip_file_skip_output( FT_GZipFile zip, + FT_ULong count ) + { + FT_Error error = 0; + FT_ULong delta; + + for (;;) + { + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_gzip_file_fill_output( zip ); + if ( error ) + break; + } + + return error; + } + + + static FT_ULong + ft_gzip_file_io( FT_GZipFile zip, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_ULong result = 0; + FT_Error error; + + /* reset inflate stream if we're seeking backwards */ + /* yes, that's not too efficient, but it saves memory :-) */ + if ( pos < zip->pos ) + { + error = ft_gzip_file_reset( zip ); + if ( error ) goto Exit; + } + + /* skip unwanted bytes */ + if ( pos > zip->pos ) + { + error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); + if (error) + goto Exit; + } + + if ( count == 0 ) + goto Exit; + + /* now read the data */ + for (;;) + { + FT_ULong delta; + + delta = (FT_ULong)( zip->limit - zip->cursor ); + if ( delta >= count ) + delta = count; + + FT_MEM_COPY( buffer, zip->cursor, delta ); + buffer += delta; + result += delta; + zip->cursor += delta; + zip->pos += delta; + + count -= delta; + if ( count == 0 ) + break; + + error = ft_gzip_file_fill_output( zip ); + if (error) + break; + } + + Exit: + return result; + } + + +/***************************************************************************/ +/***************************************************************************/ +/***** *****/ +/***** G Z E M B E D D I N G S T R E A M *****/ +/***** *****/ +/***************************************************************************/ +/***************************************************************************/ + + static void + ft_gzip_stream_close( FT_Stream stream ) + { + FT_GZipFile zip = stream->descriptor.pointer; + FT_Memory memory = stream->memory; + + if ( zip ) + { + /* finalize gzip file descriptor */ + ft_gzip_file_done( zip ); + + FT_FREE( zip ); + + stream->descriptor.pointer = NULL; + } + } + + + static FT_ULong + ft_gzip_stream_io( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ) + { + FT_GZipFile zip = stream->descriptor.pointer; + + return ft_gzip_file_io( zip, pos, buffer, count ); + } + + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) + { + FT_Error error; + FT_Memory memory = source->memory; + FT_GZipFile zip; + + FT_ZERO( stream ); + stream->memory = memory; + + if ( !FT_NEW( zip ) ) + { + error = ft_gzip_file_init( zip, stream, source ); + if ( error ) + { + FT_FREE( zip ); + goto Exit; + } + + stream->descriptor.pointer = zip; + } + + stream->size = 0x7FFFFFFF; /* don't know the real size !! */ + stream->pos = 0; + stream->base = 0; + stream->read = ft_gzip_stream_io; + stream->close = ft_gzip_stream_close; + + Exit: + return error; + } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ) + { + FT_UNUSED( stream ); + FT_UNUSED( source ); + + return FT_Err_Unimplemented_Feature; + } + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ diff --git a/lib/freetype/src/gzip/infblock.c b/lib/freetype/src/gzip/infblock.c new file mode 100644 index 0000000..8d3e210 --- /dev/null +++ b/lib/freetype/src/gzip/infblock.c @@ -0,0 +1,386 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +local void inflate_blocks_reset( /* s, z, c) */ +inflate_blocks_statef *s, +z_streamp z, +uLongf *c ) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */ +z_streamp z, +check_func c, +uInt w ) +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +local int inflate_blocks( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return 0; +#endif +} + + +local int inflate_blocks_free( /* s, z) */ +inflate_blocks_statef *s, +z_streamp z ) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + diff --git a/lib/freetype/src/gzip/infblock.h b/lib/freetype/src/gzip/infblock.h new file mode 100644 index 0000000..c2535a1 --- /dev/null +++ b/lib/freetype/src/gzip/infblock.h @@ -0,0 +1,36 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFBLOCK_H +#define _INFBLOCK_H + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +local inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +local int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +local void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +local int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +#endif /* _INFBLOCK_H */ diff --git a/lib/freetype/src/gzip/infcodes.c b/lib/freetype/src/gzip/infcodes.c new file mode 100644 index 0000000..f7bfd58 --- /dev/null +++ b/lib/freetype/src/gzip/infcodes.c @@ -0,0 +1,250 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */ +uInt bl, uInt bd, +inflate_huft *tl, +inflate_huft *td, /* need separate declaration for Borland C++ */ +z_streamp z ) +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +local int inflate_codes( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +local void inflate_codes_free( /* c, z) */ +inflate_codes_statef *c, +z_streamp z ) +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/lib/freetype/src/gzip/infcodes.h b/lib/freetype/src/gzip/infcodes.h new file mode 100644 index 0000000..154d7f8 --- /dev/null +++ b/lib/freetype/src/gzip/infcodes.h @@ -0,0 +1,31 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFCODES_H +#define _INFCODES_H + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +local inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +local int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +local void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +#endif /* _INFCODES_H */ diff --git a/drivers/lib/zlib/inffixed.h b/lib/freetype/src/gzip/inffixed.h similarity index 100% rename from drivers/lib/zlib/inffixed.h rename to lib/freetype/src/gzip/inffixed.h diff --git a/lib/freetype/src/gzip/inflate.c b/lib/freetype/src/gzip/inflate.c new file mode 100644 index 0000000..8877fa3 --- /dev/null +++ b/lib/freetype/src/gzip/inflate.c @@ -0,0 +1,273 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +#define DONE INFLATE_DONE +#define BAD INFLATE_BAD + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +ZEXPORT(int) inflateReset( /* z) */ +z_streamp z ) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +ZEXPORT(int) inflateEnd( /* z) */ +z_streamp z ) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ +z_streamp z, +int w, +const char *version, +int stream_size ) +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + + +#undef NEEDBYTE +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} + +#undef NEXTBYTE +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + + +ZEXPORT(int) inflate( /* z, f) */ +z_streamp z, +int f ) +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + diff --git a/lib/freetype/src/gzip/inftrees.c b/lib/freetype/src/gzip/inftrees.c new file mode 100644 index 0000000..c3fdc27 --- /dev/null +++ b/lib/freetype/src/gzip/inftrees.c @@ -0,0 +1,460 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + + +#if 0 +local const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +#endif +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */ +uIntf *b, /* code lengths in bits (all assumed <= BMAX) */ +uInt n, /* number of codes (assumed <= 288) */ +uInt s, /* number of simple-valued codes (0..s-1) */ +const uIntf *d, /* list of base values for non-simple codes */ +const uIntf *e, /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t, /* result: starting table */ +uIntf *m, /* maximum lookup bits, returns actual */ +inflate_huft *hp, /* space for trees */ +uInt *hn, /* hufts used in space */ +uIntf *v /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +) +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? (uInt)l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +local int inflate_trees_bits( /* c, bb, tb, hp, z) */ +uIntf *c, /* 19 code lengths */ +uIntf *bb, /* bits tree desired/actual depth */ +inflate_huft * FAR *tb, /* bits tree result */ +inflate_huft *hp, /* space for trees */ +z_streamp z /* for messages */ +) +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */ +uInt nl, /* number of literal/length codes */ +uInt nd, /* number of distance codes */ +uIntf *c, /* that many (total) code lengths */ +uIntf *bl, /* literal desired/actual bit depth */ +uIntf *bd, /* distance desired/actual bit depth */ +inflate_huft * FAR *tl, /* literal/length tree result */ +inflate_huft * FAR *td, /* distance tree result */ +inflate_huft *hp, /* space for trees */ +z_streamp z /* for messages */ +) +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +local int inflate_trees_fixed( /* bl, bd, tl, td, z) */ +uIntf *bl, /* literal desired/actual bit depth */ +uIntf *bd, /* distance desired/actual bit depth */ +inflate_huft * FAR *tl, /* literal/length tree result */ +inflate_huft * FAR *td, /* distance tree result */ +z_streamp z /* for memory allocation */ +) +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff --git a/lib/freetype/src/gzip/inftrees.h b/lib/freetype/src/gzip/inftrees.h new file mode 100644 index 0000000..92d2f28 --- /dev/null +++ b/lib/freetype/src/gzip/inftrees.h @@ -0,0 +1,63 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +#ifndef _INFTREES_H +#define _INFTREES_H + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +local int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +local int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +local int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ + +#endif /* _INFTREES_H */ diff --git a/lib/freetype/src/gzip/infutil.c b/lib/freetype/src/gzip/infutil.c new file mode 100644 index 0000000..87358d7 --- /dev/null +++ b/lib/freetype/src/gzip/infutil.c @@ -0,0 +1,86 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + + +/* And'ing with mask[n] masks the lower n bits */ +local uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush( /* s, z, r) */ +inflate_blocks_statef *s, +z_streamp z, +int r ) +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff --git a/lib/freetype/src/gzip/infutil.h b/lib/freetype/src/gzip/infutil.h new file mode 100644 index 0000000..820dcd3 --- /dev/null +++ b/lib/freetype/src/gzip/infutil.h @@ -0,0 +1,96 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define DUMPBITS(j) {b>>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +local uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +#endif diff --git a/lib/freetype/src/gzip/rules.mk b/lib/freetype/src/gzip/rules.mk new file mode 100644 index 0000000..1332fb2 --- /dev/null +++ b/lib/freetype/src/gzip/rules.mk @@ -0,0 +1,74 @@ +# +# FreeType 2 GZip support configuration rules +# + + +# Copyright 2002 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. + + +# gzip driver directory +# +GZIP_DIR := $(SRC_)gzip +GZIP_DIR_ := $(GZIP_DIR)$(SEP) + + +# compilation flags for the driver +# +ifeq ($(SYSTEM_ZLIB),) + GZIP_COMPILE := $(FT_COMPILE) $I$(GZIP_DIR) +else + GZIP_COMPILE := $(FT_COMPILE) +endif + + +# gzip support sources (i.e., C files) +# +GZIP_DRV_SRC := $(GZIP_DIR_)ftgzip.c + +# gzip support headers +# +GZIP_DRV_H := + + +# gzip driver object(s) +# +# GZIP_DRV_OBJ_M is used during `multi' builds +# GZIP_DRV_OBJ_S is used during `single' builds +# +ifeq ($(SYSTEM_ZLIB),) + GZIP_DRV_OBJ_M := $(GZIP_DRV_SRC:$(GZIP_DIR_)%.c=$(OBJ_)%.$O) +else + GZIP_DRV_OBJ_M := $(OBJ_)ftgzip.$O +endif +GZIP_DRV_OBJ_S := $(OBJ_)ftgzip.$O + +# gzip support source file for single build +# +GZIP_DRV_SRC_S := $(GZIP_DIR_)ftgzip.c + + +# gzip support - single object +# +$(GZIP_DRV_OBJ_S): $(GZIP_DRV_SRC_S) $(GZIP_DRV_SRC) $(FREETYPE_H) $(GZIP_DRV_H) + $(GZIP_COMPILE) $T$@ $(GZIP_DRV_SRC_S) + + +# gzip support - multiple objects +# +$(OBJ_)%.$O: $(GZIP_DIR_)%.c $(FREETYPE_H) $(GZIP_DRV_H) + $(GZIP_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(GZIP_DRV_OBJ_S) +DRV_OBJS_M += $(GZIP_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/gzip/zconf.h b/lib/freetype/src/gzip/zconf.h new file mode 100644 index 0000000..d6989c9 --- /dev/null +++ b/lib/freetype/src/gzip/zconf.h @@ -0,0 +1,278 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C and LCC incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + +#if defined(__LCC__) +# define NEED_DUMMY_RETURN +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include <windows.h> +# define ZEXPORT(x) x WINAPI +# ifdef WIN32 +# define ZEXPORTVA(x) x WINAPIV +# else +# define ZEXPORTVA(x) x FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include <windows.h> +# define ZEXPORT(x) x __declspec(dllexport) WINAPI +# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT(x) x _export +# define ZEXPORTVA(x) x _export +# endif +# endif +# endif +#endif + + +#ifndef ZEXPORT +# define ZEXPORT(x) static x +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA(x) static x +#endif +#ifndef ZEXTERN +# define ZEXTERN(x) static x +#endif +#ifndef ZEXTERNDEF +# define ZEXTERNDEF(x) static x +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/lib/freetype/src/gzip/zlib.h b/lib/freetype/src/gzip/zlib.h new file mode 100644 index 0000000..50d0d3f --- /dev/null +++ b/lib/freetype/src/gzip/zlib.h @@ -0,0 +1,830 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + + + /* basic functions */ + +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN(int) deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN(int) inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN(int) inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN(int) inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN(int) deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN(int) inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN(int) inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN(uLong) adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN(int) inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff --git a/lib/freetype/src/gzip/zutil.c b/lib/freetype/src/gzip/zutil.c new file mode 100644 index 0000000..5da9f98 --- /dev/null +++ b/lib/freetype/src/gzip/zutil.c @@ -0,0 +1,181 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef STDC +extern void exit OF((int)); +#endif + + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/lib/freetype/src/gzip/zutil.h b/lib/freetype/src/gzip/zutil.h new file mode 100644 index 0000000..2b26c5c --- /dev/null +++ b/lib/freetype/src/gzip/zutil.h @@ -0,0 +1,216 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef STDC +# include <stddef.h> +# include <string.h> +# include <stdlib.h> +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include <errno.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include <alloc.h> +# endif +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include <unix.h> /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy ft_memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, const Bytef *buf, + uInt len)); +local voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +local void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ diff --git a/lib/freetype/src/otlayout/otlayout.h b/lib/freetype/src/otlayout/otlayout.h new file mode 100644 index 0000000..2cd67f5 --- /dev/null +++ b/lib/freetype/src/otlayout/otlayout.h @@ -0,0 +1,205 @@ +#ifndef __OT_LAYOUT_H__ +#define __OT_LAYOUT_H__ + + +#include "otlconf.h" + +OTL_BEGIN_HEADER + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** BASE DATA TYPES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + typedef unsigned char OTL_Byte; + typedef const OTL_Byte* OTL_Bytes; + + typedef int OTL_Error; + + typedef void* OTL_Pointer; + + typedef int OTL_Int; + typedef unsigned int OTL_UInt; + + typedef long OTL_Long; + typedef unsigned long OTL_ULong; + + typedef short OTL_Int16; + typedef unsigned short OTL_UInt16; + + +#if OTL_SIZEOF_INT == 4 + + typedef int OTL_Int32; + typedef unsigned int OTL_UInt32; + +#elif OTL_SIZEOF_LONG == 4 + + typedef long OTL_Int32; + typedef unsigned long OTL_UInt32; + +#else +# error "no 32-bits type found" +#endif + + typedef OTL_UInt32 OTL_Tag; + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ERROR CODES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + typedef enum + { + OTL_Err_Ok = 0, + OTL_Err_InvalidArgument, + OTL_Err_InvalidFormat, + OTL_Err_InvalidOffset, + + OTL_Err_Max + + } OTL_Error; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** MEMORY MANAGEMENT *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + typedef OTL_Pointer (*OTL_AllocFunc)( OTL_ULong size, + OTL_Pointer data ); + + typedef OTL_Pointer (*OTL_ReallocFunc)( OTL_Pointer block, + OTL_ULong size, + OTL_Pointer data ); + + typedef void (*OTL_FreeFunc)( OTL_Pointer block, + OTL_Pointer data ); + + typedef struct OTL_MemoryRec_ + { + OTL_Pointer mem_data; + OTL_AllocFunc mem_alloc; + OTL_ReallocFunc mem_realloc; + OTL_FreeFunc mem_free; + + } OTL_MemoryRec, *OTL_Memory; + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ENUMERATIONS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +/* re-define OTL_MAKE_TAG to something different if you're not */ +/* using an ASCII-based character set (Vaxes anyone ?) */ +#ifndef OTL_MAKE_TAG +#define OTL_MAKE_TAG(c1,c2,c3,c4) \ + ( ( (OTL_UInt32)(c1) << 24 ) | \ + (OTL_UInt32)(c2) << 16 ) | \ + (OTL_UInt32)(c3) << 8 ) | \ + (OTL_UInt32)(c4) ) +#endif + + typedef enum OTL_ScriptTag_ + { + OTL_SCRIPT_NONE = 0, + +#define OTL_SCRIPT_TAG(c1,c2,c3,c4,s,n) OTL_SCRIPT_TAG_ ## n = OTL_MAKE_TAG(c1,c2,c3,c4), +#include "otltags.h" + + OTL_SCRIPT_MAX + + } OTL_ScriptTag; + + + typedef enum OTL_LangTag_ + { + OTL_LANG_DEFAULT = 0, + +#define OTL_LANG_TAG(c1,c2,c3,c4,s,n) OTL_LANG_TAG_ ## n = OTL_MAKE_TAG(c1,c2,c3,c4), +#include "otltags.h" + + OTL_LANG_MAX + + } OTL_LangTag; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** MEMORY READS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#define OTL_PEEK_USHORT(p) ( ((OTL_UInt)((p)[0]) << 8) | \ + ((OTL_UInt)((p)[1]) ) ) + +#define OTL_PEEK_ULONG(p) ( ((OTL_UInt32)((p)[0]) << 24) | \ + ((OTL_UInt32)((p)[1]) << 16) | \ + ((OTL_UInt32)((p)[2]) << 8) | \ + ((OTL_UInt32)((p)[3]) ) ) + +#define OTL_PEEK_SHORT(p) ((OTL_Int16)OTL_PEEK_USHORT(p)) + +#define OTL_PEEK_LONG(p) ((OTL_Int32)OTL_PEEK_ULONG(p)) + +#define OTL_NEXT_USHORT(p) ( (p) += 2, OTL_PEEK_USHORT((p)-2) ) +#define OTL_NEXT_ULONG(p) ( (p) += 4, OTL_PEEK_ULONG((p)-4) ) + +#define OTL_NEXT_SHORT(p) ((OTL_Int16)OTL_NEXT_USHORT(p)) +#define OTL_NEXT_LONG(p) ((OTL_Int32)OTL_NEXT_ULONG(p)) + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** VALIDATION *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + typedef struct OTL_ValidatorRec_* OTL_Validator; + + typedef struct OTL_ValidatorRec_ + { + OTL_Bytes limit; + OTL_Bytes base; + OTL_Error error; + OTL_jmp_buf jump_buffer; + + } OTL_ValidatorRec; + + typedef void (*OTL_ValidateFunc)( OTL_Bytes table, + OTL_Valid valid ); + + OTL_API( void ) + otl_validator_error( OTL_Validator validator, + OTL_Error error ); + +#define OTL_INVALID(e) otl_validator_error( valid, e ) + +#define OTL_INVALID_TOO_SHORT OTL_INVALID( OTL_Err_InvalidOffset ) +#define OTL_INVALID_DATA OTL_INVALID( OTL_Err_InvalidFormat ) + +#define OTL_CHECK(_count) OTL_BEGIN_STMNT \ + if ( p + (_count) > valid->limit ) \ + OTL_INVALID_TOO_SHORT; \ + OTL_END_STMNT + + /* */ + +OTL_END_HEADER + +#endif /* __OPENTYPE_LAYOUT_H__ */ diff --git a/lib/freetype/src/otlayout/otlbase.c b/lib/freetype/src/otlayout/otlbase.c new file mode 100644 index 0000000..614e13c --- /dev/null +++ b/lib/freetype/src/otlayout/otlbase.c @@ -0,0 +1,181 @@ +#include "otlbase.h" +#include "otlcommn.h" + + static void + otl_base_coord_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 4 ); + + format = OTL_NEXT_USHORT( p ); + p += 2; + + switch ( format ) + { + case 1: + break; + + case 2: + OTL_CHECK( 4 ); + break; + + case 3: + OTL_CHECK( 2 ); + otl_device_table_validate( table + OTL_PEEK_USHORT( p ) ); + break; + + default: + OTL_INVALID_DATA; + } + } + + + static void + otl_base_tag_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK(2); + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count*4 ); + } + + + + static void + otl_base_values_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 4 ); + + p += 2; /* skip default index */ + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + + for ( ; count > 0; count-- ) + otl_base_coord_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_base_minmax_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt min_coord, max_coord, count; + + OTL_CHECK(6); + min_coord = OTL_NEXT_USHORT( p ); + max_coord = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( min_coord ) + otl_base_coord_validate( table + min_coord, valid ); + + if ( max_coord ) + otl_base_coord_validate( table + max_coord, valid ); + + OTL_CHECK( count*8 ); + for ( ; count > 0; count-- ) + { + p += 4; /* ignore tag */ + min_coord = OTL_NEXT_USHORT( p ); + max_coord = OTL_NEXT_USHORT( p ); + + if ( min_coord ) + otl_base_coord_validate( table + min_coord, valid ); + + if ( max_coord ) + otl_base_coord_validate( table + max_coord, valid ); + } + } + + + static void + otl_base_script_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt values, default_minmax; + + OTL_CHECK(6); + + values = OTL_NEXT_USHORT( p ); + default_minmax = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( values ) + otl_base_values_validate( table + values, valid ); + + if ( default_minmax ) + otl_base_minmax_validate( table + default_minmax, valid ); + + OTL_CHECK( count*6 ); + for ( ; count > 0; count-- ) + { + p += 4; /* ignore tag */ + otl_base_minmax_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + } + + + static void + otl_base_script_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK(2); + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK(count*6); + + for ( ; count > 0; count-- ) + { + p += 4; /* ignore script tag */ + otl_base_script_validate( table + OTL_NEXT_USHORT( p ) ); + } + } + + static void + otl_axis_table_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt tags; + + OTL_CHECK(4); + + tags = OTL_NEXT_USHORT( p ); + if ( tags ) + otl_base_tag_list_validate ( table + tags ); + + otl_base_script_list_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + OTL_LOCALDEF( void ) + otl_base_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + + OTL_CHECK(6); + + if ( OTL_NEXT_ULONG( p ) != 0x10000UL ) + OTL_INVALID_DATA; + + otl_axis_table_validate( table + OTL_NEXT_USHORT( p ) ); + otl_axis_table_validate( table + OTL_NEXT_USHORT( p ) ); + } \ No newline at end of file diff --git a/lib/freetype/src/otlayout/otlbase.h b/lib/freetype/src/otlayout/otlbase.h new file mode 100644 index 0000000..563d300 --- /dev/null +++ b/lib/freetype/src/otlayout/otlbase.h @@ -0,0 +1,14 @@ +#ifndef __OTL_BASE_H__ +#define __OTL_BASE_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + OTL_LOCAL( void ) + otl_base_validate( OTL_Bytes table, + OTL_Validator valid ); + +OTL_END_HEADER + +#endif /* __OTL_BASE_H__ */ diff --git a/lib/freetype/src/otlayout/otlcommn.c b/lib/freetype/src/otlayout/otlcommn.c new file mode 100644 index 0000000..742ff5b --- /dev/null +++ b/lib/freetype/src/otlayout/otlcommn.c @@ -0,0 +1,940 @@ +/***************************************************************************/ +/* */ +/* otlcommn.c */ +/* */ +/* OpenType layout support, common tables (body). */ +/* */ +/* Copyright 2002 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 "otlayout.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_coverage_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p; + OTL_UInt format; + + + if ( table + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + if ( p + count * 2 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check glyph indices */ + } + break; + + case 2: + { + OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p ); + OTL_UInt start, end, start_cover, total = 0, last = 0; + + + if ( p + num_ranges * 6 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( n = 0; n < num_ranges; n++ ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + start_cover = OTL_NEXT_USHORT( p ); + + if ( start > end || start_cover != total ) + OTL_INVALID_DATA; + + if ( n > 0 && start <= last ) + OTL_INVALID_DATA; + + total += end - start + 1; + last = end; + } + } + break; + + default: + OTL_INVALID_FORMAT; + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_coverage_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt result = 0; + + + switch ( format ) + { + case 1: + return count; + + case 2: + { + OTL_UInt start, end; + + + for ( ; count > 0; count-- ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + p += 2; /* skip start_index */ + + result += end - start + 1; + } + } + break; + + default: + ; + } + + return result; + } + + + OTL_LOCALDEF( OTL_Int ) + otl_coverage_get_index( OTL_Bytes table, + OTL_UInt glyph_index ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + switch ( format ) + { + case 1: + { + OTL_UInt min = 0, max = count, mid, gindex; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 2 * mid; + gindex = OTL_PEEK_USHORT( p ); + + if ( glyph_index == gindex ) + return (OTL_Int)mid; + + if ( glyph_index < gindex ) + max = mid; + else + min = mid + 1; + } + } + break; + + case 2: + { + OTL_UInt min = 0, max = count, mid; + OTL_UInt start, end, delta, start_cover; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 6 * mid; + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + + if ( glyph_index < start ) + max = mid; + else if ( glyph_index > end ) + min = mid + 1; + else + return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start ); + } + } + break; + + default: + ; + } + + return -1; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_class_definition_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt count, start = OTL_NEXT_USHORT( p ); + + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + count = OTL_NEXT_USHORT( p ); + + if ( p + count * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check glyph indices */ + } + break; + + case 2: + { + OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p ); + OTL_UInt start, end, value, last = 0; + + + if ( p + num_ranges * 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( n = 0; n < num_ranges; n++ ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + value = OTL_NEXT_USHORT( p ); /* ignored */ + + if ( start > end || ( n > 0 && start <= last ) ) + OTL_INVALID_DATA; + + last = end; + } + } + break; + + default: + OTL_INVALID_FORMAT; + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_class_definition_get_value( OTL_Bytes table, + OTL_UInt glyph_index ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + + + switch ( format ) + { + case 1: + { + OTL_UInt start = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt idx = (OTL_UInt)( glyph_index - start ); + + + if ( idx < count ) + { + p += 2 * idx; + return OTL_PEEK_USHORT( p ); + } + } + break; + + case 2: + { + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt min = 0, max = count, mid, gindex; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 6 * mid; + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + + if ( glyph_index < start ) + max = mid; + else if ( glyph_index > end ) + min = mid + 1; + else + return OTL_PEEK_USHORT( p ); + } + } + break; + + default: + ; + } + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_device_table_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt start, end, count, format, count; + + + if ( p + 8 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + format = OTL_NEXT_USHORT( p ); + + if ( format < 1 || format > 3 || end < start ) + OTL_INVALID_DATA; + + count = (OTL_UInt)( end - start + 1 ); + + if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit ) + OTL_INVALID_TOO_SHORT; + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_start( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_end( OTL_Bytes table ) + { + OTL_Bytes p = table + 2; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Int ) + otl_device_table_get_delta( OTL_Bytes table, + OTL_UInt size ) + { + OTL_Bytes p = table; + OTL_Int result = 0; + OTL_UInt start, end, format, idx, value; + + + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + format = OTL_NEXT_USHORT( p ); + + if ( size >= start && size <= end ) + { + /* we could do that with clever bit operations, but a switch is */ + /* much simpler to understand and maintain */ + /* */ + switch ( format ) + { + case 1: + idx = (OTL_UInt)( ( size - start ) * 2 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 14 - shift ); + + break; + + case 2: + idx = (OTL_UInt)( ( size - start ) * 4 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 12 - shift ); + + break; + + case 3: + idx = (OTL_UInt)( ( size - start ) * 8 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 8 - shift ); + + break; + + default: + ; + } + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_lookup_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt num_tables; + + + if ( table + 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + p += 4; + num_tables = OTL_NEXT_USHORT( p ); + + if ( p + num_tables * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_tables > 0; num_tables-- ) + { + offset = OTL_NEXT_USHORT( p ); + + if ( table + offset >= valid->limit ) + OTL_INVALID_OFFSET; + } + + /* XXX: check sub-tables? */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_get_table( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = NULL; + OTL_UInt count; + + + p = table + 4; + count = OTL_NEXT_USHORT( p ); + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_lookup_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table, q; + OTL_UInt num_lookups, offset; + + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_lookups = OTL_NEXT_USHORT( p ); + + if ( p + num_lookups * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_lookups > 0; num_lookups-- ) + { + offset = OTL_NEXT_USHORT( p ); + + otl_lookup_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_list_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_lookup( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = 0; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_table( OTL_Bytes table, + OTL_UInt lookup_index, + OTL_UInt table_index ) + { + OTL_Bytes result = NULL; + + + result = otl_lookup_list_get_lookup( table, lookup_index ); + if ( result ) + result = otl_lookup_get_table( result, table_index ); + + return result; + } + + + OTL_LOCALDEF( void ) + otl_lookup_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ) + { + OTL_Bytes p = table; + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + for ( ; count > 0; count-- ) + func( table + OTL_NEXT_USHORT( p ), func_data ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_feature_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt feat_params, num_lookups; + + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + feat_params = OTL_NEXT_USHORT( p ); /* ignored */ + num_lookups = OTL_NEXT_USHORT( p ); + + if ( p + num_lookups * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check lookup indices */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_lookups( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *lookups ) + { + OTL_Bytes p; + OTL_UInt num_features, result = 0; + + + p = table + 4; + num_features = OTL_NEXT_USHORT( p ); + + p += start * 2; + + for ( ; count > 0 && start < num_features; count--, start++ ) + { + lookups[0] = OTL_NEXT_USHORT(p); + lookups++; + result++; + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURE LIST *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_feature_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt num_features, offset; + + + if ( table + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_features = OTL_NEXT_USHORT( p ); + + if ( p + num_features * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_features > 0; num_features-- ) + { + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_feature_table_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_list_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_feature_list_get_feature( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = NULL; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + OTL_LOCALDEF( void ) + otl_feature_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ) + { + OTL_Bytes p; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + + for ( ; count > 0; count-- ) + func( table + OTL_NEXT_USHORT( p ), func_data ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_lang_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt lookup_order; + OTL_UInt req_feature; + OTL_UInt num_features; + + + if ( table + 6 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + lookup_order = OTL_NEXT_USHORT( p ); + req_feature = OTL_NEXT_USHORT( p ); + num_features = OTL_NEXT_USHORT( p ); + + /* XXX: check req_feature if not 0xFFFFU */ + + if ( p + 2 * num_features >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check features indices! */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_req_feature( OTL_Bytes table ) + { + OTL_Bytes p = table + 2; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_features( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *features ) + { + OTL_Bytes p = table + 4; + OTL_UInt num_features = OTL_NEXT_USHORT( p ); + OTL_UInt result = 0; + + + p += start * 2; + + for ( ; count > 0 && start < num_features; start++, count-- ) + { + features[0] = OTL_NEXT_USHORT( p ); + features++; + result++; + } + + return result; + } + + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_script_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_UInt default_lang; + OTL_Bytes p = table; + + + if ( table + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + default_lang = OTL_NEXT_USHORT( p ); + num_langs = OTL_NEXT_USHORT( p ); + + if ( default_lang != 0 ) + { + if ( table + default_lang >= valid->limit ) + OTL_INVALID_OFFSET; + } + + if ( p + num_langs * 6 >= valid->limit ) + OTL_INVALID_OFFSET; + + for ( ; num_langs > 0; num_langs-- ) + { + OTL_UInt offset; + + + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_lang_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( void ) + otl_script_list_validate( OTL_Bytes list, + OTL_Validator valid ) + { + OTL_UInt num_scripts; + OTL_Bytes p = list; + + + if ( list + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_scripts = OTL_NEXT_USHORT( p ); + + if ( p + num_scripts * 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_scripts > 0; num_scripts-- ) + { + OTL_UInt offset; + + + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_script_table_validate( list + offset, valid ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otl_lookup_table_validate( OTL_Bytes table, + OTL_UInt type_count, + OTL_ValidateFunc* type_funcs, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt lookup_type, lookup_flag, count; + OTL_ValidateFunc validate; + + OTL_CHECK( 6 ); + lookup_type = OTL_NEXT_USHORT( p ); + lookup_flag = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( lookup_type == 0 || lookup_type >= type_count ) + OTL_INVALID_DATA; + + validate = type_funcs[ lookup_type - 1 ]; + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + OTL_LOCALDEF( void ) + otl_lookup_list_validate( OTL_Bytes table, + OTL_UInt type_count, + OTL_ValidateFunc* type_funcs, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_lookup_table_validate( table + OTL_NEXT_USHORT( p ), + type_count, type_funcs, valid ); + } + +/* END */ diff --git a/lib/freetype/src/otlayout/otlcommn.h b/lib/freetype/src/otlayout/otlcommn.h new file mode 100644 index 0000000..25914fb --- /dev/null +++ b/lib/freetype/src/otlayout/otlcommn.h @@ -0,0 +1,277 @@ +/***************************************************************************/ +/* */ +/* otlcommn.h */ +/* */ +/* OpenType layout support, common tables (specification). */ +/* */ +/* Copyright 2002 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 __OTLCOMMN_H__ +#define __OTLCOMMN_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate coverage table */ + OTL_LOCALDEF( void ) + otl_coverage_validate( OTL_Bytes base, + OTL_Validator valid ); + + /* return number of covered glyphs */ + OTL_LOCALDEF( OTL_UInt ) + otl_coverage_get_count( OTL_Bytes base ); + + /* Return the coverage index corresponding to a glyph glyph index. */ + /* Return -1 if the glyph isn't covered. */ + OTL_LOCALDEF( OTL_Int ) + otl_coverage_get_index( OTL_Bytes base, + OTL_UInt glyph_index ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate class definition table */ + OTL_LOCALDEF( void ) + otl_class_definition_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return class value for a given glyph index */ + OTL_LOCALDEF( OTL_UInt ) + otl_class_definition_get_value( OTL_Bytes table, + OTL_UInt glyph_index ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate a device table */ + OTL_LOCALDEF( void ) + otl_device_table_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return a device table's first size */ + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_start( OTL_Bytes table ); + + /* return a device table's last size */ + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_end( OTL_Bytes table ); + + /* return pixel adjustment for a given size */ + OTL_LOCALDEF( OTL_Int ) + otl_device_table_get_delta( OTL_Bytes table, + OTL_UInt size ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate lookup table */ + OTL_LOCALDEF( void ) + otl_lookup_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return number of sub-tables in a lookup */ + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_get_count( OTL_Bytes table ); + + + /* return lookup sub-table */ + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_get_table( OTL_Bytes table, + OTL_UInt idx ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate lookup list */ + OTL_LOCALDEF( void ) + otl_lookup_list_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return number of lookups in list */ + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_list_get_count( OTL_Bytes table ); + + /* return a given lookup from a list */ + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_lookup( OTL_Bytes table, + OTL_UInt idx ); + + /* return lookup sub-table from a list */ + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_table( OTL_Bytes table, + OTL_UInt lookup_index, + OTL_UInt table_index ); + + /* iterate over lookup list */ + OTL_LOCALDEF( void ) + otl_lookup_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate feature table */ + OTL_LOCALDEF( void ) + otl_feature_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return feature's lookup count */ + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_count( OTL_Bytes table ); + + /* get several lookups indices from a feature. returns the number of */ + /* lookups grabbed */ + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_lookups( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *lookups ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURE LIST *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* validate a feature list */ + OTL_LOCALDEF( void ) + otl_feature_list_validate( OTL_Bytes table, + OTL_Validator valid ); + + /* return number of features in list */ + OTL_LOCALDEF( OTL_UInt ) + otl_feature_list_get_count( OTL_Bytes table ); + + + /* return a given feature from a list */ + OTL_LOCALDEF( OTL_Bytes ) + otl_feature_list_get_feature( OTL_Bytes table, + OTL_UInt idx ); + + /* iterate over all features in a list */ + OTL_LOCALDEF( void ) + otl_feature_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCAL( void ) + otl_lang_validate( OTL_Bytes table, + OTL_Validator valid ); + + + OTL_LOCAL( OTL_UInt ) + otl_lang_get_req_feature( OTL_Bytes table ); + + + OTL_LOCAL( OTL_UInt ) + otl_lang_get_count( OTL_Bytes table ); + + + OTL_LOCAL( OTL_UInt ) + otl_lang_get_features( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *features ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCAL( void ) + otl_script_list_validate( OTL_Bytes list, + OTL_Validator valid ); + + OTL_LOCAL( OTL_Bytes ) + otl_script_list_get_script( OTL_Bytes table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCAL( void ) + otl_lookup_list_validate( OTL_Bytes list, + OTL_UInt type_count, + OTL_ValidateFunc* type_funcs, + OTL_Validator valid ); + + /* */ + +OTL_END_HEADER + +#endif /* __OTLCOMMN_H__ */ + + +/* END */ diff --git a/lib/freetype/src/otlayout/otlconf.h b/lib/freetype/src/otlayout/otlconf.h new file mode 100644 index 0000000..3ef17a0 --- /dev/null +++ b/lib/freetype/src/otlayout/otlconf.h @@ -0,0 +1,78 @@ +#ifndef __OT_LAYOUT_CONFIG_H__ +#define __OT_LAYOUT_CONFIG_H__ + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** CONFIGURATION MACROS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#ifdef __cplusplus +# define OTL_BEGIN_HEADER extern "C" { +#else +# define OTL_BEGIN_HEADER /* nothing */ +#endif + +#ifdef __cplusplus +# define OTL_END_HEADER } +#else +# define OTL_END_HEADER /* nothing */ +#endif + +#ifndef OTL_API +# ifdef __cplusplus +# define OTL_API( x ) extern "C" +# else +# define OTL_API( x ) extern x +# endif +#endif + +#ifndef OTL_APIDEF +# define OTL_APIDEF( x ) x +#endif + +#ifndef OTL_LOCAL +# define OTL_LOCAL( x ) extern x +#endif + +#ifndef OTL_LOCALDEF +# define OTL_LOCALDEF( x ) x +#endif + +#define OTL_BEGIN_STMNT do { +#define OTL_END_STMNT } while (0) +#define OTL_DUMMY_STMNT OTL_BEGIN_STMNT OTL_END_STMNT + +#define OTL_UNUSED( x ) (x)=(x) +#define OTL_UNUSED_CONST(x) (void)(x) + + +#include <limits.h> +#if UINT_MAX == 0xFFFFU +# define OTL_SIZEOF_INT 2 +#elif UINT_MAX == 0xFFFFFFFFU +# define OTL_SIZEOF_INT 4 +#elif UINT_MAX > 0xFFFFFFFFU && UINT_MAX == 0xFFFFFFFFFFFFFFFFU +# define OTL_SIZEOF_INT 8 +#else +# error "unsupported number of bytes in 'int' type!" +#endif + +#if ULONG_MAX == 0xFFFFFFFFU +# define OTL_SIZEOF_LONG 4 +#elif ULONG_MAX > 0xFFFFFFFFU && ULONG_MAX == 0xFFFFFFFFFFFFFFFFU +# define OTL_SIZEOF_LONG 8 +#else +# error "unsupported number of bytes in 'long' type!" +#endif + +#include <setjmp.h> +#define OTL_jmp_buf jmp_buf +#define otl_setjmp setjmp +#define otl_longjmp longjmp + +/* */ + +#endif /* __OT_LAYOUT_CONFIG_H__ */ diff --git a/lib/freetype/src/otlayout/otlgdef.c b/lib/freetype/src/otlayout/otlgdef.c new file mode 100644 index 0000000..ff1c2a1 --- /dev/null +++ b/lib/freetype/src/otlayout/otlgdef.c @@ -0,0 +1,175 @@ +#include "otlgdef.h" +#include "otlcommn.h" + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ATTACHMENTS LIST *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_attach_point_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + count = OTL_NEXT_USHORT( p ); + if ( table + count*2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + } + + + static void + otl_attach_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_Bytes coverage; + OTL_UInt count; + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + coverage = table + OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( coverage, valid ); + if ( count != otl_coverage_get_count( coverage ) ) + OTL_INVALID_DATA; + + if ( p + count*2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; count > 0; count-- ) + otl_attach_point_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** LIGATURE CARETS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_caret_value_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + case 2: + break; + + case 3: + { + OTL_Bytes device; + + p += 2; + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + otl_device_table_validate( table + OTL_PEEK_USHORT( p ) ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + static void + otl_ligature_glyph_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + count = OTL_NEXT_USHORT( p ); + + if ( p + count*2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; count > 0; count-- ) + otl_caret_value_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + static void + otl_ligature_caret_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_Bytes coverage; + OTL_UInt count; + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + coverage = table + OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( coverage, valid ); + if ( count != otl_coverage_get_count( coverage ) ) + OTL_INVALID_DATA; + + if ( p + count*2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; count > 0; count-- ) + otl_ligature_glyph_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GDEF TABLE *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + OTL_APIDEF( void ) + otl_gdef_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + + if ( p + 12 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* check format */ + if ( OTL_NEXT_ULONG( p ) != 0x00010000UL ) + OTL_INVALID_FORMAT; + + /* validate class definition table */ + otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) ); + + /* validate attachment point list */ + otl_attach_list_validate( table + OTL_NEXT_USHORT( p ) ); + + /* validate ligature caret list */ + otl_ligature_caret_list_validate( table + OTL_NEXT_USHORT( p ) ); + + /* validate mark attach class */ + otl_class_definition_validate( table + OTL_NEXT_USHORT( p ) ); + } + diff --git a/lib/freetype/src/otlayout/otlgdef.h b/lib/freetype/src/otlayout/otlgdef.h new file mode 100644 index 0000000..5046cc4 --- /dev/null +++ b/lib/freetype/src/otlayout/otlgdef.h @@ -0,0 +1,14 @@ +#ifndef __OTL_GDEF_H__ +#define __OTL_GDEF_H__ + +#include "otltable.h" + +OTL_BEGIN_HEADER + + OTL_API( void ) + otl_gdef_validate( OTL_Bytes table, + OTL_Valid valid ); + +OTL_END_HEADER + +#endif /* __OTL_GDEF_H__ */ diff --git a/lib/freetype/src/otlayout/otlgpos.c b/lib/freetype/src/otlayout/otlgpos.c new file mode 100644 index 0000000..01942d7 --- /dev/null +++ b/lib/freetype/src/otlayout/otlgpos.c @@ -0,0 +1,980 @@ +#include "otlgpos.h" +#include "otlcommn.h" + + /* forward declaration */ + static OTL_ValidateFunc otl_gpos_validate_funcs[]; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** VALUE RECORDS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static OTL_UInt + otl_value_length( OTL_UInt format ) + { + FT_UInt count; + + count = (( format & 0xAA ) >> 1) + ( format & 0x55 ); + count = (( count & 0xCC ) >> 2) + ( count & 0x33 ); + count = (( count & 0xF0 ) >> 4) + ( count & 0x0F ); + + return count; + } + + + static void + otl_value_validate( OTL_Bytes table, + OTL_Bytes pos_table, + OTL_UInt format, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, device; + + if ( format >= 0x100U ) + OTL_INVALID_DATA; + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + OTL_CHECK( 2 ); + p += 2; + } + + format >>= 1; + } + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + OTL_CHECK( 2 ); + device = OTL_NEXT_USHORT( p ); + if ( device ) + otl_device_table_validate( pos_table + device, valid ); + } + format >>= 1; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ANCHORS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_anchor_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 6 ); + format = OTL_NEXT_USHORT( p ); + p += 4; + + switch ( format ) + { + case 1: + break; + + case 2: + OTL_CHECK( 2 ); /* anchor point */ + break; + + case 3: + { + OTL_UInt x_device, y_device; + + OTL_CHECK( 4 ); + x_device = OTL_NEXT_USHORT( p ); + y_device = OTL_NEXT_USHORT( p ); + + if ( x_device ) + otl_device_table_validate( table + x_device, valid ); + + if ( y_device ) + otl_device_table_validate( table + y_device, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** MARK ARRAY *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_mark_array_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count * 4 ); + for ( ; count > 0; count-- ) + { + p += 2; /* ignore class index */ + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 1 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup1_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + FT_UInt coverage, value_format; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + value_format = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + otl_value_validate( p, table, value_format, valid ); + } + break; + + case 2: + { + FT_UInt coverage, value_format, count, len; + + OTL_CHECK( 6 ); + coverage = OTL_NEXT_USHORT( p ); + value_format = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + len = otl_value_length( value_format ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count * len ); + for ( ; count > 0; count-- ) + { + otl_value_validate( p, table, value_format, valid ); + p += len; + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 2 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static otl_gpos_pairset_validate( OTL_Bytes table, + OTL_Bytes pos_table, + OTL_UInt format1, + OTL_UInt format2, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt len1, len2, count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + len1 = otl_value_length( format1 ); + len2 = otl_value_length( format2 ); + + OTL_CHECK( count * (len1+len2+2) ); + for ( ; count > 0; count-- ) + { + p += 2; /* ignore glyph id */ + otl_value_validate( p, pos_table, format1, valid ); + p += len1; + + otl_value_validate( p, pos_table, format2, valid ); + p += len2; + } + } + + static void + otl_gpos_lookup2_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, value1, value2, count; + + OTL_CHECK( 8 ); + coverage = OTL_NEXT_USHORT( p ); + value1 = OTL_NEXT_USHORT( p ); + value2 = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + { + otl_gpos_pairset_validate( table + OTL_NEXT_USHORT( p ), + table, value1, value2, valid ); + } + } + break; + + case 2: + { + OTL_UInt coverage, value1, value2, class1, class2, count1, count2; + OTL_UInt len1, len2; + + OTL_CHECK( 14 ); + coverage = OTL_NEXT_USHORT( p ); + value1 = OTL_NEXT_USHORT( p ); + value2 = OTL_NEXT_USHORT( p ); + class1 = OTL_NEXT_USHORT( p ); + class2 = OTL_NEXT_USHORT( p ); + count1 = OTL_NEXT_USHORT( p ); + count2 = OTL_NEXT_USHORT( p ); + + len1 = otl_value_length( value1 ); + len2 = otl_value_length( value2 ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count1*count2*(len1+len2) ); + for ( ; count1 > 0; count1-- ) + { + for ( ; count2 > 0; count2-- ) + { + otl_value_validate( p, table, value1, valid ); + p += len1; + + otl_value_validate( p, table, value2, valid ); + p += len2; + } + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 3 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup3_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count, anchor1, anchor2; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*4 ); + for ( ; count > 0; count-- ) + { + anchor1 = OTL_NEXT_USHORT( p ); + anchor2 = OTL_NEXT_USHORT( p ); + + if ( anchor1 ) + otl_anchor_validate( table + anchor1, valid ); + + if ( anchor2 ) + otl_anchor_validate( table + anchor2, valid ); + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 4 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_base_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; count2 > 0; count2-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + static void + otl_gpos_lookup4_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt mark_coverage, base_coverage, class_count; + OTL_UInt mark_array, base_array; + + OTL_CHECK( 10 ); + mark_coverage = OTL_NEXT_USHORT( p ); + base_coverage = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + mark_array = OTL_NEXT_USHORT( p ); + base_array = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + mark_coverage, valid ); + otl_coverage_validate( table + base_coverage, valid ); + + otl_mark_array_validate( table + mark_array, valid ); + otl_base_array_validate( table, class_count, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 5 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_liga_attach_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; class_count > 0; class_count-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_liga_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_liga_attach_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup5_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt mark_coverage, lig_coverage, class_count; + OTL_UInt mar_array, lig_array; + + OTL_CHECK( 10 ); + mark_coverage = OTL_NEXT_USHORT( p ); + liga_coverage = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + mark_array = OTL_NEXT_USHORT( p ); + liga_array = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + mark_coverage, valid ); + otl_coverage_validate( table + liga_coverage, valid ); + + otl_mark_array_validate( table + mark_array, valid ); + otl_liga_array_validate( table + liga_array, class_count, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 6 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + static void + otl_mark2_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; class_count > 0; class_count-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup6_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage1, coverage2, class_count, array1, array2; + + OTL_CHECK( 10 ); + coverage1 = OTL_NEXT_USHORT( p ); + coverage2 = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + array1 = OTL_NEXT_USHORT( p ); + array2 = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage1, valid ); + otl_coverage_validate( table + coverage2, valid ); + + otl_mark_array_validate( table + array1, valid ); + otl_mark2_array_validate( table + array2, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 7 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_pos_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + pos_count*4 ); + + /* XXX: check glyph indices and pos lookups */ + } + + + static void + otl_pos_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid ); + } + + + + static void + otl_pos_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + pos_count*4 ); + + /* XXX: check glyph indices and pos lookups */ + } + + + static void + otl_pos_class_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid ); + } + + + static void + otl_gpos_lookup7_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + case 2: + { + OTL_UInt coverage, class_def, count; + + OTL_CHECK( 6 ); + coverage = OTL_NEXT_USHORT( p ); + class_def = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate ( table + coverage, valid ); + otl_class_definition_validate( table + class_def, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_ + } + break; + + case 3: + { + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( glyph_count*2 + pos_count*4 ); + for ( ; glyph_count > 0; glyph_count ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + /* XXX: check pos lookups */ + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 8 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_chain_pos_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, pos_count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( back_count*2 + 2 ); + p += back_count*2; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( input_count*2 ); + p += (input_count-1)*2; + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( ahead_count*2 + 2 ); + p += ahead_count*2; + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + + + static void + otl_chain_pos_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + + static void + otl_chain_pos_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, pos_count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( back_count*2 + 2 ); + p += back_count*2; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( input_count*2 ); + p += (input_count-1)*2; + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( ahead_count*2 + 2 ); + p += ahead_count*2; + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + + + static void + otl_chain_pos_class_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_pos_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup8_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), + valid ); + } + break; + + case 2: + { + OTL_UInt coverage, back_class, input_class, ahead_class, count; + + OTL_CHECK( 10 ); + coverage = OTL_NEXT_USHORT( p ); + back_class = OTL_NEXT_USHORT( p ); + input_class = OTL_NEXT_USHORT( p ); + ahead_class = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + otl_class_definition_validate( table + back_class, valid ); + otl_class_definition_validate( table + input_class, valid ); + otl_class_definition_validate( table + ahead_class, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_chain_pos_class_set_validate( table + OTL_NEXT_USHORT( p ), + valid ); + } + break; + + case 3: + { + OTL_UInt back_count, input_count, ahead_count, pos_count, count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*back_count+2 ); + for ( count = back_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + input_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*input_count+2 ); + for ( count = input_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + ahead_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*ahead_count+2 ); + for ( count = ahead_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 9 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup9_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt lookup_type, lookup_offset; + OTL_ValidateFunc validate; + + OTL_CHECK( 6 ); + lookup_type = OTL_NEXT_USHORT( p ); + lookup_offset = OTL_NEXT_ULONG( p ); + + if ( lookup_type == 0 || lookup_type >= 9 ) + OTL_INVALID_DATA; + + validate = otl_gpos_validate_funcs[ lookup_type-1 ]; + validate( table + lookup_offset, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + static OTL_ValidateFunc otl_gpos_validate_funcs[ 9 ] = + { + otl_gpos_lookup1_validate, + otl_gpos_lookup2_validate, + otl_gpos_lookup3_validate, + otl_gpos_lookup4_validate, + otl_gpos_lookup5_validate, + otl_gpos_lookup6_validate, + otl_gpos_lookup7_validate, + otl_gpos_lookup8_validate, + otl_gpos_lookup9_validate, + }; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS TABLE *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_gpos_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt scripts, features, lookups; + + OTL_CHECK( 10 ); + + if ( OTL_NEXT_USHORT( p ) != 0x10000UL ) + OTL_INVALID_DATA; + + scripts = OTL_NEXT_USHORT( p ); + features = OTL_NEXT_USHORT( p ); + lookups = OTL_NEXT_USHORT( p ); + + otl_script_list_validate ( table + scripts, valid ); + otl_feature_list_validate( table + features, valid ); + + otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs, + valid ); + } + \ No newline at end of file diff --git a/lib/freetype/src/otlayout/otlgpos.h b/lib/freetype/src/otlayout/otlgpos.h new file mode 100644 index 0000000..1d10cab --- /dev/null +++ b/lib/freetype/src/otlayout/otlgpos.h @@ -0,0 +1,14 @@ +#ifndef __OTL_GPOS_H__ +#define __OTL_GPOS_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + OTL_LOCAL( void ) + otl_gpos_validate( OTL_Bytes table, + OTL_Validator valid ); + +OTL_END_HEADER + +#endif /* __OTL_GPOS_H__ */ diff --git a/lib/freetype/src/otlayout/otlgsub.c b/lib/freetype/src/otlayout/otlgsub.c new file mode 100644 index 0000000..817760a --- /dev/null +++ b/lib/freetype/src/otlayout/otlgsub.c @@ -0,0 +1,867 @@ +#include "otlgsub.h" +#include "otlcommn.h" + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 1 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + /* + * 1: Single Substitution - Table format(s) + * + * This table is used to substiture individual glyph indices + * with another one. There are only two sub-formats: + * + * Name Offset Size Description + * ------------------------------------------ + * format 0 2 sub-table format (1) + * offset 2 2 offset to coverage table + * delta 4 2 16-bit delta to apply on all + * covered glyph indices + * + * Name Offset Size Description + * ------------------------------------------ + * format 0 2 sub-table format (2) + * offset 2 2 offset to coverage table + * count 4 2 coverage table count + * substs[] 6 2*count substituted glyph indices, + * + */ + + static void + otl_gsub_lookup1_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + } + break; + + case 2: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( 2*count ); + + /* NB: we don't check that there are at most 'count' */ + /* elements in the coverage table. This is delayed */ + /* to the lookup function... */ + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + static OTL_Bool + otl_gsub_lookup1_apply( OTL_Bytes table, + OTL_Parser parser ) + { + OTL_Bytes p = table; + OTL_Bytes coverage; + OTL_UInt format, gindex, property; + OTL_Int index; + OTL_Bool subst = 0; + + if ( parser->context_len != 0xFFFF && parser->context_len < 1 ) + goto Exit; + + gindex = otl_parser_get_gindex( parser ); + + if ( !otl_parser_check_property( parser, gindex, &property ) ) + goto Exit; + + format = OTL_NEXT_USHORT(p); + coverage = table + OTL_NEXT_USHORT(p); + index = otl_coverage_lookup( coverage, gindex ); + + if ( index >= 0 ) + { + switch ( format ) + { + case 1: + { + OTL_Int delta = OTL_NEXT_SHORT(p); + + gindex = ( gindex + delta ) & 0xFFFF; + otl_parser_replace_1( parser, gindex ); + subst = 1; + } + break; + + case 2: + { + OTL_UInt count = OTL_NEXT_USHORT(p); + + if ( (OTL_UInt) index < count ) + { + p += index*2; + otl_parser_replace_1( parser, OTL_PEEK_USHORT(p) ); + subst = 1; + } + } + break; + + default: + ; + } + } + Exit: + return subst; + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 2 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + /* + * 2: Multiple Substitution - Table format(s) + * + * Replaces a single glyph with one or more glyphs. + * + * Name Offset Size Description + * ----------------------------------------------------------- + * format 0 2 sub-table format (1) + * offset 2 2 offset to coverage table + * count 4 2 coverage table count + * sequencess[] 6 2*count offsets to sequence items + * + * each sequence item has the following format: + * + * Name Offset Size Description + * ----------------------------------------------------------- + * count 0 2 number of replacement glyphs + * gindices[] 2 2*count string of glyph indices + */ + + static void + otl_seq_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + /* XXX: according to the spec, 'count' should be > 0 */ + /* we can deal with these cases pretty well however */ + + OTL_CHECK( 2*count ); + /* check glyph indices */ + } + + + static void + otl_gsub_lookup2_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage, seq_count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + seq_count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( seq_count*2 ); + for ( ; seq_count > 0; seq_count-- ) + otl_seq_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + static OTL_Bool + otl_gsub_lookup2_apply( OTL_Bytes table, + OTL_Parser parser ) + { + OTL_Bytes p = table; + OTL_Bytes coverage, sequence; + OTL_UInt format, gindex, index, property; + OTL_Int index; + OTL_Bool subst = 0; + + if ( context_len != 0xFFFF && context_len < 1 ) + goto Exit; + + gindex = otl_parser_get_gindex( parser ); + + if ( !otl_parser_check_property( parser, gindex, &property ) ) + goto Exit; + + p += 2; /* skip format */ + coverage = table + OTL_NEXT_USHORT(p); + seq_count = OTL_NEXT_USHORT(p); + index = otl_coverage_lookup( coverage, gindex ); + + if ( (OTL_UInt) index >= seq_count ) + goto Exit; + + p += index*2; + sequence = table + OTL_PEEK_USHORT(p); + p = sequence; + count = OTL_NEXT_USHORT(p); + + otl_parser_replace_n( parser, count, p ); + subst = 1; + + Exit: + return subst; + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 3 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + /* + * 3: Alternate Substitution - Table format(s) + * + * Replaces a single glyph by another one taken liberally + * in a list of alternatives + * + * Name Offset Size Description + * ----------------------------------------------------------- + * format 0 2 sub-table format (1) + * offset 2 2 offset to coverage table + * count 4 2 coverage table count + * alternates[] 6 2*count offsets to alternate items + * + * each alternate item has the following format: + * + * Name Offset Size Description + * ----------------------------------------------------------- + * count 0 2 number of replacement glyphs + * gindices[] 2 2*count string of glyph indices, each one + * is a valid alternative + */ + + static void + otl_alternate_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + /* XXX: check glyph indices */ + } + + + static void + otl_gsub_lookup3_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_alternate_set_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + static OTL_Bool + otl_gsub_lookup3_apply( OTL_Bytes table, + OTL_Parser parser ) + { + OTL_Bytes p = table; + OTL_Bytes coverage, alternates; + OTL_UInt format, gindex, index, property; + OTL_Int index; + OTL_Bool subst = 0; + + OTL_GSUB_Alternate alternate = parser->alternate; + + if ( context_len != 0xFFFF && context_len < 1 ) + goto Exit; + + if ( alternate == NULL ) + goto Exit; + + gindex = otl_parser_get_gindex( parser ); + + if ( !otl_parser_check_property( parser, gindex, &property ) ) + goto Exit; + + p += 2; /* skip format */ + coverage = table + OTL_NEXT_USHORT(p); + seq_count = OTL_NEXT_USHORT(p); + index = otl_coverage_lookup( coverage, gindex ); + + if ( (OTL_UInt) index >= seq_count ) + goto Exit; + + p += index*2; + alternates = table + OTL_PEEK_USHORT(p); + p = alternates; + count = OTL_NEXT_USHORT(p); + + gindex = alternate->handler_func( + gindex, count, p, alternate->handler_data ); + + otl_parser_replace_1( parser, gindex ); + subst = 1; + + Exit: + return subst; + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 4 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_ligature_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_UInt glyph_id, count; + + OTL_CHECK( 4 ); + glyph_id = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( 2*(count-1) ); + /* XXX: check glyph indices */ + } + + + static void + otl_ligature_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_ligature_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gsub_lookup4_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_ligature_set_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 5 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + static void + otl_sub_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt glyph_count, subst_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + subst_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + substcount*4 ); + + /* XXX: check glyph indices and subst lookups */ + } + + + static void + otl_sub_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_sub_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_UInt glyph_count, subst_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + subst_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + substcount*4 ); + + /* XXX: check glyph indices and subst lookups */ + } + + + static void + otl_sub_class_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_sub_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gsub_lookup5_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_sub_rule_set_validate( table + coverage, valid ); + } + break; + + case 2: + { + OTL_UInt coverage, class_def, count; + + OTL_CHECK( 6 ); + coverage = OTL_NEXT_USHORT( p ); + class_def = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate ( table + coverage, valid ); + otl_class_definition_validate( table + class_def, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_sub_class_rule_set_validate( table + coveragen valid ); + } + break; + + case 3: + { + OTL_UInt glyph_count, subst_count, count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + subst_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*glyph_count + 4*subst_count ); + for ( count = glyph_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 6 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + static void + otl_chain_sub_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, subst_count, count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*back_count+2 ); + p += 2*back_count; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( 2*input_count ); + p += 2*(input_count-1); + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( 2*ahead_count + 2 ); + p += 2*ahead_count; + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( 4*count ); + + /* XXX: check glyph indices and subst lookups */ + } + + + static void + otl_chain_sub_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_chain_sub_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, subst_count, count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*back_count+2 ); + p += 2*back_count; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( 2*input_count ); + p += 2*(input_count-1); + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( 2*ahead_count + 2 ); + p += 2*ahead_count; + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( 4*count ); + + /* XXX: check class indices and subst lookups */ + } + + + + static void + otl_chain_sub_class_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gsub_lookup6_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_sub_rule_set_validate( table + coverage, valid ); + } + break; + + case 2: + { + OTL_UInt coverage, back_class, input_class, ahead_class, count; + + OTL_CHECK( 10 ); + coverage = OTL_NEXT_USHORT( p ); + back_class = OTL_NEXT_USHORT( p ); + input_class = OTL_NEXT_USHORT( p ); + ahead_class = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + otl_class_definition_validate( table + back_class, valid ); + otl_class_definition_validate( table + input_class, valid ); + otl_class_definition_validate( table + ahead_class, valid ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_sub_class_set( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + case 3: + { + OTL_UInt back_count, input_count, ahead_count, subst_count, count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*back_count+2 ); + for ( count = back_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + input_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*input_count+2 ); + for ( count = input_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + ahead_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*ahead_count+2 ); + for ( count = ahead_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + subst_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( subst_count*4 ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB LOOKUP TYPE 6 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gsub_lookup7_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format, coverage; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt lookup_type, lookup_offset; + OTL_ValidateFunc validate; + + OTL_CHECK( 6 ); + lookup_type = OTL_NEXT_USHORT( p ); + lookup_offset = OTL_NEXT_ULONG( p ); + + if ( lookup_type == 0 || lookup_type >= 7 ) + OTL_INVALID_DATA; + + validate = otl_gsub_validate_funcs[ lookup_type-1 ]; + validate( table + lookup_offset, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + static const OTL_ValidateFunc otl_gsub_validate_funcs[ 7 ] = + { + otl_gsub_lookup1_validate, + otl_gsub_lookup2_validate, + otl_gsub_lookup3_validate, + otl_gsub_lookup4_validate, + otl_gsub_lookup5_validate, + otl_gsub_lookup6_validate + }; + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GSUB TABLE *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_gsub_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt scripts, features, lookups; + + OTL_CHECK( 10 ); + + if ( OTL_NEXT_USHORT( p ) != 0x10000UL ) + OTL_INVALID_DATA; + + scripts = OTL_NEXT_USHORT( p ); + features = OTL_NEXT_USHORT( p ); + lookups = OTL_NEXT_USHORT( p ); + + otl_script_list_validate ( table + scripts, valid ); + otl_feature_list_validate( table + features, valid ); + + otl_lookup_list_validate( table + lookups, 7, otl_gsub_validate_funcs, + valid ); + } diff --git a/lib/freetype/src/otlayout/otlgsub.h b/lib/freetype/src/otlayout/otlgsub.h new file mode 100644 index 0000000..db5edec --- /dev/null +++ b/lib/freetype/src/otlayout/otlgsub.h @@ -0,0 +1,26 @@ +#ifndef __OTL_GSUB_H__ +#define __OTL_GSUB_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + typedef OTL_UInt (*OTL_GSUB_AlternateFunc)( OTL_UInt gindex, + OTL_UInt count, + OTL_Bytes alternates, + OTL_Pointer data ); + + typedef struct OTL_GSUB_AlternateRec_ + { + OTL_GSUB_AlternateFunc handler_func; + OTL_Pointer handler_data; + + } OTL_GSUB_AlternateRec, *OTL_GSUB_Alternate; + + OTL_LOCAL( void ) + otl_gsub_validate( OTL_Bytes table, + OTL_Validator valid ); + +OTL_END_HEADER + +#endif /* __OTL_GSUB_H__ */ diff --git a/lib/freetype/src/otlayout/otljstf.c b/lib/freetype/src/otlayout/otljstf.c new file mode 100644 index 0000000..b0fa9f4 --- /dev/null +++ b/lib/freetype/src/otlayout/otljstf.c @@ -0,0 +1,189 @@ +#include "otljstf.h" +#include "otlcommn.h" +#include "otlgpos.h" + + static void + otl_jstf_extender_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + } + + + static void + otl_jstf_gsub_mods_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count*2 ); + + /* XXX: check GSUB lookup indices */ + } + + + static void + otl_jstf_gpos_mods_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count*2 ); + + /* XXX: check GPOS lookup indices */ + } + + + static void + otl_jstf_max_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_gpos_subtable_check( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_jstf_priority_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt offset; + + OTL_CHECK( 20 ); + + /* shrinkage GSUB enable/disable */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gsub_mods_validate( table + val, valid ); + + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gsub_mods_validate( table + val, valid ); + + /* shrinkage GPOS enable/disable */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gpos_mods_validate( table + val, valid ); + + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gpos_mods_validate( table + val, valid ); + + /* shrinkage JSTF max */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_max_validate( table + val, valid ); + + /* extension GSUB enable/disable */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gsub_mods_validate( table + val, valid ); + + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gsub_mods_validate( table + val, valid ); + + /* extension GPOS enable/disable */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gpos_mods_validate( table + val, valid ); + + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_gpos_mods_validate( table + val, valid ); + + /* extension JSTF max */ + val = OTL_NEXT_USHORT( p ); + if ( val ) + otl_jstf_max_validate( table + val, valid ); + } + + static void + otl_jstf_lang_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_jstf_priority_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_jstf_script_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, extender, default_lang; + + OTL_CHECK( 6 ); + extender = OTL_NEXT_USHORT( p ); + default_lang = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( extender ) + otl_jstf_extender_validate( table + extender, valid ); + + if ( default_lang ) + otl_jstf_lang_validate( table + default_lang, valid ); + + OTL_CHECK( 6*count ); + + for ( ; count > 0; count-- ) + { + p += 4; /* ignore tag */ + otl_jstf_lang_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + } + + + OTL_LOCALDEF( void ) + otl_jstf_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 4 ); + + if ( OTL_NEXT_ULONG( p ) != 0x10000UL ) + OTL_INVALID_DATA; + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count*6 ); + + for ( ; count > 0; count++ ) + { + p += 4; /* ignore tag */ + otl_jstf_script_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + } + \ No newline at end of file diff --git a/lib/freetype/src/otlayout/otljstf.h b/lib/freetype/src/otlayout/otljstf.h new file mode 100644 index 0000000..c8a98a6 --- /dev/null +++ b/lib/freetype/src/otlayout/otljstf.h @@ -0,0 +1,14 @@ +#ifndef __OTL_JSTF_H__ +#define __OTL_JSTF_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + OTL_LOCAL( void ) + otl_jstf_validate( OTL_Bytes table, + OTL_Validator valid ); + +OTL_END_HEADER + +#endif /* __OTL_JSTF_H__ */ \ No newline at end of file diff --git a/lib/freetype/src/otlayout/otlparse.c b/lib/freetype/src/otlayout/otlparse.c new file mode 100644 index 0000000..705c0c6 --- /dev/null +++ b/lib/freetype/src/otlayout/otlparse.c @@ -0,0 +1,142 @@ +#include "otlparse.h" +#include "otlutils.h" + + static void + otl_string_ensure( OTL_String string, + OTL_UInt count, + OTL_Parser parser ) + { + count += string->length; + + if ( count > string->capacity ) + { + OTL_UInt old_count = string->capacity; + OTL_UInt new_count = old_count; + OTL_Memory memory = parser->memory; + + while ( new_count < count ) + new_count += (new_count >> 1) + 16; + + if ( OTL_MEM_RENEW_ARRAY( string->glyphs, old_count, new_count ) ) + otl_parser_error( parser, OTL_Parse_Err_Memory ); + + string->capacity = new_count; + } + } + +#define OTL_STRING_ENSURE(str,count,parser) \ + OTL_BEGIN_STMNT \ + if ( (str)->length + (count) > (str)>capacity ) \ + otl_string_ensure( str, count, parser ); \ + OTL_END_STMNT + + + OTL_LOCALDEF( OTL_UInt ) + otl_parser_get_gindex( OTL_Parser parser ) + { + OTL_String in = parser->str_in; + + if ( in->cursor >= in->num_glyphs ) + otl_parser_error( parser, OTL_Err_Parser_Internal ); + + return in->str[ in->cursor ].gindex; + } + + + OTL_LOCALDEF( void ) + otl_parser_error( OTL_Parser parser, + OTL_ParseError error; ) + { + parser->error = error; + otl_longjmp( parser->jump_buffer, 1 ); + } + +#define OTL_PARSER_UNCOVERED(x) otl_parser_error( x, OTL_Parse_Err_UncoveredGlyph ); + + OTL_LOCAL( void ) + otl_parser_check_property( OTL_Parser parser, + OTL_UInt gindex, + OTL_UInt flags, + OTL_UInt *aproperty ); + + OTL_LOCALDEF( void ) + otl_parser_replace_1( OTL_Parser parser, + OTL_UInt gindex ) + { + OTL_String in = parser->str_in; + OTL_String out = parser->str_out; + OTL_StringGlyph glyph, in_glyph; + + /* sanity check */ + if ( in == NULL || + out == NULL || + in->length == 0 || + in->cursor >= in->length ) + { + /* report as internal error, since these should */ + /* never happen !! */ + otl_parser_error( parser, OTL_Err_Parse_Internal ); + } + + OTL_STRING_ENSURE( out, 1, parser ); + glyph = out->glyphs + out->length; + in_glyph = in->glyphs + in->cursor; + + glyph->gindex = gindex; + glyph->property = in_glyph->property; + glyph->lig_component = in_glyph->lig_component; + glyph->lig_id = in_glyph->lig_id; + + out->length += 1; + out->cursor = out->length; + in->cursor += 1; + } + + OTL_LOCALDEF( void ) + otl_parser_replace_n( OTL_Parser parser, + OTL_UInt count, + OTL_Bytes indices ) + { + OTL_UInt lig_component, lig_id, property; + OTL_String in = parser->str_in; + OTL_String out = parser->str_out; + OTL_StringGlyph glyph, in_glyph; + OTL_Bytes p = indices; + + /* sanity check */ + if ( in == NULL || + out == NULL || + in->length == 0 || + in->cursor >= in->length ) + { + /* report as internal error, since these should */ + /* never happen !! */ + otl_parser_error( parser, OTL_Err_Parse_Internal ); + } + + OTL_STRING_ENSURE( out, count, parser ); + glyph = out->glyphs + out->length; + in_glyph = in->glyphs + in->cursor; + + glyph->gindex = gindex; + + lig_component = in_glyph->lig_component; + lig_id = in_glyph->lid_id; + property = in_glyph->property; + + for ( ; count > 0; count-- ) + { + glyph->gindex = OTL_NEXT_USHORT(p); + glyph->property = property; + glyph->lig_component = lig_component; + glyph->lig_id = lig_id; + + out->length ++; + } + + out->cursor = out->length; + in->cursor += 1; + } + + + diff --git a/lib/freetype/src/otlayout/otlparse.h b/lib/freetype/src/otlayout/otlparse.h new file mode 100644 index 0000000..92f34bf --- /dev/null +++ b/lib/freetype/src/otlayout/otlparse.h @@ -0,0 +1,99 @@ +#ifndef __OTL_PARSER_H__ +#define __OTL_PARSER_H__ + +#include "otlayout.h" +#include "otlgdef.h" +#include "otlgsub.h" +#include "otlgpos.h" + +OTL_BEGIN_HEADER + + typedef struct OTL_ParserRec_* OTL_Parser; + + typedef struct OTL_StringRec_* OTL_String; + + typedef struct OTL_StringGlyphRec_ + { + OTL_UInt gindex; + OTL_UInt properties; + OTL_UInt lig_component; + OTL_UInt lig_id; + + } OTL_StringGlyphRec, *OTL_StringGlyph; + + typedef struct OTL_StringRec_ + { + OTL_StringGlyph glyphs; + OTL_UInt cursor; + OTL_UInt length; + OTL_UInt capacity; + + } OTL_StringRec; + + typedef struct OTL_ParserRec_ + { + OTL_Bytes tab_gdef; + OTL_Bytes tab_gsub; + OTL_Bytes tab_gpos; + OTL_Bytes tab_base; + OTL_Bytes tab_jstf; + + OTL_Alternate alternate; /* external alternate handler */ + + OTL_UInt context_len; + OTL_UInt markup_flags; + + OTL_jmp_buf jump_buffer; + OTL_Memory memory; + OTL_Error error; + + OTL_StringRec strings[2]; + OTL_String str_in; + OTL_String str_out; + + } OTL_ParserRec; + + typedef enum + { + OTL_Err_Parser_Ok = 0, + OTL_Err_Parser_InvalidData, + OTL_Err_Parser_UncoveredGlyph + + } OTL_ParseError; + + OTL_LOCAL( OTL_UInt ) + otl_parser_get_gindex( OTL_Parser parser ); + + + OTL_LOCAL( void ) + otl_parser_error( OTL_Parser parser, OTL_ParserError error ); + +#define OTL_PARSER_UNCOVERED(x) \ + otl_parser_error( x, OTL_Err_Parser_UncoveredGlyph ) + + OTL_LOCAL( void ) + otl_parser_check_property( OTL_Parser parser, + OTL_UInt gindex, + OTL_UInt flags, + OTL_UInt *aproperty ); + + /* copy current input glyph to output */ + OTL_LOCAL( void ) + otl_parser_copy_1( OTL_Parser parser ); + + /* copy current input glyph to output, replacing its index */ + OTL_LOCAL( void ) + otl_parser_replace_1( OTL_Parser parser, + OTL_UInt gindex ); + + /* copy current input glyph to output, replacing it by several indices */ + /* read directly from the table */ + OTL_LOCAL( void ) + otl_parser_replace_n( OTL_Parser parser, + OTL_UInt count, + OTL_Bytes indices ); + +OTL_END_HEADER + +#endif /* __OTL_PARSER_H__ */ + diff --git a/lib/freetype/src/otlayout/otltable.h b/lib/freetype/src/otlayout/otltable.h new file mode 100644 index 0000000..af7bd78 --- /dev/null +++ b/lib/freetype/src/otlayout/otltable.h @@ -0,0 +1,60 @@ +#ifndef __OTL_TABLE_H__ +#define __OTL_TABLE_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + typedef struct OTL_TableRec_* OTL_Table; + + typedef enum + { + OTL_TABLE_TYPE_GDEF = 1, + OTL_TABLE_TYPE_GSUB, + OTL_TABLE_TYPE_GPOS, + OTL_TABLE_TYPE_BASE, + OTL_TABLE_TYPE_JSTF + + } OTL_TableType; + + + /* this may become a private structure later */ + typedef struct OTL_TableRec_ + { + OTL_TableType type; + OTL_Bytes base; + OTL_Bytes limit; + + OTL_Tag script_tag; + OTL_Tag lang_tag; + + OTL_UInt lookup_count; + OTL_Byte* lookup_flags; + + OTL_UInt feature_count; + OTL_Tag feature_tags; + OTL_Byte* feature_flags; + + } OTL_TableRec; + + + OTL_API( OTL_Error ) + otl_table_validate( OTL_Bytes table, + OTL_Size size, + OTL_TableType type, + OTL_Size *abyte_size ); + + OTL_API( void ) + otl_table_init( OTL_Table table, + OTL_TableType type, + OTL_Bytes base, + OTL_Size size ); + + OTL_API( void ) + otl_table_set_script( OTL_Table table, + OTL_ScriptTag script, + OTL_LangTag language ); + +OTL_END_HEADER + +#endif /* __OTL_TABLE_H__ */ diff --git a/lib/freetype/src/otlayout/otltags.h b/lib/freetype/src/otlayout/otltags.h new file mode 100644 index 0000000..d954b58 --- /dev/null +++ b/lib/freetype/src/otlayout/otltags.h @@ -0,0 +1,88 @@ +/* this file may be included several times by other parts of */ +/* the OpenType Layout library.. don't add #ifdef .. #endif */ +/* delimiters to it... */ + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** SCRIPT TAGS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#ifndef OTL_SCRIPT_TAG +#define OTL_SCRIPT_TAG(c1,c2,c3,c4,s,n) /* void */ +#endif + +OTL_SCRIPT_TAG( 'a','r','a','b', "Arabic", ARABIC ) +OTL_SCRIPT_TAG( 'a','r','m','n', "Armenian", ARMENIAN ) +OTL_SCRIPT_TAG( 'b','e','n','g', "Bengali", BENGALI ) +OTL_SCRIPT_TAG( 'b','o','p','o', "Bopomofo", BOPOMOFO ) +OTL_SCRIPT_TAG( 'b','r','a','i', "Braille", BRAILLE ) +OTL_SCRIPT_TAG( 'b','y','z','m', "Byzantine Music", BYZANTINE_MUSIC ) +OTL_SCRIPT_TAG( 'c','a','n','s', "Canadian Syllabic", CANADIAN ) +OTL_SCRIPT_TAG( 'c','h','e','r', "Cherokee", CHEROKEE ) +OTL_SCRIPT_TAG( 'h','a','n','i', "CJK Ideographic", CJK ) +OTL_SCRIPT_TAG( 'c','y','r','l', "Cyrillic", CYRILLIC ) +OTL_SCRIPT_TAG( 'd','f','l','t', "Default", DEFAULT ) +OTL_SCRIPT_TAG( 'd','e','v','a', "Devanagari", DEVANAGARI ) +OTL_SCRIPT_TAG( 'e','t','h','i', "Ethiopic", ETHIOPIC ) +OTL_SCRIPT_TAG( 'g','e','o','r', "Georgian", GEORGIAN ) +OTL_SCRIPT_TAG( 'g','r','e','k', "Greek", GREEK ) +OTL_SCRIPT_TAG( 'g','u','j','r', "Gujarati", GUJARATI ) +OTL_SCRIPT_TAG( 'g','u','r','u', "Gurmukhi", GURMUKHI ) +OTL_SCRIPT_TAG( 'j','a','m','o', "Hangul Jamo", JAMO ) +OTL_SCRIPT_TAG( 'h','a','n','g', "Hangul", HANGUL ) +OTL_SCRIPT_TAG( 'h','e','b','r', "Hebrew", HEBREW ) +OTL_SCRIPT_TAG( 'h','i','r','a', "Hiragana", HIRAGANA ) /* not in TAGS.txt */ +OTL_SCRIPT_TAG( 'k','n','d','a', "Kannada", KANNADA ) +OTL_SCRIPT_TAG( 'k','a','n','a', "Katakana", KATAKANA ) /* in TAGS.txt, means Hiragana _and_ Katakana */ +OTL_SCRIPT_TAG( 'k','h','m','r', "Khmer", KHMER ) +OTL_SCRIPT_TAG( 'l','a','o',' ', "Lao", LAO ) +OTL_SCRIPT_TAG( 'l','a','t','n', "Latin", LATIN ) +OTL_SCRIPT_TAG( 'm','l','y','m', "Malayalam", MALAYALAM ) +OTL_SCRIPT_TAG( 'm','o','n','g', "Mongolian", MONGOLIAN ) +OTL_SCRIPT_TAG( 'm','y','m','r', "Myanmar", MYANMAR ) +OTL_SCRIPT_TAG( 'o','g','a','m', "Ogham", OGHAM ) +OTL_SCRIPT_TAG( 'o','r','y','a', "Oriya", ORIYA ) +OTL_SCRIPT_TAG( 'r','u','n','r', "Runic", RUNIC ) +OTL_SCRIPT_TAG( 's','i','n','h', "Sinhala", SINHALA ) +OTL_SCRIPT_TAG( 's','y','r','c', "Syriac", SYRIAC ) +OTL_SCRIPT_TAG( 't','a','m','l', "Tamil", TAMIL ) +OTL_SCRIPT_TAG( 't','e','l','u', "Telugu", TELUGU ) +OTL_SCRIPT_TAG( 't','h','a','a', "Thaana", THAANA ) +OTL_SCRIPT_TAG( 't','h','a','i', "Thai", THAI ) +OTL_SCRIPT_TAG( 't','i','b','t', "Tibetan", TIBETAN ) +OTL_SCRIPT_TAG( 'y','i',' ',' ', "Yi", YI ) + +#undef OTL_SCRIPT_TAG + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** LANGUAGE TAGS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#ifndef OTL_LANG_TAG +#define OTL_LANG_TAG(c1,c2,c3,c4,s,n) /* void */ +#endif + +#undef OTL_LANG_TAG + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** FEATURE TAGS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#ifndef OTL_FEATURE_TAG +#define OTL_FEATURE_TAG(c1,c2,c3,c4,s,n) /* void */ +#endif + +#undef OTL_FEATURE_TAG + diff --git a/lib/freetype/src/otlayout/otlutils.h b/lib/freetype/src/otlayout/otlutils.h new file mode 100644 index 0000000..de50f66 --- /dev/null +++ b/lib/freetype/src/otlayout/otlutils.h @@ -0,0 +1,33 @@ +#ifndef __OTLAYOUT_UTILS_H__ +#define __OTLAYOUT_UTILS_H__ + +#include "otlayout.h" + +OTL_BEGIN_HEADER + + OTL_LOCAL( OTL_Error ) + otl_mem_alloc( OTL_Pointer* pblock, + OTL_ULong size, + OTL_Memory memory ); + + OTL_LOCAL( void ) + otl_mem_free( OTL_Pointer* pblock, + OTL_Memory memory ); + + OTL_LOCAL( OTL_Error ) + otl_mem_realloc( OTL_Pointer *pblock, + OTL_ULong cur_size, + OTL_ULong new_size, + OTL_Memory memory ); + +#define OTL_MEM_ALLOC(p,s) otl_mem_alloc( (void**)&(p), (s), memory ) +#define OTL_MEM_FREE(p) otl_mem_free( (void**)&(p), memory ) +#define OTL_MEM_REALLOC(p,c,n) otl_mem_realloc( (void**)&(p), (c), (s), memory ) + +#define OTL_MEM_NEW(p) OTL_MEM_ALLOC(p,sizeof(*(p))) +#define OTL_MEM_NEW_ARRAY(p,c) OTL_MEM_ALLOC(p,(c)*sizeof(*(p))) +#define OTL_MEM_RENEW_ARRAY(p,c,n) OTL_MEM_REALLOC(p,(c)*sizeof(*(p)),(n)*sizeof(*(p))) + +OTL_END_HEADER + +#endif /* __OTLAYOUT_UTILS_H__ */ diff --git a/lib/freetype/src/pcf/Jamfile b/lib/freetype/src/pcf/Jamfile new file mode 100644 index 0000000..fd77625 --- /dev/null +++ b/lib/freetype/src/pcf/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/pcf Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) pcf ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pcfdriver pcfread pcfutil ; + } + else + { + _sources = pcf ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pcf Jamfile diff --git a/lib/freetype/src/pcf/descrip.mms b/lib/freetype/src/pcf/descrip.mms new file mode 100644 index 0000000..a3fd231 --- /dev/null +++ b/lib/freetype/src/pcf/descrip.mms @@ -0,0 +1,35 @@ +# +# FreeType 2 pcf driver compilation rules for VMS +# + + +# Copyright (C) 2001, 2002 by +# Francesco Zappa Nardelli +# +# 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 +# AUTHORS OR COPYRIGHT HOLDERS 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pcf]) + +OBJS=pcf.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/pcf/module.mk b/lib/freetype/src/pcf/module.mk new file mode 100644 index 0000000..614c319 --- /dev/null +++ b/lib/freetype/src/pcf/module.mk @@ -0,0 +1,32 @@ +# +# FreeType 2 PCF module definition +# + +# Copyright 2000 by +# Francesco Zappa Nardelli +# +# 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 +# AUTHORS OR COPYRIGHT HOLDERS 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. + +make_module_list: add_pcf_driver + +add_pcf_driver: + $(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)pcf $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/pcf/pcf.c b/lib/freetype/src/pcf/pcf.c new file mode 100644 index 0000000..315655e --- /dev/null +++ b/lib/freetype/src/pcf/pcf.c @@ -0,0 +1,36 @@ +/* pcf.c + + FreeType font driver for pcf fonts + + Copyright 2000-2001 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + + +#include <ft2build.h> +#include "pcfutil.c" +#include "pcfread.c" +#include "pcfdriver.c" + +/* END */ diff --git a/lib/freetype/src/pcf/pcf.h b/lib/freetype/src/pcf/pcf.h new file mode 100644 index 0000000..1b7b585 --- /dev/null +++ b/lib/freetype/src/pcf/pcf.h @@ -0,0 +1,237 @@ +/* pcf.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000-2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __PCF_H__ +#define __PCF_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + typedef struct PCF_TableRec_ + { + FT_ULong type; + FT_ULong format; + FT_ULong size; + FT_ULong offset; + + } PCF_TableRec, *PCF_Table; + + + typedef struct PCF_TocRec_ + { + FT_ULong version; + FT_ULong count; + PCF_Table tables; + + } PCF_TocRec, *PCF_Toc; + + + typedef struct PCF_ParsePropertyRec_ + { + FT_Long name; + FT_Byte isString; + FT_Long value; + + } PCF_ParsePropertyRec, *PCF_ParseProperty; + + + typedef struct PCF_PropertyRec_ + { + FT_String* name; + FT_Byte isString; + + union + { + FT_String* atom; + FT_Long integer; + FT_ULong cardinal; + + } value; + + } PCF_PropertyRec, *PCF_Property; + + + typedef struct PCF_Compressed_MetricRec_ + { + FT_Byte leftSideBearing; + FT_Byte rightSideBearing; + FT_Byte characterWidth; + FT_Byte ascent; + FT_Byte descent; + + } PCF_Compressed_MetricRec, *PCF_Compressed_Metric; + + + typedef struct PCF_MetricRec_ + { + FT_Short leftSideBearing; + FT_Short rightSideBearing; + FT_Short characterWidth; + FT_Short ascent; + FT_Short descent; + FT_Short attributes; + FT_ULong bits; + + } PCF_MetricRec, *PCF_Metric; + + + typedef struct PCF_AccelRec_ + { + FT_Byte noOverlap; + FT_Byte constantMetrics; + FT_Byte terminalFont; + FT_Byte constantWidth; + FT_Byte inkInside; + FT_Byte inkMetrics; + FT_Byte drawDirection; + FT_Long fontAscent; + FT_Long fontDescent; + FT_Long maxOverlap; + PCF_MetricRec minbounds; + PCF_MetricRec maxbounds; + PCF_MetricRec ink_minbounds; + PCF_MetricRec ink_maxbounds; + + } PCF_AccelRec, *PCF_Accel; + + + typedef struct PCD_EncodingRec_ + { + FT_Long enc; + FT_Short glyph; + + } PCF_EncodingRec, *PCF_Encoding; + + + typedef struct PCF_FaceRec_ + { + FT_FaceRec root; + + FT_StreamRec gzip_stream; + FT_Stream gzip_source; + + char* charset_encoding; + char* charset_registry; + + PCF_TocRec toc; + PCF_AccelRec accel; + + int nprops; + PCF_Property properties; + + FT_Long nmetrics; + PCF_Metric metrics; + FT_Long nencodings; + PCF_Encoding encodings; + + FT_Short defaultChar; + + FT_ULong bitmapsFormat; + + FT_CharMap charmap_handle; + FT_CharMapRec charmap; /* a single charmap per face */ + + } PCF_FaceRec, *PCF_Face; + + + /* macros for pcf font format */ + +#define LSBFirst 0 +#define MSBFirst 1 + +#define PCF_FILE_VERSION ( ( 'p' << 24 ) | \ + ( 'c' << 16 ) | \ + ( 'f' << 8 ) | 1 ) +#define PCF_FORMAT_MASK 0xFFFFFF00L + +#define PCF_DEFAULT_FORMAT 0x00000000L +#define PCF_INKBOUNDS 0x00000200L +#define PCF_ACCEL_W_INKBOUNDS 0x00000100L +#define PCF_COMPRESSED_METRICS 0x00000100L + +#define PCF_FORMAT_MATCH( a, b ) \ + ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) ) + +#define PCF_GLYPH_PAD_MASK ( 3 << 0 ) +#define PCF_BYTE_MASK ( 1 << 2 ) +#define PCF_BIT_MASK ( 1 << 3 ) +#define PCF_SCAN_UNIT_MASK ( 3 << 4 ) + +#define PCF_BYTE_ORDER( f ) \ + ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_BIT_ORDER( f ) \ + ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst ) +#define PCF_GLYPH_PAD_INDEX( f ) \ + ( (f) & PCF_GLYPH_PAD_MASK ) +#define PCF_GLYPH_PAD( f ) \ + ( 1 << PCF_GLYPH_PAD_INDEX( f ) ) +#define PCF_SCAN_UNIT_INDEX( f ) \ + ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 ) +#define PCF_SCAN_UNIT( f ) \ + ( 1 << PCF_SCAN_UNIT_INDEX( f ) ) +#define PCF_FORMAT_BITS( f ) \ + ( (f) & ( PCF_GLYPH_PAD_MASK | \ + PCF_BYTE_MASK | \ + PCF_BIT_MASK | \ + PCF_SCAN_UNIT_MASK ) ) + +#define PCF_SIZE_TO_INDEX( s ) ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 ) +#define PCF_INDEX_TO_SIZE( b ) ( 1 << b ) + +#define PCF_FORMAT( bit, byte, glyph, scan ) \ + ( ( PCF_SIZE_TO_INDEX( scan ) << 4 ) | \ + ( ( (bit) == MSBFirst ? 1 : 0 ) << 3 ) | \ + ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \ + ( PCF_SIZE_TO_INDEX( glyph ) << 0 ) ) + +#define PCF_PROPERTIES ( 1 << 0 ) +#define PCF_ACCELERATORS ( 1 << 1 ) +#define PCF_METRICS ( 1 << 2 ) +#define PCF_BITMAPS ( 1 << 3 ) +#define PCF_INK_METRICS ( 1 << 4 ) +#define PCF_BDF_ENCODINGS ( 1 << 5 ) +#define PCF_SWIDTHS ( 1 << 6 ) +#define PCF_GLYPH_NAMES ( 1 << 7 ) +#define PCF_BDF_ACCELERATORS ( 1 << 8 ) + +#define GLYPHPADOPTIONS 4 /* I'm not sure about this */ + + FT_LOCAL( FT_Error ) + pcf_load_font( FT_Stream, + PCF_Face ); + +FT_END_HEADER + +#endif /* __PCF_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfdriver.c b/lib/freetype/src/pcf/pcfdriver.c new file mode 100644 index 0000000..6f0b9e1 --- /dev/null +++ b/lib/freetype/src/pcf/pcfdriver.c @@ -0,0 +1,545 @@ +/* pcfdriver.c + + FreeType font driver for pcf files + + Copyright (C) 2000-2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_GZIP_H +#include FT_ERRORS_H +#include FT_BDF_H + +#include "pcf.h" +#include "pcfdriver.h" +#include "pcfutil.h" +#include "pcfread.h" + +#include "pcferror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfread + + + typedef struct PCF_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_encodings; + PCF_Encoding encodings; + + } PCF_CMapRec, *PCF_CMap; + + + FT_CALLBACK_DEF( FT_Error ) + pcf_cmap_init( PCF_CMap cmap ) + { + PCF_Face face = (PCF_Face)FT_CMAP_FACE( cmap ); + + + cmap->num_encodings = (FT_UInt)face->nencodings; + cmap->encodings = face->encodings; + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + pcf_cmap_done( PCF_CMap cmap ) + { + cmap->encodings = NULL; + cmap->num_encodings = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_index( PCF_CMap cmap, + FT_UInt32 charcode ) + { + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_UInt32 code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + break; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pcf_cmap_char_next( PCF_CMap cmap, + FT_UInt32 *acharcode ) + { + PCF_Encoding encodings = cmap->encodings; + FT_UInt min, max, mid; + FT_UInt32 charcode = *acharcode + 1; + FT_UInt result = 0; + + + min = 0; + max = cmap->num_encodings; + + while ( min < max ) + { + FT_UInt32 code; + + + mid = ( min + max ) >> 1; + code = encodings[mid].enc; + + if ( charcode == code ) + { + result = encodings[mid].glyph + 1; + goto Exit; + } + + if ( charcode < code ) + max = mid; + else + min = mid + 1; + } + + charcode = 0; + if ( min < cmap->num_encodings ) + { + charcode = encodings[min].enc; + result = encodings[min].glyph + 1; + } + + Exit: + *acharcode = charcode; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec pcf_cmap_class = + { + sizeof( PCF_CMapRec ), + (FT_CMap_InitFunc) pcf_cmap_init, + (FT_CMap_DoneFunc) pcf_cmap_done, + (FT_CMap_CharIndexFunc)pcf_cmap_char_index, + (FT_CMap_CharNextFunc) pcf_cmap_char_next + }; + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfdriver + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Face_Done( PCF_Face face ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( face->encodings ); + FT_FREE( face->metrics ); + + /* free properties */ + { + PCF_Property prop = face->properties; + FT_Int i; + + + for ( i = 0; i < face->nprops; i++ ) + { + prop = &face->properties[i]; + + FT_FREE( prop->name ); + if ( prop->isString ) + FT_FREE( prop->value ); + } + + FT_FREE( face->properties ); + } + + FT_FREE( face->toc.tables ); + FT_FREE( face->root.family_name ); + FT_FREE( face->root.available_sizes ); + FT_FREE( face->charset_encoding ); + FT_FREE( face->charset_registry ); + + FT_TRACE4(( "PCF_Face_Done: done face\n" )); + + /* close gzip stream if any */ + if ( face->root.stream == &face->gzip_stream ) + { + FT_Stream_Close( &face->gzip_stream ); + face->root.stream = face->gzip_source; + } + + return PCF_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + PCF_Face_Init( FT_Stream stream, + PCF_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error = PCF_Err_Ok; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + error = pcf_load_font( stream, face ); + if ( error ) + { + FT_Error error2; + + /* this didn't work, try gzip support !! */ + error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); + if ( error2 == FT_Err_Unimplemented_Feature ) + goto Fail; + + error = error2; + if ( error ) + goto Fail; + + face->gzip_source = stream; + face->root.stream = &face->gzip_stream; + + stream = face->root.stream; + + error = pcf_load_font( stream, face ); + if ( error ) + goto Fail; + } + + /* set-up charmap */ + { + FT_String *charset_registry, *charset_encoding; + FT_Bool unicode_charmap = 0; + + + charset_registry = face->charset_registry; + charset_encoding = face->charset_encoding; + + if ( ( charset_registry != NULL ) && + ( charset_encoding != NULL ) ) + { + if ( !ft_strcmp( face->charset_registry, "ISO10646" ) || + ( !ft_strcmp( face->charset_registry, "ISO8859" ) && + !ft_strcmp( face->charset_encoding, "1" ) ) ) + unicode_charmap = 1; + } + + { + FT_CharMapRec charmap; + + + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; + charmap.platform_id = 0; + charmap.encoding_id = 0; + + if ( unicode_charmap ) + { + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = 3; + charmap.encoding_id = 1; + } + + error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (face->root.num_charmaps) + face->root.charmap = face->root.charmaps[0]; +#endif + } + } + + Exit: + return error; + + Fail: + FT_TRACE2(( "[not a valid PCF file]\n" )); + error = PCF_Err_Unknown_File_Format; /* error */ + goto Exit; + } + + + static FT_Error + PCF_Set_Pixel_Size( FT_Size size ) + { + PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); + + + FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem, + face->root.available_sizes->height )); + + if ( size->metrics.y_ppem == face->root.available_sizes->height ) + { + size->metrics.ascender = face->accel.fontAscent << 6; + size->metrics.descender = face->accel.fontDescent * (-64); +#if 0 + size->metrics.height = face->accel.maxbounds.ascent << 6; +#endif + size->metrics.height = size->metrics.ascender - + size->metrics.descender; + + size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6; + + return PCF_Err_Ok; + } + else + { + FT_TRACE4(( "size WRONG\n" )); + return PCF_Err_Invalid_Pixel_Size; + } + } + + + static FT_Error + PCF_Glyph_Load( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); + FT_Stream stream = face->root.stream; + FT_Error error = PCF_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + PCF_Metric metric; + int bytes; + + FT_UNUSED( load_flags ); + + + FT_TRACE4(( "load_glyph %d ---", glyph_index )); + + if ( !face ) + { + error = PCF_Err_Invalid_Argument; + goto Exit; + } + + if ( glyph_index > 0 ) + glyph_index--; + + metric = face->metrics + glyph_index; + + bitmap->rows = metric->ascent + metric->descent; + bitmap->width = metric->rightSideBearing - metric->leftSideBearing; + bitmap->num_grays = 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", + PCF_BIT_ORDER( face->bitmapsFormat ), + PCF_BYTE_ORDER( face->bitmapsFormat ), + PCF_GLYPH_PAD( face->bitmapsFormat ) )); + + switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) + { + case 1: + bitmap->pitch = ( bitmap->width + 7 ) >> 3; + break; + + case 2: + bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; + break; + + case 4: + bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; + break; + + case 8: + bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; + break; + + default: + return PCF_Err_Invalid_File_Format; + } + + /* XXX: to do: are there cases that need repadding the bitmap? */ + bytes = bitmap->pitch * bitmap->rows; + + error = ft_glyphslot_alloc_bitmap( slot, bytes ); + if ( error ) + goto Exit; + + if ( FT_STREAM_SEEK( metric->bits ) || + FT_STREAM_READ( bitmap->buffer, bytes ) ) + goto Exit; + + if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) + BitOrderInvert( bitmap->buffer, bytes ); + + if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != + PCF_BIT_ORDER( face->bitmapsFormat ) ) ) + { + switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) + { + case 1: + break; + + case 2: + TwoByteSwap( bitmap->buffer, bytes ); + break; + + case 4: + FourByteSwap( bitmap->buffer, bytes ); + break; + } + } + + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = metric->characterWidth << 6 ; + slot->metrics.horiBearingX = metric->leftSideBearing << 6 ; + slot->metrics.horiBearingY = metric->ascent << 6 ; + slot->metrics.width = ( metric->rightSideBearing - + metric->leftSideBearing ) << 6; + slot->metrics.height = bitmap->rows << 6; + + slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + FT_TRACE4(( " --- ok\n" )); + + Exit: + return error; + } + + + static FT_Error + pcf_get_bdf_property( PCF_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ) + { + PCF_Property prop; + + prop = pcf_find_property( face, prop_name ); + if ( prop != NULL ) + { + if ( prop->isString ) + { + aproperty->type = BDF_PROPERTY_TYPE_ATOM; + aproperty->u.atom = prop->value.atom; + } + else + { + /* apparently, the PCF driver loads all properties as signed integers ! + * this really doesn't seem to be a problem, because this is + * sufficient for any meaningful values + */ + aproperty->type = BDF_PROPERTY_TYPE_INTEGER; + aproperty->u.integer = prop->value.integer; + } + return 0; + } + return FT_Err_Invalid_Argument; + } + + + static FT_Module_Interface + pcf_driver_requester( FT_Module module, + const char* name ) + { + FT_UNUSED( module ); + + if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 ) + return (FT_Module_Interface) pcf_get_bdf_property; + + return NULL; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pcf_driver_class = + { + { + ft_module_font_driver, + sizeof ( FT_DriverRec ), + + "pcf", + 0x10000L, + 0x20000L, + + 0, + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) pcf_driver_requester + }, + + sizeof( PCF_FaceRec ), + sizeof( FT_SizeRec ), + sizeof( FT_GlyphSlotRec ), + + (FT_Face_InitFunc) PCF_Face_Init, + (FT_Face_DoneFunc) PCF_Face_Done, + (FT_Size_InitFunc) 0, + (FT_Size_DoneFunc) 0, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, + + (FT_Size_ResetPointsFunc) PCF_Set_Pixel_Size, + (FT_Size_ResetPixelsFunc) PCF_Set_Pixel_Size, + + (FT_Slot_LoadFunc) PCF_Glyph_Load, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfdriver.h b/lib/freetype/src/pcf/pcfdriver.h new file mode 100644 index 0000000..7c45b91 --- /dev/null +++ b/lib/freetype/src/pcf/pcfdriver.h @@ -0,0 +1,44 @@ +/* pcfdriver.h + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __PCFDRIVER_H__ +#define __PCFDRIVER_H__ + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + +FT_BEGIN_HEADER + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pcf_driver_class; + +FT_END_HEADER + + +#endif /* __PCFDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pcf/pcferror.h b/lib/freetype/src/pcf/pcferror.h new file mode 100644 index 0000000..d75c067 --- /dev/null +++ b/lib/freetype/src/pcf/pcferror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pcferror.h */ +/* */ +/* PCF error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the PCF error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PCFERROR_H__ +#define __PCFERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PCF_Err_ +#define FT_ERR_BASE FT_Mod_Err_PCF + +#include FT_ERRORS_H + +#endif /* __PCFERROR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfread.c b/lib/freetype/src/pcf/pcfread.c new file mode 100644 index 0000000..e3bbf06 --- /dev/null +++ b/lib/freetype/src/pcf/pcfread.c @@ -0,0 +1,1058 @@ +/* pcfread.c + + FreeType font driver for pcf fonts + + Copyright 2000-2001, 2002 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + + +#include <ft2build.h> + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H + +#include "pcf.h" +#include "pcfdriver.h" +#include "pcfread.h" + +#include "pcferror.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_pcfread + + +#if defined( FT_DEBUG_LEVEL_TRACE ) + static const char* tableNames[] = + { + "prop", "accl", "mtrcs", "bmps", "imtrcs", + "enc", "swidth", "names", "accel" + }; +#endif + + + static + const FT_Frame_Field pcf_toc_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TocRec + + FT_FRAME_START( 8 ), + FT_FRAME_ULONG_LE( version ), + FT_FRAME_ULONG_LE( count ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_table_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG_LE( type ), + FT_FRAME_ULONG_LE( format ), + FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( offset ), + FT_FRAME_END + }; + + + static FT_Error + pcf_read_TOC( FT_Stream stream, + PCF_Face face ) + { + FT_Error error; + PCF_Toc toc = &face->toc; + PCF_Table tables; + + FT_Memory memory = FT_FACE(face)->memory; + FT_UInt n; + + + if ( FT_STREAM_SEEK ( 0 ) || + FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + return PCF_Err_Cannot_Open_Resource; + + if ( toc->version != PCF_FILE_VERSION ) + return PCF_Err_Invalid_File_Format; + + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) + return PCF_Err_Out_Of_Memory; + + tables = face->toc.tables; + for ( n = 0; n < toc->count; n++ ) + { + if ( FT_STREAM_READ_FIELDS( pcf_table_header, tables ) ) + goto Exit; + tables++; + } + +#if defined( FT_DEBUG_LEVEL_TRACE ) + + { + FT_UInt i, j; + const char* name = "?"; + + + FT_TRACE4(( "Tables count: %ld\n", face->toc.count )); + tables = face->toc.tables; + for ( i = 0; i < toc->count; i++ ) + { + for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ ) + if ( tables[i].type == (FT_UInt)( 1 << j ) ) + name = tableNames[j]; + + FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX " + "size=0x%06lX (%8ld) offset=0x%04lX\n", + i, name, + tables[i].format, + tables[i].size, tables[i].size, + tables[i].offset )); + } + } + +#endif + + return PCF_Err_Ok; + + Exit: + FT_FREE( face->toc.tables ); + return error; + } + + + static + const FT_Frame_Field pcf_metric_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( 12 ), + FT_FRAME_SHORT_LE( leftSideBearing ), + FT_FRAME_SHORT_LE( rightSideBearing ), + FT_FRAME_SHORT_LE( characterWidth ), + FT_FRAME_SHORT_LE( ascent ), + FT_FRAME_SHORT_LE( descent ), + FT_FRAME_SHORT_LE( attributes ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_metric_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_MetricRec + + FT_FRAME_START( 12 ), + FT_FRAME_SHORT( leftSideBearing ), + FT_FRAME_SHORT( rightSideBearing ), + FT_FRAME_SHORT( characterWidth ), + FT_FRAME_SHORT( ascent ), + FT_FRAME_SHORT( descent ), + FT_FRAME_SHORT( attributes ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_compressed_metric_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_Compressed_MetricRec + + FT_FRAME_START( 5 ), + FT_FRAME_BYTE( leftSideBearing ), + FT_FRAME_BYTE( rightSideBearing ), + FT_FRAME_BYTE( characterWidth ), + FT_FRAME_BYTE( ascent ), + FT_FRAME_BYTE( descent ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_metric( FT_Stream stream, + FT_ULong format, + PCF_Metric metric ) + { + FT_Error error = PCF_Err_Ok; + + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + const FT_Frame_Field* fields; + + + /* parsing normal metrics */ + fields = PCF_BYTE_ORDER( format ) == MSBFirst + ? pcf_metric_msb_header + : pcf_metric_header; + + /* the following sets 'error' but doesn't return in case of failure */ + (void)FT_STREAM_READ_FIELDS( fields, metric ); + } + else + { + PCF_Compressed_MetricRec compr; + + + /* parsing compressed metrics */ + if ( FT_STREAM_READ_FIELDS( pcf_compressed_metric_header, &compr ) ) + goto Exit; + + metric->leftSideBearing = (FT_Short)( compr.leftSideBearing - 0x80 ); + metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 ); + metric->characterWidth = (FT_Short)( compr.characterWidth - 0x80 ); + metric->ascent = (FT_Short)( compr.ascent - 0x80 ); + metric->descent = (FT_Short)( compr.descent - 0x80 ); + metric->attributes = 0; + } + + Exit: + return error; + } + + + static FT_Error + pcf_seek_to_table_type( FT_Stream stream, + PCF_Table tables, + FT_Int ntables, + FT_ULong type, + FT_ULong *aformat, + FT_ULong *asize ) + { + FT_Error error = 0; + FT_Int i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + { + if ( stream->pos > tables[i].offset ) + return PCF_Err_Invalid_Stream_Skip; + + if ( FT_STREAM_SKIP( tables[i].offset - stream->pos ) ) + return PCF_Err_Invalid_Stream_Skip; + + *asize = tables[i].size; /* unused - to be removed */ + *aformat = tables[i].format; + + return PCF_Err_Ok; + } + + return PCF_Err_Invalid_File_Format; + } + + + static FT_Bool + pcf_has_table_type( PCF_Table tables, + FT_Int ntables, + FT_ULong type ) + { + FT_Int i; + + + for ( i = 0; i < ntables; i++ ) + if ( tables[i].type == type ) + return TRUE; + + return FALSE; + } + + + static + const FT_Frame_Field pcf_property_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( 9 ), + FT_FRAME_LONG_LE( name ), + FT_FRAME_BYTE ( isString ), + FT_FRAME_LONG_LE( value ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_property_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_ParsePropertyRec + + FT_FRAME_START( 9 ), + FT_FRAME_LONG( name ), + FT_FRAME_BYTE( isString ), + FT_FRAME_LONG( value ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ) + { + PCF_Property properties = face->properties; + FT_Bool found = 0; + int i; + + + for ( i = 0 ; i < face->nprops && !found; i++ ) + { + if ( !ft_strcmp( properties[i].name, prop ) ) + found = 1; + } + + if ( found ) + return properties + i - 1; + else + return NULL; + } + + + static FT_Error + pcf_get_properties( FT_Stream stream, + PCF_Face face ) + { + PCF_ParseProperty props = 0; + PCF_Property properties = 0; + FT_Int nprops, i; + FT_ULong format, size; + FT_Error error; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong string_size; + FT_String* strings = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_PROPERTIES, + &format, + &size ); + if ( error ) + goto Bail; + + if ( FT_READ_ULONG_LE( format ) ) + goto Bail; + + FT_TRACE4(( "get_prop: format = %ld\n", format )); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nprops ); + else + (void)FT_READ_ULONG_LE( nprops ); + if ( error ) + goto Bail; + + FT_TRACE4(( "get_prop: nprop = %d\n", nprops )); + + if ( FT_NEW_ARRAY( props, nprops ) ) + goto Bail; + + for ( i = 0; i < nprops; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_property_msb_header, props + i ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_property_header, props + i ) ) + goto Bail; + } + } + + /* pad the property array */ + /* */ + /* clever here - nprops is the same as the number of odd-units read, */ + /* as only isStringProp are odd length (Keith Packard) */ + /* */ + if ( nprops & 3 ) + { + i = 4 - ( nprops & 3 ); + FT_Stream_Skip( stream, i ); + } + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( string_size ); + else + (void)FT_READ_ULONG_LE( string_size ); + if ( error ) + goto Bail; + + FT_TRACE4(( "get_prop: string_size = %ld\n", string_size )); + + if ( FT_NEW_ARRAY( strings, string_size ) ) + goto Bail; + + error = FT_Stream_Read( stream, (FT_Byte*)strings, string_size ); + if ( error ) + goto Bail; + + if ( FT_NEW_ARRAY( properties, nprops ) ) + goto Bail; + + for ( i = 0; i < nprops; i++ ) + { + /* XXX: make atom */ + if ( FT_NEW_ARRAY( properties[i].name, + ft_strlen( strings + props[i].name ) + 1 ) ) + goto Bail; + ft_strcpy( properties[i].name,strings + props[i].name ); + + properties[i].isString = props[i].isString; + + if ( props[i].isString ) + { + if ( FT_NEW_ARRAY( properties[i].value.atom, + ft_strlen( strings + props[i].value ) + 1 ) ) + goto Bail; + ft_strcpy( properties[i].value.atom, strings + props[i].value ); + } + else + properties[i].value.integer = props[i].value; + } + + face->properties = properties; + face->nprops = nprops; + + FT_FREE( props ); + FT_FREE( strings ); + + return PCF_Err_Ok; + + Bail: + FT_FREE( props ); + FT_FREE( strings ); + + return error; + } + + + static FT_Error + pcf_get_metrics( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong format = 0; + FT_ULong size = 0; + PCF_Metric metrics = 0; + int i; + int nmetrics = -1; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_METRICS, + &format, + &size ); + if ( error ) + return error; + + error = FT_READ_ULONG_LE( format ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) + return PCF_Err_Invalid_File_Format; + + if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_ULONG( nmetrics ); + else + (void)FT_READ_ULONG_LE( nmetrics ); + } + else + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_USHORT( nmetrics ); + else + (void)FT_READ_USHORT_LE( nmetrics ); + } + if ( error || nmetrics == -1 ) + return PCF_Err_Invalid_File_Format; + + face->nmetrics = nmetrics; + + if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) + return PCF_Err_Out_Of_Memory; + + metrics = face->metrics; + for ( i = 0; i < nmetrics; i++ ) + { + pcf_get_metric( stream, format, metrics + i ); + + metrics[i].bits = 0; + + FT_TRACE4(( "%d : width=%d, " + "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", + i, + ( metrics + i )->characterWidth, + ( metrics + i )->leftSideBearing, + ( metrics + i )->rightSideBearing, + ( metrics + i )->ascent, + ( metrics + i )->descent, + ( metrics + i )->attributes )); + + if ( error ) + break; + } + + if ( error ) + FT_FREE( face->metrics ); + return error; + } + + + static FT_Error + pcf_get_bitmaps( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_Long* offsets; + FT_Long bitmapSizes[GLYPHPADOPTIONS]; + FT_ULong format, size; + int nbitmaps, i, sizebitmaps = 0; + char* bitmaps; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BITMAPS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 8 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + nbitmaps = FT_GET_ULONG(); + else + nbitmaps = FT_GET_ULONG_LE(); + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return PCF_Err_Invalid_File_Format; + + if ( nbitmaps != face->nmetrics ) + return PCF_Err_Invalid_File_Format; + + if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) + return error; + + for ( i = 0; i < nbitmaps; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( offsets[i] ); + else + (void)FT_READ_LONG_LE( offsets[i] ); + + FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] )); + } + if ( error ) + goto Bail; + + for ( i = 0; i < GLYPHPADOPTIONS; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + (void)FT_READ_LONG( bitmapSizes[i] ); + else + (void)FT_READ_LONG_LE( bitmapSizes[i] ); + if ( error ) + goto Bail; + + sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; + + FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] )); + } + + FT_TRACE4(( " %d bitmaps, padding index %ld\n", + nbitmaps, + PCF_GLYPH_PAD_INDEX( format ) )); + FT_TRACE4(( "bitmap size = %d\n", sizebitmaps )); + + FT_UNUSED( sizebitmaps ); /* only used for debugging */ + + for ( i = 0; i < nbitmaps; i++ ) + face->metrics[i].bits = stream->pos + offsets[i]; + + face->bitmapsFormat = format; + + FT_FREE ( offsets ); + return error; + + Bail: + FT_FREE ( offsets ); + FT_FREE ( bitmaps ); + return error; + } + + + static FT_Error + pcf_get_encodings( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_ULong format, size; + int firstCol, lastCol; + int firstRow, lastRow; + int nencoding, encodingOffset; + int i, j; + PCF_Encoding tmpEncoding, encoding = 0; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + PCF_BDF_ENCODINGS, + &format, + &size ); + if ( error ) + return error; + + error = FT_Stream_EnterFrame( stream, 14 ); + if ( error ) + return error; + + format = FT_GET_ULONG_LE(); + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + firstCol = FT_GET_SHORT(); + lastCol = FT_GET_SHORT(); + firstRow = FT_GET_SHORT(); + lastRow = FT_GET_SHORT(); + face->defaultChar = FT_GET_SHORT(); + } + else + { + firstCol = FT_GET_SHORT_LE(); + lastCol = FT_GET_SHORT_LE(); + firstRow = FT_GET_SHORT_LE(); + lastRow = FT_GET_SHORT_LE(); + face->defaultChar = FT_GET_SHORT_LE(); + } + + FT_Stream_ExitFrame( stream ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) + return PCF_Err_Invalid_File_Format; + + FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", + firstCol, lastCol, firstRow, lastRow )); + + nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 ); + + if ( FT_NEW_ARRAY( tmpEncoding, nencoding ) ) + return PCF_Err_Out_Of_Memory; + + error = FT_Stream_EnterFrame( stream, 2 * nencoding ); + if ( error ) + goto Bail; + + for ( i = 0, j = 0 ; i < nencoding; i++ ) + { + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + encodingOffset = FT_GET_SHORT(); + else + encodingOffset = FT_GET_SHORT_LE(); + + if ( encodingOffset != -1 ) + { + tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) + + firstRow ) * 256 ) + + ( ( i % ( lastCol - firstCol + 1 ) ) + + firstCol ); + + tmpEncoding[j].glyph = (FT_Short)encodingOffset; + j++; + } + + FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n", + i, tmpEncoding[j - 1].enc, encodingOffset )); + } + FT_Stream_ExitFrame( stream ); + + if ( FT_NEW_ARRAY( encoding, j ) ) + goto Bail; + + for ( i = 0; i < j; i++ ) + { + encoding[i].enc = tmpEncoding[i].enc; + encoding[i].glyph = tmpEncoding[i].glyph; + } + + face->nencodings = j; + face->encodings = encoding; + FT_FREE( tmpEncoding ); + + return error; + + Bail: + FT_FREE( encoding ); + FT_FREE( tmpEncoding ); + return error; + } + + + static + const FT_Frame_Field pcf_accel_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG_LE ( fontAscent ), + FT_FRAME_LONG_LE ( fontDescent ), + FT_FRAME_LONG_LE ( maxOverlap ), + FT_FRAME_END + }; + + + static + const FT_Frame_Field pcf_accel_msb_header[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PCF_AccelRec + + FT_FRAME_START( 20 ), + FT_FRAME_BYTE ( noOverlap ), + FT_FRAME_BYTE ( constantMetrics ), + FT_FRAME_BYTE ( terminalFont ), + FT_FRAME_BYTE ( constantWidth ), + FT_FRAME_BYTE ( inkInside ), + FT_FRAME_BYTE ( inkMetrics ), + FT_FRAME_BYTE ( drawDirection ), + FT_FRAME_SKIP_BYTES( 1 ), + FT_FRAME_LONG ( fontAscent ), + FT_FRAME_LONG ( fontDescent ), + FT_FRAME_LONG ( maxOverlap ), + FT_FRAME_END + }; + + + static FT_Error + pcf_get_accel( FT_Stream stream, + PCF_Face face, + FT_ULong type ) + { + FT_ULong format, size; + FT_Error error = PCF_Err_Ok; + PCF_Accel accel = &face->accel; + + + error = pcf_seek_to_table_type( stream, + face->toc.tables, + face->toc.count, + type, + &format, + &size ); + if ( error ) + goto Bail; + + error = FT_READ_ULONG_LE( format ); + + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && + !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + goto Bail; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) ) + goto Bail; + } + else + { + if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) ) + goto Bail; + } + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->maxbounds) ); + if ( error ) + goto Bail; + + if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) + { + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_minbounds) ); + if ( error ) + goto Bail; + + error = pcf_get_metric( stream, + format & ( ~PCF_FORMAT_MASK ), + &(accel->ink_maxbounds) ); + if ( error ) + goto Bail; + } + else + { + accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ + accel->ink_maxbounds = accel->maxbounds; + } + return error; + + Bail: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pcf_load_font( FT_Stream stream, + PCF_Face face ) + { + FT_Error error = PCF_Err_Ok; + FT_Memory memory = FT_FACE(face)->memory; + FT_Bool hasBDFAccelerators; + + + error = pcf_read_TOC( stream, face ); + if ( error ) + goto Exit; + + error = pcf_get_properties( stream, face ); + if ( error ) + goto Exit; + + /* Use the old accelerators if no BDF accelerators are in the file. */ + hasBDFAccelerators = pcf_has_table_type( face->toc.tables, + face->toc.count, + PCF_BDF_ACCELERATORS ); + if ( !hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* metrics */ + error = pcf_get_metrics( stream, face ); + if ( error ) + goto Exit; + + /* bitmaps */ + error = pcf_get_bitmaps( stream, face ); + if ( error ) + goto Exit; + + /* encodings */ + error = pcf_get_encodings( stream, face ); + if ( error ) + goto Exit; + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + if ( hasBDFAccelerators ) + { + error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS ); + if ( error ) + goto Exit; + } + + /* XXX: TO DO: inkmetrics and glyph_names are missing */ + + /* now construct the face object */ + { + FT_Face root = FT_FACE( face ); + PCF_Property prop; + int size_set = 0; + + + root->num_faces = 1; + root->face_index = 0; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL | + FT_FACE_FLAG_FAST_GLYPHS; + + if ( face->accel.constantWidth ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + root->style_flags = 0; + prop = pcf_find_property( face, "SLANT" ); + if ( prop != NULL ) + if ( prop->isString ) + if ( ( *(prop->value.atom) == 'O' ) || + ( *(prop->value.atom) == 'I' ) ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + prop = pcf_find_property( face, "WEIGHT_NAME" ); + if ( prop != NULL ) + if ( prop->isString ) + if ( *(prop->value.atom) == 'B' ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + root->style_name = (char *)"Regular"; + + if ( root->style_flags & FT_STYLE_FLAG_BOLD ) { + if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Bold Italic"; + else + root->style_name = (char *)"Bold"; + } + else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Italic"; + + prop = pcf_find_property( face, "FAMILY_NAME" ); + if ( prop != NULL ) + { + if ( prop->isString ) + { + int l = ft_strlen( prop->value.atom ) + 1; + + + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + ft_strcpy( root->family_name, prop->value.atom ); + } + } + else + root->family_name = 0; + + root->num_glyphs = face->nmetrics; + + root->num_fixed_sizes = 1; + if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) + goto Exit; + + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop != NULL ) + { + root->available_sizes->height = + root->available_sizes->width = (FT_Short)( prop->value.integer ); + + size_set = 1; + } + else + { + prop = pcf_find_property( face, "POINT_SIZE" ); + if ( prop != NULL ) + { + PCF_Property xres, yres, avgw; + + + xres = pcf_find_property( face, "RESOLUTION_X" ); + yres = pcf_find_property( face, "RESOLUTION_Y" ); + avgw = pcf_find_property( face, "AVERAGE_WIDTH" ); + + if ( ( yres != NULL ) && ( xres != NULL ) ) + { + root->available_sizes->height = + (FT_Short)( prop->value.integer * + yres->value.integer / 720 ); + + root->available_sizes->width = + (FT_Short)( prop->value.integer * + xres->value.integer / 720 ); + + size_set = 1; + } + } + } + + if (size_set == 0 ) + { + root->available_sizes->width = 12; + root->available_sizes->height = 12; + } + + /* set-up charset */ + { + PCF_Property charset_registry = 0, charset_encoding = 0; + + + charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" ); + charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" ); + + if ( ( charset_registry != NULL ) && + ( charset_encoding != NULL ) ) + { + if ( ( charset_registry->isString ) && + ( charset_encoding->isString ) ) + { + if ( FT_NEW_ARRAY( face->charset_encoding, + ft_strlen( charset_encoding->value.atom ) + 1 ) ) + goto Exit; + + if ( FT_NEW_ARRAY( face->charset_registry, + ft_strlen( charset_registry->value.atom ) + 1 ) ) + goto Exit; + + ft_strcpy( face->charset_registry, charset_registry->value.atom ); + ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); + } + } + } + } + + Exit: + if ( error ) + { + /* this is done to respect the behaviour of the original */ + /* PCF font driver. */ + error = PCF_Err_Invalid_File_Format; + } + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfread.h b/lib/freetype/src/pcf/pcfread.h new file mode 100644 index 0000000..5f54ba6 --- /dev/null +++ b/lib/freetype/src/pcf/pcfread.h @@ -0,0 +1,45 @@ +/* pcfread.h + + FreeType font driver for pcf fonts + + Copyright 2000-2001 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __PCFREAD_H__ +#define __PCFREAD_H__ + + +#include <ft2build.h> + +FT_BEGIN_HEADER + + FT_LOCAL( PCF_Property ) + pcf_find_property( PCF_Face face, + const FT_String* prop ); + +FT_END_HEADER + +#endif /* __PCFUTIL_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfutil.c b/lib/freetype/src/pcf/pcfutil.c new file mode 100644 index 0000000..eb911bb --- /dev/null +++ b/lib/freetype/src/pcf/pcfutil.c @@ -0,0 +1,215 @@ +/* + +Copyright 1990, 1994, 1998 The Open Group + +All Rights Reserved. + +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 +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + + +#include <ft2build.h> +#include "pcfutil.h" + + + /* Utility functions for reformatting font bitmaps */ + + static const unsigned char _reverse_byte[0x100] = + { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff + }; + + /* + * Invert bit order within each BYTE of an array. + */ + + void + BitOrderInvert( unsigned char* buf, + int nbytes ) + { + const unsigned char* rev = _reverse_byte; + + + for ( ; --nbytes >= 0; buf++ ) + *buf = rev[*buf]; + } + + + /* + * Invert byte order within each 16-bits of an array. + */ + + void + TwoByteSwap( unsigned char* buf, + int nbytes ) + { + unsigned char c; + + + for ( ; nbytes > 0; nbytes -= 2, buf += 2 ) + { + c = buf[0]; + buf[0] = buf[1]; + buf[1] = c; + } + } + + /* + * Invert byte order within each 32-bits of an array. + */ + + void + FourByteSwap( unsigned char* buf, + int nbytes ) + { + unsigned char c; + + + for ( ; nbytes > 0; nbytes -= 4, buf += 4 ) + { + c = buf[0]; + buf[0] = buf[3]; + buf[3] = c; + + c = buf[1]; + buf[1] = buf[2]; + buf[2] = c; + } + } + + + /* + * Repad a bitmap. + */ + + int + RepadBitmap( char* pSrc, + char* pDst, + unsigned int srcPad, + unsigned int dstPad, + int width, + int height ) + { + int srcWidthBytes, dstWidthBytes; + int row, col; + char *pTmpSrc, *pTmpDst; + + + switch ( srcPad ) + { + case 1: + srcWidthBytes = ( width + 7 ) >> 3; + break; + + case 2: + srcWidthBytes = ( ( width + 15 ) >> 4 ) << 1; + break; + + case 4: + srcWidthBytes = ( ( width + 31 ) >> 5 ) << 2; + break; + + case 8: + srcWidthBytes = ( ( width + 63 ) >> 6 ) << 3; + break; + + default: + return 0; + } + + switch ( dstPad ) + { + case 1: + dstWidthBytes = ( width + 7 ) >> 3; + break; + + case 2: + dstWidthBytes = ( ( width + 15 ) >> 4 ) << 1; + break; + + case 4: + dstWidthBytes = ( ( width + 31 ) >> 5 ) << 2; + break; + + case 8: + dstWidthBytes = ( ( width + 63 ) >> 6 ) << 3; + break; + + default: + return 0; + } + + width = srcWidthBytes; + if ( width > dstWidthBytes ) + width = dstWidthBytes; + + pTmpSrc= pSrc; + pTmpDst= pDst; + + for ( row = 0; row < height; row++ ) + { + for ( col = 0; col < width; col++ ) + *pTmpDst++ = *pTmpSrc++; + + while ( col < dstWidthBytes ) + { + *pTmpDst++ = '\0'; + col++; + } + pTmpSrc += srcWidthBytes - width; + } + + return dstWidthBytes * height; + } + + +/* END */ diff --git a/lib/freetype/src/pcf/pcfutil.h b/lib/freetype/src/pcf/pcfutil.h new file mode 100644 index 0000000..32dd1ea --- /dev/null +++ b/lib/freetype/src/pcf/pcfutil.h @@ -0,0 +1,58 @@ +/* pcfutil.h + + FreeType font driver for pcf fonts + + Copyright 2000-2001 by + Francesco Zappa Nardelli + +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 +AUTHORS OR COPYRIGHT HOLDERS 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 __PCFUTIL_H__ +#define __PCFUTIL_H__ + + +#include <ft2build.h> + + + void + BitOrderInvert( unsigned char* buf, + int nbytes); + + void + TwoByteSwap( unsigned char* buf, + int nbytes); + + void + FourByteSwap( unsigned char* buf, + int nbytes); + + int + RepadBitmap( char* pSrc, + char* pDst, + unsigned int srcPad, + unsigned int dstPad, + int width, + int height); + +#endif /* __PCFUTIL_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pcf/readme b/lib/freetype/src/pcf/readme new file mode 100644 index 0000000..75f49e1 --- /dev/null +++ b/lib/freetype/src/pcf/readme @@ -0,0 +1,114 @@ + FreeType font driver for PCF fonts + + Francesco Zappa Nardelli + <francesco.zappa.nardelli@ens.fr> + + +Introduction +************ + +PCF (Portable Compiled Format) is a binary bitmap font format, largely used +in X world. This code implements a PCF driver for the FreeType library. +Glyph images are loaded into memory only on demand, thus leading to a small +memory footprint. + +Informations on the PCF font format can only be worked out from +``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86 +(www.xfree86.org) source tree (xc/lib/font/bitmap/). + +Many good bitmap fonts in bdf format come with XFree86: they can be +compiled into the pcf format using the ``bdftopcf'' utility. + + +Supported hardware +****************** + +The driver has been tested on linux/x86 and sunos5.5/sparc. In both +cases the compiler was gcc. When back in Paris, I will test it also +on linux/alpha. + + +Encodings +********* + +The variety of encodings that accompanies pcf fonts appears to encompass the +small set defined in freetype.h. On the other hand, each pcf font defines +two properties that specify encoding and registry. + +I decided to make these two properties directly accessible, leaving to the +client application the work of interpreting them. For instance: + + #include "pcftypes.h" /* include/freetype/internal/pcftypes.h */ + + FT_Face face; + PCF_Public_Face pcfface; + + FT_New_Face( library,..., &face ); + + pcfface = (PCF_Public_Face)face; + + if ((pcfface->charset_registry == "ISO10646") && + (pcfface->charset_encoding) == "1")) [..] + +Thus the driver always export ``ft_encoding_none'' as +face->charmap.encoding. FT_Get_Char_Index() behavior is unmodified, that +is, it converts the ULong value given as argument into the corresponding +glyph number. + + +Known problems +************** + +- dealing explicitly with encodings breaks the uniformity of freetype2 + api. + +- except for encodings properties, client applications have no + visibility of the PCF_Face object. This means that applications + cannot directly access font tables and are obliged to trust + FreeType. + +- currently, glyph names and ink_metrics are ignored. + +I plan to give full visibility of the PCF_Face object in the next +release of the driver, thus implementing also glyph names and +ink_metrics. + +- height is defined as (ascent - descent). Is this correct? + +- if unable to read size informations from the font, PCF_Init_Face + sets available_size->width and available_size->height to 12. + +- too many english grammar errors in the readme file :-( + + +License +******* + +Copyright (C) 2000 by Francesco Zappa Nardelli + +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 AUTHORS OR COPYRIGHT HOLDERS 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. + + +Credits +******* + +Keith Packard wrote the pcf driver found in XFree86. His work is at +the same time the specification and the sample implementation of the +PCF format. Undoubtedly, this driver is inspired from his work. diff --git a/lib/freetype/src/pcf/rules.mk b/lib/freetype/src/pcf/rules.mk new file mode 100644 index 0000000..141f1b7 --- /dev/null +++ b/lib/freetype/src/pcf/rules.mk @@ -0,0 +1,80 @@ +# +# FreeType 2 pcf driver configuration rules +# + + +# Copyright (C) 2000, 2001 by +# Francesco Zappa Nardelli +# +# 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 +# AUTHORS OR COPYRIGHT HOLDERS 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. + + +# pcf driver directory +# +PCF_DIR := $(SRC_)pcf +PCF_DIR_ := $(PCF_DIR)$(SEP) + + +PCF_COMPILE := $(FT_COMPILE) $I$(PCF_DIR) + + +# pcf driver sources (i.e., C files) +# +PCF_DRV_SRC := $(PCF_DIR_)pcfread.c \ + $(PCF_DIR_)pcfdriver.c \ + $(PCF_DIR_)pcfutil.c + +# pcf driver headers +# +PCF_DRV_H := $(PCF_DIR_)pcf.h \ + $(PCF_DIR_)pcfdriver.h \ + $(PCF_DIR_)pcfutil.h \ + $(PCF_DIR_)pcferror.h + +# pcf driver object(s) +# +# PCF_DRV_OBJ_M is used during `multi' builds +# PCF_DRV_OBJ_S is used during `single' builds +# +PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR_)%.c=$(OBJ_)%.$O) +PCF_DRV_OBJ_S := $(OBJ_)pcf.$O + +# Windows driver source file for single build +# +PCF_DRV_SRC_S := $(PCF_DIR_)pcf.c + + +# pcf driver - single object +# +$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H) + $(PCF_COMPILE) $T$@ $(PCF_DRV_SRC_S) + + +# pcf driver - multiple objects +# +$(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H) + $(PCF_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PCF_DRV_OBJ_S) +DRV_OBJS_M += $(PCF_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/pfr/Jamfile b/lib/freetype/src/pfr/Jamfile new file mode 100644 index 0000000..3ba0ee9 --- /dev/null +++ b/lib/freetype/src/pfr/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/pfr Jamfile (c) 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) pfr ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pfrdrivr pfrgload pfrload pfrobjs pfrcmap pfrsbit ; + } + else + { + _sources = pfr ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pfr Jamfile diff --git a/lib/freetype/src/pfr/descrip.mms b/lib/freetype/src/pfr/descrip.mms new file mode 100644 index 0000000..75178d0 --- /dev/null +++ b/lib/freetype/src/pfr/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 PFR driver compilation rules for VMS +# + + +# Copyright 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.pfr]) + +OBJS=pfr.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/pfr/module.mk b/lib/freetype/src/pfr/module.mk new file mode 100644 index 0000000..3da0d5a --- /dev/null +++ b/lib/freetype/src/pfr/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 PFR module definition +# + + +# Copyright 2002 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. + + +make_module_list: add_pfr_driver + +add_pfr_driver: + $(OPEN_DRIVER)pfr_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)pfr $(ECHO_DRIVER_DESC)PFR/TrueDoc font files with extension *.pfr$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/pfr/pfr.c b/lib/freetype/src/pfr/pfr.c new file mode 100644 index 0000000..eb2c4ed --- /dev/null +++ b/lib/freetype/src/pfr/pfr.c @@ -0,0 +1,29 @@ +/***************************************************************************/ +/* */ +/* pfr.c */ +/* */ +/* FreeType PFR driver component. */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> + +#include "pfrload.c" +#include "pfrgload.c" +#include "pfrcmap.c" +#include "pfrobjs.c" +#include "pfrdrivr.c" +#include "pfrsbit.c" + +/* END */ diff --git a/lib/freetype/src/pfr/pfrcmap.c b/lib/freetype/src/pfr/pfrcmap.c new file mode 100644 index 0000000..de6c5a0 --- /dev/null +++ b/lib/freetype/src/pfr/pfrcmap.c @@ -0,0 +1,158 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.c */ +/* */ +/* FreeType PFR cmap handling (body). */ +/* */ +/* Copyright 2002 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 "pfrcmap.h" +#include "pfrobjs.h" +#include FT_INTERNAL_DEBUG_H + + + FT_CALLBACK_DEF( FT_Error ) + pfr_cmap_init( PFR_CMap cmap ) + { + PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); + + + cmap->num_chars = face->phy_font.num_chars; + cmap->chars = face->phy_font.chars; + + /* just for safety, check that the character entries are correctly */ + /* sorted in increasing character code order */ + { + FT_UInt n; + + + for ( n = 1; n < cmap->num_chars; n++ ) + { + if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) + FT_ASSERT( 0 ); + } + } + + return 0; + } + + + FT_CALLBACK_DEF( void ) + pfr_cmap_done( PFR_CMap cmap ) + { + cmap->chars = NULL; + cmap->num_chars = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_index( PFR_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + return mid + 1; + + if ( gchar->char_code < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + pfr_cmap_char_next( PFR_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_chars; + FT_UInt mid; + PFR_Char gchar; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + gchar = cmap->chars + mid; + + if ( gchar->char_code == char_code ) + { + result = mid; + if ( result != 0 ) + { + result++; + goto Exit; + } + + char_code++; + goto Restart; + } + + if ( gchar->char_code < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_chars ) + { + gchar = cmap->chars + min; + result = min; + if ( result != 0 ) + { + result++; + char_code = gchar->char_code; + } + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + pfr_cmap_class_rec = + { + sizeof ( PFR_CMapRec ), + + (FT_CMap_InitFunc) pfr_cmap_init, + (FT_CMap_DoneFunc) pfr_cmap_done, + (FT_CMap_CharIndexFunc)pfr_cmap_char_index, + (FT_CMap_CharNextFunc) pfr_cmap_char_next + }; + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrcmap.h b/lib/freetype/src/pfr/pfrcmap.h new file mode 100644 index 0000000..d77813e --- /dev/null +++ b/lib/freetype/src/pfr/pfrcmap.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* pfrcmap.h */ +/* */ +/* FreeType PFR cmap handling (specification). */ +/* */ +/* Copyright 2002 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 __PFRCMAP_H__ +#define __PFRCMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt num_chars; + PFR_Char chars; + + } PFR_CMapRec, *PFR_CMap; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec pfr_cmap_class_rec; + +FT_END_HEADER + + +#endif /* __PFRCMAP_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrdrivr.c b/lib/freetype/src/pfr/pfrdrivr.c new file mode 100644 index 0000000..07ba9b4 --- /dev/null +++ b/lib/freetype/src/pfr/pfrdrivr.c @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.c */ +/* */ +/* FreeType PFR driver interface (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_PFR_H +#include "pfrdrivr.h" +#include "pfrobjs.h" + + + static FT_Error + pfr_get_kerning( PFR_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ) + { + FT_Error error; + + error = pfr_face_get_kerning( face, left, right, avector ); + if ( !error ) + { + PFR_PhyFont phys = &face->phy_font; + + /* convert from metrics to outline units when necessary */ + if ( phys->outline_resolution != phys->metrics_resolution ) + { + if ( avector->x != 0 ) + avector->x = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + + if ( avector->y != 0 ) + avector->y = FT_MulDiv( avector->x, phys->outline_resolution, + phys->metrics_resolution ); + } + } + return error; + } + + + static FT_Error + pfr_get_advance( PFR_Face face, + FT_UInt gindex, + FT_Pos *aadvance ) + { + FT_Error error = FT_Err_Bad_Argument; + + *aadvance = 0; + if ( face ) + { + PFR_PhyFont phys = &face->phy_font; + + if ( gindex < phys->num_chars ) + { + *aadvance = phys->chars[ gindex ].advance; + error = 0; + } + } + + return error; + } + + + static FT_Error + pfr_get_metrics( PFR_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ) + { + PFR_PhyFont phys = &face->phy_font; + FT_Fixed x_scale, y_scale; + FT_Size size = face->root.size; + + if ( aoutline_resolution ) + *aoutline_resolution = phys->outline_resolution; + + if ( ametrics_resolution ) + *ametrics_resolution = phys->metrics_resolution; + + x_scale = 0x10000L; + y_scale = 0x10000L; + + if ( size ) + { + x_scale = FT_DivFix( size->metrics.x_ppem << 6, + phys->metrics_resolution ); + + y_scale = FT_DivFix( size->metrics.y_ppem << 6, + phys->metrics_resolution ); + } + + if ( ametrics_x_scale ) + *ametrics_x_scale = x_scale; + + if ( ametrics_y_scale ) + *ametrics_y_scale = y_scale; + + return 0; + } + + + FT_CALLBACK_TABLE_DEF + const FT_PFR_ServiceRec pfr_service_rec = + { + (FT_PFR_GetMetricsFunc) pfr_get_metrics, + (FT_PFR_GetKerningFunc) pfr_get_kerning, + (FT_PFR_GetAdvanceFunc) pfr_get_advance + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec pfr_driver_class = + { + { + ft_module_font_driver | + ft_module_driver_scalable, + + sizeof( FT_DriverRec ), + + "pfr", + 0x10000L, + 0x20000L, + + (FT_PFR_Service) &pfr_service_rec, /* format interface */ + + (FT_Module_Constructor)NULL, + (FT_Module_Destructor) NULL, + (FT_Module_Requester) NULL + }, + + sizeof( PFR_FaceRec ), + sizeof( PFR_SizeRec ), + sizeof( PFR_SlotRec ), + + (FT_Face_InitFunc) pfr_face_init, + (FT_Face_DoneFunc) pfr_face_done, + (FT_Size_InitFunc) NULL, + (FT_Size_DoneFunc) NULL, + (FT_Slot_InitFunc) pfr_slot_init, + (FT_Slot_DoneFunc) pfr_slot_done, + + (FT_Size_ResetPointsFunc) NULL, + (FT_Size_ResetPixelsFunc) NULL, + (FT_Slot_LoadFunc) pfr_slot_load, + + (FT_Face_GetKerningFunc) pfr_get_kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrdrivr.h b/lib/freetype/src/pfr/pfrdrivr.h new file mode 100644 index 0000000..36f1205 --- /dev/null +++ b/lib/freetype/src/pfr/pfrdrivr.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* pfrdrivr.h */ +/* */ +/* High-level Type PFR driver interface (specification). */ +/* */ +/* Copyright 2002 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 __PFRDRIVR_H__ +#define __PFRDRIVR_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) pfr_driver_class; + + +FT_END_HEADER + + +#endif /* __PFRDRIVR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrerror.h b/lib/freetype/src/pfr/pfrerror.h new file mode 100644 index 0000000..2e1c401 --- /dev/null +++ b/lib/freetype/src/pfr/pfrerror.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* pfrerror.h */ +/* */ +/* PFR error codes (specification only). */ +/* */ +/* Copyright 2002 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 define the PFR error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PFRERROR_H__ +#define __PFRERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PFR_Err_ +#define FT_ERR_BASE FT_Mod_Err_PFR + +#include FT_ERRORS_H + +#endif /* __PFRERROR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrgload.c b/lib/freetype/src/pfr/pfrgload.c new file mode 100644 index 0000000..cb5c60b --- /dev/null +++ b/lib/freetype/src/pfr/pfrgload.c @@ -0,0 +1,801 @@ +/***************************************************************************/ +/* */ +/* pfrgload.c */ +/* */ +/* FreeType PFR glyph loader (body). */ +/* */ +/* Copyright 2002 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 "pfrgload.h" +#include "pfrsbit.h" +#include "pfrload.h" /* for macro definitions */ +#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ) + { + FT_ZERO( glyph ); + + glyph->loader = loader; + glyph->path_begun = 0; + + FT_GlyphLoader_Rewind( loader ); + } + + + FT_LOCAL_DEF( void ) + pfr_glyph_done( PFR_Glyph glyph ) + { + FT_Memory memory = glyph->loader->memory; + + + FT_FREE( glyph->x_control ); + glyph->y_control = NULL; + + glyph->max_xy_control = 0; + glyph->num_x_control = 0; + glyph->num_y_control = 0; + + FT_FREE( glyph->subs ); + + glyph->max_subs = 0; + glyph->num_subs = 0; + + glyph->loader = NULL; + glyph->path_begun = 0; + } + + + /* close current contour, if any */ + static void + pfr_glyph_close_contour( PFR_Glyph glyph ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Int last, first; + + + if ( !glyph->path_begun ) + return; + + /* compute first and last point indices in current glyph outline */ + last = outline->n_points - 1; + first = 0; + if ( outline->n_contours > 0 ) + first = outline->contours[outline->n_contours - 1]; + + /* if the last point falls on the same location than the first one */ + /* we need to delete it */ + if ( last > first ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + last; + + + if ( p1->x == p2->x && p1->y == p2->y ) + { + outline->n_points--; + last--; + } + } + + /* don't add empty contours */ + if ( last >= first ) + outline->contours[outline->n_contours++] = (short)last; + + glyph->path_begun = 0; + } + + + /* reset glyph to start the loading of a new glyph */ + static void + pfr_glyph_start( PFR_Glyph glyph ) + { + glyph->path_begun = 0; + } + + + static FT_Error + pfr_glyph_line_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + FT_ASSERT( glyph->path_begun != 0 ); + + error = FT_GlyphLoader_CheckPoints( loader, 1, 0 ); + if ( !error ) + { + FT_UInt n = outline->n_points; + + + outline->points[n] = *to; + outline->tags [n] = FT_CURVE_TAG_ON; + + outline->n_points++; + } + + return error; + } + + + static FT_Error + pfr_glyph_curve_to( PFR_Glyph glyph, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Outline* outline = &loader->current.outline; + FT_Error error; + + + /* check that we have begun a new path */ + FT_ASSERT( glyph->path_begun != 0 ); + + error = FT_GlyphLoader_CheckPoints( loader, 3, 0 ); + if ( !error ) + { + FT_Vector* vec = outline->points + outline->n_points; + FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; + + + vec[0] = *control1; + vec[1] = *control2; + vec[2] = *to; + tag[0] = FT_CURVE_TAG_CUBIC; + tag[1] = FT_CURVE_TAG_CUBIC; + tag[2] = FT_CURVE_TAG_ON; + + outline->n_points = (FT_Short)( outline->n_points + 3 ); + } + + return error; + } + + + static FT_Error + pfr_glyph_move_to( PFR_Glyph glyph, + FT_Vector* to ) + { + FT_GlyphLoader loader = glyph->loader; + FT_Error error; + + + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* indicate that a new contour has started */ + glyph->path_begun = 1; + + /* check that there is room for a new contour and a new point */ + error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); + if ( !error ) + /* add new start point */ + error = pfr_glyph_line_to( glyph, to ); + + return error; + } + + + static void + pfr_glyph_end( PFR_Glyph glyph ) + { + /* close current contour if any */ + pfr_glyph_close_contour( glyph ); + + /* merge the current glyph into the stack */ + FT_GlyphLoader_Add( glyph->loader ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR GLYPH LOADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* load a simple glyph */ + static FT_Error + pfr_glyph_load_simple( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_Memory memory = glyph->loader->memory; + FT_UInt flags, x_count, y_count, i, count, mask; + FT_Int x; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) == 0 ); + + x_count = 0; + y_count = 0; + + if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) + { + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + x_count = ( count & 15 ); + y_count = ( count >> 4 ); + } + else + { + if ( flags & PFR_GLYPH_XCOUNT ) + { + PFR_CHECK( 1 ); + x_count = PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_GLYPH_YCOUNT ) + { + PFR_CHECK( 1 ); + y_count = PFR_NEXT_BYTE( p ); + } + } + + count = x_count + y_count; + + /* re-allocate array when necessary */ + if ( count > glyph->max_xy_control ) + { + FT_UInt new_max = ( count + 7 ) & -8; + + + if ( FT_RENEW_ARRAY( glyph->x_control, + glyph->max_xy_control, + new_max ) ) + goto Exit; + + glyph->max_xy_control = new_max; + } + + glyph->y_control = glyph->x_control + x_count; + + mask = 0; + x = 0; + + for ( i = 0; i < count; i++ ) + { + if ( ( i & 7 ) == 0 ) + { + PFR_CHECK( 1 ); + mask = PFR_NEXT_BYTE( p ); + } + + if ( mask & 1 ) + { + PFR_CHECK( 2 ); + x = PFR_NEXT_SHORT( p ); + } + else + { + PFR_CHECK( 1 ); + x += PFR_NEXT_BYTE( p ); + } + + glyph->x_control[i] = x; + + mask >>= 1; + } + + /* XXX: for now we ignore the secondary stroke and edge definitions */ + /* since we don't want to support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if ( error ) + goto Exit; + } + + pfr_glyph_start( glyph ); + + /* now load a simple glyph */ + { + FT_Vector pos[4]; + FT_Vector* cur; + + + pos[0].x = pos[0].y = 0; + pos[3] = pos[0]; + + for (;;) + { + FT_Int format, args_format = 0, args_count, n; + + + /***************************************************************/ + /* read instruction */ + /* */ + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + + switch ( format >> 4 ) + { + case 0: /* end glyph */ + FT_TRACE6(( "- end glyph" )); + args_count = 0; + break; + + case 1: /* general line operation */ + FT_TRACE6(( "- general line" )); + goto Line1; + + case 4: /* move to inside contour */ + FT_TRACE6(( "- move to inside" )); + goto Line1; + + case 5: /* move to outside contour */ + FT_TRACE6(( "- move to outside" )); + Line1: + args_format = format & 15; + args_count = 1; + break; + + case 2: /* horizontal line to */ + FT_TRACE6(( "- horizontal line to cx.%d", format & 15 )); + pos[0].y = pos[3].y; + pos[0].x = glyph->x_control[format & 15]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 3: /* vertical line to */ + FT_TRACE6(( "- vertical line to cy.%d", format & 15 )); + pos[0].x = pos[3].x; + pos[0].y = glyph->y_control[format & 15]; + pos[3] = pos[0]; + args_count = 0; + break; + + case 6: /* horizontal to vertical curve */ + FT_TRACE6(( "- hv curve " )); + args_format = 0xB8E; + args_count = 3; + break; + + case 7: /* vertical to horizontal curve */ + FT_TRACE6(( "- vh curve" )); + args_format = 0xE2B; + args_count = 3; + break; + + default: /* general curve to */ + FT_TRACE6(( "- general curve" )); + args_count = 4; + args_format = format & 15; + } + + /***********************************************************/ + /* now read arguments */ + /* */ + cur = pos; + for ( n = 0; n < args_count; n++ ) + { + FT_Int idx, delta; + + + /* read the X argument */ + switch ( args_format & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + cur->x = glyph->x_control[idx]; + FT_TRACE7(( " cx#%d", idx )); + break; + + case 1: /* 16-bit value */ + PFR_CHECK( 2 ); + cur->x = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " x.%d", cur->x )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->x = pos[3].x + delta; + FT_TRACE7(( " dx.%d", delta )); + break; + + default: + FT_TRACE7(( " |" )); + cur->x = pos[3].x; + } + + /* read the Y argument */ + switch ( ( args_format >> 2 ) & 3 ) + { + case 0: /* 8-bit index */ + PFR_CHECK( 1 ); + idx = PFR_NEXT_BYTE( p ); + cur->y = glyph->y_control[idx]; + FT_TRACE7(( " cy#%d", idx )); + break; + + case 1: /* 16-bit absolute value */ + PFR_CHECK( 2 ); + cur->y = PFR_NEXT_SHORT( p ); + FT_TRACE7(( " y.%d", cur->y )); + break; + + case 2: /* 8-bit delta */ + PFR_CHECK( 1 ); + delta = PFR_NEXT_INT8( p ); + cur->y = pos[3].y + delta; + FT_TRACE7(( " dy.%d", delta )); + break; + + default: + FT_TRACE7(( " -" )); + cur->y = pos[3].y; + } + + /* read the additional format flag for the general curve */ + if ( n == 0 && args_count == 4 ) + { + PFR_CHECK( 1 ); + args_format = PFR_NEXT_BYTE( p ); + args_count--; + } + else + args_format >>= 4; + + /* save the previous point */ + pos[3] = cur[0]; + cur++; + } + + FT_TRACE7(( "\n" )); + + /***********************************************************/ + /* finally, execute instruction */ + /* */ + switch ( format >> 4 ) + { + case 0: /* end glyph => EXIT */ + pfr_glyph_end( glyph ); + goto Exit; + + case 1: /* line operations */ + case 2: + case 3: + error = pfr_glyph_line_to( glyph, pos ); + goto Test_Error; + + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ + error = pfr_glyph_move_to( glyph, pos ); + goto Test_Error; + + default: /* curve operations */ + error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); + + Test_Error: /* test error condition */ + if ( error ) + goto Exit; + } + } /* for (;;) */ + } + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); + goto Exit; + } + + + /* load a composite/compound glyph */ + static FT_Error + pfr_glyph_load_compound( PFR_Glyph glyph, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Error error = 0; + FT_GlyphLoader loader = glyph->loader; + FT_Memory memory = loader->memory; + PFR_SubGlyph subglyph; + FT_UInt flags, i, count, org_count; + FT_Int x_pos, y_pos; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + /* test for composite glyphs */ + FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 ); + + count = flags & 0x3F; + + /* ignore extra items when present */ + /* */ + if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Exit; + } + + /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ + /* the PFR format is dumb, using direct file offsets to point to the */ + /* sub-glyphs (instead of glyph indices). Sigh. */ + /* */ + /* For now, we load the list of sub-glyphs into a different array */ + /* but this will prevent us from using the auto-hinter at its best */ + /* quality. */ + /* */ + org_count = glyph->num_subs; + + if ( org_count + count > glyph->max_subs ) + { + FT_UInt new_max = ( org_count + count + 3 ) & -4; + + + if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) + goto Exit; + + glyph->max_subs = new_max; + } + + subglyph = glyph->subs + org_count; + + for ( i = 0; i < count; i++, subglyph++ ) + { + FT_UInt format; + + + x_pos = 0; + y_pos = 0; + + PFR_CHECK( 1 ); + format = PFR_NEXT_BYTE( p ); + + /* read scale when available */ + subglyph->x_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_XSCALE ) + { + PFR_CHECK( 2 ); + subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; + } + + subglyph->y_scale = 0x10000L; + if ( format & PFR_SUBGLYPH_YSCALE ) + { + PFR_CHECK( 2 ); + subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; + } + + /* read offset */ + switch ( format & 3 ) + { + case 1: + PFR_CHECK( 2 ); + x_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + x_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + switch ( ( format >> 2 ) & 3 ) + { + case 1: + PFR_CHECK( 2 ); + y_pos = PFR_NEXT_SHORT( p ); + break; + + case 2: + PFR_CHECK( 1 ); + y_pos += PFR_NEXT_INT8( p ); + break; + + default: + ; + } + + subglyph->x_delta = x_pos; + subglyph->y_delta = y_pos; + + /* read glyph position and size now */ + if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) + { + PFR_CHECK( 2 ); + subglyph->gps_size = PFR_NEXT_USHORT( p ); + } + else + { + PFR_CHECK( 1 ); + subglyph->gps_size = PFR_NEXT_BYTE( p ); + } + + if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) + { + PFR_CHECK( 3 ); + subglyph->gps_offset = PFR_NEXT_LONG( p ); + } + else + { + PFR_CHECK( 2 ); + subglyph->gps_offset = PFR_NEXT_USHORT( p ); + } + + glyph->num_subs++; + } + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); + goto Exit; + } + + + + + + static FT_Error + pfr_glyph_load_rec( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + FT_Error error; + FT_Byte* p; + FT_Byte* limit; + + + if ( FT_STREAM_SEEK( gps_offset + offset ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + p = (FT_Byte*)stream->cursor; + limit = p + size; + + if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) + { + FT_Int n, old_count, count; + FT_GlyphLoader loader = glyph->loader; + FT_Outline* base = &loader->base.outline; + + + old_count = glyph->num_subs; + + /* this is a compound glyph - load it */ + error = pfr_glyph_load_compound( glyph, p, limit ); + + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + count = glyph->num_subs - old_count; + + /* now, load each individual glyph */ + for ( n = 0; n < count; n++ ) + { + FT_Int i, old_points, num_points; + PFR_SubGlyph subglyph; + + + subglyph = glyph->subs + old_count + n; + old_points = base->n_points; + + error = pfr_glyph_load_rec( glyph, stream, gps_offset, + subglyph->gps_offset, + subglyph->gps_size ); + if ( error ) + goto Exit; + + /* note that `glyph->subs' might have been re-allocated */ + subglyph = glyph->subs + old_count + n; + num_points = base->n_points - old_points; + + /* translate and eventually scale the new glyph points */ + if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) + { + FT_Vector* vec = base->points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + + subglyph->x_delta; + vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + + subglyph->y_delta; + } + } + else + { + FT_Vector* vec = loader->base.outline.points + old_points; + + + for ( i = 0; i < num_points; i++, vec++ ) + { + vec->x += subglyph->x_delta; + vec->y += subglyph->y_delta; + } + } + + /* proceed to next sub-glyph */ + } + } + else + { + /* load a simple glyph */ + error = pfr_glyph_load_simple( glyph, p, limit ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + + + + FT_LOCAL_DEF( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ) + { + /* initialize glyph loader */ + FT_GlyphLoader_Rewind( glyph->loader ); + + /* load the glyph, recursively when needed */ + return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); + } + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrgload.h b/lib/freetype/src/pfr/pfrgload.h new file mode 100644 index 0000000..7cc7a87 --- /dev/null +++ b/lib/freetype/src/pfr/pfrgload.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* pfrgload.h */ +/* */ +/* FreeType PFR glyph loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRGLOAD_H__ +#define __PFRGLOAD_H__ + +#include "pfrtypes.h" + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + pfr_glyph_init( PFR_Glyph glyph, + FT_GlyphLoader loader ); + + FT_LOCAL( void ) + pfr_glyph_done( PFR_Glyph glyph ); + + + FT_LOCAL( FT_Error ) + pfr_glyph_load( PFR_Glyph glyph, + FT_Stream stream, + FT_ULong gps_offset, + FT_ULong offset, + FT_ULong size ); + + +FT_END_HEADER + + +#endif /* __PFRGLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrload.c b/lib/freetype/src/pfr/pfrload.c new file mode 100644 index 0000000..87d0757 --- /dev/null +++ b/lib/freetype/src/pfr/pfrload.c @@ -0,0 +1,1021 @@ +/***************************************************************************/ +/* */ +/* pfrload.c */ +/* */ +/* FreeType PFR loader (body). */ +/* */ +/* Copyright 2002 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 "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** EXTRA ITEMS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, + FT_Byte* limit ) + { + return pfr_extra_items_parse( pp, limit, NULL, NULL ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ) + { + FT_Error error = 0; + FT_Byte* p = *pp; + FT_UInt num_items, item_type, item_size; + + + PFR_CHECK( 1 ); + num_items = PFR_NEXT_BYTE( p ); + + for ( ; num_items > 0; num_items-- ) + { + PFR_CHECK( 2 ); + item_size = PFR_NEXT_BYTE( p ); + item_type = PFR_NEXT_BYTE( p ); + + PFR_CHECK( item_size ); + + if ( item_list ) + { + PFR_ExtraItem extra = item_list; + + + for ( extra = item_list; extra->parser != NULL; extra++ ) + { + if ( extra->type == item_type ) + { + error = extra->parser( p, p + item_size, item_data ); + if ( error ) goto Exit; + + break; + } + } + } + + p += item_size; + } + + Exit: + *pp = p; + return error; + + Too_Short: + FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" )); + error = PFR_Err_Invalid_Table; + goto Exit; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR HEADER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static const FT_Frame_Field pfr_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE PFR_HeaderRec + + FT_FRAME_START( 58 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_USHORT( version ), + FT_FRAME_USHORT( signature2 ), + FT_FRAME_USHORT( header_size ), + + FT_FRAME_USHORT( log_dir_size ), + FT_FRAME_USHORT( log_dir_offset ), + + FT_FRAME_USHORT( log_font_max_size ), + FT_FRAME_UOFF3 ( log_font_section_size ), + FT_FRAME_UOFF3 ( log_font_section_offset ), + + FT_FRAME_USHORT( phy_font_max_size ), + FT_FRAME_UOFF3 ( phy_font_section_size ), + FT_FRAME_UOFF3 ( phy_font_section_offset ), + + FT_FRAME_USHORT( gps_max_size ), + FT_FRAME_UOFF3 ( gps_section_size ), + FT_FRAME_UOFF3 ( gps_section_offset ), + + FT_FRAME_BYTE ( max_blue_values ), + FT_FRAME_BYTE ( max_x_orus ), + FT_FRAME_BYTE ( max_y_orus ), + + FT_FRAME_BYTE ( phy_font_max_size_high ), + FT_FRAME_BYTE ( color_flags ), + + FT_FRAME_UOFF3 ( bct_max_size ), + FT_FRAME_UOFF3 ( bct_set_max_size ), + FT_FRAME_UOFF3 ( phy_bct_set_max_size ), + + FT_FRAME_USHORT( num_phy_fonts ), + FT_FRAME_BYTE ( max_vert_stem_snap ), + FT_FRAME_BYTE ( max_horz_stem_snap ), + FT_FRAME_USHORT( max_chars ), + FT_FRAME_END + }; + + + FT_LOCAL_DEF( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ) + { + FT_Error error; + + + /* read header directly */ + if ( !FT_STREAM_SEEK( 0 ) && + !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) ) + { + /* make a few adjustments to the header */ + header->phy_font_max_size += + (FT_UInt32)header->phy_font_max_size_high << 16; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Bool ) + pfr_header_check( PFR_Header header ) + { + FT_Bool result = 1; + + + /* check signature and header size */ + if ( header->signature != 0x50465230L || /* "PFR0" */ + header->version > 4 || + header->header_size < 58 || + header->signature2 != 0x0d0a ) /* CR/LF */ + { + result = 0; + } + return result; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR LOGICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 section_offset, + FT_UInt *acount ) + { + FT_Error error; + FT_UInt count; + FT_UInt result = 0; + + + if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + goto Exit; + + result = count; + + Exit: + *acount = result; + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt idx, + FT_UInt32 section_offset, + FT_Bool size_increment ) + { + FT_UInt num_log_fonts; + FT_UInt flags; + FT_UInt32 offset; + FT_UInt32 size; + FT_Error error; + + + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( num_log_fonts ) ) + goto Exit; + + if ( idx >= num_log_fonts ) + return PFR_Err_Invalid_Argument; + + if ( FT_STREAM_SKIP( idx * 5 ) || + FT_READ_USHORT( size ) || + FT_READ_UOFF3 ( offset ) ) + goto Exit; + + /* save logical font size and offset */ + log_font->size = size; + log_font->offset = offset; + + /* now, check the rest of the table before loading it */ + { + FT_Byte* p; + FT_Byte* limit; + FT_UInt local; + + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK(13); + + log_font->matrix[0] = PFR_NEXT_LONG( p ); + log_font->matrix[1] = PFR_NEXT_LONG( p ); + log_font->matrix[2] = PFR_NEXT_LONG( p ); + log_font->matrix[3] = PFR_NEXT_LONG( p ); + + flags = PFR_NEXT_BYTE( p ); + + local = 0; + if ( flags & PFR_LOG_STROKE ) + { + local++; + if ( flags & PFR_LOG_2BYTE_STROKE ) + local++; + + if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + local += 3; + } + if ( flags & PFR_LOG_BOLD ) + { + local++; + if ( flags & PFR_LOG_2BYTE_BOLD ) + local++; + } + + PFR_CHECK( local ); + + if ( flags & PFR_LOG_STROKE ) + { + log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) + log_font->miter_limit = PFR_NEXT_LONG( p ); + } + + if ( flags & PFR_LOG_BOLD ) + { + log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD ) + ? PFR_NEXT_SHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_LOG_EXTRA_ITEMS ) + { + error = pfr_extra_items_skip( &p, limit ); + if (error) goto Fail; + } + + PFR_CHECK(5); + log_font->phys_size = PFR_NEXT_USHORT( p ); + log_font->phys_offset = PFR_NEXT_ULONG( p ); + if ( size_increment ) + { + PFR_CHECK( 1 ); + log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16; + } + } + + Fail: + FT_FRAME_EXIT(); + + Exit: + return error; + + Too_Short: + FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" )); + error = PFR_Err_Invalid_Table; + goto Fail; + } + + + /***********************************************************************/ + /***********************************************************************/ + /***** *****/ + /***** PFR PHYSICAL FONTS *****/ + /***** *****/ + /***********************************************************************/ + /***********************************************************************/ + + + /* load bitmap strikes lists */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_bitmap_info( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Memory memory = phy_font->memory; + PFR_Strike strike; + FT_UInt flags0; + FT_UInt n, count, size1; + FT_Error error = 0; + + + PFR_CHECK( 5 ); + + p += 3; /* skip bctSize */ + flags0 = PFR_NEXT_BYTE( p ); + count = PFR_NEXT_BYTE( p ); + + /* re-allocate when needed */ + if ( phy_font->num_strikes + count > phy_font->max_strikes ) + { + FT_UInt new_max = (phy_font->num_strikes + count + 3) & -4; + + if ( FT_RENEW_ARRAY( phy_font->strikes, + phy_font->num_strikes, + new_max ) ) + goto Exit; + + phy_font->max_strikes = new_max; + } + + size1 = 1 + 1 + 1 + 2 + 2 + 1; + if ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + size1++; + + if ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + size1++; + + if ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + size1++; + + strike = phy_font->strikes + phy_font->num_strikes; + + PFR_CHECK( count * size1 ); + + for ( n = 0; n < count; n++, strike++ ) + { + strike->x_ppm = ( flags0 & PFR_STRIKE_2BYTE_XPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->y_ppm = ( flags0 & PFR_STRIKE_2BYTE_YPPM ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + strike->flags = PFR_NEXT_BYTE( p ); + + strike->bct_size = ( flags0 & PFR_STRIKE_3BYTE_SIZE ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->bct_offset = ( flags0 & PFR_STRIKE_3BYTE_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + + strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + } + + phy_font->num_strikes += count; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" )); + goto Exit; + } + + + /* load font ID, this is a so-called "unique" name that is rather + * long and descriptive (like "Tiresias ScreenFont v7.51"). + * + * note that a PFR font's family name is contained in an *undocumented* + * string of the "auxiliary data" portion of a physical font record. this + * may also contain the "real" style name ! + * + * if no family name is present, the font id is used instead for the + * family + */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_font_id( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + FT_UInt len = (FT_UInt)( limit - p ); + + + if ( phy_font->font_id != NULL ) + goto Exit; + + if ( FT_ALLOC( phy_font->font_id, len+1 ) ) + goto Exit; + + /* copy font ID name, and terminate it for safety */ + FT_MEM_COPY( phy_font->font_id, p, len ); + phy_font->font_id[len] = 0; + + Exit: + return error; + } + + + /* load stem snap tables */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_stem_snaps( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_UInt count, num_vert, num_horz; + FT_Int* snaps; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + + if ( phy_font->vertical.stem_snaps != NULL ) + goto Exit; + + PFR_CHECK( 1 ); + count = PFR_NEXT_BYTE( p ); + + num_vert = count & 15; + num_horz = count >> 4; + count = num_vert + num_horz; + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( snaps, count ) ) + goto Exit; + + phy_font->vertical.stem_snaps = snaps; + phy_font->horizontal.stem_snaps = snaps + num_vert; + + for ( ; count > 0; count--, snaps++ ) + *snaps = FT_NEXT_SHORT( p ); + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" )); + goto Exit; + } + + +#if 0 + + /* load kerning pair data */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_kerning_pairs( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + FT_Int count; + FT_UShort base_adj; + FT_UInt flags; + FT_UInt num_pairs; + PFR_KernPair pairs; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + + /* allocate a new kerning item */ + /* XXX: there may be multiple extra items for kerning */ + if ( phy_font->kern_pairs != NULL ) + goto Exit; + + FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); + + PFR_CHECK( 4 ); + + num_pairs = PFR_NEXT_BYTE( p ); + base_adj = PFR_NEXT_SHORT( p ); + flags = PFR_NEXT_BYTE( p ); + +#ifndef PFR_CONFIG_NO_CHECKS + count = 3; + + if ( flags & PFR_KERN_2BYTE_CHAR ) + count += 2; + + if ( flags & PFR_KERN_2BYTE_ADJ ) + count += 1; + + PFR_CHECK( num_pairs * count ); +#endif + + if ( FT_NEW_ARRAY( pairs, num_pairs ) ) + goto Exit; + + phy_font->num_kern_pairs = num_pairs; + phy_font->kern_pairs = pairs; + + for (count = num_pairs ; count > 0; count--, pairs++ ) + { + if ( flags & PFR_KERN_2BYTE_CHAR ) + { + pairs->glyph1 = PFR_NEXT_USHORT( p ); + pairs->glyph2 = PFR_NEXT_USHORT( p ); + } + else + { + pairs->glyph1 = PFR_NEXT_BYTE( p ); + pairs->glyph2 = PFR_NEXT_BYTE( p ); + } + + if ( flags & PFR_KERN_2BYTE_ADJ ) + pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p ); + else + pairs->kerning.x = base_adj + PFR_NEXT_INT8( p ); + + pairs->kerning.y = 0; + + FT_TRACE2(( "kerning %d <-> %d : %ld\n", + pairs->glyph1, pairs->glyph2, pairs->kerning.x )); + } + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " + "invalid kerning pairs table\n" )); + goto Exit; + } + +#else /* 0 */ + + /* load kerning pair data */ + FT_CALLBACK_DEF( FT_Error ) + pfr_extra_item_load_kerning_pairs( FT_Byte* p, + FT_Byte* limit, + PFR_PhyFont phy_font ) + { + PFR_KernItem item; + FT_Error error = 0; + FT_Memory memory = phy_font->memory; + + + FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); + + if ( FT_NEW( item ) ) + goto Exit; + + PFR_CHECK( 4 ); + + item->pair_count = PFR_NEXT_BYTE( p ); + item->base_adj = PFR_NEXT_SHORT( p ); + item->flags = PFR_NEXT_BYTE( p ); + item->offset = phy_font->offset + ( p - phy_font->cursor ); + +#ifndef PFR_CONFIG_NO_CHECKS + item->pair_size = 3; + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + item->pair_size += 2; + + if ( item->flags & PFR_KERN_2BYTE_ADJ ) + item->pair_size += 1; + + PFR_CHECK( item->pair_count * item->pair_size ); +#endif + + /* load first and last pairs into the item to speed up */ + /* lookup later... */ + if ( item->pair_count > 0 ) + { + FT_UInt char1, char2; + FT_Byte* q; + + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + { + q = p; + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_USHORT( q ); + char2 = PFR_NEXT_USHORT( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + else + { + q = p; + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair1 = PFR_KERN_INDEX( char1, char2 ); + + q = p + item->pair_size * ( item->pair_count - 1 ); + char1 = PFR_NEXT_BYTE( q ); + char2 = PFR_NEXT_BYTE( q ); + + item->pair2 = PFR_KERN_INDEX( char1, char2 ); + } + + /* add new item to the current list */ + item->next = NULL; + *phy_font->kern_items_tail = item; + phy_font->kern_items_tail = &item->next; + phy_font->num_kern_pairs += item->pair_count; + } + else + { + /* empty item! */ + FT_FREE( item ); + } + + Exit: + return error; + + Too_Short: + FT_FREE( item ); + + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_extra_item_load_kerning_pairs: " + "invalid kerning pairs table\n" )); + goto Exit; + } +#endif /* 0 */ + + + static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = + { + { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info }, + { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id }, + { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps }, + { 4, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_kerning_pairs }, + { 0, NULL } + }; + + + /* loads a name from the auxiliary data. Since this extracts undocumented + * strings from the font file, we need to be careful here + */ + static FT_Error + pfr_aux_name_load( FT_Byte* p, + FT_UInt len, + FT_Memory memory, + FT_String* *astring ) + { + FT_Error error = 0; + FT_String* result = NULL; + FT_UInt n, ok; + + if ( len > 0 && p[len-1] == 0 ) + len--; + + /* check that each character is ASCII, that's to be sure + * to not load garbage.. + */ + ok = (len > 0); + for ( n = 0; n < len; n++ ) + if ( p[n] < 32 || p[n] > 127 ) + { + ok = 0; + break; + } + + if ( ok ) + { + if ( FT_ALLOC( result, len+1 ) ) + goto Exit; + + FT_MEM_COPY( result, p, len ); + result[len] = 0; + } + Exit: + *astring = result; + return error; + } + + + FT_LOCAL_DEF( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ) + { + FT_FREE( phy_font->font_id ); + FT_FREE( phy_font->family_name ); + FT_FREE( phy_font->style_name ); + + FT_FREE( phy_font->vertical.stem_snaps ); + phy_font->vertical.num_stem_snaps = 0; + + phy_font->horizontal.stem_snaps = NULL; + phy_font->horizontal.num_stem_snaps = 0; + + FT_FREE( phy_font->strikes ); + phy_font->num_strikes = 0; + phy_font->max_strikes = 0; + + FT_FREE( phy_font->chars ); + phy_font->num_chars = 0; + phy_font->chars_offset = 0; + + FT_FREE( phy_font->blue_values ); + phy_font->num_blue_values = 0; + + { + PFR_KernItem item, next; + + + item = phy_font->kern_items; + while ( item ) + { + next = item->next; + FT_FREE( item ); + item = next; + } + phy_font->kern_items = NULL; + phy_font->kern_items_tail = NULL; + } + + phy_font->num_kern_pairs = 0; + } + + + + FT_LOCAL_DEF( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_UInt flags, num_aux; + FT_Byte* p; + FT_Byte* limit; + + + phy_font->memory = memory; + phy_font->offset = offset; + + phy_font->kern_items = NULL; + phy_font->kern_items_tail = &phy_font->kern_items; + + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + goto Exit; + + phy_font->cursor = stream->cursor; + + p = stream->cursor; + limit = p + size; + + PFR_CHECK( 15 ); + phy_font->font_ref_number = PFR_NEXT_USHORT( p ); + phy_font->outline_resolution = PFR_NEXT_USHORT( p ); + phy_font->metrics_resolution = PFR_NEXT_USHORT( p ); + phy_font->bbox.xMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMin = PFR_NEXT_SHORT( p ); + phy_font->bbox.xMax = PFR_NEXT_SHORT( p ); + phy_font->bbox.yMax = PFR_NEXT_SHORT( p ); + phy_font->flags = flags = PFR_NEXT_BYTE( p ); + + /* get the standard advance for non-proprotional fonts */ + if ( !(flags & PFR_PHY_PROPORTIONAL) ) + { + PFR_CHECK( 2 ); + phy_font->standard_advance = PFR_NEXT_SHORT( p ); + } + + /* load the extra items when present */ + if ( flags & PFR_PHY_EXTRA_ITEMS ) + { + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); + + if ( error ) + goto Fail; + } + + /* in certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts */ + PFR_CHECK( 3 ); + num_aux = PFR_NEXT_ULONG( p ); + + if ( num_aux > 0 ) + { + FT_Byte* q = p; + FT_Byte* q2; + + PFR_CHECK( num_aux ); + p += num_aux; + + while ( num_aux > 0 ) + { + FT_UInt length, type; + + if ( q + 4 > p ) + break; + + length = PFR_NEXT_USHORT(q); + if ( length < 4 || length > num_aux ) + break; + + q2 = q + length - 2; + type = PFR_NEXT_USHORT(q); + + switch ( type ) + { + case 1: + { + /* this seems to correspond to the font's family name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length-4U, memory, + &phy_font->family_name ); + if ( error ) + goto Exit; + } + break; + + case 2: + { + if ( q + 32 > q2 ) + break; + + q += 10; + phy_font->ascent = PFR_NEXT_SHORT(q); + phy_font->descent = PFR_NEXT_SHORT(q); + phy_font->leading = PFR_NEXT_SHORT(q); + q += 16; + } + break; + + case 3: + { + /* this seems to correspond to the font's style name, + * padded to 16-bits with one zero when necessary + */ + error = pfr_aux_name_load( q, length-4U, memory, + &phy_font->style_name ); + if ( error ) + goto Exit; + } + break; + + default: + ; + } + q = q2; + num_aux -= length; + } + } + + /* read the blue values */ + { + FT_UInt n, count; + + PFR_CHECK( 1 ); + phy_font->num_blue_values = count = PFR_NEXT_BYTE( p ); + + PFR_CHECK( count * 2 ); + + if ( FT_NEW_ARRAY( phy_font->blue_values, count ) ) + goto Fail; + + for ( n = 0; n < count; n++ ) + phy_font->blue_values[n] = PFR_NEXT_SHORT( p ); + } + + PFR_CHECK( 8 ); + phy_font->blue_fuzz = PFR_NEXT_BYTE( p ); + phy_font->blue_scale = PFR_NEXT_BYTE( p ); + + phy_font->vertical.standard = PFR_NEXT_USHORT( p ); + phy_font->horizontal.standard = PFR_NEXT_USHORT( p ); + + /* read the character descriptors */ + { + FT_UInt n, count, Size; + + + phy_font->num_chars = count = PFR_NEXT_USHORT( p ); + phy_font->chars_offset = offset + ( p - stream->cursor ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; + + Size = 1 + 1 + 2; + if ( flags & PFR_PHY_2BYTE_CHARCODE ) + Size += 1; + + if ( flags & PFR_PHY_PROPORTIONAL ) + Size += 2; + + if ( flags & PFR_PHY_ASCII_CODE ) + Size += 1; + + if ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + Size += 1; + + if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + Size += 1; + + PFR_CHECK( count * Size ); + + for ( n = 0; n < count; n++ ) + { + PFR_Char cur = &phy_font->chars[n]; + + + cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->advance = ( flags & PFR_PHY_PROPORTIONAL ) + ? PFR_NEXT_SHORT( p ) + : (FT_Int) phy_font->standard_advance; + +#if 0 + cur->ascii = ( flags & PFR_PHY_ASCII_CODE ) + ? PFR_NEXT_BYTE( p ) + : 0; +#else + if ( flags & PFR_PHY_ASCII_CODE ) + p += 1; +#endif + cur->gps_size = ( flags & PFR_PHY_2BYTE_GPS_SIZE ) + ? PFR_NEXT_USHORT( p ) + : PFR_NEXT_BYTE( p ); + + cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) + ? PFR_NEXT_ULONG( p ) + : PFR_NEXT_USHORT( p ); + } + } + + /* that's it !! */ + Fail: + FT_FRAME_EXIT(); + + /* save position of bitmap info */ + phy_font->bct_offset = FT_STREAM_POS(); + phy_font->cursor = NULL; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" )); + goto Fail; + } + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrload.h b/lib/freetype/src/pfr/pfrload.h new file mode 100644 index 0000000..9e54b7d --- /dev/null +++ b/lib/freetype/src/pfr/pfrload.h @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* pfrload.h */ +/* */ +/* FreeType PFR loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRLOAD_H__ +#define __PFRLOAD_H__ + +#include "pfrobjs.h" +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + +#ifdef PFR_CONFIG_NO_CHECKS +#define PFR_CHECK( x ) do { } while ( 0 ) +#else +#define PFR_CHECK( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) +#endif + +#define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) +#define PFR_NEXT_INT8( p ) FT_NEXT_CHAR( p ) +#define PFR_NEXT_SHORT( p ) FT_NEXT_SHORT( p ) +#define PFR_NEXT_USHORT( p ) FT_NEXT_USHORT( p ) +#define PFR_NEXT_LONG( p ) FT_NEXT_OFF3( p ) +#define PFR_NEXT_ULONG( p ) FT_NEXT_UOFF3( p ) + + + /* handling extra items */ + + typedef FT_Error + (*PFR_ExtraItem_ParseFunc)( FT_Byte* p, + FT_Byte* limit, + FT_Pointer data ); + + typedef struct PFR_ExtraItemRec_ + { + FT_UInt type; + PFR_ExtraItem_ParseFunc parser; + + } PFR_ExtraItemRec; + + typedef const struct PFR_ExtraItemRec_* PFR_ExtraItem; + + + FT_LOCAL( FT_Error ) + pfr_extra_items_skip( FT_Byte* *pp, + FT_Byte* limit ); + + FT_LOCAL( FT_Error ) + pfr_extra_items_parse( FT_Byte* *pp, + FT_Byte* limit, + PFR_ExtraItem item_list, + FT_Pointer item_data ); + + + /* load a PFR header */ + FT_LOCAL( FT_Error ) + pfr_header_load( PFR_Header header, + FT_Stream stream ); + + /* check a PFR header */ + FT_LOCAL( FT_Bool ) + pfr_header_check( PFR_Header header ); + + + /* return number of logical fonts in this file */ + FT_LOCAL( FT_Error ) + pfr_log_font_count( FT_Stream stream, + FT_UInt32 log_section_offset, + FT_UInt *acount ); + + /* load a pfr logical font entry */ + FT_LOCAL( FT_Error ) + pfr_log_font_load( PFR_LogFont log_font, + FT_Stream stream, + FT_UInt face_index, + FT_UInt32 section_offset, + FT_Bool size_increment ); + + + /* load a physical font entry */ + FT_LOCAL( FT_Error ) + pfr_phy_font_load( PFR_PhyFont phy_font, + FT_Stream stream, + FT_UInt32 offset, + FT_UInt32 size ); + + /* finalize a physical font */ + FT_LOCAL( void ) + pfr_phy_font_done( PFR_PhyFont phy_font, + FT_Memory memory ); + + /* */ + +FT_END_HEADER + +#endif /* __PFRLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrobjs.c b/lib/freetype/src/pfr/pfrobjs.c new file mode 100644 index 0000000..867644a --- /dev/null +++ b/lib/freetype/src/pfr/pfrobjs.c @@ -0,0 +1,481 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.c */ +/* */ +/* FreeType PFR object methods (body). */ +/* */ +/* Copyright 2002 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 "pfrobjs.h" +#include "pfrload.h" +#include "pfrgload.h" +#include "pfrcmap.h" +#include "pfrsbit.h" +#include FT_OUTLINE_H +#include FT_INTERNAL_DEBUG_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FACE OBJECT METHODS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + pfr_face_done( PFR_Face face ) + { + FT_Memory memory = face->root.driver->root.memory; + + /* we don't want dangling pointers */ + face->root.family_name = NULL; + face->root.style_name = NULL; + + /* finalize the physical font record */ + pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); + + /* no need to finalize the logical font or the header */ + FT_FREE( face->root.available_sizes ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_face_init( FT_Stream stream, + PFR_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + /* load the header and check it */ + error = pfr_header_load( &face->header, stream ); + if ( error ) + goto Exit; + + if ( !pfr_header_check( &face->header ) ) + { + FT_TRACE4(( "pfr_face_init: not a valid PFR font\n" )); + error = PFR_Err_Unknown_File_Format; + goto Exit; + } + + /* check face index */ + { + FT_UInt num_faces; + + + error = pfr_log_font_count( stream, + face->header.log_dir_offset, + &num_faces ); + if ( error ) + goto Exit; + + face->root.num_faces = num_faces; + } + + if ( face_index < 0 ) + goto Exit; + + if ( face_index >= face->root.num_faces ) + { + FT_ERROR(( "pfr_face_init: invalid face index\n" )); + error = PFR_Err_Invalid_Argument; + goto Exit; + } + + /* load the face */ + error = pfr_log_font_load( + &face->log_font, stream, face_index, + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + if ( error ) + goto Exit; + + /* now load the physical font descriptor */ + error = pfr_phy_font_load( &face->phy_font, stream, + face->log_font.phys_offset, + face->log_font.phys_size ); + if ( error ) + goto Exit; + + /* now, set-up all root face fields */ + { + FT_Face root = FT_FACE( face ); + PFR_PhyFont phy_font = &face->phy_font; + + + root->face_index = face_index; + root->num_glyphs = phy_font->num_chars; + root->face_flags = FT_FACE_FLAG_SCALABLE; + + if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( phy_font->flags & PFR_PHY_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_VERTICAL; + else + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + + if ( phy_font->num_strikes > 0 ) + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + + if ( phy_font->num_kern_pairs > 0 ) + root->face_flags |= FT_FACE_FLAG_KERNING; + + /* if no family name was found in the "undocumented" auxiliary + * data, use the font ID instead. This sucks but is better than + * nothing + */ + root->family_name = phy_font->family_name; + if ( root->family_name == NULL ) + root->family_name = phy_font->font_id; + + /* note that the style name can be NULL in certain PFR fonts, + * probably meaning "Regular" + */ + root->style_name = phy_font->style_name; + + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox = phy_font->bbox; + root->units_per_EM = (FT_UShort)phy_font->outline_resolution; + root->ascender = (FT_Short) phy_font->bbox.yMax; + root->descender = (FT_Short) phy_font->bbox.yMin; + root->height = (FT_Short) + ( ( ( root->ascender - root->descender ) * 12 ) + / 10 ); + + if ( phy_font->num_strikes > 0 ) + { + FT_UInt n, count = phy_font->num_strikes; + FT_Bitmap_Size* size; + PFR_Strike strike; + FT_Memory memory = root->stream->memory; + + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + size = root->available_sizes; + strike = phy_font->strikes; + for ( n = 0; n < count; n++, size++, strike++ ) + { + size->height = (FT_UShort) strike->y_ppm; + size->width = (FT_UShort) strike->x_ppm; + } + root->num_fixed_sizes = count; + } + + /* now compute maximum advance width */ + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) + root->max_advance_width = (FT_Short)phy_font->standard_advance; + else + { + FT_Int max = 0; + FT_UInt count = phy_font->num_chars; + PFR_Char gchar = phy_font->chars; + + + for ( ; count > 0; count--, gchar++ ) + { + if ( max < gchar->advance ) + max = gchar->advance; + } + + root->max_advance_width = (FT_Short)max; + } + + root->max_advance_height = root->height; + + root->underline_position = (FT_Short)( - root->units_per_EM / 10 ); + root->underline_thickness = (FT_Short)( root->units_per_EM / 30 ); + + /* create charmap */ + { + FT_CharMapRec charmap; + + + charmap.face = root; + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + + /* check whether we've loaded any kerning pairs */ + if ( phy_font->num_kern_pairs ) + root->face_flags |= FT_FACE_FLAG_KERNING; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SLOT OBJECT METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_init( PFR_Slot slot ) + { + FT_GlyphLoader loader = slot->root.internal->loader; + + pfr_glyph_init( &slot->glyph, loader ); + + return 0; + } + + + FT_LOCAL_DEF( void ) + pfr_slot_done( PFR_Slot slot ) + { + pfr_glyph_done( &slot->glyph ); + } + + + FT_LOCAL_DEF( FT_Error ) + pfr_slot_load( PFR_Slot slot, + PFR_Size size, + FT_UInt gindex, + FT_Int32 load_flags ) + { + FT_Error error; + PFR_Face face = (PFR_Face)slot->root.face; + PFR_Char gchar; + FT_Outline* outline = &slot->root.outline; + FT_ULong gps_offset; + + if (gindex > 0) + gindex--; + + /* check that the glyph index is correct */ + FT_ASSERT( gindex < face->phy_font.num_chars ); + + /* try to load an embedded bitmap */ + if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) + { + error = pfr_slot_load_bitmap( slot, size, gindex ); + if ( error == 0 ) + goto Exit; + } + + if ( load_flags & FT_LOAD_SBITS_ONLY ) + { + error = FT_Err_Invalid_Argument; + goto Exit; + } + + gchar = face->phy_font.chars + gindex; + slot->root.format = FT_GLYPH_FORMAT_OUTLINE; + outline->n_points = 0; + outline->n_contours = 0; + gps_offset = face->header.gps_section_offset; + + /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ + error = pfr_glyph_load( &slot->glyph, face->root.stream, + gps_offset, gchar->gps_offset, gchar->gps_size ); + + if ( !error ) + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &slot->root.metrics; + FT_Pos advance; + FT_Int em_metrics, em_outline; + FT_Bool scaling; + + + scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + + /* copy outline data */ + *outline = slot->glyph.loader->base.outline; + + outline->flags &= ~FT_OUTLINE_OWNER; + outline->flags |= FT_OUTLINE_REVERSE_FILL; + + if ( size && size->root.metrics.y_ppem < 24 ) + outline->flags |= FT_OUTLINE_HIGH_PRECISION; + + /* compute the advance vector */ + metrics->horiAdvance = 0; + metrics->vertAdvance = 0; + + advance = gchar->advance; + em_metrics = face->phy_font.metrics_resolution; + em_outline = face->phy_font.outline_resolution; + + if ( em_metrics != em_outline ) + advance = FT_MulDiv( advance, em_outline, em_metrics ); + + if ( face->phy_font.flags & PFR_PHY_VERTICAL ) + metrics->vertAdvance = advance; + else + metrics->horiAdvance = advance; + + slot->root.linearHoriAdvance = metrics->horiAdvance; + slot->root.linearVertAdvance = metrics->vertAdvance; + + /* make-up vertical metrics(?) */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + + /* scale when needed */ + if ( scaling ) + { + FT_Int n; + FT_Fixed x_scale = size->root.metrics.x_scale; + FT_Fixed y_scale = size->root.metrics.y_scale; + FT_Vector* vec = outline->points; + + + /* scale outline points */ + for ( n = 0; n < outline->n_points; n++, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + /* scale the advance */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + } + + /* compute the rest of the metrics */ + FT_Outline_Get_CBox( outline, &cbox ); + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax - metrics->height; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** KERNING METHOD *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) + pfr_face_get_kerning( PFR_Face face, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + FT_Error error; + PFR_PhyFont phy_font = &face->phy_font; + PFR_KernItem item = phy_font->kern_items; + FT_UInt32 idx = PFR_KERN_INDEX( glyph1, glyph2 ); + + + kerning->x = 0; + kerning->y = 0; + + /* find the kerning item containing our pair */ + while ( item ) + { + if ( item->pair1 <= idx && idx <= item->pair2 ) + goto Found_Item; + + item = item->next; + } + + /* not found */ + goto Exit; + + Found_Item: + { + /* perform simply binary search within the item */ + FT_UInt min, mid, max; + FT_Stream stream = face->root.stream; + FT_Byte* p; + + + if ( FT_STREAM_SEEK( item->offset ) || + FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) + goto Exit; + + min = 0; + max = item->pair_count; + while ( min < max ) + { + FT_UInt char1, char2, charcode; + + + mid = ( min + max ) >> 1; + p = stream->cursor + mid*item->pair_size; + + if ( item->flags & PFR_KERN_2BYTE_CHAR ) + { + char1 = FT_NEXT_USHORT( p ); + char2 = FT_NEXT_USHORT( p ); + } + else + { + char1 = FT_NEXT_USHORT( p ); + char2 = FT_NEXT_USHORT( p ); + } + charcode = PFR_KERN_INDEX( char1, char2 ); + + if ( idx == charcode ) + { + if ( item->flags & PFR_KERN_2BYTE_ADJ ) + kerning->x = item->base_adj + FT_NEXT_SHORT( p ); + else + kerning->x = item->base_adj + FT_NEXT_CHAR( p ); + + break; + } + if ( idx > charcode ) + min = mid + 1; + else + max = mid; + } + + FT_FRAME_EXIT(); + } + + Exit: + return 0; + } + +/* END */ diff --git a/lib/freetype/src/pfr/pfrobjs.h b/lib/freetype/src/pfr/pfrobjs.h new file mode 100644 index 0000000..b29b64c --- /dev/null +++ b/lib/freetype/src/pfr/pfrobjs.h @@ -0,0 +1,96 @@ +/***************************************************************************/ +/* */ +/* pfrobjs.h */ +/* */ +/* FreeType PFR object methods (specification). */ +/* */ +/* Copyright 2002 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 __PFROBJS_H__ +#define __PFROBJS_H__ + +#include "pfrtypes.h" + + +FT_BEGIN_HEADER + + typedef struct PFR_FaceRec_* PFR_Face; + + typedef struct PFR_SizeRec_* PFR_Size; + + typedef struct PFR_SlotRec_* PFR_Slot; + + + typedef struct PFR_FaceRec_ + { + FT_FaceRec root; + PFR_HeaderRec header; + PFR_LogFontRec log_font; + PFR_PhyFontRec phy_font; + + } PFR_FaceRec; + + + typedef struct PFR_SizeRec_ + { + FT_SizeRec root; + + } PFR_SizeRec; + + + typedef struct PFR_SlotRec_ + { + FT_GlyphSlotRec root; + PFR_GlyphRec glyph; + + } PFR_SlotRec; + + + FT_LOCAL( FT_Error ) + pfr_face_init( FT_Stream stream, + PFR_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + pfr_face_done( PFR_Face face ); + + + FT_LOCAL( FT_Error ) + pfr_face_get_kerning( PFR_Face face, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + + FT_LOCAL( FT_Error ) + pfr_slot_init( PFR_Slot slot ); + + FT_LOCAL( void ) + pfr_slot_done( PFR_Slot slot ); + + + FT_LOCAL( FT_Error ) + pfr_slot_load( PFR_Slot slot, + PFR_Size size, + FT_UInt gindex, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __PFROBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrsbit.c b/lib/freetype/src/pfr/pfrsbit.c new file mode 100644 index 0000000..408b063 --- /dev/null +++ b/lib/freetype/src/pfr/pfrsbit.c @@ -0,0 +1,669 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.c */ +/* */ +/* FreeType PFR bitmap loader (body). */ +/* */ +/* Copyright 2002 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 "pfrsbit.h" +#include "pfrload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "pfrerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pfr + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PFR BIT WRITER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PFR_BitWriter_ + { + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_Int width; /* width in pixels/bits */ + FT_Int rows; /* number of remaining rows to scan */ + FT_Int total; /* total number of bits to draw */ + + } PFR_BitWriterRec, *PFR_BitWriter; + + + static void + pfr_bitwriter_init( PFR_BitWriter writer, + FT_Bitmap* target, + FT_UInt decreasing ) + { + writer->line = target->buffer; + writer->pitch = target->pitch; + writer->width = target->width; + writer->rows = target->rows; + writer->total = writer->width * writer->rows; + + if ( !decreasing ) + { + writer->line += writer->pitch * ( target->rows-1 ); + writer->pitch = -writer->pitch; + } + } + + + static void + pfr_bitwriter_decode_bytes( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt val = 0; + FT_UInt c = 0; + + + n = (FT_Int)( limit - p ) * 8; + if ( n > writer->total ) + n = writer->total; + + reload = n & 7; + + for ( ; n > 0; n-- ) + { + if ( ( n & 7 ) == reload ) + val = *p++; + + if ( val & 0x80 ) + c |= mask; + + val <<= 1; + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte)c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte)c; + mask = 0x80; + c = 0; + cur ++; + } + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + static void + pfr_bitwriter_decode_rle1( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, counts[2], reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + counts[0] = 0; + counts[1] = 0; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( phase ) + { + FT_Int v; + + + if ( p >= limit ) + break; + + v = *p++; + counts[0] = v >> 4; + counts[1] = v & 15; + phase = 0; + count = counts[0]; + } + else + { + phase = 1; + count = counts[1]; + } + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + left = writer->width; + mask = 0x80; + + writer->line += writer->pitch; + cur = writer->line; + c = 0; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte) c; + mask = 0x80; + c = 0; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + static void + pfr_bitwriter_decode_rle2( PFR_BitWriter writer, + FT_Byte* p, + FT_Byte* limit ) + { + FT_Int n, phase, count, reload; + FT_Int left = writer->width; + FT_Byte* cur = writer->line; + FT_UInt mask = 0x80; + FT_UInt c = 0; + + + n = writer->total; + + phase = 1; + count = 0; + reload = 1; + + for ( ; n > 0; n-- ) + { + if ( reload ) + { + do + { + if ( p >= limit ) + break; + + count = *p++; + phase = phase ^ 1; + + } while ( count == 0 ); + } + + if ( phase ) + c |= mask; + + mask >>= 1; + + if ( --left <= 0 ) + { + cur[0] = (FT_Byte) c; + c = 0; + mask = 0x80; + left = writer->width; + + writer->line += writer->pitch; + cur = writer->line; + } + else if ( mask == 0 ) + { + cur[0] = (FT_Byte) c; + c = 0; + mask = 0x80; + cur ++; + } + + reload = ( --count <= 0 ); + } + + if ( mask != 0x80 ) + cur[0] = (FT_Byte) c; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP DATA DECODING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + pfr_lookup_bitmap_data( FT_Byte* base, + FT_Byte* limit, + FT_Int count, + FT_Byte flags, + FT_UInt char_code, + FT_ULong* found_offset, + FT_ULong* found_size ) + { + FT_UInt left, right, char_len; + FT_Bool two = FT_BOOL( flags & 1 ); + FT_Byte* buff; + + + char_len = 4; + if ( two ) char_len += 1; + if ( flags & 2 ) char_len += 1; + if ( flags & 4 ) char_len += 1; + + left = 0; + right = count; + + while ( left < right ) + { + FT_UInt middle, code; + + + middle = ( left + right ) >> 1; + buff = base + middle * char_len; + + /* check that we are not outside of the table -- */ + /* this is possible with broken fonts... */ + if ( buff + char_len > limit ) + goto Fail; + + if ( two ) + code = PFR_NEXT_USHORT( buff ); + else + code = PFR_NEXT_BYTE( buff ); + + if ( code == char_code ) + goto Found_It; + + if ( code < char_code ) + left = middle; + else + right = middle; + } + + Fail: + /* Not found */ + *found_size = 0; + *found_offset = 0; + return; + + Found_It: + if ( flags & 2 ) + *found_size = PFR_NEXT_USHORT( buff ); + else + *found_size = PFR_NEXT_BYTE( buff ); + + if ( flags & 4 ) + *found_offset = PFR_NEXT_ULONG( buff ); + else + *found_offset = PFR_NEXT_USHORT( buff ); + } + + + /* load bitmap metrics. "*padvance" must be set to the default value */ + /* before calling this function... */ + /* */ + static FT_Error + pfr_load_bitmap_metrics( FT_Byte** pdata, + FT_Byte* limit, + FT_Long scaled_advance, + FT_Long *axpos, + FT_Long *aypos, + FT_UInt *axsize, + FT_UInt *aysize, + FT_Long *aadvance, + FT_UInt *aformat ) + { + FT_Error error = 0; + FT_Byte flags; + FT_Char b; + FT_Byte* p = *pdata; + FT_Long xpos, ypos, advance; + FT_UInt xsize, ysize; + + + PFR_CHECK( 1 ); + flags = PFR_NEXT_BYTE( p ); + + xpos = 0; + ypos = 0; + xsize = 0; + ysize = 0; + advance = 0; + + switch ( flags & 3 ) + { + case 0: + PFR_CHECK( 1 ); + b = PFR_NEXT_INT8( p ); + xpos = b >> 4; + ypos = ( (FT_Char)( b << 4 ) ) >> 4; + break; + + case 1: + PFR_CHECK( 2 ); + xpos = PFR_NEXT_INT8( p ); + ypos = PFR_NEXT_INT8( p ); + break; + + case 2: + PFR_CHECK( 4 ); + xpos = PFR_NEXT_SHORT( p ); + ypos = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 6 ); + xpos = PFR_NEXT_LONG( p ); + ypos = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + /* blank image */ + xsize = 0; + ysize = 0; + break; + + case 1: + PFR_CHECK( 1 ); + b = PFR_NEXT_BYTE( p ); + xsize = ( b >> 4 ) & 0xF; + ysize = b & 0xF; + break; + + case 2: + PFR_CHECK( 2 ); + xsize = PFR_NEXT_BYTE( p ); + ysize = PFR_NEXT_BYTE( p ); + break; + + case 3: + PFR_CHECK( 4 ); + xsize = PFR_NEXT_USHORT( p ); + ysize = PFR_NEXT_USHORT( p ); + break; + + default: + ; + } + + flags >>= 2; + switch ( flags & 3 ) + { + case 0: + advance = scaled_advance; + break; + + case 1: + PFR_CHECK( 1 ); + advance = PFR_NEXT_INT8( p ) << 8; + break; + + case 2: + PFR_CHECK( 2 ); + advance = PFR_NEXT_SHORT( p ); + break; + + case 3: + PFR_CHECK( 3 ); + advance = PFR_NEXT_LONG( p ); + break; + + default: + ; + } + + *axpos = xpos; + *aypos = ypos; + *axsize = xsize; + *aysize = ysize; + *aadvance = advance; + *aformat = flags >> 2; + *pdata = p; + + Exit: + return error; + + Too_Short: + error = PFR_Err_Invalid_Table; + FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); + goto Exit; + } + + + static FT_Error + pfr_load_bitmap_bits( FT_Byte* p, + FT_Byte* limit, + FT_UInt format, + FT_UInt decreasing, + FT_Bitmap* target ) + { + FT_Error error = 0; + PFR_BitWriterRec writer; + + + if ( target->rows > 0 && target->width > 0 ) + { + pfr_bitwriter_init( &writer, target, decreasing ); + + switch ( format ) + { + case 0: /* packed bits */ + pfr_bitwriter_decode_bytes( &writer, p, limit ); + break; + + case 1: /* RLE1 */ + pfr_bitwriter_decode_rle1( &writer, p, limit ); + break; + + case 2: /* RLE2 */ + pfr_bitwriter_decode_rle2( &writer, p, limit ); + break; + + default: + FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); + error = FT_Err_Invalid_File_Format; + } + } + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BITMAP LOADING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ) + { + FT_Error error; + PFR_Face face = (PFR_Face) glyph->root.face; + FT_Stream stream = face->root.stream; + PFR_PhyFont phys = &face->phy_font; + FT_ULong gps_offset; + FT_ULong gps_size; + PFR_Char character; + PFR_Strike strike; + + + character = &phys->chars[glyph_index]; + + /* Look-up a bitmap strike corresponding to the current */ + /* character dimensions */ + { + FT_UInt n; + + + strike = phys->strikes; + for ( n = 0; n < phys->num_strikes; n++ ) + { + if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && + strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) + { + goto Found_Strike; + } + + strike++; + } + + /* couldn't find it */ + return FT_Err_Invalid_Argument; + } + + Found_Strike: + + /* Now lookup the glyph's position within the file */ + { + FT_UInt char_len; + + + char_len = 4; + if ( strike->flags & 1 ) char_len += 1; + if ( strike->flags & 2 ) char_len += 1; + if ( strike->flags & 4 ) char_len += 1; + + /* Access data directly in the frame to speed lookups */ + if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || + FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) + goto Exit; + + pfr_lookup_bitmap_data( stream->cursor, + stream->limit, + strike->num_bitmaps, + (FT_Byte) strike->flags, + character->char_code, + &gps_offset, + &gps_size ); + + FT_FRAME_EXIT(); + + if ( gps_size == 0 ) + { + /* Could not find a bitmap program string for this glyph */ + error = FT_Err_Invalid_Argument; + goto Exit; + } + } + + /* get the bitmap metrics */ + { + FT_Long xpos, ypos, advance; + FT_UInt xsize, ysize, format; + FT_Byte* p; + + + advance = FT_MulDiv( size->root.metrics.x_ppem << 8, + character->advance, + phys->metrics_resolution ); + + /* XXX: handle linearHoriAdvance correctly! */ + + if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) || + FT_FRAME_ENTER( gps_size ) ) + goto Exit; + + p = stream->cursor; + error = pfr_load_bitmap_metrics( &p, stream->limit, + advance, + &xpos, &ypos, + &xsize, &ysize, + &advance, &format ); + if ( !error ) + { + glyph->root.format = FT_GLYPH_FORMAT_BITMAP; + + /* Set up glyph bitmap and metrics */ + glyph->root.bitmap.width = (FT_Int)xsize; + glyph->root.bitmap.rows = (FT_Int)ysize; + glyph->root.bitmap.pitch = (FT_Long)( xsize + 7 ) >> 3; + glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO; + + glyph->root.metrics.width = (FT_Long)xsize << 6; + glyph->root.metrics.height = (FT_Long)ysize << 6; + glyph->root.metrics.horiBearingX = xpos << 6; + glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiAdvance = ( ( advance >> 2 ) + 32 ) & -64; + glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; + glyph->root.metrics.vertBearingY = 0; + glyph->root.metrics.vertAdvance = size->root.metrics.height; + + glyph->root.bitmap_left = xpos; + glyph->root.bitmap_top = ypos + ysize; + + /* Allocate and read bitmap data */ + { + FT_ULong len = glyph->root.bitmap.pitch * ysize; + + error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); + if ( !error ) + { + error = pfr_load_bitmap_bits( p, + stream->limit, + format, + face->header.color_flags & 2, + &glyph->root.bitmap ); + } + } + } + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + +/* END */ diff --git a/lib/freetype/src/pfr/pfrsbit.h b/lib/freetype/src/pfr/pfrsbit.h new file mode 100644 index 0000000..015e9e6 --- /dev/null +++ b/lib/freetype/src/pfr/pfrsbit.h @@ -0,0 +1,36 @@ +/***************************************************************************/ +/* */ +/* pfrsbit.h */ +/* */ +/* FreeType PFR bitmap loader (specification). */ +/* */ +/* Copyright 2002 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 __PFRSBIT_H__ +#define __PFRSBIT_H__ + +#include "pfrobjs.h" + +FT_BEGIN_HEADER + + FT_LOCAL( FT_Error ) + pfr_slot_load_bitmap( PFR_Slot glyph, + PFR_Size size, + FT_UInt glyph_index ); + +FT_END_HEADER + +#endif /* __PFR_SBIT_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/pfrtypes.h b/lib/freetype/src/pfr/pfrtypes.h new file mode 100644 index 0000000..96744fc --- /dev/null +++ b/lib/freetype/src/pfr/pfrtypes.h @@ -0,0 +1,360 @@ +/***************************************************************************/ +/* */ +/* pfrtypes.h */ +/* */ +/* FreeType PFR data structures (specification only). */ +/* */ +/* Copyright 2002 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 __PFRTYPES_H__ +#define __PFRTYPES_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + +FT_BEGIN_HEADER + + /************************************************************************/ + + /* the PFR Header structure */ + typedef struct PFR_HeaderRec_ + { + FT_UInt32 signature; + FT_UInt version; + FT_UInt signature2; + FT_UInt header_size; + + FT_UInt log_dir_size; + FT_UInt log_dir_offset; + + FT_UInt log_font_max_size; + FT_UInt32 log_font_section_size; + FT_UInt32 log_font_section_offset; + + FT_UInt32 phy_font_max_size; + FT_UInt32 phy_font_section_size; + FT_UInt32 phy_font_section_offset; + + FT_UInt gps_max_size; + FT_UInt32 gps_section_size; + FT_UInt32 gps_section_offset; + + FT_UInt max_blue_values; + FT_UInt max_x_orus; + FT_UInt max_y_orus; + + FT_UInt phy_font_max_size_high; + FT_UInt color_flags; + + FT_UInt32 bct_max_size; + FT_UInt32 bct_set_max_size; + FT_UInt32 phy_bct_set_max_size; + + FT_UInt num_phy_fonts; + FT_UInt max_vert_stem_snap; + FT_UInt max_horz_stem_snap; + FT_UInt max_chars; + + } PFR_HeaderRec, *PFR_Header; + + + /* used in `color_flags' field of the PFR_Header */ + typedef enum PFR_HeaderFlags_ + { + PFR_FLAG_BLACK_PIXEL = 1, + PFR_FLAG_INVERT_BITMAP = 2 + + } PFR_HeaderFlags; + + + /************************************************************************/ + + typedef struct PFR_LogFontRec_ + { + FT_UInt32 size; + FT_UInt32 offset; + + FT_Int32 matrix[4]; + FT_UInt stroke_flags; + FT_Int stroke_thickness; + FT_Int bold_thickness; + FT_Int32 miter_limit; + + FT_UInt32 phys_size; + FT_UInt32 phys_offset; + + } PFR_LogFontRec, *PFR_LogFont; + + + typedef enum PFR_LogFlags_ + { + PFR_LOG_EXTRA_ITEMS = 0x40, + PFR_LOG_2BYTE_BOLD = 0x20, + PFR_LOG_BOLD = 0x10, + PFR_LOG_2BYTE_STROKE = 8, + PFR_LOG_STROKE = 4, + PFR_LINE_JOIN_MASK = 3 + + } PFR_LogFlags; + + + typedef enum PFR_LineJoinFlags_ + { + PFR_LINE_JOIN_MITER = 0, + PFR_LINE_JOIN_ROUND = 1, + PFR_LINE_JOIN_BEVEL = 2 + + } PFR_LineJoinFlags; + + + /************************************************************************/ + + typedef enum PFR_BitmapFlags_ + { + PFR_BITMAP_3BYTE_OFFSET = 4, + PFR_BITMAP_2BYTE_SIZE = 2, + PFR_BITMAP_2BYTE_CHARCODE = 1 + + } PFR_BitmapFlags; + + + typedef struct PFR_BitmapCharRec_ + { + FT_UInt char_code; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_BitmapCharRec, *PFR_BitmapChar; + + + typedef enum PFR_StrikeFlags_ + { + PFR_STRIKE_2BYTE_COUNT = 0x10, + PFR_STRIKE_3BYTE_OFFSET = 0x08, + PFR_STRIKE_3BYTE_SIZE = 0x04, + PFR_STRIKE_2BYTE_YPPM = 0x02, + PFR_STRIKE_2BYTE_XPPM = 0x01 + + } PFR_StrikeFlags; + + + typedef struct PFR_StrikeRec_ + { + FT_UInt x_ppm; + FT_UInt y_ppm; + FT_UInt flags; + + FT_UInt32 gps_size; + FT_UInt32 gps_offset; + + FT_UInt32 bct_size; + FT_UInt32 bct_offset; + + /* optional */ + FT_UInt num_bitmaps; + PFR_BitmapChar bitmaps; + + } PFR_StrikeRec, *PFR_Strike; + + + /************************************************************************/ + + typedef struct PFR_CharRec_ + { + FT_UInt char_code; + FT_Int advance; + FT_UInt gps_size; + FT_UInt32 gps_offset; + + } PFR_CharRec, *PFR_Char; + + + /************************************************************************/ + + typedef struct PFR_DimensionRec_ + { + FT_UInt standard; + FT_UInt num_stem_snaps; + FT_Int* stem_snaps; + + } PFR_DimensionRec, *PFR_Dimension; + + /************************************************************************/ + + typedef struct PFR_KernItemRec_* PFR_KernItem; + + typedef struct PFR_KernItemRec_ + { + PFR_KernItem next; + FT_UInt pair_count; + FT_UInt pair_size; + FT_Int base_adj; + FT_UInt flags; + FT_UInt32 offset; + FT_UInt32 pair1; + FT_UInt32 pair2; + + } PFR_KernItemRec; + +#define PFR_KERN_INDEX( g1, g2 ) \ + ( ( (FT_UInt32)(g1) << 16 ) | (FT_UInt16)(g2) ) + + typedef struct PFR_KernPairRec_ + { + FT_UInt glyph1; + FT_UInt glyph2; + FT_Vector kerning; + + } PFR_KernPairRec, *PFR_KernPair; + + /************************************************************************/ + + typedef struct PFR_PhyFontRec_ + { + FT_Memory memory; + FT_UInt32 offset; + + FT_UInt font_ref_number; + FT_UInt outline_resolution; + FT_UInt metrics_resolution; + FT_BBox bbox; + FT_UInt flags; + FT_UInt standard_advance; + + FT_Int ascent; /* optional, bbox.yMax if not present */ + FT_Int descent; /* optional, bbox.yMin if not present */ + FT_Int leading; /* optional, 0 if not present */ + + PFR_DimensionRec horizontal; + PFR_DimensionRec vertical; + + FT_String* font_id; + FT_String* family_name; + FT_String* style_name; + + FT_UInt num_strikes; + FT_UInt max_strikes; + PFR_StrikeRec* strikes; + + FT_UInt num_blue_values; + FT_Int *blue_values; + FT_UInt blue_fuzz; + FT_UInt blue_scale; + + FT_UInt num_chars; + FT_UInt32 chars_offset; + PFR_Char chars; + + FT_UInt num_kern_pairs; + PFR_KernItem kern_items; + PFR_KernItem* kern_items_tail; + + /* not part of the spec, but used during load */ + FT_UInt32 bct_offset; + FT_Byte* cursor; + + } PFR_PhyFontRec, *PFR_PhyFont; + + + typedef enum PFR_PhyFlags_ + { + PFR_PHY_EXTRA_ITEMS = 0x80, + PFR_PHY_3BYTE_GPS_OFFSET = 0x20, + PFR_PHY_2BYTE_GPS_SIZE = 0x10, + PFR_PHY_ASCII_CODE = 0x08, + PFR_PHY_PROPORTIONAL = 0x04, + PFR_PHY_2BYTE_CHARCODE = 0x02, + PFR_PHY_VERTICAL = 0x01 + + } PFR_PhyFlags; + + + typedef enum PFR_KernFlags_ + { + PFR_KERN_2BYTE_ADJ = 0x01, + PFR_KERN_2BYTE_CHAR = 0x02 + + } PFR_KernFlags; + + + /************************************************************************/ + + typedef enum PFR_GlyphFlags_ + { + PFR_GLYPH_IS_COMPOUND = 0x80, + PFR_GLYPH_EXTRA_ITEMS = 0x08, + PFR_GLYPH_1BYTE_XYCOUNT = 0x04, + PFR_GLYPH_XCOUNT = 0x02, + PFR_GLYPH_YCOUNT = 0x01 + + } PFR_GlyphFlags; + + + /* controlled coordinate */ + typedef struct PFR_CoordRec_ + { + FT_UInt org; + FT_UInt cur; + + } PFR_CoordRec, *PFR_Coord; + + + typedef struct PFR_SubGlyphRec_ + { + FT_Fixed x_scale; + FT_Fixed y_scale; + FT_Int x_delta; + FT_Int y_delta; + FT_UInt32 gps_offset; + FT_UInt gps_size; + + } PFR_SubGlyphRec, *PFR_SubGlyph; + + + typedef enum PFR_SubgGlyphFlags_ + { + PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, + PFR_SUBGLYPH_2BYTE_SIZE = 0x40, + PFR_SUBGLYPH_YSCALE = 0x20, + PFR_SUBGLYPH_XSCALE = 0x10 + + } PFR_SubGlyphFlags; + + + typedef struct PFR_GlyphRec_ + { + FT_Byte format; + + FT_UInt num_x_control; + FT_UInt num_y_control; + FT_UInt max_xy_control; + FT_Pos* x_control; + FT_Pos* y_control; + + + FT_UInt num_subs; + FT_UInt max_subs; + PFR_SubGlyphRec* subs; + + FT_GlyphLoader loader; + FT_Bool path_begun; + + } PFR_GlyphRec, *PFR_Glyph; + + +FT_END_HEADER + +#endif /* __PFRTYPES_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pfr/rules.mk b/lib/freetype/src/pfr/rules.mk new file mode 100644 index 0000000..fe2f6eb --- /dev/null +++ b/lib/freetype/src/pfr/rules.mk @@ -0,0 +1,71 @@ +# +# FreeType 2 PFR driver configuration rules +# + + +# Copyright 2002 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. + + +# pfr driver directory +# +PFR_DIR := $(SRC_)pfr +PFR_DIR_ := $(PFR_DIR)$(SEP) + + +# compilation flags for the driver +# +PFR_COMPILE := $(FT_COMPILE) $I$(PFR_DIR) + + +# pfr driver sources (i.e., C files) +# +PFR_DRV_SRC := $(PFR_DIR_)pfrload.c \ + $(PFR_DIR_)pfrgload.c \ + $(PFR_DIR_)pfrcmap.c \ + $(PFR_DIR_)pfrdrivr.c \ + $(PFR_DIR_)pfrobjs.c + +# pfr driver headers +# +PFR_DRV_H := $(PFR_DRV_SRC:%.c=%.h) \ + $(PFR_DIR_)pfrerror.h + + +# Pfr driver object(s) +# +# PFR_DRV_OBJ_M is used during `multi' builds +# PFR_DRV_OBJ_S is used during `single' builds +# +PFR_DRV_OBJ_M := $(PFR_DRV_SRC:$(PFR_DIR_)%.c=$(OBJ_)%.$O) +PFR_DRV_OBJ_S := $(OBJ_)pfr.$O + +# pfr driver source file for single build +# +PFR_DRV_SRC_S := $(PFR_DIR_)pfr.c + + +# pfr driver - single object +# +$(PFR_DRV_OBJ_S): $(PFR_DRV_SRC_S) $(PFR_DRV_SRC) $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$@ $(PFR_DRV_SRC_S) + + +# pfr driver - multiple objects +# +$(OBJ_)%.$O: $(PFR_DIR_)%.c $(FREETYPE_H) $(PFR_DRV_H) + $(PFR_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PFR_DRV_OBJ_S) +DRV_OBJS_M += $(PFR_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/psaux/Jamfile b/lib/freetype/src/psaux/Jamfile new file mode 100644 index 0000000..fc834b3 --- /dev/null +++ b/lib/freetype/src/psaux/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/psaux Jamfile (c) 2001, 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = psauxmod psobjs t1decode t1cmap ; + } + else + { + _sources = psaux ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/psaux Jamfile diff --git a/lib/freetype/src/psaux/descrip.mms b/lib/freetype/src/psaux/descrip.mms new file mode 100644 index 0000000..bff0192 --- /dev/null +++ b/lib/freetype/src/psaux/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 PSaux driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psaux]) + +OBJS=psaux.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/psaux/module.mk b/lib/freetype/src/psaux/module.mk new file mode 100644 index 0000000..29c3e28 --- /dev/null +++ b/lib/freetype/src/psaux/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 PSaux module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_psaux_module + +add_psaux_module: + $(OPEN_DRIVER)psaux_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)psaux $(ECHO_DRIVER_DESC)Postscript Type 1 & Type 2 helper module$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/psaux/psaux.c b/lib/freetype/src/psaux/psaux.c new file mode 100644 index 0000000..9928184 --- /dev/null +++ b/lib/freetype/src/psaux/psaux.c @@ -0,0 +1,28 @@ +/***************************************************************************/ +/* */ +/* psaux.c */ +/* */ +/* FreeType auxiliary PostScript driver component (body only). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "psobjs.c" +#include "psauxmod.c" +#include "t1decode.c" +#include "t1cmap.c" + + +/* END */ diff --git a/lib/freetype/src/psaux/psauxerr.h b/lib/freetype/src/psaux/psauxerr.h new file mode 100644 index 0000000..d0baa3c --- /dev/null +++ b/lib/freetype/src/psaux/psauxerr.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* psauxerr.h */ +/* */ +/* PS auxiliary module error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the PS auxiliary module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSAUXERR_H__ +#define __PSAUXERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSaux_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSaux + +#include FT_ERRORS_H + +#endif /* __PSAUXERR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psaux/psauxmod.c b/lib/freetype/src/psaux/psauxmod.c new file mode 100644 index 0000000..fa0c4aa --- /dev/null +++ b/lib/freetype/src/psaux/psauxmod.c @@ -0,0 +1,118 @@ +/***************************************************************************/ +/* */ +/* psauxmod.c */ +/* */ +/* FreeType auxiliary PostScript module implementation (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include "psauxmod.h" +#include "psobjs.h" +#include "t1decode.h" +#include "t1cmap.h" + + + FT_CALLBACK_TABLE_DEF + const PS_Table_FuncsRec ps_table_funcs = + { + ps_table_new, + ps_table_done, + ps_table_add, + ps_table_release + }; + + + FT_CALLBACK_TABLE_DEF + const PS_Parser_FuncsRec ps_parser_funcs = + { + ps_parser_init, + ps_parser_done, + ps_parser_skip_spaces, + ps_parser_skip_alpha, + ps_parser_to_int, + ps_parser_to_fixed, + ps_parser_to_coord_array, + ps_parser_to_fixed_array, + ps_parser_to_token, + ps_parser_to_token_array, + ps_parser_load_field, + ps_parser_load_field_table + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Builder_FuncsRec t1_builder_funcs = + { + t1_builder_init, + t1_builder_done, + t1_builder_check_points, + t1_builder_add_point, + t1_builder_add_point1, + t1_builder_add_contour, + t1_builder_start_point, + t1_builder_close_contour + }; + + + FT_CALLBACK_TABLE_DEF + const T1_Decoder_FuncsRec t1_decoder_funcs = + { + t1_decoder_init, + t1_decoder_done, + t1_decoder_parse_charstrings + }; + + + FT_CALLBACK_TABLE_DEF + const T1_CMap_ClassesRec t1_cmap_classes = + { + &t1_cmap_standard_class_rec, + &t1_cmap_expert_class_rec, + &t1_cmap_custom_class_rec, + &t1_cmap_unicode_class_rec + }; + + + static + const PSAux_Interface psaux_interface = + { + &ps_table_funcs, + &ps_parser_funcs, + &t1_builder_funcs, + &t1_decoder_funcs, + + t1_decrypt, + + (const T1_CMap_ClassesRec*) &t1_cmap_classes, + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class psaux_module_class = + { + 0, + sizeof( FT_ModuleRec ), + "psaux", + 0x10000L, + 0x20000L, + + &psaux_interface, /* module-specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/psaux/psauxmod.h b/lib/freetype/src/psaux/psauxmod.h new file mode 100644 index 0000000..92ac056 --- /dev/null +++ b/lib/freetype/src/psaux/psauxmod.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* psauxmod.h */ +/* */ +/* FreeType auxiliary PostScript module implementation (specification). */ +/* */ +/* Copyright 2000-2001 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 __PSAUXMOD_H__ +#define __PSAUXMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; + + +FT_END_HEADER + +#endif /* __PSAUXMOD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psaux/psobjs.c b/lib/freetype/src/psaux/psobjs.c new file mode 100644 index 0000000..e930b71 --- /dev/null +++ b/lib/freetype/src/psaux/psobjs.c @@ -0,0 +1,1406 @@ +/***************************************************************************/ +/* */ +/* psobjs.c */ +/* */ +/* Auxiliary functions for PostScript fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_DEBUG_H + +#include "psobjs.h" + +#include "psauxerr.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_new */ + /* */ + /* <Description> */ + /* Initializes a PS_Table. */ + /* */ + /* <InOut> */ + /* table :: The address of the target table. */ + /* */ + /* <Input> */ + /* count :: The table size = the maximum number of elements. */ + /* */ + /* memory :: The memory object to use for all subsequent */ + /* reallocations. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ) + { + FT_Error error; + + + table->memory = memory; + if ( FT_NEW_ARRAY( table->elements, count ) || + FT_NEW_ARRAY( table->lengths, count ) ) + goto Exit; + + table->max_elems = count; + table->init = 0xDEADBEEFUL; + table->num_elems = 0; + table->block = 0; + table->capacity = 0; + table->cursor = 0; + + *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; + + Exit: + if ( error ) + FT_FREE( table->elements ); + + return error; + } + + + static void + shift_elements( PS_Table table, + FT_Byte* old_base ) + { + FT_Long delta = (FT_Long)( table->block - old_base ); + FT_Byte** offset = table->elements; + FT_Byte** limit = offset + table->max_elems; + + + for ( ; offset < limit; offset++ ) + { + if ( offset[0] ) + offset[0] += delta; + } + } + + + static FT_Error + reallocate_t1_table( PS_Table table, + FT_Long new_size ) + { + FT_Memory memory = table->memory; + FT_Byte* old_base = table->block; + FT_Error error; + + + /* allocate new base block */ + if ( FT_ALLOC( table->block, new_size ) ) + { + table->block = old_base; + return error; + } + + /* copy elements and shift offsets */ + if (old_base ) + { + FT_MEM_COPY( table->block, old_base, table->capacity ); + shift_elements( table, old_base ); + FT_FREE( old_base ); + } + + table->capacity = new_size; + + return PSaux_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_add */ + /* */ + /* <Description> */ + /* Adds an object to a PS_Table, possibly growing its memory block. */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Input> */ + /* idx :: The index of the object in the table. */ + /* */ + /* object :: The address of the object to copy in memory. */ + /* */ + /* length :: The length in bytes of the source object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. An error is returned if a */ + /* reallocation fails. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_Int length ) + { + if ( idx < 0 || idx > table->max_elems ) + { + FT_ERROR(( "ps_table_add: invalid index\n" )); + return PSaux_Err_Invalid_Argument; + } + + /* grow the base block if needed */ + if ( table->cursor + length > table->capacity ) + { + FT_Error error; + FT_Offset new_size = table->capacity; + FT_Long in_offset; + + + in_offset = (FT_Long)((FT_Byte*)object - table->block); + if ( (FT_ULong)in_offset >= table->capacity ) + in_offset = -1; + + while ( new_size < table->cursor + length ) + { + /* increase size by 25% and round up to the nearest multiple of 1024 */ + new_size += (new_size >> 2) + 1; + new_size = ( new_size + 1023 ) & -1024; + } + + error = reallocate_t1_table( table, new_size ); + if ( error ) + return error; + + if ( in_offset >= 0 ) + object = table->block + in_offset; + } + + /* add the object to the base block and adjust offset */ + table->elements[idx] = table->block + table->cursor; + table->lengths [idx] = length; + FT_MEM_COPY( table->block + table->cursor, object, length ); + + table->cursor += length; + return PSaux_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_table_done */ + /* */ + /* <Description> */ + /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ + /* cursor). */ + /* */ + /* <InOut> */ + /* table :: The target table. */ + /* */ + /* <Note> */ + /* This function does NOT release the heap's memory block. It is up */ + /* to the caller to clean it, or reference it in its own structures. */ + /* */ + FT_LOCAL_DEF( void ) + ps_table_done( PS_Table table ) + { + FT_Memory memory = table->memory; + FT_Error error; + FT_Byte* old_base = table->block; + + + /* should never fail, because rec.cursor <= rec.size */ + if ( !old_base ) + return; + + if ( FT_ALLOC( table->block, table->cursor ) ) + return; + FT_MEM_COPY( table->block, old_base, table->cursor ); + shift_elements( table, old_base ); + + table->capacity = table->cursor; + FT_FREE( old_base ); + + FT_UNUSED( error ); + } + + + FT_LOCAL_DEF( void ) + ps_table_release( PS_Table table ) + { + FT_Memory memory = table->memory; + + + if ( (FT_ULong)table->init == 0xDEADBEEFUL ) + { + FT_FREE( table->block ); + FT_FREE( table->elements ); + FT_FREE( table->lengths ); + table->init = 0; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + +#define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) +#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) + +#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) + + + FT_LOCAL_DEF( void ) + ps_parser_skip_spaces( PS_Parser parser ) + { + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + while ( cur < limit ) + { + FT_Byte c = *cur; + + + if ( !IS_T1_SPACE( c ) ) + break; + cur++; + } + parser->cursor = cur; + } + + + FT_LOCAL_DEF( void ) + ps_parser_skip_alpha( PS_Parser parser ) + { + FT_Byte* cur = parser->cursor; + FT_Byte* limit = parser->limit; + + + while ( cur < limit ) + { + FT_Byte c = *cur; + + + if ( IS_T1_SPACE( c ) ) + break; + cur++; + } + parser->cursor = cur; + } + + + FT_LOCAL_DEF( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ) + { + FT_Byte* cur; + FT_Byte* limit; + FT_Byte starter, ender; + FT_Int embed; + + + token->type = T1_TOKEN_TYPE_NONE; + token->start = 0; + token->limit = 0; + + /* first of all, skip space */ + ps_parser_skip_spaces( parser ); + + cur = parser->cursor; + limit = parser->limit; + + if ( cur < limit ) + { + switch ( *cur ) + { + /************* check for strings ***********************/ + case '(': + token->type = T1_TOKEN_TYPE_STRING; + ender = ')'; + goto Lookup_Ender; + + /************* check for programs/array ****************/ + case '{': + token->type = T1_TOKEN_TYPE_ARRAY; + ender = '}'; + goto Lookup_Ender; + + /************* check for table/array ******************/ + case '[': + token->type = T1_TOKEN_TYPE_ARRAY; + ender = ']'; + + Lookup_Ender: + embed = 1; + starter = *cur++; + token->start = cur; + while ( cur < limit ) + { + if ( *cur == starter ) + embed++; + else if ( *cur == ender ) + { + embed--; + if ( embed <= 0 ) + { + token->limit = cur++; + break; + } + } + cur++; + } + break; + + /* **************** otherwise, it's any token **********/ + default: + token->start = cur++; + token->type = T1_TOKEN_TYPE_ANY; + while ( cur < limit && !IS_T1_SPACE( *cur ) ) + cur++; + + token->limit = cur; + } + + if ( !token->limit ) + { + token->start = 0; + token->type = T1_TOKEN_TYPE_NONE; + } + + parser->cursor = cur; + } + } + + + FT_LOCAL_DEF( void ) + ps_parser_to_token_array( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ) + { + T1_TokenRec master; + + + *pnum_tokens = -1; + + ps_parser_to_token( parser, &master ); + if ( master.type == T1_TOKEN_TYPE_ARRAY ) + { + FT_Byte* old_cursor = parser->cursor; + FT_Byte* old_limit = parser->limit; + T1_Token cur = tokens; + T1_Token limit = cur + max_tokens; + + + parser->cursor = master.start; + parser->limit = master.limit; + + while ( parser->cursor < parser->limit ) + { + T1_TokenRec token; + + + ps_parser_to_token( parser, &token ); + if ( !token.type ) + break; + + if ( cur < limit ) + *cur = token; + + cur++; + } + + *pnum_tokens = (FT_Int)( cur - tokens ); + + parser->cursor = old_cursor; + parser->limit = old_limit; + } + } + + + static FT_Long + T1Radix( FT_Long radixBase, + FT_Byte** cur, + FT_Byte* limit ) + { + FT_Long result = 0; + FT_Byte radixEndChar0 = + (FT_Byte)( radixBase > 10 ? '9' + 1 : '0' + radixBase ); + FT_Byte radixEndChar1 = + (FT_Byte)( 'A' + radixBase - 10 ); + FT_Byte radixEndChar2 = + (FT_Byte)( 'a' + radixBase - 10 ); + + + while( *cur < limit ) + { + if ( (*cur)[0] >= '0' && (*cur)[0] < radixEndChar0 ) + result = result * radixBase + (*cur)[0] - '0'; + + else if ( radixBase > 10 && + (*cur)[0] >= 'A' && (*cur)[0] < radixEndChar1 ) + result = result * radixBase + ( (*cur)[0] - 'A' + 10 ); + + else if ( radixBase > 10 && + (*cur)[0] >= 'a' && (*cur)[0] < radixEndChar2 ) + result = result * radixBase + ( (*cur)[0] - 'a' + 10 ); + + else + return result; + + (*cur)++; + } + + return result; + } + + + static FT_Long + t1_toint( FT_Byte** cursor, + FT_Byte* limit ) + { + FT_Long result = 0; + FT_Byte* cur = *cursor; + FT_Byte c = '\0', d; + + + for ( ; cur < limit; cur++ ) + { + c = *cur; + d = (FT_Byte)( c - '0' ); + if ( d < 10 ) + break; + + if ( c == '-' ) + { + cur++; + break; + } + } + + if ( cur < limit ) + { + do + { + d = (FT_Byte)( cur[0] - '0' ); + if ( d >= 10 ) + { + if ( cur[0] == '#' ) + { + cur++; + result = T1Radix( result, &cur, limit ); + } + break; + } + + result = result * 10 + d; + cur++; + + } while ( cur < limit ); + + if ( c == '-' ) + result = -result; + } + + *cursor = cur; + return result; + } + + + static FT_Long + t1_tofixed( FT_Byte** cursor, + FT_Byte* limit, + FT_Long power_ten ) + { + FT_Byte* cur = *cursor; + FT_Long num, divider, result; + FT_Int sign = 0; + FT_Byte d; + + + if ( cur >= limit ) + return 0; + + /* first of all, check the sign */ + if ( *cur == '-' ) + { + sign = 1; + cur++; + } + + /* then, read the integer part, if any */ + if ( *cur != '.' ) + result = t1_toint( &cur, limit ) << 16; + else + result = 0; + + num = 0; + divider = 1; + + if ( cur >= limit ) + goto Exit; + + /* read decimal part, if any */ + if ( *cur == '.' && cur + 1 < limit ) + { + cur++; + + for (;;) + { + d = (FT_Byte)( *cur - '0' ); + if ( d >= 10 ) + break; + + if ( divider < 10000000L ) + { + num = num * 10 + d; + divider *= 10; + } + + cur++; + if ( cur >= limit ) + break; + } + } + + /* read exponent, if any */ + if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) + { + cur++; + power_ten += t1_toint( &cur, limit ); + } + + Exit: + /* raise to power of ten if needed */ + while ( power_ten > 0 ) + { + result = result * 10; + num = num * 10; + power_ten--; + } + + while ( power_ten < 0 ) + { + result = result / 10; + divider = divider * 10; + power_ten++; + } + + if ( num ) + result += FT_DivFix( num, divider ); + + if ( sign ) + result = -result; + + *cursor = cur; + return result; + } + + + static FT_Int + t1_tocoordarray( FT_Byte** cursor, + FT_Byte* limit, + FT_Int max_coords, + FT_Short* coords ) + { + FT_Byte* cur = *cursor; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) + goto Exit; + + /* check for the beginning of an array; if not, only one number will */ + /* be read */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + + if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the coordinates */ + for ( ; cur < limit; ) + { + /* skip whitespace in front of data */ + for (;;) + { + c = *cur; + if ( c != ' ' && c != '\t' ) + break; + + cur++; + if ( cur >= limit ) + goto Exit; + } + + if ( count >= max_coords || c == ender ) + break; + + coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); + count++; + + if ( !ender ) + break; + } + + Exit: + *cursor = cur; + return count; + } + + + static FT_Int + t1_tofixedarray( FT_Byte** cursor, + FT_Byte* limit, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + FT_Byte* cur = *cursor; + FT_Int count = 0; + FT_Byte c, ender; + + + if ( cur >= limit ) goto Exit; + + /* check for the beginning of an array. If not, only one number will */ + /* be read */ + c = *cur; + ender = 0; + + if ( c == '[' ) + ender = ']'; + + if ( c == '{' ) + ender = '}'; + + if ( ender ) + cur++; + + /* now, read the values */ + for ( ; cur < limit; ) + { + /* skip whitespace in front of data */ + for (;;) + { + c = *cur; + if ( c != ' ' && c != '\t' ) + break; + + cur++; + if ( cur >= limit ) + goto Exit; + } + + if ( count >= max_values || c == ender ) + break; + + values[count] = t1_tofixed( &cur, limit, power_ten ); + count++; + + if ( !ender ) + break; + } + + Exit: + *cursor = cur; + return count; + } + + +#if 0 + + static FT_String* + t1_tostring( FT_Byte** cursor, + FT_Byte* limit, + FT_Memory memory ) + { + FT_Byte* cur = *cursor; + FT_PtrDist len = 0; + FT_Int count; + FT_String* result; + FT_Error error; + + + /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ + /* that simply doesn't begin with an opening parenthesis, even */ + /* though they have a closing one! E.g. "amuncial.pfb" */ + /* */ + /* We must deal with these ill-fated cases there. Note that */ + /* these fonts didn't work with the old Type 1 driver as the */ + /* notice/copyright was not recognized as a valid string token */ + /* and made the old token parser commit errors. */ + + while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) + cur++; + if ( cur + 1 >= limit ) + return 0; + + if ( *cur == '(' ) + cur++; /* skip the opening parenthesis, if there is one */ + + *cursor = cur; + count = 0; + + /* then, count its length */ + for ( ; cur < limit; cur++ ) + { + if ( *cur == '(' ) + count++; + + else if ( *cur == ')' ) + { + count--; + if ( count < 0 ) + break; + } + } + + len = cur - *cursor; + if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) + return 0; + + /* now copy the string */ + FT_MEM_COPY( result, *cursor, len ); + result[len] = '\0'; + *cursor = cur; + return result; + } + +#endif /* 0 */ + + + static int + t1_tobool( FT_Byte** cursor, + FT_Byte* limit ) + { + FT_Byte* cur = *cursor; + FT_Bool result = 0; + + + /* return 1 if we find `true', 0 otherwise */ + if ( cur + 3 < limit && + cur[0] == 't' && + cur[1] == 'r' && + cur[2] == 'u' && + cur[3] == 'e' ) + { + result = 1; + cur += 5; + } + else if ( cur + 4 < limit && + cur[0] == 'f' && + cur[1] == 'a' && + cur[2] == 'l' && + cur[3] == 's' && + cur[4] == 'e' ) + { + result = 0; + cur += 6; + } + + *cursor = cur; + return result; + } + + + /* Load a simple field (i.e. non-table) into the current list of objects */ + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec token; + FT_Byte* cur; + FT_Byte* limit; + FT_UInt count; + FT_UInt idx; + FT_Error error; + + + ps_parser_to_token( parser, &token ); + if ( !token.type ) + goto Fail; + + count = 1; + idx = 0; + cur = token.start; + limit = token.limit; + + /* we must detect arrays */ + if ( field->type == T1_FIELD_TYPE_BBOX ) + { + T1_TokenRec token2; + FT_Byte* old_cur = parser->cursor; + FT_Byte* old_limit = parser->limit; + + + parser->cursor = token.start; + parser->limit = token.limit; + + ps_parser_to_token( parser, &token2 ); + parser->cursor = old_cur; + parser->limit = old_limit; + + if ( token2.type == T1_TOKEN_TYPE_ARRAY ) + goto FieldArray; + } + else if ( token.type == T1_TOKEN_TYPE_ARRAY ) + { + FieldArray: + /* if this is an array, and we have no blend, an error occurs */ + if ( max_objects == 0 ) + goto Fail; + + count = max_objects; + idx = 1; + } + + for ( ; count > 0; count--, idx++ ) + { + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Long val; + FT_String* string; + + + switch ( field->type ) + { + case T1_FIELD_TYPE_BOOL: + val = t1_tobool( &cur, limit ); + goto Store_Integer; + + case T1_FIELD_TYPE_FIXED: + val = t1_tofixed( &cur, limit, 3 ); + goto Store_Integer; + + case T1_FIELD_TYPE_INTEGER: + val = t1_toint( &cur, limit ); + + Store_Integer: + switch ( field->size ) + { + case 1: + *(FT_Byte*)q = (FT_Byte)val; + break; + + case 2: + *(FT_UShort*)q = (FT_UShort)val; + break; + + case 4: + *(FT_UInt32*)q = (FT_UInt32)val; + break; + + default: /* for 64-bit systems */ + *(FT_Long*)q = val; + } + break; + + case T1_FIELD_TYPE_STRING: + { + FT_Memory memory = parser->memory; + FT_UInt len = (FT_UInt)( limit - cur ); + + + if ( *(FT_String**)q ) + /* with synthetic fonts, it's possible to find a field twice */ + break; + + if ( FT_ALLOC( string, len + 1 ) ) + goto Exit; + + FT_MEM_COPY( string, cur, len ); + string[len] = 0; + + *(FT_String**)q = string; + } + break; + + case T1_FIELD_TYPE_BBOX: + { + FT_Fixed temp[4]; + FT_BBox* bbox = (FT_BBox*)q; + + + /* we need the '[' and ']' delimiters */ + token.start--; + token.limit++; + (void)t1_tofixedarray( &token.start, token.limit, 4, temp, 0 ); + + bbox->xMin = FT_RoundFix( temp[0] ); + bbox->yMin = FT_RoundFix( temp[1] ); + bbox->xMax = FT_RoundFix( temp[2] ); + bbox->yMax = FT_RoundFix( temp[3] ); + } + break; + + default: + /* an error occured */ + goto Fail; + } + } + +#if 0 /* obsolete - keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + error = PSaux_Err_Ok; + + Exit: + return error; + + Fail: + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + +#define T1_MAX_TABLE_ELEMENTS 32 + + + FT_LOCAL_DEF( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ) + { + T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; + T1_Token token; + FT_Int num_elements; + FT_Error error = 0; + FT_Byte* old_cursor; + FT_Byte* old_limit; + T1_FieldRec fieldrec = *(T1_Field)field; + + +#if 1 + fieldrec.type = T1_FIELD_TYPE_INTEGER; + if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + fieldrec.type = T1_FIELD_TYPE_FIXED; +#endif + + ps_parser_to_token_array( parser, elements, 32, &num_elements ); + if ( num_elements < 0 ) + goto Fail; + + if ( num_elements > T1_MAX_TABLE_ELEMENTS ) + num_elements = T1_MAX_TABLE_ELEMENTS; + + old_cursor = parser->cursor; + old_limit = parser->limit; + + /* we store the elements count */ + *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = + (FT_Byte)num_elements; + + /* we now load each element, adjusting the field.offset on each one */ + token = elements; + for ( ; num_elements > 0; num_elements--, token++ ) + { + parser->cursor = token->start; + parser->limit = token->limit; + ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); + fieldrec.offset += fieldrec.size; + } + +#if 0 /* obsolete -- keep for reference */ + if ( pflags ) + *pflags |= 1L << field->flag_bit; +#else + FT_UNUSED( pflags ); +#endif + + parser->cursor = old_cursor; + parser->limit = old_limit; + + Exit: + return error; + + Fail: + error = PSaux_Err_Invalid_File_Format; + goto Exit; + } + + + FT_LOCAL_DEF( FT_Long ) + ps_parser_to_int( PS_Parser parser ) + { + return t1_toint( &parser->cursor, parser->limit ); + } + + + FT_LOCAL_DEF( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ) + { + return t1_tofixed( &parser->cursor, parser->limit, power_ten ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ) + { + return t1_tocoordarray( &parser->cursor, parser->limit, + max_coords, coords ); + } + + + FT_LOCAL_DEF( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ) + { + return t1_tofixedarray( &parser->cursor, parser->limit, + max_values, values, power_ten ); + } + + +#if 0 + + FT_LOCAL_DEF( FT_String* ) + T1_ToString( PS_Parser parser ) + { + return t1_tostring( &parser->cursor, parser->limit, parser->memory ); + } + + + FT_LOCAL_DEF( FT_Bool ) + T1_ToBool( PS_Parser parser ) + { + return t1_tobool( &parser->cursor, parser->limit ); + } + +#endif /* 0 */ + + + FT_LOCAL_DEF( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ) + { + parser->error = 0; + parser->base = base; + parser->limit = limit; + parser->cursor = base; + parser->memory = memory; + parser->funcs = ps_parser_funcs; + } + + + FT_LOCAL_DEF( void ) + ps_parser_done( PS_Parser parser ) + { + FT_UNUSED( parser ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting should be applied. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->path_begun = 0; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = size->internal; + builder->hints_funcs = 0; + + if ( hinting ) + builder->hints_funcs = glyph->internal->glyph_hints; + } + + if ( size ) + { + builder->scale_x = size->metrics.x_scale; + builder->scale_y = size->metrics.y_scale; + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + + builder->funcs = t1_builder_funcs; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + FT_LOCAL_DEF( void ) + t1_builder_done( T1_Builder builder ) + { + FT_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->outline = *builder->base; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ) + { + return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + + + if ( builder->shift ) + { + x >>= 16; + y >>= 16; + } + point->x = x; + point->y = y; + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + + builder->last = *point; + } + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = t1_builder_check_points( builder, 1 ); + if ( !error ) + t1_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check room for a new contour, then add it */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_add_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return PSaux_Err_Ok; + } + + error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = 0; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = t1_builder_add_contour( builder ); + if ( !error ) + error = t1_builder_add_point1( builder, x, y ); + } + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + t1_builder_close_contour( T1_Builder builder ) + { + FT_Outline* outline = builder->current; + + + /* XXXX: We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Int first = 0; + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + if ( outline->n_contours > 1 ) + { + first = outline->contours[outline->n_contours - 2] + 1; + p1 = outline->points + first; + } + + /* `delete' last point only if it coincides with the first */ + /* point and it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ) + { + while ( length > 0 ) + { + FT_Byte plain; + + + plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) ); + seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 ); + *buffer++ = plain; + length--; + } + } + + +/* END */ diff --git a/lib/freetype/src/psaux/psobjs.h b/lib/freetype/src/psaux/psobjs.h new file mode 100644 index 0000000..9e81675 --- /dev/null +++ b/lib/freetype/src/psaux/psobjs.h @@ -0,0 +1,204 @@ +/***************************************************************************/ +/* */ +/* psobjs.h */ +/* */ +/* Auxiliary functions for PostScript fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __PSOBJS_H__ +#define __PSOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE + const PS_Table_FuncsRec ps_table_funcs; + + FT_CALLBACK_TABLE + const PS_Parser_FuncsRec ps_parser_funcs; + + FT_CALLBACK_TABLE + const T1_Builder_FuncsRec t1_builder_funcs; + + + FT_LOCAL( FT_Error ) + ps_table_new( PS_Table table, + FT_Int count, + FT_Memory memory ); + + FT_LOCAL( FT_Error ) + ps_table_add( PS_Table table, + FT_Int idx, + void* object, + FT_Int length ); + + FT_LOCAL( void ) + ps_table_done( PS_Table table ); + + + FT_LOCAL( void ) + ps_table_release( PS_Table table ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL( void ) + ps_parser_skip_spaces( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_skip_alpha( PS_Parser parser ); + + FT_LOCAL( void ) + ps_parser_to_token( PS_Parser parser, + T1_Token token ); + + FT_LOCAL( void ) + ps_parser_to_token_array( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Error ) + ps_parser_load_field_table( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_LOCAL( FT_Long ) + ps_parser_to_int( PS_Parser parser ); + + + FT_LOCAL( FT_Fixed ) + ps_parser_to_fixed( PS_Parser parser, + FT_Int power_ten ); + + + FT_LOCAL( FT_Int ) + ps_parser_to_coord_array( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + + FT_LOCAL( FT_Int ) + ps_parser_to_fixed_array( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + + FT_LOCAL( void ) + ps_parser_init( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + FT_LOCAL( void ) + ps_parser_done( PS_Parser parser ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_builder_init( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot glyph, + FT_Bool hinting ); + + FT_LOCAL( void ) + t1_builder_done( T1_Builder builder ); + + FT_LOCAL( FT_Error ) + t1_builder_check_points( T1_Builder builder, + FT_Int count ); + + FT_LOCAL( void ) + t1_builder_add_point( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + FT_LOCAL( FT_Error ) + t1_builder_add_point1( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + FT_LOCAL( FT_Error ) + t1_builder_add_contour( T1_Builder builder ); + + + FT_LOCAL( FT_Error ) + t1_builder_start_point( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + + FT_LOCAL( void ) + t1_builder_close_contour( T1_Builder builder ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** OTHER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + t1_decrypt( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + +FT_END_HEADER + +#endif /* __PSOBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psaux/rules.mk b/lib/freetype/src/psaux/rules.mk new file mode 100644 index 0000000..0473085 --- /dev/null +++ b/lib/freetype/src/psaux/rules.mk @@ -0,0 +1,72 @@ +# +# FreeType 2 PSaux driver configuration rules +# + + +# Copyright 1996-2000, 2002 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. + + +# PSAUX driver directory +# +PSAUX_DIR := $(SRC_)psaux +PSAUX_DIR_ := $(PSAUX_DIR)$(SEP) + + +# compilation flags for the driver +# +PSAUX_COMPILE := $(FT_COMPILE) $I$(PSAUX_DIR) + + +# PSAUX driver sources (i.e., C files) +# +PSAUX_DRV_SRC := $(PSAUX_DIR_)psobjs.c \ + $(PSAUX_DIR_)t1decode.c \ + $(PSAUX_DIR_)t1cmap.c \ + $(PSAUX_DIR_)psauxmod.c + +# PSAUX driver headers +# +PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ + $(PSAUX_DIR_)psauxerr.h + + +# PSAUX driver object(s) +# +# PSAUX_DRV_OBJ_M is used during `multi' builds. +# PSAUX_DRV_OBJ_S is used during `single' builds. +# +PSAUX_DRV_OBJ_M := $(PSAUX_DRV_SRC:$(PSAUX_DIR_)%.c=$(OBJ_)%.$O) +PSAUX_DRV_OBJ_S := $(OBJ_)psaux.$O + +# PSAUX driver source file for single build +# +PSAUX_DRV_SRC_S := $(PSAUX_DIR_)psaux.c + + +# PSAUX driver - single object +# +$(PSAUX_DRV_OBJ_S): $(PSAUX_DRV_SRC_S) $(PSAUX_DRV_SRC) \ + $(FREETYPE_H) $(PSAUX_DRV_H) + $(PSAUX_COMPILE) $T$@ $(PSAUX_DRV_SRC_S) + + +# PSAUX driver - multiple objects +# +$(OBJ_)%.$O: $(PSAUX_DIR_)%.c $(FREETYPE_H) $(PSAUX_DRV_H) + $(PSAUX_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PSAUX_DRV_OBJ_S) +DRV_OBJS_M += $(PSAUX_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/psaux/t1cmap.c b/lib/freetype/src/psaux/t1cmap.c new file mode 100644 index 0000000..0ddd3f5 --- /dev/null +++ b/lib/freetype/src/psaux/t1cmap.c @@ -0,0 +1,454 @@ +/***************************************************************************/ +/* */ +/* t1cmap.c */ +/* */ +/* Type 1 character map support (body). */ +/* */ +/* Copyright 2002 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 "t1cmap.h" + +#include FT_INTERNAL_DEBUG_H + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_cmap_std_init( T1_CMapStd cmap, + FT_Int is_expert ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + PSNames_Service psnames = (PSNames_Service)face->psnames; + + + cmap->num_glyphs = face->type1.num_glyphs; + cmap->glyph_names = (const char* const*)face->type1.glyph_names; + cmap->sid_to_string = psnames->adobe_std_strings; + cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding + : psnames->adobe_std_encoding; + + FT_ASSERT( cmap->code_to_sid != NULL ); + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_std_done( T1_CMapStd cmap ) + { + cmap->num_glyphs = 0; + cmap->glyph_names = NULL; + cmap->sid_to_string = NULL; + cmap->code_to_sid = NULL; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_std_char_index( T1_CMapStd cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( char_code < 256 ) + { + FT_UInt code, n; + const char* glyph_name; + + + /* convert character code to Adobe SID string */ + code = cmap->code_to_sid[char_code]; + glyph_name = cmap->sid_to_string( code ); + + /* look for the corresponding glyph name */ + for ( n = 0; n < cmap->num_glyphs; n++ ) + { + const char* gname = cmap->glyph_names[n]; + + + if ( gname && gname[0] == glyph_name[0] && + ft_strcmp( gname, glyph_name ) == 0 ) + { + result = n; + break; + } + } + } + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_std_char_next( T1_CMapStd cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + while ( char_code < 256 ) + { + result = t1_cmap_std_char_index( cmap, char_code ); + if ( result != 0 ) + goto Exit; + + char_code++; + } + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_standard_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 0 ); + return 0; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_standard_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_standard_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next + }; + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_expert_init( T1_CMapStd cmap ) + { + t1_cmap_std_init( cmap, 1 ); + return 0; + } + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_expert_class_rec = + { + sizeof ( T1_CMapStdRec ), + + (FT_CMap_InitFunc) t1_cmap_expert_init, + (FT_CMap_DoneFunc) t1_cmap_std_done, + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, + (FT_CMap_CharNextFunc) t1_cmap_std_char_next + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_custom_init( T1_CMapCustom cmap ) + { + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + T1_Encoding encoding = &face->type1.encoding; + + + cmap->first = encoding->code_first; + cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); + cmap->indices = encoding->char_index; + + FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( encoding->code_first <= encoding->code_last ); + + return 0; + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_custom_done( T1_CMapCustom cmap ) + { + cmap->indices = NULL; + cmap->first = 0; + cmap->count = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_custom_char_index( T1_CMapCustom cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + + + if ( ( char_code >= cmap->first ) && + ( char_code < ( cmap->first + cmap->count ) ) ) + result = cmap->indices[char_code]; + + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_custom_char_next( T1_CMapCustom cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code; + + + ++char_code; + + if ( char_code < cmap->first ) + char_code = cmap->first; + + for ( ; char_code < ( cmap->first + cmap->count ); char_code++ ) + { + result = cmap->indices[char_code]; + if ( result != 0 ) + goto Exit; + } + + char_code = 0; + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_custom_class_rec = + { + sizeof ( T1_CMapCustomRec ), + + (FT_CMap_InitFunc) t1_cmap_custom_init, + (FT_CMap_DoneFunc) t1_cmap_custom_done, + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Int ) + t1_cmap_uni_pair_compare( const void* pair1, + const void* pair2 ) + { + FT_UInt32 u1 = ((T1_CMapUniPair)pair1)->unicode; + FT_UInt32 u2 = ((T1_CMapUniPair)pair2)->unicode; + + + if ( u1 < u2 ) + return -1; + + if ( u1 > u2 ) + return +1; + + return 0; + } + + + FT_CALLBACK_DEF( FT_Error ) + t1_cmap_unicode_init( T1_CMapUnicode cmap ) + { + FT_Error error; + FT_UInt count; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); + PSNames_Service psnames = (PSNames_Service)face->psnames; + + + cmap->num_pairs = 0; + cmap->pairs = NULL; + + count = face->type1.num_glyphs; + + if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) + { + FT_UInt n, new_count; + T1_CMapUniPair pair; + FT_UInt32 uni_code; + + + pair = cmap->pairs; + for ( n = 0; n < count; n++ ) + { + const char* gname = face->type1.glyph_names[n]; + + + /* build unsorted pair table by matching glyph names */ + if ( gname ) + { + uni_code = psnames->unicode_value( gname ); + + if ( uni_code != 0 ) + { + pair->unicode = uni_code; + pair->gindex = n; + pair++; + } + } + } + + new_count = (FT_UInt)( pair - cmap->pairs ); + if ( new_count == 0 ) + { + /* there are no unicode characters in here! */ + FT_FREE( cmap->pairs ); + error = FT_Err_Invalid_Argument; + } + else + { + /* re-allocate if the new array is much smaller than the original */ + /* one */ + if ( new_count != count && new_count < count / 2 ) + { + (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); + error = 0; + } + + /* sort the pairs table to allow efficient binary searches */ + ft_qsort( cmap->pairs, + new_count, + sizeof ( T1_CMapUniPairRec ), + t1_cmap_uni_pair_compare ); + + cmap->num_pairs = new_count; + } + } + + return error; + } + + + FT_CALLBACK_DEF( void ) + t1_cmap_unicode_done( T1_CMapUnicode cmap ) + { + FT_Face face = FT_CMAP_FACE(cmap); + FT_Memory memory = FT_FACE_MEMORY(face); + + FT_FREE( cmap->pairs ); + cmap->num_pairs = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_unicode_char_index( T1_CMapUnicode cmap, + FT_UInt32 char_code ) + { + FT_UInt min = 0; + FT_UInt max = cmap->num_pairs; + FT_UInt mid; + T1_CMapUniPair pair; + + + while ( min < max ) + { + mid = min + ( max - min ) / 2; + pair = cmap->pairs + mid; + + if ( pair->unicode == char_code ) + return pair->gindex; + + if ( pair->unicode < char_code ) + min = mid + 1; + else + max = mid; + } + return 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + t1_cmap_unicode_char_next( T1_CMapUnicode cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + Restart: + { + FT_UInt min = 0; + FT_UInt max = cmap->num_pairs; + FT_UInt mid; + T1_CMapUniPair pair; + + + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + pair = cmap->pairs + mid; + + if ( pair->unicode == char_code ) + { + result = pair->gindex; + if ( result != 0 ) + goto Exit; + + char_code++; + goto Restart; + } + + if ( pair->unicode < char_code ) + min = mid+1; + else + max = mid; + } + + /* we didn't find it, but we have a pair just above it */ + char_code = 0; + + if ( min < cmap->num_pairs ) + { + pair = cmap->pairs + min; + result = pair->gindex; + if ( result != 0 ) + char_code = pair->unicode; + } + } + + Exit: + *pchar_code = char_code; + return result; + } + + + FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec + t1_cmap_unicode_class_rec = + { + sizeof ( T1_CMapUnicodeRec ), + + (FT_CMap_InitFunc) t1_cmap_unicode_init, + (FT_CMap_DoneFunc) t1_cmap_unicode_done, + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next + }; + + +/* END */ diff --git a/lib/freetype/src/psaux/t1cmap.h b/lib/freetype/src/psaux/t1cmap.h new file mode 100644 index 0000000..0d68c99 --- /dev/null +++ b/lib/freetype/src/psaux/t1cmap.h @@ -0,0 +1,124 @@ +/***************************************************************************/ +/* */ +/* t1cmap.h */ +/* */ +/* Type 1 character map support (specification). */ +/* */ +/* Copyright 2002 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 __T1CMAP_H__ +#define __T1CMAP_H__ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 STANDARD (AND EXPERT) ENCODING CMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* standard (and expert) encoding cmaps */ + typedef struct T1_CMapStdRec_* T1_CMapStd; + + typedef struct T1_CMapStdRec_ + { + FT_CMapRec cmap; + + const FT_UShort* code_to_sid; + PS_Adobe_Std_Strings_Func sid_to_string; + + FT_UInt num_glyphs; + const char* const* glyph_names; + + } T1_CMapStdRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_standard_class_rec; + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_expert_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CUSTOM ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct T1_CMapCustomRec_* T1_CMapCustom; + + typedef struct T1_CMapCustomRec_ + { + FT_CMapRec cmap; + FT_UInt first; + FT_UInt count; + FT_UShort* indices; + + } T1_CMapCustomRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_custom_class_rec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 SYNTHETIC UNICODE ENCODING CMAP *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* unicode (syntehtic) cmaps */ + typedef struct T1_CMapUnicodeRec_* T1_CMapUnicode; + + typedef struct T1_CMapUniPairRec_ + { + FT_UInt32 unicode; + FT_UInt gindex; + + } T1_CMapUniPairRec, *T1_CMapUniPair; + + + typedef struct T1_CMapUnicodeRec_ + { + FT_CMapRec cmap; + FT_UInt num_pairs; + T1_CMapUniPair pairs; + + } T1_CMapUnicodeRec; + + + FT_CALLBACK_TABLE const FT_CMap_ClassRec + t1_cmap_unicode_class_rec; + + /* */ + + +FT_END_HEADER + +#endif /* __T1CMAP_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psaux/t1decode.c b/lib/freetype/src/psaux/t1decode.c new file mode 100644 index 0000000..27b4e87 --- /dev/null +++ b/lib/freetype/src/psaux/t1decode.c @@ -0,0 +1,1170 @@ +/***************************************************************************/ +/* */ +/* t1decode.c */ +/* */ +/* PostScript Type 1 decoding routines (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_OUTLINE_H + +#include "t1decode.h" +#include "psobjs.h" + +#include "psauxerr.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1decode + + + typedef enum T1_Operator_ + { + op_none = 0, + op_endchar, + op_hsbw, + op_seac, + op_sbw, + op_closepath, + op_hlineto, + op_hmoveto, + op_hvcurveto, + op_rlineto, + op_rmoveto, + op_rrcurveto, + op_vhcurveto, + op_vlineto, + op_vmoveto, + op_dotsection, + op_hstem, + op_hstem3, + op_vstem, + op_vstem3, + op_div, + op_callothersubr, + op_callsubr, + op_pop, + op_return, + op_setcurrentpoint, + + op_max /* never remove this one */ + + } T1_Operator; + + + static + const FT_Int t1_args_count[op_max] = + { + 0, /* none */ + 0, /* endchar */ + 2, /* hsbw */ + 5, /* seac */ + 4, /* sbw */ + 0, /* closepath */ + 1, /* hlineto */ + 1, /* hmoveto */ + 4, /* hvcurveto */ + 2, /* rlineto */ + 2, /* rmoveto */ + 6, /* rrcurveto */ + 4, /* vhcurveto */ + 1, /* vlineto */ + 1, /* vmoveto */ + 0, /* dotsection */ + 2, /* hstem */ + 6, /* hstem3 */ + 2, /* vstem */ + 6, /* vstem3 */ + 2, /* div */ + -1, /* callothersubr */ + 1, /* callsubr */ + 0, /* pop */ + 0, /* return */ + 2 /* setcurrentpoint */ + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_lookup_glyph_by_stdcharcode */ + /* */ + /* <Description> */ + /* Looks up a given glyph by its StandardEncoding charcode. Used to */ + /* implement the SEAC Type 1 operator. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* charcode :: The character code to look for. */ + /* */ + /* <Return> */ + /* A glyph index in the font face. Returns -1 if the corresponding */ + /* glyph wasn't found. */ + /* */ + static FT_Int + t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, + FT_Int charcode ) + { + FT_UInt n; + const FT_String* glyph_name; + PSNames_Service psnames = decoder->psnames; + + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + glyph_name = psnames->adobe_std_strings( + psnames->adobe_std_encoding[charcode]); + + for ( n = 0; n < decoder->num_glyphs; n++ ) + { + FT_String* name = (FT_String*)decoder->glyph_names[n]; + + + if ( name && name[0] == glyph_name[0] && + ft_strcmp( name,glyph_name ) == 0 ) + return n; + } + + return -1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1operator_seac */ + /* */ + /* <Description> */ + /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ + /* */ + /* <Input> */ + /* decoder :: The current CID decoder. */ + /* */ + /* asb :: The accent's side bearing. */ + /* */ + /* adx :: The horizontal offset of the accent. */ + /* */ + /* ady :: The vertical offset of the accent. */ + /* */ + /* bchar :: The base character's StandardEncoding charcode. */ + /* */ + /* achar :: The accent character's StandardEncoding charcode. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + t1operator_seac( T1_Decoder decoder, + FT_Pos asb, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + FT_Int bchar_index, achar_index; +#if 0 + FT_Int n_base_points; + FT_Outline* base = decoder->builder.base; +#endif + FT_Vector left_bearing, advance; + + + /* seac weirdness */ + adx += decoder->builder.left_bearing.x; + + /* `glyph_names' is set to 0 for CID fonts which do not */ + /* include an encoding. How can we deal with these? */ + if ( decoder->glyph_names == 0 ) + { + FT_ERROR(( "t1operator_seac:" )); + FT_ERROR(( " glyph names table not available in this font!\n" )); + return PSaux_Err_Syntax_Error; + } + + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "t1operator_seac:" )); + FT_ERROR(( " invalid seac character code arguments\n" )); + return PSaux_Err_Syntax_Error; + } + + /* if we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( decoder->builder.no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = adx - asb; + subg->arg2 = ady; + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + goto Exit; + } + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + + error = t1_decoder_parse_glyph( decoder, bchar_index ); + if ( error ) + goto Exit; + +#if 0 + n_base_points = base->n_points; +#endif + + /* save the left bearing and width of the base character */ + /* as they will be erased by the next load. */ + + left_bearing = decoder->builder.left_bearing; + advance = decoder->builder.advance; + + decoder->builder.left_bearing.x = 0; + decoder->builder.left_bearing.y = 0; + + decoder->builder.pos_x = adx - asb; + decoder->builder.pos_y = ady; + + /* Now load `achar' on top of */ + /* the base outline */ + error = t1_decoder_parse_glyph( decoder, achar_index ); + if ( error ) + goto Exit; + + /* restore the left side bearing and */ + /* advance width of the base character */ + + decoder->builder.left_bearing = left_bearing; + decoder->builder.advance = advance; + + /* XXX: old code doesn't work with PostScript hinter */ +#if 0 + /* Finally, move the accent */ + if ( decoder->builder.load_points ) + { + FT_Outline dummy; + + + dummy.n_points = (short)( base->n_points - n_base_points ); + dummy.points = base->points + n_base_points; + + FT_Outline_Translate( &dummy, adx - asb, ady ); + } +#else + decoder->builder.pos_x = 0; + decoder->builder.pos_y = 0; +#endif + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 1 charstrings program. */ + /* */ + /* <Input> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* charstring_base :: The base address of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* charstring_base, + FT_UInt charstring_len ) + { + FT_Error error; + T1_Decoder_Zone zone; + FT_Byte* ip; + FT_Byte* limit; + T1_Builder builder = &decoder->builder; + FT_Pos x, y, orig_x, orig_y; + + T1_Hints_Funcs hinter; + + + /* we don't want to touch the source code -- use macro trick */ +#define start_point t1_builder_start_point +#define check_points t1_builder_check_points +#define add_point t1_builder_add_point +#define add_point1 t1_builder_add_point1 +#define add_contour t1_builder_add_contour +#define close_contour t1_builder_close_contour + + /* First of all, initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + + builder->path_begun = 0; + + hinter = (T1_Hints_Funcs)builder->hints_funcs; + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = PSaux_Err_Ok; + + x = orig_x = builder->pos_x; + y = orig_y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + /* now, execute loop */ + while ( ip < limit ) + { + FT_Long* top = decoder->top; + T1_Operator op = op_none; + FT_Long value = 0; + + + /*********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + /* */ + + /* first of all, decompress operator or value */ + switch ( *ip++ ) + { + case 1: + op = op_hstem; + break; + + case 3: + op = op_vstem; + break; + case 4: + op = op_vmoveto; + break; + case 5: + op = op_rlineto; + break; + case 6: + op = op_hlineto; + break; + case 7: + op = op_vlineto; + break; + case 8: + op = op_rrcurveto; + break; + case 9: + op = op_closepath; + break; + case 10: + op = op_callsubr; + break; + case 11: + op = op_return; + break; + + case 13: + op = op_hsbw; + break; + case 14: + op = op_endchar; + break; + + case 15: /* undocumented, obsolete operator */ + op = op_none; + break; + + case 21: + op = op_rmoveto; + break; + case 22: + op = op_hmoveto; + break; + + case 30: + op = op_vhcurveto; + break; + case 31: + op = op_hvcurveto; + break; + + case 12: + if ( ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid escape (12+EOF)\n" )); + goto Syntax_Error; + } + + switch ( *ip++ ) + { + case 0: + op = op_dotsection; + break; + case 1: + op = op_vstem3; + break; + case 2: + op = op_hstem3; + break; + case 6: + op = op_seac; + break; + case 7: + op = op_sbw; + break; + case 12: + op = op_div; + break; + case 16: + op = op_callothersubr; + break; + case 17: + op = op_pop; + break; + case 33: + op = op_setcurrentpoint; + break; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid escape (12+%d)\n", + ip[-1] )); + goto Syntax_Error; + } + break; + + case 255: /* four bytes integer */ + if ( ip + 4 > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + value = (FT_Int32)( ((FT_Long)ip[0] << 24) | + ((FT_Long)ip[1] << 16) | + ((FT_Long)ip[2] << 8 ) | + ip[3] ); + ip += 4; + break; + + default: + if ( ip[-1] >= 32 ) + { + if ( ip[-1] < 247 ) + value = (FT_Long)ip[-1] - 139; + else + { + if ( ++ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + if ( ip[-2] < 251 ) + value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + else + value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + } + } + else + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid byte (%d)\n", ip[-1] )); + goto Syntax_Error; + } + } + + /*********************************************************************/ + /* */ + /* Push value on stack, or process operator */ + /* */ + /* */ + if ( op == op_none ) + { + if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); + goto Syntax_Error; + } + + FT_TRACE4(( " %ld", value )); + + *top++ = value; + decoder->top = top; + } + else if ( op == op_callothersubr ) /* callothersubr */ + { + FT_TRACE4(( " callothersubr" )); + + if ( top - decoder->stack < 2 ) + goto Stack_Underflow; + + top -= 2; + switch ( top[1] ) + { + case 1: /* start flex feature */ + if ( top[0] != 0 ) + goto Unexpected_OtherSubr; + + decoder->flex_state = 1; + decoder->num_flex_vectors = 0; + if ( start_point( builder, x, y ) || + check_points( builder, 6 ) ) + goto Memory_Error; + break; + + case 2: /* add flex vectors */ + { + FT_Int idx; + + + if ( top[0] != 0 ) + goto Unexpected_OtherSubr; + + /* note that we should not add a point for index 0; */ + /* this will move our current position to the flex */ + /* point without adding any point to the outline */ + idx = decoder->num_flex_vectors++; + if ( idx > 0 && idx < 7 ) + add_point( builder, + x, + y, + (FT_Byte)( idx == 3 || idx == 6 ) ); + } + break; + + case 0: /* end flex feature */ + if ( top[0] != 3 ) + goto Unexpected_OtherSubr; + + if ( decoder->flex_state == 0 || + decoder->num_flex_vectors != 7 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "unexpected flex end\n" )); + goto Syntax_Error; + } + + /* now consume the remaining `pop pop setcurpoint' */ + if ( ip + 6 > limit || + ip[0] != 12 || ip[1] != 17 || /* pop */ + ip[2] != 12 || ip[3] != 17 || /* pop */ + ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid flex charstring\n" )); + goto Syntax_Error; + } + + ip += 6; + decoder->flex_state = 0; + break; + + case 3: /* change hints */ + if ( top[0] != 1 ) + goto Unexpected_OtherSubr; + + /* eat the following `pop' */ + if ( ip + 2 > limit ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid escape (12+%d)\n", ip[-1] )); + goto Syntax_Error; + } + + if ( ip[0] != 12 || ip[1] != 17 ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] )); + goto Syntax_Error; + } + ip += 2; + + if ( hinter ) + hinter->reset( hinter->hints, builder->current->n_points ); + + break; + + case 12: + case 13: + /* counter control hints, clear stack */ + top = decoder->stack; + break; + + case 14: + case 15: + case 16: + case 17: + case 18: /* multiple masters */ + { + PS_Blend blend = decoder->blend; + FT_UInt num_points, nn, mm; + FT_Long* delta; + FT_Long* values; + + + if ( !blend ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "unexpected multiple masters operator!\n" )); + goto Syntax_Error; + } + + num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 ); + if ( top[0] != (FT_Int)( num_points * blend->num_designs ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "incorrect number of mm arguments\n" )); + goto Syntax_Error; + } + + top -= blend->num_designs * num_points; + if ( top < decoder->stack ) + goto Stack_Underflow; + + /* we want to compute: */ + /* */ + /* a0*w0 + a1*w1 + ... + ak*wk */ + /* */ + /* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */ + /* however, given that w0 + w1 + ... + wk == 1, we can */ + /* rewrite it easily as: */ + /* */ + /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ + /* */ + /* where k == num_designs-1 */ + /* */ + /* I guess that's why it's written in this `compact' */ + /* form. */ + /* */ + delta = top + num_points; + values = top; + for ( nn = 0; nn < num_points; nn++ ) + { + FT_Int tmp = values[0]; + + + for ( mm = 1; mm < blend->num_designs; mm++ ) + tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); + + *values++ = tmp; + } + /* note that `top' will be incremented later by calls to `pop' */ + break; + } + + default: + Unexpected_OtherSubr: + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid othersubr [%d %d]!\n", top[0], top[1] )); + goto Syntax_Error; + } + decoder->top = top; + } + else /* general operator */ + { + FT_Int num_args = t1_args_count[op]; + + + if ( top - decoder->stack < num_args ) + goto Stack_Underflow; + + top -= num_args; + + switch ( op ) + { + case op_endchar: + FT_TRACE4(( " endchar" )); + + close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if (hinter->close( hinter->hints, builder->current->n_points )) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + hinter->apply( hinter->hints, + builder->current, + (PSH_Globals) builder->hints_globals, + decoder->hint_mode ); + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n\n" )); + return PSaux_Err_Ok; + + case op_hsbw: + FT_TRACE4(( " hsbw" )); + + builder->left_bearing.x += top[0]; + builder->advance.x = top[1]; + builder->advance.y = 0; + + orig_x = builder->last.x = x = builder->pos_x + top[0]; + orig_y = builder->last.y = y = builder->pos_y; + + FT_UNUSED( orig_y ); + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return PSaux_Err_Ok; + + break; + + case op_seac: + /* return immediately after the processing */ + return t1operator_seac( decoder, top[0], top[1], + top[2], top[3], top[4] ); + + case op_sbw: + FT_TRACE4(( " sbw" )); + + builder->left_bearing.x += top[0]; + builder->left_bearing.y += top[1]; + builder->advance.x = top[2]; + builder->advance.y = top[3]; + + builder->last.x = x = builder->pos_x + top[0]; + builder->last.y = y = builder->pos_y + top[1]; + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + return PSaux_Err_Ok; + + break; + + case op_closepath: + FT_TRACE4(( " closepath" )); + + close_contour( builder ); + builder->path_begun = 0; + break; + + case op_hlineto: + FT_TRACE4(( " hlineto" )); + + if ( start_point( builder, x, y ) ) + goto Memory_Error; + + x += top[0]; + goto Add_Line; + + case op_hmoveto: + FT_TRACE4(( " hmoveto" )); + + x += top[0]; + if ( !decoder->flex_state ) + builder->path_begun = 0; + break; + + case op_hvcurveto: + FT_TRACE4(( " hvcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Memory_Error; + + x += top[0]; + add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + add_point( builder, x, y, 0 ); + y += top[3]; + add_point( builder, x, y, 1 ); + break; + + case op_rlineto: + FT_TRACE4(( " rlineto" )); + + if ( start_point( builder, x, y ) ) + goto Memory_Error; + + x += top[0]; + y += top[1]; + + Add_Line: + if ( add_point1( builder, x, y ) ) + goto Memory_Error; + break; + + case op_rmoveto: + FT_TRACE4(( " rmoveto" )); + + x += top[0]; + y += top[1]; + if ( !decoder->flex_state ) + builder->path_begun = 0; + break; + + case op_rrcurveto: + FT_TRACE4(( " rcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Memory_Error; + + x += top[0]; + y += top[1]; + add_point( builder, x, y, 0 ); + + x += top[2]; + y += top[3]; + add_point( builder, x, y, 0 ); + + x += top[4]; + y += top[5]; + add_point( builder, x, y, 1 ); + break; + + case op_vhcurveto: + FT_TRACE4(( " vhcurveto" )); + + if ( start_point( builder, x, y ) || + check_points( builder, 3 ) ) + goto Memory_Error; + + y += top[0]; + add_point( builder, x, y, 0 ); + x += top[1]; + y += top[2]; + add_point( builder, x, y, 0 ); + x += top[3]; + add_point( builder, x, y, 1 ); + break; + + case op_vlineto: + FT_TRACE4(( " vlineto" )); + + if ( start_point( builder, x, y ) ) + goto Memory_Error; + + y += top[0]; + goto Add_Line; + + case op_vmoveto: + FT_TRACE4(( " vmoveto" )); + + y += top[0]; + if ( !decoder->flex_state ) + builder->path_begun = 0; + break; + + case op_div: + FT_TRACE4(( " div" )); + + if ( top[1] ) + { + *top = top[0] / top[1]; + ++top; + } + else + { + FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); + goto Syntax_Error; + } + break; + + case op_callsubr: + { + FT_Int idx; + + + FT_TRACE4(( " callsubr" )); + + idx = top[0]; + if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invalid subrs index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + + /* The Type 1 driver stores subroutines without the seed bytes. */ + /* The CID driver stores subroutines with seed bytes. This */ + /* case is taken care of when decoder->subrs_len == 0. */ + zone->base = decoder->subrs[idx]; + + if ( decoder->subrs_len ) + zone->limit = zone->base + decoder->subrs_len[idx]; + else + { + /* We are using subroutines from a CID font. We must adjust */ + /* for the seed bytes. */ + zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + zone->limit = decoder->subrs[idx + 1]; + } + + zone->cursor = zone->base; + + if ( !zone->base ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: " + "invoking empty subrs!\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + break; + } + + case op_pop: + FT_TRACE4(( " pop" )); + + /* theoretically, the arguments are already on the stack */ + top++; + break; + + case op_return: + FT_TRACE4(( " return" )); + + if ( zone <= decoder->zones ) + { + FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); + goto Syntax_Error; + } + + zone--; + ip = zone->cursor; + limit = zone->limit; + decoder->zone = zone; + break; + + case op_dotsection: + FT_TRACE4(( " dotsection" )); + + break; + + case op_hstem: + FT_TRACE4(( " hstem" )); + + /* record horizontal hint */ + if ( hinter ) + { + /* top[0] += builder->left_bearing.y; */ + hinter->stem( hinter->hints, 1, top ); + } + + break; + + case op_hstem3: + FT_TRACE4(( " hstem3" )); + + /* record horizontal counter-controlled hints */ + if ( hinter ) + hinter->stem3( hinter->hints, 1, top ); + + break; + + case op_vstem: + FT_TRACE4(( " vstem" )); + + /* record vertical hint */ + if ( hinter ) + { + top[0] += orig_x; + hinter->stem( hinter->hints, 0, top ); + } + + break; + + case op_vstem3: + FT_TRACE4(( " vstem3" )); + + /* record vertical counter-controlled hints */ + if ( hinter ) + { + FT_Pos dx = orig_x; + + + top[0] += dx; + top[2] += dx; + top[4] += dx; + hinter->stem3( hinter->hints, 0, top ); + } + break; + + case op_setcurrentpoint: + FT_TRACE4(( " setcurrentpoint" )); + + FT_ERROR(( "t1_decoder_parse_charstrings: " )); + FT_ERROR(( "unexpected `setcurrentpoint'\n" )); + goto Syntax_Error; + + default: + FT_ERROR(( "t1_decoder_parse_charstrings: " + "unhandled opcode %d\n", op )); + goto Syntax_Error; + } + + decoder->top = top; + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + return error; + + Syntax_Error: + return PSaux_Err_Syntax_Error; + + Stack_Underflow: + return PSaux_Err_Stack_Underflow; + + Memory_Error: + return builder->error; + } + + + /* parse a single Type 1 glyph */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph ) + { + return decoder->parse_callback( decoder, glyph ); + } + + + /* initialize T1 decoder */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_callback ) + { + FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + + /* retrieve PSNames interface from list of current modules */ + { + PSNames_Service psnames = 0; + + + psnames = (PSNames_Service)FT_Get_Module_Interface( + FT_FACE_LIBRARY(face), "psnames" ); + if ( !psnames ) + { + FT_ERROR(( "t1_decoder_init: " )); + FT_ERROR(( "the `psnames' module is not available\n" )); + return PSaux_Err_Unimplemented_Feature; + } + + decoder->psnames = psnames; + } + + t1_builder_init( &decoder->builder, face, size, slot, hinting ); + + decoder->num_glyphs = (FT_UInt)face->num_glyphs; + decoder->glyph_names = glyph_names; + decoder->hint_flags = face->internal->hint_flags; + decoder->hint_mode = hint_mode; + decoder->blend = blend; + decoder->parse_callback = parse_callback; + + decoder->funcs = t1_decoder_funcs; + + return 0; + } + + + /* finalize T1 decoder */ + FT_LOCAL_DEF( void ) + t1_decoder_done( T1_Decoder decoder ) + { + t1_builder_done( &decoder->builder ); + } + + +/* END */ diff --git a/lib/freetype/src/psaux/t1decode.h b/lib/freetype/src/psaux/t1decode.h new file mode 100644 index 0000000..fcb853c --- /dev/null +++ b/lib/freetype/src/psaux/t1decode.h @@ -0,0 +1,65 @@ +/***************************************************************************/ +/* */ +/* t1decode.h */ +/* */ +/* PostScript Type 1 decoding routines (specification). */ +/* */ +/* Copyright 2000-2001, 2002 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 __T1DECODE_H__ +#define __T1DECODE_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + FT_CALLBACK_TABLE + const T1_Decoder_FuncsRec t1_decoder_funcs; + + + FT_LOCAL( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph_index ); + + FT_LOCAL( FT_Error ) + t1_decoder_parse_charstrings( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + FT_LOCAL( FT_Error ) + t1_decoder_init( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback parse_glyph ); + + FT_LOCAL( void ) + t1_decoder_done( T1_Decoder decoder ); + + +FT_END_HEADER + +#endif /* __T1DECODE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/Jamfile b/lib/freetype/src/pshinter/Jamfile new file mode 100644 index 0000000..8eb3dea --- /dev/null +++ b/lib/freetype/src/pshinter/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/pshinter Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = pshrec pshglob pshalgo1 pshalgo2 pshalgo3 pshmod ; + } + else + { + _sources = pshinter ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/pshinter Jamfile diff --git a/lib/freetype/src/pshinter/descrip.mms b/lib/freetype/src/pshinter/descrip.mms new file mode 100644 index 0000000..205d6cf --- /dev/null +++ b/lib/freetype/src/pshinter/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 PSHinter driver compilation rules for OpenVMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psnames]) + +OBJS=pshinter.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/pshinter/module.mk b/lib/freetype/src/pshinter/module.mk new file mode 100644 index 0000000..63c7e21 --- /dev/null +++ b/lib/freetype/src/pshinter/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 PSHinter module definition +# + + +# Copyright 1996-2001 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. + + +make_module_list: add_pshinter_module + +add_pshinter_module: + $(OPEN_DRIVER)pshinter_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)pshinter $(ECHO_DRIVER_DESC)Postscript hinter module$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/pshinter/pshalgo.h b/lib/freetype/src/pshinter/pshalgo.h new file mode 100644 index 0000000..e79ad02 --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* pshalgo.h */ +/* */ +/* This header file defines the used hinting algorithm. */ +/* */ +/* Copyright 2001 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 __PSHALGO_H__ +#define __PSHALGO_H__ + +FT_BEGIN_HEADER + +/* define to choose hinting algorithm */ +#define PSH_ALGORITHM_3 + +#if defined(PSH_ALGORITHM_1) + +# include "pshalgo1.h" +# define PS_HINTS_APPLY_FUNC ps1_hints_apply + +#elif defined(PSH_ALGORITHM_2) + +# include "pshalgo2.h" +# define PS_HINTS_APPLY_FUNC ps2_hints_apply + +#elif defined(PSH_ALGORITHM_3) + +# include "pshalgo3.h" +# define PS_HINTS_APPLY_FUNC ps3_hints_apply + +#else + +# error "invalid Postscript Hinter algorithm selection" + +#endif + +FT_END_HEADER + +#endif /* __PSHALGO_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo1.c b/lib/freetype/src/pshinter/pshalgo1.c new file mode 100644 index 0000000..06da597 --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo1.c @@ -0,0 +1,785 @@ +/***************************************************************************/ +/* */ +/* pshalgo1.c */ +/* */ +/* PostScript hinting algorithm 1 (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include "pshalgo1.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshalgo1 + +#ifdef DEBUG_HINTER + PSH1_Hint_Table ps1_debug_hint_table = 0; + PSH1_HintFunc ps1_debug_hint_func = 0; +#endif + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + /* return true iff two stem hints overlap */ + static FT_Int + psh1_hint_overlap( PSH1_Hint hint1, + PSH1_Hint hint2 ) + { + return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos ); + } + + + /* destroy hints table */ + static void + psh1_hint_table_done( PSH1_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->zones ); + table->num_zones = 0; + table->zone = 0; + + FT_FREE( table->sort ); + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + table->sort_global = 0; + } + + + /* deactivate all hints in a table */ + static void + psh1_hint_table_deactivate( PSH1_Hint_Table table ) + { + FT_UInt count = table->max_hints; + PSH1_Hint hint = table->hints; + + + for ( ; count > 0; count--, hint++ ) + { + psh1_hint_deactivate( hint ); + hint->order = -1; + } + } + + + /* internal function used to record a new hint */ + static void + psh1_hint_table_record( PSH1_Hint_Table table, + FT_UInt idx ) + { + PSH1_Hint hint = table->hints + idx; + + + if ( idx >= table->max_hints ) + { + FT_ERROR(( "%s.activate: invalid hint index %d\n", idx )); + return; + } + + /* ignore active hints */ + if ( psh1_hint_is_active( hint ) ) + return; + + psh1_hint_activate( hint ); + + /* now scan the current active hint set in order to determine */ + /* if we are overlapping with another segment */ + { + PSH1_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH1_Hint hint2; + + + hint->parent = 0; + for ( ; count > 0; count--, sorted++ ) + { + hint2 = sorted[0]; + + if ( psh1_hint_overlap( hint, hint2 ) ) + { + hint->parent = hint2; + break; + } + } + } + + if ( table->num_hints < table->max_hints ) + table->sort_global[table->num_hints++] = hint; + else + FT_ERROR(( "%s.activate: too many sorted hints! BUG!\n", + "ps.fitter" )); + } + + + static void + psh1_hint_table_record_mask( PSH1_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit; + + + limit = hint_mask->num_bits; + + if ( limit != table->max_hints ) + FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n", + "ps.fitter", hint_mask->num_bits, table->max_hints )); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + psh1_hint_table_record( table, idx ); + + mask >>= 1; + } + } + + + /* create hints table */ + static FT_Error + psh1_hint_table_init( PSH1_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) + { + FT_UInt count = hints->num_hints; + FT_Error error; + + FT_UNUSED( counter_masks ); + + + /* allocate our tables */ + if ( FT_NEW_ARRAY( table->sort, 2 * count ) || + FT_NEW_ARRAY( table->hints, count ) || + FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) + goto Exit; + + table->max_hints = count; + table->sort_global = table->sort + count; + table->num_hints = 0; + table->num_zones = 0; + table->zone = 0; + + /* now, initialize the "hints" array */ + { + PSH1_Hint write = table->hints; + PS_Hint read = hints->hints; + + + for ( ; count > 0; count--, write++, read++ ) + { + write->org_pos = read->pos; + write->org_len = read->len; + write->flags = read->flags; + } + } + + /* we now need to determine the initial "parent" stems; first */ + /* activate the hints that are given by the initial hint masks */ + if ( hint_masks ) + { + FT_UInt Count = hint_masks->num_masks; + PS_Mask Mask = hint_masks->masks; + + + table->hint_masks = hint_masks; + + for ( ; Count > 0; Count--, Mask++ ) + psh1_hint_table_record_mask( table, Mask ); + } + + /* now, do a linear parse in case some hints were left alone */ + if ( table->num_hints != table->max_hints ) + { + FT_UInt Index, Count; + + + FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); + Count = table->max_hints; + for ( Index = 0; Index < Count; Index++ ) + psh1_hint_table_record( table, Index ); + } + + Exit: + return error; + } + + + static void + psh1_hint_table_activate_mask( PSH1_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit, count; + + + limit = hint_mask->num_bits; + count = 0; + + psh1_hint_table_deactivate( table ); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + { + PSH1_Hint hint = &table->hints[idx]; + + + if ( !psh1_hint_is_active( hint ) ) + { + PSH1_Hint* sort = table->sort; + FT_UInt count2; + PSH1_Hint hint2; + + + for ( count2 = count; count2 > 0; count2--, sort++ ) + { + hint2 = sort[0]; + if ( psh1_hint_overlap( hint, hint2 ) ) + { + FT_ERROR(( "%s.activate_mask: found overlapping hints\n", + "psf.hint" )); + break; + } + } + + if ( count2 == 0 ) + { + psh1_hint_activate( hint ); + if ( count < table->max_hints ) + table->sort[count++] = hint; + else + FT_ERROR(( "%s.activate_mask: too many active hints\n", + "psf.hint" )); + } + } + } + + mask >>= 1; + } + table->num_hints = count; + + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ + { + FT_Int i1, i2; + PSH1_Hint hint1, hint2; + PSH1_Hint* sort = table->sort; + + + /* a simple bubble sort will do, since in 99% of cases, the hints */ + /* will be already sorted; and the sort will be linear */ + for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + { + hint1 = sort[i1]; + + for ( i2 = i1 - 1; i2 >= 0; i2-- ) + { + hint2 = sort[i2]; + if ( hint2->org_pos < hint1->org_pos ) + break; + + sort[i2 + 1] = hint2; + sort[i2] = hint1; + } + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef DEBUG_HINTER + void + ps_simple_scale( PSH1_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int vertical ) + { + PSH1_Hint hint; + FT_UInt count; + + + for ( count = 0; count < table->num_hints; count++ ) + { + hint = table->sort[count]; + if ( psh1_hint_is_active( hint ) ) + { + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + + if ( ps1_debug_hint_func ) + ps1_debug_hint_func( hint, vertical ); + } + } + } +#endif + + + FT_LOCAL_DEF( FT_Error ) + psh1_hint_table_optimize( PSH1_Hint_Table table, + PSH_Globals globals, + FT_Outline* outline, + FT_Int vertical ) + { + PSH_Dimension dim = &globals->dimension[vertical]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + FT_UNUSED( outline ); + + +#ifdef DEBUG_HINTER + if ( ps_debug_no_vert_hints && vertical ) + { + ps_simple_scale( table, scale, delta, vertical ); + return 0; + } + + if ( ps_debug_no_horz_hints && !vertical ) + { + ps_simple_scale( table, scale, delta, vertical ); + return 0; + } +#endif + + /* XXXX: for now, we only scale the hints to test all other aspects */ + /* of the PostScript hinter */ + { + PSH1_Hint hint; + FT_UInt count; + + + for ( count = 0; count < table->num_hints; count++ ) + { + hint = table->sort[count]; + if ( psh1_hint_is_active( hint ) ) + { +#if 1 + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Pos fit_center; + FT_Pos fit_len; + + PSH_AlignmentRec align; + + + /* compute fitted width/height */ + fit_len = psh_dimension_snap_width( dim, hint->org_len ); + if ( fit_len < 64 ) + fit_len = 64; + else + fit_len = ( fit_len + 32 ) & -64; + + hint->cur_len = fit_len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + if ( !vertical ) + { + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + } + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + /* normal processing */ + if ( ( fit_len / 64 ) & 1 ) + { + /* odd number of pixels */ + fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; + } + else + { + /* even number of pixels */ + fit_center = ( pos + ( len >> 1 ) + 32 ) & -64; + } + + hint->cur_pos = fit_center - ( fit_len >> 1 ); + } + +# else + + hint->cur_pos = ( FT_MulFix( hint->org_pos, scale ) + delta + 32 ) + & -64; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + +# endif + +#ifdef DEBUG_HINTER + if ( ps1_debug_hint_func ) + ps1_debug_hint_func( hint, vertical ); +#endif + } + } + } + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PSH1_ZONE_MIN -3200000 +#define PSH1_ZONE_MAX +3200000 + +#define xxDEBUG_ZONES + + +#ifdef DEBUG_ZONES + +#include <stdio.h> + + static void + psh1_print_zone( PSH1_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale / 65536.0, + zone->delta / 64.0, + zone->min, + zone->max ); + } + +#else +#define psh1_print_zone( x ) do { } while ( 0 ) +#endif + + /* setup interpolation zones once the hints have been grid-fitted */ + /* by the optimizer */ + static void + psh1_hint_table_setup_zones( PSH1_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta ) + { + FT_UInt count; + PSH1_Zone zone; + PSH1_Hint *sort, hint, hint2; + + + zone = table->zones; + + /* special case, no hints defined */ + if ( table->num_hints == 0 ) + { + zone->scale = scale; + zone->delta = delta; + zone->min = PSH1_ZONE_MIN; + zone->max = PSH1_ZONE_MAX; + + table->num_zones = 1; + table->zone = zone; + return; + } + + /* the first zone is before the first hint */ + /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */ + + sort = table->sort; + hint = sort[0]; + + zone->scale = scale; + zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); + zone->min = PSH1_ZONE_MIN; + zone->max = hint->org_pos; + + psh1_print_zone( zone ); + + zone++; + + for ( count = table->num_hints; count > 0; count-- ) + { + FT_Fixed scale2; + + + if ( hint->org_len > 0 ) + { + /* setup a zone for inner-stem interpolation */ + /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */ + /* x' = x*s2 + x0' - x0*s2 */ + + scale2 = FT_DivFix( hint->cur_len, hint->org_len ); + zone->scale = scale2; + zone->min = hint->org_pos; + zone->max = hint->org_pos + hint->org_len; + zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 ); + + psh1_print_zone( zone ); + + zone++; + } + + if ( count == 1 ) + break; + + sort++; + hint2 = sort[0]; + + /* setup zone for inter-stem interpolation */ + /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */ + /* x' = x*s3 + x1' - x1*s3 */ + + scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), + hint2->org_pos - (hint->org_pos + hint->org_len) ); + zone->scale = scale2; + zone->min = hint->org_pos + hint->org_len; + zone->max = hint2->org_pos; + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale2 ); + + psh1_print_zone( zone ); + + zone++; + + hint = hint2; + } + + /* the last zone */ + zone->scale = scale; + zone->min = hint->org_pos + hint->org_len; + zone->max = PSH1_ZONE_MAX; + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale ); + + psh1_print_zone( zone ); + + zone++; + + table->num_zones = zone - table->zones; + table->zone = table->zones; + } + + + /* tune a single coordinate with the current interpolation zones */ + static FT_Pos + psh1_hint_table_tune_coord( PSH1_Hint_Table table, + FT_Int coord ) + { + PSH1_Zone zone; + + + zone = table->zone; + + if ( coord < zone->min ) + { + do + { + if ( zone == table->zones ) + break; + + zone--; + + } while ( coord < zone->min ); + table->zone = zone; + } + else if ( coord > zone->max ) + { + do + { + if ( zone == table->zones + table->num_zones - 1 ) + break; + + zone++; + + } while ( coord > zone->max ); + table->zone = zone; + } + + return FT_MulFix( coord, zone->scale ) + zone->delta; + } + + + /* tune a given outline with current interpolation zones. */ + /* The function only works in a single dimension. */ + static void + psh1_hint_table_tune_outline( PSH1_Hint_Table table, + FT_Outline* outline, + PSH_Globals globals, + FT_Int vertical ) + + { + FT_UInt count, first, last; + PS_Mask_Table hint_masks = table->hint_masks; + PS_Mask mask; + PSH_Dimension dim = &globals->dimension[vertical]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( hint_masks && hint_masks->num_masks > 0 ) + { + first = 0; + mask = hint_masks->masks; + count = hint_masks->num_masks; + + for ( ; count > 0; count--, mask++ ) + { + last = mask->end_point; + + if ( last > first ) + { + FT_Vector* vec; + FT_Int count2; + + + psh1_hint_table_activate_mask( table, mask ); + psh1_hint_table_optimize( table, globals, outline, vertical ); + psh1_hint_table_setup_zones( table, scale, delta ); + last = mask->end_point; + + vec = outline->points + first; + count2 = last - first; + + for ( ; count2 > 0; count2--, vec++ ) + { + FT_Pos x, *px; + + + px = vertical ? &vec->x : &vec->y; + x = *px; + + *px = psh1_hint_table_tune_coord( table, (FT_Int)x ); + } + } + + first = last; + } + } + else /* no hints in this glyph, simply scale the outline */ + { + FT_Vector* vec; + + + vec = outline->points; + count = outline->n_points; + + if ( vertical ) + { + for ( ; count > 0; count--, vec++ ) + vec->x = FT_MulFix( vec->x, scale ) + delta; + } + else + { + for ( ; count > 0; count--, vec++ ) + vec->y = FT_MulFix( vec->y, scale ) + delta; + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_Error + ps1_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + PSH1_Hint_TableRec hints; + FT_Error error = 0; + FT_Int dimension; + + + FT_UNUSED( hint_mode ); + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + PS_Dimension dim = &ps_hints->dimension[dimension]; + + + /* initialize hints table */ + FT_MEM_ZERO( &hints, sizeof ( hints ) ); + error = psh1_hint_table_init( &hints, + &dim->hints, + &dim->masks, + &dim->counters, + ps_hints->memory ); + if ( error ) + goto Exit; + + psh1_hint_table_tune_outline( &hints, + outline, + globals, + dimension ); + + psh1_hint_table_done( &hints, ps_hints->memory ); + } + + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo1.h b/lib/freetype/src/pshinter/pshalgo1.h new file mode 100644 index 0000000..2f795a6 --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo1.h @@ -0,0 +1,110 @@ +/***************************************************************************/ +/* */ +/* pshalgo1.h */ +/* */ +/* PostScript hinting algorithm 1 (specification). */ +/* */ +/* Copyright 2001 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 __PSHALGO1_H__ +#define __PSHALGO1_H__ + +#include "pshrec.h" + +FT_BEGIN_HEADER + + typedef struct PSH1_HintRec_* PSH1_Hint; + + typedef enum + { + PSH1_HINT_FLAG_GHOST = PS_HINT_FLAG_GHOST, + PSH1_HINT_FLAG_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH1_HINT_FLAG_ACTIVE = 4 + + } PSH1_Hint_Flags; + +#define psh1_hint_is_active( x ) \ + ( ( (x)->flags & PSH1_HINT_FLAG_ACTIVE ) != 0 ) +#define psh1_hint_is_ghost( x ) \ + ( ( (x)->flags & PSH1_HINT_FLAG_GHOST ) != 0 ) + +#define psh1_hint_activate( x ) (x)->flags |= PSH1_HINT_FLAG_ACTIVE +#define psh1_hint_deactivate( x ) (x)->flags &= ~PSH1_HINT_FLAG_ACTIVE + + typedef struct PSH1_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + + FT_UInt flags; + + PSH1_Hint parent; + FT_Int order; + + } PSH1_HintRec; + + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH1_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH1_ZoneRec, *PSH1_Zone; + + + typedef struct PSH1_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH1_Hint hints; + PSH1_Hint* sort; + PSH1_Hint* sort_global; + FT_UInt num_zones; + PSH1_Zone zones; + PSH1_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH1_Hint_TableRec, *PSH1_Hint_Table; + + + extern FT_Error + ps1_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + +#ifdef DEBUG_HINTER + extern PSH1_Hint_Table ps1_debug_hint_table; + + typedef void + (*PSH1_HintFunc)( PSH1_Hint hint, + FT_Bool vertical ); + + extern PSH1_HintFunc ps1_debug_hint_func; +#endif + +FT_END_HEADER + +#endif /* __PSHALGO1_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo2.c b/lib/freetype/src/pshinter/pshalgo2.c new file mode 100644 index 0000000..c0a9265 --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo2.c @@ -0,0 +1,1557 @@ +/***************************************************************************/ +/* */ +/* pshalgo2.c */ +/* */ +/* PostScript hinting algorithm 2 (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include "pshalgo2.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshalgo2 + +#ifdef DEBUG_HINTER + PSH2_Hint_Table ps2_debug_hint_table = 0; + PSH2_HintFunc ps2_debug_hint_func = 0; + PSH2_Glyph ps2_debug_glyph = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* return true iff two stem hints overlap */ + static FT_Int + psh2_hint_overlap( PSH2_Hint hint1, + PSH2_Hint hint2 ) + { + return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos ); + } + + + /* destroy hints table */ + static void + psh2_hint_table_done( PSH2_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->zones ); + table->num_zones = 0; + table->zone = 0; + + FT_FREE( table->sort ); + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + table->sort_global = 0; + } + + + /* deactivate all hints in a table */ + static void + psh2_hint_table_deactivate( PSH2_Hint_Table table ) + { + FT_UInt count = table->max_hints; + PSH2_Hint hint = table->hints; + + + for ( ; count > 0; count--, hint++ ) + { + psh2_hint_deactivate( hint ); + hint->order = -1; + } + } + + + /* internal function used to record a new hint */ + static void + psh2_hint_table_record( PSH2_Hint_Table table, + FT_UInt idx ) + { + PSH2_Hint hint = table->hints + idx; + + + if ( idx >= table->max_hints ) + { + FT_ERROR(( "%s.activate: invalid hint index %d\n", idx )); + return; + } + + /* ignore active hints */ + if ( psh2_hint_is_active( hint ) ) + return; + + psh2_hint_activate( hint ); + + /* now scan the current active hint set in order to determine */ + /* if we are overlapping with another segment */ + { + PSH2_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH2_Hint hint2; + + + hint->parent = 0; + for ( ; count > 0; count--, sorted++ ) + { + hint2 = sorted[0]; + + if ( psh2_hint_overlap( hint, hint2 ) ) + { + hint->parent = hint2; + break; + } + } + } + + if ( table->num_hints < table->max_hints ) + table->sort_global[table->num_hints++] = hint; + else + FT_ERROR(( "%s.activate: too many sorted hints! BUG!\n", + "ps.fitter" )); + } + + + static void + psh2_hint_table_record_mask( PSH2_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit; + + + limit = hint_mask->num_bits; + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + psh2_hint_table_record( table, idx ); + + mask >>= 1; + } + } + + + /* create hints table */ + static FT_Error + psh2_hint_table_init( PSH2_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) + { + FT_UInt count = hints->num_hints; + FT_Error error; + + FT_UNUSED( counter_masks ); + + + /* allocate our tables */ + if ( FT_NEW_ARRAY( table->sort, 2 * count ) || + FT_NEW_ARRAY( table->hints, count ) || + FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) + goto Exit; + + table->max_hints = count; + table->sort_global = table->sort + count; + table->num_hints = 0; + table->num_zones = 0; + table->zone = 0; + + /* now, initialize the "hints" array */ + { + PSH2_Hint write = table->hints; + PS_Hint read = hints->hints; + + + for ( ; count > 0; count--, write++, read++ ) + { + write->org_pos = read->pos; + write->org_len = read->len; + write->flags = read->flags; + } + } + + /* we now need to determine the initial "parent" stems; first */ + /* activate the hints that are given by the initial hint masks */ + if ( hint_masks ) + { + FT_UInt Count = hint_masks->num_masks; + PS_Mask Mask = hint_masks->masks; + + + table->hint_masks = hint_masks; + + for ( ; Count > 0; Count--, Mask++ ) + psh2_hint_table_record_mask( table, Mask ); + } + + /* now, do a linear parse in case some hints were left alone */ + if ( table->num_hints != table->max_hints ) + { + FT_UInt Index, Count; + + + FT_ERROR(( "%s.init: missing/incorrect hint masks!\n" )); + Count = table->max_hints; + for ( Index = 0; Index < Count; Index++ ) + psh2_hint_table_record( table, Index ); + } + + Exit: + return error; + } + + + static void + psh2_hint_table_activate_mask( PSH2_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit, count; + + + limit = hint_mask->num_bits; + count = 0; + + psh2_hint_table_deactivate( table ); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + { + PSH2_Hint hint = &table->hints[idx]; + + + if ( !psh2_hint_is_active( hint ) ) + { + FT_UInt count2; + +#if 0 + PSH2_Hint* sort = table->sort; + PSH2_Hint hint2; + + for ( count2 = count; count2 > 0; count2--, sort++ ) + { + hint2 = sort[0]; + if ( psh2_hint_overlap( hint, hint2 ) ) + FT_ERROR(( "%s.activate_mask: found overlapping hints\n", + "psf.hint" )); + } +#else + count2 = 0; +#endif + + if ( count2 == 0 ) + { + psh2_hint_activate( hint ); + if ( count < table->max_hints ) + table->sort[count++] = hint; + else + FT_ERROR(( "%s.activate_mask: too many active hints\n", + "psf.hint" )); + } + } + } + + mask >>= 1; + } + table->num_hints = count; + + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ + { + FT_Int i1, i2; + PSH2_Hint hint1, hint2; + PSH2_Hint* sort = table->sort; + + + /* a simple bubble sort will do, since in 99% of cases, the hints */ + /* will be already sorted -- and the sort will be linear */ + for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + { + hint1 = sort[i1]; + for ( i2 = i1 - 1; i2 >= 0; i2-- ) + { + hint2 = sort[i2]; + + if ( hint2->org_pos < hint1->org_pos ) + break; + + sort[i2 + 1] = hint2; + sort[i2] = hint1; + } + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef DEBUG_HINTER + static void + ps2_simple_scale( PSH2_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int dimension ) + { + PSH2_Hint hint; + FT_UInt count; + + + for ( count = 0; count < table->max_hints; count++ ) + { + hint = table->hints + count; + + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + + if ( ps2_debug_hint_func ) + ps2_debug_hint_func( hint, dimension ); + } + } +#endif + + + static void + psh2_hint_align( PSH2_Hint hint, + PSH_Globals globals, + FT_Int dimension ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh2_hint_is_fitted(hint) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Pos fit_center; + FT_Pos fit_len; + + PSH_AlignmentRec align; + + + /* compute fitted width/height */ + fit_len = 0; + if ( hint->org_len ) + { + fit_len = psh_dimension_snap_width( dim, hint->org_len ); + if ( fit_len < 64 ) + fit_len = 64; + else + fit_len = ( fit_len + 32 ) & -64; + } + + hint->cur_len = fit_len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH2_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh2_hint_is_fitted( parent ) ) + psh2_hint_align( parent, globals, dimension ); + + par_org_center = parent->org_pos + ( parent->org_len / 2); + par_cur_center = parent->cur_pos + ( parent->cur_len / 2); + cur_org_center = hint->org_pos + ( hint->org_len / 2); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); +#if 0 + if ( cur_delta >= 0 ) + cur_delta = ( cur_delta + 16 ) & -64; + else + cur_delta = -( (-cur_delta + 16 ) & -64 ); +#endif + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + /* normal processing */ + if ( ( fit_len / 64 ) & 1 ) + { + /* odd number of pixels */ + fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; + } + else + { + /* even number of pixels */ + fit_center = ( pos + ( len >> 1 ) + 32 ) & -64; + } + + hint->cur_pos = fit_center - ( fit_len >> 1 ); + } + } + + psh2_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps2_debug_hint_func ) + ps2_debug_hint_func( hint, dimension ); +#endif + } + } + + + static void + psh2_hint_table_align_hints( PSH2_Hint_Table table, + PSH_Globals globals, + FT_Int dimension ) + { + PSH2_Hint hint; + FT_UInt count; + +#ifdef DEBUG_HINTER + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( ps_debug_no_vert_hints && dimension == 0 ) + { + ps2_simple_scale( table, scale, delta, dimension ); + return; + } + + if ( ps_debug_no_horz_hints && dimension == 1 ) + { + ps2_simple_scale( table, scale, delta, dimension ); + return; + } +#endif + + hint = table->hints; + count = table->max_hints; + + for ( ; count > 0; count--, hint++ ) + psh2_hint_align( hint, globals, dimension ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PSH2_ZONE_MIN -3200000 +#define PSH2_ZONE_MAX +3200000 + +#define xxDEBUG_ZONES + + +#ifdef DEBUG_ZONES + +#include <stdio.h> + + static void + psh2_print_zone( PSH2_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale/65536.0, + zone->delta/64.0, + zone->min, + zone->max ); + } + +#else + +#define psh2_print_zone( x ) do { } while ( 0 ) + +#endif + +#if 0 + /* setup interpolation zones once the hints have been grid-fitted */ + /* by the optimizer */ + static void + psh2_hint_table_setup_zones( PSH2_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta ) + { + FT_UInt count; + PSH2_Zone zone; + PSH2_Hint *sort, hint, hint2; + + + zone = table->zones; + + /* special case, no hints defined */ + if ( table->num_hints == 0 ) + { + zone->scale = scale; + zone->delta = delta; + zone->min = PSH2_ZONE_MIN; + zone->max = PSH2_ZONE_MAX; + + table->num_zones = 1; + table->zone = zone; + return; + } + + /* the first zone is before the first hint */ + /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */ + sort = table->sort; + hint = sort[0]; + + zone->scale = scale; + zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale ); + zone->min = PSH2_ZONE_MIN; + zone->max = hint->org_pos; + + psh2_print_zone( zone ); + + zone++; + + for ( count = table->num_hints; count > 0; count-- ) + { + FT_Fixed scale2; + + + if ( hint->org_len > 0 ) + { + /* setup a zone for inner-stem interpolation */ + /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */ + /* x' = x*s2 + x0' - x0*s2 */ + + scale2 = FT_DivFix( hint->cur_len, hint->org_len ); + zone->scale = scale2; + zone->min = hint->org_pos; + zone->max = hint->org_pos + hint->org_len; + zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 ); + + psh2_print_zone( zone ); + + zone++; + } + + if ( count == 1 ) + break; + + sort++; + hint2 = sort[0]; + + /* setup zone for inter-stem interpolation */ + /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */ + /* x' = x*s3 + x1' - x1*s3 */ + + scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len), + hint2->org_pos - (hint->org_pos + hint->org_len) ); + zone->scale = scale2; + zone->min = hint->org_pos + hint->org_len; + zone->max = hint2->org_pos; + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale2 ); + + psh2_print_zone( zone ); + + zone++; + + hint = hint2; + } + + /* the last zone */ + zone->scale = scale; + zone->min = hint->org_pos + hint->org_len; + zone->max = PSH2_ZONE_MAX; + zone->delta = hint->cur_pos + hint->cur_len - + FT_MulFix( zone->min, scale ); + + psh2_print_zone( zone ); + + zone++; + + table->num_zones = zone - table->zones; + table->zone = table->zones; + } +#endif + +#if 0 + /* tune a single coordinate with the current interpolation zones */ + static FT_Pos + psh2_hint_table_tune_coord( PSH2_Hint_Table table, + FT_Int coord ) + { + PSH2_Zone zone; + + + zone = table->zone; + + if ( coord < zone->min ) + { + do + { + if ( zone == table->zones ) + break; + + zone--; + + } while ( coord < zone->min ); + table->zone = zone; + } + else if ( coord > zone->max ) + { + do + { + if ( zone == table->zones + table->num_zones - 1 ) + break; + + zone++; + + } while ( coord > zone->max ); + table->zone = zone; + } + + return FT_MulFix( coord, zone->scale ) + zone->delta; + } +#endif + +#if 0 + /* tune a given outline with current interpolation zones */ + /* the function only works in a single dimension.. */ + static void + psh2_hint_table_tune_outline( PSH2_Hint_Table table, + FT_Outline* outline, + PSH_Globals globals, + FT_Int dimension ) + + { + FT_UInt count, first, last; + PS_Mask_Table hint_masks = table->hint_masks; + PS_Mask mask; + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( hint_masks && hint_masks->num_masks > 0 ) + { + first = 0; + mask = hint_masks->masks; + count = hint_masks->num_masks; + + for ( ; count > 0; count--, mask++ ) + { + last = mask->end_point; + + if ( last > first ) + { + FT_Vector* vec; + FT_Int count2; + + + psh2_hint_table_activate_mask( table, mask ); + psh2_hint_table_optimize( table, globals, outline, dimension ); + psh2_hint_table_setup_zones( table, scale, delta ); + last = mask->end_point; + + vec = outline->points + first; + count2 = last - first; + + for ( ; count2 > 0; count2--, vec++ ) + { + FT_Pos x, *px; + + + px = dimension ? &vec->y : &vec->x; + x = *px; + + *px = psh2_hint_table_tune_coord( table, (FT_Int)x ); + } + } + + first = last; + } + } + else /* no hints in this glyph, simply scale the outline */ + { + FT_Vector* vec; + + + vec = outline->points; + count = outline->n_points; + + if ( dimension == 0 ) + { + for ( ; count > 0; count--, vec++ ) + vec->x = FT_MulFix( vec->x, scale ) + delta; + } + else + { + for ( ; count > 0; count--, vec++ ) + vec->y = FT_MulFix( vec->y, scale ) + delta; + } + } + } +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTER GLYPH MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static int + psh2_point_is_extremum( PSH2_Point point ) + { + PSH2_Point before = point; + PSH2_Point after = point; + FT_Pos d_before; + FT_Pos d_after; + + + do + { + before = before->prev; + if ( before == point ) + return 0; + + d_before = before->org_u - point->org_u; + + } while ( d_before == 0 ); + + do + { + after = after->next; + if ( after == point ) + return 0; + + d_after = after->org_u - point->org_u; + + } while ( d_after == 0 ); + + return ( ( d_before > 0 && d_after > 0 ) || + ( d_before < 0 && d_after < 0 ) ); + } + + + static void + psh2_glyph_done( PSH2_Glyph glyph ) + { + FT_Memory memory = glyph->memory; + + + psh2_hint_table_done( &glyph->hint_tables[1], memory ); + psh2_hint_table_done( &glyph->hint_tables[0], memory ); + + FT_FREE( glyph->points ); + FT_FREE( glyph->contours ); + + glyph->num_points = 0; + glyph->num_contours = 0; + + glyph->memory = 0; + } + + + static int + psh2_compute_dir( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ax, ay; + int result = PSH2_DIR_NONE; + + + ax = ( dx >= 0 ) ? dx : -dx; + ay = ( dy >= 0 ) ? dy : -dy; + + if ( ay * 12 < ax ) + { + /* |dy| <<< |dx| means a near-horizontal segment */ + result = ( dx >= 0 ) ? PSH2_DIR_RIGHT : PSH2_DIR_LEFT; + } + else if ( ax * 12 < ay ) + { + /* |dx| <<< |dy| means a near-vertical segment */ + result = ( dy >= 0 ) ? PSH2_DIR_UP : PSH2_DIR_DOWN; + } + + return result; + } + + + static FT_Error + psh2_glyph_init( PSH2_Glyph glyph, + FT_Outline* outline, + PS_Hints ps_hints, + PSH_Globals globals ) + { + FT_Error error; + FT_Memory memory; + + + /* clear all fields */ + FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + + memory = globals->memory; + + /* allocate and setup points + contours arrays */ + if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || + FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) + goto Exit; + + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; + + { + FT_UInt first = 0, next, n; + PSH2_Point points = glyph->points; + PSH2_Contour contour = glyph->contours; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + FT_Int count; + PSH2_Point point; + + + next = outline->contours[n] + 1; + count = next - first; + + contour->start = points + first; + contour->count = (FT_UInt)count; + + if ( count > 0 ) + { + point = points + first; + + point->prev = points + next - 1; + point->contour = contour; + + for ( ; count > 1; count-- ) + { + point[0].next = point + 1; + point[1].prev = point; + point++; + point->contour = contour; + } + point->next = points + first; + } + + contour++; + first = next; + } + } + + { + PSH2_Point points = glyph->points; + PSH2_Point point = points; + FT_Vector* vec = outline->points; + FT_UInt n; + + + for ( n = 0; n < glyph->num_points; n++, point++ ) + { + FT_Int n_prev = point->prev - points; + FT_Int n_next = point->next - points; + FT_Pos dxi, dyi, dxo, dyo; + + + if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) + point->flags = PSH2_POINT_OFF; + + dxi = vec[n].x - vec[n_prev].x; + dyi = vec[n].y - vec[n_prev].y; + + point->dir_in = (FT_Char)psh2_compute_dir( dxi, dyi ); + + dxo = vec[n_next].x - vec[n].x; + dyo = vec[n_next].y - vec[n].y; + + point->dir_out = (FT_Char)psh2_compute_dir( dxo, dyo ); + + /* detect smooth points */ + if ( point->flags & PSH2_POINT_OFF ) + point->flags |= PSH2_POINT_SMOOTH; + else if ( point->dir_in != PSH2_DIR_NONE || + point->dir_out != PSH2_DIR_NONE ) + { + if ( point->dir_in == point->dir_out ) + point->flags |= PSH2_POINT_SMOOTH; + } + else + { + FT_Angle angle_in, angle_out, diff; + + + angle_in = FT_Atan2( dxi, dyi ); + angle_out = FT_Atan2( dxo, dyo ); + + diff = angle_in - angle_out; + if ( diff < 0 ) + diff = -diff; + + if ( diff > FT_ANGLE_PI ) + diff = FT_ANGLE_2PI - diff; + + if ( diff < FT_ANGLE_PI / 16 ) + point->flags |= PSH2_POINT_SMOOTH; + } + } + } + + glyph->memory = memory; + glyph->outline = outline; + glyph->globals = globals; + + /* now deal with hints tables */ + error = psh2_hint_table_init( &glyph->hint_tables [0], + &ps_hints->dimension[0].hints, + &ps_hints->dimension[0].masks, + &ps_hints->dimension[0].counters, + memory ); + if ( error ) + goto Exit; + + error = psh2_hint_table_init( &glyph->hint_tables [1], + &ps_hints->dimension[1].hints, + &ps_hints->dimension[1].masks, + &ps_hints->dimension[1].counters, + memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* load outline point coordinates into hinter glyph */ + static void + psh2_glyph_load_points( PSH2_Glyph glyph, + FT_Int dimension ) + { + FT_Vector* vec = glyph->outline->points; + PSH2_Point point = glyph->points; + FT_UInt count = glyph->num_points; + + + for ( ; count > 0; count--, point++, vec++ ) + { + point->flags &= PSH2_POINT_OFF | PSH2_POINT_SMOOTH; + point->hint = 0; + if ( dimension == 0 ) + point->org_u = vec->x; + else + point->org_u = vec->y; + +#ifdef DEBUG_HINTER + point->org_x = vec->x; + point->org_y = vec->y; +#endif + } + } + + + /* save hinted point coordinates back to outline */ + static void + psh2_glyph_save_points( PSH2_Glyph glyph, + FT_Int dimension ) + { + FT_UInt n; + PSH2_Point point = glyph->points; + FT_Vector* vec = glyph->outline->points; + char* tags = glyph->outline->tags; + + + for ( n = 0; n < glyph->num_points; n++ ) + { + if ( dimension == 0 ) + vec[n].x = point->cur_u; + else + vec[n].y = point->cur_u; + + if ( psh2_point_is_strong( point ) ) + tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); + +#ifdef DEBUG_HINTER + if ( dimension == 0 ) + { + point->cur_x = point->cur_u; + point->flags_x = point->flags; + } + else + { + point->cur_y = point->cur_u; + point->flags_y = point->flags; + } +#endif + point++; + } + } + + +#define PSH2_STRONG_THRESHOLD 10 + + + static void + psh2_hint_table_find_strong_point( PSH2_Hint_Table table, + PSH2_Point point, + FT_Int major_dir ) + { + PSH2_Hint* sort = table->sort; + FT_UInt num_hints = table->num_hints; + + + for ( ; num_hints > 0; num_hints--, sort++ ) + { + PSH2_Hint hint = sort[0]; + + + if ( ABS( point->dir_in ) == major_dir || + ABS( point->dir_out ) == major_dir ) + { + FT_Pos d; + + + d = point->org_u - hint->org_pos; + if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) + { + Is_Strong: + psh2_point_set_strong( point ); + point->hint = hint; + break; + } + + d -= hint->org_len; + if ( ABS( d ) < PSH2_STRONG_THRESHOLD ) + goto Is_Strong; + } + +#if 1 + if ( point->org_u >= hint->org_pos && + point->org_u <= hint->org_pos + hint->org_len && + psh2_point_is_extremum( point ) ) + { + /* attach to hint, but don't mark as strong */ + point->hint = hint; + break; + } +#endif + } + } + + + /* find strong points in a glyph */ + static void + psh2_glyph_find_strong_points( PSH2_Glyph glyph, + FT_Int dimension ) + { + /* a point is strong if it is located on a stem */ + /* edge and has an "in" or "out" tangent to the hint's direction */ + { + PSH2_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH2_DIR_UP : PSH2_DIR_RIGHT; + + + /* process secondary hints to "selected" points */ + if ( num_masks > 1 && glyph->num_points > 0 ) + { + first = mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) + { + FT_UInt next; + FT_Int count; + + + next = mask->end_point; + count = next - first; + if ( count > 0 ) + { + PSH2_Point point = glyph->points + first; + + + psh2_hint_table_activate_mask( table, mask ); + + for ( ; count > 0; count--, point++ ) + psh2_hint_table_find_strong_point( table, point, major_dir ); + } + first = next; + } + } + + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH2_Point point = glyph->points; + + + psh2_hint_table_activate_mask( table, table->hint_masks->masks ); + for ( ; count > 0; count--, point++ ) + { + if ( !psh2_point_is_strong( point ) ) + psh2_hint_table_find_strong_point( table, point, major_dir ); + } + } + + /* now, certain points may have been attached to hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH2_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh2_point_is_strong( point ) ) + psh2_point_set_strong( point ); + } + } + } + + + /* interpolate strong points with the help of hinted coordinates */ + static void + psh2_glyph_interpolate_strong_points( PSH2_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + + { + FT_UInt count = glyph->num_points; + PSH2_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + PSH2_Hint hint = point->hint; + + + if ( hint ) + { + FT_Pos delta; + + + delta = point->org_u - hint->org_pos; + + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); + + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else if ( hint->org_len > 0 ) + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, hint->org_len ); + else + point->cur_u = hint->cur_pos; + + psh2_point_set_fitted( point ); + } + } + } + } + + + static void + psh2_glyph_interpolate_normal_points( PSH2_Glyph glyph, + FT_Int dimension ) + { +#if 1 + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + + /* first technique: a point is strong if it is a local extrema */ + { + FT_UInt count = glyph->num_points; + PSH2_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + if ( psh2_point_is_strong( point ) ) + continue; + + /* sometimes, some local extremas are smooth points */ + if ( psh2_point_is_smooth( point ) ) + { + if ( point->dir_in == PSH2_DIR_NONE || + point->dir_in != point->dir_out ) + continue; + + if ( !psh2_point_is_extremum( point ) ) + continue; + + point->flags &= ~PSH2_POINT_SMOOTH; + } + + /* find best enclosing point coordinates */ + { + PSH2_Point before = 0; + PSH2_Point after = 0; + + FT_Pos diff_before = -32000; + FT_Pos diff_after = 32000; + FT_Pos u = point->org_u; + + FT_Int count2 = glyph->num_points; + PSH2_Point cur = glyph->points; + + + for ( ; count2 > 0; count2--, cur++ ) + { + if ( psh2_point_is_strong( cur ) ) + { + FT_Pos diff = cur->org_u - u;; + + + if ( diff <= 0 ) + { + if ( diff > diff_before ) + { + diff_before = diff; + before = cur; + } + } + else if ( diff >= 0 ) + { + if ( diff < diff_after ) + { + diff_after = diff; + after = cur; + } + } + } + } + + if ( !before ) + { + if ( !after ) + continue; + + /* we are before the first strong point coordinate; */ + /* simply translate the point */ + point->cur_u = after->cur_u + + FT_MulFix( point->org_u - after->org_u, scale ); + } + else if ( !after ) + { + /* we are after the last strong point coordinate; */ + /* simply translate the point */ + point->cur_u = before->cur_u + + FT_MulFix( point->org_u - before->org_u, scale ); + } + else + { + if ( diff_before == 0 ) + point->cur_u = before->cur_u; + + else if ( diff_after == 0 ) + point->cur_u = after->cur_u; + + else + point->cur_u = before->cur_u + + FT_MulDiv( u - before->org_u, + after->cur_u - before->cur_u, + after->org_u - before->org_u ); + } + + psh2_point_set_fitted( point ); + } + } + } +#endif + } + + + /* interpolate other points */ + static void + psh2_glyph_interpolate_other_points( PSH2_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + PSH2_Contour contour = glyph->contours; + FT_UInt num_contours = glyph->num_contours; + + + for ( ; num_contours > 0; num_contours--, contour++ ) + { + PSH2_Point start = contour->start; + PSH2_Point first, next, point; + FT_UInt fit_count; + + + /* count the number of strong points in this contour */ + next = start + contour->count; + fit_count = 0; + first = 0; + + for ( point = start; point < next; point++ ) + if ( psh2_point_is_fitted( point ) ) + { + if ( !first ) + first = point; + + fit_count++; + } + + /* if there are less than 2 fitted points in the contour, we */ + /* simply scale and eventually translate the contour points */ + if ( fit_count < 2 ) + { + if ( fit_count == 1 ) + delta = first->cur_u - FT_MulFix( first->org_u, scale ); + + for ( point = start; point < next; point++ ) + if ( point != first ) + point->cur_u = FT_MulFix( point->org_u, scale ) + delta; + + goto Next_Contour; + } + + /* there are more than 2 strong points in this contour; we */ + /* need to interpolate weak points between them */ + start = first; + do + { + point = first; + + /* skip consecutive fitted points */ + for (;;) + { + next = first->next; + if ( next == start ) + goto Next_Contour; + + if ( !psh2_point_is_fitted( next ) ) + break; + + first = next; + } + + /* find next fitted point after unfitted one */ + for (;;) + { + next = next->next; + if ( psh2_point_is_fitted( next ) ) + break; + } + + /* now interpolate between them */ + { + FT_Pos org_a, org_ab, cur_a, cur_ab; + FT_Pos org_c, org_ac, cur_c; + FT_Fixed scale_ab; + + + if ( first->org_u <= next->org_u ) + { + org_a = first->org_u; + cur_a = first->cur_u; + org_ab = next->org_u - org_a; + cur_ab = next->cur_u - cur_a; + } + else + { + org_a = next->org_u; + cur_a = next->cur_u; + org_ab = first->org_u - org_a; + cur_ab = first->cur_u - cur_a; + } + + scale_ab = 0x10000L; + if ( org_ab > 0 ) + scale_ab = FT_DivFix( cur_ab, org_ab ); + + point = first->next; + do + { + org_c = point->org_u; + org_ac = org_c - org_a; + + if ( org_ac <= 0 ) + { + /* on the left of the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale ); + } + else if ( org_ac >= org_ab ) + { + /* on the right on the interpolation zone */ + cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); + } + else + { + /* within the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); + } + + point->cur_u = cur_c; + + point = point->next; + + } while ( point != next ); + } + + /* keep going until all points in the contours have been processed */ + first = next; + + } while ( first != start ); + + Next_Contour: + ; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_Error + ps2_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + PSH2_GlyphRec glyphrec; + PSH2_Glyph glyph = &glyphrec; + FT_Error error; +#ifdef DEBUG_HINTER + FT_Memory memory; +#endif + FT_Int dimension; + + FT_UNUSED( hint_mode ); + +#ifdef DEBUG_HINTER + memory = globals->memory; + + if ( ps2_debug_glyph ) + { + psh2_glyph_done( ps2_debug_glyph ); + FT_FREE( ps2_debug_glyph ); + } + + if ( FT_NEW( glyph ) ) + return error; + + ps2_debug_glyph = glyph; +#endif + + error = psh2_glyph_init( glyph, outline, ps_hints, globals ); + if ( error ) + goto Exit; + + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh2_glyph_load_points( glyph, dimension ); + + /* compute aligned stem/hints positions */ + psh2_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension ); + + /* find strong points, align them, then interpolate others */ + psh2_glyph_find_strong_points( glyph, dimension ); + psh2_glyph_interpolate_strong_points( glyph, dimension ); + psh2_glyph_interpolate_normal_points( glyph, dimension ); + psh2_glyph_interpolate_other_points( glyph, dimension ); + + /* save hinted coordinates back to outline */ + psh2_glyph_save_points( glyph, dimension ); + } + + Exit: +#ifndef DEBUG_HINTER + psh2_glyph_done( glyph ); +#endif + return error; + } + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo2.h b/lib/freetype/src/pshinter/pshalgo2.h new file mode 100644 index 0000000..405d34b --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo2.h @@ -0,0 +1,203 @@ +/***************************************************************************/ +/* */ +/* pshalgo2.h */ +/* */ +/* PostScript hinting algorithm 2 (specification). */ +/* */ +/* Copyright 2001 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 __PSHALGO2_H__ +#define __PSHALGO2_H__ + + +#include "pshrec.h" +#include "pshglob.h" +#include FT_TRIGONOMETRY_H + + +FT_BEGIN_HEADER + + + typedef struct PSH2_HintRec_* PSH2_Hint; + + typedef enum + { + PSH2_HINT_GHOST = PS_HINT_FLAG_GHOST, + PSH2_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH2_HINT_ACTIVE = 4, + PSH2_HINT_FITTED = 8 + + } PSH2_Hint_Flags; + + +#define psh2_hint_is_active( x ) ( ( (x)->flags & PSH2_HINT_ACTIVE ) != 0 ) +#define psh2_hint_is_ghost( x ) ( ( (x)->flags & PSH2_HINT_GHOST ) != 0 ) +#define psh2_hint_is_fitted( x ) ( ( (x)->flags & PSH2_HINT_FITTED ) != 0 ) + +#define psh2_hint_activate( x ) (x)->flags |= PSH2_HINT_ACTIVE +#define psh2_hint_deactivate( x ) (x)->flags &= ~PSH2_HINT_ACTIVE +#define psh2_hint_set_fitted( x ) (x)->flags |= PSH2_HINT_FITTED + + + typedef struct PSH2_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + FT_UInt flags; + PSH2_Hint parent; + FT_Int order; + + } PSH2_HintRec; + + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH2_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH2_ZoneRec, *PSH2_Zone; + + + typedef struct PSH2_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH2_Hint hints; + PSH2_Hint* sort; + PSH2_Hint* sort_global; + FT_UInt num_zones; + PSH2_Zone zones; + PSH2_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH2_Hint_TableRec, *PSH2_Hint_Table; + + + typedef struct PSH2_PointRec_* PSH2_Point; + typedef struct PSH2_ContourRec_* PSH2_Contour; + + enum + { + PSH2_DIR_NONE = 4, + PSH2_DIR_UP = 1, + PSH2_DIR_DOWN = -1, + PSH2_DIR_LEFT = -2, + PSH2_DIR_RIGHT = 2 + }; + + enum + { + PSH2_POINT_OFF = 1, /* point is off the curve */ + PSH2_POINT_STRONG = 2, /* point is strong */ + PSH2_POINT_SMOOTH = 4, /* point is smooth */ + PSH2_POINT_FITTED = 8 /* point is already fitted */ + }; + + + typedef struct PSH2_PointRec_ + { + PSH2_Point prev; + PSH2_Point next; + PSH2_Contour contour; + FT_UInt flags; + FT_Char dir_in; + FT_Char dir_out; + FT_Angle angle_in; + FT_Angle angle_out; + PSH2_Hint hint; + FT_Pos org_u; + FT_Pos cur_u; +#ifdef DEBUG_HINTER + FT_Pos org_x; + FT_Pos cur_x; + FT_Pos org_y; + FT_Pos cur_y; + FT_UInt flags_x; + FT_UInt flags_y; +#endif + + } PSH2_PointRec; + + +#define psh2_point_is_strong( p ) ( (p)->flags & PSH2_POINT_STRONG ) +#define psh2_point_is_fitted( p ) ( (p)->flags & PSH2_POINT_FITTED ) +#define psh2_point_is_smooth( p ) ( (p)->flags & PSH2_POINT_SMOOTH ) + +#define psh2_point_set_strong( p ) (p)->flags |= PSH2_POINT_STRONG +#define psh2_point_set_fitted( p ) (p)->flags |= PSH2_POINT_FITTED +#define psh2_point_set_smooth( p ) (p)->flags |= PSH2_POINT_SMOOTH + + + typedef struct PSH2_ContourRec_ + { + PSH2_Point start; + FT_UInt count; + + } PSH2_ContourRec; + + + typedef struct PSH2_GlyphRec_ + { + FT_UInt num_points; + FT_UInt num_contours; + + PSH2_Point points; + PSH2_Contour contours; + + FT_Memory memory; + FT_Outline* outline; + PSH_Globals globals; + PSH2_Hint_TableRec hint_tables[2]; + + FT_Bool vertical; + FT_Int major_dir; + FT_Int minor_dir; + + } PSH2_GlyphRec, *PSH2_Glyph; + + +#ifdef DEBUG_HINTER + extern PSH2_Hint_Table ps2_debug_hint_table; + + typedef void + (*PSH2_HintFunc)( PSH2_Hint hint, + FT_Bool vertical ); + + extern PSH2_HintFunc ps2_debug_hint_func; + + extern PSH2_Glyph ps2_debug_glyph; +#endif + + + extern FT_Error + ps2_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + +FT_END_HEADER + + +#endif /* __PSHALGO2_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo3.c b/lib/freetype/src/pshinter/pshalgo3.c new file mode 100644 index 0000000..77f39bd --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo3.c @@ -0,0 +1,1958 @@ +/***************************************************************************/ +/* */ +/* pshalgo3.c */ +/* */ +/* PostScript hinting algorithm 3 (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include "pshalgo3.h" + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshalgo2 + + +#ifdef DEBUG_HINTER + PSH3_Hint_Table ps3_debug_hint_table = 0; + PSH3_HintFunc ps3_debug_hint_func = 0; + PSH3_Glyph ps3_debug_glyph = 0; +#endif + + +#define COMPUTE_INFLEXS /* compute inflection points to optimize "S" and others */ +#define STRONGER /* slightly increase the contrast of smooth hinting */ + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC HINTS RECORDINGS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* return true iff two stem hints overlap */ + static FT_Int + psh3_hint_overlap( PSH3_Hint hint1, + PSH3_Hint hint2 ) + { + return ( hint1->org_pos + hint1->org_len >= hint2->org_pos && + hint2->org_pos + hint2->org_len >= hint1->org_pos ); + } + + + /* destroy hints table */ + static void + psh3_hint_table_done( PSH3_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->zones ); + table->num_zones = 0; + table->zone = 0; + + FT_FREE( table->sort ); + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + table->sort_global = 0; + } + + + /* deactivate all hints in a table */ + static void + psh3_hint_table_deactivate( PSH3_Hint_Table table ) + { + FT_UInt count = table->max_hints; + PSH3_Hint hint = table->hints; + + + for ( ; count > 0; count--, hint++ ) + { + psh3_hint_deactivate( hint ); + hint->order = -1; + } + } + + + /* internal function used to record a new hint */ + static void + psh3_hint_table_record( PSH3_Hint_Table table, + FT_UInt idx ) + { + PSH3_Hint hint = table->hints + idx; + + + if ( idx >= table->max_hints ) + { + FT_ERROR(( "psh3_hint_table_record: invalid hint index %d\n", idx )); + return; + } + + /* ignore active hints */ + if ( psh3_hint_is_active( hint ) ) + return; + + psh3_hint_activate( hint ); + + /* now scan the current active hint set in order to determine */ + /* if we are overlapping with another segment */ + { + PSH3_Hint* sorted = table->sort_global; + FT_UInt count = table->num_hints; + PSH3_Hint hint2; + + + hint->parent = 0; + for ( ; count > 0; count--, sorted++ ) + { + hint2 = sorted[0]; + + if ( psh3_hint_overlap( hint, hint2 ) ) + { + hint->parent = hint2; + break; + } + } + } + + if ( table->num_hints < table->max_hints ) + table->sort_global[table->num_hints++] = hint; + else + FT_ERROR(( "psh3_hint_table_record: too many sorted hints! BUG!\n" )); + } + + + static void + psh3_hint_table_record_mask( PSH3_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit; + + + limit = hint_mask->num_bits; + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + psh3_hint_table_record( table, idx ); + + mask >>= 1; + } + } + + + /* create hints table */ + static FT_Error + psh3_hint_table_init( PSH3_Hint_Table table, + PS_Hint_Table hints, + PS_Mask_Table hint_masks, + PS_Mask_Table counter_masks, + FT_Memory memory ) + { + FT_UInt count = hints->num_hints; + FT_Error error; + + FT_UNUSED( counter_masks ); + + + /* allocate our tables */ + if ( FT_NEW_ARRAY( table->sort, 2 * count ) || + FT_NEW_ARRAY( table->hints, count ) || + FT_NEW_ARRAY( table->zones, 2 * count + 1 ) ) + goto Exit; + + table->max_hints = count; + table->sort_global = table->sort + count; + table->num_hints = 0; + table->num_zones = 0; + table->zone = 0; + + /* now, initialize the "hints" array */ + { + PSH3_Hint write = table->hints; + PS_Hint read = hints->hints; + + + for ( ; count > 0; count--, write++, read++ ) + { + write->org_pos = read->pos; + write->org_len = read->len; + write->flags = read->flags; + } + } + + /* we now need to determine the initial "parent" stems; first */ + /* activate the hints that are given by the initial hint masks */ + if ( hint_masks ) + { + FT_UInt Count = hint_masks->num_masks; + PS_Mask Mask = hint_masks->masks; + + + table->hint_masks = hint_masks; + + for ( ; Count > 0; Count--, Mask++ ) + psh3_hint_table_record_mask( table, Mask ); + } + + /* now, do a linear parse in case some hints were left alone */ + if ( table->num_hints != table->max_hints ) + { + FT_UInt Index, Count; + + + FT_ERROR(( "psh3_hint_table_init: missing/incorrect hint masks!\n" )); + Count = table->max_hints; + for ( Index = 0; Index < Count; Index++ ) + psh3_hint_table_record( table, Index ); + } + + Exit: + return error; + } + + + static void + psh3_hint_table_activate_mask( PSH3_Hint_Table table, + PS_Mask hint_mask ) + { + FT_Int mask = 0, val = 0; + FT_Byte* cursor = hint_mask->bytes; + FT_UInt idx, limit, count; + + + limit = hint_mask->num_bits; + count = 0; + + psh3_hint_table_deactivate( table ); + + for ( idx = 0; idx < limit; idx++ ) + { + if ( mask == 0 ) + { + val = *cursor++; + mask = 0x80; + } + + if ( val & mask ) + { + PSH3_Hint hint = &table->hints[idx]; + + + if ( !psh3_hint_is_active( hint ) ) + { + FT_UInt count2; + +#if 0 + PSH3_Hint* sort = table->sort; + PSH3_Hint hint2; + + + for ( count2 = count; count2 > 0; count2--, sort++ ) + { + hint2 = sort[0]; + if ( psh3_hint_overlap( hint, hint2 ) ) + FT_ERROR(( "psh3_hint_table_activate_mask:" + " found overlapping hints\n" )) + } +#else + count2 = 0; +#endif + + if ( count2 == 0 ) + { + psh3_hint_activate( hint ); + if ( count < table->max_hints ) + table->sort[count++] = hint; + else + FT_ERROR(( "psh3_hint_tableactivate_mask:" + " too many active hints\n" )); + } + } + } + + mask >>= 1; + } + table->num_hints = count; + + /* now, sort the hints; they are guaranteed to not overlap */ + /* so we can compare their "org_pos" field directly */ + { + FT_Int i1, i2; + PSH3_Hint hint1, hint2; + PSH3_Hint* sort = table->sort; + + + /* a simple bubble sort will do, since in 99% of cases, the hints */ + /* will be already sorted -- and the sort will be linear */ + for ( i1 = 1; i1 < (FT_Int)count; i1++ ) + { + hint1 = sort[i1]; + for ( i2 = i1 - 1; i2 >= 0; i2-- ) + { + hint2 = sort[i2]; + + if ( hint2->org_pos < hint1->org_pos ) + break; + + sort[i2 + 1] = hint2; + sort[i2] = hint1; + } + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTS GRID-FITTING AND OPTIMIZATION *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 1 + static FT_Pos + psh3_dimension_quantize_len( PSH_Dimension dim, + FT_Pos len, + FT_Bool do_snapping ) + { + if ( len <= 64 ) + len = 64; + else + { + FT_Pos delta = len - dim->stdw.widths[0].cur; + + + if ( delta < 0 ) + delta = -delta; + + if ( delta < 40 ) + { + len = dim->stdw.widths[0].cur; + if ( len < 48 ) + len = 48; + } + + if ( len < 3 * 64 ) + { + delta = ( len & 63 ); + len &= -64; + + if ( delta < 10 ) + len += delta; + + else if ( delta < 32 ) + len += 10; + + else if ( delta < 54 ) + len += 54; + + else + len += delta; + } + else + len = ( len + 32 ) & -64; + } + + if ( do_snapping ) + len = ( len + 32 ) & -64; + + return len; + } +#endif /* 0 */ + + +#ifdef DEBUG_HINTER + + static void + ps3_simple_scale( PSH3_Hint_Table table, + FT_Fixed scale, + FT_Fixed delta, + FT_Int dimension ) + { + PSH3_Hint hint; + FT_UInt count; + + + for ( count = 0; count < table->max_hints; count++ ) + { + hint = table->hints + count; + + hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; + hint->cur_len = FT_MulFix( hint->org_len, scale ); + + if ( ps3_debug_hint_func ) + ps3_debug_hint_func( hint, dimension ); + } + } + +#endif /* DEBUG_HINTER */ + + + static FT_Fixed + psh3_hint_snap_stem_side_delta( FT_Fixed pos, + FT_Fixed len ) + { + FT_Fixed delta1 = ( ( pos + 32 ) & -64 ) - pos; + FT_Fixed delta2 = ( ( pos + len + 32 ) & -64 ) - pos - len; + + + if ( ABS( delta1 ) <= ABS( delta2 ) ) + return delta1; + else + return delta2; + } + + + static void + psh3_hint_align( PSH3_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH3_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh3_hint_is_fitted( hint ) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Int do_snapping; + FT_Pos fit_len; + PSH_AlignmentRec align; + + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh3_hint_set_fitted( hint ); + return; + } + + /* perform stem snapping when requested - this is necessary + * for monochrome and LCD hinting modes only + */ + do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) || + ( dimension == 1 && glyph->do_vert_snapping ); + + hint->cur_len = fit_len = len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH3_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh3_hint_is_fitted( parent ) ) + psh3_hint_align( parent, globals, dimension, glyph ); + + par_org_center = parent->org_pos + ( parent->org_len >> 1 ); + par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 ); + cur_org_center = hint->org_pos + ( hint->org_len >> 1 ); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + hint->cur_pos = pos; + hint->cur_len = fit_len; + + /* stem adjustment tries to snap stem widths to standard + * ones. this is important to prevent unpleasant rounding + * artefacts... + */ + if ( glyph->do_stem_adjust ) + { + if ( len <= 64 ) + { + /* the stem is less than one pixel, we will center it + * around the nearest pixel center + */ +#if 1 + pos = ( pos + (len >> 1) ) & -64; +#else + /* this seems to be a bug !! */ + pos = ( pos + ( (len >> 1) & -64 ) ); +#endif + len = 64; + } + else + { + len = psh3_dimension_quantize_len( dim, len, 0 ); + } + } + + /* now that we have a good hinted stem width, try to position */ + /* the stem along a pixel grid integer coordinate */ + hint->cur_pos = pos + psh3_hint_snap_stem_side_delta( pos, len ); + hint->cur_len = len; + } + } + + if ( do_snapping ) + { + pos = hint->cur_pos; + len = hint->cur_len; + + if ( len < 64 ) + len = 64; + else + len = ( len + 32 ) & -64; + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + hint->cur_pos = align.align_top - len; + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT: + hint->cur_len = len; + break; + + case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP: + /* don't touch */ + break; + + + default: + hint->cur_len = len; + if ( len & 64 ) + pos = ( ( pos + ( len >> 1 ) ) & -64 ) + 32; + else + pos = ( pos + ( len >> 1 ) + 32 ) & -64; + + hint->cur_pos = pos - ( len >> 1 ); + hint->cur_len = len; + } + } + + psh3_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps3_debug_hint_func ) + ps3_debug_hint_func( hint, dimension ); +#endif + } + } + + +#if 0 /* not used for now, experimental */ + + /* + * A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT) + * of stems + */ + static void + psh3_hint_align_light( PSH3_Hint hint, + PSH_Globals globals, + FT_Int dimension, + PSH3_Glyph glyph ) + { + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( !psh3_hint_is_fitted(hint) ) + { + FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; + FT_Pos len = FT_MulFix( hint->org_len, scale ); + + FT_Pos fit_len; + + PSH_AlignmentRec align; + + /* ignore stem alignments when requested through the hint flags */ + if ( ( dimension == 0 && !glyph->do_horz_hints ) || + ( dimension == 1 && !glyph->do_vert_hints ) ) + { + hint->cur_pos = pos; + hint->cur_len = len; + + psh3_hint_set_fitted( hint ); + return; + } + + fit_len = len; + + hint->cur_len = fit_len; + + /* check blue zones for horizontal stems */ + align.align = PSH_BLUE_ALIGN_NONE; + align.align_bot = align.align_top = 0; + + if ( dimension == 1 ) + psh_blues_snap_stem( &globals->blues, + hint->org_pos + hint->org_len, + hint->org_pos, + &align ); + + switch ( align.align ) + { + case PSH_BLUE_ALIGN_TOP: + /* the top of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_top - fit_len; + break; + + case PSH_BLUE_ALIGN_BOT: + /* the bottom of the stem is aligned against a blue zone */ + hint->cur_pos = align.align_bot; + break; + + case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: + /* both edges of the stem are aligned against blue zones */ + hint->cur_pos = align.align_bot; + hint->cur_len = align.align_top - align.align_bot; + break; + + default: + { + PSH3_Hint parent = hint->parent; + + + if ( parent ) + { + FT_Pos par_org_center, par_cur_center; + FT_Pos cur_org_center, cur_delta; + + + /* ensure that parent is already fitted */ + if ( !psh3_hint_is_fitted( parent ) ) + psh3_hint_align_light( parent, globals, dimension, glyph ); + + par_org_center = parent->org_pos + ( parent->org_len / 2); + par_cur_center = parent->cur_pos + ( parent->cur_len / 2); + cur_org_center = hint->org_pos + ( hint->org_len / 2); + + cur_delta = FT_MulFix( cur_org_center - par_org_center, scale ); + pos = par_cur_center + cur_delta - ( len >> 1 ); + } + + /* Stems less than one pixel wide are easy - we want to + * make them as dark as possible, so they must fall within + * one pixel. If the stem is split between two pixels + * then snap the edge that is nearer to the pixel boundary + * to the pixel boundary + */ + if (len <= 64) + { + if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 ) + pos += psh3_hint_snap_stem_side_delta ( pos, len ); + } + /* Position stems other to minimize the amount of mid-grays. + * There are, in general, two positions that do this, + * illustrated as A) and B) below. + * + * + + + + + * + * A) |--------------------------------| + * B) |--------------------------------| + * C) |--------------------------------| + * + * Position A) (split the excess stem equally) should be better + * for stems of width N + f where f < 0.5 + * + * Position B) (split the deficiency equally) should be better + * for stems of width N + f where f > 0.5 + * + * It turns out though that minimizing the total number of lit + * pixels is also important, so position C), with one edge + * aligned with a pixel boundary is actually preferable + * to A). There are also more possibile positions for C) than + * for A) or B), so it involves less distortion of the overall + * character shape. + */ + else /* len > 64 */ + { + FT_Fixed frac_len = len & 63; + FT_Fixed center = pos + ( len >> 1 ); + FT_Fixed delta_a, delta_b; + + if ( ( len / 64 ) & 1 ) + { + delta_a = ( center & -64 ) + 32 - center; + delta_b = ( ( center + 32 ) & - 64 ) - center; + } + else + { + delta_a = ( ( center + 32 ) & - 64 ) - center; + delta_b = ( center & -64 ) + 32 - center; + } + + /* We choose between B) and C) above based on the amount + * of fractinal stem width; for small amounts, choose + * C) always, for large amounts, B) always, and inbetween, + * pick whichever one involves less stem movement. + */ + if (frac_len < 32) + { + pos += psh3_hint_snap_stem_side_delta ( pos, len ); + } + else if (frac_len < 48) + { + FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len ); + + if ( ABS( side_delta ) < ABS( delta_b ) ) + pos += side_delta; + else + pos += delta_b; + } + else + { + pos += delta_b; + } + } + + hint->cur_pos = pos; + } + } /* switch */ + + psh3_hint_set_fitted( hint ); + +#ifdef DEBUG_HINTER + if ( ps3_debug_hint_func ) + ps3_debug_hint_func( hint, dimension ); +#endif + } + } + +#endif /* 0 */ + + + static void + psh3_hint_table_align_hints( PSH3_Hint_Table table, + PSH_Globals globals, + FT_Int dimension, + PSH3_Glyph glyph ) + { + PSH3_Hint hint; + FT_UInt count; + +#ifdef DEBUG_HINTER + + PSH_Dimension dim = &globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + + + if ( ps_debug_no_vert_hints && dimension == 0 ) + { + ps3_simple_scale( table, scale, delta, dimension ); + return; + } + + if ( ps_debug_no_horz_hints && dimension == 1 ) + { + ps3_simple_scale( table, scale, delta, dimension ); + return; + } + +#endif /* DEBUG_HINTER*/ + + hint = table->hints; + count = table->max_hints; + + for ( ; count > 0; count--, hint++ ) + psh3_hint_align( hint, globals, dimension, glyph ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** POINTS INTERPOLATION ROUTINES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PSH3_ZONE_MIN -3200000L +#define PSH3_ZONE_MAX +3200000L + +#define xxDEBUG_ZONES + + +#ifdef DEBUG_ZONES + +#include <stdio.h> + + static void + psh3_print_zone( PSH3_Zone zone ) + { + printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + zone->scale / 65536.0, + zone->delta / 64.0, + zone->min, + zone->max ); + } + +#else + +#define psh3_print_zone( x ) do { } while ( 0 ) + +#endif /* DEBUG_ZONES */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HINTER GLYPH MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#ifdef COMPUTE_INFLEXS + + /* compute all inflex points in a given glyph */ + static void + psh3_glyph_compute_inflections( PSH3_Glyph glyph ) + { + FT_UInt n; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH3_Point first, start, end, before, after; + FT_Angle angle_in, angle_seg, angle_out; + FT_Angle diff_in, diff_out; + FT_Int finished = 0; + + + /* we need at least 4 points to create an inflection point */ + if ( glyph->contours[n].count < 4 ) + continue; + + /* compute first segment in contour */ + first = glyph->contours[n].start; + + start = end = first; + do + { + end = end->next; + if ( end == first ) + goto Skip; + + } while ( PSH3_POINT_EQUAL_ORG( end, first ) ); + + angle_seg = PSH3_POINT_ANGLE( start, end ); + + /* extend the segment start whenever possible */ + before = start; + do + { + do + { + start = before; + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( PSH3_POINT_EQUAL_ORG( before, start ) ); + + angle_in = PSH3_POINT_ANGLE( before, start ); + + } while ( angle_in == angle_seg ); + + first = start; + diff_in = FT_Angle_Diff( angle_in, angle_seg ); + + /* now, process all segments in the contour */ + do + { + /* first, extend current segment's end whenever possible */ + after = end; + do + { + do + { + end = after; + after = after->next; + if ( after == first ) + finished = 1; + + } while ( PSH3_POINT_EQUAL_ORG( end, after ) ); + + angle_out = PSH3_POINT_ANGLE( end, after ); + + } while ( angle_out == angle_seg ); + + diff_out = FT_Angle_Diff( angle_seg, angle_out ); + + if ( ( diff_in ^ diff_out ) < 0 ) + { + /* diff_in and diff_out have different signs, we have */ + /* inflection points here... */ + + do + { + psh3_point_set_inflex( start ); + start = start->next; + } + while ( start != end ); + + psh3_point_set_inflex( start ); + } + + start = end; + end = after; + angle_seg = angle_out; + diff_in = diff_out; + + } while ( !finished ); + + Skip: + ; + } + } + +#endif /* COMPUTE_INFLEXS */ + + + static void + psh3_glyph_done( PSH3_Glyph glyph ) + { + FT_Memory memory = glyph->memory; + + + psh3_hint_table_done( &glyph->hint_tables[1], memory ); + psh3_hint_table_done( &glyph->hint_tables[0], memory ); + + FT_FREE( glyph->points ); + FT_FREE( glyph->contours ); + + glyph->num_points = 0; + glyph->num_contours = 0; + + glyph->memory = 0; + } + + + static int + psh3_compute_dir( FT_Pos dx, + FT_Pos dy ) + { + FT_Pos ax, ay; + int result = PSH3_DIR_NONE; + + + ax = ( dx >= 0 ) ? dx : -dx; + ay = ( dy >= 0 ) ? dy : -dy; + + if ( ay * 12 < ax ) + { + /* |dy| <<< |dx| means a near-horizontal segment */ + result = ( dx >= 0 ) ? PSH3_DIR_RIGHT : PSH3_DIR_LEFT; + } + else if ( ax * 12 < ay ) + { + /* |dx| <<< |dy| means a near-vertical segment */ + result = ( dy >= 0 ) ? PSH3_DIR_UP : PSH3_DIR_DOWN; + } + + return result; + } + + + /* load outline point coordinates into hinter glyph */ + static void + psh3_glyph_load_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + FT_Vector* vec = glyph->outline->points; + PSH3_Point point = glyph->points; + FT_UInt count = glyph->num_points; + + + for ( ; count > 0; count--, point++, vec++ ) + { + point->flags2 = 0; + point->hint = NULL; + if ( dimension == 0 ) + { + point->org_u = vec->x; + point->org_v = vec->y; + } + else + { + point->org_u = vec->y; + point->org_v = vec->x; + } + +#ifdef DEBUG_HINTER + point->org_x = vec->x; + point->org_y = vec->y; +#endif + + } + } + + + /* save hinted point coordinates back to outline */ + static void + psh3_glyph_save_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + FT_UInt n; + PSH3_Point point = glyph->points; + FT_Vector* vec = glyph->outline->points; + char* tags = glyph->outline->tags; + + + for ( n = 0; n < glyph->num_points; n++ ) + { + if ( dimension == 0 ) + vec[n].x = point->cur_u; + else + vec[n].y = point->cur_u; + + if ( psh3_point_is_strong( point ) ) + tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 ); + +#ifdef DEBUG_HINTER + + if ( dimension == 0 ) + { + point->cur_x = point->cur_u; + point->flags_x = point->flags2 | point->flags; + } + else + { + point->cur_y = point->cur_u; + point->flags_y = point->flags2 | point->flags; + } + +#endif + + point++; + } + } + + + static FT_Error + psh3_glyph_init( PSH3_Glyph glyph, + FT_Outline* outline, + PS_Hints ps_hints, + PSH_Globals globals ) + { + FT_Error error; + FT_Memory memory; + + + /* clear all fields */ + FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + + memory = globals->memory; + + /* allocate and setup points + contours arrays */ + if ( FT_NEW_ARRAY( glyph->points, outline->n_points ) || + FT_NEW_ARRAY( glyph->contours, outline->n_contours ) ) + goto Exit; + + glyph->num_points = outline->n_points; + glyph->num_contours = outline->n_contours; + + { + FT_UInt first = 0, next, n; + PSH3_Point points = glyph->points; + PSH3_Contour contour = glyph->contours; + + + for ( n = 0; n < glyph->num_contours; n++ ) + { + FT_Int count; + PSH3_Point point; + + + next = outline->contours[n] + 1; + count = next - first; + + contour->start = points + first; + contour->count = (FT_UInt)count; + + if ( count > 0 ) + { + point = points + first; + + point->prev = points + next - 1; + point->contour = contour; + + for ( ; count > 1; count-- ) + { + point[0].next = point + 1; + point[1].prev = point; + point++; + point->contour = contour; + } + point->next = points + first; + } + + contour++; + first = next; + } + } + + { + PSH3_Point points = glyph->points; + PSH3_Point point = points; + FT_Vector* vec = outline->points; + FT_UInt n; + + + for ( n = 0; n < glyph->num_points; n++, point++ ) + { + FT_Int n_prev = point->prev - points; + FT_Int n_next = point->next - points; + FT_Pos dxi, dyi, dxo, dyo; + + + if ( !( outline->tags[n] & FT_CURVE_TAG_ON ) ) + point->flags = PSH3_POINT_OFF; + + dxi = vec[n].x - vec[n_prev].x; + dyi = vec[n].y - vec[n_prev].y; + + point->dir_in = (FT_Char)psh3_compute_dir( dxi, dyi ); + + dxo = vec[n_next].x - vec[n].x; + dyo = vec[n_next].y - vec[n].y; + + point->dir_out = (FT_Char)psh3_compute_dir( dxo, dyo ); + + /* detect smooth points */ + if ( point->flags & PSH3_POINT_OFF ) + point->flags |= PSH3_POINT_SMOOTH; + else if ( point->dir_in != PSH3_DIR_NONE || + point->dir_out != PSH3_DIR_NONE ) + { + if ( point->dir_in == point->dir_out ) + point->flags |= PSH3_POINT_SMOOTH; + } + else + { + FT_Angle angle_in, angle_out, diff; + + + angle_in = FT_Atan2( dxi, dyi ); + angle_out = FT_Atan2( dxo, dyo ); + + diff = angle_in - angle_out; + if ( diff < 0 ) + diff = -diff; + + if ( diff > FT_ANGLE_PI ) + diff = FT_ANGLE_2PI - diff; + + if ( diff < FT_ANGLE_PI / 16 ) + point->flags |= PSH3_POINT_SMOOTH; + } + } + } + + glyph->memory = memory; + glyph->outline = outline; + glyph->globals = globals; + +#ifdef COMPUTE_INFLEXS + psh3_glyph_load_points( glyph, 0 ); + psh3_glyph_compute_inflections( glyph ); +#endif /* COMPUTE_INFLEXS */ + + /* now deal with hints tables */ + error = psh3_hint_table_init( &glyph->hint_tables [0], + &ps_hints->dimension[0].hints, + &ps_hints->dimension[0].masks, + &ps_hints->dimension[0].counters, + memory ); + if ( error ) + goto Exit; + + error = psh3_hint_table_init( &glyph->hint_tables [1], + &ps_hints->dimension[1].hints, + &ps_hints->dimension[1].masks, + &ps_hints->dimension[1].counters, + memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* compute all extrema in a glyph for a given dimension */ + static void + psh3_glyph_compute_extrema( PSH3_Glyph glyph ) + { + FT_UInt n; + + + /* first of all, compute all local extrema */ + for ( n = 0; n < glyph->num_contours; n++ ) + { + PSH3_Point first = glyph->contours[n].start; + PSH3_Point point, before, after; + + + point = first; + before = point; + after = point; + + do + { + before = before->prev; + if ( before == first ) + goto Skip; + + } while ( before->org_u == point->org_u ); + + first = point = before->next; + + for (;;) + { + after = point; + do + { + after = after->next; + if ( after == first ) + goto Next; + + } while ( after->org_u == point->org_u ); + + if ( before->org_u < point->org_u ) + { + if ( after->org_u < point->org_u ) + { + /* local maximum */ + goto Extremum; + } + } + else /* before->org_u > point->org_u */ + { + if ( after->org_u > point->org_u ) + { + /* local minimum */ + Extremum: + do + { + psh3_point_set_extremum( point ); + point = point->next; + + } while ( point != after ); + } + } + + before = after->prev; + point = after; + + } /* for */ + + Next: + ; + } + + /* for each extrema, determine its direction along the */ + /* orthogonal axis */ + for ( n = 0; n < glyph->num_points; n++ ) + { + PSH3_Point point, before, after; + + + point = &glyph->points[n]; + before = point; + after = point; + + if ( psh3_point_is_extremum( point ) ) + { + do + { + before = before->prev; + if ( before == point ) + goto Skip; + + } while ( before->org_v == point->org_v ); + + do + { + after = after->next; + if ( after == point ) + goto Skip; + + } while ( after->org_v == point->org_v ); + } + + if ( before->org_v < point->org_v && + after->org_v > point->org_v ) + { + psh3_point_set_positive( point ); + } + else if ( before->org_v > point->org_v && + after->org_v < point->org_v ) + { + psh3_point_set_negative( point ); + } + + Skip: + ; + } + } + + +#define PSH3_STRONG_THRESHOLD 30 + + + /* major_dir is the direction for points on the bottom/left of the stem; */ + /* Points on the top/right of the stem will have a direction of */ + /* -major_dir. */ + + static void + psh3_hint_table_find_strong_point( PSH3_Hint_Table table, + PSH3_Point point, + FT_Int major_dir ) + { + PSH3_Hint* sort = table->sort; + FT_UInt num_hints = table->num_hints; + FT_Int point_dir = 0; + + + if ( PSH3_DIR_COMPARE( point->dir_in, major_dir ) ) + point_dir = point->dir_in; + + else if ( PSH3_DIR_COMPARE( point->dir_out, major_dir ) ) + point_dir = point->dir_out; + + if ( point_dir ) + { + FT_UInt flag; + + + for ( ; num_hints > 0; num_hints--, sort++ ) + { + PSH3_Hint hint = sort[0]; + FT_Pos d; + + + if ( point_dir == major_dir ) + { + flag = PSH3_POINT_EDGE_MIN; + d = point->org_u - hint->org_pos; + + if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + { + Is_Strong: + psh3_point_set_strong( point ); + point->flags2 |= flag; + point->hint = hint; + break; + } + } + else if ( point_dir == -major_dir ) + { + flag = PSH3_POINT_EDGE_MAX; + d = point->org_u - hint->org_pos - hint->org_len; + + if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + goto Is_Strong; + } + } + } + +#if 1 + else if ( psh3_point_is_extremum( point ) ) + { + /* treat extrema as special cases for stem edge alignment */ + FT_UInt min_flag, max_flag; + + + if ( major_dir == PSH3_DIR_HORIZONTAL ) + { + min_flag = PSH3_POINT_POSITIVE; + max_flag = PSH3_POINT_NEGATIVE; + } + else + { + min_flag = PSH3_POINT_NEGATIVE; + max_flag = PSH3_POINT_POSITIVE; + } + + for ( ; num_hints > 0; num_hints--, sort++ ) + { + PSH3_Hint hint = sort[0]; + FT_Pos d, flag; + + + if ( point->flags2 & min_flag ) + { + flag = PSH3_POINT_EDGE_MIN; + d = point->org_u - hint->org_pos; + + if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + { + Is_Strong2: + point->flags2 |= flag; + point->hint = hint; + psh3_point_set_strong( point ); + break; + } + } + else if ( point->flags2 & max_flag ) + { + flag = PSH3_POINT_EDGE_MAX; + d = point->org_u - hint->org_pos - hint->org_len; + + if ( ABS( d ) < PSH3_STRONG_THRESHOLD ) + goto Is_Strong2; + } + + if ( point->org_u >= hint->org_pos && + point->org_u <= hint->org_pos + hint->org_len ) + { + point->hint = hint; + } + } + } + +#endif /* 1 */ + } + + + /* find strong points in a glyph */ + static void + psh3_glyph_find_strong_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + /* a point is strong if it is located on a stem */ + /* edge and has an "in" or "out" tangent to the hint's direction */ + { + PSH3_Hint_Table table = &glyph->hint_tables[dimension]; + PS_Mask mask = table->hint_masks->masks; + FT_UInt num_masks = table->hint_masks->num_masks; + FT_UInt first = 0; + FT_Int major_dir = dimension == 0 ? PSH3_DIR_VERTICAL + : PSH3_DIR_HORIZONTAL; + + + /* process secondary hints to "selected" points */ + if ( num_masks > 1 && glyph->num_points > 0 ) + { + first = mask->end_point; + mask++; + for ( ; num_masks > 1; num_masks--, mask++ ) + { + FT_UInt next; + FT_Int count; + + + next = mask->end_point; + count = next - first; + if ( count > 0 ) + { + PSH3_Point point = glyph->points + first; + + + psh3_hint_table_activate_mask( table, mask ); + + for ( ; count > 0; count--, point++ ) + psh3_hint_table_find_strong_point( table, point, major_dir ); + } + first = next; + } + } + + /* process primary hints for all points */ + if ( num_masks == 1 ) + { + FT_UInt count = glyph->num_points; + PSH3_Point point = glyph->points; + + + psh3_hint_table_activate_mask( table, table->hint_masks->masks ); + for ( ; count > 0; count--, point++ ) + { + if ( !psh3_point_is_strong( point ) ) + psh3_hint_table_find_strong_point( table, point, major_dir ); + } + } + + /* now, certain points may have been attached to hint and */ + /* not marked as strong; update their flags then */ + { + FT_UInt count = glyph->num_points; + PSH3_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + if ( point->hint && !psh3_point_is_strong( point ) ) + psh3_point_set_strong( point ); + } + } + } + + + /* interpolate strong points with the help of hinted coordinates */ + static void + psh3_glyph_interpolate_strong_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + + { + FT_UInt count = glyph->num_points; + PSH3_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + PSH3_Hint hint = point->hint; + + + if ( hint ) + { + FT_Pos delta; + + + if ( psh3_point_is_edge_min( point ) ) + { + point->cur_u = hint->cur_pos; + } + else if ( psh3_point_is_edge_max( point ) ) + { + point->cur_u = hint->cur_pos + hint->cur_len; + } + else + { + delta = point->org_u - hint->org_pos; + + if ( delta <= 0 ) + point->cur_u = hint->cur_pos + FT_MulFix( delta, scale ); + + else if ( delta >= hint->org_len ) + point->cur_u = hint->cur_pos + hint->cur_len + + FT_MulFix( delta - hint->org_len, scale ); + + else if ( hint->org_len > 0 ) + point->cur_u = hint->cur_pos + + FT_MulDiv( delta, hint->cur_len, + hint->org_len ); + else + point->cur_u = hint->cur_pos; + } + psh3_point_set_fitted( point ); + } + } + } + } + + + static void + psh3_glyph_interpolate_normal_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + +#if 1 + + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + + + /* first technique: a point is strong if it is a local extrema */ + { + FT_UInt count = glyph->num_points; + PSH3_Point point = glyph->points; + + + for ( ; count > 0; count--, point++ ) + { + if ( psh3_point_is_strong( point ) ) + continue; + + /* sometimes, some local extremas are smooth points */ + if ( psh3_point_is_smooth( point ) ) + { + if ( point->dir_in == PSH3_DIR_NONE || + point->dir_in != point->dir_out ) + continue; + + if ( !psh3_point_is_extremum( point ) && + !psh3_point_is_inflex( point ) ) + continue; + + point->flags &= ~PSH3_POINT_SMOOTH; + } + + /* find best enclosing point coordinates */ + { + PSH3_Point before = 0; + PSH3_Point after = 0; + + FT_Pos diff_before = -32000; + FT_Pos diff_after = 32000; + FT_Pos u = point->org_u; + + FT_Int count2 = glyph->num_points; + PSH3_Point cur = glyph->points; + + + for ( ; count2 > 0; count2--, cur++ ) + { + if ( psh3_point_is_strong( cur ) ) + { + FT_Pos diff = cur->org_u - u;; + + + if ( diff <= 0 ) + { + if ( diff > diff_before ) + { + diff_before = diff; + before = cur; + } + } + else if ( diff >= 0 ) + { + if ( diff < diff_after ) + { + diff_after = diff; + after = cur; + } + } + } + } + + if ( !before ) + { + if ( !after ) + continue; + + /* we are before the first strong point coordinate; */ + /* simply translate the point */ + point->cur_u = after->cur_u + + FT_MulFix( point->org_u - after->org_u, scale ); + } + else if ( !after ) + { + /* we are after the last strong point coordinate; */ + /* simply translate the point */ + point->cur_u = before->cur_u + + FT_MulFix( point->org_u - before->org_u, scale ); + } + else + { + if ( diff_before == 0 ) + point->cur_u = before->cur_u; + + else if ( diff_after == 0 ) + point->cur_u = after->cur_u; + + else + point->cur_u = before->cur_u + + FT_MulDiv( u - before->org_u, + after->cur_u - before->cur_u, + after->org_u - before->org_u ); + } + + psh3_point_set_fitted( point ); + } + } + } + +#endif /* 1 */ + + } + + + /* interpolate other points */ + static void + psh3_glyph_interpolate_other_points( PSH3_Glyph glyph, + FT_Int dimension ) + { + PSH_Dimension dim = &glyph->globals->dimension[dimension]; + FT_Fixed scale = dim->scale_mult; + FT_Fixed delta = dim->scale_delta; + PSH3_Contour contour = glyph->contours; + FT_UInt num_contours = glyph->num_contours; + + + for ( ; num_contours > 0; num_contours--, contour++ ) + { + PSH3_Point start = contour->start; + PSH3_Point first, next, point; + FT_UInt fit_count; + + + /* count the number of strong points in this contour */ + next = start + contour->count; + fit_count = 0; + first = 0; + + for ( point = start; point < next; point++ ) + if ( psh3_point_is_fitted( point ) ) + { + if ( !first ) + first = point; + + fit_count++; + } + + /* if there are less than 2 fitted points in the contour, we */ + /* simply scale and eventually translate the contour points */ + if ( fit_count < 2 ) + { + if ( fit_count == 1 ) + delta = first->cur_u - FT_MulFix( first->org_u, scale ); + + for ( point = start; point < next; point++ ) + if ( point != first ) + point->cur_u = FT_MulFix( point->org_u, scale ) + delta; + + goto Next_Contour; + } + + /* there are more than 2 strong points in this contour; we */ + /* need to interpolate weak points between them */ + start = first; + do + { + point = first; + + /* skip consecutive fitted points */ + for (;;) + { + next = first->next; + if ( next == start ) + goto Next_Contour; + + if ( !psh3_point_is_fitted( next ) ) + break; + + first = next; + } + + /* find next fitted point after unfitted one */ + for (;;) + { + next = next->next; + if ( psh3_point_is_fitted( next ) ) + break; + } + + /* now interpolate between them */ + { + FT_Pos org_a, org_ab, cur_a, cur_ab; + FT_Pos org_c, org_ac, cur_c; + FT_Fixed scale_ab; + + + if ( first->org_u <= next->org_u ) + { + org_a = first->org_u; + cur_a = first->cur_u; + org_ab = next->org_u - org_a; + cur_ab = next->cur_u - cur_a; + } + else + { + org_a = next->org_u; + cur_a = next->cur_u; + org_ab = first->org_u - org_a; + cur_ab = first->cur_u - cur_a; + } + + scale_ab = 0x10000L; + if ( org_ab > 0 ) + scale_ab = FT_DivFix( cur_ab, org_ab ); + + point = first->next; + do + { + org_c = point->org_u; + org_ac = org_c - org_a; + + if ( org_ac <= 0 ) + { + /* on the left of the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale ); + } + else if ( org_ac >= org_ab ) + { + /* on the right on the interpolation zone */ + cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale ); + } + else + { + /* within the interpolation zone */ + cur_c = cur_a + FT_MulFix( org_ac, scale_ab ); + } + + point->cur_u = cur_c; + + point = point->next; + + } while ( point != next ); + } + + /* keep going until all points in the contours have been processed */ + first = next; + + } while ( first != start ); + + Next_Contour: + ; + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** HIGH-LEVEL INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_Error + ps3_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ) + { + PSH3_GlyphRec glyphrec; + PSH3_Glyph glyph = &glyphrec; + FT_Error error; +#ifdef DEBUG_HINTER + FT_Memory memory; +#endif + FT_Int dimension; + + +#ifdef DEBUG_HINTER + + memory = globals->memory; + + if ( ps3_debug_glyph ) + { + psh3_glyph_done( ps3_debug_glyph ); + FT_FREE( ps3_debug_glyph ); + } + + if ( FT_NEW( glyph ) ) + return error; + + ps3_debug_glyph = glyph; + +#endif /* DEBUG_HINTER */ + + error = psh3_glyph_init( glyph, outline, ps_hints, globals ); + if ( error ) + goto Exit; + + glyph->do_horz_hints = 1; + glyph->do_vert_hints = 1; + + glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD ); + + glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO || + hint_mode == FT_RENDER_MODE_LCD_V ); + + glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT ); + + for ( dimension = 0; dimension < 2; dimension++ ) + { + /* load outline coordinates into glyph */ + psh3_glyph_load_points( glyph, dimension ); + + /* compute local extrema */ + psh3_glyph_compute_extrema( glyph ); + + /* compute aligned stem/hints positions */ + psh3_hint_table_align_hints( &glyph->hint_tables[dimension], + glyph->globals, + dimension, + glyph ); + + /* find strong points, align them, then interpolate others */ + psh3_glyph_find_strong_points( glyph, dimension ); + psh3_glyph_interpolate_strong_points( glyph, dimension ); + psh3_glyph_interpolate_normal_points( glyph, dimension ); + psh3_glyph_interpolate_other_points( glyph, dimension ); + + /* save hinted coordinates back to outline */ + psh3_glyph_save_points( glyph, dimension ); + } + + Exit: + +#ifndef DEBUG_HINTER + psh3_glyph_done( glyph ); +#endif + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshalgo3.h b/lib/freetype/src/pshinter/pshalgo3.h new file mode 100644 index 0000000..7b69bb0 --- /dev/null +++ b/lib/freetype/src/pshinter/pshalgo3.h @@ -0,0 +1,255 @@ +/***************************************************************************/ +/* */ +/* pshalgo3.h */ +/* */ +/* PostScript hinting algorithm 3 (specification). */ +/* */ +/* Copyright 2001, 2002 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 __PSHALGO3_H__ +#define __PSHALGO3_H__ + + +#include "pshrec.h" +#include "pshglob.h" +#include FT_TRIGONOMETRY_H + + +FT_BEGIN_HEADER + + + /* handle to Hint structure */ + typedef struct PSH3_HintRec_* PSH3_Hint; + + /* hint bit-flags */ + typedef enum + { + PSH3_HINT_GHOST = PS_HINT_FLAG_GHOST, + PSH3_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, + PSH3_HINT_ACTIVE = 4, + PSH3_HINT_FITTED = 8 + + } PSH3_Hint_Flags; + + +#define psh3_hint_is_active( x ) ( ( (x)->flags & PSH3_HINT_ACTIVE ) != 0 ) +#define psh3_hint_is_ghost( x ) ( ( (x)->flags & PSH3_HINT_GHOST ) != 0 ) +#define psh3_hint_is_fitted( x ) ( ( (x)->flags & PSH3_HINT_FITTED ) != 0 ) + +#define psh3_hint_activate( x ) (x)->flags |= PSH3_HINT_ACTIVE +#define psh3_hint_deactivate( x ) (x)->flags &= ~PSH3_HINT_ACTIVE +#define psh3_hint_set_fitted( x ) (x)->flags |= PSH3_HINT_FITTED + + /* hint structure */ + typedef struct PSH3_HintRec_ + { + FT_Int org_pos; + FT_Int org_len; + FT_Pos cur_pos; + FT_Pos cur_len; + FT_UInt flags; + PSH3_Hint parent; + FT_Int order; + + } PSH3_HintRec; + + + /* this is an interpolation zone used for strong points; */ + /* weak points are interpolated according to their strong */ + /* neighbours */ + typedef struct PSH3_ZoneRec_ + { + FT_Fixed scale; + FT_Fixed delta; + FT_Pos min; + FT_Pos max; + + } PSH3_ZoneRec, *PSH3_Zone; + + + typedef struct PSH3_Hint_TableRec_ + { + FT_UInt max_hints; + FT_UInt num_hints; + PSH3_Hint hints; + PSH3_Hint* sort; + PSH3_Hint* sort_global; + FT_UInt num_zones; + PSH3_ZoneRec* zones; + PSH3_Zone zone; + PS_Mask_Table hint_masks; + PS_Mask_Table counter_masks; + + } PSH3_Hint_TableRec, *PSH3_Hint_Table; + + + typedef struct PSH3_PointRec_* PSH3_Point; + typedef struct PSH3_ContourRec_* PSH3_Contour; + + enum + { + PSH3_DIR_NONE = 4, + PSH3_DIR_UP = -1, + PSH3_DIR_DOWN = 1, + PSH3_DIR_LEFT = -2, + PSH3_DIR_RIGHT = 2 + }; + +#define PSH3_DIR_HORIZONTAL 2 +#define PSH3_DIR_VERTICAL 1 + +#define PSH3_DIR_COMPARE( d1, d2 ) ( (d1) == (d2) || (d1) == -(d2) ) +#define PSH3_DIR_IS_HORIZONTAL( d ) PSH3_DIR_COMPARE( d, PSH3_DIR_HORIZONTAL ) +#define PSH3_DIR_IS_VERTICAL( d ) PSH3_DIR_COMPARE( d, PSH3_DIR_VERTICAL ) + + + /* the following bit-flags are computed once by the glyph */ + /* analyzer, for both dimensions */ + enum + { + PSH3_POINT_OFF = 1, /* point is off the curve */ + PSH3_POINT_SMOOTH = 2, /* point is smooth */ + PSH3_POINT_INFLEX = 4 /* point is inflection */ + }; + +#define psh3_point_is_smooth( p ) ( (p)->flags & PSH3_POINT_SMOOTH ) +#define psh3_point_is_off( p ) ( (p)->flags & PSH3_POINT_OFF ) +#define psh3_point_is_inflex( p ) ( (p)->flags & PSH3_POINT_INFLEX ) + +#define psh3_point_set_smooth( p ) (p)->flags |= PSH3_POINT_SMOOTH +#define psh3_point_set_off( p ) (p)->flags |= PSH3_POINT_OFF +#define psh3_point_set_inflex( p ) (p)->flags |= PSH3_POINT_INFLEX + + /* the following bit-flags are re-computed for each dimension */ + enum + { + PSH3_POINT_STRONG = 16, /* point is strong */ + PSH3_POINT_FITTED = 32, /* point is already fitted */ + PSH3_POINT_EXTREMUM = 64, /* point is local extremum */ + PSH3_POINT_POSITIVE = 128, /* extremum has positive contour flow */ + PSH3_POINT_NEGATIVE = 256, /* extremum has negative contour flow */ + PSH3_POINT_EDGE_MIN = 512, /* point is aligned to left/bottom stem edge */ + PSH3_POINT_EDGE_MAX = 1024 /* point is aligned to top/right stem edge */ + }; + +#define psh3_point_is_strong( p ) ( (p)->flags2 & PSH3_POINT_STRONG ) +#define psh3_point_is_fitted( p ) ( (p)->flags2 & PSH3_POINT_FITTED ) +#define psh3_point_is_extremum( p ) ( (p)->flags2 & PSH3_POINT_EXTREMUM ) +#define psh3_point_is_positive( p ) ( (p)->flags2 & PSH3_POINT_POSITIVE ) +#define psh3_point_is_negative( p ) ( (p)->flags2 & PSH3_POINT_NEGATIVE ) +#define psh3_point_is_edge_min( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MIN ) +#define psh3_point_is_edge_max( p ) ( (p)->flags2 & PSH3_POINT_EDGE_MAX ) + +#define psh3_point_set_strong( p ) (p)->flags2 |= PSH3_POINT_STRONG +#define psh3_point_set_fitted( p ) (p)->flags2 |= PSH3_POINT_FITTED +#define psh3_point_set_extremum( p ) (p)->flags2 |= PSH3_POINT_EXTREMUM +#define psh3_point_set_positive( p ) (p)->flags2 |= PSH3_POINT_POSITIVE +#define psh3_point_set_negative( p ) (p)->flags2 |= PSH3_POINT_NEGATIVE +#define psh3_point_set_edge_min( p ) (p)->flags2 |= PSH3_POINT_EDGE_MIN +#define psh3_point_set_edge_max( p ) (p)->flags2 |= PSH3_POINT_EDGE_MAX + + + typedef struct PSH3_PointRec_ + { + PSH3_Point prev; + PSH3_Point next; + PSH3_Contour contour; + FT_UInt flags; + FT_UInt flags2; + FT_Char dir_in; + FT_Char dir_out; + FT_Angle angle_in; + FT_Angle angle_out; + PSH3_Hint hint; + FT_Pos org_u; + FT_Pos org_v; + FT_Pos cur_u; +#ifdef DEBUG_HINTER + FT_Pos org_x; + FT_Pos cur_x; + FT_Pos org_y; + FT_Pos cur_y; + FT_UInt flags_x; + FT_UInt flags_y; +#endif + + } PSH3_PointRec; + + +#define PSH3_POINT_EQUAL_ORG( a, b ) ( (a)->org_u == (b)->org_u && \ + (a)->org_v == (b)->org_v ) + +#define PSH3_POINT_ANGLE( a, b ) FT_Atan2( (b)->org_u - (a)->org_u, \ + (b)->org_v - (a)->org_v ) + + typedef struct PSH3_ContourRec_ + { + PSH3_Point start; + FT_UInt count; + + } PSH3_ContourRec; + + + typedef struct PSH3_GlyphRec_ + { + FT_UInt num_points; + FT_UInt num_contours; + + PSH3_Point points; + PSH3_Contour contours; + + FT_Memory memory; + FT_Outline* outline; + PSH_Globals globals; + PSH3_Hint_TableRec hint_tables[2]; + + FT_Bool vertical; + FT_Int major_dir; + FT_Int minor_dir; + + FT_Bool do_horz_hints; + FT_Bool do_vert_hints; + FT_Bool do_horz_snapping; + FT_Bool do_vert_snapping; + FT_Bool do_stem_adjust; + + } PSH3_GlyphRec, *PSH3_Glyph; + + +#ifdef DEBUG_HINTER + extern PSH3_Hint_Table ps3_debug_hint_table; + + typedef void + (*PSH3_HintFunc)( PSH3_Hint hint, + FT_Bool vertical ); + + extern PSH3_HintFunc ps3_debug_hint_func; + + extern PSH3_Glyph ps3_debug_glyph; +#endif + + + extern FT_Error + ps3_hints_apply( PS_Hints ps_hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + +FT_END_HEADER + + +#endif /* __PSHALGO3_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshglob.c b/lib/freetype/src/pshinter/pshglob.c new file mode 100644 index 0000000..e5ead54 --- /dev/null +++ b/lib/freetype/src/pshinter/pshglob.c @@ -0,0 +1,743 @@ +/***************************************************************************/ +/* */ +/* pshglob.c */ +/* */ +/* PostScript hinter global hinting management (body). */ +/* Inspired by the new auto-hinter module. */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include "pshglob.h" + +#ifdef DEBUG_HINTER + PSH_Globals ps_debug_globals = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** STANDARD WIDTHS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* scale the widths/heights table */ + static void + psh_globals_scale_widths( PSH_Globals globals, + FT_UInt direction ) + { + PSH_Dimension dim = &globals->dimension[direction]; + PSH_Widths stdw = &dim->stdw; + FT_UInt count = stdw->count; + PSH_Width width = stdw->widths; + PSH_Width stand = width; /* standard width/height */ + FT_Fixed scale = dim->scale_mult; + + + if ( count > 0 ) + { + width->cur = FT_MulFix( width->org, scale ); + width->fit = FT_RoundFix( width->cur ); + + width++; + count--; + + for ( ; count > 0; count--, width++ ) + { + FT_Pos w, dist; + + + w = FT_MulFix( width->org, scale ); + dist = w - stand->cur; + + if ( dist < 0 ) + dist = -dist; + + if ( dist < 128 ) + w = stand->cur; + + width->cur = w; + width->fit = FT_RoundFix( w ); + } + } + } + + + /* org_width is is font units, result in device pixels, 26.6 format */ + FT_LOCAL_DEF( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ) + { + FT_UInt n; + FT_Pos width = FT_MulFix( org_width, dimension->scale_mult ); + FT_Pos best = 64 + 32 + 2; + FT_Pos reference = width; + + + for ( n = 0; n < dimension->stdw.count; n++ ) + { + FT_Pos w; + FT_Pos dist; + + + w = dimension->stdw.widths[n].cur; + dist = width - w; + if ( dist < 0 ) + dist = -dist; + if ( dist < best ) + { + best = dist; + reference = w; + } + } + + if ( width >= reference ) + { + width -= 0x21; + if ( width < reference ) + width = reference; + } + else + { + width += 0x21; + if ( width > reference ) + width = reference; + } + + return width; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BLUE ZONES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_blues_set_zones_0( PSH_Blues target, + FT_Bool is_others, + FT_UInt read_count, + FT_Short* read, + PSH_Blue_Table top_table, + PSH_Blue_Table bot_table ) + { + FT_UInt count_top = top_table->count; + FT_UInt count_bot = bot_table->count; + FT_Bool first = 1; + + FT_UNUSED( target ); + + + for ( ; read_count > 0; read_count -= 2 ) + { + FT_Int reference, delta; + FT_UInt count; + PSH_Blue_Zone zones, zone; + FT_Bool top; + + + /* read blue zone entry, and select target top/bottom zone */ + top = 0; + if ( first || is_others ) + { + reference = read[1]; + delta = read[0] - reference; + + zones = bot_table->zones; + count = count_bot; + first = 0; + } + else + { + reference = read[0]; + delta = read[1] - reference; + + zones = top_table->zones; + count = count_top; + top = 1; + } + + /* insert into sorted table */ + zone = zones; + for ( ; count > 0; count--, zone++ ) + { + if ( reference < zone->org_ref ) + break; + + if ( reference == zone->org_ref ) + { + FT_Int delta0 = zone->org_delta; + + + /* we have two zones on the same reference position -- */ + /* only keep the largest one */ + if ( delta < 0 ) + { + if ( delta < delta0 ) + zone->org_delta = delta; + } + else + { + if ( delta > delta0 ) + zone->org_delta = delta; + } + goto Skip; + } + } + + for ( ; count > 0; count-- ) + zone[count] = zone[count-1]; + + zone->org_ref = reference; + zone->org_delta = delta; + + if ( top ) + count_top++; + else + count_bot++; + + Skip: + read += 2; + } + + top_table->count = count_top; + bot_table->count = count_bot; + } + + + /* Re-read blue zones from the original fonts and store them into out */ + /* private structure. This function re-orders, sanitizes and */ + /* fuzz-expands the zones as well. */ + static void + psh_blues_set_zones( PSH_Blues target, + FT_UInt count, + FT_Short* blues, + FT_UInt count_others, + FT_Short* other_blues, + FT_Int fuzz, + FT_Int family ) + { + PSH_Blue_Table top_table, bot_table; + FT_Int count_top, count_bot; + + + if ( family ) + { + top_table = &target->family_top; + bot_table = &target->family_bottom; + } + else + { + top_table = &target->normal_top; + bot_table = &target->normal_bottom; + } + + /* read the input blue zones, and build two sorted tables */ + /* (one for the top zones, the other for the bottom zones) */ + top_table->count = 0; + bot_table->count = 0; + + /* first, the blues */ + psh_blues_set_zones_0( target, 0, + count, blues, top_table, bot_table ); + psh_blues_set_zones_0( target, 1, + count_others, other_blues, top_table, bot_table ); + + count_top = top_table->count; + count_bot = bot_table->count; + + /* sanitize top table */ + if ( count_top > 0 ) + { + PSH_Blue_Zone zone = top_table->zones; + + + for ( count = count_top; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[1].org_ref - zone[0].org_ref; + if ( zone->org_delta > delta ) + zone->org_delta = delta; + } + + zone->org_bottom = zone->org_ref; + zone->org_top = zone->org_delta + zone->org_ref; + } + } + + /* sanitize bottom table */ + if ( count_bot > 0 ) + { + PSH_Blue_Zone zone = bot_table->zones; + + + for ( count = count_bot; count > 0; count--, zone++ ) + { + FT_Int delta; + + + if ( count > 1 ) + { + delta = zone[0].org_ref - zone[1].org_ref; + if ( zone->org_delta < delta ) + zone->org_delta = delta; + } + + zone->org_top = zone->org_ref; + zone->org_bottom = zone->org_delta + zone->org_ref; + } + } + + /* expand top and bottom tables with blue fuzz */ + { + FT_Int dim, top, bot, delta; + PSH_Blue_Zone zone; + + + zone = top_table->zones; + count = count_top; + + for ( dim = 1; dim >= 0; dim-- ) + { + if ( count > 0 ) + { + /* expand the bottom of the lowest zone normally */ + zone->org_bottom -= fuzz; + + /* expand the top and bottom of intermediate zones; */ + /* checking that the interval is smaller than the fuzz */ + top = zone->org_top; + + for ( count--; count > 0; count-- ) + { + bot = zone[1].org_bottom; + delta = bot - top; + + if ( delta < 2 * fuzz ) + zone[0].org_top = zone[1].org_bottom = top + delta / 2; + else + { + zone[0].org_top = top + fuzz; + zone[1].org_bottom = bot - fuzz; + } + + zone++; + top = zone->org_top; + } + + /* expand the top of the highest zone normally */ + zone->org_top = top + fuzz; + } + zone = bot_table->zones; + count = count_bot; + } + } + } + + + /* reset the blues table when the device transform changes */ + static void + psh_blues_scale_zones( PSH_Blues blues, + FT_Fixed scale, + FT_Pos delta ) + { + FT_UInt count; + FT_UInt num; + PSH_Blue_Table table = 0; + + /* */ + /* Determine whether we need to suppress overshoots or */ + /* not. We simply need to compare the vertical scale */ + /* parameter to the raw bluescale value. Here is why: */ + /* */ + /* We need to suppress overshoots for all pointsizes. */ + /* At 300dpi that satisfy: */ + /* */ + /* pointsize < 240*bluescale + 0.49 */ + /* */ + /* This corresponds to: */ + /* */ + /* pixelsize < 1000*bluescale + 49/24 */ + /* */ + /* scale*EM_Size < 1000*bluescale + 49/24 */ + /* */ + /* However, for normal Type 1 fonts, EM_Size is 1000! */ + /* We thus only check: */ + /* */ + /* scale < bluescale + 49/24000 */ + /* */ + /* which we shorten to */ + /* */ + /* "scale < bluescale" */ + /* */ + blues->no_overshoots = FT_BOOL( scale < blues->blue_scale ); + + /* */ + /* The blue threshold is the font units distance under */ + /* which overshoots are suppressed due to the BlueShift */ + /* even if the scale is greater than BlueScale. */ + /* */ + /* It is the smallest distance such that */ + /* */ + /* dist <= BlueShift && dist*scale <= 0.5 pixels */ + /* */ + { + FT_Int threshold = blues->blue_shift; + + + while ( threshold > 0 && FT_MulFix( threshold, scale ) > 32 ) + threshold --; + + blues->blue_threshold = threshold; + } + + for ( num = 0; num < 4; num++ ) + { + PSH_Blue_Zone zone; + + + switch ( num ) + { + case 0: + table = &blues->normal_top; + break; + case 1: + table = &blues->normal_bottom; + break; + case 2: + table = &blues->family_top; + break; + default: + table = &blues->family_bottom; + break; + } + + zone = table->zones; + count = table->count; + for ( ; count > 0; count--, zone++ ) + { + zone->cur_top = FT_MulFix( zone->org_top, scale ) + delta; + zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta; + zone->cur_ref = FT_MulFix( zone->org_ref, scale ) + delta; + zone->cur_delta = FT_MulFix( zone->org_delta, scale ); + + /* round scaled reference position */ + zone->cur_ref = ( zone->cur_ref + 32 ) & -64; + +#if 0 + if ( zone->cur_ref > zone->cur_top ) + zone->cur_ref -= 64; + else if ( zone->cur_ref < zone->cur_bottom ) + zone->cur_ref += 64; +#endif + } + } + + /* process the families now */ + + for ( num = 0; num < 2; num++ ) + { + PSH_Blue_Zone zone1, zone2; + FT_UInt count1, count2; + PSH_Blue_Table normal, family; + + + switch ( num ) + { + case 0: + normal = &blues->normal_top; + family = &blues->family_top; + break; + + default: + normal = &blues->normal_bottom; + family = &blues->family_bottom; + } + + zone1 = normal->zones; + count1 = normal->count; + + for ( ; count1 > 0; count1--, zone1++ ) + { + /* try to find a family zone whose reference position is less */ + /* than 1 pixel far from the current zone */ + zone2 = family->zones; + count2 = family->count; + + for ( ; count2 > 0; count2--, zone2++ ) + { + FT_Pos Delta; + + + Delta = zone1->org_ref - zone2->org_ref; + if ( Delta < 0 ) + Delta = -Delta; + + if ( FT_MulFix( Delta, scale ) < 64 ) + { + zone1->cur_top = zone2->cur_top; + zone1->cur_bottom = zone2->cur_bottom; + zone1->cur_ref = zone2->cur_ref; + zone1->cur_delta = zone2->cur_delta; + break; + } + } + } + } + } + + + FT_LOCAL_DEF( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ) + { + PSH_Blue_Table table; + FT_UInt count; + FT_Pos delta; + PSH_Blue_Zone zone; + FT_Int no_shoots; + + + alignment->align = PSH_BLUE_ALIGN_NONE; + + no_shoots = blues->no_overshoots; + + /* lookup stem top in top zones table */ + table = &blues->normal_top; + count = table->count; + zone = table->zones; + + for ( ; count > 0; count--, zone++ ) + { + delta = stem_top - zone->org_bottom; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_top <= zone->org_top + blues->blue_fuzz ) + { + if ( no_shoots || delta <= blues->blue_threshold ) + { + alignment->align |= PSH_BLUE_ALIGN_TOP; + alignment->align_top = zone->cur_ref; + } + break; + } + } + + /* look up stem bottom in bottom zones table */ + table = &blues->normal_bottom; + count = table->count; + zone = table->zones + count-1; + + for ( ; count > 0; count--, zone-- ) + { + delta = zone->org_top - stem_bot; + if ( delta < -blues->blue_fuzz ) + break; + + if ( stem_bot >= zone->org_bottom - blues->blue_fuzz ) + { + if ( no_shoots || delta < blues->blue_shift ) + { + alignment->align |= PSH_BLUE_ALIGN_BOT; + alignment->align_bot = zone->cur_ref; + } + break; + } + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + psh_globals_destroy( PSH_Globals globals ) + { + if ( globals ) + { + FT_Memory memory; + + + memory = globals->memory; + globals->dimension[0].stdw.count = 0; + globals->dimension[1].stdw.count = 0; + + globals->blues.normal_top.count = 0; + globals->blues.normal_bottom.count = 0; + globals->blues.family_top.count = 0; + globals->blues.family_bottom.count = 0; + + FT_FREE( globals ); + +#ifdef DEBUG_HINTER + ps_debug_globals = 0; +#endif + } + } + + + static FT_Error + psh_globals_new( FT_Memory memory, + T1_Private* priv, + PSH_Globals *aglobals ) + { + PSH_Globals globals; + FT_Error error; + + + if ( !FT_NEW( globals ) ) + { + FT_UInt count; + FT_Short* read; + + + globals->memory = memory; + + /* copy standard widths */ + { + PSH_Dimension dim = &globals->dimension[1]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_width[0]; + write++; + + read = priv->snap_widths; + for ( count = priv->num_snap_widths; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = write - dim->stdw.widths; + } + + /* copy standard heights */ + { + PSH_Dimension dim = &globals->dimension[0]; + PSH_Width write = dim->stdw.widths; + + + write->org = priv->standard_height[0]; + write++; + read = priv->snap_heights; + for ( count = priv->num_snap_heights; count > 0; count-- ) + { + write->org = *read; + write++; + read++; + } + + dim->stdw.count = write - dim->stdw.widths; + } + + /* copy blue zones */ + psh_blues_set_zones( &globals->blues, priv->num_blue_values, + priv->blue_values, priv->num_other_blues, + priv->other_blues, priv->blue_fuzz, 0 ); + + psh_blues_set_zones( &globals->blues, priv->num_family_blues, + priv->family_blues, priv->num_family_other_blues, + priv->family_other_blues, priv->blue_fuzz, 1 ); + + globals->blues.blue_scale = priv->blue_scale + ? priv->blue_scale + : 0x28937L; /* 0.039625 * 0x400000L */ + + globals->blues.blue_shift = priv->blue_shift + ? priv->blue_shift + : 7; + + globals->blues.blue_fuzz = priv->blue_fuzz; + + globals->dimension[0].scale_mult = 0; + globals->dimension[0].scale_delta = 0; + globals->dimension[1].scale_mult = 0; + globals->dimension[1].scale_delta = 0; + +#ifdef DEBUG_HINTER + ps_debug_globals = globals; +#endif + } + + *aglobals = globals; + return error; + } + + + static FT_Error + psh_globals_set_scale( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ) + { + PSH_Dimension dim = &globals->dimension[0]; + + + dim = &globals->dimension[0]; + if ( x_scale != dim->scale_mult || + x_delta != dim->scale_delta ) + { + dim->scale_mult = x_scale; + dim->scale_delta = x_delta; + + psh_globals_scale_widths( globals, 0 ); + } + + dim = &globals->dimension[1]; + if ( y_scale != dim->scale_mult || + y_delta != dim->scale_delta ) + { + dim->scale_mult = y_scale; + dim->scale_delta = y_delta; + + psh_globals_scale_widths( globals, 1 ); + psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); + } + + return 0; + } + + + FT_LOCAL_DEF( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ) + { + funcs->create = psh_globals_new; + funcs->set_scale = psh_globals_set_scale; + funcs->destroy = psh_globals_destroy; + } + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshglob.h b/lib/freetype/src/pshinter/pshglob.h new file mode 100644 index 0000000..0a3a96a --- /dev/null +++ b/lib/freetype/src/pshinter/pshglob.h @@ -0,0 +1,187 @@ +/***************************************************************************/ +/* */ +/* pshglob.h */ +/* */ +/* PostScript hinter global hinting management. */ +/* */ +/* Copyright 2001, 2002 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 __PSHGLOB_H__ +#define __PSHGLOB_H__ + + +#include FT_FREETYPE_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLOBAL HINTS INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_BLUE_ZONES */ + /* */ + /* @description: */ + /* The maximum number of blue zones in a font global hints structure. */ + /* See @PS_Globals_BluesRec. */ + /* */ +#define PS_GLOBALS_MAX_BLUE_ZONES 16 + + + /*************************************************************************/ + /* */ + /* @constant: */ + /* PS_GLOBALS_MAX_STD_WIDTHS */ + /* */ + /* @description: */ + /* The maximum number of standard and snap widths in either the */ + /* horizontal or vertical direction. See @PS_Globals_WidthsRec. */ + /* */ +#define PS_GLOBALS_MAX_STD_WIDTHS 16 + + + /* standard and snap width */ + typedef struct PSH_WidthRec_ + { + FT_Int org; + FT_Pos cur; + FT_Pos fit; + + } PSH_WidthRec, *PSH_Width; + + + /* standard and snap widths table */ + typedef struct PSH_WidthsRec_ + { + FT_UInt count; + PSH_WidthRec widths[PS_GLOBALS_MAX_STD_WIDTHS]; + + } PSH_WidthsRec, *PSH_Widths; + + + typedef struct PSH_DimensionRec_ + { + PSH_WidthsRec stdw; + FT_Fixed scale_mult; + FT_Fixed scale_delta; + + } PSH_DimensionRec, *PSH_Dimension; + + + /* blue zone descriptor */ + typedef struct PSH_Blue_ZoneRec_ + { + FT_Int org_ref; + FT_Int org_delta; + FT_Int org_top; + FT_Int org_bottom; + + FT_Pos cur_ref; + FT_Pos cur_delta; + FT_Pos cur_bottom; + FT_Pos cur_top; + + } PSH_Blue_ZoneRec, *PSH_Blue_Zone; + + + typedef struct PSH_Blue_TableRec_ + { + FT_UInt count; + PSH_Blue_ZoneRec zones[PS_GLOBALS_MAX_BLUE_ZONES]; + + } PSH_Blue_TableRec, *PSH_Blue_Table; + + + /* blue zones table */ + typedef struct PSH_BluesRec_ + { + PSH_Blue_TableRec normal_top; + PSH_Blue_TableRec normal_bottom; + PSH_Blue_TableRec family_top; + PSH_Blue_TableRec family_bottom; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_threshold; + FT_Int blue_fuzz; + FT_Bool no_overshoots; + + } PSH_BluesRec, *PSH_Blues; + + + /* font globals. */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PSH_GlobalsRec_ + { + FT_Memory memory; + PSH_DimensionRec dimension[2]; + PSH_BluesRec blues; + + } PSH_GlobalsRec; + + +#define PSH_BLUE_ALIGN_NONE 0 +#define PSH_BLUE_ALIGN_TOP 1 +#define PSH_BLUE_ALIGN_BOT 2 + + + typedef struct PSH_AlignmentRec_ + { + int align; + FT_Pos align_top; + FT_Pos align_bot; + + } PSH_AlignmentRec, *PSH_Alignment; + + + FT_LOCAL( void ) + psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); + + + /* snap a stem width to fitter coordinates. `org_width' is in font */ + /* units. The result is in device pixels (26.6 format). */ + FT_LOCAL( FT_Pos ) + psh_dimension_snap_width( PSH_Dimension dimension, + FT_Int org_width ); + + /* snap a stem to one or two blue zones */ + FT_LOCAL( void ) + psh_blues_snap_stem( PSH_Blues blues, + FT_Int stem_top, + FT_Int stem_bot, + PSH_Alignment alignment ); + /* */ + +#ifdef DEBUG_HINTER + extern PSH_Globals ps_debug_globals; +#endif + + +FT_END_HEADER + + +#endif /* __PSHGLOB_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshinter.c b/lib/freetype/src/pshinter/pshinter.c new file mode 100644 index 0000000..180f6c8 --- /dev/null +++ b/lib/freetype/src/pshinter/pshinter.c @@ -0,0 +1,30 @@ +/***************************************************************************/ +/* */ +/* pshinter.c */ +/* */ +/* FreeType PostScript Hinting module */ +/* */ +/* Copyright 2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "pshrec.c" +#include "pshglob.c" +#include "pshalgo1.c" +#include "pshalgo2.c" +#include "pshalgo3.c" +#include "pshmod.c" + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshmod.c b/lib/freetype/src/pshinter/pshmod.c new file mode 100644 index 0000000..5b18684 --- /dev/null +++ b/lib/freetype/src/pshinter/pshmod.c @@ -0,0 +1,120 @@ +/***************************************************************************/ +/* */ +/* pshmod.c */ +/* */ +/* FreeType PostScript hinter module implementation (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include "pshrec.h" +#include "pshalgo.h" + + + /* the Postscript Hinter module structure */ + typedef struct PS_Hinter_Module_Rec_ + { + FT_ModuleRec root; + PS_HintsRec ps_hints; + + PSH_Globals_FuncsRec globals_funcs; + T1_Hints_FuncsRec t1_funcs; + T2_Hints_FuncsRec t2_funcs; + + } PS_Hinter_ModuleRec, *PS_Hinter_Module; + + + /* finalize module */ + FT_CALLBACK_DEF( void ) + ps_hinter_done( PS_Hinter_Module module ) + { + module->t1_funcs.hints = NULL; + module->t2_funcs.hints = NULL; + + ps_hints_done( &module->ps_hints ); + } + + + /* initialize module, create hints recorder and the interface */ + FT_CALLBACK_DEF( FT_Error ) + ps_hinter_init( PS_Hinter_Module module ) + { + FT_Memory memory = module->root.memory; + + + ps_hints_init( &module->ps_hints, memory ); + + psh_globals_funcs_init( &module->globals_funcs ); + + t1_hints_funcs_init( &module->t1_funcs ); + module->t1_funcs.hints = (T1_Hints)&module->ps_hints; + + t2_hints_funcs_init( &module->t2_funcs ); + module->t2_funcs.hints = (T2_Hints)&module->ps_hints; + + return 0; + } + + + /* returns global hints interface */ + FT_CALLBACK_DEF( PSH_Globals_Funcs ) + pshinter_get_globals_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->globals_funcs; + } + + + /* return Type 1 hints interface */ + FT_CALLBACK_DEF( T1_Hints_Funcs ) + pshinter_get_t1_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t1_funcs; + } + + + /* return Type 2 hints interface */ + FT_CALLBACK_DEF( T2_Hints_Funcs ) + pshinter_get_t2_funcs( FT_Module module ) + { + return &((PS_Hinter_Module)module)->t2_funcs; + } + + + static + const PSHinter_Interface pshinter_interface = + { + pshinter_get_globals_funcs, + pshinter_get_t1_funcs, + pshinter_get_t2_funcs + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class pshinter_module_class = + { + 0, + sizeof ( PS_Hinter_ModuleRec ), + "pshinter", + 0x10000L, + 0x20000L, + + &pshinter_interface, /* module-specific interface */ + + (FT_Module_Constructor)ps_hinter_init, + (FT_Module_Destructor) ps_hinter_done, + (FT_Module_Requester) 0 /* no additional interface for now */ + }; + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshmod.h b/lib/freetype/src/pshinter/pshmod.h new file mode 100644 index 0000000..1a91025 --- /dev/null +++ b/lib/freetype/src/pshinter/pshmod.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* pshmod.h */ +/* */ +/* PostScript hinter module interface (specification). */ +/* */ +/* Copyright 2001 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 __PSHMOD_H__ +#define __PSHMOD_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Module_Class ) pshinter_module_class; + + +FT_END_HEADER + + +#endif /* __PSHMOD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshrec.c b/lib/freetype/src/pshinter/pshrec.c new file mode 100644 index 0000000..21ced1e --- /dev/null +++ b/lib/freetype/src/pshinter/pshrec.c @@ -0,0 +1,1211 @@ +/***************************************************************************/ +/* */ +/* pshrec.c */ +/* */ +/* FreeType PostScript hints recorder (body). */ +/* */ +/* Copyright 2001, 2002 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 <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include "pshrec.h" +#include "pshalgo.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_pshrec + +#ifdef DEBUG_HINTER + PS_Hints ps_debug_hints = 0; + int ps_debug_no_horz_hints = 0; + int ps_debug_no_vert_hints = 0; +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_HINT MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy hints table */ + static void + ps_hint_table_done( PS_Hint_Table table, + FT_Memory memory ) + { + FT_FREE( table->hints ); + table->num_hints = 0; + table->max_hints = 0; + } + + + /* ensure that a table can contain "count" elements */ + static FT_Error + ps_hint_table_ensure( PS_Hint_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_hints; + FT_UInt new_max = count; + FT_Error error = 0; + + + if ( new_max > old_max ) + { + /* try to grow the table */ + new_max = ( new_max + 7 ) & -8; + if ( !FT_RENEW_ARRAY( table->hints, old_max, new_max ) ) + table->max_hints = new_max; + } + return error; + } + + + static FT_Error + ps_hint_table_alloc( PS_Hint_Table table, + FT_Memory memory, + PS_Hint *ahint ) + { + FT_Error error = 0; + FT_UInt count; + PS_Hint hint = 0; + + + count = table->num_hints; + count++; + + if ( count >= table->max_hints ) + { + error = ps_hint_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + hint = table->hints + count - 1; + hint->pos = 0; + hint->len = 0; + hint->flags = 0; + + table->num_hints = count; + + Exit: + *ahint = hint; + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_MASK MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* destroy mask */ + static void + ps_mask_done( PS_Mask mask, + FT_Memory memory ) + { + FT_FREE( mask->bytes ); + mask->num_bits = 0; + mask->max_bits = 0; + mask->end_point = 0; + } + + + /* ensure that a mask can contain "count" bits */ + static FT_Error + ps_mask_ensure( PS_Mask mask, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = ( mask->max_bits + 7 ) >> 3; + FT_UInt new_max = ( count + 7 ) >> 3; + FT_Error error = 0; + + + if ( new_max > old_max ) + { + new_max = ( new_max + 7 ) & -8; + if ( !FT_RENEW_ARRAY( mask->bytes, old_max, new_max ) ) + mask->max_bits = new_max * 8; + } + return error; + } + + + /* test a bit value in a given mask */ + static FT_Int + ps_mask_test_bit( PS_Mask mask, + FT_Int idx ) + { + if ( (FT_UInt)idx >= mask->num_bits ) + return 0; + + return mask->bytes[idx >> 3] & ( 0x80 >> ( idx & 7 ) ); + } + + + /* clear a given bit */ + static void + ps_mask_clear_bit( PS_Mask mask, + FT_Int idx ) + { + FT_Byte* p; + + + if ( (FT_UInt)idx >= mask->num_bits ) + return; + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] & ~( 0x80 >> ( idx & 7 ) ) ); + } + + + /* set a given bit, possibly grow the mask */ + static FT_Error + ps_mask_set_bit( PS_Mask mask, + FT_Int idx, + FT_Memory memory ) + { + FT_Error error = 0; + FT_Byte* p; + + + if ( idx < 0 ) + goto Exit; + + if ( (FT_UInt)idx >= mask->num_bits ) + { + error = ps_mask_ensure( mask, idx + 1, memory ); + if ( error ) + goto Exit; + + mask->num_bits = idx + 1; + } + + p = mask->bytes + ( idx >> 3 ); + p[0] = (FT_Byte)( p[0] | ( 0x80 >> ( idx & 7 ) ) ); + + Exit: + return error; + } + + + /* destroy mask table */ + static void + ps_mask_table_done( PS_Mask_Table table, + FT_Memory memory ) + { + FT_UInt count = table->max_masks; + PS_Mask mask = table->masks; + + + for ( ; count > 0; count--, mask++ ) + ps_mask_done( mask, memory ); + + FT_FREE( table->masks ); + table->num_masks = 0; + table->max_masks = 0; + } + + + /* ensure that a mask table can contain "count" masks */ + static FT_Error + ps_mask_table_ensure( PS_Mask_Table table, + FT_UInt count, + FT_Memory memory ) + { + FT_UInt old_max = table->max_masks; + FT_UInt new_max = count; + FT_Error error = 0; + + + if ( new_max > old_max ) + { + new_max = ( new_max + 7 ) & -8; + if ( !FT_RENEW_ARRAY( table->masks, old_max, new_max ) ) + table->max_masks = new_max; + } + return error; + } + + + /* allocate a new mask in a table */ + static FT_Error + ps_mask_table_alloc( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_UInt count; + FT_Error error = 0; + PS_Mask mask = 0; + + + count = table->num_masks; + count++; + + if ( count > table->max_masks ) + { + error = ps_mask_table_ensure( table, count, memory ); + if ( error ) + goto Exit; + } + + mask = table->masks + count - 1; + mask->num_bits = 0; + mask->end_point = 0; + table->num_masks = count; + + Exit: + *amask = mask; + return error; + } + + + /* return last hint mask in a table, create one if the table is empty */ + static FT_Error + ps_mask_table_last( PS_Mask_Table table, + FT_Memory memory, + PS_Mask *amask ) + { + FT_Error error = 0; + FT_UInt count; + PS_Mask mask; + + + count = table->num_masks; + if ( count == 0 ) + { + error = ps_mask_table_alloc( table, memory, &mask ); + if ( error ) + goto Exit; + } + else + mask = table->masks + count - 1; + + Exit: + *amask = mask; + return error; + } + + + /* set a new mask to a given bit range */ + static FT_Error + ps_mask_table_set_bits( PS_Mask_Table table, + FT_Byte* source, + FT_UInt bit_pos, + FT_UInt bit_count, + FT_Memory memory ) + { + FT_Error error = 0; + PS_Mask mask; + + + /* allocate new mask, and grow it to "bit_count" bits */ + error = ps_mask_table_alloc( table, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_ensure( mask, bit_count, memory ); + if ( error ) + goto Exit; + + mask->num_bits = bit_count; + + /* now, copy bits */ + { + FT_Byte* read = source + ( bit_pos >> 3 ); + FT_Int rmask = 0x80 >> ( bit_pos & 7 ); + FT_Byte* write = mask->bytes; + FT_Int wmask = 0x80; + FT_Int val; + + + for ( ; bit_count > 0; bit_count-- ) + { + val = write[0] & ~wmask; + + if ( read[0] & rmask ) + val |= wmask; + + write[0] = (FT_Byte)val; + + rmask >>= 1; + if ( rmask == 0 ) + { + read++; + rmask = 0x80; + } + + wmask >>= 1; + if ( wmask == 0 ) + { + write++; + wmask = 0x80; + } + } + } + + Exit: + return error; + } + + + /* test whether two masks in a table intersect */ + static FT_Int + ps_mask_table_test_intersect( PS_Mask_Table table, + FT_Int index1, + FT_Int index2 ) + { + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_Byte* p1 = mask1->bytes; + FT_Byte* p2 = mask2->bytes; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_UInt count; + + + count = ( count1 <= count2 ) ? count1 : count2; + for ( ; count >= 8; count -= 8 ) + { + if ( p1[0] & p2[0] ) + return 1; + + p1++; + p2++; + } + + if ( count == 0 ) + return 0; + + return ( p1[0] & p2[0] ) & ~( 0xFF >> count ); + } + + + /* merge two masks, used by ps_mask_table_merge_all */ + static FT_Error + ps_mask_table_merge( PS_Mask_Table table, + FT_Int index1, + FT_Int index2, + FT_Memory memory ) + { + FT_UInt temp; + FT_Error error = 0; + + + /* swap index1 and index2 so that index1 < index2 */ + if ( index1 > index2 ) + { + temp = index1; + index1 = index2; + index2 = temp; + } + + if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks ) + { + /* we need to merge the bitsets of index1 and index2 with a */ + /* simple union */ + PS_Mask mask1 = table->masks + index1; + PS_Mask mask2 = table->masks + index2; + FT_UInt count1 = mask1->num_bits; + FT_UInt count2 = mask2->num_bits; + FT_Int delta; + + + if ( count2 > 0 ) + { + FT_UInt pos; + FT_Byte* read; + FT_Byte* write; + + + /* if "count2" is greater than "count1", we need to grow the */ + /* first bitset, and clear the highest bits */ + if ( count2 > count1 ) + { + error = ps_mask_ensure( mask1, count2, memory ); + if ( error ) + goto Exit; + + for ( pos = count1; pos < count2; pos++ ) + ps_mask_clear_bit( mask1, pos ); + } + + /* merge (unite) the bitsets */ + read = mask2->bytes; + write = mask1->bytes; + pos = (FT_UInt)( ( count2 + 7 ) >> 3 ); + + for ( ; pos > 0; pos-- ) + { + write[0] = (FT_Byte)( write[0] | read[0] ); + write++; + read++; + } + } + + /* Now, remove "mask2" from the list. We need to keep the masks */ + /* sorted in order of importance, so move table elements. */ + mask2->num_bits = 0; + mask2->end_point = 0; + + delta = table->num_masks - 1 - index2; /* number of masks to move */ + if ( delta > 0 ) + { + /* move to end of table for reuse */ + PS_MaskRec dummy = *mask2; + + + ft_memmove( mask2, mask2 + 1, delta * sizeof ( PS_MaskRec ) ); + + mask2[delta] = dummy; + } + + table->num_masks--; + } + else + FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n", + index1, index2 )); + + Exit: + return error; + } + + + /* Try to merge all masks in a given table. This is used to merge */ + /* all counter masks into independent counter "paths". */ + /* */ + static FT_Error + ps_mask_table_merge_all( PS_Mask_Table table, + FT_Memory memory ) + { + FT_Int index1, index2; + FT_Error error = 0; + + + for ( index1 = table->num_masks - 1; index1 > 0; index1-- ) + { + for ( index2 = index1 - 1; index2 >= 0; index2-- ) + { + if ( ps_mask_table_test_intersect( table, index1, index2 ) ) + { + error = ps_mask_table_merge( table, index2, index1, memory ); + if ( error ) + goto Exit; + + break; + } + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_DIMENSION MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* finalize a given dimension */ + static void + ps_dimension_done( PS_Dimension dimension, + FT_Memory memory ) + { + ps_mask_table_done( &dimension->counters, memory ); + ps_mask_table_done( &dimension->masks, memory ); + ps_hint_table_done( &dimension->hints, memory ); + } + + + /* initialize a given dimension */ + static void + ps_dimension_init( PS_Dimension dimension ) + { + dimension->hints.num_hints = 0; + dimension->masks.num_masks = 0; + dimension->counters.num_masks = 0; + } + + +#if 0 + + /* set a bit at a given index in the current hint mask */ + static FT_Error + ps_dimension_set_mask_bit( PS_Dimension dim, + FT_UInt idx, + FT_Memory memory ) + { + PS_Mask mask; + FT_Error error = 0; + + + /* get last hint mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + + Exit: + return error; + } + +#endif + + /* set the end point in a mask, called from "End" & "Reset" methods */ + static void + ps_dimension_end_mask( PS_Dimension dim, + FT_UInt end_point ) + { + FT_UInt count = dim->masks.num_masks; + PS_Mask mask; + + + if ( count > 0 ) + { + mask = dim->masks.masks + count - 1; + mask->end_point = end_point; + } + } + + + /* set the end point in the current mask, then create a new empty one */ + /* (called by "Reset" method) */ + static FT_Error + ps_dimension_reset_mask( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + PS_Mask mask; + + + /* end current mask */ + ps_dimension_end_mask( dim, end_point ); + + /* allocate new one */ + return ps_mask_table_alloc( &dim->masks, memory, &mask ); + } + + + /* set a new mask, called from the "T2Stem" method */ + static FT_Error + ps_dimension_set_mask_bits( PS_Dimension dim, + const FT_Byte* source, + FT_UInt source_pos, + FT_UInt source_bits, + FT_UInt end_point, + FT_Memory memory ) + { + FT_Error error = 0; + + + /* reset current mask, if any */ + error = ps_dimension_reset_mask( dim, end_point, memory ); + if ( error ) + goto Exit; + + /* set bits in new mask */ + error = ps_mask_table_set_bits( &dim->masks, (FT_Byte*)source, + source_pos, source_bits, memory ); + + Exit: + return error; + } + + + /* add a new single stem (called from "T1Stem" method) */ + static FT_Error + ps_dimension_add_t1stem( PS_Dimension dim, + FT_Int pos, + FT_Int len, + FT_Memory memory, + FT_Int *aindex ) + { + FT_Error error = 0; + FT_UInt flags = 0; + + + /* detect ghost stem */ + if ( len < 0 ) + { + flags |= PS_HINT_FLAG_GHOST; + if ( len == -21 ) + { + flags |= PS_HINT_FLAG_BOTTOM; + pos += len; + } + len = 0; + } + + if ( aindex ) + *aindex = -1; + + /* now, lookup stem in the current hints table */ + { + PS_Mask mask; + FT_UInt idx; + FT_UInt max = dim->hints.num_hints; + PS_Hint hint = dim->hints.hints; + + + for ( idx = 0; idx < max; idx++, hint++ ) + { + if ( hint->pos == pos && hint->len == len ) + break; + } + + /* we need to create a new hint in the table */ + if ( idx >= max ) + { + error = ps_hint_table_alloc( &dim->hints, memory, &hint ); + if ( error ) + goto Exit; + + hint->pos = pos; + hint->len = len; + hint->flags = flags; + } + + /* now, store the hint in the current mask */ + error = ps_mask_table_last( &dim->masks, memory, &mask ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( mask, idx, memory ); + if ( error ) + goto Exit; + + if ( aindex ) + *aindex = (FT_Int)idx; + } + + Exit: + return error; + } + + + /* add a "hstem3/vstem3" counter to our dimension table */ + static FT_Error + ps_dimension_add_counter( PS_Dimension dim, + FT_Int hint1, + FT_Int hint2, + FT_Int hint3, + FT_Memory memory ) + { + FT_Error error = 0; + FT_UInt count = dim->counters.num_masks; + PS_Mask counter = dim->counters.masks; + + + /* try to find an existing counter mask that already uses */ + /* one of these stems here */ + for ( ; count > 0; count--, counter++ ) + { + if ( ps_mask_test_bit( counter, hint1 ) || + ps_mask_test_bit( counter, hint2 ) || + ps_mask_test_bit( counter, hint3 ) ) + break; + } + + /* creat a new counter when needed */ + if ( count == 0 ) + { + error = ps_mask_table_alloc( &dim->counters, memory, &counter ); + if ( error ) + goto Exit; + } + + /* now, set the bits for our hints in the counter mask */ + error = ps_mask_set_bit( counter, hint1, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint2, memory ); + if ( error ) + goto Exit; + + error = ps_mask_set_bit( counter, hint3, memory ); + if ( error ) + goto Exit; + + Exit: + return error; + } + + + /* end of recording session for a given dimension */ + static FT_Error + ps_dimension_end( PS_Dimension dim, + FT_UInt end_point, + FT_Memory memory ) + { + /* end hint mask table */ + ps_dimension_end_mask( dim, end_point ); + + /* merge all counter masks into independent "paths" */ + return ps_mask_table_merge_all( &dim->counters, memory ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS_RECORDER MANAGEMENT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /* destroy hints */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ) + { + FT_Memory memory = hints->memory; + + + ps_dimension_done( &hints->dimension[0], memory ); + ps_dimension_done( &hints->dimension[1], memory ); + + hints->error = 0; + hints->memory = 0; + } + + + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ) + { + FT_MEM_ZERO( hints, sizeof ( *hints ) ); + hints->memory = memory; + return 0; + } + + + /* initialize a hints for a new session */ + static void + ps_hints_open( PS_Hints hints, + PS_Hint_Type hint_type ) + { + switch ( hint_type ) + { + case PS_HINT_TYPE_1: + case PS_HINT_TYPE_2: + hints->error = 0; + hints->hint_type = hint_type; + + ps_dimension_init( &hints->dimension[0] ); + ps_dimension_init( &hints->dimension[1] ); + break; + + default: + hints->error = FT_Err_Invalid_Argument; + hints->hint_type = hint_type; + + FT_ERROR(( "ps_hints_open: invalid charstring type!\n" )); + break; + } + } + + + /* add one or more stems to the current hints table */ + static void + ps_hints_stem( PS_Hints hints, + FT_Int dimension, + FT_UInt count, + FT_Long* stems ) + { + if ( !hints->error ) + { + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_ERROR(( "ps_hints_stem: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + /* record the stems in the current hints/masks table */ + switch ( hints->hint_type ) + { + case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */ + case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */ + { + PS_Dimension dim = &hints->dimension[dimension]; + + + for ( ; count > 0; count--, stems += 2 ) + { + FT_Error error; + FT_Memory memory = hints->memory; + + + error = ps_dimension_add_t1stem( dim, stems[0], stems[1], + memory, NULL ); + if ( error ) + { + FT_ERROR(( "ps_hints_stem: could not add stem" + " (%d,%d) to hints table\n", stems[0], stems[1] )); + + hints->error = error; + return; + } + } + break; + } + + default: + FT_ERROR(( "ps_hints_stem: called with invalid hint type (%d)\n", + hints->hint_type )); + break; + } + } + } + + + /* add one Type1 counter stem to the current hints table */ + static void + ps_hints_t1stem3( PS_Hints hints, + FT_Int dimension, + FT_Long* stems ) + { + FT_Error error = 0; + + + if ( !hints->error ) + { + PS_Dimension dim; + FT_Memory memory = hints->memory; + FT_Int count; + FT_Int idx[3]; + + + /* limit "dimension" to 0..1 */ + if ( dimension < 0 || dimension > 1 ) + { + FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n", + dimension )); + dimension = ( dimension != 0 ); + } + + dim = &hints->dimension[dimension]; + + /* there must be 6 elements in the 'stem' array */ + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + /* add the three stems to our hints/masks table */ + for ( count = 0; count < 3; count++, stems += 2 ) + { + error = ps_dimension_add_t1stem( dim, stems[0], stems[1], + memory, &idx[count] ); + if ( error ) + goto Fail; + } + + /* now, add the hints to the counters table */ + error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2], + memory ); + if ( error ) + goto Fail; + } + else + { + FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" )); + error = FT_Err_Invalid_Argument; + goto Fail; + } + } + + return; + + Fail: + FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" )); + hints->error = error; + } + + + /* reset hints (only with Type 1 hints) */ + static void + ps_hints_t1reset( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error = 0; + + + if ( !hints->error ) + { + FT_Memory memory = hints->memory; + + + if ( hints->hint_type == PS_HINT_TYPE_1 ) + { + error = ps_dimension_reset_mask( &hints->dimension[0], + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_reset_mask( &hints->dimension[1], + end_point, memory ); + if ( error ) + goto Fail; + } + else + { + /* invalid hint type */ + error = FT_Err_Invalid_Argument; + goto Fail; + } + } + return; + + Fail: + hints->error = error; + } + + + /* Type2 "hintmask" operator, add a new hintmask to each direction */ + static void + ps_hints_t2mask( PS_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count; must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_ERROR(( "ps_hints_t2mask: " + "called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + end_point, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + end_point, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + static void + ps_hints_t2counter( PS_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ) + { + FT_Error error; + + + if ( !hints->error ) + { + PS_Dimension dim = hints->dimension; + FT_Memory memory = hints->memory; + FT_UInt count1 = dim[0].hints.num_hints; + FT_UInt count2 = dim[1].hints.num_hints; + + + /* check bit count, must be equal to current total hint count */ + if ( bit_count != count1 + count2 ) + { + FT_ERROR(( "ps_hints_t2counter: " + "called with invalid bitcount %d (instead of %d)\n", + bit_count, count1 + count2 )); + + /* simply ignore the operator */ + return; + } + + /* set-up new horizontal and vertical hint mask now */ + error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1, + 0, memory ); + if ( error ) + goto Fail; + + error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2, + 0, memory ); + if ( error ) + goto Fail; + } + return; + + Fail: + hints->error = error; + } + + + /* end recording session */ + static FT_Error + ps_hints_close( PS_Hints hints, + FT_UInt end_point ) + { + FT_Error error; + + + error = hints->error; + if ( !error ) + { + FT_Memory memory = hints->memory; + PS_Dimension dim = hints->dimension; + + + error = ps_dimension_end( &dim[0], end_point, memory ); + if ( !error ) + { + error = ps_dimension_end( &dim[1], end_point, memory ); + } + } + +#ifdef DEBUG_HINTER + if ( !error ) + ps_debug_hints = hints; +#endif + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t1_hints_open( T1_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 ); + } + + static void + t1_hints_stem( T1_Hints hints, + FT_Int dimension, + FT_Long* coords ) + { + ps_hints_stem( (PS_Hints)hints, dimension, 1, coords ); + } + + + FT_LOCAL_DEF( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + + funcs->open = (T1_Hints_OpenFunc) t1_hints_open; + funcs->close = (T1_Hints_CloseFunc) ps_hints_close; + funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem; + funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3; + funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset; + funcs->apply = (T1_Hints_ApplyFunc) PS_HINTS_APPLY_FUNC; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 2 HINTS RECORDING INTERFACE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + t2_hints_open( T2_Hints hints ) + { + ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 ); + } + + + static void + t2_hints_stems( T2_Hints hints, + FT_Int dimension, + FT_Int count, + FT_Fixed* coords ) + { + FT_Pos stems[32], y, n, total = count; + + + y = 0; + while ( total > 0 ) + { + /* determine number of stems to write */ + count = total; + if ( count > 16 ) + count = 16; + + /* compute integer stem positions in font units */ + for ( n = 0; n < count * 2; n++ ) + { + y += coords[n]; + stems[n] = ( y + 0x8000 ) >> 16; + } + + /* compute lengths */ + for ( n = 0; n < count * 2; n += 2 ) + stems[n + 1] = stems[n + 1] - stems[n]; + + /* add them to the current dimension */ + ps_hints_stem( (PS_Hints)hints, dimension, count, stems ); + + total -= count; + } + } + + + FT_LOCAL_DEF( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) + { + FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + + funcs->open = (T2_Hints_OpenFunc) t2_hints_open; + funcs->close = (T2_Hints_CloseFunc) ps_hints_close; + funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems; + funcs->hintmask= (T2_Hints_MaskFunc) ps_hints_t2mask; + funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter; + funcs->apply = (T2_Hints_ApplyFunc) PS_HINTS_APPLY_FUNC; + } + + +/* END */ diff --git a/lib/freetype/src/pshinter/pshrec.h b/lib/freetype/src/pshinter/pshrec.h new file mode 100644 index 0000000..884aa5c --- /dev/null +++ b/lib/freetype/src/pshinter/pshrec.h @@ -0,0 +1,180 @@ +/***************************************************************************/ +/* */ +/* pshrec.h */ +/* */ +/* Postscript (Type1/Type2) hints recorder (specification). */ +/* */ +/* Copyright 2001, 2002 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 functions defined here are called from the Type 1, CID and CFF */ + /* font drivers to record the hints of a given character/glyph. */ + /* */ + /* The hints are recorded in a unified format, and are later processed */ + /* by the "optimizer" and "fitter" to adjust the outlines to the pixel */ + /* grid. */ + /* */ + /**************************************************************************/ + + +#ifndef __PSHREC_H__ +#define __PSHREC_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include "pshglob.h" + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH HINTS RECORDER INTERNALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to hint record */ + typedef struct PS_HintRec_* PS_Hint; + + /* hint types */ + typedef enum + { + PS_HINT_TYPE_1 = 1, + PS_HINT_TYPE_2 = 2 + + } PS_Hint_Type; + + + /* hint flags */ + typedef enum + { + PS_HINT_FLAG_GHOST = 1, + PS_HINT_FLAG_BOTTOM = 2 + + } PS_Hint_Flags; + + + /* hint descriptor */ + typedef struct PS_HintRec_ + { + FT_Int pos; + FT_Int len; + FT_UInt flags; + + } PS_HintRec; + + +#define ps_hint_is_active( x ) ( (x)->flags & PS_HINT_FLAG_ACTIVE ) +#define ps_hint_is_ghost( x ) ( (x)->flags & PS_HINT_FLAG_GHOST ) +#define ps_hint_is_bottom( x ) ( (x)->flags & PS_HINT_FLAG_BOTTOM ) + + + /* hints table descriptor */ + typedef struct PS_Hint_TableRec_ + { + FT_UInt num_hints; + FT_UInt max_hints; + PS_Hint hints; + + } PS_Hint_TableRec, *PS_Hint_Table; + + + /* hint and counter mask descriptor */ + typedef struct PS_MaskRec_ + { + FT_UInt num_bits; + FT_UInt max_bits; + FT_Byte* bytes; + FT_UInt end_point; + + } PS_MaskRec, *PS_Mask; + + + /* masks and counters table descriptor */ + typedef struct PS_Mask_TableRec_ + { + FT_UInt num_masks; + FT_UInt max_masks; + PS_Mask masks; + + } PS_Mask_TableRec, *PS_Mask_Table; + + + /* dimension-specific hints descriptor */ + typedef struct PS_DimensionRec_ + { + PS_Hint_TableRec hints; + PS_Mask_TableRec masks; + PS_Mask_TableRec counters; + + } PS_DimensionRec, *PS_Dimension; + + + /* magic value used within PS_HintsRec */ +#define PS_HINTS_MAGIC 0x68696e74 /* "hint" */ + + + /* glyph hints descriptor */ + /* dimension 0 => X coordinates + vertical hints/stems */ + /* dimension 1 => Y coordinates + horizontal hints/stems */ + typedef struct PS_HintsRec_ + { + FT_Memory memory; + FT_Error error; + FT_UInt32 magic; + PS_Hint_Type hint_type; + PS_DimensionRec dimension[2]; + + } PS_HintsRec, *PS_Hints; + + /* */ + + /* initialize hints recorder */ + FT_LOCAL( FT_Error ) + ps_hints_init( PS_Hints hints, + FT_Memory memory ); + + /* finalize hints recorder */ + FT_LOCAL( void ) + ps_hints_done( PS_Hints hints ); + + /* initialize Type1 hints recorder interface */ + FT_LOCAL( void ) + t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); + + /* initialize Type2 hints recorder interface */ + FT_LOCAL( void ) + t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); + + +#ifdef DEBUG_HINTER + extern PS_Hints ps_debug_hints; + extern int ps_debug_no_horz_hints; + extern int ps_debug_no_vert_hints; +#endif + + /* */ + + +FT_END_HEADER + + +#endif /* __PS_HINTER_RECORD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/pshinter/rules.mk b/lib/freetype/src/pshinter/rules.mk new file mode 100644 index 0000000..207d349 --- /dev/null +++ b/lib/freetype/src/pshinter/rules.mk @@ -0,0 +1,74 @@ +# +# FreeType 2 PSHinter driver configuration rules +# + + +# Copyright 2001 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. + + +# PSHINTER driver directory +# +PSHINTER_DIR := $(SRC_)pshinter +PSHINTER_DIR_ := $(PSHINTER_DIR)$(SEP) + + +# compilation flags for the driver +# +PSHINTER_COMPILE := $(FT_COMPILE) $I$(PSHINTER_DIR) + + +# PSHINTER driver sources (i.e., C files) +# +PSHINTER_DRV_SRC := $(PSHINTER_DIR_)pshrec.c \ + $(PSHINTER_DIR_)pshglob.c \ + $(PSHINTER_DIR_)pshmod.c \ + $(PSHINTER_DIR_)pshalgo1.c \ + $(PSHINTER_DIR_)pshalgo2.c \ + $(PSHINTER_DIR_)pshalgo3.c + + +# PSHINTER driver headers +# +PSHINTER_DRV_H := $(PSHINTER_DRV_SRC:%c=%h) + + +# PSHINTER driver object(s) +# +# PSHINTER_DRV_OBJ_M is used during `multi' builds. +# PSHINTER_DRV_OBJ_S is used during `single' builds. +# +PSHINTER_DRV_OBJ_M := $(PSHINTER_DRV_SRC:$(PSHINTER_DIR_)%.c=$(OBJ_)%.$O) +PSHINTER_DRV_OBJ_S := $(OBJ_)pshinter.$O + +# PSHINTER driver source file for single build +# +PSHINTER_DRV_SRC_S := $(PSHINTER_DIR_)pshinter.c + + +# PSHINTER driver - single object +# +$(PSHINTER_DRV_OBJ_S): $(PSHINTER_DRV_SRC_S) $(PSHINTER_DRV_SRC) \ + $(FREETYPE_H) $(PSHINTER_DRV_H) + $(PSHINTER_COMPILE) $T$@ $(PSHINTER_DRV_SRC_S) + + +# PSHINTER driver - multiple objects +# +$(OBJ_)%.$O: $(PSHINTER_DIR_)%.c $(FREETYPE_H) $(PSHINTER_DRV_H) + $(PSHINTER_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PSHINTER_DRV_OBJ_S) +DRV_OBJS_M += $(PSHINTER_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/psnames/Jamfile b/lib/freetype/src/psnames/Jamfile new file mode 100644 index 0000000..e75ae1e --- /dev/null +++ b/lib/freetype/src/psnames/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/psnames Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) psnames ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = psmodule ; + } + else + { + _sources = psnames ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/psnames Jamfile diff --git a/lib/freetype/src/psnames/descrip.mms b/lib/freetype/src/psnames/descrip.mms new file mode 100644 index 0000000..6a66b9f --- /dev/null +++ b/lib/freetype/src/psnames/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 PSNames driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.psnames]) + +OBJS=psnames.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/psnames/module.mk b/lib/freetype/src/psnames/module.mk new file mode 100644 index 0000000..e1e59c4 --- /dev/null +++ b/lib/freetype/src/psnames/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 PSnames module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_psnames_module + +add_psnames_module: + $(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/psnames/psmodule.c b/lib/freetype/src/psnames/psmodule.c new file mode 100644 index 0000000..b2ddcb7 --- /dev/null +++ b/lib/freetype/src/psnames/psmodule.c @@ -0,0 +1,357 @@ +/***************************************************************************/ +/* */ +/* psmodule.c */ +/* */ +/* PSNames module implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_OBJECTS_H + +#include "psmodule.h" +#include "pstables.h" + +#include "psnamerr.h" + + +#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES + + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /* return the Unicode value corresponding to a given glyph. Note that */ + /* we do deal with glyph variants by detecting a non-initial dot in */ + /* the name, as in `A.swash' or `e.final', etc. */ + /* */ + static FT_UInt32 + ps_unicode_value( const char* glyph_name ) + { + FT_Int n; + char first = glyph_name[0]; + char temp[64]; + + + /* if the name begins with `uni', then the glyph name may be a */ + /* hard-coded unicode character code. */ + if ( glyph_name[0] == 'u' && + glyph_name[1] == 'n' && + glyph_name[2] == 'i' ) + { + /* determine whether the next four characters following are */ + /* hexadecimal. */ + + /* XXX: Add code to deal with ligatures, i.e. glyph names like */ + /* `uniXXXXYYYYZZZZ'... */ + + FT_Int count; + FT_ULong value = 0; + const char* p = glyph_name + 3; + + + for ( count = 4; count > 0; count--, p++ ) + { + char c = *p; + unsigned int d; + + + d = (unsigned char)c - '0'; + if ( d >= 10 ) + { + d = (unsigned char)c - 'A'; + if ( d >= 6 ) + d = 16; + else + d += 10; + } + + /* exit if a non-uppercase hexadecimal character was found */ + if ( d >= 16 ) + break; + + value = ( value << 4 ) + d; + } + if ( count == 0 ) + return value; + } + + /* look for a non-initial dot in the glyph name in order to */ + /* sort-out variants like `A.swash', `e.final', etc. */ + { + const char* p; + int len; + + + p = glyph_name; + + while ( *p && *p != '.' ) + p++; + + len = (int)( p - glyph_name ); + + if ( *p && len < 64 ) + { + ft_strncpy( temp, glyph_name, len ); + temp[len] = 0; + glyph_name = temp; + } + } + + /* now, look up the glyph in the Adobe Glyph List */ + for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ ) + { + const char* name = sid_standard_names[n]; + + + if ( first == name[0] && ft_strcmp( glyph_name, name ) == 0 ) + return ps_names_to_unicode[n]; + } + + /* not found, there is probably no Unicode value for this glyph name */ + return 0; + } + + + /* ft_qsort callback to sort the unicode map */ + FT_CALLBACK_DEF( int ) + compare_uni_maps( const void* a, + const void* b ) + { + PS_UniMap* map1 = (PS_UniMap*)a; + PS_UniMap* map2 = (PS_UniMap*)b; + + + return ( map1->unicode - map2->unicode ); + } + + + /* Builds a table that maps Unicode values to glyph indices */ + static FT_Error + ps_build_unicode_table( FT_Memory memory, + FT_UInt num_glyphs, + const char** glyph_names, + PS_Unicodes* table ) + { + FT_Error error; + + + /* we first allocate the table */ + table->num_maps = 0; + table->maps = 0; + + if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) + { + FT_UInt n; + FT_UInt count; + PS_UniMap* map; + FT_UInt32 uni_char; + + + map = table->maps; + + for ( n = 0; n < num_glyphs; n++ ) + { + const char* gname = glyph_names[n]; + + + if ( gname ) + { + uni_char = ps_unicode_value( gname ); + + if ( uni_char != 0 && uni_char != 0xFFFF ) + { + map->unicode = uni_char; + map->glyph_index = n; + map++; + } + } + } + + /* now, compress the table a bit */ + count = (FT_UInt)( map - table->maps ); + + if ( count > 0 && FT_REALLOC( table->maps, + num_glyphs * sizeof ( PS_UniMap ), + count * sizeof ( PS_UniMap ) ) ) + count = 0; + + if ( count == 0 ) + { + FT_FREE( table->maps ); + if ( !error ) + error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */ + } + else + /* sort the table in increasing order of unicode values */ + ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); + + table->num_maps = count; + } + + return error; + } + + + static FT_UInt + ps_lookup_unicode( PS_Unicodes* table, + FT_ULong unicode ) + { + PS_UniMap *min, *max, *mid; + + + /* perform a binary search on the table */ + + min = table->maps; + max = min + table->num_maps - 1; + + while ( min <= max ) + { + mid = min + ( max - min ) / 2; + if ( mid->unicode == unicode ) + return mid->glyph_index; + + if ( min == max ) + break; + + if ( mid->unicode < unicode ) + min = mid + 1; + else + max = mid - 1; + } + + return 0xFFFF; + } + + + static FT_ULong + ps_next_unicode( PS_Unicodes* table, + FT_ULong unicode ) + { + PS_UniMap *min, *max, *mid; + + + unicode++; + /* perform a binary search on the table */ + + min = table->maps; + max = min + table->num_maps - 1; + + while ( min <= max ) + { + mid = min + ( max - min ) / 2; + if ( mid->unicode == unicode ) + return unicode; + + if ( min == max ) + break; + + if ( mid->unicode < unicode ) + min = mid + 1; + else + max = mid - 1; + } + + if ( max < table->maps ) + max = table->maps; + + while ( max < table->maps + table->num_maps ) + { + if ( unicode < max->unicode ) + return max->unicode; + max++; + } + + return 0; + } + + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + + static const char* + ps_get_macintosh_name( FT_UInt name_index ) + { + if ( name_index >= 258 ) + name_index = 0; + + return ps_glyph_names[mac_standard_names[name_index]]; + } + + + static const char* + ps_get_standard_strings( FT_UInt sid ) + { + return ( sid < NUM_SID_GLYPHS ? sid_standard_names[sid] : 0 ); + } + + + static + const PSNames_Interface psnames_interface = + { +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + (PS_Unicode_Value_Func) ps_unicode_value, + (PS_Build_Unicodes_Func) ps_build_unicode_table, + (PS_Lookup_Unicode_Func) ps_lookup_unicode, + +#else + + 0, + 0, + 0, + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + (PS_Macintosh_Name_Func) ps_get_macintosh_name, + (PS_Adobe_Std_Strings_Func) ps_get_standard_strings, + + t1_standard_encoding, + t1_expert_encoding, + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + (PS_Next_Unicode_Func) ps_next_unicode +#else + 0 +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + }; + + +#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class psnames_module_class = + { + 0, /* this is not a font driver, nor a renderer */ + sizeof ( FT_ModuleRec ), + + "psnames", /* driver name */ + 0x10000L, /* driver version */ + 0x20000L, /* driver requires FreeType 2 or above */ + +#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES + 0, +#else + (void*)&psnames_interface, /* module specific interface */ +#endif + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/psnames/psmodule.h b/lib/freetype/src/psnames/psmodule.h new file mode 100644 index 0000000..232fdfb --- /dev/null +++ b/lib/freetype/src/psnames/psmodule.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* psmodule.h */ +/* */ +/* High-level PSNames module interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __PSMODULE_H__ +#define __PSMODULE_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; + + +FT_END_HEADER + +#endif /* __PSMODULE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psnames/psnamerr.h b/lib/freetype/src/psnames/psnamerr.h new file mode 100644 index 0000000..ae1541d --- /dev/null +++ b/lib/freetype/src/psnames/psnamerr.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* psnamerr.h */ +/* */ +/* PS names module error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the PS names module error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __PSNAMERR_H__ +#define __PSNAMERR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX PSnames_Err_ +#define FT_ERR_BASE FT_Mod_Err_PSnames + +#include FT_ERRORS_H + +#endif /* __PSNAMERR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/psnames/psnames.c b/lib/freetype/src/psnames/psnames.c new file mode 100644 index 0000000..d6ed998 --- /dev/null +++ b/lib/freetype/src/psnames/psnames.c @@ -0,0 +1,25 @@ +/***************************************************************************/ +/* */ +/* psnames.c */ +/* */ +/* FreeType PSNames module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "psmodule.c" + + +/* END */ diff --git a/lib/freetype/src/psnames/pstables.h b/lib/freetype/src/psnames/pstables.h new file mode 100644 index 0000000..39c838a --- /dev/null +++ b/lib/freetype/src/psnames/pstables.h @@ -0,0 +1,2967 @@ +/***************************************************************************/ +/* */ +/* pstables.h */ +/* */ +/* PostScript glyph names (specification only). */ +/* */ +/* Copyright 2000-2001 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 has been generated automatically -- do not edit! */ + + + static const char* const ps_glyph_names[] = + { + ".null", + "nonmarkingreturn", + "nonbreakingspace", + "apple", + ".notdef", + "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", + "asciicircum", + "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", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold", + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + "AEacute", + "Abreve", + "Acute", + "Alpha", + "Alphatonos", + "Amacron", + "Aogonek", + "Aringacute", + "Beta", + "Cacute", + "Caron", + "Ccaron", + "Ccircumflex", + "Cdotaccent", + "Chi", + "Dcaron", + "Dcroat", + "Delta", + "Delta", + "Dieresis", + "DieresisAcute", + "DieresisGrave", + "Ebreve", + "Ecaron", + "Edotaccent", + "Emacron", + "Eng", + "Eogonek", + "Epsilon", + "Epsilontonos", + "Eta", + "Etatonos", + "Euro", + "Gamma", + "Gbreve", + "Gcaron", + "Gcircumflex", + "Gcommaaccent", + "Gdotaccent", + "Grave", + "H18533", + "H18543", + "H18551", + "H22073", + "Hbar", + "Hcircumflex", + "Hungarumlaut", + "IJ", + "Ibreve", + "Idotaccent", + "Ifraktur", + "Imacron", + "Iogonek", + "Iota", + "Iotadieresis", + "Iotatonos", + "Itilde", + "Jcircumflex", + "Kappa", + "Kcommaaccent", + "LL", + "Lacute", + "Lambda", + "Lcaron", + "Lcommaaccent", + "Ldot", + "Macron", + "Mu", + "Nacute", + "Ncaron", + "Ncommaaccent", + "Nu", + "Obreve", + "Ohorn", + "Ohungarumlaut", + "Omacron", + "Omega", + "Omega", + "Omegatonos", + "Omicron", + "Omicrontonos", + "Oslashacute", + "Phi", + "Pi", + "Psi", + "Racute", + "Rcaron", + "Rcommaaccent", + "Rfraktur", + "Rho", + "SF010000", + "SF020000", + "SF030000", + "SF040000", + "SF050000", + "SF060000", + "SF070000", + "SF080000", + "SF090000", + "SF100000", + "SF110000", + "SF190000", + "SF200000", + "SF210000", + "SF220000", + "SF230000", + "SF240000", + "SF250000", + "SF260000", + "SF270000", + "SF280000", + "SF360000", + "SF370000", + "SF380000", + "SF390000", + "SF400000", + "SF410000", + "SF420000", + "SF430000", + "SF440000", + "SF450000", + "SF460000", + "SF470000", + "SF480000", + "SF490000", + "SF500000", + "SF510000", + "SF520000", + "SF530000", + "SF540000", + "Sacute", + "Scedilla", + "Scedilla", + "Scircumflex", + "Scommaaccent", + "Sigma", + "Tau", + "Tbar", + "Tcaron", + "Tcommaaccent", + "Tcommaaccent", + "Theta", + "Ubreve", + "Uhorn", + "Uhungarumlaut", + "Umacron", + "Uogonek", + "Upsilon", + "Upsilon1", + "Upsilondieresis", + "Upsilontonos", + "Uring", + "Utilde", + "Wacute", + "Wcircumflex", + "Wdieresis", + "Wgrave", + "Xi", + "Ycircumflex", + "Ygrave", + "Zacute", + "Zdotaccent", + "Zeta", + "abreve", + "acutecomb", + "aeacute", + "afii00208", + "afii10017", + "afii10018", + "afii10019", + "afii10020", + "afii10021", + "afii10022", + "afii10023", + "afii10024", + "afii10025", + "afii10026", + "afii10027", + "afii10028", + "afii10029", + "afii10030", + "afii10031", + "afii10032", + "afii10033", + "afii10034", + "afii10035", + "afii10036", + "afii10037", + "afii10038", + "afii10039", + "afii10040", + "afii10041", + "afii10042", + "afii10043", + "afii10044", + "afii10045", + "afii10046", + "afii10047", + "afii10048", + "afii10049", + "afii10050", + "afii10051", + "afii10052", + "afii10053", + "afii10054", + "afii10055", + "afii10056", + "afii10057", + "afii10058", + "afii10059", + "afii10060", + "afii10061", + "afii10062", + "afii10063", + "afii10064", + "afii10065", + "afii10066", + "afii10067", + "afii10068", + "afii10069", + "afii10070", + "afii10071", + "afii10072", + "afii10073", + "afii10074", + "afii10075", + "afii10076", + "afii10077", + "afii10078", + "afii10079", + "afii10080", + "afii10081", + "afii10082", + "afii10083", + "afii10084", + "afii10085", + "afii10086", + "afii10087", + "afii10088", + "afii10089", + "afii10090", + "afii10091", + "afii10092", + "afii10093", + "afii10094", + "afii10095", + "afii10096", + "afii10097", + "afii10098", + "afii10099", + "afii10100", + "afii10101", + "afii10102", + "afii10103", + "afii10104", + "afii10105", + "afii10106", + "afii10107", + "afii10108", + "afii10109", + "afii10110", + "afii10145", + "afii10146", + "afii10147", + "afii10148", + "afii10192", + "afii10193", + "afii10194", + "afii10195", + "afii10196", + "afii10831", + "afii10832", + "afii10846", + "afii299", + "afii300", + "afii301", + "afii57381", + "afii57388", + "afii57392", + "afii57393", + "afii57394", + "afii57395", + "afii57396", + "afii57397", + "afii57398", + "afii57399", + "afii57400", + "afii57401", + "afii57403", + "afii57407", + "afii57409", + "afii57410", + "afii57411", + "afii57412", + "afii57413", + "afii57414", + "afii57415", + "afii57416", + "afii57417", + "afii57418", + "afii57419", + "afii57420", + "afii57421", + "afii57422", + "afii57423", + "afii57424", + "afii57425", + "afii57426", + "afii57427", + "afii57428", + "afii57429", + "afii57430", + "afii57431", + "afii57432", + "afii57433", + "afii57434", + "afii57440", + "afii57441", + "afii57442", + "afii57443", + "afii57444", + "afii57445", + "afii57446", + "afii57448", + "afii57449", + "afii57450", + "afii57451", + "afii57452", + "afii57453", + "afii57454", + "afii57455", + "afii57456", + "afii57457", + "afii57458", + "afii57470", + "afii57505", + "afii57506", + "afii57507", + "afii57508", + "afii57509", + "afii57511", + "afii57512", + "afii57513", + "afii57514", + "afii57519", + "afii57534", + "afii57636", + "afii57645", + "afii57658", + "afii57664", + "afii57665", + "afii57666", + "afii57667", + "afii57668", + "afii57669", + "afii57670", + "afii57671", + "afii57672", + "afii57673", + "afii57674", + "afii57675", + "afii57676", + "afii57677", + "afii57678", + "afii57679", + "afii57680", + "afii57681", + "afii57682", + "afii57683", + "afii57684", + "afii57685", + "afii57686", + "afii57687", + "afii57688", + "afii57689", + "afii57690", + "afii57694", + "afii57695", + "afii57700", + "afii57705", + "afii57716", + "afii57717", + "afii57718", + "afii57723", + "afii57793", + "afii57794", + "afii57795", + "afii57796", + "afii57797", + "afii57798", + "afii57799", + "afii57800", + "afii57801", + "afii57802", + "afii57803", + "afii57804", + "afii57806", + "afii57807", + "afii57839", + "afii57841", + "afii57842", + "afii57929", + "afii61248", + "afii61289", + "afii61352", + "afii61573", + "afii61574", + "afii61575", + "afii61664", + "afii63167", + "afii64937", + "aleph", + "alpha", + "alphatonos", + "amacron", + "angle", + "angleleft", + "angleright", + "anoteleia", + "aogonek", + "approxequal", + "aringacute", + "arrowboth", + "arrowdblboth", + "arrowdbldown", + "arrowdblleft", + "arrowdblright", + "arrowdblup", + "arrowdown", + "arrowhorizex", + "arrowleft", + "arrowright", + "arrowup", + "arrowupdn", + "arrowupdnbse", + "arrowvertex", + "asteriskmath", + "beta", + "block", + "braceex", + "braceleftbt", + "braceleftmid", + "bracelefttp", + "bracerightbt", + "bracerightmid", + "bracerighttp", + "bracketleftbt", + "bracketleftex", + "bracketlefttp", + "bracketrightbt", + "bracketrightex", + "bracketrighttp", + "cacute", + "carriagereturn", + "ccaron", + "ccircumflex", + "cdotaccent", + "chi", + "circle", + "circlemultiply", + "circleplus", + "club", + "commaaccent", + "congruent", + "copyrightsans", + "copyrightserif", + "cyrBreve", + "cyrFlex", + "cyrbreve", + "cyrflex", + "dblGrave", + "dblgrave", + "dcaron", + "dcroat", + "delta", + "diamond", + "dieresisacute", + "dieresisgrave", + "dieresistonos", + "dkshade", + "dnblock", + "dong", + "dotbelowcomb", + "dotlessj", + "dotmath", + "ebreve", + "ecaron", + "edotaccent", + "element", + "emacron", + "emptyset", + "eng", + "eogonek", + "epsilon", + "epsilontonos", + "equivalence", + "estimated", + "eta", + "etatonos", + "exclamdbl", + "existential", + "female", + "filledbox", + "filledrect", + "franc", + "gamma", + "gbreve", + "gcaron", + "gcircumflex", + "gcommaaccent", + "gdotaccent", + "gradient", + "gravecomb", + "greaterequal", + "hbar", + "hcircumflex", + "heart", + "hookabovecomb", + "house", + "ibreve", + "ij", + "imacron", + "infinity", + "integral", + "integralbt", + "integralex", + "integraltp", + "intersection", + "invbullet", + "invcircle", + "invsmileface", + "iogonek", + "iota", + "iotadieresis", + "iotadieresistonos", + "iotatonos", + "itilde", + "jcircumflex", + "kappa", + "kcommaaccent", + "kgreenlandic", + "lacute", + "lambda", + "lcaron", + "lcommaaccent", + "ldot", + "lessequal", + "lfblock", + "lira", + "ll", + "logicaland", + "logicalor", + "longs", + "lozenge", + "ltshade", + "male", + "minute", + "musicalnote", + "musicalnotedbl", + "nacute", + "napostrophe", + "ncaron", + "ncommaaccent", + "notelement", + "notequal", + "notsubset", + "nu", + "obreve", + "ohorn", + "ohungarumlaut", + "omacron", + "omega", + "omega1", + "omegatonos", + "omicron", + "omicrontonos", + "openbullet", + "orthogonal", + "oslashacute", + "parenleftbt", + "parenleftex", + "parenlefttp", + "parenrightbt", + "parenrightex", + "parenrighttp", + "partialdiff", + "perpendicular", + "peseta", + "phi", + "phi1", + "pi", + "prescription", + "product", + "propersubset", + "propersuperset", + "proportional", + "psi", + "quotereversed", + "racute", + "radical", + "radicalex", + "rcaron", + "rcommaaccent", + "reflexsubset", + "reflexsuperset", + "registersans", + "registerserif", + "revlogicalnot", + "rho", + "rtblock", + "sacute", + "scedilla", + "scedilla", + "scircumflex", + "scommaaccent", + "second", + "shade", + "sigma", + "sigma1", + "similar", + "smileface", + "spade", + "suchthat", + "summation", + "sun", + "tau", + "tbar", + "tcaron", + "tcommaaccent", + "tcommaaccent", + "therefore", + "theta", + "theta1", + "tildecomb", + "tonos", + "trademarksans", + "trademarkserif", + "triagdn", + "triaglf", + "triagrt", + "triagup", + "ubreve", + "uhorn", + "uhungarumlaut", + "umacron", + "underscoredbl", + "union", + "universal", + "uogonek", + "upblock", + "upsilon", + "upsilondieresis", + "upsilondieresistonos", + "upsilontonos", + "uring", + "utilde", + "wacute", + "wcircumflex", + "wdieresis", + "weierstrass", + "wgrave", + "xi", + "ycircumflex", + "ygrave", + "zacute", + "zdotaccent", + "zeta", + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + + NULL + }; + + + static const char* const * const sid_standard_names = ps_glyph_names + 4; + + +#define NUM_SID_GLYPHS 391 + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST +#define NUM_ADOBE_GLYPHS 1058 +#else +#define NUM_ADOBE_GLYPHS 391 +#endif + + + static const unsigned short mac_standard_names[259] = + { + 4, + 0, + 1, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 108, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 128, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 177, + 179, + 181, + 182, + 190, + 193, + 199, + 204, + 207, + 205, + 206, + 209, + 208, + 210, + 211, + 214, + 212, + 213, + 215, + 218, + 216, + 217, + 219, + 220, + 223, + 221, + 222, + 224, + 226, + 229, + 227, + 228, + 116, + 165, + 101, + 102, + 106, + 120, + 119, + 153, + 169, + 174, + 157, + 129, + 135, + 959, + 142, + 145, + 917, + 160, + 941, + 908, + 104, + 156, + 980, + 1018, + 987, + 985, + 918, + 143, + 147, + 471, + 148, + 151, + 127, + 100, + 155, + 994, + 105, + 815, + 412, + 110, + 124, + 125, + 2, + 178, + 180, + 195, + 146, + 152, + 115, + 141, + 109, + 123, + 69, + 12, + 163, + 948, + 231, + 202, + 103, + 107, + 111, + 112, + 113, + 114, + 117, + 118, + 121, + 122, + 126, + 176, + 183, + 175, + 184, + 185, + 186, + 187, + 188, + 189, + 191, + 192, + 3, + 194, + 197, + 198, + 200, + 149, + 130, + 131, + 132, + 133, + 134, + 136, + 137, + 138, + 139, + 140, + 144, + 150, + 196, + 225, + 203, + 232, + 164, + 158, + 171, + 201, + 230, + 161, + 166, + 170, + 172, + 154, + 168, + 173, + 159, + 162, + 167, + 899, + 429, + 901, + 444, + 526, + 1006, + 404, + 847, + 406, + 849, + 868, + 0 + }; + + + + static const unsigned short ps_names_to_unicode[1059] = + { + 0, + 0x0020, + 0x0021, + 0x0022, + 0x0023, + 0x0024, + 0x0025, + 0x0026, + 0x2019, + 0x0028, + 0x0029, + 0x002A, + 0x002B, + 0x002C, + 0x002D, + 0x002E, + 0x002F, + 0x0030, + 0x0031, + 0x0032, + 0x0033, + 0x0034, + 0x0035, + 0x0036, + 0x0037, + 0x0038, + 0x0039, + 0x003A, + 0x003B, + 0x003C, + 0x003D, + 0x003E, + 0x003F, + 0x0040, + 0x0041, + 0x0042, + 0x0043, + 0x0044, + 0x0045, + 0x0046, + 0x0047, + 0x0048, + 0x0049, + 0x004A, + 0x004B, + 0x004C, + 0x004D, + 0x004E, + 0x004F, + 0x0050, + 0x0051, + 0x0052, + 0x0053, + 0x0054, + 0x0055, + 0x0056, + 0x0057, + 0x0058, + 0x0059, + 0x005A, + 0x005B, + 0x005C, + 0x005D, + 0x005E, + 0x005F, + 0x2018, + 0x0061, + 0x0062, + 0x0063, + 0x0064, + 0x0065, + 0x0066, + 0x0067, + 0x0068, + 0x0069, + 0x006A, + 0x006B, + 0x006C, + 0x006D, + 0x006E, + 0x006F, + 0x0070, + 0x0071, + 0x0072, + 0x0073, + 0x0074, + 0x0075, + 0x0076, + 0x0077, + 0x0078, + 0x0079, + 0x007A, + 0x007B, + 0x007C, + 0x007D, + 0x007E, + 0x00A1, + 0x00A2, + 0x00A3, + 0x2044, + 0x00A5, + 0x0192, + 0x00A7, + 0x00A4, + 0x0027, + 0x201C, + 0x00AB, + 0x2039, + 0x203A, + 0xFB01, + 0xFB02, + 0x2013, + 0x2020, + 0x2021, + 0x00B7, + 0x00B6, + 0x2022, + 0x201A, + 0x201E, + 0x201D, + 0x00BB, + 0x2026, + 0x2030, + 0x00BF, + 0x0060, + 0x00B4, + 0x02C6, + 0x02DC, + 0x00AF, + 0x02D8, + 0x02D9, + 0x00A8, + 0x02DA, + 0x00B8, + 0x02DD, + 0x02DB, + 0x02C7, + 0x2014, + 0x00C6, + 0x00AA, + 0x0141, + 0x00D8, + 0x0152, + 0x00BA, + 0x00E6, + 0x0131, + 0x0142, + 0x00F8, + 0x0153, + 0x00DF, + 0x00B9, + 0x00AC, + 0x00B5, + 0x2122, + 0x00D0, + 0x00BD, + 0x00B1, + 0x00DE, + 0x00BC, + 0x00F7, + 0x00A6, + 0x00B0, + 0x00FE, + 0x00BE, + 0x00B2, + 0x00AE, + 0x2212, + 0x00F0, + 0x00D7, + 0x00B3, + 0x00A9, + 0x00C1, + 0x00C2, + 0x00C4, + 0x00C0, + 0x00C5, + 0x00C3, + 0x00C7, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00C8, + 0x00CD, + 0x00CE, + 0x00CF, + 0x00CC, + 0x00D1, + 0x00D3, + 0x00D4, + 0x00D6, + 0x00D2, + 0x00D5, + 0x0160, + 0x00DA, + 0x00DB, + 0x00DC, + 0x00D9, + 0x00DD, + 0x0178, + 0x017D, + 0x00E1, + 0x00E2, + 0x00E4, + 0x00E0, + 0x00E5, + 0x00E3, + 0x00E7, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00E8, + 0x00ED, + 0x00EE, + 0x00EF, + 0x00EC, + 0x00F1, + 0x00F3, + 0x00F4, + 0x00F6, + 0x00F2, + 0x00F5, + 0x0161, + 0x00FA, + 0x00FB, + 0x00FC, + 0x00F9, + 0x00FD, + 0x00FF, + 0x017E, + 0xF721, + 0xF6F8, + 0xF724, + 0xF6E4, + 0xF726, + 0xF7B4, + 0x207D, + 0x207E, + 0x2025, + 0x2024, + 0xF730, + 0xF731, + 0xF732, + 0xF733, + 0xF734, + 0xF735, + 0xF736, + 0xF737, + 0xF738, + 0xF739, + 0xF6E2, + 0xF6DE, + 0xF6E8, + 0xF73F, + 0xF6E9, + 0xF6EA, + 0xF6E0, + 0xF6EB, + 0xF6EC, + 0xF6ED, + 0xF6EE, + 0xF6EF, + 0x207F, + 0xF6F0, + 0xF6F1, + 0xF6F2, + 0xF6F3, + 0xFB00, + 0xFB03, + 0xFB04, + 0x208D, + 0x208E, + 0xF6F6, + 0xF6E6, + 0xF760, + 0xF761, + 0xF762, + 0xF763, + 0xF764, + 0xF765, + 0xF766, + 0xF767, + 0xF768, + 0xF769, + 0xF76A, + 0xF76B, + 0xF76C, + 0xF76D, + 0xF76E, + 0xF76F, + 0xF770, + 0xF771, + 0xF772, + 0xF773, + 0xF774, + 0xF775, + 0xF776, + 0xF777, + 0xF778, + 0xF779, + 0xF77A, + 0x20A1, + 0xF6DC, + 0xF6DD, + 0xF6FE, + 0xF7A1, + 0xF7A2, + 0xF6F9, + 0xF6FD, + 0xF6FF, + 0xF7A8, + 0xF6F4, + 0xF6F5, + 0xF6F7, + 0xF7AF, + 0x2012, + 0xF6E5, + 0xF6FB, + 0xF6FC, + 0xF7B8, + 0xF7BF, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + 0x2153, + 0x2154, + 0x2070, + 0x2074, + 0x2075, + 0x2076, + 0x2077, + 0x2078, + 0x2079, + 0x2080, + 0x2081, + 0x2082, + 0x2083, + 0x2084, + 0x2085, + 0x2086, + 0x2087, + 0x2088, + 0x2089, + 0xF6DF, + 0xF6E3, + 0xF6E7, + 0xF6E1, + 0xF7E0, + 0xF7E1, + 0xF7E2, + 0xF7E3, + 0xF7E4, + 0xF7E5, + 0xF7E6, + 0xF7E7, + 0xF7E8, + 0xF7E9, + 0xF7EA, + 0xF7EB, + 0xF7EC, + 0xF7ED, + 0xF7EE, + 0xF7EF, + 0xF7F0, + 0xF7F1, + 0xF7F2, + 0xF7F3, + 0xF7F4, + 0xF7F5, + 0xF7F6, + 0xF6FA, + 0xF7F8, + 0xF7F9, + 0xF7FA, + 0xF7FB, + 0xF7FC, + 0xF7FD, + 0xF7FE, + 0xF7FF, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + +#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + 0x01FC, + 0x0102, + 0xF6C9, + 0x0391, + 0x0386, + 0x0100, + 0x0104, + 0x01FA, + 0x0392, + 0x0106, + 0xF6CA, + 0x010C, + 0x0108, + 0x010A, + 0x03A7, + 0x010E, + 0x0110, + 0x2206, + 0x2206, + 0xF6CB, + 0xF6CC, + 0xF6CD, + 0x0114, + 0x011A, + 0x0116, + 0x0112, + 0x014A, + 0x0118, + 0x0395, + 0x0388, + 0x0397, + 0x0389, + 0x20AC, + 0x0393, + 0x011E, + 0x01E6, + 0x011C, + 0x0122, + 0x0120, + 0xF6CE, + 0x25CF, + 0x25AA, + 0x25AB, + 0x25A1, + 0x0126, + 0x0124, + 0xF6CF, + 0x0132, + 0x012C, + 0x0130, + 0x2111, + 0x012A, + 0x012E, + 0x0399, + 0x03AA, + 0x038A, + 0x0128, + 0x0134, + 0x039A, + 0x0136, + 0xF6BF, + 0x0139, + 0x039B, + 0x013D, + 0x013B, + 0x013F, + 0xF6D0, + 0x039C, + 0x0143, + 0x0147, + 0x0145, + 0x039D, + 0x014E, + 0x01A0, + 0x0150, + 0x014C, + 0x2126, + 0x2126, + 0x038F, + 0x039F, + 0x038C, + 0x01FE, + 0x03A6, + 0x03A0, + 0x03A8, + 0x0154, + 0x0158, + 0x0156, + 0x211C, + 0x03A1, + 0x250C, + 0x2514, + 0x2510, + 0x2518, + 0x253C, + 0x252C, + 0x2534, + 0x251C, + 0x2524, + 0x2500, + 0x2502, + 0x2561, + 0x2562, + 0x2556, + 0x2555, + 0x2563, + 0x2551, + 0x2557, + 0x255D, + 0x255C, + 0x255B, + 0x255E, + 0x255F, + 0x255A, + 0x2554, + 0x2569, + 0x2566, + 0x2560, + 0x2550, + 0x256C, + 0x2567, + 0x2568, + 0x2564, + 0x2565, + 0x2559, + 0x2558, + 0x2552, + 0x2553, + 0x256B, + 0x256A, + 0x015A, + 0x015E, + 0x015E, + 0x015C, + 0x0218, + 0x03A3, + 0x03A4, + 0x0166, + 0x0164, + 0x0162, + 0x0162, + 0x0398, + 0x016C, + 0x01AF, + 0x0170, + 0x016A, + 0x0172, + 0x03A5, + 0x03D2, + 0x03AB, + 0x038E, + 0x016E, + 0x0168, + 0x1E82, + 0x0174, + 0x1E84, + 0x1E80, + 0x039E, + 0x0176, + 0x1EF2, + 0x0179, + 0x017B, + 0x0396, + 0x0103, + 0x0301, + 0x01FD, + 0x2015, + 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, + 0x0490, + 0x0402, + 0x0403, + 0x0404, + 0x0405, + 0x0406, + 0x0407, + 0x0408, + 0x0409, + 0x040A, + 0x040B, + 0x040C, + 0x040E, + 0xF6C4, + 0xF6C5, + 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, + 0x0491, + 0x0452, + 0x0453, + 0x0454, + 0x0455, + 0x0456, + 0x0457, + 0x0458, + 0x0459, + 0x045A, + 0x045B, + 0x045C, + 0x045E, + 0x040F, + 0x0462, + 0x0472, + 0x0474, + 0xF6C6, + 0x045F, + 0x0463, + 0x0473, + 0x0475, + 0xF6C7, + 0xF6C8, + 0x04D9, + 0x200E, + 0x200F, + 0x200D, + 0x066A, + 0x060C, + 0x0660, + 0x0661, + 0x0662, + 0x0663, + 0x0664, + 0x0665, + 0x0666, + 0x0667, + 0x0668, + 0x0669, + 0x061B, + 0x061F, + 0x0621, + 0x0622, + 0x0623, + 0x0624, + 0x0625, + 0x0626, + 0x0627, + 0x0628, + 0x0629, + 0x062A, + 0x062B, + 0x062C, + 0x062D, + 0x062E, + 0x062F, + 0x0630, + 0x0631, + 0x0632, + 0x0633, + 0x0634, + 0x0635, + 0x0636, + 0x0637, + 0x0638, + 0x0639, + 0x063A, + 0x0640, + 0x0641, + 0x0642, + 0x0643, + 0x0644, + 0x0645, + 0x0646, + 0x0648, + 0x0649, + 0x064A, + 0x064B, + 0x064C, + 0x064D, + 0x064E, + 0x064F, + 0x0650, + 0x0651, + 0x0652, + 0x0647, + 0x06A4, + 0x067E, + 0x0686, + 0x0698, + 0x06AF, + 0x0679, + 0x0688, + 0x0691, + 0x06BA, + 0x06D2, + 0x06D5, + 0x20AA, + 0x05BE, + 0x05C3, + 0x05D0, + 0x05D1, + 0x05D2, + 0x05D3, + 0x05D4, + 0x05D5, + 0x05D6, + 0x05D7, + 0x05D8, + 0x05D9, + 0x05DA, + 0x05DB, + 0x05DC, + 0x05DD, + 0x05DE, + 0x05DF, + 0x05E0, + 0x05E1, + 0x05E2, + 0x05E3, + 0x05E4, + 0x05E5, + 0x05E6, + 0x05E7, + 0x05E8, + 0x05E9, + 0x05EA, + 0xFB2A, + 0xFB2B, + 0xFB4B, + 0xFB1F, + 0x05F0, + 0x05F1, + 0x05F2, + 0xFB35, + 0x05B4, + 0x05B5, + 0x05B6, + 0x05BB, + 0x05B8, + 0x05B7, + 0x05B0, + 0x05B2, + 0x05B1, + 0x05B3, + 0x05C2, + 0x05C1, + 0x05B9, + 0x05BC, + 0x05BD, + 0x05BF, + 0x05C0, + 0x02BC, + 0x2105, + 0x2113, + 0x2116, + 0x202C, + 0x202D, + 0x202E, + 0x200C, + 0x066D, + 0x02BD, + 0x2135, + 0x03B1, + 0x03AC, + 0x0101, + 0x2220, + 0x2329, + 0x232A, + 0x0387, + 0x0105, + 0x2248, + 0x01FB, + 0x2194, + 0x21D4, + 0x21D3, + 0x21D0, + 0x21D2, + 0x21D1, + 0x2193, + 0xF8E7, + 0x2190, + 0x2192, + 0x2191, + 0x2195, + 0x21A8, + 0xF8E6, + 0x2217, + 0x03B2, + 0x2588, + 0xF8F4, + 0xF8F3, + 0xF8F2, + 0xF8F1, + 0xF8FE, + 0xF8FD, + 0xF8FC, + 0xF8F0, + 0xF8EF, + 0xF8EE, + 0xF8FB, + 0xF8FA, + 0xF8F9, + 0x0107, + 0x21B5, + 0x010D, + 0x0109, + 0x010B, + 0x03C7, + 0x25CB, + 0x2297, + 0x2295, + 0x2663, + 0xF6C3, + 0x2245, + 0xF8E9, + 0xF6D9, + 0xF6D1, + 0xF6D2, + 0xF6D4, + 0xF6D5, + 0xF6D3, + 0xF6D6, + 0x010F, + 0x0111, + 0x03B4, + 0x2666, + 0xF6D7, + 0xF6D8, + 0x0385, + 0x2593, + 0x2584, + 0x20AB, + 0x0323, + 0xF6BE, + 0x22C5, + 0x0115, + 0x011B, + 0x0117, + 0x2208, + 0x0113, + 0x2205, + 0x014B, + 0x0119, + 0x03B5, + 0x03AD, + 0x2261, + 0x212E, + 0x03B7, + 0x03AE, + 0x203C, + 0x2203, + 0x2640, + 0x25A0, + 0x25AC, + 0x20A3, + 0x03B3, + 0x011F, + 0x01E7, + 0x011D, + 0x0123, + 0x0121, + 0x2207, + 0x0300, + 0x2265, + 0x0127, + 0x0125, + 0x2665, + 0x0309, + 0x2302, + 0x012D, + 0x0133, + 0x012B, + 0x221E, + 0x222B, + 0x2321, + 0xF8F5, + 0x2320, + 0x2229, + 0x25D8, + 0x25D9, + 0x263B, + 0x012F, + 0x03B9, + 0x03CA, + 0x0390, + 0x03AF, + 0x0129, + 0x0135, + 0x03BA, + 0x0137, + 0x0138, + 0x013A, + 0x03BB, + 0x013E, + 0x013C, + 0x0140, + 0x2264, + 0x258C, + 0x20A4, + 0xF6C0, + 0x2227, + 0x2228, + 0x017F, + 0x25CA, + 0x2591, + 0x2642, + 0x2032, + 0x266A, + 0x266B, + 0x0144, + 0x0149, + 0x0148, + 0x0146, + 0x2209, + 0x2260, + 0x2284, + 0x03BD, + 0x014F, + 0x01A1, + 0x0151, + 0x014D, + 0x03C9, + 0x03D6, + 0x03CE, + 0x03BF, + 0x03CC, + 0x25E6, + 0x221F, + 0x01FF, + 0xF8ED, + 0xF8EC, + 0xF8EB, + 0xF8F8, + 0xF8F7, + 0xF8F6, + 0x2202, + 0x22A5, + 0x20A7, + 0x03C6, + 0x03D5, + 0x03C0, + 0x211E, + 0x220F, + 0x2282, + 0x2283, + 0x221D, + 0x03C8, + 0x201B, + 0x0155, + 0x221A, + 0xF8E5, + 0x0159, + 0x0157, + 0x2286, + 0x2287, + 0xF8E8, + 0xF6DA, + 0x2310, + 0x03C1, + 0x2590, + 0x015B, + 0x015F, + 0x015F, + 0x015D, + 0x0219, + 0x2033, + 0x2592, + 0x03C3, + 0x03C2, + 0x223C, + 0x263A, + 0x2660, + 0x220B, + 0x2211, + 0x263C, + 0x03C4, + 0x0167, + 0x0165, + 0x0163, + 0x0163, + 0x2234, + 0x03B8, + 0x03D1, + 0x0303, + 0x0384, + 0xF8EA, + 0xF6DB, + 0x25BC, + 0x25C4, + 0x25BA, + 0x25B2, + 0x016D, + 0x01B0, + 0x0171, + 0x016B, + 0x2017, + 0x222A, + 0x2200, + 0x0173, + 0x2580, + 0x03C5, + 0x03CB, + 0x03B0, + 0x03CD, + 0x016F, + 0x0169, + 0x1E83, + 0x0175, + 0x1E85, + 0x2118, + 0x1E81, + 0x03BE, + 0x0177, + 0x1EF3, + 0x017A, + 0x017C, + 0x03B6, + +#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ + 0 + }; + + + + static const unsigned short t1_standard_encoding[257] = + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 0, + 111, + 112, + 113, + 114, + 0, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 0, + 123, + 0, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 0, + 132, + 133, + 0, + 134, + 135, + 136, + 137, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 138, + 0, + 139, + 0, + 0, + 0, + 0, + 140, + 141, + 142, + 143, + 0, + 0, + 0, + 0, + 0, + 144, + 0, + 0, + 0, + 145, + 0, + 0, + 146, + 147, + 148, + 149, + 0, + 0, + 0, + 0, + 0 + }; + + + static const unsigned short t1_expert_encoding[257] = + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 229, + 230, + 0, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 13, + 14, + 15, + 99, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 27, + 28, + 249, + 250, + 251, + 252, + 0, + 253, + 254, + 255, + 256, + 257, + 0, + 0, + 0, + 258, + 0, + 0, + 259, + 260, + 261, + 262, + 0, + 0, + 263, + 264, + 265, + 0, + 266, + 109, + 110, + 267, + 268, + 269, + 0, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 304, + 305, + 306, + 0, + 0, + 307, + 308, + 309, + 310, + 311, + 0, + 312, + 0, + 0, + 313, + 0, + 0, + 314, + 315, + 0, + 0, + 316, + 317, + 318, + 0, + 0, + 0, + 158, + 155, + 163, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 0, + 0, + 326, + 150, + 164, + 169, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 0 + }; + + +/* END */ diff --git a/lib/freetype/src/psnames/rules.mk b/lib/freetype/src/psnames/rules.mk new file mode 100644 index 0000000..4a4b82e --- /dev/null +++ b/lib/freetype/src/psnames/rules.mk @@ -0,0 +1,71 @@ +# +# FreeType 2 PSNames driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# PSNames driver directory +# +PSNAMES_DIR := $(SRC_)psnames +PSNAMES_DIR_ := $(PSNAMES_DIR)$(SEP) + + +# compilation flags for the driver +# +PSNAMES_COMPILE := $(FT_COMPILE) $I$(PSNAMES_DIR) + + +# PSNames driver sources (i.e., C files) +# +PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c + + +# PSNames driver headers +# +PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ + $(PSNAMES_DIR_)pstables.h \ + $(PSNAMES_DIR_)psnamerr.h + + +# PSNames driver object(s) +# +# PSNAMES_DRV_OBJ_M is used during `multi' builds +# PSNAMES_DRV_OBJ_S is used during `single' builds +# +PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR_)%.c=$(OBJ_)%.$O) +PSNAMES_DRV_OBJ_S := $(OBJ_)psnames.$O + +# PSNames driver source file for single build +# +PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c + + +# PSNames driver - single object +# +$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ + $(FREETYPE_H) $(PSNAMES_DRV_H) + $(PSNAMES_COMPILE) $T$@ $(PSNAMES_DRV_SRC_S) + + +# PSNames driver - multiple objects +# +$(OBJ_)%.$O: $(PSNAMES_DIR_)%.c $(FREETYPE_H) $(PSNAMES_DRV_H) + $(PSNAMES_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) +DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/raster/Jamfile b/lib/freetype/src/raster/Jamfile new file mode 100644 index 0000000..01b5c0d --- /dev/null +++ b/lib/freetype/src/raster/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/raster Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) raster ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftraster ftrend1 ; + } + else + { + _sources = raster ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/raster Jamfile diff --git a/lib/freetype/src/raster/descrip.mms b/lib/freetype/src/raster/descrip.mms new file mode 100644 index 0000000..d0650eb --- /dev/null +++ b/lib/freetype/src/raster/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 renderer module compilation rules for VMS +# + + +# Copyright 2001 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.raster]) + +OBJS=raster.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/raster/ftraster.c b/lib/freetype/src/raster/ftraster.c new file mode 100644 index 0000000..654a81e --- /dev/null +++ b/lib/freetype/src/raster/ftraster.c @@ -0,0 +1,3288 @@ +/***************************************************************************/ +/* */ +/* ftraster.c */ +/* */ +/* The FreeType glyph rasterizer (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 a rewrite of the FreeType 1.x scan-line converter */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include "ftraster.h" +#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ + + + /*************************************************************************/ + /* */ + /* A simple technical note on how the raster works */ + /* ----------------------------------------------- */ + /* */ + /* Converting an outline into a bitmap is achieved in several steps: */ + /* */ + /* 1 - Decomposing the outline into successive `profiles'. Each */ + /* profile is simply an array of scanline intersections on a given */ + /* dimension. A profile's main attributes are */ + /* */ + /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ + /* */ + /* o an array of intersection coordinates for each scanline */ + /* between `Ymin' and `Ymax'. */ + /* */ + /* o a direction, indicating whether it was built going `up' or */ + /* `down', as this is very important for filling rules. */ + /* */ + /* 2 - Sweeping the target map's scanlines in order to compute segment */ + /* `spans' which are then filled. Additionally, this pass */ + /* performs drop-out control. */ + /* */ + /* The outline data is parsed during step 1 only. The profiles are */ + /* built from the bottom of the render pool, used as a stack. The */ + /* following graphics shows the profile list under construction: */ + /* */ + /* ____________________________________________________________ _ _ */ + /* | | | | | */ + /* | profile | coordinates for | profile | coordinates for |--> */ + /* | 1 | profile 1 | 2 | profile 2 |--> */ + /* |_________|___________________|_________|_________________|__ _ _ */ + /* */ + /* ^ ^ */ + /* | | */ + /* start of render pool top */ + /* */ + /* The top of the profile stack is kept in the `top' variable. */ + /* */ + /* As you can see, a profile record is pushed on top of the render */ + /* pool, which is then followed by its coordinates/intersections. If */ + /* a change of direction is detected in the outline, a new profile is */ + /* generated until the end of the outline. */ + /* */ + /* Note that when all profiles have been generated, the function */ + /* Finalize_Profile_Table() is used to record, for each profile, its */ + /* bottom-most scanline as well as the scanline above its upmost */ + /* boundary. These positions are called `y-turns' because they (sort */ + /* of) correspond to local extrema. They are stored in a sorted list */ + /* built from the top of the render pool as a downwards stack: */ + /* */ + /* _ _ _______________________________________ */ + /* | | */ + /* <--| sorted list of | */ + /* <--| extrema scanlines | */ + /* _ _ __________________|____________________| */ + /* */ + /* ^ ^ */ + /* | | */ + /* maxBuff sizeBuff = end of pool */ + /* */ + /* This list is later used during the sweep phase in order to */ + /* optimize performance (see technical note on the sweep below). */ + /* */ + /* Of course, the raster detects whether the two stacks collide and */ + /* handles the situation propertly. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** CONFIGURATION MACROS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /* define DEBUG_RASTER if you want to compile a debugging version */ +#define xxxDEBUG_RASTER + + /* The default render pool size in bytes */ +#define RASTER_RENDER_POOL 8192 + + /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ + /* 5-levels anti-aliasing */ +#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS +#define FT_RASTER_OPTION_ANTI_ALIASING +#endif + + /* The size of the two-lines intermediate bitmap used */ + /* for anti-aliasing, in bytes. */ +#define RASTER_GRAY_LINES 2048 + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** OTHER MACROS (do not change) **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_raster + + +#ifdef _STANDALONE_ + + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + /* Disable the tracing mechanism for simplicity -- developers can */ + /* activate it easily by redefining these two macros. */ +#ifndef FT_ERROR +#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#endif + +#ifndef FT_TRACE +#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ +#endif + +#define Raster_Err_None 0 +#define Raster_Err_Not_Ini -1 +#define Raster_Err_Overflow -2 +#define Raster_Err_Neg_Height -3 +#define Raster_Err_Invalid -4 +#define Raster_Err_Unsupported -5 + + +#else /* _STANDALONE_ */ + + +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */ + +#include "rasterrs.h" + +#define Raster_Err_None Raster_Err_Ok +#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized +#define Raster_Err_Overflow Raster_Err_Raster_Overflow +#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height +#define Raster_Err_Invalid Raster_Err_Invalid_Outline +#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph + + +#endif /* _STANDALONE_ */ + + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + + + /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ + /* typically a small value and the result of a*b is known to fit into */ + /* 32 bits. */ +#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) + + /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ + /* for clipping computations. It simply uses the FT_MulDiv() function */ + /* defined in `ftcalc.h'. */ +#define SMulDiv FT_MulDiv + + /* 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 + +#ifndef SUCCESS +#define SUCCESS 0 +#endif + +#ifndef FAILURE +#define FAILURE 1 +#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 */ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SIMPLE TYPE DECLARATIONS **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + typedef int Int; + typedef unsigned int UInt; + typedef short Short; + typedef unsigned short UShort, *PUShort; + typedef long Long, *PLong; + typedef unsigned long ULong; + + typedef unsigned char Byte, *PByte; + typedef char Bool; + + typedef struct TPoint_ + { + Long x; + Long y; + + } TPoint; + + + typedef enum TFlow_ + { + Flow_None = 0, + Flow_Up = 1, + Flow_Down = -1 + + } TFlow; + + + /* States of each line, arc, and profile */ + typedef enum TStates_ + { + Unknown_State, + Ascending_State, + Descending_State, + Flat_State + + } TStates; + + + typedef struct TProfile_ TProfile; + typedef TProfile* PProfile; + + struct TProfile_ + { + FT_F26Dot6 X; /* current coordinate during sweep */ + PProfile link; /* link to next profile - various purpose */ + PLong 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 */ + + unsigned 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; + + + /* Simple record used to implement a stack of bands, required */ + /* by the sub-banding mechanism */ + typedef struct TBand_ + { + Short y_min; /* band's minimum */ + Short y_max; /* band's maximum */ + + } TBand; + + +#define AlignProfileSize \ + ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) ) + + +#ifdef TT_STATIC_RASTER + + +#define RAS_ARGS /* void */ +#define RAS_ARG /* void */ + +#define RAS_VARS /* void */ +#define RAS_VAR /* void */ + +#define FT_UNUSED_RASTER do ; while ( 0 ) + + +#else /* TT_STATIC_RASTER */ + + +#define RAS_ARGS TRaster_Instance* raster, +#define RAS_ARG TRaster_Instance* raster + +#define RAS_VARS raster, +#define RAS_VAR raster + +#define FT_UNUSED_RASTER FT_UNUSED( raster ) + + +#endif /* TT_STATIC_RASTER */ + + + typedef struct TRaster_Instance_ TRaster_Instance; + + + /* 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, + FT_F26Dot6 x1, + FT_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 ) + + /* 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 */ + + PLong buff; /* The profiles buffer */ + PLong sizeBuff; /* Render pool size */ + PLong maxBuff; /* Profiles buffer size */ + PLong top; /* Current cursor in buffer */ + + FT_Error error; + + 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 */ + + FT_Bitmap target; /* description of target bit/pixmap */ + FT_Outline outline; + + 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; + + Byte dropOutControl; /* current drop_out control method */ + + 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[3 * 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 */ + + void* memory; + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + Byte grays[5]; /* Palette of gray levels used for */ + /* render. */ + + Byte gray_lines[RASTER_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'. */ + +#endif /* FT_RASTER_ANTI_ALIASING */ + +#if 0 + PByte flags; /* current flags table */ + PUShort outs; /* current outlines table */ + FT_Vector* coords; + + UShort nPoints; /* number of points in current glyph */ + Short nContours; /* number of contours in current glyph */ +#endif + + }; + + +#ifdef FT_CONFIG_OPTION_STATIC_RASTER + + static TRaster_Instance cur_ras; +#define ras cur_ras + +#else + +#define ras (*raster) + +#endif /* FT_CONFIG_OPTION_STATIC_RASTER */ + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** PROFILES COMPUTATION **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <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 Int 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; + } + + FT_TRACE6(( "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 :: The state/orientation of the new profile. */ + /* */ + /* <Return> */ + /* 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_State: + ras.cProfile->flow = Flow_Up; + FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); + break; + + case Descending_State: + ras.cProfile->flow = Flow_Down; + FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); + break; + + default: + FT_ERROR(( "New_Profile: invalid profile direction!\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. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ + /* */ + static Bool + End_Profile( RAS_ARG ) + { + Long h; + PProfile oldProfile; + + + h = (Long)( ras.top - ras.cProfile->offset ); + + if ( h < 0 ) + { + FT_ERROR(( "End_Profile: negative height encountered!\n" )); + ras.error = Raster_Err_Neg_Height; + return FAILURE; + } + + if ( h > 0 ) + { + FT_TRACE6(( "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 ) + { + FT_TRACE1(( "overflow in End_Profile\n" )); + ras.error = Raster_Err_Overflow; + return FAILURE; + } + + ras.joint = FALSE; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Insert_Y_Turn */ + /* */ + /* <Description> */ + /* Inserts a salient into the sorted list placed on top of the render */ + /* pool. */ + /* */ + /* <Input> */ + /* New y scanline position. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + static Bool + Insert_Y_Turn( RAS_ARGS Int y ) + { + PLong 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 = (Int)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. */ + /* */ + /* <Return> */ + /* SUCCESS on success. FAILURE in case of overflow. */ + /* */ + 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 Flow_Down: + bottom = (Int)( p->start - p->height + 1 ); + top = (Int)p->start; + p->start = bottom; + p->offset += p->height - 1; + break; + + case Flow_Up: + default: + bottom = (Int)p->start; + top = (Int)( 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_Conic */ + /* */ + /* <Description> */ + /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */ + /* stack. */ + /* */ + /* <Input> */ + /* None (subdivided Bezier is taken from the top of the stack). */ + /* */ + /* <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_Conic( 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 to be too good at common */ + /* expression substitution and instruction scheduling ;-) */ + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Split_Cubic */ + /* */ + /* <Description> */ + /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */ + /* Bezier stack. */ + /* */ + /* <Note> */ + /* This routine is the `beef' of the component. It is one of _the_ */ + /* inner loops that should be optimized like hell to get the best */ + /* performance. */ + /* */ + static void + Split_Cubic( TPoint* base ) + { + Long a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c + 1 ) >> 1; + base[5].x = b = ( base[3].x + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].x = a = ( a + c + 1 ) >> 1; + base[4].x = b = ( b + c + 1 ) >> 1; + base[3].x = ( a + b + 1 ) >> 1; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c + 1 ) >> 1; + base[5].y = b = ( base[3].y + d + 1 ) >> 1; + c = ( c + d + 1 ) >> 1; + base[2].y = a = ( a + c + 1 ) >> 1; + base[4].y = b = ( b + c + 1 ) >> 1; + base[3].y = ( a + b + 1 ) >> 1; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Up */ + /* */ + /* <Description> */ + /* Computes the x-coordinates of an ascending line segment and stores */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* 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; + + PLong 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 = (Int)TRUNC( y1 ); + f1 = (Int)FRAC( y1 ); + } + + if ( y2 > maxy ) + { + /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ + e2 = (Int)TRUNC( maxy ); + f2 = 0; + } + else + { + e2 = (Int)TRUNC( y2 ); + f2 = (Int)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 = (char)( 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; + + x1 += Ix; + Ax += Rx; + if ( Ax >= 0 ) + { + Ax -= Dy; + x1 += Dx; + } + size--; + } + + ras.top = top; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Line_Down */ + /* */ + /* <Description> */ + /* Computes the x-coordinates of an descending line segment and */ + /* stores them in the render pool. */ + /* */ + /* <Input> */ + /* x1 :: The x-coordinate of the segment's start point. */ + /* */ + /* y1 :: The y-coordinate of the segment's start point. */ + /* */ + /* x2 :: The x-coordinate of the segment's end point. */ + /* */ + /* y2 :: The y-coordinate of the segment's end point. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + 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; + } + + + /* A function type describing the functions used to split Bezier arcs */ + typedef void (*TSplitter)( TPoint* base ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Up */ + /* */ + /* <Description> */ + /* Computes the x-coordinates of an ascending Bezier arc and stores */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Up( RAS_ARGS Int degree, + TSplitter splitter, + Long miny, + Long maxy ) + { + Long y1, y2, e, e2, e0; + Short f1; + + TPoint* arc; + TPoint* start_arc; + + PLong top; + + + arc = ras.arc; + y1 = arc[degree].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 = (Short)( FRAC( y1 ) ); + e0 = e; + + if ( f1 == 0 ) + { + if ( ras.joint ) + { + top--; + ras.joint = FALSE; + } + + *top++ = arc[degree].x; + + 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[degree].y; + if ( y2 - y1 >= ras.precision_step ) + { + splitter( arc ); + arc += degree; + } + else + { + *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, + e - y1, y2 - y1 ); + arc -= degree; + e += ras.precision; + } + } + else + { + if ( y2 == e ) + { + ras.joint = TRUE; + *top++ = arc[0].x; + + e += ras.precision; + } + arc -= degree; + } + } + + Fin: + ras.top = top; + ras.arc -= degree; + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Bezier_Down */ + /* */ + /* <Description> */ + /* Computes the x-coordinates of an descending Bezier arc and stores */ + /* them in the render pool. */ + /* */ + /* <Input> */ + /* degree :: The degree of the Bezier arc (either 2 or 3). */ + /* */ + /* splitter :: The function to split Bezier arcs. */ + /* */ + /* miny :: A lower vertical clipping bound value. */ + /* */ + /* maxy :: An upper vertical clipping bound value. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow. */ + /* */ + static Bool + Bezier_Down( RAS_ARGS Int degree, + TSplitter splitter, + 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; + if ( degree > 2 ) + arc[3].y = -arc[3].y; + + fresh = ras.fresh; + + result = Bezier_Up( RAS_VARS degree, splitter, -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 :: The x-coordinate of the segment's end point (its start point */ + /* is stored in `LastX'). */ + /* */ + /* y :: The y-coordinate of the segment's end point (its start point */ + /* is stored in `LastY'). */ + /* */ + /* <Return> */ + /* 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_State: + if ( y > ras.lastY ) + { + if ( New_Profile( RAS_VARS Ascending_State ) ) + return FAILURE; + } + else + { + if ( y < ras.lastY ) + if ( New_Profile( RAS_VARS Descending_State ) ) + return FAILURE; + } + break; + + case Ascending_State: + if ( y < ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Descending_State ) ) + return FAILURE; + } + break; + + case Descending_State: + if ( y > ras.lastY ) + { + if ( End_Profile( RAS_VAR ) || + New_Profile( RAS_VARS Ascending_State ) ) + return FAILURE; + } + break; + + default: + ; + } + + /* Then compute the lines */ + + switch ( ras.state ) + { + case Ascending_State: + if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, + x, y, ras.minY, ras.maxY ) ) + return FAILURE; + break; + + case Descending_State: + 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> */ + /* Conic_To */ + /* */ + /* <Description> */ + /* Injects a new conic arc and adjusts the profile list. */ + /* */ + /* <Input> */ + /* cx :: The x-coordinate of the arc's new control point. */ + /* */ + /* cy :: The y-coordinate of the arc's new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `LastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `LastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Conic_To( RAS_ARGS Long cx, + Long cy, + Long x, + Long y ) + { + Long y1, y2, y3, x3, ymin, ymax; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[2].x = ras.lastX; + ras.arc[2].y = ras.lastY; + ras.arc[1].x = cx; ras.arc[1].y = cy; + ras.arc[0].x = x; ras.arc[0].y = 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 <= y3 ) + { + ymin = y1; + ymax = y3; + } + else + { + ymin = y3; + ymax = y1; + } + + if ( y2 < ymin || y2 > ymax ) + { + /* this arc has no given direction, split it! */ + Split_Conic( ras.arc ); + ras.arc += 2; + } + else if ( y1 == y3 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 2; + } + else + { + /* the arc is y-monotonous, either ascending or descending */ + /* detect a change of direction */ + state_bez = y1 < y3 ? Ascending_State : Descending_State; + if ( ras.state != state_bez ) + { + /* finalize current profile if any */ + if ( ras.state != Unknown_State && + End_Profile( RAS_VAR ) ) + goto Fail; + + /* create a new profile */ + if ( New_Profile( RAS_VARS state_bez ) ) + goto Fail; + } + + /* now call the appropriate routine */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x3; + ras.lastY = y3; + + return SUCCESS; + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Cubic_To */ + /* */ + /* <Description> */ + /* Injects a new cubic arc and adjusts the profile list. */ + /* */ + /* <Input> */ + /* cx1 :: The x-coordinate of the arc's first new control point. */ + /* */ + /* cy1 :: The y-coordinate of the arc's first new control point. */ + /* */ + /* cx2 :: The x-coordinate of the arc's second new control point. */ + /* */ + /* cy2 :: The y-coordinate of the arc's second new control point. */ + /* */ + /* x :: The x-coordinate of the arc's end point (its start point is */ + /* stored in `LastX'). */ + /* */ + /* y :: The y-coordinate of the arc's end point (its start point is */ + /* stored in `LastY'). */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ + /* profile. */ + /* */ + static Bool + Cubic_To( RAS_ARGS Long cx1, + Long cy1, + Long cx2, + Long cy2, + Long x, + Long y ) + { + Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; + TStates state_bez; + + + ras.arc = ras.arcs; + ras.arc[3].x = ras.lastX; + ras.arc[3].y = ras.lastY; + ras.arc[2].x = cx1; ras.arc[2].y = cy1; + ras.arc[1].x = cx2; ras.arc[1].y = cy2; + ras.arc[0].x = x; ras.arc[0].y = y; + + do + { + y1 = ras.arc[3].y; + y2 = ras.arc[2].y; + y3 = ras.arc[1].y; + y4 = ras.arc[0].y; + x4 = ras.arc[0].x; + + /* first, categorize the Bezier arc */ + + if ( y1 <= y4 ) + { + ymin1 = y1; + ymax1 = y4; + } + else + { + ymin1 = y4; + ymax1 = y1; + } + + if ( y2 <= y3 ) + { + ymin2 = y2; + ymax2 = y3; + } + else + { + ymin2 = y3; + ymax2 = y2; + } + + if ( ymin2 < ymin1 || ymax2 > ymax1 ) + { + /* this arc has no given direction, split it! */ + Split_Cubic( ras.arc ); + ras.arc += 3; + } + else if ( y1 == y4 ) + { + /* this arc is flat, ignore it and pop it from the Bezier stack */ + ras.arc -= 3; + } + else + { + state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; + + /* detect a change of direction */ + if ( ras.state != state_bez ) + { + if ( ras.state != Unknown_State && + End_Profile( RAS_VAR ) ) + goto Fail; + + if ( New_Profile( RAS_VARS state_bez ) ) + goto Fail; + } + + /* compute intersections */ + if ( state_bez == Ascending_State ) + { + if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + else + if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) + goto Fail; + } + + } while ( ras.arc >= ras.arcs ); + + ras.lastX = x4; + ras.lastY = y4; + + return SUCCESS; + + Fail: + return FAILURE; + } + + +#undef SWAP_ +#define SWAP_( x, y ) do \ + { \ + Long swap = x; \ + \ + \ + x = y; \ + y = swap; \ + } while ( 0 ) + + + /*************************************************************************/ + /* */ + /* <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 :: The index of the first point in the contour. */ + /* */ + /* last :: The index of the last point in the contour. */ + /* */ + /* flipped :: If set, flip the direction of the curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE on error. */ + /* */ + static Bool + Decompose_Curve( RAS_ARGS UShort first, + UShort last, + int flipped ) + { + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* points; + FT_Vector* point; + FT_Vector* limit; + char* tags; + + unsigned tag; /* current point's state */ + + + points = ras.outline.points; + limit = points + last; + + v_start.x = SCALED( points[first].x ); + v_start.y = SCALED( points[first].y ); + v_last.x = SCALED( points[last].x ); + v_last.y = SCALED( points[last].y ); + + if ( flipped ) + { + SWAP_( v_start.x, v_start.y ); + SWAP_( v_last.x, v_last.y ); + } + + v_control = v_start; + + point = points + first; + tags = ras.outline.tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + ras.lastX = v_start.x; + ras.lastY = v_start.y; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + Long x, y; + + + x = SCALED( point->x ); + y = SCALED( point->y ); + if ( flipped ) + SWAP_( x, y ); + + if ( Line_To( RAS_VARS x, y ) ) + goto Fail; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + v_control.x = SCALED( point[0].x ); + v_control.y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( v_control.x, v_control.y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector v_middle; + Long x, y; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + x = SCALED( point[0].x ); + y = SCALED( point[0].y ); + + if ( flipped ) + SWAP_( x, y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) + goto Fail; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + x ) / 2; + v_middle.y = ( v_control.y + y ) / 2; + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_middle.x, v_middle.y ) ) + goto Fail; + + v_control.x = x; + v_control.y = y; + + goto Do_Conic; + } + + if ( Conic_To( RAS_VARS v_control.x, v_control.y, + v_start.x, v_start.y ) ) + goto Fail; + + goto Close; + + default: /* FT_CURVE_TAG_CUBIC */ + { + Long x1, y1, x2, y2, x3, y3; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + x1 = SCALED( point[-2].x ); + y1 = SCALED( point[-2].y ); + x2 = SCALED( point[-1].x ); + y2 = SCALED( point[-1].y ); + x3 = SCALED( point[ 0].x ); + y3 = SCALED( point[ 0].y ); + + if ( flipped ) + { + SWAP_( x1, y1 ); + SWAP_( x2, y2 ); + SWAP_( x3, y3 ); + } + + if ( point <= limit ) + { + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) + goto Fail; + continue; + } + + if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) + goto Fail; + goto Close; + } + } + } + + /* close the contour with a line segment */ + if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) + goto Fail; + + Close: + return SUCCESS; + + Invalid_Outline: + ras.error = Raster_Err_Invalid; + + Fail: + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Convert_Glyph */ + /* */ + /* <Description> */ + /* Converts a glyph into a series of segments and arcs and makes a */ + /* profiles list with them. */ + /* */ + /* <Input> */ + /* flipped :: If set, flip the direction of curve. */ + /* */ + /* <Return> */ + /* SUCCESS on success, FAILURE if any error was encountered during */ + /* rendering. */ + /* */ + static Bool + Convert_Glyph( RAS_ARGS int flipped ) + { + int i; + unsigned 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.outline.n_contours; i++ ) + { + ras.state = Unknown_State; + ras.gProfile = NULL; + + if ( Decompose_Curve( RAS_VARS (unsigned short)start, + ras.outline.contours[i], + flipped ) ) + return FAILURE; + + start = ras.outline.contours[i] + 1; + + /* We must now see whether 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 (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /** **/ + /** SCAN-LINE SWEEPS AND DRAWING **/ + /** **/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Init_Linked */ + /* */ + /* Initializes 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. */ + } + + + /*************************************************************************/ + /* */ + /* 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 */ + current = *list; + while ( current ) + { + current->X = *current->offset; + current->offset += current->flow; + current->height--; + current = current->link; + } + + /* 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 four 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 ) + { + Long pitch = ras.target.pitch; + + FT_UNUSED( max ); + + + ras.traceIncr = (Short)-pitch; + ras.traceOfs = -*min * pitch; + if ( pitch > 0 ) + ras.traceOfs += ( ras.target.rows - 1 ) * pitch; + + ras.gray_min_x = 0; + ras.gray_max_x = 0; + } + + + static void + Vertical_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + int c1, c2; + Byte f1, f2; + Byte* target; + + FT_UNUSED( y ); + FT_UNUSED( left ); + FT_UNUSED( right ); + + + /* 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 = (Byte) ( 0xFF >> ( e1 & 7 ) ); + f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); + + if ( ras.gray_min_x > c1 ) ras.gray_min_x = (short)c1; + if ( ras.gray_max_x < c2 ) ras.gray_max_x = (short)c2; + + target = ras.bTarget + ras.traceOfs + c1; + c2 -= c1; + + if ( c2 > 0 ) + { + target[0] |= f1; + + /* memset() is slower than the following code on many platforms. */ + /* This is due to the fact that, in the vast majority of cases, */ + /* the span length in bytes is relatively small. */ + c2--; + while ( c2 > 0 ) + { + *(++target) = 0xFF; + c2--; + } + target[1] |= f2; + } + else + *target |= ( f1 & f2 ); + } + } + + + static void + Vertical_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_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 if: */ + /* */ + /* 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 0 + if ( x2 - x1 < ras.precision_half ) +#endif + { + /* 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 = (Short)( 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 = (Short)( 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 four 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 */ + FT_UNUSED( raster ); + FT_UNUSED( min ); + FT_UNUSED( max ); + } + + + static void + Horizontal_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + Long e1, e2; + PByte bits; + Byte f1; + + FT_UNUSED( left ); + FT_UNUSED( right ); + + + 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 ) + { + PByte p; + + + p = bits - e1*ras.target.pitch; + if ( ras.target.pitch > 0 ) + p += ( ras.target.rows - 1 ) * ras.target.pitch; + + p[0] |= f1; + } + } + } + } + + + static void + Horizontal_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_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 ) ); + + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + 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 ) + { + bits -= e1 * ras.target.pitch; + if ( ras.target.pitch > 0 ) + bits += ( ras.target.rows - 1 ) * ras.target.pitch; + + bits[0] |= f1; + } + } + + + static void + Horizontal_Sweep_Step( RAS_ARG ) + { + /* Nothing, really */ + FT_UNUSED( raster ); + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + + /*************************************************************************/ + /* */ + /* 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 ) + { + Long pitch, byte_len; + + + *min = *min & -2; + *max = ( *max + 3 ) & -2; + + ras.traceOfs = 0; + pitch = ras.target.pitch; + byte_len = -pitch; + ras.traceIncr = (Short)byte_len; + ras.traceG = ( *min / 2 ) * byte_len; + + if ( pitch > 0 ) + { + ras.traceG += ( ras.target.rows - 1 ) * pitch; + byte_len = -byte_len; + } + + ras.gray_min_x = (Short)byte_len; + ras.gray_max_x = -(Short)byte_len; + } + + + 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 ) + { + Long last_pixel = ras.target.width - 1; + Int last_cell = last_pixel >> 2; + Int last_bit = last_pixel & 3; + Bool over = 0; + + + if ( ras.gray_max_x >= last_cell && last_bit != 3 ) + { + ras.gray_max_x = last_cell - 1; + over = 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 >> 12) & 0x000F]; + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + pix[3] = grays[ c2 & 0x000F]; + + *bit = 0; + *bit2 = 0; + } + + bit++; + bit2++; + pix += 4; + c1--; + } + + if ( over ) + { + c2 = count[*bit] + count[*bit2]; + if ( c2 ) + { + switch ( last_bit ) + { + case 2: + pix[2] = grays[(c2 >> 4 ) & 0x000F]; + case 1: + pix[1] = grays[(c2 >> 8 ) & 0x000F]; + default: + pix[0] = grays[(c2 >> 12) & 0x000F]; + } + + *bit = 0; + *bit2 = 0; + } + } + } + + ras.traceOfs = 0; + ras.traceG += ras.traceIncr; + + ras.gray_min_x = 32000; + ras.gray_max_x = -32000; + } + } + + + static void + Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_F26Dot6 x2, + PProfile left, + PProfile right ) + { + /* nothing, really */ + FT_UNUSED( raster ); + FT_UNUSED( y ); + FT_UNUSED( x1 ); + FT_UNUSED( x2 ); + FT_UNUSED( left ); + FT_UNUSED( right ); + } + + + static void + Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, + FT_F26Dot6 x1, + FT_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 ) + { + pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; + if ( ras.target.pitch > 0 ) + pixel += ( ras.target.rows - 1 ) * ras.target.pitch; + + if ( pixel[0] == ras.grays[0] ) + pixel[0] = color; + } + } + } + + +#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ + + + /*************************************************************************/ + /* */ + /* 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 waiting; + TProfileList draw_left, draw_right; + + + /* Init empty linked lists */ + + Init_Linked( &waiting ); + + 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 = (Short)P->start; + top = (Short)( P->start + P->height - 1 ); + + if ( min_Y > bottom ) min_Y = bottom; + if ( max_Y < top ) max_Y = top; + + P->X = 0; + InsNew( &waiting, 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 = waiting; + + while ( P ) + { + P->countL = (UShort)( 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 waiting list for new activations */ + + P = waiting; + + while ( P ) + { + Q = P->link; + P->countL -= y_height; + if ( P->countL == 0 ) + { + DelOld( &waiting, P ); + + switch ( P->flow ) + { + case Flow_Up: + InsNew( &draw_left, P ); + break; + + case 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 = (Short)( 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 */ + + P = draw_left; + while ( P ) + { + Q = P->link; + if ( P->height == 0 ) + DelOld( &draw_left, P ); + P = 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; +#if 0 + dropouts--; /* -- this is useful when debugging only */ +#endif + 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> */ + /* flipped :: If set, flip the direction of the outline. */ + /* */ + /* <Return> */ + /* Renderer error code. */ + /* */ + static int + 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 = (Short)( ( 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 = (Short)( k - 1 ); + + ras.band_top++; + } + else + { + if ( ras.fProfile ) + if ( Draw_Sweep( RAS_VAR ) ) + return ras.error; + ras.band_top--; + } + } + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Glyph */ + /* */ + /* <Description> */ + /* Renders a glyph in a bitmap. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Glyph( RAS_ARG ) + { + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift; + ras.dropOutControl = 2; + ras.second_pass = (FT_Byte)( !( ras.outline.flags & + FT_OUTLINE_SINGLE_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 = (short)( ras.target.rows - 1 ); + + ras.bWidth = (unsigned short)ras.target.width; + ras.bTarget = (Byte*)ras.target.buffer; + + 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 = (short)( ras.target.width - 1 ); + + if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) + return error; + } + + return Raster_Err_Ok; + } + + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* Render_Gray_Glyph */ + /* */ + /* <Description> */ + /* Renders a glyph with grayscaling. Sub-banding if needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + Long pixel_width; + FT_Error error; + + + Set_High_Precision( RAS_VARS ras.outline.flags & + FT_OUTLINE_HIGH_PRECISION ); + ras.scale_shift = ras.precision_shift + 1; + ras.dropOutControl = 2; + ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_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; + pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); + + if ( ras.bWidth > pixel_width ) + ras.bWidth = pixel_width; + + ras.bWidth = ras.bWidth * 8; + ras.bTarget = (Byte*)ras.gray_lines; + ras.gTarget = (Byte*)ras.target.buffer; + + 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 Raster_Err_Ok; + } + +#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + FT_LOCAL_DEF( FT_Error ) + Render_Gray_Glyph( RAS_ARG ) + { + FT_UNUSED_RASTER; + + return Raster_Err_Cannot_Render_Glyph; + } + +#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ + + + static void + ft_black_init( TRaster_Instance* raster ) + { + FT_UInt n; + FT_ULong c; + + + /* setup count table */ + for ( n = 0; n < 256; n++ ) + { + c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 ); + + c = ( ( c << 6 ) & 0x3000 ) | + ( ( c << 4 ) & 0x0300 ) | + ( ( c << 2 ) & 0x0030 ) | + (c & 0x0003 ); + + raster->count_table[n] = (UInt)c; + } + +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + /* set default 5-levels gray palette */ + for ( n = 0; n < 5; n++ ) + raster->grays[n] = n * 255 / 4; + + raster->gray_width = RASTER_GRAY_LINES / 2; + +#endif + } + + + /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ + /**** a static object. *****/ + + +#ifdef _STANDALONE_ + + + static int + ft_black_new( void* memory, + FT_Raster *araster ) + { + static FT_RasterRec_ the_raster; + + + *araster = &the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + ft_black_init( &the_raster ); + + return 0; + } + + + static void + ft_black_done( FT_Raster raster ) + { + /* nothing */ + raster->init = 0; + } + + +#else /* _STANDALONE_ */ + + + static int + ft_black_new( FT_Memory memory, + TRaster_Instance** araster ) + { + FT_Error error; + TRaster_Instance* raster; + + + *araster = 0; + if ( !FT_NEW( raster ) ) + { + raster->memory = memory; + ft_black_init( raster ); + + *araster = raster; + } + + return error; + } + + + static void + ft_black_done( TRaster_Instance* raster ) + { + FT_Memory memory = (FT_Memory)raster->memory; + FT_FREE( raster ); + } + + +#endif /* _STANDALONE_ */ + + + static void + ft_black_reset( TRaster_Instance* raster, + const char* pool_base, + long pool_size ) + { + if ( raster && pool_base && pool_size >= 4096 ) + { + /* save the pool */ + raster->buff = (PLong)pool_base; + raster->sizeBuff = raster->buff + pool_size / sizeof ( Long ); + } + } + + + static void + ft_black_set_mode( TRaster_Instance* raster, + unsigned long mode, + const char* palette ) + { +#ifdef FT_RASTER_OPTION_ANTI_ALIASING + + if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) + { + /* set 5-levels gray palette */ + raster->grays[0] = palette[0]; + raster->grays[1] = palette[1]; + raster->grays[2] = palette[2]; + raster->grays[3] = palette[3]; + raster->grays[4] = palette[4]; + } + +#else + + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( palette ); + +#endif + } + + + static int + ft_black_render( TRaster_Instance* raster, + FT_Raster_Params* params ) + { + FT_Outline* outline = (FT_Outline*)params->source; + FT_Bitmap* target_map = params->target; + + + if ( !raster || !raster->buff || !raster->sizeBuff ) + return Raster_Err_Not_Ini; + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return Raster_Err_None; + + if ( !outline || !outline->contours || !outline->points ) + return Raster_Err_Invalid; + + if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) + return Raster_Err_Invalid; + + /* this version of the raster does not support direct rendering, sorry */ + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + return Raster_Err_Unsupported; + + if ( !target_map || !target_map->buffer ) + return Raster_Err_Invalid; + + ras.outline = *outline; + ras.target = *target_map; + + return ( ( params->flags & FT_RASTER_FLAG_AA ) + ? Render_Gray_Glyph( raster ) + : Render_Glyph( raster ) ); + } + + + const FT_Raster_Funcs ft_standard_raster = + { + FT_GLYPH_FORMAT_OUTLINE, + (FT_Raster_New_Func) ft_black_new, + (FT_Raster_Reset_Func) ft_black_reset, + (FT_Raster_Set_Mode_Func)ft_black_set_mode, + (FT_Raster_Render_Func) ft_black_render, + (FT_Raster_Done_Func) ft_black_done + }; + + +/* END */ diff --git a/lib/freetype/src/raster/ftraster.h b/lib/freetype/src/raster/ftraster.h new file mode 100644 index 0000000..80fe46d --- /dev/null +++ b/lib/freetype/src/raster/ftraster.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ftraster.h */ +/* */ +/* The FreeType glyph rasterizer (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTRASTER_H__ +#define __FTRASTER_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_IMAGE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Uncomment the following line if you are using ftraster.c as a */ + /* standalone module, fully independent of FreeType. */ + /* */ +/* #define _STANDALONE_ */ + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; + + +FT_END_HEADER + +#endif /* __FTRASTER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/raster/ftrend1.c b/lib/freetype/src/raster/ftrend1.c new file mode 100644 index 0000000..86b170c --- /dev/null +++ b/lib/freetype/src/raster/ftrend1.c @@ -0,0 +1,273 @@ +/***************************************************************************/ +/* */ +/* ftrend1.c */ +/* */ +/* The FreeType glyph rasterizer interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftrend1.h" +#include "ftraster.h" + +#include "rasterrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_raster1_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return Raster_Err_Ok; + } + + + /* set render-specific mode */ + static FT_Error + ft_raster1_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + + /* transform a given glyph image */ + static FT_Error + ft_raster1_transform( FT_Renderer render, + FT_GlyphSlot slot, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Error error = Raster_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = Raster_Err_Invalid_Argument; + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_raster1_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_raster1_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + FT_Vector* origin ) + { + FT_Error error; + FT_Outline* outline; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = Raster_Err_Invalid_Argument; + goto Exit; + } + + /* check rendering mode */ + if ( mode != FT_RENDER_MODE_MONO ) + { + /* raster1 is only capable of producing monochrome bitmaps */ + if ( render->clazz == &ft_raster1_renderer_class ) + return Raster_Err_Cannot_Render_Glyph; + } + else + { + /* raster5 is only capable of producing 5-gray-levels bitmaps */ + if ( render->clazz == &ft_raster5_renderer_class ) + return Raster_Err_Cannot_Render_Glyph; + } + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax + 63 ) & -64; + cbox.yMax = ( cbox.yMax + 63 ) & -64; + + width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); + height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); + bitmap = &slot->bitmap; + memory = render->root.memory; + + /* release old bitmap buffer */ + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one, depends on pixel format */ + if ( !( mode & FT_RENDER_MODE_MONO ) ) + { + /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ + pitch = ( width + 3 ) & -4; + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + } + else + { + pitch = ( ( width + 15 ) >> 4 ) << 1; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + } + + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + goto Exit; + + slot->flags |= FT_GLYPH_OWN_BITMAP; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = 0; + + if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) + params.flags |= FT_RASTER_FLAG_AA; + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + + if ( error ) + goto Exit; + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); + slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + + Exit: + return error; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Renderer_Class ft_raster1_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "raster1", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &ft_standard_raster + }; + + + /* This renderer is _NOT_ part of the default modules; you will need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_CALLBACK_TABLE_DEF + const FT_Renderer_Class ft_raster5_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "raster5", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_raster1_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_raster1_render, + (FT_Renderer_TransformFunc)ft_raster1_transform, + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + + (FT_Raster_Funcs*) &ft_standard_raster + }; + + +/* END */ diff --git a/lib/freetype/src/raster/ftrend1.h b/lib/freetype/src/raster/ftrend1.h new file mode 100644 index 0000000..76e9a5f --- /dev/null +++ b/lib/freetype/src/raster/ftrend1.h @@ -0,0 +1,44 @@ +/***************************************************************************/ +/* */ +/* ftrend1.h */ +/* */ +/* The FreeType glyph rasterizer interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTREND1_H__ +#define __FTREND1_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; + + /* this renderer is _NOT_ part of the default modules, you'll need */ + /* to register it by hand in your application. It should only be */ + /* used for backwards-compatibility with FT 1.x anyway. */ + /* */ + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; + + +FT_END_HEADER + +#endif /* __FTREND1_H__ */ + + +/* END */ diff --git a/lib/freetype/src/raster/module.mk b/lib/freetype/src/raster/module.mk new file mode 100644 index 0000000..8a31364 --- /dev/null +++ b/lib/freetype/src/raster/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 renderer module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_raster_module + +add_raster_module: + $(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)raster $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/raster/raster.c b/lib/freetype/src/raster/raster.c new file mode 100644 index 0000000..f13a67a --- /dev/null +++ b/lib/freetype/src/raster/raster.c @@ -0,0 +1,26 @@ +/***************************************************************************/ +/* */ +/* raster.c */ +/* */ +/* FreeType monochrome rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftraster.c" +#include "ftrend1.c" + + +/* END */ diff --git a/lib/freetype/src/raster/rasterrs.h b/lib/freetype/src/raster/rasterrs.h new file mode 100644 index 0000000..5df9a7a --- /dev/null +++ b/lib/freetype/src/raster/rasterrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* rasterrs.h */ +/* */ +/* monochrome renderer error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the monochrome renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __RASTERRS_H__ +#define __RASTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Raster_Err_ +#define FT_ERR_BASE FT_Mod_Err_Raster + +#include FT_ERRORS_H + +#endif /* __RASTERRS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/raster/rules.mk b/lib/freetype/src/raster/rules.mk new file mode 100644 index 0000000..9fe4b8b --- /dev/null +++ b/lib/freetype/src/raster/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 renderer module build rules +# + + +# Copyright 1996-2000, 2001 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. + + +# raster1 driver directory +# +RAS1_DIR := $(SRC_)raster +RAS1_DIR_ := $(RAS1_DIR)$(SEP) + +# compilation flags for the driver +# +RAS1_COMPILE := $(FT_COMPILE) $I$(RAS1_DIR) + + +# raster1 driver sources (i.e., C files) +# +RAS1_DRV_SRC := $(RAS1_DIR_)ftraster.c \ + $(RAS1_DIR_)ftrend1.c + + +# raster1 driver headers +# +RAS1_DRV_H := $(RAS1_DRV_SRC:%.c=%.h) \ + $(RAS1_DIR_)rasterrs.h + + +# raster1 driver object(s) +# +# RAS1_DRV_OBJ_M is used during `multi' builds. +# RAS1_DRV_OBJ_S is used during `single' builds. +# +RAS1_DRV_OBJ_M := $(RAS1_DRV_SRC:$(RAS1_DIR_)%.c=$(OBJ_)%.$O) +RAS1_DRV_OBJ_S := $(OBJ_)raster.$O + +# raster1 driver source file for single build +# +RAS1_DRV_SRC_S := $(RAS1_DIR_)raster.c + + +# raster1 driver - single object +# +$(RAS1_DRV_OBJ_S): $(RAS1_DRV_SRC_S) $(RAS1_DRV_SRC) \ + $(FREETYPE_H) $(RAS1_DRV_H) + $(RAS1_COMPILE) $T$@ $(RAS1_DRV_SRC_S) + + +# raster1 driver - multiple objects +# +$(OBJ_)%.$O: $(RAS1_DIR_)%.c $(FREETYPE_H) $(RAS1_DRV_H) + $(RAS1_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(RAS1_DRV_OBJ_S) +DRV_OBJS_M += $(RAS1_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/sfnt/Jamfile b/lib/freetype/src/sfnt/Jamfile new file mode 100644 index 0000000..adddfb6 --- /dev/null +++ b/lib/freetype/src/sfnt/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/sfnt Jamfile (c) 2001, 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = sfobjs sfdriver ttcmap ttcmap0 ttpost ttload ttsbit ; + } + else + { + _sources = sfnt ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/sfnt Jamfile diff --git a/lib/freetype/src/sfnt/descrip.mms b/lib/freetype/src/sfnt/descrip.mms new file mode 100644 index 0000000..811c8b3 --- /dev/null +++ b/lib/freetype/src/sfnt/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 SFNT driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.sfnt]) + +OBJS=sfnt.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/sfnt/module.mk b/lib/freetype/src/sfnt/module.mk new file mode 100644 index 0000000..52607e2 --- /dev/null +++ b/lib/freetype/src/sfnt/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 SFNT module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_sfnt_module + +add_sfnt_module: + $(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/sfnt/rules.mk b/lib/freetype/src/sfnt/rules.mk new file mode 100644 index 0000000..c074a6a --- /dev/null +++ b/lib/freetype/src/sfnt/rules.mk @@ -0,0 +1,75 @@ +# +# FreeType 2 SFNT driver configuration rules +# + + +# Copyright 1996-2000, 2002 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. + + +# SFNT driver directory +# +SFNT_DIR := $(SRC_)sfnt +SFNT_DIR_ := $(SFNT_DIR)$(SEP) + + +# compilation flags for the driver +# +SFNT_COMPILE := $(FT_COMPILE) $I$(SFNT_DIR) + + +# SFNT driver sources (i.e., C files) +# +SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c \ + $(SFNT_DIR_)ttcmap.c \ + $(SFNT_DIR_)ttcmap0.c \ + $(SFNT_DIR_)ttsbit.c \ + $(SFNT_DIR_)ttpost.c \ + $(SFNT_DIR_)sfobjs.c \ + $(SFNT_DIR_)sfdriver.c + +# SFNT driver headers +# +SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) \ + $(SFNT_DIR_)sferrors.h + + +# SFNT driver object(s) +# +# SFNT_DRV_OBJ_M is used during `multi' builds. +# SFNT_DRV_OBJ_S is used during `single' builds. +# +SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O) +SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O + +# SFNT driver source file for single build +# +SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c + + +# SFNT driver - single object +# +$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ + $(FREETYPE_H) $(SFNT_DRV_H) + $(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S) + + +# SFNT driver - multiple objects +# +$(OBJ_)%.$O: $(SFNT_DIR_)%.c $(FREETYPE_H) $(SFNT_DRV_H) + $(SFNT_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(SFNT_DRV_OBJ_S) +DRV_OBJS_M += $(SFNT_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/sfnt/sfdriver.c b/lib/freetype/src/sfnt/sfdriver.c new file mode 100644 index 0000000..c4dd1b4 --- /dev/null +++ b/lib/freetype/src/sfnt/sfdriver.c @@ -0,0 +1,335 @@ +/***************************************************************************/ +/* */ +/* sfdriver.c */ +/* */ +/* High-level SFNT driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + +#include "sfdriver.h" +#include "ttload.h" +#include "ttcmap.h" +#include "sfobjs.h" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "ttsbit.h" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.h" +#endif + + + static void* + get_sfnt_table( TT_Face face, + FT_Sfnt_Tag tag ) + { + void* table; + + + switch ( tag ) + { + case ft_sfnt_head: + table = &face->header; + break; + + case ft_sfnt_hhea: + table = &face->horizontal; + break; + + case ft_sfnt_vhea: + table = face->vertical_info ? &face->vertical : 0; + break; + + case ft_sfnt_os2: + table = face->os2.version == 0xFFFFU ? 0 : &face->os2; + break; + + case ft_sfnt_post: + table = &face->postscript; + break; + + case ft_sfnt_maxp: + table = &face->max_profile; + break; + + case ft_sfnt_pclt: + table = face->pclt.Version ? &face->pclt : 0; + break; + + default: + table = 0; + } + + return table; + } + + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + static FT_Error + get_sfnt_glyph_name( TT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_String* gname; + FT_Error error; + + + error = tt_face_get_ps_name( face, glyph_index, &gname ); + if ( !error && buffer_max > 0 ) + { + FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); + + + if ( len >= buffer_max ) + len = buffer_max - 1; + + FT_MEM_COPY( buffer, gname, len ); + ((FT_Byte*)buffer)[len] = 0; + } + + return error; + } + + + static const char* + get_sfnt_postscript_name( TT_Face face ) + { + FT_Int n, found_win, found_apple; + const char* result = NULL; + + + /* shouldn't happen, but just in case to avoid memory leaks */ + if ( face->root.internal->postscript_name ) + return face->root.internal->postscript_name; + + /* scan the name table to see whether we have a Postscript name here, */ + /* either in Macintosh or Windows platform encodings */ + found_win = -1; + found_apple = -1; + + for ( n = 0; n < face->num_names; n++ ) + { + TT_NameEntryRec* name = face->name_table.names + n; + + + if ( name->nameID == 6 && name->stringLength > 0 ) + { + if ( name->platformID == 3 && + name->encodingID == 1 && + name->languageID == 0x409 ) + found_win = n; + + if ( name->platformID == 1 && + name->encodingID == 0 && + name->languageID == 0 ) + found_apple = n; + } + } + + if ( found_win != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_win; + FT_UInt len = name->stringLength / 2; + FT_Error error; + + + if ( !FT_ALLOC( result, name->stringLength + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + FT_String* r = (FT_String*)result; + FT_Byte* p = (FT_Byte*)name->string; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_FRAME_ENTER( name->stringLength ) ) + { + FT_FREE( result ); + name->stringLength = 0; + name->stringOffset = 0; + FT_FREE( name->string ); + + goto Exit; + } + + p = (FT_Byte*)stream->cursor; + + for ( ; len > 0; len--, p += 2 ) + { + if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + *r++ = p[1]; + } + *r = '\0'; + + FT_FRAME_EXIT(); + } + goto Exit; + } + + if ( found_apple != -1 ) + { + FT_Memory memory = face->root.memory; + TT_NameEntryRec* name = face->name_table.names + found_apple; + FT_UInt len = name->stringLength; + FT_Error error; + + + if ( !FT_ALLOC( result, len + 1 ) ) + { + FT_Stream stream = face->name_table.stream; + + + if ( FT_STREAM_SEEK( name->stringOffset ) || + FT_STREAM_READ( result, len ) ) + { + name->stringOffset = 0; + name->stringLength = 0; + FT_FREE( name->string ); + FT_FREE( result ); + goto Exit; + } + ((char*)result)[len] = '\0'; + } + } + + Exit: + face->root.internal->postscript_name = result; + return result; + } + + +#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + FT_CALLBACK_DEF( FT_Module_Interface ) + sfnt_get_interface( FT_Module module, + const char* module_interface ) + { + FT_UNUSED( module ); + + if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 ) + return (FT_Module_Interface)get_sfnt_table; + + if ( ft_strcmp( module_interface, "load_sfnt" ) == 0 ) + return (FT_Module_Interface)tt_face_load_any; + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + if ( ft_strcmp( module_interface, "glyph_name" ) == 0 ) + return (FT_Module_Interface)get_sfnt_glyph_name; +#endif + + if ( ft_strcmp( module_interface, "postscript_name" ) == 0 ) + return (FT_Module_Interface)get_sfnt_postscript_name; + + return 0; + } + + + static + const SFNT_Interface sfnt_interface = + { + tt_face_goto_table, + + sfnt_init_face, + sfnt_load_face, + sfnt_done_face, + sfnt_get_interface, + + tt_face_load_any, + tt_face_load_sfnt_header, + tt_face_load_directory, + + tt_face_load_header, + tt_face_load_metrics_header, + tt_face_load_cmap, + tt_face_load_max_profile, + tt_face_load_os2, + tt_face_load_postscript, + + tt_face_load_names, + tt_face_free_names, + + tt_face_load_hdmx, + tt_face_free_hdmx, + + tt_face_load_kern, + tt_face_load_gasp, + tt_face_load_pclt, + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* see `ttload.h' */ + tt_face_load_bitmap_header, + + /* see `ttsbit.h' */ + tt_face_set_sbit_strike, + tt_face_load_sbit_strikes, + tt_face_load_sbit_image, + tt_face_free_sbit_strikes, + +#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + 0, + 0, + 0, + 0, + 0, + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + /* see `ttpost.h' */ + tt_face_get_ps_name, + tt_face_free_ps_names, + +#else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + 0, + 0, + +#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + /* see `ttcmap.h' */ + tt_face_load_charmap, + tt_face_free_charmap, + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Module_Class sfnt_module_class = + { + 0, /* not a font driver or renderer */ + sizeof( FT_ModuleRec ), + + "sfnt", /* driver name */ + 0x10000L, /* driver version 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or higher */ + + (const void*)&sfnt_interface, /* module specific interface */ + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) sfnt_get_interface + }; + + +/* END */ diff --git a/lib/freetype/src/sfnt/sfdriver.h b/lib/freetype/src/sfnt/sfdriver.h new file mode 100644 index 0000000..92db796 --- /dev/null +++ b/lib/freetype/src/sfnt/sfdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* sfdriver.h */ +/* */ +/* High-level SFNT driver interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __SFDRIVER_H__ +#define __SFDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/sferrors.h b/lib/freetype/src/sfnt/sferrors.h new file mode 100644 index 0000000..fd2736b --- /dev/null +++ b/lib/freetype/src/sfnt/sferrors.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* sferrors.h */ +/* */ +/* SFNT error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the SFNT error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __SFERRORS_H__ +#define __SFERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX SFNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_SFNT + +#include FT_ERRORS_H + +#endif /* __SFERRORS_H__ */ + +/* END */ diff --git a/lib/freetype/src/sfnt/sfnt.c b/lib/freetype/src/sfnt/sfnt.c new file mode 100644 index 0000000..6e0757a --- /dev/null +++ b/lib/freetype/src/sfnt/sfnt.c @@ -0,0 +1,37 @@ +/***************************************************************************/ +/* */ +/* sfnt.c */ +/* */ +/* Single object library component. */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ttload.c" +#include "ttcmap.c" +#include "ttcmap0.c" +#include "sfobjs.c" +#include "sfdriver.c" + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS +#include "ttsbit.c" +#endif + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttpost.c" +#endif + + +/* END */ diff --git a/lib/freetype/src/sfnt/sfobjs.c b/lib/freetype/src/sfnt/sfobjs.c new file mode 100644 index 0000000..adaca24 --- /dev/null +++ b/lib/freetype/src/sfnt/sfobjs.c @@ -0,0 +1,829 @@ +/***************************************************************************/ +/* */ +/* sfobjs.c */ +/* */ +/* SFNT object management (base). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include "sfobjs.h" +#include "ttload.h" +#include "ttcmap0.h" +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_sfobjs + + + + /* convert a UTF-16 name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_utf16( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + + + len = (FT_UInt)entry->stringLength / 2; + + if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = FT_NEXT_USHORT( read ); + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[len] = 0; + + return string; + } + + + /* convert a UCS-4 name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_ucs4( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + + + len = (FT_UInt)entry->stringLength / 4; + + if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = (FT_UInt)FT_NEXT_ULONG( read ); + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[len] = 0; + + return string; + } + + + /* convert an Apple Roman or symbol name entry to ASCII */ + static FT_String* + tt_name_entry_ascii_from_other( TT_NameEntry entry, + FT_Memory memory ) + { + FT_String* string; + FT_UInt len, code, n; + FT_Byte* read = (FT_Byte*)entry->string; + + + len = (FT_UInt)entry->stringLength; + + if ( FT_MEM_NEW_ARRAY( string, len + 1 ) ) + return NULL; + + for ( n = 0; n < len; n++ ) + { + code = *read++; + if ( code < 32 || code > 127 ) + code = '?'; + + string[n] = (char)code; + } + + string[len] = 0; + + return string; + } + + + typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, + FT_Memory memory ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_name */ + /* */ + /* <Description> */ + /* Returns a given ENGLISH name record in ASCII. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <Return> */ + /* Character string. NULL if no name is present. */ + /* */ + static FT_String* + tt_face_get_name( TT_Face face, + FT_UShort nameid ) + { + FT_Memory memory = face->root.memory; + FT_String* result = NULL; + FT_UShort n; + TT_NameEntryRec* rec; + FT_Int found_apple = -1; + FT_Int found_win = -1; + FT_Int found_unicode = -1; + + TT_NameEntry_ConvertFunc convert; + + + rec = face->name_table.names; + for ( n = 0; n < face->num_names; n++, rec++ ) + { + /* According to the OpenType 1.3 specification, only Microsoft or */ + /* Apple platform IDs might be used in the `name' table. The */ + /* `Unicode' platform is reserved for the `cmap' table, and the */ + /* `Iso' one is deprecated. */ + /* */ + /* However, the Apple TrueType specification doesn't say the same */ + /* thing and goes to suggest that all Unicode `name' table entries */ + /* should be coded in UTF-16 (in big-endian format I suppose). */ + /* */ + if ( rec->nameID == nameid && rec->stringLength > 0 ) + { + switch ( rec->platformID ) + { + case TT_PLATFORM_APPLE_UNICODE: + case TT_PLATFORM_ISO: + /* there is `languageID' to check there. We should use this */ + /* field only as a last solution when nothing else is */ + /* available. */ + /* */ + found_unicode = n; + break; + + case TT_PLATFORM_MACINTOSH: + if ( rec->languageID == TT_MAC_LANGID_ENGLISH ) + found_apple = n; + + break; + + case TT_PLATFORM_MICROSOFT: + /* we only take a non-English name when there is nothing */ + /* else available in the font */ + /* */ + if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 ) + { + switch ( rec->encodingID ) + { + case TT_MS_ID_SYMBOL_CS: + case TT_MS_ID_UNICODE_CS: + case TT_MS_ID_UCS_4: + found_win = n; + break; + + default: + ; + } + } + break; + + default: + ; + } + } + } + + /* some fonts contain invalid Unicode or Macintosh formatted entries; */ + /* we will thus favor names encoded in Windows formats if available */ + /* */ + convert = NULL; + if ( found_win >= 0 ) + { + rec = face->name_table.names + found_win; + switch ( rec->encodingID ) + { + case TT_MS_ID_UNICODE_CS: + case TT_MS_ID_SYMBOL_CS: + convert = tt_name_entry_ascii_from_utf16; + break; + + case TT_MS_ID_UCS_4: + convert = tt_name_entry_ascii_from_ucs4; + break; + + default: + ; + } + } + else if ( found_apple >= 0 ) + { + rec = face->name_table.names + found_apple; + convert = tt_name_entry_ascii_from_other; + } + else if ( found_unicode >= 0 ) + { + rec = face->name_table.names + found_unicode; + convert = tt_name_entry_ascii_from_utf16; + } + + if ( rec && convert ) + { + if ( rec->string == NULL ) + { + FT_Error error; + FT_Stream stream = face->name_table.stream; + + + if ( FT_NEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) + { + FT_FREE( rec->string ); + rec->stringLength = 0; + result = NULL; + goto Exit; + } + } + + result = convert( rec, memory ); + } + + Exit: + return result; + } + + + static FT_Encoding + sfnt_find_encoding( int platform_id, + int encoding_id ) + { + typedef struct TEncoding + { + int platform_id; + int encoding_id; + FT_Encoding encoding; + + } TEncoding; + + static + const TEncoding tt_encodings[] = + { + { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE }, + + { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN }, + + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_MS_SJIS }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_MS_GB2312 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_MS_BIG5 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_MS_WANSUNG }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_MS_JOHAB } + }; + + const TEncoding *cur, *limit; + + + cur = tt_encodings; + limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); + + for ( ; cur < limit; cur++ ) + { + if ( cur->platform_id == platform_id ) + { + if ( cur->encoding_id == encoding_id || + cur->encoding_id == -1 ) + return cur->encoding; + } + } + + return FT_ENCODING_NONE; + } + + + FT_LOCAL_DEF( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + SFNT_HeaderRec sfnt_header; + + /* for now, parameters are unused */ + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + sfnt = (SFNT_Service)face->sfnt; + if ( !sfnt ) + { + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + face->sfnt = sfnt; + face->goto_table = sfnt->goto_table; + } + + if ( !face->psnames ) + { + face->psnames = (PSNames_Service) + FT_Get_Module_Interface( library, "psnames" ); + } + + /* check that we have a valid TrueType file */ + error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header ); + if ( error ) + goto Exit; + + face->format_tag = sfnt_header.format_tag; + face->num_tables = sfnt_header.num_tables; + + /* Load font directory */ + error = sfnt->load_directory( face, stream, &sfnt_header ); + if ( error ) + goto Exit; + + face->root.num_faces = face->ttc_header.count; + if ( face->root.num_faces < 1 ) + face->root.num_faces = 1; + + Exit: + return error; + } + + +#undef LOAD_ +#define LOAD_( x ) ( ( error = sfnt->load_##x( face, stream ) ) \ + != SFNT_Err_Ok ) + + + FT_LOCAL_DEF( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Bool has_outline; + FT_Bool is_apple_sbit; + + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_UNUSED( face_index ); + FT_UNUSED( num_params ); + FT_UNUSED( params ); + + + /* Load tables */ + + /* We now support two SFNT-based bitmapped font formats. They */ + /* are recognized easily as they do not include a `glyf' */ + /* table. */ + /* */ + /* The first format comes from Apple, and uses a table named */ + /* `bhed' instead of `head' to store the font header (using */ + /* the same format). It also doesn't include horizontal and */ + /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */ + /* missing). */ + /* */ + /* The other format comes from Microsoft, and is used with */ + /* WinCE/PocketPC. It looks like a standard TTF, except that */ + /* it doesn't contain outlines. */ + /* */ + + /* do we have outlines in there? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || + tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#else + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || + tt_face_lookup_table( face, TTAG_CFF ) != 0 ); +#endif + + is_apple_sbit = 0; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* if this font doesn't contain outlines, we try to load */ + /* a `bhed' table */ + if ( !has_outline ) + is_apple_sbit = FT_BOOL( !LOAD_( bitmap_header ) ); + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* load the font header (`head' table) if this isn't an Apple */ + /* sbit font file */ + if ( !is_apple_sbit && LOAD_( header ) ) + goto Exit; + + /* the following tables are often not present in embedded TrueType */ + /* fonts within PDF documents, so don't check for them. */ + (void)LOAD_( max_profile ); + (void)LOAD_( charmaps ); + + /* the following tables are optional in PCL fonts -- */ + /* don't check for errors */ + (void)LOAD_( names ); + (void)LOAD_( psnames ); + + /* do not load the metrics headers and tables if this is an Apple */ + /* sbit font file */ + if ( !is_apple_sbit ) + { + /* load the `hhea' and `hmtx' tables at once */ + error = sfnt->load_metrics( face, stream, 0 ); + if ( error ) + goto Exit; + + /* try to load the `vhea' and `vmtx' tables at once */ + error = sfnt->load_metrics( face, stream, 1 ); + if ( error ) + goto Exit; + + if ( LOAD_( os2 ) ) + goto Exit; + } + + /* the optional tables */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* embedded bitmap support. */ + if ( sfnt->load_sbits && LOAD_( sbits ) ) + { + /* return an error if this font file has no outlines */ + if ( error == SFNT_Err_Table_Missing && has_outline ) + error = SFNT_Err_Ok; + else + goto Exit; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + if ( LOAD_( hdmx ) || + LOAD_( gasp ) || + LOAD_( kerning ) || + LOAD_( pclt ) ) + goto Exit; + + face->root.family_name = tt_face_get_name( face, + TT_NAME_ID_FONT_FAMILY ); + face->root.style_name = tt_face_get_name( face, + TT_NAME_ID_FONT_SUBFAMILY ); + + /* now set up root fields */ + { + FT_Face root = &face->root; + FT_Int32 flags = 0; + FT_Memory memory; + + + memory = root->memory; + + /*********************************************************************/ + /* */ + /* Compute face flags. */ + /* */ + if ( has_outline == TRUE ) + flags = FT_FACE_FLAG_SCALABLE; /* scalable outlines */ + + flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */ + FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + /* might need more polish to detect the presence of a Postscript */ + /* name table in the font */ + flags |= FT_FACE_FLAG_GLYPH_NAMES; +#endif + + /* fixed width font? */ + if ( face->postscript.isFixedPitch ) + flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* vertical information? */ + if ( face->vertical_info ) + flags |= FT_FACE_FLAG_VERTICAL; + + /* kerning available ? */ + if ( face->kern_pairs ) + flags |= FT_FACE_FLAG_KERNING; + + root->face_flags = flags; + + /*********************************************************************/ + /* */ + /* Compute style flags. */ + /* */ + flags = 0; + if ( has_outline == TRUE && face->os2.version != 0xFFFF ) + { + /* we have an OS/2 table; use the `fsSelection' field */ + if ( face->os2.fsSelection & 1 ) + flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->os2.fsSelection & 32 ) + flags |= FT_STYLE_FLAG_BOLD; + } + else + { + /* this is an old Mac font, use the header field */ + if ( face->header.Mac_Style & 1 ) + flags |= FT_STYLE_FLAG_BOLD; + + if ( face->header.Mac_Style & 2 ) + flags |= FT_STYLE_FLAG_ITALIC; + } + + root->style_flags = flags; + + /*********************************************************************/ + /* */ + /* Polish the charmaps. */ + /* */ + /* Try to set the charmap encoding according to the platform & */ + /* encoding ID of each charmap. */ + /* */ + + tt_face_build_cmaps( face ); /* ignore errors */ + + + /* set the encoding fields */ + { + FT_Int m; + + + for ( m = 0; m < root->num_charmaps; m++ ) + { + FT_CharMap charmap = root->charmaps[m]; + + + charmap->encoding = sfnt_find_encoding( charmap->platform_id, + charmap->encoding_id ); + +#if 0 + if ( root->charmap == NULL && + charmap->encoding == FT_ENCODING_UNICODE ) + { + /* set 'root->charmap' to the first Unicode encoding we find */ + root->charmap = charmap; + } +#endif + } + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( face->num_sbit_strikes ) + { + FT_ULong n; + + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + +#if 0 + /* XXX: I don't know criteria whether layout is horizontal */ + /* or vertical. */ + if ( has_outline.... ) + { + ... + root->face_flags |= FT_FACE_FLAG_VERTICAL; + } +#endif + root->num_fixed_sizes = face->num_sbit_strikes; + + if ( FT_NEW_ARRAY( root->available_sizes, face->num_sbit_strikes ) ) + goto Exit; + + for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) + { + root->available_sizes[n].width = + face->sbit_strikes[n].x_ppem; + + root->available_sizes[n].height = + face->sbit_strikes[n].y_ppem; + } + } + else + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + { + root->num_fixed_sizes = 0; + root->available_sizes = 0; + } + + /*********************************************************************/ + /* */ + /* Set up metrics. */ + /* */ + if ( has_outline == TRUE ) + { + /* XXX What about if outline header is missing */ + /* (e.g. sfnt wrapped outline)? */ + root->bbox.xMin = face->header.xMin; + root->bbox.yMin = face->header.yMin; + root->bbox.xMax = face->header.xMax; + root->bbox.yMax = face->header.yMax; + root->units_per_EM = face->header.Units_Per_EM; + + + /* XXX: Computing the ascender/descender/height is very different */ + /* from what the specification tells you. Apparently, we */ + /* must be careful because */ + /* */ + /* - not all fonts have an OS/2 table; in this case, we take */ + /* the values in the horizontal header. However, these */ + /* values very often are not reliable. */ + /* */ + /* - otherwise, the correct typographic values are in the */ + /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */ + /* */ + /* However, certains fonts have these fields set to 0. */ + /* Rather, they have usWinAscent & usWinDescent correctly */ + /* set (but with different values). */ + /* */ + /* As an example, Arial Narrow is implemented through four */ + /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */ + /* */ + /* Strangely, all fonts have the same values in their */ + /* sTypoXXX fields, except ARIALNB which sets them to 0. */ + /* */ + /* On the other hand, they all have different */ + /* usWinAscent/Descent values -- as a conclusion, the OS/2 */ + /* table cannot be used to compute the text height reliably! */ + /* */ + + /* The ascender/descender/height are computed from the OS/2 table */ + /* when found. Otherwise, they're taken from the horizontal */ + /* header. */ + /* */ + + root->ascender = face->horizontal.Ascender; + root->descender = face->horizontal.Descender; + + root->height = (FT_Short)( root->ascender - root->descender + + face->horizontal.Line_Gap ); + + /* if the line_gap is 0, we add an extra 15% to the text height -- */ + /* this computation is based on various versions of Times New Roman */ + if ( face->horizontal.Line_Gap == 0 ) + root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); + +#if 0 + + /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ + /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ + if ( face->os2.version != 0xFFFF && root->ascender ) + { + FT_Int height; + + + root->ascender = face->os2.sTypoAscender; + root->descender = -face->os2.sTypoDescender; + + height = root->ascender + root->descender + face->os2.sTypoLineGap; + if ( height > root->height ) + root->height = height; + } + +#endif /* 0 */ + + root->max_advance_width = face->horizontal.advance_Width_Max; + + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); + + root->underline_position = face->postscript.underlinePosition; + root->underline_thickness = face->postscript.underlineThickness; + + /* root->max_points -- already set up */ + /* root->max_contours -- already set up */ + } + } + + Exit: + return error; + } + + +#undef LOAD_ + + + FT_LOCAL_DEF( void ) + sfnt_done_face( TT_Face face ) + { + FT_Memory memory = face->root.memory; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + if ( sfnt ) + { + /* destroy the postscript names table if it is loaded */ + if ( sfnt->free_psnames ) + sfnt->free_psnames( face ); + + /* destroy the embedded bitmaps table if it is loaded */ + if ( sfnt->free_sbits ) + sfnt->free_sbits( face ); + } + + /* freeing the kerning table */ + FT_FREE( face->kern_pairs ); + face->num_kern_pairs = 0; + + /* freeing the collection table */ + FT_FREE( face->ttc_header.offsets ); + face->ttc_header.count = 0; + + /* freeing table directory */ + FT_FREE( face->dir_tables ); + face->num_tables = 0; + + { + FT_Stream stream = FT_FACE_STREAM( face ); + + + /* simply release the 'cmap' table frame */ + FT_FRAME_RELEASE( face->cmap_table ); + face->cmap_size = 0; + } + + /* freeing the horizontal metrics */ + FT_FREE( face->horizontal.long_metrics ); + FT_FREE( face->horizontal.short_metrics ); + + /* freeing the vertical ones, if any */ + if ( face->vertical_info ) + { + FT_FREE( face->vertical.long_metrics ); + FT_FREE( face->vertical.short_metrics ); + face->vertical_info = 0; + } + + /* freeing the gasp table */ + FT_FREE( face->gasp.gaspRanges ); + face->gasp.numRanges = 0; + + /* freeing the name table */ + sfnt->free_names( face ); + + /* freeing the hdmx table */ + sfnt->free_hdmx( face ); + + /* freeing family and style name */ + FT_FREE( face->root.family_name ); + FT_FREE( face->root.style_name ); + + /* freeing sbit size table */ + face->root.num_fixed_sizes = 0; + if ( face->root.available_sizes ) + FT_FREE( face->root.available_sizes ); + + face->sfnt = 0; + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/sfobjs.h b/lib/freetype/src/sfnt/sfobjs.h new file mode 100644 index 0000000..6241c93 --- /dev/null +++ b/lib/freetype/src/sfnt/sfobjs.h @@ -0,0 +1,54 @@ +/***************************************************************************/ +/* */ +/* sfobjs.h */ +/* */ +/* SFNT object management (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __SFOBJS_H__ +#define __SFOBJS_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + sfnt_init_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( FT_Error ) + sfnt_load_face( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + sfnt_done_face( TT_Face face ); + + +FT_END_HEADER + +#endif /* __SFDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttcmap.c b/lib/freetype/src/sfnt/ttcmap.c new file mode 100644 index 0000000..f6aabfe --- /dev/null +++ b/lib/freetype/src/sfnt/ttcmap.c @@ -0,0 +1,1110 @@ +/***************************************************************************/ +/* */ +/* ttcmap.c */ +/* */ +/* TrueType character mapping table (cmap) support (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include "ttload.h" +#include "ttcmap.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttcmap + + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index0( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next0( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index2( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next2( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index4( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next4( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index6( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next6( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index8_12( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next8_12( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_UInt ) + code_to_index10( TT_CMapTable charmap, + FT_ULong char_code ); + + FT_CALLBACK_DEF( FT_ULong ) + code_to_next10( TT_CMapTable charmap, + FT_ULong char_code ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_charmap */ + /* */ + /* <Description> */ + /* Loads a given TrueType character map into memory. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* stream :: A handle to the current stream object. */ + /* */ + /* <InOut> */ + /* table :: A pointer to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function assumes that the stream is already in use (i.e., */ + /* opened). In case of error, all partially allocated tables are */ + /* released. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_charmap( TT_Face face, + TT_CMapTable cmap, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory; + FT_UShort num_SH, num_Seg, i; + FT_ULong j, n; + + FT_UShort u, l; + + TT_CMap0 cmap0; + TT_CMap2 cmap2; + TT_CMap4 cmap4; + TT_CMap6 cmap6; + TT_CMap8_12 cmap8_12; + TT_CMap10 cmap10; + + TT_CMap2SubHeader cmap2sub; + TT_CMap4Segment segments; + TT_CMapGroup groups; + + + if ( cmap->loaded ) + return SFNT_Err_Ok; + + memory = stream->memory; + + if ( FT_STREAM_SEEK( cmap->offset ) ) + return error; + + switch ( cmap->format ) + { + case 0: + cmap0 = &cmap->c.cmap0; + + if ( FT_READ_USHORT( cmap0->language ) || + FT_ALLOC( cmap0->glyphIdArray, 256L ) || + FT_STREAM_READ( cmap0->glyphIdArray, 256L ) ) + goto Fail; + + cmap->get_index = code_to_index0; + cmap->get_next_char = code_to_next0; + break; + + case 2: + num_SH = 0; + cmap2 = &cmap->c.cmap2; + + /* allocate subheader keys */ + + if ( FT_NEW_ARRAY( cmap2->subHeaderKeys, 256 ) || + FT_FRAME_ENTER( 2L + 512L ) ) + goto Fail; + + cmap2->language = FT_GET_USHORT(); + + for ( i = 0; i < 256; i++ ) + { + u = (FT_UShort)( FT_GET_USHORT() / 8 ); + cmap2->subHeaderKeys[i] = u; + + if ( num_SH < u ) + num_SH = u; + } + + FT_FRAME_EXIT(); + + /* load subheaders */ + + cmap2->numGlyphId = l = (FT_UShort)( + ( ( cmap->length - 2L * ( 256 + 3 ) - num_SH * 8L ) & 0xFFFFU ) / 2 ); + + if ( FT_NEW_ARRAY( cmap2->subHeaders, num_SH + 1 ) || + FT_FRAME_ENTER( ( num_SH + 1 ) * 8L ) ) + { + FT_FREE( cmap2->subHeaderKeys ); + goto Fail; + } + + cmap2sub = cmap2->subHeaders; + + for ( i = 0; i <= num_SH; i++ ) + { + cmap2sub->firstCode = FT_GET_USHORT(); + cmap2sub->entryCount = FT_GET_USHORT(); + cmap2sub->idDelta = FT_GET_SHORT(); + /* we apply the location offset immediately */ + cmap2sub->idRangeOffset = (FT_UShort)( + FT_GET_USHORT() - ( num_SH - i ) * 8 - 2 ); + + cmap2sub++; + } + + FT_FRAME_EXIT(); + + /* load glyph IDs */ + + if ( FT_NEW_ARRAY( cmap2->glyphIdArray, l ) || + FT_FRAME_ENTER( l * 2L ) ) + { + FT_FREE( cmap2->subHeaders ); + FT_FREE( cmap2->subHeaderKeys ); + goto Fail; + } + + for ( i = 0; i < l; i++ ) + cmap2->glyphIdArray[i] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + cmap->get_index = code_to_index2; + cmap->get_next_char = code_to_next2; + break; + + case 4: + cmap4 = &cmap->c.cmap4; + + /* load header */ + + if ( FT_FRAME_ENTER( 10L ) ) + goto Fail; + + cmap4->language = FT_GET_USHORT(); + cmap4->segCountX2 = FT_GET_USHORT(); + cmap4->searchRange = FT_GET_USHORT(); + cmap4->entrySelector = FT_GET_USHORT(); + cmap4->rangeShift = FT_GET_USHORT(); + + num_Seg = (FT_UShort)( cmap4->segCountX2 / 2 ); + + FT_FRAME_EXIT(); + + /* load segments */ + + if ( FT_NEW_ARRAY( cmap4->segments, num_Seg ) || + FT_FRAME_ENTER( ( num_Seg * 4 + 1 ) * 2L ) ) + goto Fail; + + segments = cmap4->segments; + + for ( i = 0; i < num_Seg; i++ ) + segments[i].endCount = FT_GET_USHORT(); + + (void)FT_GET_USHORT(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].startCount = FT_GET_USHORT(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idDelta = FT_GET_SHORT(); + + for ( i = 0; i < num_Seg; i++ ) + segments[i].idRangeOffset = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + cmap4->numGlyphId = l = (FT_UShort)( + ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFFU ) / 2 ); + + /* load IDs */ + + if ( FT_NEW_ARRAY( cmap4->glyphIdArray, l ) || + FT_FRAME_ENTER( l * 2L ) ) + { + FT_FREE( cmap4->segments ); + goto Fail; + } + + for ( i = 0; i < l; i++ ) + cmap4->glyphIdArray[i] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + cmap4->last_segment = cmap4->segments; + + cmap->get_index = code_to_index4; + cmap->get_next_char = code_to_next4; + break; + + case 6: + cmap6 = &cmap->c.cmap6; + + if ( FT_FRAME_ENTER( 6L ) ) + goto Fail; + + cmap6->language = FT_GET_USHORT(); + cmap6->firstCode = FT_GET_USHORT(); + cmap6->entryCount = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + l = cmap6->entryCount; + + if ( FT_NEW_ARRAY( cmap6->glyphIdArray, l ) || + FT_FRAME_ENTER( l * 2L ) ) + goto Fail; + + for ( i = 0; i < l; i++ ) + cmap6->glyphIdArray[i] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + cmap->get_index = code_to_index6; + cmap->get_next_char = code_to_next6; + break; + + case 8: + case 12: + cmap8_12 = &cmap->c.cmap8_12; + + if ( FT_FRAME_ENTER( 8L ) ) + goto Fail; + + cmap->length = FT_GET_ULONG(); + cmap8_12->language = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + if ( cmap->format == 8 ) + if ( FT_STREAM_SKIP( 8192L ) ) + goto Fail; + + if ( FT_READ_ULONG( cmap8_12->nGroups ) ) + goto Fail; + + n = cmap8_12->nGroups; + + if ( FT_NEW_ARRAY( cmap8_12->groups, n ) || + FT_FRAME_ENTER( n * 3 * 4L ) ) + goto Fail; + + groups = cmap8_12->groups; + + for ( j = 0; j < n; j++ ) + { + groups[j].startCharCode = FT_GET_ULONG(); + groups[j].endCharCode = FT_GET_ULONG(); + groups[j].startGlyphID = FT_GET_ULONG(); + } + + FT_FRAME_EXIT(); + + cmap8_12->last_group = cmap8_12->groups; + + cmap->get_index = code_to_index8_12; + cmap->get_next_char = code_to_next8_12; + break; + + case 10: + cmap10 = &cmap->c.cmap10; + + if ( FT_FRAME_ENTER( 16L ) ) + goto Fail; + + cmap->length = FT_GET_ULONG(); + cmap10->language = FT_GET_ULONG(); + cmap10->startCharCode = FT_GET_ULONG(); + cmap10->numChars = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + n = cmap10->numChars; + + if ( FT_NEW_ARRAY( cmap10->glyphs, n ) || + FT_FRAME_ENTER( n * 2L ) ) + goto Fail; + + for ( j = 0; j < n; j++ ) + cmap10->glyphs[j] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + cmap->get_index = code_to_index10; + cmap->get_next_char = code_to_next10; + break; + + default: /* corrupt character mapping table */ + return SFNT_Err_Invalid_CharMap_Format; + + } + + return SFNT_Err_Ok; + + Fail: + tt_face_free_charmap( face, cmap ); + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_charmap */ + /* */ + /* <Description> */ + /* Destroys a character mapping table. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* cmap :: A handle to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_free_charmap( TT_Face face, + TT_CMapTable cmap ) + { + FT_Memory memory; + + + if ( !cmap ) + return SFNT_Err_Ok; + + memory = face->root.driver->root.memory; + + switch ( cmap->format ) + { + case 0: + FT_FREE( cmap->c.cmap0.glyphIdArray ); + break; + + case 2: + FT_FREE( cmap->c.cmap2.subHeaderKeys ); + FT_FREE( cmap->c.cmap2.subHeaders ); + FT_FREE( cmap->c.cmap2.glyphIdArray ); + break; + + case 4: + FT_FREE( cmap->c.cmap4.segments ); + FT_FREE( cmap->c.cmap4.glyphIdArray ); + cmap->c.cmap4.segCountX2 = 0; + break; + + case 6: + FT_FREE( cmap->c.cmap6.glyphIdArray ); + cmap->c.cmap6.entryCount = 0; + break; + + case 8: + case 12: + FT_FREE( cmap->c.cmap8_12.groups ); + cmap->c.cmap8_12.nGroups = 0; + break; + + case 10: + FT_FREE( cmap->c.cmap10.glyphs ); + cmap->c.cmap10.numChars = 0; + break; + + default: + /* invalid table format, do nothing */ + ; + } + + cmap->loaded = FALSE; + return SFNT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_index0 */ + /* */ + /* <Description> */ + /* Converts the character code into a glyph index. Uses format 0. */ + /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */ + /* returned). */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap0 :: A pointer to a cmap table in format 0. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index0( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap0 cmap0 = &cmap->c.cmap0; + + + return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next0 */ + /* */ + /* <Description> */ + /* Finds the next encoded character after the given one. Uses */ + /* format 0. `charCode' must be in the range 0x00-0xFF (otherwise 0 */ + /* is returned). */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap0 :: A pointer to a cmap table in format 0. */ + /* */ + /* <Return> */ + /* Next char code. 0 if no higher one is encoded. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next0( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap0 cmap0 = &cmap->c.cmap0; + + + while ( ++charCode <= 0xFF ) + if ( cmap0->glyphIdArray[charCode] ) + return ( charCode ); + 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. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index2( TT_CMapTable cmap, + FT_ULong charCode ) + { + FT_UInt result, index1, offset; + FT_UInt char_lo; + FT_ULong char_hi; + TT_CMap2SubHeader sh2; + TT_CMap2 cmap2; + + + cmap2 = &cmap->c.cmap2; + result = 0; + char_lo = (FT_UInt)( charCode & 0xFF ); + char_hi = charCode >> 8; + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use the subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + index1 = cmap2->subHeaderKeys[char_lo]; + if ( index1 != 0 ) + return 0; + } + else + { + /* a 16-bit character code */ + index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; + if ( index1 == 0 ) + return 0; + } + + sh2 = cmap2->subHeaders + index1; + char_lo -= sh2->firstCode; + + if ( char_lo < (FT_UInt)sh2->entryCount ) + { + offset = sh2->idRangeOffset / 2 + char_lo; + if ( offset < (FT_UInt)cmap2->numGlyphId ) + { + result = cmap2->glyphIdArray[offset]; + if ( result ) + result = ( result + sh2->idDelta ) & 0xFFFFU; + } + } + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next2 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 2. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap2 :: A pointer to a cmap table in format 2. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next2( TT_CMapTable cmap, + FT_ULong charCode ) + { + FT_UInt index1, offset; + FT_UInt char_lo; + FT_ULong char_hi; + TT_CMap2SubHeader sh2; + TT_CMap2 cmap2; + + + cmap2 = &cmap->c.cmap2; + charCode++; + + /* + * This is relatively simplistic -- look for a subHeader containing + * glyphs and then walk to the first glyph in that subHeader. + */ + while ( charCode < 0x10000L ) + { + char_lo = (FT_UInt)( charCode & 0xFF ); + char_hi = charCode >> 8; + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use the subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + index1 = cmap2->subHeaderKeys[char_lo]; + if ( index1 != 0 ) + { + charCode++; + continue; + } + } + else + { + /* a 16-bit character code */ + index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; + if ( index1 == 0 ) + { + charCode = ( char_hi + 1 ) << 8; + continue; + } + } + + sh2 = cmap2->subHeaders + index1; + char_lo -= sh2->firstCode; + + if ( char_lo > (FT_UInt)sh2->entryCount ) + { + charCode = ( char_hi + 1 ) << 8; + continue; + } + + offset = sh2->idRangeOffset / 2 + char_lo; + if ( offset >= (FT_UInt)cmap2->numGlyphId || + cmap2->glyphIdArray[offset] == 0 ) + { + charCode++; + continue; + } + + return charCode; + } + 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. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index4( TT_CMapTable cmap, + FT_ULong charCode ) + { + FT_UInt result, index1, segCount; + TT_CMap4 cmap4; + TT_CMap4SegmentRec *seg4, *limit; + + + cmap4 = &cmap->c.cmap4; + result = 0; + segCount = cmap4->segCountX2 / 2; + limit = cmap4->segments + segCount; + + /* first, check against the last used segment */ + + seg4 = cmap4->last_segment; + + /* the following is equivalent to performing two tests, as in */ + /* */ + /* if ( charCode >= seg4->startCount && charCode <= seg4->endCount ) */ + /* */ + /* This is a bit strange, but it is faster, and the idea behind the */ + /* cache is to significantly speed up charcode to glyph index */ + /* conversion. */ + + if ( (FT_ULong)( charCode - seg4->startCount ) < + (FT_ULong)( seg4->endCount - seg4->startCount ) ) + goto Found1; + + for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) + { + /* the ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode > (FT_UInt)seg4->endCount ) + continue; + + if ( charCode >= (FT_UInt)seg4->startCount ) + goto Found; + } + return 0; + + Found: + cmap4->last_segment = seg4; + + Found1: + /* if the idRangeOffset is 0, we can compute the glyph index */ + /* directly */ + + if ( seg4->idRangeOffset == 0 ) + result = (FT_UInt)( charCode + seg4->idDelta ) & 0xFFFFU; + else + { + /* otherwise, we must use the glyphIdArray to do it */ + index1 = (FT_UInt)( seg4->idRangeOffset / 2 + + ( charCode - seg4->startCount ) + + ( seg4 - cmap4->segments ) + - segCount ); + + if ( index1 < (FT_UInt)cmap4->numGlyphId && + cmap4->glyphIdArray[index1] != 0 ) + result = ( cmap4->glyphIdArray[index1] + seg4->idDelta ) & 0xFFFFU; + } + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next4 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 4. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap :: A pointer to a cmap table in format 4. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next4( TT_CMapTable cmap, + FT_ULong charCode ) + { + FT_UInt index1, segCount; + TT_CMap4 cmap4; + TT_CMap4SegmentRec *seg4, *limit; + + + cmap4 = &cmap->c.cmap4; + segCount = cmap4->segCountX2 / 2; + limit = cmap4->segments + segCount; + + charCode++; + + for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) + { + /* The ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode <= (FT_UInt)seg4->endCount ) + goto Found; + } + return 0; + + Found: + if ( charCode < (FT_ULong) seg4->startCount ) + charCode = seg4->startCount; + + /* if the idRangeOffset is 0, all chars in the map exist */ + + if ( seg4->idRangeOffset == 0 ) + return ( charCode ); + + while ( charCode <= (FT_UInt) seg4->endCount ) + { + /* otherwise, we must use the glyphIdArray to do it */ + index1 = (FT_UInt)( seg4->idRangeOffset / 2 + + ( charCode - seg4->startCount ) + + ( seg4 - cmap4->segments ) + - segCount ); + + if ( index1 < (FT_UInt)cmap4->numGlyphId && + cmap4->glyphIdArray[index1] != 0 ) + return ( charCode ); + charCode++; + } + + 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. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index6( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap6 cmap6; + FT_UInt result = 0; + + + cmap6 = &cmap->c.cmap6; + charCode -= cmap6->firstCode; + + if ( charCode < (FT_UInt)cmap6->entryCount ) + result = cmap6->glyphIdArray[charCode]; + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next6 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 6. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap :: A pointer to a cmap table in format 6. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next6( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap6 cmap6; + + + charCode++; + + cmap6 = &cmap->c.cmap6; + + if ( charCode < (FT_ULong) cmap6->firstCode ) + charCode = cmap6->firstCode; + + charCode -= cmap6->firstCode; + + while ( charCode < (FT_UInt)cmap6->entryCount ) + { + if ( cmap6->glyphIdArray[charCode] != 0 ) + return charCode + cmap6->firstCode; + charCode++; + } + + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_index8_12 */ + /* */ + /* <Description> */ + /* Converts the (possibly 32bit) character code into a glyph index. */ + /* Uses format 8 or 12. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap8_12 :: A pointer to a cmap table in format 8 or 12. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index8_12( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap8_12 cmap8_12; + TT_CMapGroupRec *group, *limit; + + + cmap8_12 = &cmap->c.cmap8_12; + limit = cmap8_12->groups + cmap8_12->nGroups; + + /* first, check against the last used group */ + + group = cmap8_12->last_group; + + /* the following is equivalent to performing two tests, as in */ + /* */ + /* if ( charCode >= group->startCharCode && */ + /* charCode <= group->endCharCode ) */ + /* */ + /* This is a bit strange, but it is faster, and the idea behind the */ + /* cache is to significantly speed up charcode to glyph index */ + /* conversion. */ + + if ( (FT_ULong)( charCode - group->startCharCode ) < + (FT_ULong)( group->endCharCode - group->startCharCode ) ) + goto Found1; + + for ( group = cmap8_12->groups; group < limit; group++ ) + { + /* the ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode > group->endCharCode ) + continue; + + if ( charCode >= group->startCharCode ) + goto Found; + } + return 0; + + Found: + cmap8_12->last_group = group; + + Found1: + return (FT_UInt)( group->startGlyphID + + ( charCode - group->startCharCode ) ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next8_12 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 8 or 12. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap :: A pointer to a cmap table in format 8 or 12. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next8_12( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap8_12 cmap8_12; + TT_CMapGroupRec *group, *limit; + + + charCode++; + cmap8_12 = &cmap->c.cmap8_12; + limit = cmap8_12->groups + cmap8_12->nGroups; + + for ( group = cmap8_12->groups; group < limit; group++ ) + { + /* the ranges are sorted in increasing order. If we are out of */ + /* the range here, the char code isn't in the charmap, so exit. */ + + if ( charCode <= group->endCharCode ) + goto Found; + } + return 0; + + Found: + if ( charCode < group->startCharCode ) + charCode = group->startCharCode; + + return charCode; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_index10 */ + /* */ + /* <Description> */ + /* Converts the (possibly 32bit) character code into a glyph index. */ + /* Uses format 10. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap10 :: A pointer to a cmap table in format 10. */ + /* */ + /* <Return> */ + /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ + /* */ + FT_CALLBACK_DEF( FT_UInt ) + code_to_index10( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap10 cmap10; + FT_UInt result = 0; + + + cmap10 = &cmap->c.cmap10; + charCode -= cmap10->startCharCode; + + /* the overflow trick for comparison works here also since the number */ + /* of glyphs (even if numChars is specified as ULong in the specs) in */ + /* an OpenType font is limited to 64k */ + + if ( charCode < cmap10->numChars ) + result = cmap10->glyphs[charCode]; + + return result; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* code_to_next10 */ + /* */ + /* <Description> */ + /* Find the next encoded character. Uses format 10. */ + /* */ + /* <Input> */ + /* charCode :: The wanted character code. */ + /* */ + /* cmap :: A pointer to a cmap table in format 10. */ + /* */ + /* <Return> */ + /* Next encoded character. 0 if none exists. */ + /* */ + FT_CALLBACK_DEF( FT_ULong ) + code_to_next10( TT_CMapTable cmap, + FT_ULong charCode ) + { + TT_CMap10 cmap10; + + + charCode++; + cmap10 = &cmap->c.cmap10; + + if ( charCode < cmap10->startCharCode ) + charCode = cmap10->startCharCode; + + charCode -= cmap10->startCharCode; + + /* the overflow trick for comparison works here also since the number */ + /* of glyphs (even if numChars is specified as ULong in the specs) in */ + /* an OpenType font is limited to 64k */ + + while ( charCode < cmap10->numChars ) + { + if ( cmap10->glyphs[charCode] ) + return ( charCode + cmap10->startCharCode ); + charCode++; + } + + return 0; + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttcmap.h b/lib/freetype/src/sfnt/ttcmap.h new file mode 100644 index 0000000..cd19a6b --- /dev/null +++ b/lib/freetype/src/sfnt/ttcmap.h @@ -0,0 +1,45 @@ +/***************************************************************************/ +/* */ +/* ttcmap.h */ +/* */ +/* TrueType character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_charmap( TT_Face face, + TT_CMapTable cmap, + FT_Stream input ); + + FT_LOCAL( FT_Error ) + tt_face_free_charmap( TT_Face face, + TT_CMapTable cmap ); + + +FT_END_HEADER + +#endif /* __TTCMAP_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttcmap0.c b/lib/freetype/src/sfnt/ttcmap0.c new file mode 100644 index 0000000..4053345 --- /dev/null +++ b/lib/freetype/src/sfnt/ttcmap0.c @@ -0,0 +1,1784 @@ +/***************************************************************************/ +/* */ +/* ttcmap0.c */ +/* */ +/* TrueType new character mapping table (cmap) support (body). */ +/* */ +/* Copyright 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include "ttload.h" +#include "ttcmap0.h" + +#include "sferrors.h" + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttcmap + + +#define TT_PEEK_SHORT FT_PEEK_SHORT +#define TT_PEEK_USHORT FT_PEEK_USHORT +#define TT_PEEK_LONG FT_PEEK_LONG +#define TT_PEEK_ULONG FT_PEEK_ULONG + +#define TT_NEXT_SHORT FT_NEXT_SHORT +#define TT_NEXT_USHORT FT_NEXT_USHORT +#define TT_NEXT_LONG FT_NEXT_LONG +#define TT_NEXT_ULONG FT_NEXT_ULONG + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap_init( TT_CMap cmap, + FT_Byte* table ) + { + cmap->data = table; + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 0 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 0 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* glyph_ids 6 BYTE[256] array of glyph indices */ + /* 262 */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_0 + + FT_CALLBACK_DEF( void ) + tt_cmap0_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; + FT_UInt length = TT_NEXT_USHORT( p ); + + + if ( table + length > valid->limit || length < 262 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices whenever necessary */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt n, idx; + + + p = table + 6; + for ( n = 0; n < 256; n++ ) + { + idx = *p++; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap0_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + + + return char_code < 256 ? table[6 + char_code] : 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap0_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 charcode = *pchar_code; + FT_UInt32 result = 0; + FT_UInt gindex = 0; + + + table += 6; /* go to glyph ids */ + while ( ++charcode < 256 ) + { + gindex = table[charcode]; + if ( gindex != 0 ) + { + result = charcode; + break; + } + } + + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap0_class_rec = + { + { + sizeof( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, + (FT_CMap_CharNextFunc) tt_cmap0_char_next + }, + 0, + (TT_CMap_ValidateFunc) tt_cmap0_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_0 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 2 *****/ + /***** *****/ + /***** This is used for certain CJK encodings that encode text in a *****/ + /***** mixed 8/16 bits encoding along the following lines: *****/ + /***** *****/ + /***** * Certain byte values correspond to an 8-bit character code *****/ + /***** (typically in the range 0..127 for ASCII compatibility). *****/ + /***** *****/ + /***** * Certain byte values signal the first byte of a 2-byte *****/ + /***** character code (but these values are also valid as the *****/ + /***** second byte of a 2-byte character). *****/ + /***** *****/ + /***** The following charmap lookup and iteration functions all *****/ + /***** assume that the value "charcode" correspond to following: *****/ + /***** *****/ + /***** - For one byte characters, "charcode" is simply the *****/ + /***** character code. *****/ + /***** *****/ + /***** - For two byte characters, "charcode" is the 2-byte *****/ + /***** character code in big endian format. More exactly: *****/ + /***** *****/ + /***** (charcode >> 8) is the first byte value *****/ + /***** (charcode & 0xFF) is the second byte value *****/ + /***** *****/ + /***** Note that not all values of "charcode" are valid according *****/ + /***** to these rules, and the function moderately check the *****/ + /***** arguments. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 2 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* keys 6 USHORT[256] sub-header keys */ + /* subs 518 SUBHEAD[NSUBS] sub-headers array */ + /* glyph_ids 518+NSUB*8 USHORT[] glyph id array */ + /* */ + /* The `keys' table is used to map charcode high-bytes to sub-headers. */ + /* The value of `NSUBS' is the number of sub-headers defined in the */ + /* table and is computed by finding the maximum of the `keys' table. */ + /* */ + /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ + /* table, i.e., it is the corresponding sub-header index multiplied */ + /* by 8. */ + /* */ + /* Each sub-header has the following format: */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* first 0 USHORT first valid low-byte */ + /* count 2 USHORT number of valid low-bytes */ + /* delta 4 SHORT see below */ + /* offset 6 USHORT see below */ + /* */ + /* A sub-header defines, for each high-byte, the range of valid */ + /* low-bytes within the charmap. Note that the range defined by `first' */ + /* and `count' must be completely included in the interval [0..255] */ + /* according to the specification. */ + /* */ + /* If a character code is contained within a given sub-header, then */ + /* mapping it to a glyph index is done as follows: */ + /* */ + /* * The value of `offset' is read. This is a _byte_ distance from the */ + /* location of the `offset' field itself into a slice of the */ + /* `glyph_ids' table. Let's call it `slice' (it's a USHORT[] too). */ + /* */ + /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ + /* no glyph for the charcode. Otherwise, the value of `delta' is */ + /* added to it (modulo 65536) to form a new glyph index. */ + /* */ + /* It is up to the validation routine to check that all offsets fall */ + /* within the glyph ids table (and not within the `subs' table itself or */ + /* outside of the CMap). */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + + FT_CALLBACK_DEF( void ) + tt_cmap2_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_PEEK_USHORT( p ); + FT_UInt n, max_subs; + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph id array */ + + + if ( table + length > valid->limit || length < 6 + 512 ) + FT_INVALID_TOO_SHORT; + + keys = table + 6; + + /* parse keys to compute sub-headers count */ + p = keys; + max_subs = 0; + for ( n = 0; n < 256; n++ ) + { + FT_UInt idx = TT_NEXT_USHORT( p ); + + + /* value must be multiple of 8 */ + if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) + FT_INVALID_DATA; + + idx >>= 3; + + if ( idx > max_subs ) + max_subs = idx; + } + + FT_ASSERT( p == table + 518 ); + + subs = p; + glyph_ids = subs + (max_subs + 1) * 8; + if ( glyph_ids > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* parse sub-headers */ + for ( n = 0; n <= max_subs; n++ ) + { + FT_UInt first_code, code_count, offset; + FT_Int delta; + FT_Byte* ids; + + + first_code = TT_NEXT_USHORT( p ); + code_count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT( p ); + offset = TT_NEXT_USHORT( p ); + + /* check range within 0..255 */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + if ( first_code >= 256 || first_code + code_count > 256 ) + FT_INVALID_DATA; + } + + /* check offset */ + if ( offset != 0 ) + { + ids = p - 2 + offset; + if ( ids < glyph_ids || ids + code_count*2 > table + length ) + FT_INVALID_OFFSET; + + /* check glyph ids */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_Byte* limit = p + code_count * 2; + FT_UInt idx; + + + for ( ; p < limit; ) + { + idx = TT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = ( idx + delta ) & 0xFFFFU; + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + } + } + + + /* return sub header corresponding to a given character code */ + /* NULL on invalid charcode */ + static FT_Byte* + tt_cmap2_get_subheader( FT_Byte* table, + FT_UInt32 char_code ) + { + FT_Byte* result = NULL; + + + if ( char_code < 0x10000UL ) + { + FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); + FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); + FT_Byte* p = table + 6; /* keys table */ + FT_Byte* subs = table + 518; /* subheaders table */ + FT_Byte* sub; + + + if ( char_hi == 0 ) + { + /* an 8-bit character code -- we use subHeader 0 in this case */ + /* to test whether the character code is in the charmap */ + /* */ + sub = subs; /* jump to first sub-header */ + + /* check that the sub-header for this byte is 0, which */ + /* indicates that it's really a valid one-byte value */ + /* Otherwise, return 0 */ + /* */ + p += char_lo * 2; + if ( TT_PEEK_USHORT( p ) != 0 ) + goto Exit; + } + else + { + /* a 16-bit character code */ + p += char_hi * 2; /* jump to key entry */ + sub = subs + ( TT_PEEK_USHORT( p ) & -8 ); /* jump to sub-header */ + + /* check that the hi byte isn't a valid one-byte value */ + if ( sub == subs ) + goto Exit; + } + result = sub; + } + Exit: + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap2_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* subheader; + + + subheader = tt_cmap2_get_subheader( table, char_code ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt idx = (FT_UInt)(char_code & 0xFF); + FT_UInt start, count; + FT_Int delta; + FT_UInt offset; + + + start = TT_NEXT_USHORT( p ); + count = TT_NEXT_USHORT( p ); + delta = TT_NEXT_SHORT ( p ); + offset = TT_PEEK_USHORT( p ); + + idx -= start; + if ( idx < count && offset != 0 ) + { + p += offset + 2 * idx; + idx = TT_PEEK_USHORT( p ); + + if ( idx != 0 ) + result = (FT_UInt)( idx + delta ) & 0xFFFFU; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap2_char_next( TT_CMap cmap, + FT_UInt32 *pcharcode ) + { + FT_Byte* table = cmap->data; + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 charcode = *pcharcode + 1; + FT_Byte* subheader; + + + while ( charcode < 0x10000UL ) + { + subheader = tt_cmap2_get_subheader( table, charcode ); + if ( subheader ) + { + FT_Byte* p = subheader; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_Int delta = TT_NEXT_SHORT ( p ); + FT_UInt offset = TT_PEEK_USHORT( p ); + FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); + FT_UInt pos, idx; + + + if ( offset == 0 ) + goto Next_SubHeader; + + if ( char_lo < start ) + { + char_lo = start; + pos = 0; + } + else + pos = (FT_UInt)( char_lo - start ); + + p += offset + pos * 2; + charcode = ( charcode & -256 ) + char_lo; + + for ( ; pos < count; pos++, charcode++ ) + { + idx = TT_NEXT_USHORT( p ); + + if ( idx != 0 ) + { + gindex = ( idx + delta ) & 0xFFFFU; + if ( gindex != 0 ) + { + result = charcode; + goto Exit; + } + } + } + } + + /* jump to next sub-header, i.e. higher byte value */ + Next_SubHeader: + charcode = ( charcode & -256 ) + 256; + } + + Exit: + *pcharcode = result; + + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap2_class_rec = + { + { + sizeof( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, + (FT_CMap_CharNextFunc) tt_cmap2_char_next + }, + 2, + (TT_CMap_ValidateFunc) tt_cmap2_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_2 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 4 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length */ + /* in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* segCountX2 6 USHORT 2*NUM_SEGS */ + /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ + /* entrySelector 10 USHORT LOG_SEGS */ + /* rangeShift 12 USHORT segCountX2 - */ + /* searchRange */ + /* */ + /* endCount 14 USHORT[NUM_SEGS] end charcode for */ + /* each segment; last */ + /* is 0xFFFF */ + /* */ + /* pad 14+NUM_SEGS*2 USHORT padding */ + /* */ + /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ + /* each segment */ + /* */ + /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ + /* segment */ + /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ + /* each segment; can be */ + /* zero */ + /* */ + /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph id */ + /* ranges */ + /* */ + /* Character codes are modelled by a series of ordered (increasing) */ + /* intervals called segments. Each segment has start and end codes, */ + /* provided by the `startCount' and `endCount' arrays. Segments must */ + /* not be overlapping and the last segment should always contain the */ + /* `0xFFFF' endCount. */ + /* */ + /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ + /* ignored (they are traces of over-engineering in the TrueType */ + /* specification). */ + /* */ + /* Each segment also has a signed `delta', as well as an optional offset */ + /* within the `glyphIds' table. */ + /* */ + /* If a segment's idOffset is 0, the glyph index corresponding to any */ + /* charcode within the segment is obtained by adding the value of */ + /* `idDelta' directly to the charcode, modulo 65536. */ + /* */ + /* Otherwise, a glyph index is taken from the glyph ids sub-array for */ + /* the segment, and the value of `idDelta' is added to it. */ + /* */ + /* */ + /* Finally, note that certain fonts contain invalid charmaps that */ + /* contain end=0xFFFF, start=0xFFFF, delta=0x0001, offset=0xFFFF at the */ + /* of their charmaps (e.g. opens___.ttf which comes with OpenOffice.org) */ + /* we need special code to deal with them correctly... */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + + FT_CALLBACK_DEF( void ) + tt_cmap4_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 2; /* skip format */ + FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; + FT_UInt num_segs; + + + /* in certain fonts, the `length' field is invalid and goes */ + /* out of bound. We try to correct this here... */ + if ( length < 16 ) + FT_INVALID_TOO_SHORT; + + if ( table + length > valid->limit ) + { + if ( valid->level >= FT_VALIDATE_TIGHT ) + FT_INVALID_TOO_SHORT; + + length = (FT_UInt)( valid->limit - table ); + } + + p = table + 6; + num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ + + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check that we have an even value here */ + if ( num_segs & 1 ) + FT_INVALID_DATA; + } + + num_segs /= 2; + + /* check the search parameters - even though we never use them */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + /* check the values of 'searchRange', 'entrySelector', 'rangeShift' */ + FT_UInt search_range = TT_NEXT_USHORT( p ); + FT_UInt entry_selector = TT_NEXT_USHORT( p ); + FT_UInt range_shift = TT_NEXT_USHORT( p ); + + + if ( ( search_range | range_shift ) & 1 ) /* must be even values */ + FT_INVALID_DATA; + + search_range /= 2; + range_shift /= 2; + + /* `search range' is the greatest power of 2 that is <= num_segs */ + + if ( search_range > num_segs || + search_range * 2 < num_segs || + search_range + range_shift != num_segs || + search_range != ( 1U << entry_selector ) ) + FT_INVALID_DATA; + } + + ends = table + 14; + starts = table + 16 + num_segs * 2; + deltas = starts + num_segs * 2; + offsets = deltas + num_segs * 2; + glyph_ids = offsets + num_segs * 2; + + if ( glyph_ids > table + length ) + FT_INVALID_TOO_SHORT; + + /* check last segment, its end count must be FFFF */ + if ( valid->level >= FT_VALIDATE_PARANOID ) + { + p = ends + ( num_segs - 1 ) * 2; + if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) + FT_INVALID_DATA; + } + + /* check that segments are sorted in increasing order and do not */ + /* overlap; check also the offsets */ + { + FT_UInt start, end, last = 0, offset, n; + FT_Int delta; + + + for ( n = 0; n < num_segs; n++ ) + { + p = starts + n * 2; + start = TT_PEEK_USHORT( p ); + p = ends + n * 2; + end = TT_PEEK_USHORT( p ); + p = deltas + n * 2; + delta = TT_PEEK_SHORT( p ); + p = offsets + n * 2; + offset = TT_PEEK_USHORT( p ); + + if ( start > end ) + FT_INVALID_DATA; + + /* this test should be performed at default validation level; */ + /* unfortunately, some popular Asian fonts present overlapping */ + /* ranges in their charmaps */ + /* */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + } + + if ( offset && offset != 0xFFFFU ) + { + p += offset; /* start of glyph id array */ + + /* check that we point within the glyph ids table only */ + if ( p < glyph_ids || + p + ( end - start + 1 ) * 2 > table + length ) + FT_INVALID_DATA; + + /* check glyph indices within the segment range */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt i, idx; + + + for ( i = start; i < end; i++ ) + { + idx = FT_NEXT_USHORT( p ); + if ( idx != 0 ) + { + idx = (FT_UInt)( idx + delta ) & 0xFFFFU; + + if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + } + else if ( offset == 0xFFFFU ) + { + /* Some fonts (erroneously?) use a range offset of 0xFFFF */ + /* to mean missing glyph in cmap table */ + /* */ + if ( valid->level >= FT_VALIDATE_PARANOID || + n != num_segs - 1 || + !( start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) ) + FT_INVALID_DATA; + } + + last = end; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap4_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + + + if ( char_code < 0x10000UL ) + { + FT_UInt idx, num_segs2; + FT_Int delta; + FT_UInt code = (FT_UInt)char_code; + FT_Byte* p; + + + p = table + 6; + num_segs2 = TT_PEEK_USHORT( p ) & -2; /* be paranoid! */ + +#if 1 + /* Some fonts have more than 170 segments in their charmaps! */ + /* We changed this function to use a more efficient binary */ + /* search for improving performance */ + { + FT_UInt min = 0; + FT_UInt max = num_segs2 >> 1; + FT_UInt mid, start, end, offset; + + + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 14 + mid * 2; + end = TT_NEXT_USHORT( p ); + p += num_segs2; + start = TT_PEEK_USHORT( p); + + if ( code < start ) + max = mid; + + else if ( code > end ) + min = mid + 1; + + else + { + /* we found the segment */ + idx = code; + + p += num_segs2; + delta = TT_PEEK_SHORT( p ); + + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset == 0xFFFFU ) + goto Exit; + + if ( offset != 0 ) + { + p += offset + 2 * ( idx - start ); + idx = TT_PEEK_USHORT( p ); + } + + if ( idx != 0 ) + result = (FT_UInt)( idx + delta ) & 0xFFFFU; + + goto Exit; + } + } + } + +#else /* 0 - old code */ + + { + FT_UInt n; + FT_Byte* q; + + + p = table + 14; /* ends table */ + q = table + 16 + num_segs2; /* starts table */ + + + for ( n = 0; n < num_segs2; n += 2 ) + { + FT_UInt end = TT_NEXT_USHORT( p ); + FT_UInt start = TT_NEXT_USHORT( q ); + FT_UInt offset; + + + if ( code < start ) + break; + + if ( code <= end ) + { + idx = code; + + p = q + num_segs2 - 2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset == 0xFFFFU ) + goto Exit; + + if ( offset != 0 ) + { + p += offset + 2 * ( idx - start ); + idx = TT_PEEK_USHORT( p ); + } + + if ( idx != 0 ) + result = (FT_UInt)( idx + delta ) & 0xFFFFU; + } + } + } + +#endif /* 0 */ + + } + + Exit: + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap4_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* p; + FT_Byte* q; + FT_UInt code, num_segs2; + + + if ( char_code >= 0x10000UL ) + goto Exit; + + code = (FT_UInt)char_code; + p = table + 6; + num_segs2 = TT_PEEK_USHORT(p) & -2; /* ensure even-ness */ + + for (;;) + { + FT_UInt offset, n; + FT_Int delta; + + + p = table + 14; /* ends table */ + q = table + 16 + num_segs2; /* starts table */ + + for ( n = 0; n < num_segs2; n += 2 ) + { + FT_UInt end = TT_NEXT_USHORT( p ); + FT_UInt start = TT_NEXT_USHORT( q ); + + + if ( code < start ) + code = start; + + if ( code <= end ) + { + p = q + num_segs2 - 2; + delta = TT_PEEK_SHORT( p ); + p += num_segs2; + offset = TT_PEEK_USHORT( p ); + + if ( offset != 0 && offset != 0xFFFFU ) + { + /* parse the glyph ids array for non-0 index */ + p += offset + ( code - start ) * 2; + while ( code <= end ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; + if ( gindex != 0 ) + break; + } + code++; + } + } + else if ( offset == 0xFFFFU ) + { + /* an offset of 0xFFFF means an empty glyph in certain fonts! */ + code = end; + break; + } + else + gindex = (FT_UInt)( code + delta ) & 0xFFFFU; + + if ( gindex == 0 ) + break; + + result = code; + goto Exit; + } + } + + /* loop to next trial charcode */ + if ( code >= 0xFFFFU ) + break; + + code++; + } + return (FT_UInt)result; + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap4_class_rec = + { + { + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, + (FT_CMap_CharNextFunc) tt_cmap4_char_next + }, + 4, + (TT_CMap_ValidateFunc) tt_cmap4_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_4 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 6 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 4 */ + /* length 2 USHORT table length in bytes */ + /* language 4 USHORT Mac language code */ + /* */ + /* first 6 USHORT first segment code */ + /* count 8 USHORT segment size in chars */ + /* glyphIds 10 USHORT[count] glyph ids */ + /* */ + /* A very simplified segment mapping. */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + + FT_CALLBACK_DEF( void ) + tt_cmap6_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_UInt length, start, count; + + + if ( table + 10 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_USHORT( p ); + + p = table + 6; /* skip language */ + start = TT_NEXT_USHORT( p ); + count = TT_NEXT_USHORT( p ); + + if ( table + length > valid->limit || length < 10 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap6_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx = (FT_UInt)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap6_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + + FT_Byte* p = table + 6; + FT_UInt start = TT_NEXT_USHORT( p ); + FT_UInt count = TT_NEXT_USHORT( p ); + FT_UInt idx; + + + if ( char_code >= 0x10000UL ) + goto Exit; + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + result = char_code; + break; + } + char_code++; + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap6_class_rec = + { + { + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, + (FT_CMap_CharNextFunc) tt_cmap6_char_next + }, + 6, + (TT_CMap_ValidateFunc) tt_cmap6_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_6 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 8 *****/ + /***** *****/ + /***** It's hard to completely understand what the OpenType spec *****/ + /***** says about this format, but here is my conclusion. *****/ + /***** *****/ + /***** The purpose of this format is to easily map UTF-16 text to *****/ + /***** glyph indices. Basically, the `char_code' must be in one of *****/ + /***** the following formats: *****/ + /***** *****/ + /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ + /***** Area (i.e. U+D800-U+DFFF). *****/ + /***** *****/ + /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ + /***** `char_code = (char_hi << 16) | char_lo', then both *****/ + /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ + /***** Area. *****/ + /***** *****/ + /***** The 'is32' table embedded in the charmap indicates whether a *****/ + /***** given 16-bit value is in the surrogates area or not. *****/ + /***** *****/ + /***** So, for any given `char_code', we can assert the following: *****/ + /***** *****/ + /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ + /***** *****/ + /***** If `char_hi != 0' then we must have both *****/ + /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 8 */ + /* reseved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* is32 12 BYTE[8192] 32-bitness bitmap */ + /* count 8204 ULONG number of groups */ + /* */ + /* This header is followed by 'count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph id for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + + FT_CALLBACK_DEF( void ) + tt_cmap8_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_Byte* is32; + FT_UInt32 length; + FT_UInt32 num_groups; + + + if ( table + 16 + 8192 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + if ( table + length > valid->limit || length < 8208 ) + FT_INVALID_TOO_SHORT; + + is32 = table + 12; + p = is32 + 8192; /* skip `is32' array */ + num_groups = TT_NEXT_ULONG( p ); + + if ( p + num_groups * 12 > valid->limit ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_UInt32 n, start, end, start_id, count, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + FT_UInt hi, lo; + + + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + + count = (FT_UInt32)( end - start + 1 ); + + if ( start & ~0xFFFFU ) + { + /* start_hi != 0; check that is32[i] is 1 for each i in */ + /* the `hi' and `lo' of the range [start..end] */ + for ( ; count > 0; count--, start++ ) + { + hi = (FT_UInt)( start >> 16 ); + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) + FT_INVALID_DATA; + } + } + else + { + /* start_hi == 0; check that is32[i] is 0 for each i in */ + /* the range [start..end] */ + + /* end_hi cannot be != 0! */ + if ( end & ~0xFFFFU ) + FT_INVALID_DATA; + + for ( ; count > 0; count--, start++ ) + { + lo = (FT_UInt)( start & 0xFFFFU ); + + if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) + FT_INVALID_DATA; + } + } + } + + last = end; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap8_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + break; + + if ( char_code <= end ) + { + result = (FT_UInt)( start_id + char_code - start ); + break; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap8_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* table = cmap->data; + FT_Byte* p = table + 8204; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + p = table + 8208; + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)( char_code - start + start_id ); + if ( gindex != 0 ) + { + result = char_code; + goto Exit; + } + } + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap8_class_rec = + { + { + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, + (FT_CMap_CharNextFunc) tt_cmap8_char_next + }, + 8, + (TT_CMap_ValidateFunc) tt_cmap8_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_8 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 10 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 10 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* */ + /* start 12 ULONG first char in range */ + /* count 16 ULONG number of chars in range */ + /* glyphIds 20 USHORT[count] glyph indices covered */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + + FT_CALLBACK_DEF( void ) + tt_cmap10_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p = table + 4; + FT_ULong length, start, count; + + + if ( table + 20 > valid->limit ) + FT_INVALID_TOO_SHORT; + + length = TT_NEXT_ULONG( p ); + p = table + 12; + start = TT_NEXT_ULONG( p ); + count = TT_NEXT_ULONG( p ); + + if ( table + length > valid->limit || length < 20 + count * 2 ) + FT_INVALID_TOO_SHORT; + + /* check glyph indices */ + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + FT_UInt gindex; + + + for ( ; count > 0; count-- ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap10_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_Byte* table = cmap->data; + FT_UInt result = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx = (FT_ULong)( char_code - start ); + + + if ( idx < count ) + { + p += 2 * idx; + result = TT_PEEK_USHORT( p ); + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap10_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* p = table + 12; + FT_UInt32 start = TT_NEXT_ULONG( p ); + FT_UInt32 count = TT_NEXT_ULONG( p ); + FT_UInt32 idx; + + + if ( char_code < start ) + char_code = start; + + idx = (FT_UInt32)( char_code - start ); + p += 2 * idx; + + for ( ; idx < count; idx++ ) + { + gindex = TT_NEXT_USHORT( p ); + if ( gindex != 0 ) + { + result = char_code; + break; + } + char_code++; + } + + *pchar_code = char_code; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap10_class_rec = + { + { + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, + (FT_CMap_CharNextFunc) tt_cmap10_char_next + }, + 10, + (TT_CMap_ValidateFunc) tt_cmap10_validate + }; + +#endif /* TT_CONFIG_CMAP_FORMAT_10 */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FORMAT 12 *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* TABLE OVERVIEW */ + /* -------------- */ + /* */ + /* NAME OFFSET TYPE DESCRIPTION */ + /* */ + /* format 0 USHORT must be 12 */ + /* reserved 2 USHORT reserved */ + /* length 4 ULONG length in bytes */ + /* language 8 ULONG Mac language code */ + /* count 12 ULONG number of groups */ + /* 16 */ + /* */ + /* This header is followed by `count' groups of the following format: */ + /* */ + /* start 0 ULONG first charcode */ + /* end 4 ULONG last charcode */ + /* startId 8 ULONG start glyph id for the group */ + /* */ + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + + FT_CALLBACK_DEF( void ) + tt_cmap12_validate( FT_Byte* table, + FT_Validator valid ) + { + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; + + + if ( table + 16 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 4; + length = TT_NEXT_ULONG( p ); + + p = table + 12; + num_groups = TT_NEXT_ULONG( p ); + + if ( table + length > valid->limit || length < 16 + 12 * num_groups ) + FT_INVALID_TOO_SHORT; + + /* check groups, they must be in increasing order */ + { + FT_ULong n, start, end, start_id, last = 0; + + + for ( n = 0; n < num_groups; n++ ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( start > end ) + FT_INVALID_DATA; + + if ( n > 0 && start <= last ) + FT_INVALID_DATA; + + if ( valid->level >= FT_VALIDATE_TIGHT ) + { + if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) + FT_INVALID_GLYPH_ID; + } + + last = end; + } + } + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap12_char_index( TT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt result = 0; + FT_Byte* table = cmap->data; + FT_Byte* p = table + 12; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + break; + + if ( char_code <= end ) + { + result = (FT_UInt)( start_id + char_code - start ); + break; + } + } + return result; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap12_char_next( TT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_Byte* table = cmap->data; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + FT_UInt gindex = 0; + FT_Byte* p = table + 12; + FT_UInt32 num_groups = TT_NEXT_ULONG( p ); + FT_UInt32 start, end, start_id; + + + p = table + 16; + + for ( ; num_groups > 0; num_groups-- ) + { + start = TT_NEXT_ULONG( p ); + end = TT_NEXT_ULONG( p ); + start_id = TT_NEXT_ULONG( p ); + + if ( char_code < start ) + char_code = start; + + if ( char_code <= end ) + { + gindex = (FT_UInt)(char_code - start + start_id); + if ( gindex != 0 ) + { + result = char_code; + goto Exit; + } + } + } + + Exit: + *pchar_code = result; + return gindex; + } + + + FT_CALLBACK_TABLE_DEF + const TT_CMap_ClassRec tt_cmap12_class_rec = + { + { + sizeof ( TT_CMapRec ), + + (FT_CMap_InitFunc) tt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, + (FT_CMap_CharNextFunc) tt_cmap12_char_next + }, + 12, + (TT_CMap_ValidateFunc) tt_cmap12_validate + }; + + +#endif /* TT_CONFIG_CMAP_FORMAT_12 */ + + + static const TT_CMap_Class tt_cmap_classes[] = + { +#ifdef TT_CONFIG_CMAP_FORMAT_0 + &tt_cmap0_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_2 + &tt_cmap2_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_4 + &tt_cmap4_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_6 + &tt_cmap6_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_8 + &tt_cmap8_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_10 + &tt_cmap10_class_rec, +#endif + +#ifdef TT_CONFIG_CMAP_FORMAT_12 + &tt_cmap12_class_rec, +#endif + + NULL, + }; + + + /* parse the `cmap' table and build the corresponding TT_CMap objects */ + /* in the current face */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_build_cmaps( TT_Face face ) + { + FT_Byte* table = face->cmap_table; + FT_Byte* limit = table + face->cmap_size; + FT_UInt volatile num_cmaps; + FT_Byte* volatile p = table; + + + if ( p + 4 > limit ) + return FT_Err_Invalid_Table; + + /* only recognize format 0 */ + if ( TT_NEXT_USHORT( p ) != 0 ) + { + p -= 2; + FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n", + TT_PEEK_USHORT( p ) )); + return FT_Err_Invalid_Table; + } + + num_cmaps = TT_NEXT_USHORT( p ); + + for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) + { + FT_CharMapRec charmap; + FT_UInt32 offset; + + + charmap.platform_id = TT_NEXT_USHORT( p ); + charmap.encoding_id = TT_NEXT_USHORT( p ); + charmap.face = FT_FACE( face ); + charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ + offset = TT_NEXT_ULONG( p ); + + if ( offset && table + offset + 2 < limit ) + { + FT_Byte* cmap = table + offset; + FT_UInt format = TT_PEEK_USHORT( cmap ); + const TT_CMap_Class* volatile pclazz = tt_cmap_classes; + TT_CMap_Class clazz; + + + for ( ; *pclazz; pclazz++ ) + { + clazz = *pclazz; + if ( clazz->format == format ) + { + volatile TT_ValidatorRec valid; + + + ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, + FT_VALIDATE_DEFAULT ); + + valid.num_glyphs = (FT_UInt)face->root.num_glyphs; + + if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer ) == 0 ) + { + /* validate this cmap sub-table */ + clazz->validate( cmap, FT_VALIDATOR( &valid ) ); + } + + if ( valid.validator.error == 0 ) + (void)FT_CMap_New( (FT_CMap_Class)clazz, cmap, &charmap, NULL ); + else + { + FT_ERROR(( "tt_face_build_cmaps:" )); + FT_ERROR(( " broken cmap sub-table ignored!\n" )); + } + } + } + } + } + + return 0; + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttcmap0.h b/lib/freetype/src/sfnt/ttcmap0.h new file mode 100644 index 0000000..ff1276e --- /dev/null +++ b/lib/freetype/src/sfnt/ttcmap0.h @@ -0,0 +1,74 @@ +/***************************************************************************/ +/* */ +/* ttcmap0.h */ +/* */ +/* TrueType new character mapping table (cmap) support (specification). */ +/* */ +/* Copyright 2002 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 __TTCMAP0_H__ +#define __TTCMAP0_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + typedef struct TT_CMapRec_ + { + FT_CMapRec cmap; + FT_Byte* data; /* pointer to in-memory cmap table */ + + } TT_CMapRec, *TT_CMap; + + typedef const struct TT_CMap_ClassRec_* TT_CMap_Class; + + + typedef FT_Error + (*TT_CMap_ValidateFunc)( FT_Byte* data, + FT_Validator valid ); + + typedef struct TT_CMap_ClassRec_ + { + FT_CMap_ClassRec clazz; + FT_UInt format; + TT_CMap_ValidateFunc validate; + + } TT_CMap_ClassRec; + + + typedef struct TT_ValidatorRec_ + { + FT_ValidatorRec validator; + FT_UInt num_glyphs; + + } TT_ValidatorRec, *TT_Validator; + + +#define TT_VALIDATOR( x ) ((TT_Validator)( x )) +#define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs + + + FT_LOCAL( FT_Error ) + tt_face_build_cmaps( TT_Face face ); + + +FT_END_HEADER + +#endif /* __TTCMAP0_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttload.c b/lib/freetype/src/sfnt/ttload.c new file mode 100644 index 0000000..7a79503 --- /dev/null +++ b/lib/freetype/src/sfnt/ttload.c @@ -0,0 +1,1870 @@ +/***************************************************************************/ +/* */ +/* ttload.c */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttload.h" +#include "ttcmap.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttload + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_lookup_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* <Return> */ + /* A pointer to the table directory entry. 0 if not found. */ + /* */ + FT_LOCAL_DEF( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ) + { + TT_Table entry; + TT_Table limit; + + + FT_TRACE3(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ", + face, + (FT_Char)( tag >> 24 ), + (FT_Char)( tag >> 16 ), + (FT_Char)( tag >> 8 ), + (FT_Char)( tag ) )); + + entry = face->dir_tables; + limit = entry + face->num_tables; + + for ( ; entry < limit; entry++ ) + { + /* For compatibility with Windows, we consider 0-length */ + /* tables the same as missing tables. */ + if ( entry->Tag == tag && entry->Length != 0 ) + { + FT_TRACE3(( "found table.\n" )); + return entry; + } + } + + FT_TRACE3(( "could not find table!\n" )); + return 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_goto_table */ + /* */ + /* <Description> */ + /* Looks for a TrueType table by name, then seek a stream to it. */ + /* */ + /* <Input> */ + /* face :: A face object handle. */ + /* */ + /* tag :: The searched tag. */ + /* */ + /* stream :: The stream to seek when the table is found. */ + /* */ + /* <Output> */ + /* length :: The length of the table if found, undefined otherwise. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ) + { + TT_Table table; + FT_Error error; + + + table = tt_face_lookup_table( face, tag ); + if ( table ) + { + if ( length ) + *length = table->Length; + + if ( FT_STREAM_SEEK( table->Offset ) ) + goto Exit; + } + else + error = SFNT_Err_Table_Missing; + + Exit: + return error; + } + + + /* In theory, we should check the values of `search_range', */ + /* `entry_selector', and `range_shift' to detect non-SFNT based files */ + /* whose header might also start with 0x100000L (yes, these exist). */ + /* */ + /* Very unfortunately, many TrueType fonts don't have these fields */ + /* set correctly and we must ignore them to support them. An alternative */ + /* way to check the font file is thus to: */ + /* */ + /* - check that `num_tables' is valid */ + /* - look for a "head" table, check its size, and parse it to */ + /* see if its "magic" field is correctly set */ + /* */ + /* When checking directory entries, ignore the tables `glyx' and `locx' */ + /* which are hacked-out versions of `glyf' and `loca' in some PostScript */ + /* Type 42 fonts, and will generally be invalid. */ + /* */ + static FT_Error + sfnt_dir_check( FT_Stream stream, + FT_ULong offset, + FT_UInt num_tables ) + { + FT_Error error; + FT_UInt nn, has_head = 0; + + const FT_ULong glyx_tag = FT_MAKE_TAG( 'g', 'l', 'y', 'x' ); + const FT_ULong locx_tag = FT_MAKE_TAG( 'l', 'o', 'c', 'x' ); + + static const FT_Frame_Field sfnt_dir_entry_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_TableRec + + FT_FRAME_START( 16 ), + FT_FRAME_ULONG( Tag ), + FT_FRAME_ULONG( CheckSum ), + FT_FRAME_ULONG( Offset ), + FT_FRAME_ULONG( Length ), + FT_FRAME_END + }; + + + /* if 'num_tables' is 0, read the table count from the file */ + if ( num_tables == 0 ) + { + FT_ULong format_tag; + + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_ULONG ( format_tag ) || + FT_READ_USHORT( num_tables ) || + FT_STREAM_SKIP( 6 ) ) + goto Bad_Format; + + if ( offset + 12 + num_tables*16 > stream->size ) + goto Bad_Format; + } + else if ( FT_STREAM_SEEK( offset + 12 ) ) + goto Bad_Format; + + for ( nn = 0; nn < num_tables; nn++ ) + { + TT_TableRec table; + + + if ( FT_STREAM_READ_FIELDS( sfnt_dir_entry_fields, &table ) ) + goto Bad_Format; + + if ( table.Offset + table.Length > stream->size && + table.Tag != glyx_tag && table.Tag != locx_tag ) + goto Bad_Format; + + if ( table.Tag == TTAG_head ) + { + FT_UInt32 magic; + + + has_head = 1; + + /* the table length should be 0x36, but certain font tools + * make it 0x38, so we will just check that it is greater. + * + * note that according to the specification, + * the table must be padded to 32-bit lengths, but this doesn't + * apply to the value of its "Length" field !! + */ + if ( table.Length < 0x36 || + FT_STREAM_SEEK( table.Offset + 12 ) || + FT_READ_ULONG( magic ) || + magic != 0x5F0F3CF5UL ) + goto Bad_Format; + + if ( FT_STREAM_SEEK( offset + 28 + 16*nn ) ) + goto Bad_Format; + } + } + + if ( has_head == 0 ) + goto Bad_Format; + + Exit: + return error; + + Bad_Format: + error = FT_Err_Unknown_File_Format; + goto Exit; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_sfnt_header */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. Supports collections. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* face_index :: If the font is a collection, the number of the font */ + /* in the collection, ignored otherwise. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType collection' */ + /* */ + /* The header will be checked whether it is valid by looking at the */ + /* values of `search_range', `entry_selector', and `range_shift'. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_sfnt_header( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header sfnt ) + { + FT_Error error; + FT_ULong format_tag, offset; + FT_Memory memory = stream->memory; + + static const FT_Frame_Field sfnt_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE SFNT_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( search_range ), + FT_FRAME_USHORT( entry_selector ), + FT_FRAME_USHORT( range_shift ), + FT_FRAME_END + }; + + static const FT_Frame_Field ttc_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TTC_HeaderRec + + FT_FRAME_START( 8 ), + FT_FRAME_LONG( version ), + FT_FRAME_LONG( count ), + FT_FRAME_END + }; + + + FT_TRACE2(( "tt_face_load_sfnt_header: %08p, %ld\n", + face, face_index )); + + face->ttc_header.tag = 0; + face->ttc_header.version = 0; + face->ttc_header.count = 0; + + face->num_tables = 0; + + /* first of all, read the first 4 bytes. If it is `ttcf', then the */ + /* file is a TrueType collection, otherwise it can be any other */ + /* kind of font. */ + /* */ + offset = FT_STREAM_POS(); + + if ( FT_READ_ULONG( format_tag ) ) + goto Exit; + + if ( format_tag == TTAG_ttcf ) + { + FT_Int n; + + + FT_TRACE3(( "tt_face_load_sfnt_header: file is a collection\n" )); + + /* It is a TrueType collection, i.e. a file containing several */ + /* font files. Read the font directory now */ + if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) + goto Exit; + + /* now read the offsets of each font in the file */ + if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) || + FT_FRAME_ENTER( face->ttc_header.count * 4L ) ) + goto Exit; + + for ( n = 0; n < face->ttc_header.count; n++ ) + face->ttc_header.offsets[n] = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + /* check face index */ + if ( face_index >= face->ttc_header.count ) + { + error = SFNT_Err_Bad_Argument; + goto Exit; + } + + /* seek to the appropriate TrueType file, then read tag */ + offset = face->ttc_header.offsets[face_index]; + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_LONG( format_tag ) ) + goto Exit; + } + + /* the format tag was read, now check the rest of the header */ + sfnt->format_tag = format_tag; + sfnt->offset = offset; + + if ( FT_STREAM_READ_FIELDS( sfnt_header_fields, sfnt ) ) + goto Exit; + + /* now check the sfnt directory */ + error = sfnt_dir_check( stream, offset, sfnt->num_tables ); + if ( error ) + { + FT_TRACE2(( "tt_face_load_sfnt_header: file is not SFNT!\n" )); + error = SFNT_Err_Unknown_File_Format; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_directory */ + /* */ + /* <Description> */ + /* Loads the table directory into a face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* sfnt :: The SFNT directory header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_directory( TT_Face face, + FT_Stream stream, + SFNT_Header sfnt ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + TT_TableRec *entry, *limit; + + + FT_TRACE2(( "tt_face_load_directory: %08p\n", face )); + + FT_TRACE2(( "-- Tables count: %12u\n", sfnt->num_tables )); + FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag )); + + face->num_tables = sfnt->num_tables; + + if ( FT_NEW_ARRAY( face->dir_tables, face->num_tables ) ) + goto Exit; + + if ( FT_STREAM_SEEK( sfnt->offset + 12 ) || + FT_FRAME_ENTER( face->num_tables * 16L ) ) + goto Exit; + + entry = face->dir_tables; + limit = entry + face->num_tables; + + for ( ; entry < limit; entry++ ) + { /* loop through the tables and get all entries */ + entry->Tag = FT_GET_TAG4(); + entry->CheckSum = FT_GET_ULONG(); + entry->Offset = FT_GET_LONG(); + entry->Length = FT_GET_LONG(); + + FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", + (FT_Char)( entry->Tag >> 24 ), + (FT_Char)( entry->Tag >> 16 ), + (FT_Char)( entry->Tag >> 8 ), + (FT_Char)( entry->Tag ), + entry->Offset, + entry->Length )); + } + + FT_FRAME_EXIT(); + + FT_TRACE2(( "Directory loaded\n\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_any */ + /* */ + /* <Description> */ + /* Loads any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The 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 :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ) + { + FT_Error error; + FT_Stream stream; + TT_Table table; + FT_ULong size; + + + if ( tag != 0 ) + { + /* look for tag in font directory */ + table = tt_face_lookup_table( face, tag ); + if ( !table ) + { + error = SFNT_Err_Table_Missing; + goto Exit; + } + + offset += table->Offset; + size = table->Length; + } + else + /* tag == 0 -- the user wants to access the font file directly */ + size = face->root.stream->size; + + if ( length && *length == 0 ) + { + *length = size; + + return SFNT_Err_Ok; + } + + if ( length ) + size = *length; + + stream = face->root.stream; + /* the `if' is syntactic sugar for picky compilers */ + if ( FT_STREAM_READ_AT( offset, buffer, size ) ) + goto Exit; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_generic_header */ + /* */ + /* <Description> */ + /* Loads the TrueType table `head' or `bhed'. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_load_generic_header( TT_Face face, + FT_Stream stream, + FT_ULong tag ) + { + FT_Error error; + TT_Header* header; + + static const FT_Frame_Field header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Header + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Table_Version ), + FT_FRAME_ULONG ( Font_Revision ), + FT_FRAME_LONG ( CheckSum_Adjust ), + FT_FRAME_LONG ( Magic_Number ), + FT_FRAME_USHORT( Flags ), + FT_FRAME_USHORT( Units_Per_EM ), + FT_FRAME_LONG ( Created[0] ), + FT_FRAME_LONG ( Created[1] ), + FT_FRAME_LONG ( Modified[0] ), + FT_FRAME_LONG ( Modified[1] ), + FT_FRAME_SHORT ( xMin ), + FT_FRAME_SHORT ( yMin ), + FT_FRAME_SHORT ( xMax ), + FT_FRAME_SHORT ( yMax ), + FT_FRAME_USHORT( Mac_Style ), + FT_FRAME_USHORT( Lowest_Rec_PPEM ), + FT_FRAME_SHORT ( Font_Direction ), + FT_FRAME_SHORT ( Index_To_Loc_Format ), + FT_FRAME_SHORT ( Glyph_Data_Format ), + FT_FRAME_END + }; + + + FT_TRACE2(( "tt_face_load_generic_header: " + "%08p, looking up font table `%c%c%c%c'.\n", + face, + (FT_Char)( tag >> 24 ), + (FT_Char)( tag >> 16 ), + (FT_Char)( tag >> 8 ), + (FT_Char)( tag ) )); + + error = face->goto_table( face, tag, stream, 0 ); + if ( error ) + { + FT_TRACE2(( "tt_face_load_generic_header: Font table is missing!\n" )); + goto Exit; + } + + header = &face->header; + + if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) + goto Exit; + + FT_TRACE2(( " Units per EM: %8u\n", header->Units_Per_EM )); + FT_TRACE2(( " IndexToLoc: %8d\n", header->Index_To_Loc_Format )); + FT_TRACE2(( "tt_face_load_generic_header: Font table loaded.\n" )); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_header( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_head ); + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_bitmap_header( TT_Face face, + FT_Stream stream ) + { + return tt_face_load_generic_header( face, stream, TTAG_bhed ); + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_max_profile */ + /* */ + /* <Description> */ + /* Loads the maximum profile into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_max_profile( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_MaxProfile* maxProfile = &face->max_profile; + + const FT_Frame_Field maxp_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_MaxProfile + + FT_FRAME_START( 6 ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT( numGlyphs ), + FT_FRAME_END + }; + + const FT_Frame_Field maxp_fields_extra[] = + { + FT_FRAME_START( 26 ), + FT_FRAME_USHORT( maxPoints ), + FT_FRAME_USHORT( maxContours ), + FT_FRAME_USHORT( maxCompositePoints ), + FT_FRAME_USHORT( maxCompositeContours ), + FT_FRAME_USHORT( maxZones ), + FT_FRAME_USHORT( maxTwilightPoints ), + FT_FRAME_USHORT( maxStorage ), + FT_FRAME_USHORT( maxFunctionDefs ), + FT_FRAME_USHORT( maxInstructionDefs ), + FT_FRAME_USHORT( maxStackElements ), + FT_FRAME_USHORT( maxSizeOfInstructions ), + FT_FRAME_USHORT( maxComponentElements ), + FT_FRAME_USHORT( maxComponentDepth ), + FT_FRAME_END + }; + + + FT_TRACE2(( "Load_TT_MaxProfile: %08p\n", face )); + + error = face->goto_table( face, TTAG_maxp, stream, 0 ); + if ( error ) + goto Exit; + + if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) + goto Exit; + + maxProfile->maxPoints = 0; + maxProfile->maxContours = 0; + maxProfile->maxCompositePoints = 0; + maxProfile->maxCompositeContours = 0; + maxProfile->maxZones = 0; + maxProfile->maxTwilightPoints = 0; + maxProfile->maxStorage = 0; + maxProfile->maxFunctionDefs = 0; + maxProfile->maxInstructionDefs = 0; + maxProfile->maxStackElements = 0; + maxProfile->maxSizeOfInstructions = 0; + maxProfile->maxComponentElements = 0; + maxProfile->maxComponentDepth = 0; + + if ( maxProfile->version >= 0x10000L ) + { + if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) + goto Exit; + + /* XXX: an adjustment 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->root.num_glyphs = maxProfile->numGlyphs; + + face->root.internal->max_points = + (FT_UShort)MAX( maxProfile->maxCompositePoints, + maxProfile->maxPoints ); + + face->root.internal->max_contours = + (FT_Short)MAX( maxProfile->maxCompositeContours, + maxProfile->maxContours ); + + face->max_components = (FT_ULong)maxProfile->maxComponentElements + + maxProfile->maxComponentDepth; + + /* XXX: some fonts have maxComponents set to 0; we will */ + /* then use 16 of them by default. */ + if ( face->max_components == 0 ) + face->max_components = 16; + + /* We also increase maxPoints and maxContours in order to support */ + /* some broken fonts. */ + face->root.internal->max_points += (FT_UShort)8; + face->root.internal->max_contours += (FT_Short) 4; + } + + FT_TRACE2(( "MAXP loaded.\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_metrics */ + /* */ + /* <Description> */ + /* Loads the horizontal or vertical metrics table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + tt_face_load_metrics( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_ULong table_len; + FT_Long num_shorts, num_longs, num_shorts_checked; + + TT_LongMetrics * longs; + TT_ShortMetrics** shorts; + + + FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical" + : "Horizontal", + 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! */ + /* */ + error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); + if ( error ) + { + /* Set number_Of_VMetrics to 0! */ + FT_TRACE2(( " no vertical header in file.\n" )); + face->vertical.number_Of_VMetrics = 0; + error = SFNT_Err_Ok; + goto Exit; + } + + num_longs = face->vertical.number_Of_VMetrics; + longs = (TT_LongMetrics *)&face->vertical.long_metrics; + shorts = (TT_ShortMetrics**)&face->vertical.short_metrics; + } + else + { + error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); + if ( error ) + { + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* If this is an incrementally loaded font and there are */ + /* overriding metrics tolerate a missing 'hmtx' table. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs-> + get_glyph_metrics ) + { + face->horizontal.number_Of_HMetrics = 0; + error = SFNT_Err_Ok; + goto Exit; + } +#endif + + FT_ERROR(( " no horizontal metrics in file!\n" )); + error = SFNT_Err_Hmtx_Table_Missing; + goto Exit; + } + + num_longs = face->horizontal.number_Of_HMetrics; + longs = (TT_LongMetrics *)&face->horizontal.long_metrics; + shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics; + } + + /* never trust derived values */ + + num_shorts = face->max_profile.numGlyphs - num_longs; + num_shorts_checked = ( table_len - num_longs * 4L ) / 2; + + if ( num_shorts < 0 ) + { + FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n", + vertical ? "Vertical" + : "Horizontal" )); + + error = vertical ? SFNT_Err_Invalid_Vert_Metrics + : SFNT_Err_Invalid_Horiz_Metrics; + goto Exit; + } + + if ( FT_NEW_ARRAY( *longs, num_longs ) || + FT_NEW_ARRAY( *shorts, num_shorts ) ) + goto Exit; + + if ( FT_FRAME_ENTER( table_len ) ) + goto Exit; + + { + TT_LongMetrics cur = *longs; + TT_LongMetrics limit = cur + num_longs; + + + for ( ; cur < limit; cur++ ) + { + cur->advance = FT_GET_USHORT(); + cur->bearing = FT_GET_SHORT(); + } + } + + /* do we have an inconsistent number of metric values? */ + { + TT_ShortMetrics* cur = *shorts; + TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); + + + for ( ; cur < limit; cur++ ) + *cur = FT_GET_SHORT(); + + /* we fill up the missing left side bearings with the */ + /* last valid value. Since this will occur for buggy CJK */ + /* fonts usually only, nothing serious will happen */ + if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) + { + FT_Short val = (*shorts)[num_shorts_checked - 1]; + + + limit = *shorts + num_shorts; + for ( ; cur < limit; cur++ ) + *cur = val; + } + } + + FT_FRAME_EXIT(); + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_metrics_header */ + /* */ + /* <Description> */ + /* Loads the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_metrics_header( TT_Face face, + FT_Stream stream, + FT_Bool vertical ) + { + FT_Error error; + TT_HoriHeader* header; + + const FT_Frame_Field metrics_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_HoriHeader + + FT_FRAME_START( 36 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_SHORT ( Ascender ), + FT_FRAME_SHORT ( Descender ), + FT_FRAME_SHORT ( Line_Gap ), + FT_FRAME_USHORT( advance_Width_Max ), + FT_FRAME_SHORT ( min_Left_Side_Bearing ), + FT_FRAME_SHORT ( min_Right_Side_Bearing ), + FT_FRAME_SHORT ( xMax_Extent ), + FT_FRAME_SHORT ( caret_Slope_Rise ), + FT_FRAME_SHORT ( caret_Slope_Run ), + FT_FRAME_SHORT ( caret_Offset ), + FT_FRAME_SHORT ( Reserved[0] ), + FT_FRAME_SHORT ( Reserved[1] ), + FT_FRAME_SHORT ( Reserved[2] ), + FT_FRAME_SHORT ( Reserved[3] ), + FT_FRAME_SHORT ( metric_Data_Format ), + FT_FRAME_USHORT( number_Of_HMetrics ), + FT_FRAME_END + }; + + + FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " )); + + if ( vertical ) + { + face->vertical_info = 0; + + /* The vertical header table is optional, so return quietly if */ + /* we don't find it. */ + error = face->goto_table( face, TTAG_vhea, stream, 0 ); + if ( error ) + { + error = SFNT_Err_Ok; + goto Exit; + } + + face->vertical_info = 1; + header = (TT_HoriHeader*)&face->vertical; + } + else + { + /* The horizontal header is mandatory; return an error if we */ + /* don't find it. */ + error = face->goto_table( face, TTAG_hhea, stream, 0 ); + if ( error ) + { + error = SFNT_Err_Horiz_Header_Missing; + goto Exit; + } + + header = &face->horizontal; + } + + if ( FT_STREAM_READ_FIELDS( metrics_header_fields, header ) ) + goto Exit; + + header->long_metrics = NULL; + header->short_metrics = NULL; + + FT_TRACE2(( "loaded\n" )); + + /* Now try to load the corresponding metrics */ + + error = tt_face_load_metrics( face, stream, vertical ); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_names */ + /* */ + /* <Description> */ + /* Loads the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_names( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_pos, table_len; + FT_ULong storage_start, storage_limit; + FT_UInt count; + TT_NameTable table; + + static const FT_Frame_Field name_table_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameTableRec + + FT_FRAME_START( 6 ), + FT_FRAME_USHORT( format ), + FT_FRAME_USHORT( numNameRecords ), + FT_FRAME_USHORT( storageOffset ), + FT_FRAME_END + }; + + static const FT_Frame_Field name_record_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_NameEntryRec + + /* no FT_FRAME_START */ + FT_FRAME_USHORT( platformID ), + FT_FRAME_USHORT( encodingID ), + FT_FRAME_USHORT( languageID ), + FT_FRAME_USHORT( nameID ), + FT_FRAME_USHORT( stringLength ), + FT_FRAME_USHORT( stringOffset ), + FT_FRAME_END + }; + + + table = &face->name_table; + table->stream = stream; + + FT_TRACE2(( "Names " )); + + error = face->goto_table( face, TTAG_name, stream, &table_len ); + if ( error ) + { + /* The name table is required so indicate failure. */ + FT_TRACE2(( "is missing!\n" )); + error = SFNT_Err_Name_Table_Missing; + goto Exit; + } + + table_pos = FT_STREAM_POS(); + + + if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) + goto Exit; + + /* Some popular Asian fonts have an invalid `storageOffset' value */ + /* (it should be at least "6 + 12*num_names"). However, the string */ + /* offsets, computed as "storageOffset + entry->stringOffset", are */ + /* valid pointers within the name table... */ + /* */ + /* We thus can't check `storageOffset' right now. */ + /* */ + storage_start = table_pos + 6 + 12*table->numNameRecords; + storage_limit = table_pos + table_len; + + if ( storage_start > storage_limit ) + { + FT_ERROR(( "tt_face_load_names: invalid `name' table\n" )); + error = SFNT_Err_Name_Table_Missing; + goto Exit; + } + + /* Allocate the array of name records. */ + count = table->numNameRecords; + table->numNameRecords = 0; + + if ( FT_NEW_ARRAY( table->names, count ) || + FT_FRAME_ENTER( count * 12 ) ) + goto Exit; + + /* Load the name records and determine how much storage is needed */ + /* to hold the strings themselves. */ + { + TT_NameEntryRec* entry = table->names; + + + for ( ; count > 0; count-- ) + { + if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) + continue; + + /* check that the name is not empty */ + if ( entry->stringLength == 0 ) + continue; + + /* check that the name string is within the table */ + entry->stringOffset += table_pos + table->storageOffset; + if ( entry->stringOffset < storage_start || + entry->stringOffset + entry->stringLength > storage_limit ) + { + /* invalid entry - ignore it */ + entry->stringOffset = 0; + entry->stringLength = 0; + continue; + } + + entry++; + } + + table->numNameRecords = (FT_UInt)( entry - table->names ); + } + + FT_FRAME_EXIT(); + + FT_TRACE2(( "loaded\n" )); + + /* everything went well, update face->num_names */ + face->num_names = (FT_UShort) table->numNameRecords; + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_names */ + /* */ + /* <Description> */ + /* Frees the name records. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_names( TT_Face face ) + { + FT_Memory memory = face->root.driver->root.memory; + TT_NameTable table = &face->name_table; + TT_NameEntry entry = table->names; + FT_UInt count = table->numNameRecords; + + + for ( ; count > 0; count--, entry++ ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + + /* free strings table */ + FT_FREE( table->names ); + + table->numNameRecords = 0; + table->format = 0; + table->storageOffset = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_cmap */ + /* */ + /* <Description> */ + /* Loads the cmap directory in a face object. The cmaps itselves are */ + /* loaded on demand in the `ttcmap.c' module. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + + + error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); + if ( error ) + { + FT_TRACE2(( "No `cmap' table in font !\n" )); + error = SFNT_Err_CMap_Table_Missing; + goto Exit; + } + + if ( !FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) + FT_TRACE2(( "`cmap' table loaded\n" )); + else + { + FT_ERROR(( "`cmap' table is too short!\n" )); + face->cmap_size = 0; + } + + Exit: + return error; + } + + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_os2 */ + /* */ + /* <Description> */ + /* Loads the OS2 table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_OS2* os2; + + const FT_Frame_Field os2_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_OS2 + + FT_FRAME_START( 78 ), + FT_FRAME_USHORT( version ), + FT_FRAME_SHORT ( xAvgCharWidth ), + FT_FRAME_USHORT( usWeightClass ), + FT_FRAME_USHORT( usWidthClass ), + FT_FRAME_SHORT ( fsType ), + FT_FRAME_SHORT ( ySubscriptXSize ), + FT_FRAME_SHORT ( ySubscriptYSize ), + FT_FRAME_SHORT ( ySubscriptXOffset ), + FT_FRAME_SHORT ( ySubscriptYOffset ), + FT_FRAME_SHORT ( ySuperscriptXSize ), + FT_FRAME_SHORT ( ySuperscriptYSize ), + FT_FRAME_SHORT ( ySuperscriptXOffset ), + FT_FRAME_SHORT ( ySuperscriptYOffset ), + FT_FRAME_SHORT ( yStrikeoutSize ), + FT_FRAME_SHORT ( yStrikeoutPosition ), + FT_FRAME_SHORT ( sFamilyClass ), + FT_FRAME_BYTE ( panose[0] ), + FT_FRAME_BYTE ( panose[1] ), + FT_FRAME_BYTE ( panose[2] ), + FT_FRAME_BYTE ( panose[3] ), + FT_FRAME_BYTE ( panose[4] ), + FT_FRAME_BYTE ( panose[5] ), + FT_FRAME_BYTE ( panose[6] ), + FT_FRAME_BYTE ( panose[7] ), + FT_FRAME_BYTE ( panose[8] ), + FT_FRAME_BYTE ( panose[9] ), + FT_FRAME_ULONG ( ulUnicodeRange1 ), + FT_FRAME_ULONG ( ulUnicodeRange2 ), + FT_FRAME_ULONG ( ulUnicodeRange3 ), + FT_FRAME_ULONG ( ulUnicodeRange4 ), + FT_FRAME_BYTE ( achVendID[0] ), + FT_FRAME_BYTE ( achVendID[1] ), + FT_FRAME_BYTE ( achVendID[2] ), + FT_FRAME_BYTE ( achVendID[3] ), + + FT_FRAME_USHORT( fsSelection ), + FT_FRAME_USHORT( usFirstCharIndex ), + FT_FRAME_USHORT( usLastCharIndex ), + FT_FRAME_SHORT ( sTypoAscender ), + FT_FRAME_SHORT ( sTypoDescender ), + FT_FRAME_SHORT ( sTypoLineGap ), + FT_FRAME_USHORT( usWinAscent ), + FT_FRAME_USHORT( usWinDescent ), + FT_FRAME_END + }; + + const FT_Frame_Field os2_fields_extra[] = + { + FT_FRAME_START( 8 ), + FT_FRAME_ULONG( ulCodePageRange1 ), + FT_FRAME_ULONG( ulCodePageRange2 ), + FT_FRAME_END + }; + + const FT_Frame_Field os2_fields_extra2[] = + { + FT_FRAME_START( 10 ), + FT_FRAME_SHORT ( sxHeight ), + FT_FRAME_SHORT ( sCapHeight ), + FT_FRAME_USHORT( usDefaultChar ), + FT_FRAME_USHORT( usBreakChar ), + FT_FRAME_USHORT( usMaxContext ), + FT_FRAME_END + }; + + + FT_TRACE2(( "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. */ + error = face->goto_table( face, TTAG_OS2, stream, 0 ); + if ( error ) + { + FT_TRACE2(( "is missing!\n" )); + face->os2.version = 0xFFFFU; + error = SFNT_Err_Ok; + goto Exit; + } + + os2 = &face->os2; + + if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) + goto Exit; + + os2->ulCodePageRange1 = 0; + os2->ulCodePageRange2 = 0; + os2->sxHeight = 0; + os2->sCapHeight = 0; + os2->usDefaultChar = 0; + os2->usBreakChar = 0; + os2->usMaxContext = 0; + + if ( os2->version >= 0x0001 ) + { + /* only version 1 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) + goto Exit; + + if ( os2->version >= 0x0002 ) + { + /* only version 2 tables */ + if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) + goto Exit; + } + } + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_postscript */ + /* */ + /* <Description> */ + /* Loads the Postscript table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_postscript( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + TT_Postscript* post = &face->postscript; + + static const FT_Frame_Field post_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_Postscript + + FT_FRAME_START( 32 ), + FT_FRAME_ULONG( FormatType ), + FT_FRAME_ULONG( italicAngle ), + FT_FRAME_SHORT( underlinePosition ), + FT_FRAME_SHORT( underlineThickness ), + FT_FRAME_ULONG( isFixedPitch ), + FT_FRAME_ULONG( minMemType42 ), + FT_FRAME_ULONG( maxMemType42 ), + FT_FRAME_ULONG( minMemType1 ), + FT_FRAME_ULONG( maxMemType1 ), + FT_FRAME_END + }; + + + FT_TRACE2(( "PostScript " )); + + error = face->goto_table( face, TTAG_post, stream, 0 ); + if ( error ) + return SFNT_Err_Post_Table_Missing; + + if ( FT_STREAM_READ_FIELDS( post_fields, post ) ) + return error; + + /* we don't load the glyph names, we do that in another */ + /* module (ttpost). */ + FT_TRACE2(( "loaded\n" )); + + return SFNT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_pclt */ + /* */ + /* <Description> */ + /* Loads the PCL 5 Table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ) + { + static const FT_Frame_Field pclt_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_PCLT + + FT_FRAME_START( 54 ), + FT_FRAME_ULONG ( Version ), + FT_FRAME_ULONG ( FontNumber ), + FT_FRAME_USHORT( Pitch ), + FT_FRAME_USHORT( xHeight ), + FT_FRAME_USHORT( Style ), + FT_FRAME_USHORT( TypeFamily ), + FT_FRAME_USHORT( CapHeight ), + FT_FRAME_BYTES ( TypeFace, 16 ), + FT_FRAME_BYTES ( CharacterComplement, 8 ), + FT_FRAME_BYTES ( FileName, 6 ), + FT_FRAME_CHAR ( StrokeWeight ), + FT_FRAME_CHAR ( WidthType ), + FT_FRAME_BYTE ( SerifStyle ), + FT_FRAME_BYTE ( Reserved ), + FT_FRAME_END + }; + + FT_Error error; + TT_PCLT* pclt = &face->pclt; + + + FT_TRACE2(( "PCLT " )); + + /* optional table */ + error = face->goto_table( face, TTAG_PCLT, stream, 0 ); + if ( error ) + { + FT_TRACE2(( "missing (optional)\n" )); + pclt->Version = 0; + return SFNT_Err_Ok; + } + + if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) ) + goto Exit; + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_gasp */ + /* */ + /* <Description> */ + /* Loads the `gasp' table into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_UInt j,num_ranges; + TT_GaspRange gaspranges; + + + FT_TRACE2(( "tt_face_load_gasp: %08p\n", face )); + + /* the gasp table is optional */ + error = face->goto_table( face, TTAG_gasp, stream, 0 ); + if ( error ) + return SFNT_Err_Ok; + + if ( FT_FRAME_ENTER( 4L ) ) + goto Exit; + + face->gasp.version = FT_GET_USHORT(); + face->gasp.numRanges = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + num_ranges = face->gasp.numRanges; + FT_TRACE3(( "number of ranges = %d\n", num_ranges )); + + if ( FT_NEW_ARRAY( gaspranges, num_ranges ) || + FT_FRAME_ENTER( num_ranges * 4L ) ) + goto Exit; + + face->gasp.gaspRanges = gaspranges; + + for ( j = 0; j < num_ranges; j++ ) + { + gaspranges[j].maxPPEM = FT_GET_USHORT(); + gaspranges[j].gaspFlag = FT_GET_USHORT(); + + FT_TRACE3(( " [max:%d flag:%d]", + gaspranges[j].maxPPEM, + gaspranges[j].gaspFlag )); + } + FT_TRACE3(( "\n" )); + + FT_FRAME_EXIT(); + FT_TRACE2(( "GASP loaded\n" )); + + Exit: + return error; + } + + + FT_CALLBACK_DEF( int ) + tt_kern_pair_compare( const void* a, + const void* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_kern */ + /* */ + /* <Description> */ + /* Loads the first kerning table with format 0 in the font. Only */ + /* accepts the first horizontal kerning table. Developers should use */ + /* the `ftxkern' extension to access other kerning tables in the font */ + /* file, if they really want to. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + FT_UInt n, num_tables; + + + /* the kern table is optional; exit silently if it is missing */ + error = face->goto_table( face, TTAG_kern, stream, 0 ); + if ( error ) + return SFNT_Err_Ok; + + if ( FT_FRAME_ENTER( 4L ) ) + goto Exit; + + (void)FT_GET_USHORT(); /* version */ + num_tables = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + for ( n = 0; n < num_tables; n++ ) + { + FT_UInt coverage; + FT_UInt length; + + + if ( FT_FRAME_ENTER( 6L ) ) + goto Exit; + + (void)FT_GET_USHORT(); /* version */ + length = FT_GET_USHORT() - 6; /* substract header length */ + coverage = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + + if ( coverage == 0x0001 ) + { + FT_UInt num_pairs; + TT_Kern0_Pair pair; + TT_Kern0_Pair limit; + + + /* found a horizontal format 0 kerning table! */ + if ( FT_FRAME_ENTER( 8L ) ) + goto Exit; + + num_pairs = FT_GET_USHORT(); + + /* skip the rest */ + + FT_FRAME_EXIT(); + + /* allocate array of kerning pairs */ + if ( FT_NEW_ARRAY( face->kern_pairs, num_pairs ) || + FT_FRAME_ENTER( 6L * num_pairs ) ) + goto Exit; + + pair = face->kern_pairs; + limit = pair + num_pairs; + for ( ; pair < limit; pair++ ) + { + pair->left = FT_GET_USHORT(); + pair->right = FT_GET_USHORT(); + pair->value = FT_GET_USHORT(); + } + + FT_FRAME_EXIT(); + + face->num_kern_pairs = num_pairs; + face->kern_table_index = n; + + /* ensure that the kerning pair table is sorted (yes, some */ + /* fonts have unsorted tables!) */ + { + FT_UInt i; + TT_Kern0_Pair pair0; + + + pair0 = face->kern_pairs; + + for ( i = 1; i < num_pairs; i++, pair0++ ) + { + if ( tt_kern_pair_compare( pair0, pair0 + 1 ) != -1 ) + { + ft_qsort( (void*)face->kern_pairs, (int)num_pairs, + sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare ); + break; + } + } + } + + goto Exit; + } + + if ( FT_STREAM_SKIP( length ) ) + goto Exit; + } + + /* no kern table found -- doesn't matter */ + face->kern_table_index = -1; + face->num_kern_pairs = 0; + face->kern_pairs = NULL; + + Exit: + return error; + } + + +#undef TT_KERN_INDEX +#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) + + + FT_CALLBACK_DEF( int ) + tt_kern_pair_compare( const void* a, + const void* b ) + { + TT_Kern0_Pair pair1 = (TT_Kern0_Pair)a; + TT_Kern0_Pair pair2 = (TT_Kern0_Pair)b; + + FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right ); + FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right ); + + + return ( index1 < index2 ? -1 : + ( index1 > index2 ? 1 : 0 )); + } + + +#undef TT_KERN_INDEX + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_hdmx */ + /* */ + /* <Description> */ + /* Loads the horizontal device metrics table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + TT_Hdmx hdmx = &face->hdmx; + FT_Long num_glyphs; + FT_Long record_size; + + + hdmx->version = 0; + hdmx->num_records = 0; + hdmx->records = 0; + + /* this table is optional */ + error = face->goto_table( face, TTAG_hdmx, stream, 0 ); + if ( error ) + return SFNT_Err_Ok; + + if ( FT_FRAME_ENTER( 8L ) ) + goto Exit; + + hdmx->version = FT_GET_USHORT(); + hdmx->num_records = FT_GET_SHORT(); + record_size = FT_GET_LONG(); + + FT_FRAME_EXIT(); + + /* Only recognize format 0 */ + if ( hdmx->version != 0 ) + goto Exit; + + if ( FT_NEW_ARRAY( hdmx->records, hdmx->num_records ) ) + goto Exit; + + num_glyphs = face->root.num_glyphs; + record_size -= num_glyphs + 2; + + { + TT_HdmxEntry cur = hdmx->records; + TT_HdmxEntry limit = cur + hdmx->num_records; + + + for ( ; cur < limit; cur++ ) + { + /* read record */ + if ( FT_READ_BYTE( cur->ppem ) || + FT_READ_BYTE( cur->max_width ) ) + goto Exit; + + if ( FT_ALLOC( cur->widths, num_glyphs ) || + FT_STREAM_READ( cur->widths, num_glyphs ) ) + goto Exit; + + /* skip padding bytes */ + if ( record_size > 0 && FT_STREAM_SKIP( record_size ) ) + goto Exit; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_hdmx */ + /* */ + /* <Description> */ + /* Frees the horizontal device metrics table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_hdmx( TT_Face face ) + { + if ( face ) + { + FT_Int n; + FT_Memory memory = face->root.driver->root.memory; + + + for ( n = 0; n < face->hdmx.num_records; n++ ) + FT_FREE( face->hdmx.records[n].widths ); + + FT_FREE( face->hdmx.records ); + face->hdmx.num_records = 0; + } + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttload.h b/lib/freetype/src/sfnt/ttload.h new file mode 100644 index 0000000..27c41b5 --- /dev/null +++ b/lib/freetype/src/sfnt/ttload.h @@ -0,0 +1,137 @@ +/***************************************************************************/ +/* */ +/* ttload.h */ +/* */ +/* Load the basic TrueType tables, i.e., tables that can be either in */ +/* TTF or OTF fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTLOAD_H__ +#define __TTLOAD_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( TT_Table ) + tt_face_lookup_table( TT_Face face, + FT_ULong tag ); + + FT_LOCAL( FT_Error ) + tt_face_goto_table( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_sfnt_header( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header sfnt ); + + FT_LOCAL( FT_Error ) + tt_face_load_directory( TT_Face face, + FT_Stream stream, + SFNT_Header sfnt ); + + FT_LOCAL( FT_Error ) + tt_face_load_any( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + FT_LOCAL( FT_Error ) + tt_face_load_header( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_metrics_header( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + FT_LOCAL( FT_Error ) + tt_face_load_cmap( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_max_profile( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_names( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_os2( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_postscript( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_hdmx( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_Error ) + tt_face_load_pclt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_names( TT_Face face ); + + + FT_LOCAL( void ) + tt_face_free_hdmx ( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_load_kern( TT_Face face, + FT_Stream stream ); + + + FT_LOCAL( FT_Error ) + tt_face_load_gasp( TT_Face face, + FT_Stream stream ); + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_LOCAL( FT_Error ) + tt_face_load_bitmap_header( TT_Face face, + FT_Stream stream ); + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + +FT_END_HEADER + +#endif /* __TTLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttpost.c b/lib/freetype/src/sfnt/ttpost.c new file mode 100644 index 0000000..486ba3d --- /dev/null +++ b/lib/freetype/src/sfnt/ttpost.c @@ -0,0 +1,521 @@ +/***************************************************************************/ +/* */ +/* ttpost.c */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttpost.h" +#include "ttload.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttpost + + + /* If this configuration macro is defined, we rely on the `PSNames' */ + /* module to grab the glyph names. */ + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) + + +#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + /* Otherwise, we ignore the `PSNames' module, and provide our own */ + /* table of Mac names. Thus, it is possible to build a version of */ + /* FreeType without the Type 1 driver & PSNames module. */ + +#define MAC_NAME( x ) tt_post_default_names[x] + + /* the 258 default Mac PS glyph names */ + + static const FT_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", + }; + + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + + static FT_Error + load_format_20( TT_Face face, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_UShort num_names; + + FT_UShort* glyph_indices = 0; + FT_Char** name_strings = 0; + + + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* 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_glyphs > face->root.num_glyphs ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + /* load the indices */ + { + FT_Int n; + + + if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * 2L ) ) + goto Fail; + + for ( n = 0; n < num_glyphs; n++ ) + glyph_indices[n] = FT_GET_USHORT(); + + FT_FRAME_EXIT(); + } + + /* compute number of names stored in table */ + { + FT_Int n; + + + num_names = 0; + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Int idx; + + + idx = glyph_indices[n]; + if ( idx >= 258 ) + { + idx -= 257; + if ( idx > num_names ) + num_names = (FT_UShort)idx; + } + } + } + + /* now load the name strings */ + { + FT_UShort n; + + + if ( FT_NEW_ARRAY( name_strings, num_names ) ) + goto Fail; + + for ( n = 0; n < num_names; n++ ) + { + FT_UInt len; + + + if ( FT_READ_BYTE ( len ) || + FT_NEW_ARRAY( name_strings[n], len + 1 ) || + FT_STREAM_READ ( name_strings[n], len ) ) + goto Fail1; + + name_strings[n][len] = '\0'; + } + } + + /* all right, set table fields and exit successfuly */ + { + TT_Post_20 table = &face->postscript_names.names.format_20; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->num_names = (FT_UShort)num_names; + table->glyph_indices = glyph_indices; + table->glyph_names = name_strings; + } + return SFNT_Err_Ok; + + Fail1: + { + FT_UShort n; + + + for ( n = 0; n < num_names; n++ ) + FT_FREE( name_strings[n] ); + } + + Fail: + FT_FREE( name_strings ); + FT_FREE( glyph_indices ); + + Exit: + return error; + } + + + static FT_Error + load_format_25( TT_Face face, + FT_Stream stream ) + { + FT_Memory memory = stream->memory; + FT_Error error; + + FT_Int num_glyphs; + FT_Char* offset_table = 0; + + + /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ + if ( FT_READ_USHORT( num_glyphs ) ) + goto Exit; + + /* check the number of glyphs */ + if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 ) + { + error = SFNT_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_ALLOC( offset_table, num_glyphs ) || + FT_STREAM_READ( offset_table, num_glyphs ) ) + goto Fail; + + /* now check the offset table */ + { + FT_Int n; + + + for ( n = 0; n < num_glyphs; n++ ) + { + FT_Long idx = (FT_Long)n + offset_table[n]; + + + if ( idx < 0 || idx > num_glyphs ) + { + error = SFNT_Err_Invalid_File_Format; + goto Fail; + } + } + } + + /* OK, set table fields and exit successfuly */ + { + TT_Post_25 table = &face->postscript_names.names.format_25; + + + table->num_glyphs = (FT_UShort)num_glyphs; + table->offsets = offset_table; + } + + return SFNT_Err_Ok; + + Fail: + FT_FREE( offset_table ); + + Exit: + return error; + } + + + static FT_Error + load_post_names( TT_Face face ) + { + FT_Stream stream; + FT_Error error; + FT_Fixed format; + + + /* get a stream for the face's resource */ + stream = face->root.stream; + + /* seek to the beginning of the PS names table */ + error = face->goto_table( face, TTAG_post, stream, 0 ); + if ( error ) + goto Exit; + + format = face->postscript.FormatType; + + /* go to beginning of subtable */ + if ( FT_STREAM_SKIP( 32 ) ) + goto Exit; + + /* now read postscript table */ + if ( format == 0x00020000L ) + error = load_format_20( face, stream ); + else if ( format == 0x00028000L ) + error = load_format_25( face, stream ); + else + error = SFNT_Err_Invalid_File_Format; + + face->postscript_names.loaded = 1; + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + tt_face_free_ps_names( TT_Face face ) + { + FT_Memory memory = face->root.memory; + TT_Post_Names names = &face->postscript_names; + FT_Fixed format; + + + if ( names->loaded ) + { + format = face->postscript.FormatType; + + if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + FT_UShort n; + + + FT_FREE( table->glyph_indices ); + table->num_glyphs = 0; + + for ( n = 0; n < table->num_names; n++ ) + FT_FREE( table->glyph_names[n] ); + + FT_FREE( table->glyph_names ); + table->num_names = 0; + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + FT_FREE( table->offsets ); + table->num_glyphs = 0; + } + } + names->loaded = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_get_ps_name */ + /* */ + /* <Description> */ + /* Gets the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ) + { + FT_Error error; + TT_Post_Names names; + FT_Fixed format; + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + PSNames_Service psnames; +#endif + + + if ( !face ) + return SFNT_Err_Invalid_Face_Handle; + + if ( idx >= (FT_UInt)face->root.num_glyphs ) + return SFNT_Err_Invalid_Glyph_Index; + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + psnames = (PSNames_Service)face->psnames; + if ( !psnames ) + return SFNT_Err_Unimplemented_Feature; +#endif + + names = &face->postscript_names; + + /* `.notdef' by default */ + *PSname = MAC_NAME( 0 ); + + format = face->postscript.FormatType; + + if ( format == 0x00010000L ) + { + if ( idx < 258 ) /* paranoid checking */ + *PSname = MAC_NAME( idx ); + } + else if ( format == 0x00020000L ) + { + TT_Post_20 table = &names->names.format_20; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) + { + FT_UShort name_index = table->glyph_indices[idx]; + + + if ( name_index < 258 ) + *PSname = MAC_NAME( name_index ); + else + *PSname = (FT_String*)table->glyph_names[name_index - 258]; + } + } + else if ( format == 0x00028000L ) + { + TT_Post_25 table = &names->names.format_25; + + + if ( !names->loaded ) + { + error = load_post_names( face ); + if ( error ) + goto End; + } + + if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ + { + idx += table->offsets[idx]; + *PSname = MAC_NAME( idx ); + } + } + + /* nothing to do for format == 0x00030000L */ + + End: + return SFNT_Err_Ok; + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttpost.h b/lib/freetype/src/sfnt/ttpost.h new file mode 100644 index 0000000..6f06d75 --- /dev/null +++ b/lib/freetype/src/sfnt/ttpost.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* ttpost.h */ +/* */ +/* Postcript name table processing for TrueType and OpenType fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTPOST_H__ +#define __TTPOST_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_get_ps_name( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + FT_LOCAL( void ) + tt_face_free_ps_names( TT_Face face ); + + +FT_END_HEADER + +#endif /* __TTPOST_H__ */ + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttsbit.c b/lib/freetype/src/sfnt/ttsbit.c new file mode 100644 index 0000000..9cfa92b --- /dev/null +++ b/lib/freetype/src/sfnt/ttsbit.c @@ -0,0 +1,1467 @@ +/***************************************************************************/ +/* */ +/* ttsbit.c */ +/* */ +/* TrueType and OpenType embedded bitmap support (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H +#include "ttsbit.h" + +#include "sferrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttsbit + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* blit_sbit */ + /* */ + /* <Description> */ + /* Blits a bitmap from an input stream into a given target. Supports */ + /* x and y offsets as well as byte padded lines. */ + /* */ + /* <Input> */ + /* target :: The target bitmap/pixmap. */ + /* */ + /* source :: The input packed bitmap data. */ + /* */ + /* line_bits :: The number of bits per line. */ + /* */ + /* byte_padded :: A flag which is true if lines are byte-padded. */ + /* */ + /* x_offset :: The horizontal offset. */ + /* */ + /* y_offset :: The vertical offset. */ + /* */ + /* <Note> */ + /* IMPORTANT: The x and y offsets are relative to the top corner of */ + /* the target bitmap (unlike the normal TrueType */ + /* convention). A positive y offset indicates a downwards */ + /* direction! */ + /* */ + static void + blit_sbit( FT_Bitmap* target, + FT_Byte* source, + FT_Int line_bits, + FT_Bool byte_padded, + FT_Int x_offset, + FT_Int y_offset ) + { + FT_Byte* line_buff; + FT_Int line_incr; + FT_Int height; + + FT_UShort acc; + FT_UInt loaded; + + + /* first of all, compute starting write position */ + line_incr = target->pitch; + line_buff = target->buffer; + + if ( line_incr < 0 ) + line_buff -= line_incr * ( target->rows - 1 ); + + line_buff += ( x_offset >> 3 ) + y_offset * line_incr; + + /***********************************************************************/ + /* */ + /* We use the extra-classic `accumulator' trick to extract the bits */ + /* from the source byte stream. */ + /* */ + /* Namely, the variable `acc' is a 16-bit accumulator containing the */ + /* last `loaded' bits from the input stream. The bits are shifted to */ + /* the upmost position in `acc'. */ + /* */ + /***********************************************************************/ + + acc = 0; /* clear accumulator */ + loaded = 0; /* no bits were loaded */ + + for ( height = target->rows; height > 0; height-- ) + { + FT_Byte* cur = line_buff; /* current write cursor */ + FT_Int count = line_bits; /* # of bits to extract per line */ + FT_Byte shift = (FT_Byte)( x_offset & 7 ); /* current write shift */ + FT_Byte space = (FT_Byte)( 8 - shift ); + + + /* first of all, read individual source bytes */ + if ( count >= 8 ) + { + count -= 8; + { + do + { + FT_Byte val; + + + /* ensure that there are at least 8 bits in the accumulator */ + if ( loaded < 8 ) + { + acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded )); + loaded += 8; + } + + /* now write one byte */ + val = (FT_Byte)( acc >> 8 ); + if ( shift ) + { + cur[0] |= (FT_Byte)( val >> shift ); + cur[1] |= (FT_Byte)( val << space ); + } + else + cur[0] |= val; + + cur++; + acc <<= 8; /* remove bits from accumulator */ + loaded -= 8; + count -= 8; + + } while ( count >= 0 ); + } + + /* restore `count' to correct value */ + count += 8; + } + + /* now write remaining bits (count < 8) */ + if ( count > 0 ) + { + FT_Byte val; + + + /* ensure that there are at least `count' bits in the accumulator */ + if ( (FT_Int)loaded < count ) + { + acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded )); + loaded += 8; + } + + /* now write remaining bits */ + val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) ); + cur[0] |= (FT_Byte)( val >> shift ); + + if ( count > space ) + cur[1] |= (FT_Byte)( val << space ); + + acc <<= count; + loaded -= count; + } + + /* now, skip to next line */ + if ( byte_padded ) + { + acc = 0; + loaded = 0; /* clear accumulator on byte-padded lines */ + } + + line_buff += line_incr; + } + } + + + const FT_Frame_Field sbit_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_MetricsRec + + FT_FRAME_START( 8 ), + FT_FRAME_BYTE( height ), + FT_FRAME_BYTE( width ), + + FT_FRAME_CHAR( horiBearingX ), + FT_FRAME_CHAR( horiBearingY ), + FT_FRAME_BYTE( horiAdvance ), + + FT_FRAME_CHAR( vertBearingX ), + FT_FRAME_CHAR( vertBearingY ), + FT_FRAME_BYTE( vertAdvance ), + FT_FRAME_END + }; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_SBit_Const_Metrics */ + /* */ + /* <Description> */ + /* Loads the metrics for `EBLC' index tables format 2 and 5. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Const_Metrics( TT_SBit_Range range, + FT_Stream stream ) + { + FT_Error error; + + + if ( FT_READ_ULONG( range->image_size ) ) + return error; + + return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_SBit_Range_Codes */ + /* */ + /* <Description> */ + /* Loads the range codes for `EBLC' index tables format 4 and 5. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* load_offsets :: A flag whether to load the glyph offset table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Range_Codes( TT_SBit_Range range, + FT_Stream stream, + FT_Bool load_offsets ) + { + FT_Error error; + FT_ULong count, n, size; + FT_Memory memory = stream->memory; + + + if ( FT_READ_ULONG( count ) ) + goto Exit; + + range->num_glyphs = count; + + /* Allocate glyph offsets table if needed */ + if ( load_offsets ) + { + if ( FT_NEW_ARRAY( range->glyph_offsets, count ) ) + goto Exit; + + size = count * 4L; + } + else + size = count * 2L; + + /* Allocate glyph codes table and access frame */ + if ( FT_NEW_ARRAY ( range->glyph_codes, count ) || + FT_FRAME_ENTER( size ) ) + goto Exit; + + for ( n = 0; n < count; n++ ) + { + range->glyph_codes[n] = FT_GET_USHORT(); + + if ( load_offsets ) + range->glyph_offsets[n] = (FT_ULong)range->image_offset + + FT_GET_USHORT(); + } + + FT_FRAME_EXIT(); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Load_SBit_Range */ + /* */ + /* <Description> */ + /* Loads a given `EBLC' index/range table. */ + /* */ + /* <Input> */ + /* range :: The target range. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_SBit_Range( TT_SBit_Range range, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + + + switch( range->index_format ) + { + case 1: /* variable metrics with 4-byte offsets */ + case 3: /* variable metrics with 2-byte offsets */ + { + FT_ULong num_glyphs, n; + FT_Int size_elem; + FT_Bool large = FT_BOOL( range->index_format == 1 ); + + + num_glyphs = range->last_glyph - range->first_glyph + 1L; + range->num_glyphs = num_glyphs; + num_glyphs++; /* XXX: BEWARE - see spec */ + + size_elem = large ? 4 : 2; + + if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) || + FT_FRAME_ENTER( num_glyphs * size_elem ) ) + goto Exit; + + for ( n = 0; n < num_glyphs; n++ ) + range->glyph_offsets[n] = (FT_ULong)( range->image_offset + + ( large ? FT_GET_ULONG() + : FT_GET_USHORT() ) ); + FT_FRAME_EXIT(); + } + break; + + case 2: /* all glyphs have identical metrics */ + error = Load_SBit_Const_Metrics( range, stream ); + break; + + case 4: + error = Load_SBit_Range_Codes( range, stream, 1 ); + break; + + case 5: + error = Load_SBit_Const_Metrics( range, stream ) || + Load_SBit_Range_Codes( range, stream, 0 ); + break; + + default: + error = SFNT_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_sbit_strikes */ + /* */ + /* <Description> */ + /* Loads the table of embedded bitmap sizes for this face. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_sbit_strikes( TT_Face face, + FT_Stream stream ) + { + FT_Error error = 0; + FT_Memory memory = stream->memory; + FT_Fixed version; + FT_ULong num_strikes; + FT_ULong table_base; + + const FT_Frame_Field sbit_line_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_LineMetricsRec + + /* no FT_FRAME_START */ + FT_FRAME_CHAR( ascender ), + FT_FRAME_CHAR( descender ), + FT_FRAME_BYTE( max_width ), + + FT_FRAME_CHAR( caret_slope_numerator ), + FT_FRAME_CHAR( caret_slope_denominator ), + FT_FRAME_CHAR( caret_offset ), + + FT_FRAME_CHAR( min_origin_SB ), + FT_FRAME_CHAR( min_advance_SB ), + FT_FRAME_CHAR( max_before_BL ), + FT_FRAME_CHAR( min_after_BL ), + FT_FRAME_CHAR( pads[0] ), + FT_FRAME_CHAR( pads[1] ), + FT_FRAME_END + }; + + const FT_Frame_Field strike_start_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_StrikeRec + + /* no FT_FRAME_START */ + FT_FRAME_ULONG( ranges_offset ), + FT_FRAME_SKIP_LONG, + FT_FRAME_ULONG( num_ranges ), + FT_FRAME_ULONG( color_ref ), + FT_FRAME_END + }; + + const FT_Frame_Field strike_end_fields[] = + { + /* no FT_FRAME_START */ + FT_FRAME_USHORT( start_glyph ), + FT_FRAME_USHORT( end_glyph ), + FT_FRAME_BYTE ( x_ppem ), + FT_FRAME_BYTE ( y_ppem ), + FT_FRAME_BYTE ( bit_depth ), + FT_FRAME_CHAR ( flags ), + FT_FRAME_END + }; + + + face->num_sbit_strikes = 0; + + /* this table is optional */ + error = face->goto_table( face, TTAG_EBLC, stream, 0 ); + if ( error ) + error = face->goto_table( face, TTAG_bloc, stream, 0 ); + if ( error ) + goto Exit; + + table_base = FT_STREAM_POS(); + if ( FT_FRAME_ENTER( 8L ) ) + goto Exit; + + version = FT_GET_LONG(); + num_strikes = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + /* check version number and strike count */ + if ( version != 0x00020000L || + num_strikes >= 0x10000L ) + { + FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" )); + error = SFNT_Err_Invalid_File_Format; + + goto Exit; + } + + /* allocate the strikes table */ + if ( FT_NEW_ARRAY( face->sbit_strikes, num_strikes ) ) + goto Exit; + + face->num_sbit_strikes = num_strikes; + + /* now read each strike table separately */ + { + TT_SBit_Strike strike = face->sbit_strikes; + FT_ULong count = num_strikes; + + + if ( FT_FRAME_ENTER( 48L * num_strikes ) ) + goto Exit; + + while ( count > 0 ) + { + if ( FT_STREAM_READ_FIELDS( strike_start_fields, strike ) || + FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->hori ) || + FT_STREAM_READ_FIELDS( sbit_line_metrics_fields, &strike->vert ) || + FT_STREAM_READ_FIELDS( strike_end_fields, strike ) ) + break; + + count--; + strike++; + } + + FT_FRAME_EXIT(); + } + + /* allocate the index ranges for each strike table */ + { + TT_SBit_Strike strike = face->sbit_strikes; + FT_ULong count = num_strikes; + + + while ( count > 0 ) + { + TT_SBit_Range range; + FT_ULong count2 = strike->num_ranges; + + + if ( FT_NEW_ARRAY( strike->sbit_ranges, strike->num_ranges ) ) + goto Exit; + + /* read each range */ + if ( FT_STREAM_SEEK( table_base + strike->ranges_offset ) || + FT_FRAME_ENTER( strike->num_ranges * 8L ) ) + goto Exit; + + range = strike->sbit_ranges; + while ( count2 > 0 ) + { + range->first_glyph = FT_GET_USHORT(); + range->last_glyph = FT_GET_USHORT(); + range->table_offset = table_base + strike->ranges_offset + + FT_GET_ULONG(); + count2--; + range++; + } + + FT_FRAME_EXIT(); + + /* Now, read each index table */ + count2 = strike->num_ranges; + range = strike->sbit_ranges; + while ( count2 > 0 ) + { + /* Read the header */ + if ( FT_STREAM_SEEK( range->table_offset ) || + FT_FRAME_ENTER( 8L ) ) + goto Exit; + + range->index_format = FT_GET_USHORT(); + range->image_format = FT_GET_USHORT(); + range->image_offset = FT_GET_ULONG(); + + FT_FRAME_EXIT(); + + error = Load_SBit_Range( range, stream ); + if ( error ) + goto Exit; + + count2--; + range++; + } + + count--; + strike++; + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_free_sbit_strikes */ + /* */ + /* <Description> */ + /* Releases the embedded bitmap tables. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_free_sbit_strikes( TT_Face face ) + { + FT_Memory memory = face->root.memory; + TT_SBit_Strike strike = face->sbit_strikes; + TT_SBit_Strike strike_limit = strike + face->num_sbit_strikes; + + + if ( strike ) + { + for ( ; strike < strike_limit; strike++ ) + { + TT_SBit_Range range = strike->sbit_ranges; + TT_SBit_Range range_limit = range + strike->num_ranges; + + + if ( range ) + { + for ( ; range < range_limit; range++ ) + { + /* release the glyph offsets and codes tables */ + /* where appropriate */ + FT_FREE( range->glyph_offsets ); + FT_FREE( range->glyph_codes ); + } + } + FT_FREE( strike->sbit_ranges ); + strike->num_ranges = 0; + } + FT_FREE( face->sbit_strikes ); + } + face->num_sbit_strikes = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Int x_ppem, + FT_Int y_ppem, + FT_ULong *astrike_index ) + { + FT_ULong i; + + + if ( x_ppem < 0 || x_ppem > 255 || + y_ppem < 1 || y_ppem > 255 ) + return SFNT_Err_Invalid_PPem; + + for ( i = 0; i < face->num_sbit_strikes; i++ ) + { + if ( ( face->sbit_strikes[i].y_ppem == y_ppem ) && + ( ( x_ppem == 0 ) || + ( face->sbit_strikes[i].x_ppem == x_ppem ) ) ) + { + *astrike_index = i; + return SFNT_Err_Ok; + } + } + + return SFNT_Err_Invalid_PPem; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_sbit_range */ + /* */ + /* <Description> */ + /* Scans a given strike's ranges and return, for a given glyph */ + /* index, the corresponding sbit range, and `EBDT' offset. */ + /* */ + /* <Input> */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike :: The source/current sbit strike. */ + /* */ + /* <Output> */ + /* arange :: The sbit range containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means the glyph index was found. */ + /* */ + static FT_Error + find_sbit_range( FT_UInt glyph_index, + TT_SBit_Strike strike, + TT_SBit_Range *arange, + FT_ULong *aglyph_offset ) + { + TT_SBit_RangeRec *range, *range_limit; + + + /* check whether the glyph index is within this strike's */ + /* glyph range */ + if ( glyph_index < (FT_UInt)strike->start_glyph || + glyph_index > (FT_UInt)strike->end_glyph ) + goto Fail; + + /* scan all ranges in strike */ + range = strike->sbit_ranges; + range_limit = range + strike->num_ranges; + if ( !range ) + goto Fail; + + for ( ; range < range_limit; range++ ) + { + if ( glyph_index >= (FT_UInt)range->first_glyph && + glyph_index <= (FT_UInt)range->last_glyph ) + { + FT_UShort delta = (FT_UShort)( glyph_index - range->first_glyph ); + + + switch ( range->index_format ) + { + case 1: + case 3: + *aglyph_offset = range->glyph_offsets[delta]; + break; + + case 2: + *aglyph_offset = range->image_offset + + range->image_size * delta; + break; + + case 4: + case 5: + { + FT_ULong n; + + + for ( n = 0; n < range->num_glyphs; n++ ) + { + if ( (FT_UInt)range->glyph_codes[n] == glyph_index ) + { + if ( range->index_format == 4 ) + *aglyph_offset = range->glyph_offsets[n]; + else + *aglyph_offset = range->image_offset + + n * range->image_size; + goto Found; + } + } + } + + /* fall-through */ + default: + goto Fail; + } + + Found: + /* return successfully! */ + *arange = range; + return 0; + } + } + + Fail: + *arange = 0; + *aglyph_offset = 0; + + return SFNT_Err_Invalid_Argument; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* find_sbit_image */ + /* */ + /* <Description> */ + /* Checks whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + static FT_Error + find_sbit_image( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ) + { + FT_Error error; + TT_SBit_Strike strike; + + + if ( !face->sbit_strikes || + ( face->num_sbit_strikes <= strike_index ) ) + goto Fail; + + strike = &face->sbit_strikes[strike_index]; + + error = find_sbit_range( glyph_index, strike, + arange, aglyph_offset ); + if ( error ) + goto Fail; + + *astrike = strike; + + return SFNT_Err_Ok; + + Fail: + /* no embedded bitmap for this glyph in face */ + *arange = 0; + *astrike = 0; + *aglyph_offset = 0; + + return SFNT_Err_Invalid_Argument; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* load_sbit_metrics */ + /* */ + /* <Description> */ + /* Gets the big metrics for a given SBit. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + static FT_Error + load_sbit_metrics( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ) + { + FT_Error error = SFNT_Err_Ok; + + + switch ( range->image_format ) + { + case 1: + case 2: + case 8: + /* variable small metrics */ + { + TT_SBit_SmallMetricsRec smetrics; + + const FT_Frame_Field sbit_small_metrics_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_SBit_SmallMetricsRec + + FT_FRAME_START( 5 ), + FT_FRAME_BYTE( height ), + FT_FRAME_BYTE( width ), + FT_FRAME_CHAR( bearingX ), + FT_FRAME_CHAR( bearingY ), + FT_FRAME_BYTE( advance ), + FT_FRAME_END + }; + + + /* read small metrics */ + if ( FT_STREAM_READ_FIELDS( sbit_small_metrics_fields, &smetrics ) ) + goto Exit; + + /* convert it to a big metrics */ + metrics->height = smetrics.height; + metrics->width = smetrics.width; + metrics->horiBearingX = smetrics.bearingX; + metrics->horiBearingY = smetrics.bearingY; + metrics->horiAdvance = smetrics.advance; + + /* these metrics are made up at a higher level when */ + /* needed. */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + } + break; + + case 6: + case 7: + case 9: + /* variable big metrics */ + if ( FT_STREAM_READ_FIELDS( sbit_metrics_fields, metrics ) ) + goto Exit; + break; + + case 5: + default: /* constant metrics */ + if ( range->index_format == 2 || range->index_format == 5 ) + *metrics = range->metrics; + else + return SFNT_Err_Invalid_File_Format; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* crop_bitmap */ + /* */ + /* <Description> */ + /* Crops a bitmap to its tightest bounding box, and adjusts its */ + /* metrics. */ + /* */ + /* <InOut> */ + /* map :: The bitmap. */ + /* */ + /* metrics :: The corresponding metrics structure. */ + /* */ + static void + crop_bitmap( FT_Bitmap* map, + TT_SBit_Metrics metrics ) + { + /***********************************************************************/ + /* */ + /* In this situation, some bounding boxes of embedded bitmaps are too */ + /* large. We need to crop it to a reasonable size. */ + /* */ + /* --------- */ + /* | | ----- */ + /* | *** | |***| */ + /* | * | | * | */ + /* | * | ------> | * | */ + /* | * | | * | */ + /* | * | | * | */ + /* | *** | |***| */ + /* --------- ----- */ + /* */ + /***********************************************************************/ + + FT_Int rows, count; + FT_Long line_len; + FT_Byte* line; + + + /***********************************************************************/ + /* */ + /* first of all, check the top-most lines of the bitmap, and remove */ + /* them if they're empty. */ + /* */ + { + line = (FT_Byte*)map->buffer; + rows = map->rows; + line_len = map->pitch; + + + for ( count = 0; count < rows; count++ ) + { + FT_Byte* cur = line; + FT_Byte* 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 = (FT_Byte*)map->buffer; + + FT_MEM_MOVE( line, line + count * line_len, + ( rows - count ) * line_len ); + + metrics->height = (FT_Byte)( metrics->height - count ); + metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count ); + metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count ); + + map->rows -= count; + rows -= count; + } + } + + /***********************************************************************/ + /* */ + /* second, crop the lower lines */ + /* */ + { + line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len; + + for ( count = 0; count < rows; count++ ) + { + FT_Byte* cur = line; + FT_Byte* 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 ) + { + metrics->height = (FT_Byte)( metrics->height - count ); + rows -= count; + map->rows -= count; + } + } + + /***********************************************************************/ + /* */ + /* third, get rid of the space on the left side of the glyph */ + /* */ + do + { + FT_Byte* limit; + + + line = (FT_Byte*)map->buffer; + 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 = (FT_Byte*)map->buffer; + limit = line + rows * line_len; + + for ( ; line < limit; line += line_len ) + { + FT_Int n, width = map->width; + FT_Byte old; + FT_Byte* cur = line; + + + old = (FT_Byte)(cur[0] << 1); + for ( n = 8; n < width; n += 8 ) + { + FT_Byte val; + + + val = cur[1]; + cur[0] = (FT_Byte)( old | ( val >> 7 ) ); + old = (FT_Byte)( val << 1 ); + cur++; + } + cur[0] = old; + } + + map->width--; + metrics->horiBearingX++; + metrics->vertBearingX++; + metrics->width--; + + } while ( map->width > 0 ); + + Found_Left: + + /***********************************************************************/ + /* */ + /* finally, crop the bitmap width to get rid of the space on the right */ + /* side of the glyph. */ + /* */ + do + { + FT_Int right = map->width - 1; + FT_Byte* limit; + FT_Byte mask; + + + line = (FT_Byte*)map->buffer + ( right >> 3 ); + limit = line + rows * line_len; + mask = (FT_Byte)( 0x80 >> ( right & 7 ) ); + + for ( ; line < limit; line += line_len ) + if ( line[0] & mask ) + goto Found_Right; + + /* crop the whole glyph to the right */ + map->width--; + metrics->width--; + + } while ( map->width > 0 ); + + Found_Right: + /* all right, the bitmap was cropped */ + return; + + Empty_Bitmap: + map->width = 0; + map->rows = 0; + map->pitch = 0; + map->pixel_mode = FT_PIXEL_MODE_MONO; + } + + + static FT_Error + Load_SBit_Single( FT_Bitmap* map, + FT_Int x_offset, + FT_Int y_offset, + FT_Int pix_bits, + FT_UShort image_format, + TT_SBit_Metrics metrics, + FT_Stream stream ) + { + FT_Error error; + + + /* check that the source bitmap fits into the target pixmap */ + if ( x_offset < 0 || x_offset + metrics->width > map->width || + y_offset < 0 || y_offset + metrics->height > map->rows ) + { + error = SFNT_Err_Invalid_Argument; + + goto Exit; + } + + { + FT_Int glyph_width = metrics->width; + FT_Int glyph_height = metrics->height; + FT_Int glyph_size; + FT_Int line_bits = pix_bits * glyph_width; + FT_Bool pad_bytes = 0; + + + /* compute size of glyph image */ + switch ( image_format ) + { + case 1: /* byte-padded formats */ + case 6: + { + FT_Int line_length; + + + switch ( pix_bits ) + { + case 1: + line_length = ( glyph_width + 7 ) >> 3; + break; + case 2: + line_length = ( glyph_width + 3 ) >> 2; + break; + case 4: + line_length = ( glyph_width + 1 ) >> 1; + break; + default: + line_length = glyph_width; + } + + glyph_size = glyph_height * line_length; + pad_bytes = 1; + } + break; + + case 2: + case 5: + case 7: + line_bits = glyph_width * pix_bits; + glyph_size = ( glyph_height * line_bits + 7 ) >> 3; + break; + + default: /* invalid format */ + return SFNT_Err_Invalid_File_Format; + } + + /* Now read data and draw glyph into target pixmap */ + if ( FT_FRAME_ENTER( glyph_size ) ) + goto Exit; + + /* don't forget to multiply `x_offset' by `map->pix_bits' as */ + /* the sbit blitter doesn't make a difference between pixmap */ + /* depths. */ + blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, + x_offset * pix_bits, y_offset ); + + FT_FRAME_EXIT(); + } + + Exit: + return error; + } + + + static FT_Error + Load_SBit_Image( TT_SBit_Strike strike, + TT_SBit_Range range, + FT_ULong ebdt_pos, + FT_ULong glyph_offset, + FT_GlyphSlot slot, + FT_Int x_offset, + FT_Int y_offset, + FT_Stream stream, + TT_SBit_Metrics metrics, + FT_Int depth ) + { + FT_Memory memory = stream->memory; + FT_Bitmap* map = &slot->bitmap; + FT_Error error; + + + /* place stream at beginning of glyph data and read metrics */ + if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) ) + goto Exit; + + error = load_sbit_metrics( stream, range, metrics ); + if ( error ) + goto Exit; + + /* this function is recursive. At the top-level call, we */ + /* compute the dimensions of the higher-level glyph to */ + /* allocate the final pixmap buffer */ + if ( depth == 0 ) + { + FT_Long size; + + + map->width = metrics->width; + map->rows = metrics->height; + + switch ( strike->bit_depth ) + { + case 1: + map->pixel_mode = FT_PIXEL_MODE_MONO; + map->pitch = ( map->width + 7 ) >> 3; + break; + + case 2: + map->pixel_mode = FT_PIXEL_MODE_GRAY2; + map->pitch = ( map->width + 3 ) >> 2; + break; + + case 4: + map->pixel_mode = FT_PIXEL_MODE_GRAY4; + map->pitch = ( map->width + 1 ) >> 1; + break; + + case 8: + map->pixel_mode = FT_PIXEL_MODE_GRAY; + map->pitch = map->width; + break; + + default: + return SFNT_Err_Invalid_File_Format; + } + + size = map->rows * map->pitch; + + /* check that there is no empty image */ + if ( size == 0 ) + goto Exit; /* exit successfully! */ + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if (error) + goto Exit; + } + + switch ( range->image_format ) + { + case 1: /* single sbit image - load it */ + case 2: + case 5: + case 6: + case 7: + return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth, + range->image_format, metrics, stream ); + + case 8: /* compound format */ + FT_Stream_Skip( stream, 1L ); + /* fallthrough */ + + case 9: + break; + + default: /* invalid image format */ + return SFNT_Err_Invalid_File_Format; + } + + /* All right, we have a compound format. First of all, read */ + /* the array of elements. */ + { + TT_SBit_Component components; + TT_SBit_Component comp; + FT_UShort num_components, count; + + + if ( FT_READ_USHORT( num_components ) || + FT_NEW_ARRAY( components, num_components ) ) + goto Exit; + + count = num_components; + + if ( FT_FRAME_ENTER( 4L * num_components ) ) + goto Fail_Memory; + + for ( comp = components; count > 0; count--, comp++ ) + { + comp->glyph_code = FT_GET_USHORT(); + comp->x_offset = FT_GET_CHAR(); + comp->y_offset = FT_GET_CHAR(); + } + + FT_FRAME_EXIT(); + + /* Now recursively load each element glyph */ + count = num_components; + comp = components; + for ( ; count > 0; count--, comp++ ) + { + TT_SBit_Range elem_range; + TT_SBit_MetricsRec elem_metrics; + FT_ULong elem_offset; + + + /* find the range for this element */ + error = find_sbit_range( comp->glyph_code, + strike, + &elem_range, + &elem_offset ); + if ( error ) + goto Fail_Memory; + + /* now load the element, recursively */ + error = Load_SBit_Image( strike, + elem_range, + ebdt_pos, + elem_offset, + slot, + x_offset + comp->x_offset, + y_offset + comp->y_offset, + stream, + &elem_metrics, + depth+1 ); + if ( error ) + goto Fail_Memory; + } + + Fail_Memory: + FT_FREE( components ); + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_face_load_sbit_image */ + /* */ + /* <Description> */ + /* Loads a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* glyph_index :: The current glyph index. */ + /* */ + /* load_flags :: The glyph load flags (the code checks for the flag */ + /* FT_LOAD_CROP_BITMAP). */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* map :: The target pixmap. */ + /* */ + /* metrics :: A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ) + { + FT_Error error; + FT_ULong ebdt_pos, glyph_offset; + + TT_SBit_Strike strike; + TT_SBit_Range range; + + + /* Check whether there is a glyph sbit for the current index */ + error = find_sbit_image( face, glyph_index, strike_index, + &range, &strike, &glyph_offset ); + if ( error ) + goto Exit; + + /* now, find the location of the `EBDT' table in */ + /* the font file */ + error = face->goto_table( face, TTAG_EBDT, stream, 0 ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, 0 ); + if (error) + goto Exit; + + ebdt_pos = FT_STREAM_POS(); + + error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset, + face->root.glyph, 0, 0, stream, metrics, 0 ); + if ( error ) + goto Exit; + + /* setup vertical metrics if needed */ + if ( strike->flags & 1 ) + { + /* in case of a horizontal strike only */ + FT_Int advance; + + + advance = strike->hori.ascender - strike->hori.descender; + + /* some heuristic values */ + + metrics->vertBearingX = (FT_Char)(-metrics->width / 2 ); + metrics->vertBearingY = (FT_Char)( advance / 10 ); + metrics->vertAdvance = (FT_Char)( advance * 12 / 10 ); + } + + /* Crop the bitmap now, unless specified otherwise */ + if ( load_flags & FT_LOAD_CROP_BITMAP ) + crop_bitmap( map, metrics ); + + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/sfnt/ttsbit.h b/lib/freetype/src/sfnt/ttsbit.h new file mode 100644 index 0000000..edc858a --- /dev/null +++ b/lib/freetype/src/sfnt/ttsbit.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttsbit.h */ +/* */ +/* TrueType and OpenType embedded bitmap support (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTSBIT_H__ +#define __TTSBIT_H__ + + +#include <ft2build.h> +#include "ttload.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_strikes( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_sbit_strikes( TT_Face face ); + + + FT_LOCAL( FT_Error ) + tt_face_set_sbit_strike( TT_Face face, + FT_Int x_ppem, + FT_Int y_ppem, + FT_ULong *astrike_index ); + + FT_LOCAL( FT_Error ) + tt_face_load_sbit_image( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *map, + TT_SBit_MetricsRec *metrics ); + + +FT_END_HEADER + +#endif /* __TTSBIT_H__ */ + + +/* END */ diff --git a/lib/freetype/src/smooth/Jamfile b/lib/freetype/src/smooth/Jamfile new file mode 100644 index 0000000..5ab9b60 --- /dev/null +++ b/lib/freetype/src/smooth/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/smooth Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) smooth ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ftgrays ftsmooth ; + } + else + { + _sources = smooth ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/smooth Jamfile diff --git a/lib/freetype/src/smooth/descrip.mms b/lib/freetype/src/smooth/descrip.mms new file mode 100644 index 0000000..9ebc7ff --- /dev/null +++ b/lib/freetype/src/smooth/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 smooth renderer module compilation rules for VMS +# + + +# Copyright 2001 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.smooth]) + +OBJS=smooth.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/smooth/ftgrays.c b/lib/freetype/src/smooth/ftgrays.c new file mode 100644 index 0000000..6c09481 --- /dev/null +++ b/lib/freetype/src/smooth/ftgrays.c @@ -0,0 +1,2159 @@ +/***************************************************************************/ +/* */ +/* ftgrays.c */ +/* */ +/* A new `perfect' anti-aliasing renderer (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 can be compiled without the rest of the FreeType engine, by */ + /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* put the files `ftgrays.h' and `ftimage.h' into the current */ + /* compilation directory. Typically, you could do something like */ + /* */ + /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ + /* */ + /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ + /* same directory */ + /* */ + /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* */ + /* cc -c -D_STANDALONE_ ftgrays.c */ + /* */ + /* The renderer can be initialized with a call to */ + /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ + /* with a call to `ft_gray_raster.raster_render'. */ + /* */ + /* See the comments and documentation in the file `ftimage.h' for more */ + /* details on how the raster works. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* This is a new anti-aliasing scan-converter for FreeType 2. The */ + /* algorithm used here is _very_ different from the one in the standard */ + /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ + /* coverage of the outline on each pixel cell. */ + /* */ + /* It is based on ideas that I initially found in Raph Levien's */ + /* excellent LibArt graphics library (see http://www.levien.com/libart */ + /* for more information, though the web pages do not tell anything */ + /* about the renderer; you'll have to dive into the source code to */ + /* understand how it works). */ + /* */ + /* Note, however, that this is a _very_ different implementation */ + /* compared to Raph's. Coverage information is stored in a very */ + /* different way, and I don't use sorted vector paths. Also, it doesn't */ + /* use floating point values. */ + /* */ + /* This renderer has the following advantages: */ + /* */ + /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ + /* callback function that will be called by the renderer to draw gray */ + /* spans on any target surface. You can thus do direct composition on */ + /* any kind of bitmap, provided that you give the renderer the right */ + /* callback. */ + /* */ + /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ + /* each pixel cell. */ + /* */ + /* - It performs a single pass on the outline (the `standard' FT2 */ + /* renderer makes two passes). */ + /* */ + /* - It can easily be modified to render to _any_ number of gray levels */ + /* cheaply. */ + /* */ + /* - For small (< 20) pixel sizes, it is faster than the standard */ + /* renderer. */ + /* */ + /*************************************************************************/ + + + +/* experimental support for gamma correction within the rasterizer */ +#define xxxGRAYS_USE_GAMMA + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_smooth + + +#define ErrRaster_MemoryOverflow -4 + + +#ifdef _STANDALONE_ + +#include <string.h> /* for ft_memcpy() */ +#include <setjmp.h> +#include <limits.h> +#define FT_UINT_MAX UINT_MAX + +#define ft_memset memset + +#define ft_setjmp setjmp +#define ft_longjmp longjmp +#define ft_jmp_buf jmp_buf + + +#define ErrRaster_Invalid_Mode -2 +#define ErrRaster_Invalid_Outline -1 + +#define FT_BEGIN_HEADER +#define FT_END_HEADER + +#include "ftimage.h" +#include "ftgrays.h" + + /* This macro is used to indicate that a function parameter is unused. */ + /* Its purpose is simply to reduce compiler warnings. Note also that */ + /* simply defining it as `(void)x' doesn't avoid warnings with certain */ + /* ANSI compilers (e.g. LCC). */ +#define FT_UNUSED( x ) (x) = (x) + + /* Disable the tracing mechanism for simplicity -- developers can */ + /* activate it easily by redefining these two macros. */ +#ifndef FT_ERROR +#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ +#endif + +#ifndef FT_TRACE +#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ +#endif + + +#else /* _STANDALONE_ */ + + +#include <ft2build.h> +#include "ftgrays.h" +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_OUTLINE_H + +#include "ftsmerrs.h" + +#define ErrRaster_Invalid_Mode Smooth_Err_Cannot_Render_Glyph +#define ErrRaster_Invalid_Outline Smooth_Err_Invalid_Outline + + +#endif /* _STANDALONE_ */ + + +#ifndef FT_MEM_SET +#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) +#endif + +#ifndef FT_MEM_ZERO +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + + /* define this to dump debugging information */ +#define xxxDEBUG_GRAYS + + /* as usual, for the speed hungry :-) */ + +#ifndef FT_STATIC_RASTER + + +#define RAS_ARG PRaster raster +#define RAS_ARG_ PRaster raster, + +#define RAS_VAR raster +#define RAS_VAR_ raster, + +#define ras (*raster) + + +#else /* FT_STATIC_RASTER */ + + +#define RAS_ARG /* empty */ +#define RAS_ARG_ /* empty */ +#define RAS_VAR /* empty */ +#define RAS_VAR_ /* empty */ + + static TRaster ras; + + +#endif /* FT_STATIC_RASTER */ + + + /* must be at least 6 bits! */ +#define PIXEL_BITS 8 + +#define ONE_PIXEL ( 1L << PIXEL_BITS ) +#define PIXEL_MASK ( -1L << PIXEL_BITS ) +#define TRUNC( x ) ( (TCoord)((x) >> PIXEL_BITS) ) +#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define FLOOR( x ) ( (x) & -ONE_PIXEL ) +#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) +#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) + +#if PIXEL_BITS >= 6 +#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) +#else +#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#endif + + /* Define this if you want to use a more compact storage scheme. This */ + /* increases the number of cells available in the render pool but slows */ + /* down the rendering a bit. It is useful if you have a really tiny */ + /* render pool. */ +#undef GRAYS_COMPACT + + + /*************************************************************************/ + /* */ + /* TYPE DEFINITIONS */ + /* */ + + /* don't change the following types to FT_Int or FT_Pos, since we might */ + /* need to define them to "float" or "double" when experimenting with */ + /* new algorithms */ + + typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef long TPos; /* sub-pixel coordinate */ + + /* determine the type used to store cell areas. This normally takes at */ + /* least PIXEL_BYTES*2 + 1. On 16-bit systems, we need to use `long' */ + /* instead of `int', otherwise bad things happen */ + +#if PIXEL_BITS <= 7 + + typedef int TArea; + +#else /* PIXEL_BITS >= 8 */ + + /* approximately determine the size of integers using an ANSI-C header */ +#if FT_UINT_MAX == 0xFFFFU + typedef long TArea; +#else + typedef int TArea; +#endif + +#endif /* PIXEL_BITS >= 8 */ + + + /* maximal number of gray spans in a call to the span callback */ +#define FT_MAX_GRAY_SPANS 32 + + +#ifdef GRAYS_COMPACT + + typedef struct TCell_ + { + short x : 14; + short y : 14; + int cover : PIXEL_BITS + 2; + int area : PIXEL_BITS * 2 + 2; + + } TCell, *PCell; + +#else /* GRAYS_COMPACT */ + + typedef struct TCell_ + { + TCoord x; + TCoord y; + int cover; + TArea area; + + } TCell, *PCell; + +#endif /* GRAYS_COMPACT */ + + + typedef struct TRaster_ + { + PCell cells; + int max_cells; + int num_cells; + + TPos min_ex, max_ex; + TPos min_ey, max_ey; + + TArea area; + int cover; + int invalid; + + TCoord ex, ey; + TCoord cx, cy; + TPos x, y; + + TPos last_ey; + + FT_Vector bez_stack[32 * 3 + 1]; + int lev_stack[32]; + + FT_Outline outline; + FT_Bitmap target; + FT_BBox clip_box; + + FT_Span gray_spans[FT_MAX_GRAY_SPANS]; + int num_gray_spans; + + FT_Raster_Span_Func render_span; + void* render_span_data; + int span_y; + + int band_size; + int band_shoot; + int conic_level; + int cubic_level; + + void* memory; + ft_jmp_buf jump_buffer; + +#ifdef GRAYS_USE_GAMMA + unsigned char gamma[257]; +#endif + + } TRaster, *PRaster; + + + /*************************************************************************/ + /* */ + /* Initialize the cells table. */ + /* */ + static void + gray_init_cells( RAS_ARG_ void* buffer, + long byte_size ) + { + ras.cells = (PCell)buffer; + ras.max_cells = byte_size / sizeof ( TCell ); + ras.num_cells = 0; + ras.area = 0; + ras.cover = 0; + ras.invalid = 1; + } + + + /*************************************************************************/ + /* */ + /* Compute the outline bounding box. */ + /* */ + static void + gray_compute_cbox( RAS_ARG ) + { + FT_Outline* outline = &ras.outline; + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + if ( outline->n_points <= 0 ) + { + ras.min_ex = ras.max_ex = 0; + ras.min_ey = ras.max_ey = 0; + return; + } + + ras.min_ex = ras.max_ex = vec->x; + ras.min_ey = ras.max_ey = vec->y; + + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x = vec->x; + TPos y = vec->y; + + + if ( x < ras.min_ex ) ras.min_ex = x; + if ( x > ras.max_ex ) ras.max_ex = x; + if ( y < ras.min_ey ) ras.min_ey = y; + if ( y > ras.max_ey ) ras.max_ey = y; + } + + /* truncate the bounding box to integer pixels */ + ras.min_ex = ras.min_ex >> 6; + ras.min_ey = ras.min_ey >> 6; + ras.max_ex = ( ras.max_ex + 63 ) >> 6; + ras.max_ey = ( ras.max_ey + 63 ) >> 6; + } + + + /*************************************************************************/ + /* */ + /* Record the current cell in the table. */ + /* */ + static void + gray_record_cell( RAS_ARG ) + { + PCell cell; + + + if ( !ras.invalid && ( ras.area | ras.cover ) ) + { + if ( ras.num_cells >= ras.max_cells ) + ft_longjmp( ras.jump_buffer, 1 ); + + cell = ras.cells + ras.num_cells++; + cell->x = (TCoord)(ras.ex - ras.min_ex); + cell->y = (TCoord)(ras.ey - ras.min_ey); + cell->area = ras.area; + cell->cover = ras.cover; + } + } + + + /*************************************************************************/ + /* */ + /* Set the current cell to a new position. */ + /* */ + static void + gray_set_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + int invalid, record, clean; + + + /* Move the cell pointer to a new position. We set the `invalid' */ + /* flag to indicate that the cell isn't part of those we're interested */ + /* in during the render phase. This means that: */ + /* */ + /* . the new vertical position must be within min_ey..max_ey-1. */ + /* . the new horizontal position must be strictly less than max_ex */ + /* */ + /* Note that if a cell is to the left of the clipping region, it is */ + /* actually set to the (min_ex-1) horizontal position. */ + + record = 0; + clean = 1; + + invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex ); + if ( !invalid ) + { + /* All cells that are on the left of the clipping region go to the */ + /* min_ex - 1 horizontal position. */ + if ( ex < ras.min_ex ) + ex = (TCoord)(ras.min_ex - 1); + + /* if our position is new, then record the previous cell */ + if ( ex != ras.ex || ey != ras.ey ) + record = 1; + else + clean = ras.invalid; /* do not clean if we didn't move from */ + /* a valid cell */ + } + + /* record the previous cell if needed (i.e., if we changed the cell */ + /* position, of changed the `invalid' flag) */ + if ( ras.invalid != invalid || record ) + gray_record_cell( RAS_VAR ); + + if ( clean ) + { + ras.area = 0; + ras.cover = 0; + } + + ras.invalid = invalid; + ras.ex = ex; + ras.ey = ey; + } + + + /*************************************************************************/ + /* */ + /* Start a new contour at a given cell. */ + /* */ + static void + gray_start_cell( RAS_ARG_ TCoord ex, + TCoord ey ) + { + if ( ex < ras.min_ex ) + ex = (TCoord)(ras.min_ex - 1); + + ras.area = 0; + ras.cover = 0; + ras.ex = ex; + ras.ey = ey; + ras.last_ey = SUBPIXELS( ey ); + ras.invalid = 0; + + gray_set_cell( RAS_VAR_ ex, ey ); + } + + + /*************************************************************************/ + /* */ + /* Render a scanline as one or more cells. */ + /* */ + static void + gray_render_scanline( RAS_ARG_ TCoord ey, + TPos x1, + TCoord y1, + TPos x2, + TCoord y2 ) + { + TCoord ex1, ex2, fx1, fx2, delta; + long p, first, dx; + int incr, lift, mod, rem; + + + dx = x2 - x1; + + ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */ + ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */ + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + + /* trivial case. Happens often */ + if ( y1 == y2 ) + { + gray_set_cell( RAS_VAR_ ex2, ey ); + return; + } + + /* everything is located in a single cell. That is easy! */ + /* */ + if ( ex1 == ex2 ) + { + delta = y2 - y1; + ras.area += (TArea)( fx1 + fx2 ) * delta; + ras.cover += delta; + return; + } + + /* ok, we'll have to render a run of adjacent cells on the same */ + /* scanline... */ + /* */ + p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); + first = ONE_PIXEL; + incr = 1; + + if ( dx < 0 ) + { + p = fx1 * ( y2 - y1 ); + first = 0; + incr = -1; + dx = -dx; + } + + delta = (TCoord)( p / dx ); + mod = (TCoord)( p % dx ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dx; + } + + ras.area += (TArea)( fx1 + first ) * delta; + ras.cover += delta; + + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + y1 += delta; + + if ( ex1 != ex2 ) + { + p = ONE_PIXEL * ( y2 - y1 + delta ); + lift = (TCoord)( p / dx ); + rem = (TCoord)( p % dx ); + if ( rem < 0 ) + { + lift--; + rem += (TCoord)dx; + } + + mod -= dx; + + while ( ex1 != ex2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (TCoord)dx; + delta++; + } + + ras.area += (TArea)ONE_PIXEL * delta; + ras.cover += delta; + y1 += delta; + ex1 += incr; + gray_set_cell( RAS_VAR_ ex1, ey ); + } + } + + delta = y2 - y1; + ras.area += (TArea)( fx2 + ONE_PIXEL - first ) * delta; + ras.cover += delta; + } + + + /*************************************************************************/ + /* */ + /* Render a given line as a series of scanlines. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TCoord ey1, ey2, fy1, fy2; + TPos dx, dy, x, x2; + long p, first; + int delta, rem, mod, lift, incr; + + + ey1 = TRUNC( ras.last_ey ); + ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ + fy1 = (TCoord)( ras.y - ras.last_ey ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + /* XXX: we should do something about the trivial case where dx == 0, */ + /* as it happens very often! */ + + /* perform vertical clipping */ + { + TCoord min, max; + + + min = ey1; + max = ey2; + if ( ey1 > ey2 ) + { + min = ey2; + max = ey1; + } + if ( min >= ras.max_ey || max < ras.min_ey ) + goto End; + } + + /* everything is on a single scanline */ + if ( ey1 == ey2 ) + { + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); + goto End; + } + + /* vertical line - avoid calling gray_render_scanline */ + incr = 1; + + if ( dx == 0 ) + { + TCoord ex = TRUNC( ras.x ); + TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); + TPos area; + + + first = ONE_PIXEL; + if ( dy < 0 ) + { + first = 0; + incr = -1; + } + + delta = (int)( first - fy1 ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + ey1 += incr; + + gray_set_cell( raster, ex, ey1 ); + + delta = (int)( first + first - ONE_PIXEL ); + area = (TArea)two_fx * delta; + while ( ey1 != ey2 ) + { + ras.area += area; + ras.cover += delta; + ey1 += incr; + gray_set_cell( raster, ex, ey1 ); + } + + delta = (int)( fy2 - ONE_PIXEL + first ); + ras.area += (TArea)two_fx * delta; + ras.cover += delta; + goto End; + } + + /* ok, we have to render several scanlines */ + p = ( ONE_PIXEL - fy1 ) * dx; + first = ONE_PIXEL; + incr = 1; + + if ( dy < 0 ) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = (int)( p / dy ); + mod = (int)( p % dy ); + if ( mod < 0 ) + { + delta--; + mod += (TCoord)dy; + } + + x = ras.x + delta; + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + + if ( ey1 != ey2 ) + { + p = ONE_PIXEL * dx; + lift = (int)( p / dy ); + rem = (int)( p % dy ); + if ( rem < 0 ) + { + lift--; + rem += (int)dy; + } + mod -= (int)dy; + + while ( ey1 != ey2 ) + { + delta = lift; + mod += rem; + if ( mod >= 0 ) + { + mod -= (int)dy; + delta++; + } + + x2 = x + delta; + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), x2, + (TCoord)first ); + x = x2; + + ey1 += incr; + gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); + } + } + + gray_render_scanline( RAS_VAR_ ey1, x, + (TCoord)( ONE_PIXEL - first ), to_x, + fy2 ); + + End: + ras.x = to_x; + ras.y = to_y; + ras.last_ey = SUBPIXELS( ey2 ); + } + + + static void + gray_split_conic( FT_Vector* base ) + { + TPos 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; + } + + + static void + gray_render_conic( RAS_ARG_ FT_Vector* control, + FT_Vector* to ) + { + TPos dx, dy; + int top, level; + int* levels; + FT_Vector* arc; + + + dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + + level = 1; + dx = dx / ras.conic_level; + while ( dx > 0 ) + { + dx >>= 2; + level++; + } + + /* a shortcut to speed things up */ + if ( level <= 1 ) + { + /* we compute the mid-point directly in order to avoid */ + /* calling gray_split_conic() */ + TPos to_x, to_y, mid_x, mid_y; + + + to_x = UPSCALE( to->x ); + to_y = UPSCALE( to->y ); + mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4; + mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + return; + } + + arc = ras.bez_stack; + levels = ras.lev_stack; + top = 0; + levels[0] = level; + + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control->x ); + arc[1].y = UPSCALE( control->y ); + arc[2].x = ras.x; + arc[2].y = ras.y; + + while ( top >= 0 ) + { + level = levels[top]; + if ( level > 1 ) + { + /* check that the arc crosses the current band */ + TPos min, max, y; + + + min = max = arc[0].y; + + y = arc[1].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + y = arc[2].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) + goto Draw; + + gray_split_conic( arc ); + arc += 2; + top++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = arc[0].x; + to_y = arc[0].y; + mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4; + mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + + top--; + arc -= 2; + } + } + return; + } + + + static void + gray_split_cubic( FT_Vector* base ) + { + TPos a, b, c, d; + + + base[6].x = base[3].x; + c = base[1].x; + d = base[2].x; + base[1].x = a = ( base[0].x + c ) / 2; + base[5].x = b = ( base[3].x + d ) / 2; + c = ( c + d ) / 2; + base[2].x = a = ( a + c ) / 2; + base[4].x = b = ( b + c ) / 2; + base[3].x = ( a + b ) / 2; + + base[6].y = base[3].y; + c = base[1].y; + d = base[2].y; + base[1].y = a = ( base[0].y + c ) / 2; + base[5].y = b = ( base[3].y + d ) / 2; + c = ( c + d ) / 2; + base[2].y = a = ( a + c ) / 2; + base[4].y = b = ( b + c ) / 2; + base[3].y = ( a + b ) / 2; + } + + + static void + gray_render_cubic( RAS_ARG_ FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ) + { + TPos dx, dy, da, db; + int top, level; + int* levels; + FT_Vector* arc; + + + dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + da = dx; + + dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); + if ( dx < 0 ) + dx = -dx; + dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); + if ( dy < 0 ) + dy = -dy; + if ( dx < dy ) + dx = dy; + db = dx; + + level = 1; + da = da / ras.cubic_level; + db = db / ras.conic_level; + while ( da > 0 || db > 0 ) + { + da >>= 2; + db >>= 3; + level++; + } + + if ( level <= 1 ) + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = UPSCALE( to->x ); + to_y = UPSCALE( to->y ); + mid_x = ( ras.x + to_x + + 3 * UPSCALE( control1->x + control2->x ) ) / 8; + mid_y = ( ras.y + to_y + + 3 * UPSCALE( control1->y + control2->y ) ) / 8; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + return; + } + + arc = ras.bez_stack; + arc[0].x = UPSCALE( to->x ); + arc[0].y = UPSCALE( to->y ); + arc[1].x = UPSCALE( control2->x ); + arc[1].y = UPSCALE( control2->y ); + arc[2].x = UPSCALE( control1->x ); + arc[2].y = UPSCALE( control1->y ); + arc[3].x = ras.x; + arc[3].y = ras.y; + + levels = ras.lev_stack; + top = 0; + levels[0] = level; + + while ( top >= 0 ) + { + level = levels[top]; + if ( level > 1 ) + { + /* check that the arc crosses the current band */ + TPos min, max, y; + + + min = max = arc[0].y; + y = arc[1].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + y = arc[2].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + y = arc[3].y; + if ( y < min ) min = y; + if ( y > max ) max = y; + if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) + goto Draw; + gray_split_cubic( arc ); + arc += 3; + top ++; + levels[top] = levels[top - 1] = level - 1; + continue; + } + + Draw: + { + TPos to_x, to_y, mid_x, mid_y; + + + to_x = arc[0].x; + to_y = arc[0].y; + mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8; + mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8; + + gray_render_line( RAS_VAR_ mid_x, mid_y ); + gray_render_line( RAS_VAR_ to_x, to_y ); + top --; + arc -= 3; + } + } + return; + } + + + /* a macro comparing two cell pointers. Returns true if a <= b. */ +#if 1 + +#define PACK( a ) ( ( (long)(a)->y << 16 ) + (a)->x ) +#define LESS_THAN( a, b ) ( PACK( a ) < PACK( b ) ) + +#else /* 1 */ + +#define LESS_THAN( a, b ) ( (a)->y < (b)->y || \ + ( (a)->y == (b)->y && (a)->x < (b)->x ) ) + +#endif /* 1 */ + +#define SWAP_CELLS( a, b, temp ) do \ + { \ + temp = *(a); \ + *(a) = *(b); \ + *(b) = temp; \ + } while ( 0 ) +#define DEBUG_SORT +#define QUICK_SORT + +#ifdef SHELL_SORT + + /* a simple shell sort algorithm that works directly on our */ + /* cells table */ + static void + gray_shell_sort ( PCell cells, + int count ) + { + PCell i, j, limit = cells + count; + TCell temp; + int gap; + + + /* compute initial gap */ + for ( gap = 0; ++gap < count; gap *= 3 ) + ; + + while ( gap /= 3 ) + { + for ( i = cells + gap; i < limit; i++ ) + { + for ( j = i - gap; ; j -= gap ) + { + PCell k = j + gap; + + + if ( LESS_THAN( j, k ) ) + break; + + SWAP_CELLS( j, k, temp ); + + if ( j < cells + gap ) + break; + } + } + } + } + +#endif /* SHELL_SORT */ + + +#ifdef QUICK_SORT + + /* This is a non-recursive quicksort that directly process our cells */ + /* array. It should be faster than calling the stdlib qsort(), and we */ + /* can even tailor our insertion threshold... */ + +#define QSORT_THRESHOLD 9 /* below this size, a sub-array will be sorted */ + /* through a normal insertion sort */ + + static void + gray_quick_sort( PCell cells, + int count ) + { + PCell stack[40]; /* should be enough ;-) */ + PCell* top; /* top of stack */ + PCell base, limit; + TCell temp; + + + limit = cells + count; + base = cells; + top = stack; + + for (;;) + { + int len = (int)( limit - base ); + PCell i, j, pivot; + + + if ( len > QSORT_THRESHOLD ) + { + /* we use base + len/2 as the pivot */ + pivot = base + len / 2; + SWAP_CELLS( base, pivot, temp ); + + i = base + 1; + j = limit - 1; + + /* now ensure that *i <= *base <= *j */ + if ( LESS_THAN( j, i ) ) + SWAP_CELLS( i, j, temp ); + + if ( LESS_THAN( base, i ) ) + SWAP_CELLS( base, i, temp ); + + if ( LESS_THAN( j, base ) ) + SWAP_CELLS( base, j, temp ); + + for (;;) + { + do i++; while ( LESS_THAN( i, base ) ); + do j--; while ( LESS_THAN( base, j ) ); + + if ( i > j ) + break; + + SWAP_CELLS( i, j, temp ); + } + + SWAP_CELLS( base, j, temp ); + + /* now, push the largest sub-array */ + if ( j - base > limit - i ) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + /* the sub-array is small, perform insertion sort */ + j = base; + i = j + 1; + + for ( ; i < limit; j = i, i++ ) + { + for ( ; LESS_THAN( j + 1, j ); j-- ) + { + SWAP_CELLS( j + 1, j, temp ); + if ( j == base ) + break; + } + } + if ( top > stack ) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + break; + } + } + } + +#endif /* QUICK_SORT */ + + +#ifdef DEBUG_GRAYS +#ifdef DEBUG_SORT + + static int + gray_check_sort( PCell cells, + int count ) + { + PCell p, q; + + + for ( p = cells + count - 2; p >= cells; p-- ) + { + q = p + 1; + if ( !LESS_THAN( p, q ) ) + return 0; + } + return 1; + } + +#endif /* DEBUG_SORT */ +#endif /* DEBUG_GRAYS */ + + + static int + gray_move_to( FT_Vector* to, + FT_Raster raster ) + { + TPos x, y; + + + /* record current cell, if any */ + gray_record_cell( (PRaster)raster ); + + /* start to a new position */ + x = UPSCALE( to->x ); + y = UPSCALE( to->y ); + + gray_start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) ); + + ((PRaster)raster)->x = x; + ((PRaster)raster)->y = y; + return 0; + } + + + static int + gray_line_to( FT_Vector* to, + FT_Raster raster ) + { + gray_render_line( (PRaster)raster, + UPSCALE( to->x ), UPSCALE( to->y ) ); + return 0; + } + + + static int + gray_conic_to( FT_Vector* control, + FT_Vector* to, + FT_Raster raster ) + { + gray_render_conic( (PRaster)raster, control, to ); + return 0; + } + + + static int + gray_cubic_to( FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to, + FT_Raster raster ) + { + gray_render_cubic( (PRaster)raster, control1, control2, to ); + return 0; + } + + + static void + gray_render_span( int y, + int count, + FT_Span* spans, + PRaster raster ) + { + unsigned char* p; + FT_Bitmap* map = &raster->target; + + + /* first of all, compute the scanline offset */ + p = (unsigned char*)map->buffer - y * map->pitch; + if ( map->pitch >= 0 ) + p += ( map->rows - 1 ) * map->pitch; + + for ( ; count > 0; count--, spans++ ) + { + unsigned char coverage = spans->coverage; + + +#ifdef GRAYS_USE_GAMMA + coverage = raster->gamma[coverage]; +#endif + + if ( coverage ) +#if 1 + FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); +#else /* 1 */ + { + q = p + spans->x; + limit = q + spans->len; + for ( ; q < limit; q++ ) + q[0] = (unsigned char)coverage; + } +#endif /* 1 */ + } + } + + +#ifdef DEBUG_GRAYS + +#include <stdio.h> + + static void + gray_dump_cells( RAS_ARG ) + { + PCell cell, limit; + int y = -1; + + + cell = ras.cells; + limit = cell + ras.num_cells; + + for ( ; cell < limit; cell++ ) + { + if ( cell->y != y ) + { + fprintf( stderr, "\n%2d: ", cell->y ); + y = cell->y; + } + fprintf( stderr, "[%d %d %d]", + cell->x, cell->area, cell->cover ); + } + fprintf(stderr, "\n" ); + } + +#endif /* DEBUG_GRAYS */ + + + static void + gray_hline( RAS_ARG_ TCoord x, + TCoord y, + TPos area, + int acount ) + { + FT_Span* span; + int count; + int coverage; + + + /* compute the coverage line's coverage, depending on the */ + /* outline fill rule */ + /* */ + /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ + /* */ + coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); + /* use range 0..256 */ + if ( coverage < 0 ) + coverage = -coverage; + + if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) + { + coverage &= 511; + + if ( coverage > 256 ) + coverage = 512 - coverage; + else if ( coverage == 256 ) + coverage = 255; + } + else + { + /* normal non-zero winding rule */ + if ( coverage >= 256 ) + coverage = 255; + } + + y += (TCoord)ras.min_ey; + x += (TCoord)ras.min_ex; + + if ( coverage ) + { + /* see if we can add this span to the current list */ + count = ras.num_gray_spans; + span = ras.gray_spans + count - 1; + if ( count > 0 && + ras.span_y == y && + (int)span->x + span->len == (int)x && + span->coverage == coverage ) + { + span->len = (unsigned short)( span->len + acount ); + return; + } + + if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) + { + if ( ras.render_span && count > 0 ) + ras.render_span( ras.span_y, count, ras.gray_spans, + ras.render_span_data ); + /* ras.render_span( span->y, ras.gray_spans, count ); */ + +#ifdef DEBUG_GRAYS + + if ( ras.span_y >= 0 ) + { + int n; + + + fprintf( stderr, "y=%3d ", ras.span_y ); + span = ras.gray_spans; + for ( n = 0; n < count; n++, span++ ) + fprintf( stderr, "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage ); + fprintf( stderr, "\n" ); + } + +#endif /* DEBUG_GRAYS */ + + ras.num_gray_spans = 0; + ras.span_y = y; + + count = 0; + span = ras.gray_spans; + } + else + span++; + + /* add a gray span to the current list */ + span->x = (short)x; + span->len = (unsigned short)acount; + span->coverage = (unsigned char)coverage; + ras.num_gray_spans++; + } + } + + + static void + gray_sweep( RAS_ARG_ FT_Bitmap* target ) + { + TCoord x, y, cover; + TArea area; + PCell start, cur, limit; + + FT_UNUSED( target ); + + + if ( ras.num_cells == 0 ) + return; + + cur = ras.cells; + limit = cur + ras.num_cells; + + cover = 0; + ras.span_y = -1; + ras.num_gray_spans = 0; + + for (;;) + { + start = cur; + y = start->y; + x = start->x; + + area = start->area; + cover += start->cover; + + /* accumulate all start cells */ + for (;;) + { + ++cur; + if ( cur >= limit || cur->y != start->y || cur->x != start->x ) + break; + + area += cur->area; + cover += cur->cover; + } + + /* if the start cell has a non-null area, we must draw an */ + /* individual gray pixel there */ + if ( area && x >= 0 ) + { + gray_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 ); + x++; + } + + if ( x < 0 ) + x = 0; + + if ( cur < limit && start->y == cur->y ) + { + /* draw a gray span between the start cell and the current one */ + if ( cur->x > x ) + gray_hline( RAS_VAR_ x, y, + cover * ( ONE_PIXEL * 2 ), cur->x - x ); + } + else + { + /* draw a gray span until the end of the clipping region */ + if ( cover && x < ras.max_ex - ras.min_ex ) + gray_hline( RAS_VAR_ x, y, + cover * ( ONE_PIXEL * 2 ), + (int)( ras.max_ex - x - ras.min_ex ) ); + cover = 0; + } + + if ( cur >= limit ) + break; + } + + if ( ras.render_span && ras.num_gray_spans > 0 ) + ras.render_span( ras.span_y, ras.num_gray_spans, + ras.gray_spans, ras.render_span_data ); + +#ifdef DEBUG_GRAYS + + { + int n; + FT_Span* span; + + + fprintf( stderr, "y=%3d ", ras.span_y ); + span = ras.gray_spans; + for ( n = 0; n < ras.num_gray_spans; n++, span++ ) + fprintf( stderr, "[%d..%d]:%02x ", + span->x, span->x + span->len - 1, span->coverage ); + fprintf( stderr, "\n" ); + } + +#endif /* DEBUG_GRAYS */ + + } + + +#ifdef _STANDALONE_ + + /*************************************************************************/ + /* */ + /* The following function should only compile in stand_alone mode, */ + /* i.e., when building this component without the rest of FreeType. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walks over an outline's structure to decompose it into individual */ + /* segments and Bezier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* Error code. 0 means sucess. */ + /* */ + static + int FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ) + { +#undef SCALED +#if 0 +#define SCALED( x ) ( ( (x) << shift ) - delta ) +#else +#define SCALED( x ) (x) +#endif + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + int n; /* index of contour in outline */ + int first; /* index of first point in contour */ + int error; + char tag; /* current point's state */ + +#if 0 + int shift = func_interface->shift; + TPos delta = func_interface->delta; +#endif + + + first = 0; + + for ( n = 0; n < outline->n_contours; n++ ) + { + int last; /* index of last point in contour */ + + + last = outline->contours[n]; + limit = outline->points + last; + + v_start = outline->points[first]; + v_last = outline->points[last]; + + v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); + v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); + + v_control = v_start; + + point = outline->points + first; + tags = outline->tags + first; + tag = FT_CURVE_TAG( tags[0] ); + + /* A contour cannot start with a cubic control point! */ + if ( tag == FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + /* check first point to determine origin */ + if ( tag == FT_CURVE_TAG_CONIC ) + { + /* first point is conic control. Yes, this happens. */ + if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) + { + /* start at last point if it is on the curve */ + v_start = v_last; + limit--; + } + else + { + /* if both first and last points are conic, */ + /* start at their middle and record its position */ + /* for closure */ + v_start.x = ( v_start.x + v_last.x ) / 2; + v_start.y = ( v_start.y + v_last.y ) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + error = func_interface->move_to( &v_start, user ); + if ( error ) + goto Exit; + + while ( point < limit ) + { + point++; + tags++; + + tag = FT_CURVE_TAG( tags[0] ); + switch ( tag ) + { + case FT_CURVE_TAG_ON: /* emit a single line_to */ + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + error = func_interface->line_to( &vec, user ); + if ( error ) + goto Exit; + continue; + } + + case FT_CURVE_TAG_CONIC: /* consume conic arcs */ + { + v_control.x = SCALED( point->x ); + v_control.y = SCALED( point->y ); + + Do_Conic: + if ( point < limit ) + { + FT_Vector vec; + FT_Vector v_middle; + + + point++; + tags++; + tag = FT_CURVE_TAG( tags[0] ); + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + if ( tag == FT_CURVE_TAG_ON ) + { + error = func_interface->conic_to( &v_control, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + if ( tag != FT_CURVE_TAG_CONIC ) + goto Invalid_Outline; + + v_middle.x = ( v_control.x + vec.x ) / 2; + v_middle.y = ( v_control.y + vec.y ) / 2; + + error = func_interface->conic_to( &v_control, &v_middle, user ); + if ( error ) + goto Exit; + + v_control = vec; + goto Do_Conic; + } + + error = func_interface->conic_to( &v_control, &v_start, user ); + goto Close; + } + + default: /* FT_CURVE_TAG_CUBIC */ + { + FT_Vector vec1, vec2; + + + if ( point + 1 > limit || + FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) + goto Invalid_Outline; + + point += 2; + tags += 2; + + vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); + vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); + + if ( point <= limit ) + { + FT_Vector vec; + + + vec.x = SCALED( point->x ); + vec.y = SCALED( point->y ); + + error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); + if ( error ) + goto Exit; + continue; + } + + error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); + goto Close; + } + } + } + + /* close the contour with a line segment */ + error = func_interface->line_to( &v_start, user ); + + Close: + if ( error ) + goto Exit; + + first = last + 1; + } + + return 0; + + Exit: + return error; + + Invalid_Outline: + return ErrRaster_Invalid_Outline; + } + +#endif /* _STANDALONE_ */ + + + typedef struct TBand_ + { + TPos min, max; + + } TBand; + + + static int + gray_convert_glyph_inner( RAS_ARG ) + { + static + const FT_Outline_Funcs func_interface = + { + (FT_Outline_MoveTo_Func) gray_move_to, + (FT_Outline_LineTo_Func) gray_line_to, + (FT_Outline_ConicTo_Func)gray_conic_to, + (FT_Outline_CubicTo_Func)gray_cubic_to, + 0, + 0 + }; + + volatile int error = 0; + + if ( ft_setjmp( ras.jump_buffer ) == 0 ) + { + error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); + gray_record_cell( RAS_VAR ); + } + else + { + error = ErrRaster_MemoryOverflow; + } + + return error; + } + + + static int + gray_convert_glyph( RAS_ARG ) + { + TBand bands[40]; + TBand* volatile band; + int volatile n, num_bands; + TPos volatile min, max, max_y; + FT_BBox* clip; + + + /* Set up state in the raster object */ + gray_compute_cbox( RAS_VAR ); + + /* clip to target bitmap, exit if nothing to do */ + clip = &ras.clip_box; + + if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || + ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) + return 0; + + if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; + if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; + + if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; + if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; + + /* simple heuristic used to speed-up the bezier decomposition -- see */ + /* the code in gray_render_conic() and gray_render_cubic() for more */ + /* details */ + ras.conic_level = 32; + ras.cubic_level = 16; + + { + int level = 0; + + + if ( ras.max_ex > 24 || ras.max_ey > 24 ) + level++; + if ( ras.max_ex > 120 || ras.max_ey > 120 ) + level++; + + ras.conic_level <<= level; + ras.cubic_level <<= level; + } + + /* setup vertical bands */ + num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); + if ( num_bands == 0 ) num_bands = 1; + if ( num_bands >= 39 ) num_bands = 39; + + ras.band_shoot = 0; + + min = ras.min_ey; + max_y = ras.max_ey; + + for ( n = 0; n < num_bands; n++, min = max ) + { + max = min + ras.band_size; + if ( n == num_bands - 1 || max > max_y ) + max = max_y; + + bands[0].min = min; + bands[0].max = max; + band = bands; + + while ( band >= bands ) + { + TPos bottom, top, middle; + int error; + + + ras.num_cells = 0; + ras.invalid = 1; + ras.min_ey = band->min; + ras.max_ey = band->max; + +#if 1 + error = gray_convert_glyph_inner( RAS_VAR ); +#else + error = FT_Outline_Decompose( outline, &func_interface, &ras ) || + gray_record_cell( RAS_VAR ); +#endif + + if ( !error ) + { +#ifdef SHELL_SORT + gray_shell_sort( ras.cells, ras.num_cells ); +#else + gray_quick_sort( ras.cells, ras.num_cells ); +#endif + +#ifdef DEBUG_GRAYS + gray_check_sort( ras.cells, ras.num_cells ); + gray_dump_cells( RAS_VAR ); +#endif + + gray_sweep( RAS_VAR_ &ras.target ); + band--; + continue; + } + else if ( error != ErrRaster_MemoryOverflow ) + return 1; + + /* render pool overflow, we will reduce the render band by half */ + bottom = band->min; + top = band->max; + middle = bottom + ( ( top - bottom ) >> 1 ); + + /* waoow! This is too complex for a single scanline, something */ + /* must be really rotten here! */ + if ( middle == bottom ) + { +#ifdef DEBUG_GRAYS + fprintf( stderr, "Rotten glyph!\n" ); +#endif + return 1; + } + + if ( bottom-top >= ras.band_size ) + ras.band_shoot++; + + band[1].min = bottom; + band[1].max = middle; + band[0].min = middle; + band[0].max = top; + band++; + } + } + + if ( ras.band_shoot > 8 && ras.band_size > 16 ) + ras.band_size = ras.band_size / 2; + + return 0; + } + + + extern int + gray_raster_render( PRaster raster, + FT_Raster_Params* params ) + { + FT_Outline* outline = (FT_Outline*)params->source; + FT_Bitmap* target_map = params->target; + + + if ( !raster || !raster->cells || !raster->max_cells ) + return -1; + + /* return immediately if the outline is empty */ + if ( outline->n_points == 0 || outline->n_contours <= 0 ) + return 0; + + if ( !outline || !outline->contours || !outline->points ) + return ErrRaster_Invalid_Outline; + + if ( outline->n_points != + outline->contours[outline->n_contours - 1] + 1 ) + return ErrRaster_Invalid_Outline; + + /* if direct mode is not set, we must have a target bitmap */ + if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 && + ( !target_map || !target_map->buffer ) ) + return -1; + + /* this version does not support monochrome rendering */ + if ( !( params->flags & FT_RASTER_FLAG_AA ) ) + return ErrRaster_Invalid_Mode; + + /* compute clipping box */ + if ( ( params->flags & FT_RASTER_FLAG_DIRECT ) == 0 ) + { + /* compute clip box from target pixmap */ + ras.clip_box.xMin = 0; + ras.clip_box.yMin = 0; + ras.clip_box.xMax = target_map->width; + ras.clip_box.yMax = target_map->rows; + } + else if ( params->flags & FT_RASTER_FLAG_CLIP ) + { + ras.clip_box = params->clip_box; + } + else + { + ras.clip_box.xMin = -32768L; + ras.clip_box.yMin = -32768L; + ras.clip_box.xMax = 32767L; + ras.clip_box.yMax = 32767L; + } + + ras.outline = *outline; + ras.num_cells = 0; + ras.invalid = 1; + + if ( target_map ) + ras.target = *target_map; + + ras.render_span = (FT_Raster_Span_Func)gray_render_span; + ras.render_span_data = &ras; + + if ( params->flags & FT_RASTER_FLAG_DIRECT ) + { + ras.render_span = (FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + } + + return gray_convert_glyph( (PRaster)raster ); + } + + + /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ + /**** a static object. *****/ + +#ifdef GRAYS_USE_GAMMA + + /* initialize the "gamma" table. Yes, this is really a crummy function */ + /* but the results look pretty good for something that simple. */ + /* */ +#define M_MAX 255 +#define M_X 128 +#define M_Y 192 + + static void + grays_init_gamma( PRaster raster ) + { + unsigned int x, a; + + + for ( x = 0; x < 256; x++ ) + { + if ( x <= M_X ) + a = ( x * M_Y + M_X / 2) / M_X; + else + a = M_Y + ( ( x - M_X ) * ( M_MAX - M_Y ) + + ( M_MAX - M_X ) / 2 ) / ( M_MAX - M_X ); + + raster->gamma[x] = (unsigned char)a; + } + } + +#endif /* GRAYS_USE_GAMMA */ + +#ifdef _STANDALONE_ + + static int + gray_raster_new( void* memory, + FT_Raster* araster ) + { + static TRaster the_raster; + + FT_UNUSED( memory ); + + + *araster = (FT_Raster)&the_raster; + FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + +#ifdef GRAYS_USE_GAMMA + grays_init_gamma( (PRaster)*araster ); +#endif + + return 0; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + /* nothing */ + FT_UNUSED( raster ); + } + +#else /* _STANDALONE_ */ + + static int + gray_raster_new( FT_Memory memory, + FT_Raster* araster ) + { + FT_Error error; + PRaster raster; + + + *araster = 0; + if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) ) + { + raster->memory = memory; + *araster = (FT_Raster)raster; + +#ifdef GRAYS_USE_GAMMA + grays_init_gamma( raster ); +#endif + } + + return error; + } + + + static void + gray_raster_done( FT_Raster raster ) + { + FT_Memory memory = (FT_Memory)((PRaster)raster)->memory; + + + FT_FREE( raster ); + } + +#endif /* _STANDALONE_ */ + + + static void + gray_raster_reset( FT_Raster raster, + const char* pool_base, + long pool_size ) + { + PRaster rast = (PRaster)raster; + + + if ( raster && pool_base && pool_size >= 4096 ) + gray_init_cells( rast, (char*)pool_base, pool_size ); + + rast->band_size = (int)( ( pool_size / sizeof ( TCell ) ) / 8 ); + } + + + const FT_Raster_Funcs ft_grays_raster = + { + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Raster_New_Func) gray_raster_new, + (FT_Raster_Reset_Func) gray_raster_reset, + (FT_Raster_Set_Mode_Func)0, + (FT_Raster_Render_Func) gray_raster_render, + (FT_Raster_Done_Func) gray_raster_done + }; + + +/* END */ diff --git a/lib/freetype/src/smooth/ftgrays.h b/lib/freetype/src/smooth/ftgrays.h new file mode 100644 index 0000000..2d40954 --- /dev/null +++ b/lib/freetype/src/smooth/ftgrays.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* ftgrays.h */ +/* */ +/* FreeType smooth renderer declaration */ +/* */ +/* Copyright 1996-2001 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 __FTGRAYS_H__ +#define __FTGRAYS_H__ + +#ifdef __cplusplus + extern "C" { +#endif + + +#ifdef _STANDALONE_ +#include "ftimage.h" +#else +#include <ft2build.h> +#include FT_IMAGE_H +#endif + + + /*************************************************************************/ + /* */ + /* To make ftgrays.h independent from configuration files we check */ + /* whether FT_EXPORT_VAR has been defined already. */ + /* */ + /* On some systems and compilers (Win32 mostly), an extra keyword is */ + /* necessary to compile the library as a DLL. */ + /* */ +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR( x ) extern x +#endif + + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_grays_raster; + + +#ifdef __cplusplus + } +#endif + +#endif /* __FTGRAYS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/smooth/ftsmerrs.h b/lib/freetype/src/smooth/ftsmerrs.h new file mode 100644 index 0000000..0c2a2ec --- /dev/null +++ b/lib/freetype/src/smooth/ftsmerrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* ftsmerrs.h */ +/* */ +/* smooth renderer error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the smooth renderer error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FTSMERRS_H__ +#define __FTSMERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX Smooth_Err_ +#define FT_ERR_BASE FT_Mod_Err_Smooth + +#include FT_ERRORS_H + +#endif /* __FTSMERRS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/smooth/ftsmooth.c b/lib/freetype/src/smooth/ftsmooth.c new file mode 100644 index 0000000..131b17e --- /dev/null +++ b/lib/freetype/src/smooth/ftsmooth.c @@ -0,0 +1,371 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.c */ +/* */ +/* Anti-aliasing renderer interface (body). */ +/* */ +/* Copyright 2000-2001, 2002 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 <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_OUTLINE_H +#include "ftsmooth.h" +#include "ftgrays.h" + +#include "ftsmerrs.h" + + + /* initialize renderer -- init its raster */ + static FT_Error + ft_smooth_init( FT_Renderer render ) + { + FT_Library library = FT_MODULE_LIBRARY( render ); + + + render->clazz->raster_class->raster_reset( render->raster, + library->raster_pool, + library->raster_pool_size ); + + return 0; + } + + + /* sets render-specific mode */ + static FT_Error + ft_smooth_set_mode( FT_Renderer render, + FT_ULong mode_tag, + FT_Pointer data ) + { + /* we simply pass it to the raster */ + return render->clazz->raster_class->raster_set_mode( render->raster, + mode_tag, + data ); + } + + /* transform a given glyph image */ + static FT_Error + ft_smooth_transform( FT_Renderer render, + FT_GlyphSlot slot, + FT_Matrix* matrix, + FT_Vector* delta ) + { + FT_Error error = Smooth_Err_Ok; + + + if ( slot->format != render->glyph_format ) + { + error = Smooth_Err_Invalid_Argument; + goto Exit; + } + + if ( matrix ) + FT_Outline_Transform( &slot->outline, matrix ); + + if ( delta ) + FT_Outline_Translate( &slot->outline, delta->x, delta->y ); + + Exit: + return error; + } + + + /* return the glyph's control box */ + static void + ft_smooth_get_cbox( FT_Renderer render, + FT_GlyphSlot slot, + FT_BBox* cbox ) + { + FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + + if ( slot->format == render->glyph_format ) + FT_Outline_Get_CBox( &slot->outline, cbox ); + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render_generic( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + FT_Vector* origin, + FT_Render_Mode required_mode, + FT_Int hmul, + FT_Int vmul ) + { + FT_Error error; + FT_Outline* outline = NULL; + FT_BBox cbox; + FT_UInt width, height, pitch; + FT_Bitmap* bitmap; + FT_Memory memory; + + FT_Raster_Params params; + + + /* check glyph image format */ + if ( slot->format != render->glyph_format ) + { + error = Smooth_Err_Invalid_Argument; + goto Exit; + } + + /* check mode */ + if ( mode != required_mode ) + return Smooth_Err_Cannot_Render_Glyph; + + outline = &slot->outline; + + /* translate the outline to the new origin if needed */ + if ( origin ) + FT_Outline_Translate( outline, origin->x, origin->y ); + + /* compute the control box, and grid fit it */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax + 63 ) & -64; + cbox.yMax = ( cbox.yMax + 63 ) & -64; + + width = ( cbox.xMax - cbox.xMin ) >> 6; + height = ( cbox.yMax - cbox.yMin ) >> 6; + bitmap = &slot->bitmap; + memory = render->root.memory; + + /* release old bitmap buffer */ + if ( slot->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + /* allocate new one, depends on pixel format */ + pitch = width; + if ( hmul ) + { + width = width * hmul; + pitch = ( width + 3 ) & -4; + } + + if ( vmul ) + height *= vmul; + + bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap->num_grays = 256; + bitmap->width = width; + bitmap->rows = height; + bitmap->pitch = pitch; + + if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) + goto Exit; + + slot->flags |= FT_GLYPH_OWN_BITMAP; + + /* translate outline to render it into the bitmap */ + FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + + /* set up parameters */ + params.target = bitmap; + params.source = outline; + params.flags = FT_RASTER_FLAG_AA; + + /* implode outline if needed */ + { + FT_Int n; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) + vec->x *= hmul; + + if ( vmul ) + for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) + vec->y *= vmul; + } + + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + + /* deflate outline if needed */ + { + FT_Int n; + FT_Vector* vec; + + + if ( hmul ) + for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) + vec->x /= hmul; + + if ( vmul ) + for ( vec = outline->points, n = 0; n < outline->n_points; n++, vec++ ) + vec->y /= vmul; + } + + FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); + + if ( error ) + goto Exit; + + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); + slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); + + Exit: + if ( outline && origin ) + FT_Outline_Translate( outline, -origin->x, -origin->y ); + + return error; + } + + + /* convert a slot's glyph image into a bitmap */ + static FT_Error + ft_smooth_render( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + FT_Vector* origin ) + { + return ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_NORMAL, + 0, 0 ); + } + + + /* convert a slot's glyph image into a horizontal LCD bitmap */ + static FT_Error + ft_smooth_render_lcd( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD, + 3, 0 ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; + + return error; + } + + + /* convert a slot's glyph image into a vertical LCD bitmap */ + static FT_Error + ft_smooth_render_lcd_v( FT_Renderer render, + FT_GlyphSlot slot, + FT_Render_Mode mode, + FT_Vector* origin ) + { + FT_Error error; + + error = ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD_V, + 0, 3 ); + if ( !error ) + slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; + + return error; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Renderer_Class ft_smooth_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "smooth", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &ft_grays_raster + }; + + + FT_CALLBACK_TABLE_DEF + const FT_Renderer_Class ft_smooth_lcd_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "smooth-lcd", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &ft_grays_raster + }; + + + + FT_CALLBACK_TABLE_DEF + const FT_Renderer_Class ft_smooth_lcdv_renderer_class = + { + { + ft_module_renderer, + sizeof( FT_RendererRec ), + + "smooth-lcdv", + 0x10000L, + 0x20000L, + + 0, /* module specific interface */ + + (FT_Module_Constructor)ft_smooth_init, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + FT_GLYPH_FORMAT_OUTLINE, + + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, + (FT_Renderer_TransformFunc)ft_smooth_transform, + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + + (FT_Raster_Funcs*) &ft_grays_raster + }; + + +/* END */ diff --git a/lib/freetype/src/smooth/ftsmooth.h b/lib/freetype/src/smooth/ftsmooth.h new file mode 100644 index 0000000..62cced4 --- /dev/null +++ b/lib/freetype/src/smooth/ftsmooth.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* ftsmooth.h */ +/* */ +/* Anti-aliasing renderer interface (specification). */ +/* */ +/* Copyright 1996-2001 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 __FTSMOOTH_H__ +#define __FTSMOOTH_H__ + + +#include <ft2build.h> +#include FT_RENDER_H + + +FT_BEGIN_HEADER + + +#ifndef FT_CONFIG_OPTION_NO_STD_RASTER + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; +#endif + +#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; + + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_renderer_class; + + FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_lcd_v_renderer_class; +#endif + + + +FT_END_HEADER + +#endif /* __FTSMOOTH_H__ */ + + +/* END */ diff --git a/lib/freetype/src/smooth/module.mk b/lib/freetype/src/smooth/module.mk new file mode 100644 index 0000000..ead77cf --- /dev/null +++ b/lib/freetype/src/smooth/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 smooth renderer module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_smooth_renderer + +add_smooth_renderer: + $(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/smooth/rules.mk b/lib/freetype/src/smooth/rules.mk new file mode 100644 index 0000000..457f1e5 --- /dev/null +++ b/lib/freetype/src/smooth/rules.mk @@ -0,0 +1,70 @@ +# +# FreeType 2 smooth renderer module build rules +# + + +# Copyright 1996-2000, 2001 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. + + +# smooth driver directory +# +SMOOTH_DIR := $(SRC_)smooth +SMOOTH_DIR_ := $(SMOOTH_DIR)$(SEP) + +# compilation flags for the driver +# +SMOOTH_COMPILE := $(FT_COMPILE) $I$(SMOOTH_DIR) + + +# smooth driver sources (i.e., C files) +# +SMOOTH_DRV_SRC := $(SMOOTH_DIR_)ftgrays.c \ + $(SMOOTH_DIR_)ftsmooth.c + + +# smooth driver headers +# +SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) \ + $(SMOOTH_DIR_)ftsmerrs.h + + +# smooth driver object(s) +# +# SMOOTH_DRV_OBJ_M is used during `multi' builds. +# SMOOTH_DRV_OBJ_S is used during `single' builds. +# +SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR_)%.c=$(OBJ_)%.$O) +SMOOTH_DRV_OBJ_S := $(OBJ_)smooth.$O + +# smooth driver source file for single build +# +SMOOTH_DRV_SRC_S := $(SMOOTH_DIR_)smooth.c + + +# smooth driver - single object +# +$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ + $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$@ $(SMOOTH_DRV_SRC_S) + + +# smooth driver - multiple objects +# +$(OBJ_)%.$O: $(SMOOTH_DIR_)%.c $(FREETYPE_H) $(SMOOTH_DRV_H) + $(SMOOTH_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) +DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) + + +# EOF diff --git a/lib/freetype/src/smooth/smooth.c b/lib/freetype/src/smooth/smooth.c new file mode 100644 index 0000000..ff6be3e --- /dev/null +++ b/lib/freetype/src/smooth/smooth.c @@ -0,0 +1,26 @@ +/***************************************************************************/ +/* */ +/* smooth.c */ +/* */ +/* FreeType anti-aliasing rasterer module component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include <ft2build.h> +#include "ftgrays.c" +#include "ftsmooth.c" + + +/* END */ diff --git a/lib/freetype/src/tools/cordic.py b/lib/freetype/src/tools/cordic.py new file mode 100644 index 0000000..bb1a238 --- /dev/null +++ b/lib/freetype/src/tools/cordic.py @@ -0,0 +1,78 @@ +# compute arctangent table for CORDIC computations in fttrigon.c +import sys, math + +units = 64*65536.0 # don't change !! +scale = units/math.pi +shrink = 1.0 +comma = "" + +def calc_val( x ): + global units, shrink + angle = math.atan(x) + shrink = shrink * math.cos(angle) + return angle/math.pi * units + +def print_val( n, x ): + global comma + + lo = int(x) + hi = lo + 1 + alo = math.atan(lo) + ahi = math.atan(hi) + ax = math.atan(2.0**n) + + errlo = abs( alo - ax ) + errhi = abs( ahi - ax ) + + if ( errlo < errhi ): + hi = lo + + sys.stdout.write( comma + repr( int(hi) ) ) + comma = ", " + + +print "" +print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units" + +# compute range of "i" +r = [-1] +r = r + range(32) + +for n in r: + + if n >= 0: + x = 1.0/(2.0**n) # tangent value + else: + x = 2.0**(-n) + + angle = math.atan(x) # arctangent + angle2 = angle*scale # arctangent in FT_Angle units + + # determine which integer value for angle gives the best tangent + lo = int(angle2) + hi = lo + 1 + tlo = math.tan(lo/scale) + thi = math.tan(hi/scale) + + errlo = abs( tlo - x ) + errhi = abs( thi - x ) + + angle2 = hi + if errlo < errhi: + angle2 = lo + + if angle2 <= 0: + break + + sys.stdout.write( comma + repr( int(angle2) ) ) + comma = ", " + + shrink = shrink * math.cos( angle2/scale) + + +print +print "shrink factor = " + repr( shrink ) +print "shrink factor 2 = " + repr( shrink * (2.0**32) ) +print "expansion factor = " + repr(1/shrink) +print "" + \ No newline at end of file diff --git a/lib/freetype/src/tools/docmaker/content.py b/lib/freetype/src/tools/docmaker/content.py new file mode 100644 index 0000000..6d33b5d --- /dev/null +++ b/lib/freetype/src/tools/docmaker/content.py @@ -0,0 +1,547 @@ +# +# this file contains routines used to parse the content of documentation +# comment block and build a more structured objects out of them +# + +from sources import * +from utils import * +import string, re + + +# this regular expresion is used to detect code sequences. these +# are simply code fragments embedded in '{' and '}' like in: +# +# { +# x = y + z; +# if ( zookoo == 2 ) +# { +# foobar(); +# } +# } +# +# note that identation of the starting and ending accolades must be +# exactly the same. the code sequence can contain accolades at greater +# indentation +# +re_code_start = re.compile( r"(\s*){\s*$" ) +re_code_end = re.compile( r"(\s*)}\s*$" ) + + +# this regular expression is used to isolate identifiers from +# other text +# +re_identifier = re.compile( r'(\w*)' ) + + +############################################################################# +# +# The DocCode class is used to store source code lines. +# +# 'self.lines' contains a set of source code lines that will be dumped as +# HTML in a <PRE> tag. +# +# The object is filled line by line by the parser; it strips the leading +# "margin" space from each input line before storing it in 'self.lines'. +# +class DocCode: + + def __init__( self, margin, lines ): + self.lines = [] + self.words = None + + # remove margin spaces + for l in lines: + if string.strip( l[:margin] ) == "": + l = l[margin:] + self.lines.append( l ) + + def dump( self, prefix = "", width=60 ): + for l in self.lines: + print prefix + l + + +############################################################################# +# +# The DocPara class is used to store "normal" text paragraph. +# +# 'self.words' contains the list of words that make up the paragraph +# +class DocPara: + + def __init__( self, lines ): + self.lines = None + self.words = [] + for l in lines: + l = string.strip(l) + self.words.extend( string.split( l ) ) + + def dump( self, prefix = "", width = 60 ): + cur = "" # current line + col = 0 # current width + + for word in self.words: + ln = len(word) + if col > 0: + ln = ln+1 + + if col + ln > width: + print prefix + cur + cur = word + col = len(word) + else: + if col > 0: + cur = cur + " " + cur = cur + word + col = col + ln + + if col > 0: + print prefix + cur + + + +############################################################################# +# +# The DocField class is used to store a list containing either DocPara or +# DocCode objects. Each DocField also has an optional "name" which is used +# when the object corresponds to a field of value definition +# +class DocField: + + def __init__( self, name, lines ): + + self.name = name # can be None for normal paragraphs/sources + self.items = [] # list of items + + mode_none = 0 # start parsing mode + mode_code = 1 # parsing code sequences + mode_para = 3 # parsing normal paragraph + + margin = -1 # current code sequence indentation + cur_lines = [] + + # now analyze the markup lines to see if they contain paragraphs, + # code sequences or fields definitions + # + start = 0 + mode = mode_none + for l in lines: + + # are we parsing a code sequence ? + if mode == mode_code: + + m = re_code_end.match( l ) + if m and len(m.group(1)) <= margin: + # that's it, we finised the code sequence + code = DocCode( 0, cur_lines ) + self.items.append( code ) + margin = -1 + cur_lines = [] + mode = mode_none + else: + # nope, continue the code sequence + cur_lines.append( l[margin:] ) + else: + # start of code sequence ? + m = re_code_start.match( l ) + if m: + # save current lines + if cur_lines: + para = DocPara( cur_lines ) + self.items.append( para ) + cur_lines = [] + + # switch to code extraction mode + margin = len(m.group(1)) + mode = mode_code + + else: + if not string.split( l ) and cur_lines: + # if the line is empty, we end the current paragraph, + # if any + para = DocPara( cur_lines ) + self.items.append( para ) + cur_lines = [] + else: + # otherwise, simply add the line to the current + # paragraph + cur_lines.append( l ) + + if mode == mode_code: + # unexpected end of code sequence + code = DocCode( margin, cur_lines ) + self.items.append( code ) + + elif cur_lines: + para = DocPara( cur_lines ) + self.items.append( para ) + + def dump( self, prefix = "" ): + if self.field: + print prefix + self.field + " ::" + prefix = prefix + "----" + + first = 1 + for p in self.items: + if not first: + print "" + p.dump( prefix ) + first = 0 + + +# this regular expression is used to detect field definitions +# +re_field = re.compile( r"\s*(\w*)\s*::" ) + + + +class DocMarkup: + + def __init__( self, tag, lines ): + self.tag = string.lower(tag) + self.fields = [] + + cur_lines = [] + field = None + mode = 0 + + for l in lines: + m = re_field.match( l ) + if m: + # we detected the start of a new field definition + + # first, save the current one + if cur_lines: + f = DocField( field, cur_lines ) + self.fields.append( f ) + cur_lines = [] + field = None + + field = m.group(1) # record field name + ln = len(m.group(0)) + l = " "*ln + l[ln:] + cur_lines = [ l ] + else: + cur_lines.append( l ) + + if field or cur_lines: + f = DocField( field, cur_lines ) + self.fields.append( f ) + + def get_name( self ): + try: + return self.fields[0].items[0].words[0] + + except: + return None + + def dump( self, margin ): + print " "*margin + "<" + self.tag + ">" + for f in self.fields: + f.dump( " " ) + print " "*margin + "</" + self.tag + ">" + + + + +class DocChapter: + + def __init__( self, block ): + self.block = block + self.sections = [] + if block: + self.name = block.name + self.title = block.get_markup_words( "title" ) + self.order = block.get_markup_words( "sections" ) + else: + self.name = "Other" + self.title = string.split( "Miscellaneous" ) + self.order = [] + + + +class DocSection: + + def __init__( self, name = "Other" ): + self.name = name + self.blocks = {} + self.block_names = [] # ordered block names in section + self.defs = [] + self.abstract = "" + self.description = "" + self.order = [] + self.title = "ERROR" + self.chapter = None + + def add_def( self, block ): + self.defs.append( block ) + + def add_block( self, block ): + self.block_names.append( block.name ) + self.blocks[ block.name ] = block + + def process( self ): + # lookup one block that contains a valid section description + for block in self.defs: + title = block.get_markup_text( "Title" ) + if title: + self.title = title + self.abstract = block.get_markup_words( "abstract" ) + self.description = block.get_markup_items( "description" ) + self.order = block.get_markup_words( "order" ) + return + + def reorder( self ): + + self.block_names = sort_order_list( self.block_names, self.order ) + + +class ContentProcessor: + + def __init__( self ): + """initialize a block content processor""" + self.reset() + + self.sections = {} # dictionary of documentation sections + self.section = None # current documentation section + + self.chapters = [] # list of chapters + + def set_section( self, section_name ): + """set current section during parsing""" + if not self.sections.has_key( section_name ): + section = DocSection( section_name ) + self.sections[ section_name ] = section + self.section = section + else: + self.section = self.sections[ section_name ] + + def add_chapter( self, block ): + chapter = DocChapter( block ) + self.chapters.append( chapter ) + + + def reset( self ): + """reset the content processor for a new block""" + self.markups = [] + self.markup = None + self.markup_lines = [] + + def add_markup( self ): + """add a new markup section""" + if self.markup and self.markup_lines: + + # get rid of last line of markup if it's empty + marks = self.markup_lines + if len(marks) > 0 and not string.strip(marks[-1]): + self.markup_lines = marks[:-1] + + m = DocMarkup( self.markup, self.markup_lines ) + + self.markups.append( m ) + + self.markup = None + self.markup_lines = [] + + + def process_content( self, content ): + """process a block content and return a list of DocMarkup objects + corresponding to it""" + markup = None + markup_lines = [] + first = 1 + + for line in content: + found = None + for t in re_markup_tags: + m = t.match( line ) + if m: + found = string.lower(m.group(1)) + prefix = len(m.group(0)) + line = " "*prefix + line[prefix:] # remove markup from line + break + + # is it the start of a new markup section ? + if found: + first = 0 + self.add_markup() # add current markup content + self.markup = found + if len(string.strip( line )) > 0: + self.markup_lines.append( line ) + elif first == 0: + self.markup_lines.append( line ) + + self.add_markup() + + return self.markups + + + def parse_sources( self, source_processor ): + blocks = source_processor.blocks + count = len(blocks) + for n in range(count): + + source = blocks[n] + if source.content: + # this is a documentation comment, we need to catch + # all following normal blocks in the "follow" list + # + follow = [] + m = n+1 + while m < count and not blocks[m].content: + follow.append( blocks[m] ) + m = m+1 + + doc_block = DocBlock( source, follow, self ) + + + def finish( self ): + + # process all sections to extract their abstract, description + # and ordered list of items + # + for sec in self.sections.values(): + sec.process() + + # process chapters to check that all sections are correctly + # listed there + for chap in self.chapters: + for sec in chap.order: + if self.sections.has_key(sec): + section = self.sections[ sec ] + section.chapter = chap + section.reorder() + chap.sections.append( section ) + else: + sys.stderr.write( "WARNING: chapter '" + + chap.name + "' in " + chap.block.location() + \ + " lists unknown section '" + sec + "'\n" ) + + # check that all sections are in a chapter + # + others = [] + for sec in self.sections.values(): + if not sec.chapter: + others.append(sec) + + # create a new special chapter for all remaining sections + # when necessary + # + if others: + chap = DocChapter( None ) + chap.sections = others + self.chapters.append( chap ) + + + +class DocBlock: + + def __init__( self, source, follow, processor ): + + processor.reset() + + self.source = source + self.code = [] + self.type = "ERRTYPE" + self.name = "ERRNAME" + self.section = processor.section + self.markups = processor.process_content( source.content ) + + # compute block type from first markup tag + try: + self.type = self.markups[0].tag + except: + pass + + + # compute block name from first markup paragraph + try: + markup = self.markups[0] + para = markup.fields[0].items[0] + name = para.words[0] + m = re_identifier.match( name ) + if m: + name = m.group(1) + self.name = name + except: + pass + + # detect new section starts + if self.type == "section": + processor.set_section( self.name ) + processor.section.add_def( self ) + + # detect new chapter + elif self.type == "chapter": + processor.add_chapter( self ) + + else: + processor.section.add_block( self ) + + # now, compute the source lines relevant to this documentation + # block. We keep normal comments in for obvious reasons (??) + source = [] + for b in follow: + if b.format: + break + for l in b.lines: + # we use "/* */" as a separator + if re_source_sep.match( l ): + break + source.append( l ) + + # now strip the leading and trailing empty lines from the sources + start = 0 + end = len( source )-1 + + while start < end and not string.strip( source[start] ): + start = start + 1 + + while start < end and not string.strip( source[end] ): + end = end - 1 + + source = source[start:end+1] + + self.code = source + + + def location( self ): + return self.source.location() + + + + def get_markup( self, tag_name ): + """return the DocMarkup corresponding to a given tag in a block""" + for m in self.markups: + if m.tag == string.lower(tag_name): + return m + return None + + + def get_markup_name( self, tag_name ): + """return the name of a given primary markup in a block""" + try: + m = self.get_markup( tag_name ) + return m.get_name() + except: + return None + + + def get_markup_words( self, tag_name ): + try: + m = self.get_markup( tag_name ) + return m.fields[0].items[0].words + except: + return [] + + + def get_markup_text( self, tag_name ): + result = self.get_markup_words( tag_name ) + return string.join( result ) + + + def get_markup_items( self, tag_name ): + try: + m = self.get_markup( tag_name ) + return m.fields[0].items + except: + return None \ No newline at end of file diff --git a/lib/freetype/src/tools/docmaker/docmaker.py b/lib/freetype/src/tools/docmaker/docmaker.py new file mode 100644 index 0000000..285bcd6 --- /dev/null +++ b/lib/freetype/src/tools/docmaker/docmaker.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +# +# DocMaker 0.2 (c) 2002 David Turner <david@freetype.org> +# +# This program is a re-write of the original DocMaker took used +# to generate the API Reference of the FreeType font engine +# by converting in-source comments into structured HTML +# +# This new version is capable of outputting XML data, as well +# as accepts more liberal formatting options +# +# It also uses regular expression matching and substitution +# to speed things significantly +# + +from sources import * +from content import * +from utils import * +from formatter import * +from tohtml import * + +import utils + +import sys, os, time, string, glob, getopt + + +def file_exists( pathname ): + """checks that a given file exists""" + result = 1 + try: + file = open( pathname, "r" ) + file.close() + except: + result = None + sys.stderr.write( pathname + " couldn't be accessed\n" ) + + return result + + +def make_file_list( args = None ): + """builds a list of input files from command-line arguments""" + + file_list = [] + # sys.stderr.write( repr( sys.argv[1 :] ) + '\n' ) + + if not args: + args = sys.argv[1 :] + + for pathname in args: + if string.find( pathname, '*' ) >= 0: + newpath = glob.glob( pathname ) + newpath.sort() # sort files -- this is important because + # of the order of files + else: + newpath = [pathname] + + file_list.extend( newpath ) + + if len( file_list ) == 0: + file_list = None + else: + # now filter the file list to remove non-existing ones + file_list = filter( file_exists, file_list ) + + return file_list + + + +def usage(): + print "\nDocMaker 0.2 Usage information\n" + print " docmaker [options] file1 [ file2 ... ]\n" + print "using the following options:\n" + print " -h : print this page" + print " -t : set project title, as in '-t \"My Project\"'" + print " -o : set output directory, as in '-o mydir'" + print " -p : set documentation prefix, as in '-p ft2'" + print "" + print " --title : same as -t, as in '--title=\"My Project\"'" + print " --output : same as -o, as in '--output=mydir'" + print " --prefix : same as -p, as in '--prefix=ft2'" + + +def main( argv ): + """main program loop""" + + global output_dir + + try: + opts, args = getopt.getopt( sys.argv[1:], + "ht:o:p:", + [ "help", "title=", "output=", "prefix=" ] ) + + except getopt.GetoptError: + usage() + sys.exit( 2 ) + + if args == []: + usage() + sys.exit( 1 ) + + # process options + # + project_title = "Project" + project_prefix = None + output_dir = None + + for opt in opts: + if opt[0] in ( "-h", "--help" ): + usage() + sys.exit( 0 ) + + if opt[0] in ( "-t", "--title" ): + project_title = opt[1] + + if opt[0] in ( "-o", "--output" ): + utils.output_dir = opt[1] + + if opt[0] in ( "-p", "--prefix" ): + project_prefix = opt[1] + + check_output( ) + + # create context and processor + source_processor = SourceProcessor() + content_processor = ContentProcessor() + + # retrieve the list of files to process + file_list = make_file_list( args ) + for filename in file_list: + source_processor.parse_file( filename ) + content_processor.parse_sources( source_processor ) + + # process sections + content_processor.finish() + + formatter = HtmlFormatter( content_processor, project_title, project_prefix ) + + formatter.toc_dump() + formatter.index_dump() + formatter.section_dump_all() + + +# if called from the command line +# +if __name__ == '__main__': + main( sys.argv ) + + +# eof diff --git a/lib/freetype/src/tools/docmaker/formatter.py b/lib/freetype/src/tools/docmaker/formatter.py new file mode 100644 index 0000000..36d72ae --- /dev/null +++ b/lib/freetype/src/tools/docmaker/formatter.py @@ -0,0 +1,194 @@ +from sources import * +from content import * +from utils import * + +class Formatter: + + def __init__( self, processor ): + + self.processor = processor + self.identifiers = {} + self.chapters = processor.chapters + self.sections = processor.sections.values() + self.block_index = [] + + # store all blocks in a dictionary + self.blocks = [] + for section in self.sections: + for block in section.blocks.values(): + self.add_identifier( block.name, block ) + + # add enumeration values to the index, since this is useful + for markup in block.markups: + if markup.tag == 'values': + for field in markup.fields: + self.add_identifier( field.name, block ) + + + self.block_index = self.identifiers.keys() + self.block_index.sort( index_sort ) + + + def add_identifier( self, name, block ): + if self.identifiers.has_key( name ): + # duplicate name !! + sys.stderr.write( \ + "WARNING: duplicate definition for '" + name + "' in " + \ + block.location() + ", previous definition in " + \ + self.identifiers[ name ].location() + "\n" ) + else: + self.identifiers[name] = block + + + # + # Formatting the table of contents + # + + def toc_enter( self ): + pass + + def toc_chapter_enter( self, chapter ): + pass + + def toc_section_enter( self, section ): + pass + + def toc_section_exit( self, section ): + pass + + def toc_chapter_exit( self, chapter ): + pass + + def toc_index( self, index_filename ): + pass + + def toc_exit( self ): + pass + + def toc_dump( self, toc_filename = None, index_filename = None ): + + output = None + if toc_filename: + output = open_output( toc_filename ) + + self.toc_enter() + + for chap in self.processor.chapters: + + self.toc_chapter_enter( chap ) + + for section in chap.sections: + self.toc_section_enter( section ) + self.toc_section_exit( section ) + + self.toc_chapter_exit ( chap ) + + self.toc_index( index_filename ) + + self.toc_exit() + + if output: + close_output( output ) + + # + # Formatting the index + # + + def index_enter( self ): + pass + + def index_name_enter( self, name ): + pass + + def index_name_exit( self, name ): + pass + + def index_exit( self ): + pass + + def index_dump( self, index_filename = None ): + + output = None + if index_filename: + output = open_output( index_filename ) + + self.index_enter() + + for name in self.block_index: + self.index_name_enter( name ) + self.index_name_exit ( name ) + + self.index_exit() + + if output: + close_output( output ) + + # + # Formatting a section + # + def section_enter( self, section ): + pass + + def block_enter( self, block ): + pass + + def markup_enter( self, markup, block = None ): + pass + + def field_enter( self, field, markup = None, block = None ): + pass + + def field_exit( self, field, markup = None, block = None ): + pass + + def markup_exit( self, markup, block = None ): + pass + + def block_exit( self, block ): + pass + + def section_exit( self, section ): + pass + + + def section_dump( self, section, section_filename = None ): + + output = None + if section_filename: + output = open_output( section_filename ) + + self.section_enter( section ) + + for name in section.block_names: + block = self.identifiers[ name ] + self.block_enter( block ) + + for markup in block.markups[1:]: # always ignore first markup !! + self.markup_enter( markup, block ) + + for field in markup.fields: + self.field_enter( field, markup, block ) + + self.field_exit ( field, markup, block ) + + self.markup_exit( markup, block ) + + self.block_exit( block ) + + self.section_exit ( section ) + + if output: + close_output( output ) + + + def section_dump_all( self ): + for section in self.sections: + self.section_dump( section ) + + # + # Formatting a block + # + + + + diff --git a/lib/freetype/src/tools/docmaker/sources.py b/lib/freetype/src/tools/docmaker/sources.py new file mode 100644 index 0000000..9828aa6 --- /dev/null +++ b/lib/freetype/src/tools/docmaker/sources.py @@ -0,0 +1,355 @@ +# +# this file contains definitions of classes needed to decompose +# C sources files into a series of multi-line "blocks". There are +# two kinds of blocks: +# +# - normal blocks, which contain source code or ordinary comments +# +# - documentation blocks, which have restricted formatting, and +# whose text always start with a documentation markup tag like +# "<Function>", "<Type>", etc.. +# +# the routines used to process the content of documentation blocks +# are not contained here, but in "content.py" +# +# the classes and methods found here only deal with text parsing +# and basic documentation block extraction +# +import fileinput, re, sys, os, string + + + + + + +################################################################ +## +## BLOCK FORMAT PATTERN +## +## A simple class containing compiled regular expressions used +## to detect potential documentation format block comments within +## C source code +## +## note that the 'column' pattern must contain a group that will +## be used to "unbox" the content of documentation comment blocks +## +class SourceBlockFormat: + + def __init__( self, id, start, column, end ): + """create a block pattern, used to recognize special documentation blocks""" + + self.id = id + self.start = re.compile( start, re.VERBOSE ) + self.column = re.compile( column, re.VERBOSE ) + self.end = re.compile( end, re.VERBOSE ) + + + +# +# format 1 documentation comment blocks look like the following: +# +# /************************************/ +# /* */ +# /* */ +# /* */ +# /************************************/ +# +# we define a few regular expressions here to detect them +# + +start = r''' + \s* # any number of whitespace + /\*{2,}/ # followed by '/' and at least two asterisks then '/' + \s*$ # eventually followed by whitespace +''' + +column = r''' + \s* # any number of whitespace + /\*{1} # followed by '/' and precisely one asterisk + ([^*].*) # followed by anything (group 1) + \*{1}/ # followed by one asterisk and a '/' + \s*$ # enventually followed by whitespace +''' + +re_source_block_format1 = SourceBlockFormat( 1, start, column, start ) + +# +# format 2 documentation comment blocks look like the following: +# +# /************************************ (at least 2 asterisks) +# * +# * +# * +# * +# **/ (1 or more asterisks at the end) +# +# we define a few regular expressions here to detect them +# +start = r''' + \s* # any number of whitespace + /\*{2,} # followed by '/' and at least two asterisks + \s*$ # eventually followed by whitespace +''' + +column = r''' + \s* # any number of whitespace + \*{1} # followed by precisely one asterisk + (.*) # then anything (group1) +''' + +end = r''' + \s* # any number of whitespace + \*+/ # followed by at least one asterisk, then '/' +''' + +re_source_block_format2 = SourceBlockFormat( 2, start, column, end ) + +# +# the list of supported documentation block formats, we could add new ones +# relatively easily +# +re_source_block_formats = [ re_source_block_format1, re_source_block_format2 ] + + +# +# the following regular expressions corresponds to markup tags +# within the documentation comment blocks. they're equivalent +# despite their different syntax +# +# notice how each markup tag _must_ begin a new line +# +re_markup_tag1 = re.compile( r'''\s*<(\w*)>''' ) # <xxxx> format +re_markup_tag2 = re.compile( r'''\s*@(\w*):''' ) # @xxxx: format + +# +# the list of supported markup tags, we could add new ones relatively +# easily +# +re_markup_tags = [ re_markup_tag1, re_markup_tag2 ] + +# +# used to detect a cross-reference, after markup tags have been stripped +# +re_crossref = re.compile( r'@(\w*)' ) + +# +# used to detect italic and bold styles in paragraph text +# +re_italic = re.compile( r'_(\w+)_' ) +re_bold = re.compile( r'\*(\w+)\*' ) + +# +# used to detect the end of commented source lines +# +re_source_sep = re.compile( r'\s*/\*\s*\*/' ) + +# +# used to perform cross-reference within source output +# +re_source_crossref = re.compile( r'(\W*)(\w*)' ) + +# +# a list of reserved source keywords +# +re_source_keywords = re.compile( '''( typedef | + struct | + enum | + union | + const | + char | + int | + short | + long | + void | + signed | + unsigned | + \#include | + \#define | + \#undef | + \#if | + \#ifdef | + \#ifndef | + \#else | + \#endif )''', re.VERBOSE ) + +################################################################ +## +## SOURCE BLOCK CLASS +## +## A SourceProcessor is in charge or reading a C source file +## and decomposing it into a series of different "SourceBlocks". +## each one of these blocks can be made of the following data: +## +## - A documentation comment block that starts with "/**" and +## whose exact format will be discussed later +## +## - normal sources lines, include comments +## +## the important fields in a text block are the following ones: +## +## self.lines : a list of text lines for the corresponding block +## +## self.content : for documentation comment blocks only, this is the +## block content that has been "unboxed" from its +## decoration. This is None for all other blocks +## (i.e. sources or ordinary comments with no starting +## markup tag) +## +class SourceBlock: + def __init__( self, processor, filename, lineno, lines ): + self.processor = processor + self.filename = filename + self.lineno = lineno + self.lines = lines + self.format = processor.format + self.content = [] + + if self.format == None: + return + + words = [] + + # extract comment lines + lines = [] + + for line0 in self.lines[1:]: + m = self.format.column.match( line0 ) + if m: + lines.append( m.group(1) ) + + # now, look for a markup tag + for l in lines: + l = string.strip(l) + if len(l) > 0: + for tag in re_markup_tags: + if tag.match( l ): + self.content = lines + return + + def location( self ): + return "(" + self.filename + ":" + repr(self.lineno) + ")" + + + # debugging only - not used in normal operations + def dump( self ): + + if self.content: + print "{{{content start---" + for l in self.content: + print l + print "---content end}}}" + return + + fmt = "" + if self.format: + fmt = repr(self.format.id) + " " + + for line in self.lines: + print line + + +################################################################ +## +## SOURCE PROCESSOR CLASS +## +## The SourceProcessor is in charge or reading a C source file +## and decomposing it into a series of different "SourceBlock" +## objects. +## +## each one of these blocks can be made of the following data: +## +## - A documentation comment block that starts with "/**" and +## whose exact format will be discussed later +## +## - normal sources lines, include comments +## +## +class SourceProcessor: + + def __init__( self ): + """initialize a source processor""" + self.blocks = [] + self.filename = None + self.format = None + self.lines = [] + + def reset( self ): + """reset a block processor, clean all its blocks""" + self.blocks = [] + self.format = None + + + def parse_file( self, filename ): + """parse a C source file, and adds its blocks to the processor's list""" + + self.reset() + + self.filename = filename + + fileinput.close() + self.format = None + self.lineno = 0 + self.lines = [] + + for line in fileinput.input( filename ): + + # strip trailing newlines, important on Windows machines !! + if line[-1] == '\012': + line = line[0:-1] + + if self.format == None: + self.process_normal_line( line ) + + else: + if self.format.end.match( line ): + # that's a normal block end, add it to lines and + # create a new block + # self.lines.append( line ) + self.add_block_lines() + + elif self.format.column.match( line ): + # that's a normal column line, add it to 'lines' + self.lines.append( line ) + + else: + # humm.. this is an unexcepted block end, + # create a new block, but don't process the line + self.add_block_lines() + + # we need to process the line again + self.process_normal_line( line ) + + # record the last lines + self.add_block_lines() + + + + def process_normal_line( self, line ): + """process a normal line and check if it's the start of a new block""" + for f in re_source_block_formats: + if f.start.match( line ): + self.add_block_lines() + self.format = f + self.lineno = fileinput.filelineno() + + self.lines.append( line ) + + + + def add_block_lines( self ): + """add the current accumulated lines, and create a new block""" + if self.lines != []: + block = SourceBlock( self, self.filename, self.lineno, self.lines ) + + self.blocks.append( block ) + self.format = None + self.lines = [] + + + # debugging only, not used in normal operations + def dump( self ): + """print all blocks in a processor""" + for b in self.blocks: + b.dump() + +# eof diff --git a/lib/freetype/src/tools/docmaker/tohtml.py b/lib/freetype/src/tools/docmaker/tohtml.py new file mode 100644 index 0000000..75e5db0 --- /dev/null +++ b/lib/freetype/src/tools/docmaker/tohtml.py @@ -0,0 +1,476 @@ +from sources import * +from content import * +from formatter import * + +import time + +# The following defines the HTML header used by all generated pages. +# +html_header_1 = """\ +<html> +<header> +<title>""" + +html_header_2= """ API Reference + + + + +

""" + +html_header_3=""" API Reference

+""" + + + +# The HTML footer used by all generated pages. +# +html_footer = """\ + +""" + +# The header and footer used for each section. +# +section_title_header = "

" +section_title_footer = "

" + +# The header and footer used for code segments. +# +code_header = "
"
+code_footer = "
" + +# Paragraph header and footer. +# +para_header = "

" +para_footer = "

" + +# Block header and footer. +# +block_header = "
" +block_footer = "

" + +# Description header/footer. +# +description_header = "
" +description_footer = "

" + +# Marker header/inter/footer combination. +# +marker_header = "
" +marker_inter = "
" +marker_footer = "
" + +# Source code extracts header/footer. +# +source_header = "
\n"
+source_footer = "\n

" + +# Chapter header/inter/footer. +# +chapter_header = "

" +chapter_inter = "

    " +chapter_footer = "
" + + +# source language keyword coloration/styling +# +keyword_prefix = '' +keyword_suffix = '' + +section_synopsis_header = '

Synopsys

' +section_synopsis_footer = '' + +# Translate a single line of source to HTML. This will convert +# a "<" into "<.", ">" into ">.", etc. +# +def html_quote( line ): + result = string.replace( line, "&", "&" ) + result = string.replace( result, "<", "<" ) + result = string.replace( result, ">", ">" ) + return result + + +# same as 'html_quote', but ignores left and right brackets +# +def html_quote0( line ): + return string.replace( line, "&", "&" ) + + +def dump_html_code( lines, prefix = "" ): + # clean the last empty lines + # + l = len( self.lines ) + while l > 0 and string.strip( self.lines[l - 1] ) == "": + l = l - 1 + + # The code footer should be directly appended to the last code + # line to avoid an additional blank line. + # + print prefix + code_header, + for line in self.lines[0 : l+1]: + print '\n' + prefix + html_quote(line), + print prefix + code_footer, + + + +class HtmlFormatter(Formatter): + + def __init__( self, processor, project_title, file_prefix ): + + Formatter.__init__( self, processor ) + + global html_header_1, html_header_2, html_header_3, html_footer + + if file_prefix: + file_prefix = file_prefix + "-" + else: + file_prefix = "" + + self.project_title = project_title + self.file_prefix = file_prefix + self.html_header = html_header_1 + project_title + html_header_2 + \ + project_title + html_header_3 + + self.html_footer = "

generated on " + \ + time.asctime( time.localtime( time.time() ) ) + \ + "

" + html_footer + + self.columns = 3 + + def make_section_url( self, section ): + return self.file_prefix + section.name + ".html" + + + def make_block_url( self, block ): + return self.make_section_url( block.section ) + "#" + block.name + + + def make_html_words( self, words ): + """ convert a series of simple words into some HTML text """ + line = "" + if words: + line = html_quote( words[0] ) + for w in words[1:]: + line = line + " " + html_quote( w ) + + return line + + + def make_html_word( self, word ): + """analyze a simple word to detect cross-references and styling""" + # look for cross-references + # + m = re_crossref.match( word ) + if m: + try: + name = m.group(1) + block = self.identifiers[ name ] + url = self.make_block_url( block ) + return '' + name + '' + except: + return '?' + name + '?' + + # look for italics and bolds + m = re_italic.match( word ) + if m: + name = m.group(1) + return ''+name+'' + + m = re_bold.match( word ) + if m: + name = m.group(1) + return ''+name+'' + + return html_quote(word) + + + def make_html_para( self, words ): + """ convert a paragraph's words into tagged HTML text, handle xrefs """ + line = "" + if words: + line = self.make_html_word( words[0] ) + for word in words[1:]: + line = line + " " + self.make_html_word( word ) + + return "

" + line + "

" + + + def make_html_code( self, lines ): + """ convert a code sequence to HTML """ + line = code_header + '\n' + for l in lines: + line = line + html_quote( l ) + '\n' + + return line + code_footer + + + def make_html_items( self, items ): + """ convert a field's content into some valid HTML """ + lines = [] + for item in items: + if item.lines: + lines.append( self.make_html_code( item.lines ) ) + else: + lines.append( self.make_html_para( item.words ) ) + + return string.join( lines, '\n' ) + + + def print_html_items( self, items ): + print self.make_html_items( items ) + + + def print_html_field( self, field ): + if field.name: + print "
"+field.name+"" + + print self.make_html_items( field.items ) + + if field.name: + print "
" + + + def html_source_quote( self, line, block_name = None ): + result = "" + while line: + m = re_source_crossref.match( line ) + if m: + name = m.group(2) + prefix = html_quote( m.group(1) ) + length = len( m.group(0) ) + + if name == block_name: + # this is the current block name, if any + result = result + prefix + '' + name + '' + + elif re_source_keywords.match(name): + # this is a C keyword + result = result + prefix + keyword_prefix + name + keyword_suffix + + elif self.identifiers.has_key(name): + # this is a known identifier + block = self.identifiers[name] + result = result + prefix + '' + name + '' + else: + result = result + html_quote(line[ : length ]) + + line = line[ length : ] + else: + result = result + html_quote(line) + line = [] + + return result + + + def print_html_field_list( self, fields ): + print "" + for field in fields: + print "" + print "
" + field.name + "" + self.print_html_items( field.items ) + print "
" + + + def print_html_markup( self, markup ): + table_fields = [] + for field in markup.fields: + if field.name: + # we begin a new series of field or value definitions, we + # will record them in the 'table_fields' list before outputting + # all of them as a single table + # + table_fields.append( field ) + + else: + if table_fields: + self.print_html_field_list( table_fields ) + table_fields = [] + + self.print_html_items( field.items ) + + if table_fields: + self.print_html_field_list( table_fields ) + + # + # Formatting the index + # + + def index_enter( self ): + print self.html_header + self.index_items = {} + + def index_name_enter( self, name ): + block = self.identifiers[ name ] + url = self.make_block_url( block ) + self.index_items[ name ] = url + + def index_exit( self ): + + # block_index already contains the sorted list of index names + count = len( self.block_index ) + rows = (count + self.columns - 1)/self.columns + + print "
" + for r in range(rows): + line = "" + for c in range(self.columns): + i = r + c*rows + if i < count: + bname = self.block_index[ r + c*rows ] + url = self.index_items[ bname ] + line = line + '' + else: + line = line + '' + line = line + "" + print line + + print "
' + bname + '
" + print self.html_footer + self.index_items = {} + + def index_dump( self, index_filename = None ): + + if index_filename == None: + index_filename = self.file_prefix + "index.html" + + Formatter.index_dump( self, index_filename ) + + # + # Formatting the table of content + # + def toc_enter( self ): + print self.html_header + print "

Table of Contents

" + + def toc_chapter_enter( self, chapter ): + print chapter_header + string.join(chapter.title) + chapter_inter + print "" + + def toc_section_enter( self, section ): + print "" + + def toc_chapter_exit( self, chapter ): + print "
" + print '' + \ + section.title + '' + + print self.make_html_para( section.abstract ) + + def toc_section_exit( self, section ): + print "
" + print chapter_footer + + def toc_index( self, index_filename ): + print chapter_header + 'Global Index' + chapter_inter + chapter_footer + + def toc_exit( self ): + print "" + print self.html_footer + + def toc_dump( self, toc_filename = None, index_filename = None ): + if toc_filename == None: + toc_filename = self.file_prefix + "toc.html" + + if index_filename == None: + index_filename = self.file_prefix + "index.html" + + Formatter.toc_dump( self, toc_filename, index_filename ) + + # + # Formatting sections + # + def section_enter( self, section ): + print self.html_header + + print section_title_header + print section.title + print section_title_footer + + # print section synopsys + print section_synopsis_header + print "
" + + maxwidth = 0 + for b in section.blocks.values(): + if len(b.name) > maxwidth: + maxwidth = len(b.name) + + width = 70 # XXX magic number + columns = width / maxwidth + if columns < 1: + columns = 1 + + count = len(section.block_names) + rows = (count + columns-1)/columns + for r in range(rows): + line = "" + for c in range(columns): + i = r + c*rows + line = line + '' + line = line + "" + print line + + print "
' + if i < count: + name = section.block_names[i] + line = line + '' + name + '' + + line = line + '


" + print section_synopsis_footer + + print description_header + print self.make_html_items( section.description ) + print description_footer + + def block_enter( self, block ): + print block_header + + # place html anchor if needed + if block.name: + print '' + print "

" + block.name + "

" + print "
" + + # dump the block C source lines now + if block.code: + print source_header + for l in block.code: + print self.html_source_quote( l, block.name ) + print source_footer + + + def markup_enter( self, markup, block ): + if markup.tag == "description": + print description_header + else: + print marker_header + markup.tag + marker_inter + + self.print_html_markup( markup ) + + def markup_exit( self, markup, block ): + if markup.tag == "description": + print description_footer + else: + print marker_footer + + def block_exit( self, block ): + print block_footer + + + def section_exit( self, section ): + print html_footer + + + def section_dump_all( self ): + for section in self.sections: + self.section_dump( section, self.file_prefix + section.name + '.html' ) + \ No newline at end of file diff --git a/lib/freetype/src/tools/docmaker/utils.py b/lib/freetype/src/tools/docmaker/utils.py new file mode 100644 index 0000000..6d4653d --- /dev/null +++ b/lib/freetype/src/tools/docmaker/utils.py @@ -0,0 +1,87 @@ +import string, sys, os + +# current output directory +# +output_dir = None + + +# This function is used to sort the index. It is a simple lexicographical +# sort, except that it places capital letters before lowercase ones. +# +def index_sort( s1, s2 ): + if not s1: + return -1 + + if not s2: + return 1 + + l1 = len( s1 ) + l2 = len( s2 ) + m1 = string.lower( s1 ) + m2 = string.lower( s2 ) + + for i in range( l1 ): + if i >= l2 or m1[i] > m2[i]: + return 1 + + if m1[i] < m2[i]: + return -1 + + if s1[i] < s2[i]: + return -1 + + if s1[i] > s2[i]: + return 1 + + if l2 > l1: + return -1 + + return 0 + +# Sort input_list, placing the elements of order_list in front. +# +def sort_order_list( input_list, order_list ): + new_list = order_list[:] + for id in input_list: + if not id in order_list: + new_list.append( id ) + return new_list + + + +# Open the standard output to a given project documentation file. Use +# "output_dir" to determine the filename location if necessary and save the +# old stdout in a tuple that is returned by this function. +# +def open_output( filename ): + global output_dir + + if output_dir and output_dir != "": + filename = output_dir + os.sep + filename + + old_stdout = sys.stdout + new_file = open( filename, "w" ) + sys.stdout = new_file + + return ( new_file, old_stdout ) + + +# Close the output that was returned by "close_output". +# +def close_output( output ): + output[0].close() + sys.stdout = output[1] + + +# Check output directory. +# +def check_output( ): + global output_dir + if output_dir: + if output_dir != "": + if not os.path.isdir( output_dir ): + sys.stderr.write( "argument" + " '" + output_dir + "' " + + "is not a valid directory" ) + sys.exit( 2 ) + else: + output_dir = None diff --git a/lib/freetype/src/tools/glnames.py b/lib/freetype/src/tools/glnames.py new file mode 100644 index 0000000..e377cd0 --- /dev/null +++ b/lib/freetype/src/tools/glnames.py @@ -0,0 +1,1722 @@ +#!/usr/bin/env python +# + +# +# FreeType 2 glyph name builder +# + + +# Copyright 1996-2000 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. + + +"""\ + +usage: %s + + This very simple python script is used to generate the glyph names + tables defined in the PSNames module. + + Its single argument is the name of the header file to be created. +""" + + +import sys, string + + +# This table is used to name the glyph according to the Macintosh +# specification. It is used by the TrueType Postscript names table +# +# see http://fonts.apple.com/TTRefMan/RM06/Chap6post.html +# for the official list +# +mac_standard_names = \ +[ + # 0 + ".notdef", ".null", "nonmarkingreturn", "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", "nonbreakingspace", "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 + "Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dcroat" +] + + +# the list of standard "SID" glyph names. For the official list, +# see Annex A of document at +# http://partners.adobe.com/asn/developer/pdfs/tn/5176.CFF.pdf +# +sid_standard_names = \ +[ + # 0 + ".notdef", "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quoteright", "parenleft", + + # 10 + "parenright", "asterisk", "plus", "comma", "hyphen", + "period", "slash", "zero", "one", "two", + + # 20 + "three", "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", "less", + + # 30 + "equal", "greater", "question", "at", "A", + "B", "C", "D", "E", "F", + + # 40 + "G", "H", "I", "J", "K", + "L", "M", "N", "O", "P", + + # 50 + "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", + + # 60 + "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", + "quoteleft", "a", "b", "c", "d", + + # 70 + "e", "f", "g", "h", "i", + "j", "k", "l", "m", "n", + + # 80 + "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", + + # 90 + "y", "z", "braceleft", "bar", "braceright", + "asciitilde", "exclamdown", "cent", "sterling", "fraction", + + # 100 + "yen", "florin", "section", "currency", "quotesingle", + "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", + + # 110 + "fl", "endash", "dagger", "daggerdbl", "periodcentered", + "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", + + # 120 + "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", + "acute", "circumflex", "tilde", "macron", "breve", + + # 130 + "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", + "ogonek", "caron", "emdash", "AE", "ordfeminine", + + # 140 + "Lslash", "Oslash", "OE", "ordmasculine", "ae", + "dotlessi", "lslash", "oslash", "oe", "germandbls", + + # 150 + "onesuperior", "logicalnot", "mu", "trademark", "Eth", + "onehalf", "plusminus", "Thorn", "onequarter", "divide", + + # 160 + "brokenbar", "degree", "thorn", "threequarters", "twosuperior", + "registered", "minus", "eth", "multiply", "threesuperior", + + # 170 + "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", + "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", + + # 180 + "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", + + # 190 + "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", + "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", + + # 200 + "aacute", "acircumflex", "adieresis", "agrave", "aring", + "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", + + # 210 + "egrave", "iacute", "icircumflex", "idieresis", "igrave", + "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", + + # 220 + "otilde", "scaron", "uacute", "ucircumflex", "udieresis", + "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", + + # 230 + "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", + "Acutesmall", + "parenleftsuperior", "parenrightsuperior", "twodotenleader", + "onedotenleader", "zerooldstyle", + + # 240 + "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", + "commasuperior", + + # 250 + "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", + "bsuperior", + "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", + + # 260 + "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", + "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", + + # 270 + "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", + "Asmall", + "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", + + # 280 + "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", + "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", + + # 290 + "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", + "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", + + # 300 + "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", + "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", + "Dieresissmall", + + # 310 + "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", + "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", + "questiondownsmall", + + # 320 + "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", + "twothirds", "zerosuperior", "foursuperior", "fivesuperior", + "sixsuperior", + + # 330 + "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", + "oneinferior", + "twoinferior", "threeinferior", "fourinferior", "fiveinferior", + "sixinferior", + + # 340 + "seveninferior", "eightinferior", "nineinferior", "centinferior", + "dollarinferior", + "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", + "Acircumflexsmall", + + # 350 + "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", + "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", + "Igravesmall", + + # 360 + "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", + "Ntildesmall", + "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", + "Odieresissmall", + + # 370 + "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", + "001.000", + + # 380 + "001.001", "001.002", "001.003", "Black", "Bold", + "Book", "Light", "Medium", "Regular", "Roman", + + # 390 + "Semibold" +] + + +# this table maps character code of the Adobe Standard Type 1 +# encoding to glyph indexes in the sid_standard_names table +# +t1_standard_encoding = \ +[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, + 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, + 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, + + 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, + 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, + 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, + + 148, 149, 0, 0, 0, 0 +] + + +# this table maps character code of the Adobe Expert Type 1 +# encoding to glyph indexes in the sid_standard_names table +# +t1_expert_encoding = \ +[ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, + 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, + + 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, + 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, + 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, + 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, + 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, + + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, + 311, 0, 312, 0, 0, 313, 0, 0, 314, 315, + 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, + 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, + + 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + + 373, 374, 375, 376, 377, 378 +] + + +# This data has been taken literally from the file `glyphlist.txt', +# version 1.2, 22 Oct 1998. It is available from +# +# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html +# +adobe_glyph_list = """\ +0041;A;LATIN CAPITAL LETTER A +00C6;AE;LATIN CAPITAL LETTER AE +01FC;AEacute;LATIN CAPITAL LETTER AE WITH ACUTE +F7E6;AEsmall;LATIN SMALL CAPITAL LETTER AE +00C1;Aacute;LATIN CAPITAL LETTER A WITH ACUTE +F7E1;Aacutesmall;LATIN SMALL CAPITAL LETTER A WITH ACUTE +0102;Abreve;LATIN CAPITAL LETTER A WITH BREVE +00C2;Acircumflex;LATIN CAPITAL LETTER A WITH CIRCUMFLEX +F7E2;Acircumflexsmall;LATIN SMALL CAPITAL LETTER A WITH CIRCUMFLEX +F6C9;Acute;CAPITAL ACUTE ACCENT +F7B4;Acutesmall;SMALL CAPITAL ACUTE ACCENT +00C4;Adieresis;LATIN CAPITAL LETTER A WITH DIAERESIS +F7E4;Adieresissmall;LATIN SMALL CAPITAL LETTER A WITH DIAERESIS +00C0;Agrave;LATIN CAPITAL LETTER A WITH GRAVE +F7E0;Agravesmall;LATIN SMALL CAPITAL LETTER A WITH GRAVE +0391;Alpha;GREEK CAPITAL LETTER ALPHA +0386;Alphatonos;GREEK CAPITAL LETTER ALPHA WITH TONOS +0100;Amacron;LATIN CAPITAL LETTER A WITH MACRON +0104;Aogonek;LATIN CAPITAL LETTER A WITH OGONEK +00C5;Aring;LATIN CAPITAL LETTER A WITH RING ABOVE +01FA;Aringacute;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +F7E5;Aringsmall;LATIN SMALL CAPITAL LETTER A WITH RING ABOVE +F761;Asmall;LATIN SMALL CAPITAL LETTER A +00C3;Atilde;LATIN CAPITAL LETTER A WITH TILDE +F7E3;Atildesmall;LATIN SMALL CAPITAL LETTER A WITH TILDE +0042;B;LATIN CAPITAL LETTER B +0392;Beta;GREEK CAPITAL LETTER BETA +F6F4;Brevesmall;SMALL CAPITAL BREVE +F762;Bsmall;LATIN SMALL CAPITAL LETTER B +0043;C;LATIN CAPITAL LETTER C +0106;Cacute;LATIN CAPITAL LETTER C WITH ACUTE +F6CA;Caron;CAPITAL CARON +F6F5;Caronsmall;SMALL CAPITAL CARON +010C;Ccaron;LATIN CAPITAL LETTER C WITH CARON +00C7;Ccedilla;LATIN CAPITAL LETTER C WITH CEDILLA +F7E7;Ccedillasmall;LATIN SMALL CAPITAL LETTER C WITH CEDILLA +0108;Ccircumflex;LATIN CAPITAL LETTER C WITH CIRCUMFLEX +010A;Cdotaccent;LATIN CAPITAL LETTER C WITH DOT ABOVE +F7B8;Cedillasmall;SMALL CAPITAL CEDILLA +03A7;Chi;GREEK CAPITAL LETTER CHI +F6F6;Circumflexsmall;SMALL CAPITAL MODIFIER LETTER CIRCUMFLEX ACCENT +F763;Csmall;LATIN SMALL CAPITAL LETTER C +0044;D;LATIN CAPITAL LETTER D +010E;Dcaron;LATIN CAPITAL LETTER D WITH CARON +0110;Dcroat;LATIN CAPITAL LETTER D WITH STROKE +2206;Delta;INCREMENT +0394;Delta;GREEK CAPITAL LETTER DELTA;Duplicate +F6CB;Dieresis;CAPITAL DIAERESIS +F6CC;DieresisAcute;CAPITAL DIAERESIS ACUTE ACCENT +F6CD;DieresisGrave;CAPITAL DIAERESIS GRAVE ACCENT +F7A8;Dieresissmall;SMALL CAPITAL DIAERESIS +F6F7;Dotaccentsmall;SMALL CAPITAL DOT ABOVE +F764;Dsmall;LATIN SMALL CAPITAL LETTER D +0045;E;LATIN CAPITAL LETTER E +00C9;Eacute;LATIN CAPITAL LETTER E WITH ACUTE +F7E9;Eacutesmall;LATIN SMALL CAPITAL LETTER E WITH ACUTE +0114;Ebreve;LATIN CAPITAL LETTER E WITH BREVE +011A;Ecaron;LATIN CAPITAL LETTER E WITH CARON +00CA;Ecircumflex;LATIN CAPITAL LETTER E WITH CIRCUMFLEX +F7EA;Ecircumflexsmall;LATIN SMALL CAPITAL LETTER E WITH CIRCUMFLEX +00CB;Edieresis;LATIN CAPITAL LETTER E WITH DIAERESIS +F7EB;Edieresissmall;LATIN SMALL CAPITAL LETTER E WITH DIAERESIS +0116;Edotaccent;LATIN CAPITAL LETTER E WITH DOT ABOVE +00C8;Egrave;LATIN CAPITAL LETTER E WITH GRAVE +F7E8;Egravesmall;LATIN SMALL CAPITAL LETTER E WITH GRAVE +0112;Emacron;LATIN CAPITAL LETTER E WITH MACRON +014A;Eng;LATIN CAPITAL LETTER ENG +0118;Eogonek;LATIN CAPITAL LETTER E WITH OGONEK +0395;Epsilon;GREEK CAPITAL LETTER EPSILON +0388;Epsilontonos;GREEK CAPITAL LETTER EPSILON WITH TONOS +F765;Esmall;LATIN SMALL CAPITAL LETTER E +0397;Eta;GREEK CAPITAL LETTER ETA +0389;Etatonos;GREEK CAPITAL LETTER ETA WITH TONOS +00D0;Eth;LATIN CAPITAL LETTER ETH +F7F0;Ethsmall;LATIN SMALL CAPITAL LETTER ETH +20AC;Euro;EURO SIGN +0046;F;LATIN CAPITAL LETTER F +F766;Fsmall;LATIN SMALL CAPITAL LETTER F +0047;G;LATIN CAPITAL LETTER G +0393;Gamma;GREEK CAPITAL LETTER GAMMA +011E;Gbreve;LATIN CAPITAL LETTER G WITH BREVE +01E6;Gcaron;LATIN CAPITAL LETTER G WITH CARON +011C;Gcircumflex;LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0122;Gcommaaccent;LATIN CAPITAL LETTER G WITH CEDILLA +0120;Gdotaccent;LATIN CAPITAL LETTER G WITH DOT ABOVE +F6CE;Grave;CAPITAL GRAVE ACCENT +F760;Gravesmall;SMALL CAPITAL GRAVE ACCENT +F767;Gsmall;LATIN SMALL CAPITAL LETTER G +0048;H;LATIN CAPITAL LETTER H +25CF;H18533;BLACK CIRCLE +25AA;H18543;BLACK SMALL SQUARE +25AB;H18551;WHITE SMALL SQUARE +25A1;H22073;WHITE SQUARE +0126;Hbar;LATIN CAPITAL LETTER H WITH STROKE +0124;Hcircumflex;LATIN CAPITAL LETTER H WITH CIRCUMFLEX +F768;Hsmall;LATIN SMALL CAPITAL LETTER H +F6CF;Hungarumlaut;CAPITAL DOUBLE ACUTE ACCENT +F6F8;Hungarumlautsmall;SMALL CAPITAL DOUBLE ACUTE ACCENT +0049;I;LATIN CAPITAL LETTER I +0132;IJ;LATIN CAPITAL LIGATURE IJ +00CD;Iacute;LATIN CAPITAL LETTER I WITH ACUTE +F7ED;Iacutesmall;LATIN SMALL CAPITAL LETTER I WITH ACUTE +012C;Ibreve;LATIN CAPITAL LETTER I WITH BREVE +00CE;Icircumflex;LATIN CAPITAL LETTER I WITH CIRCUMFLEX +F7EE;Icircumflexsmall;LATIN SMALL CAPITAL LETTER I WITH CIRCUMFLEX +00CF;Idieresis;LATIN CAPITAL LETTER I WITH DIAERESIS +F7EF;Idieresissmall;LATIN SMALL CAPITAL LETTER I WITH DIAERESIS +0130;Idotaccent;LATIN CAPITAL LETTER I WITH DOT ABOVE +2111;Ifraktur;BLACK-LETTER CAPITAL I +00CC;Igrave;LATIN CAPITAL LETTER I WITH GRAVE +F7EC;Igravesmall;LATIN SMALL CAPITAL LETTER I WITH GRAVE +012A;Imacron;LATIN CAPITAL LETTER I WITH MACRON +012E;Iogonek;LATIN CAPITAL LETTER I WITH OGONEK +0399;Iota;GREEK CAPITAL LETTER IOTA +03AA;Iotadieresis;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +038A;Iotatonos;GREEK CAPITAL LETTER IOTA WITH TONOS +F769;Ismall;LATIN SMALL CAPITAL LETTER I +0128;Itilde;LATIN CAPITAL LETTER I WITH TILDE +004A;J;LATIN CAPITAL LETTER J +0134;Jcircumflex;LATIN CAPITAL LETTER J WITH CIRCUMFLEX +F76A;Jsmall;LATIN SMALL CAPITAL LETTER J +004B;K;LATIN CAPITAL LETTER K +039A;Kappa;GREEK CAPITAL LETTER KAPPA +0136;Kcommaaccent;LATIN CAPITAL LETTER K WITH CEDILLA +F76B;Ksmall;LATIN SMALL CAPITAL LETTER K +004C;L;LATIN CAPITAL LETTER L +F6BF;LL;LATIN CAPITAL LETTER LL +0139;Lacute;LATIN CAPITAL LETTER L WITH ACUTE +039B;Lambda;GREEK CAPITAL LETTER LAMDA +013D;Lcaron;LATIN CAPITAL LETTER L WITH CARON +013B;Lcommaaccent;LATIN CAPITAL LETTER L WITH CEDILLA +013F;Ldot;LATIN CAPITAL LETTER L WITH MIDDLE DOT +0141;Lslash;LATIN CAPITAL LETTER L WITH STROKE +F6F9;Lslashsmall;LATIN SMALL CAPITAL LETTER L WITH STROKE +F76C;Lsmall;LATIN SMALL CAPITAL LETTER L +004D;M;LATIN CAPITAL LETTER M +F6D0;Macron;CAPITAL MACRON +F7AF;Macronsmall;SMALL CAPITAL MACRON +F76D;Msmall;LATIN SMALL CAPITAL LETTER M +039C;Mu;GREEK CAPITAL LETTER MU +004E;N;LATIN CAPITAL LETTER N +0143;Nacute;LATIN CAPITAL LETTER N WITH ACUTE +0147;Ncaron;LATIN CAPITAL LETTER N WITH CARON +0145;Ncommaaccent;LATIN CAPITAL LETTER N WITH CEDILLA +F76E;Nsmall;LATIN SMALL CAPITAL LETTER N +00D1;Ntilde;LATIN CAPITAL LETTER N WITH TILDE +F7F1;Ntildesmall;LATIN SMALL CAPITAL LETTER N WITH TILDE +039D;Nu;GREEK CAPITAL LETTER NU +004F;O;LATIN CAPITAL LETTER O +0152;OE;LATIN CAPITAL LIGATURE OE +F6FA;OEsmall;LATIN SMALL CAPITAL LIGATURE OE +00D3;Oacute;LATIN CAPITAL LETTER O WITH ACUTE +F7F3;Oacutesmall;LATIN SMALL CAPITAL LETTER O WITH ACUTE +014E;Obreve;LATIN CAPITAL LETTER O WITH BREVE +00D4;Ocircumflex;LATIN CAPITAL LETTER O WITH CIRCUMFLEX +F7F4;Ocircumflexsmall;LATIN SMALL CAPITAL LETTER O WITH CIRCUMFLEX +00D6;Odieresis;LATIN CAPITAL LETTER O WITH DIAERESIS +F7F6;Odieresissmall;LATIN SMALL CAPITAL LETTER O WITH DIAERESIS +F6FB;Ogoneksmall;SMALL CAPITAL OGONEK +00D2;Ograve;LATIN CAPITAL LETTER O WITH GRAVE +F7F2;Ogravesmall;LATIN SMALL CAPITAL LETTER O WITH GRAVE +01A0;Ohorn;LATIN CAPITAL LETTER O WITH HORN +0150;Ohungarumlaut;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +014C;Omacron;LATIN CAPITAL LETTER O WITH MACRON +2126;Omega;OHM SIGN +03A9;Omega;GREEK CAPITAL LETTER OMEGA;Duplicate +038F;Omegatonos;GREEK CAPITAL LETTER OMEGA WITH TONOS +039F;Omicron;GREEK CAPITAL LETTER OMICRON +038C;Omicrontonos;GREEK CAPITAL LETTER OMICRON WITH TONOS +00D8;Oslash;LATIN CAPITAL LETTER O WITH STROKE +01FE;Oslashacute;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +F7F8;Oslashsmall;LATIN SMALL CAPITAL LETTER O WITH STROKE +F76F;Osmall;LATIN SMALL CAPITAL LETTER O +00D5;Otilde;LATIN CAPITAL LETTER O WITH TILDE +F7F5;Otildesmall;LATIN SMALL CAPITAL LETTER O WITH TILDE +0050;P;LATIN CAPITAL LETTER P +03A6;Phi;GREEK CAPITAL LETTER PHI +03A0;Pi;GREEK CAPITAL LETTER PI +03A8;Psi;GREEK CAPITAL LETTER PSI +F770;Psmall;LATIN SMALL CAPITAL LETTER P +0051;Q;LATIN CAPITAL LETTER Q +F771;Qsmall;LATIN SMALL CAPITAL LETTER Q +0052;R;LATIN CAPITAL LETTER R +0154;Racute;LATIN CAPITAL LETTER R WITH ACUTE +0158;Rcaron;LATIN CAPITAL LETTER R WITH CARON +0156;Rcommaaccent;LATIN CAPITAL LETTER R WITH CEDILLA +211C;Rfraktur;BLACK-LETTER CAPITAL R +03A1;Rho;GREEK CAPITAL LETTER RHO +F6FC;Ringsmall;SMALL CAPITAL RING ABOVE +F772;Rsmall;LATIN SMALL CAPITAL LETTER R +0053;S;LATIN CAPITAL LETTER S +250C;SF010000;BOX DRAWINGS LIGHT DOWN AND RIGHT +2514;SF020000;BOX DRAWINGS LIGHT UP AND RIGHT +2510;SF030000;BOX DRAWINGS LIGHT DOWN AND LEFT +2518;SF040000;BOX DRAWINGS LIGHT UP AND LEFT +253C;SF050000;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +252C;SF060000;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +2534;SF070000;BOX DRAWINGS LIGHT UP AND HORIZONTAL +251C;SF080000;BOX DRAWINGS LIGHT VERTICAL AND RIGHT +2524;SF090000;BOX DRAWINGS LIGHT VERTICAL AND LEFT +2500;SF100000;BOX DRAWINGS LIGHT HORIZONTAL +2502;SF110000;BOX DRAWINGS LIGHT VERTICAL +2561;SF190000;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +2562;SF200000;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +2556;SF210000;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +2555;SF220000;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +2563;SF230000;BOX DRAWINGS DOUBLE VERTICAL AND LEFT +2551;SF240000;BOX DRAWINGS DOUBLE VERTICAL +2557;SF250000;BOX DRAWINGS DOUBLE DOWN AND LEFT +255D;SF260000;BOX DRAWINGS DOUBLE UP AND LEFT +255C;SF270000;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +255B;SF280000;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +255E;SF360000;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +255F;SF370000;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +255A;SF380000;BOX DRAWINGS DOUBLE UP AND RIGHT +2554;SF390000;BOX DRAWINGS DOUBLE DOWN AND RIGHT +2569;SF400000;BOX DRAWINGS DOUBLE UP AND HORIZONTAL +2566;SF410000;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +2560;SF420000;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +2550;SF430000;BOX DRAWINGS DOUBLE HORIZONTAL +256C;SF440000;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +2567;SF450000;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +2568;SF460000;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +2564;SF470000;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +2565;SF480000;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +2559;SF490000;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +2558;SF500000;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +2552;SF510000;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +2553;SF520000;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +256B;SF530000;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +256A;SF540000;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +015A;Sacute;LATIN CAPITAL LETTER S WITH ACUTE +0160;Scaron;LATIN CAPITAL LETTER S WITH CARON +F6FD;Scaronsmall;LATIN SMALL CAPITAL LETTER S WITH CARON +015E;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA +F6C1;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA;Duplicate +015C;Scircumflex;LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0218;Scommaaccent;LATIN CAPITAL LETTER S WITH COMMA BELOW +03A3;Sigma;GREEK CAPITAL LETTER SIGMA +F773;Ssmall;LATIN SMALL CAPITAL LETTER S +0054;T;LATIN CAPITAL LETTER T +03A4;Tau;GREEK CAPITAL LETTER TAU +0166;Tbar;LATIN CAPITAL LETTER T WITH STROKE +0164;Tcaron;LATIN CAPITAL LETTER T WITH CARON +0162;Tcommaaccent;LATIN CAPITAL LETTER T WITH CEDILLA +021A;Tcommaaccent;LATIN CAPITAL LETTER T WITH COMMA BELOW;Duplicate +0398;Theta;GREEK CAPITAL LETTER THETA +00DE;Thorn;LATIN CAPITAL LETTER THORN +F7FE;Thornsmall;LATIN SMALL CAPITAL LETTER THORN +F6FE;Tildesmall;SMALL CAPITAL SMALL TILDE +F774;Tsmall;LATIN SMALL CAPITAL LETTER T +0055;U;LATIN CAPITAL LETTER U +00DA;Uacute;LATIN CAPITAL LETTER U WITH ACUTE +F7FA;Uacutesmall;LATIN SMALL CAPITAL LETTER U WITH ACUTE +016C;Ubreve;LATIN CAPITAL LETTER U WITH BREVE +00DB;Ucircumflex;LATIN CAPITAL LETTER U WITH CIRCUMFLEX +F7FB;Ucircumflexsmall;LATIN SMALL CAPITAL LETTER U WITH CIRCUMFLEX +00DC;Udieresis;LATIN CAPITAL LETTER U WITH DIAERESIS +F7FC;Udieresissmall;LATIN SMALL CAPITAL LETTER U WITH DIAERESIS +00D9;Ugrave;LATIN CAPITAL LETTER U WITH GRAVE +F7F9;Ugravesmall;LATIN SMALL CAPITAL LETTER U WITH GRAVE +01AF;Uhorn;LATIN CAPITAL LETTER U WITH HORN +0170;Uhungarumlaut;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +016A;Umacron;LATIN CAPITAL LETTER U WITH MACRON +0172;Uogonek;LATIN CAPITAL LETTER U WITH OGONEK +03A5;Upsilon;GREEK CAPITAL LETTER UPSILON +03D2;Upsilon1;GREEK UPSILON WITH HOOK SYMBOL +03AB;Upsilondieresis;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +038E;Upsilontonos;GREEK CAPITAL LETTER UPSILON WITH TONOS +016E;Uring;LATIN CAPITAL LETTER U WITH RING ABOVE +F775;Usmall;LATIN SMALL CAPITAL LETTER U +0168;Utilde;LATIN CAPITAL LETTER U WITH TILDE +0056;V;LATIN CAPITAL LETTER V +F776;Vsmall;LATIN SMALL CAPITAL LETTER V +0057;W;LATIN CAPITAL LETTER W +1E82;Wacute;LATIN CAPITAL LETTER W WITH ACUTE +0174;Wcircumflex;LATIN CAPITAL LETTER W WITH CIRCUMFLEX +1E84;Wdieresis;LATIN CAPITAL LETTER W WITH DIAERESIS +1E80;Wgrave;LATIN CAPITAL LETTER W WITH GRAVE +F777;Wsmall;LATIN SMALL CAPITAL LETTER W +0058;X;LATIN CAPITAL LETTER X +039E;Xi;GREEK CAPITAL LETTER XI +F778;Xsmall;LATIN SMALL CAPITAL LETTER X +0059;Y;LATIN CAPITAL LETTER Y +00DD;Yacute;LATIN CAPITAL LETTER Y WITH ACUTE +F7FD;Yacutesmall;LATIN SMALL CAPITAL LETTER Y WITH ACUTE +0176;Ycircumflex;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0178;Ydieresis;LATIN CAPITAL LETTER Y WITH DIAERESIS +F7FF;Ydieresissmall;LATIN SMALL CAPITAL LETTER Y WITH DIAERESIS +1EF2;Ygrave;LATIN CAPITAL LETTER Y WITH GRAVE +F779;Ysmall;LATIN SMALL CAPITAL LETTER Y +005A;Z;LATIN CAPITAL LETTER Z +0179;Zacute;LATIN CAPITAL LETTER Z WITH ACUTE +017D;Zcaron;LATIN CAPITAL LETTER Z WITH CARON +F6FF;Zcaronsmall;LATIN SMALL CAPITAL LETTER Z WITH CARON +017B;Zdotaccent;LATIN CAPITAL LETTER Z WITH DOT ABOVE +0396;Zeta;GREEK CAPITAL LETTER ZETA +F77A;Zsmall;LATIN SMALL CAPITAL LETTER Z +0061;a;LATIN SMALL LETTER A +00E1;aacute;LATIN SMALL LETTER A WITH ACUTE +0103;abreve;LATIN SMALL LETTER A WITH BREVE +00E2;acircumflex;LATIN SMALL LETTER A WITH CIRCUMFLEX +00B4;acute;ACUTE ACCENT +0301;acutecomb;COMBINING ACUTE ACCENT +00E4;adieresis;LATIN SMALL LETTER A WITH DIAERESIS +00E6;ae;LATIN SMALL LETTER AE +01FD;aeacute;LATIN SMALL LETTER AE WITH ACUTE +2015;afii00208;HORIZONTAL BAR +0410;afii10017;CYRILLIC CAPITAL LETTER A +0411;afii10018;CYRILLIC CAPITAL LETTER BE +0412;afii10019;CYRILLIC CAPITAL LETTER VE +0413;afii10020;CYRILLIC CAPITAL LETTER GHE +0414;afii10021;CYRILLIC CAPITAL LETTER DE +0415;afii10022;CYRILLIC CAPITAL LETTER IE +0401;afii10023;CYRILLIC CAPITAL LETTER IO +0416;afii10024;CYRILLIC CAPITAL LETTER ZHE +0417;afii10025;CYRILLIC CAPITAL LETTER ZE +0418;afii10026;CYRILLIC CAPITAL LETTER I +0419;afii10027;CYRILLIC CAPITAL LETTER SHORT I +041A;afii10028;CYRILLIC CAPITAL LETTER KA +041B;afii10029;CYRILLIC CAPITAL LETTER EL +041C;afii10030;CYRILLIC CAPITAL LETTER EM +041D;afii10031;CYRILLIC CAPITAL LETTER EN +041E;afii10032;CYRILLIC CAPITAL LETTER O +041F;afii10033;CYRILLIC CAPITAL LETTER PE +0420;afii10034;CYRILLIC CAPITAL LETTER ER +0421;afii10035;CYRILLIC CAPITAL LETTER ES +0422;afii10036;CYRILLIC CAPITAL LETTER TE +0423;afii10037;CYRILLIC CAPITAL LETTER U +0424;afii10038;CYRILLIC CAPITAL LETTER EF +0425;afii10039;CYRILLIC CAPITAL LETTER HA +0426;afii10040;CYRILLIC CAPITAL LETTER TSE +0427;afii10041;CYRILLIC CAPITAL LETTER CHE +0428;afii10042;CYRILLIC CAPITAL LETTER SHA +0429;afii10043;CYRILLIC CAPITAL LETTER SHCHA +042A;afii10044;CYRILLIC CAPITAL LETTER HARD SIGN +042B;afii10045;CYRILLIC CAPITAL LETTER YERU +042C;afii10046;CYRILLIC CAPITAL LETTER SOFT SIGN +042D;afii10047;CYRILLIC CAPITAL LETTER E +042E;afii10048;CYRILLIC CAPITAL LETTER YU +042F;afii10049;CYRILLIC CAPITAL LETTER YA +0490;afii10050;CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0402;afii10051;CYRILLIC CAPITAL LETTER DJE +0403;afii10052;CYRILLIC CAPITAL LETTER GJE +0404;afii10053;CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405;afii10054;CYRILLIC CAPITAL LETTER DZE +0406;afii10055;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407;afii10056;CYRILLIC CAPITAL LETTER YI +0408;afii10057;CYRILLIC CAPITAL LETTER JE +0409;afii10058;CYRILLIC CAPITAL LETTER LJE +040A;afii10059;CYRILLIC CAPITAL LETTER NJE +040B;afii10060;CYRILLIC CAPITAL LETTER TSHE +040C;afii10061;CYRILLIC CAPITAL LETTER KJE +040E;afii10062;CYRILLIC CAPITAL LETTER SHORT U +F6C4;afii10063;CYRILLIC SMALL LETTER GHE VARIANT +F6C5;afii10064;CYRILLIC SMALL LETTER BE VARIANT +0430;afii10065;CYRILLIC SMALL LETTER A +0431;afii10066;CYRILLIC SMALL LETTER BE +0432;afii10067;CYRILLIC SMALL LETTER VE +0433;afii10068;CYRILLIC SMALL LETTER GHE +0434;afii10069;CYRILLIC SMALL LETTER DE +0435;afii10070;CYRILLIC SMALL LETTER IE +0451;afii10071;CYRILLIC SMALL LETTER IO +0436;afii10072;CYRILLIC SMALL LETTER ZHE +0437;afii10073;CYRILLIC SMALL LETTER ZE +0438;afii10074;CYRILLIC SMALL LETTER I +0439;afii10075;CYRILLIC SMALL LETTER SHORT I +043A;afii10076;CYRILLIC SMALL LETTER KA +043B;afii10077;CYRILLIC SMALL LETTER EL +043C;afii10078;CYRILLIC SMALL LETTER EM +043D;afii10079;CYRILLIC SMALL LETTER EN +043E;afii10080;CYRILLIC SMALL LETTER O +043F;afii10081;CYRILLIC SMALL LETTER PE +0440;afii10082;CYRILLIC SMALL LETTER ER +0441;afii10083;CYRILLIC SMALL LETTER ES +0442;afii10084;CYRILLIC SMALL LETTER TE +0443;afii10085;CYRILLIC SMALL LETTER U +0444;afii10086;CYRILLIC SMALL LETTER EF +0445;afii10087;CYRILLIC SMALL LETTER HA +0446;afii10088;CYRILLIC SMALL LETTER TSE +0447;afii10089;CYRILLIC SMALL LETTER CHE +0448;afii10090;CYRILLIC SMALL LETTER SHA +0449;afii10091;CYRILLIC SMALL LETTER SHCHA +044A;afii10092;CYRILLIC SMALL LETTER HARD SIGN +044B;afii10093;CYRILLIC SMALL LETTER YERU +044C;afii10094;CYRILLIC SMALL LETTER SOFT SIGN +044D;afii10095;CYRILLIC SMALL LETTER E +044E;afii10096;CYRILLIC SMALL LETTER YU +044F;afii10097;CYRILLIC SMALL LETTER YA +0491;afii10098;CYRILLIC SMALL LETTER GHE WITH UPTURN +0452;afii10099;CYRILLIC SMALL LETTER DJE +0453;afii10100;CYRILLIC SMALL LETTER GJE +0454;afii10101;CYRILLIC SMALL LETTER UKRAINIAN IE +0455;afii10102;CYRILLIC SMALL LETTER DZE +0456;afii10103;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0457;afii10104;CYRILLIC SMALL LETTER YI +0458;afii10105;CYRILLIC SMALL LETTER JE +0459;afii10106;CYRILLIC SMALL LETTER LJE +045A;afii10107;CYRILLIC SMALL LETTER NJE +045B;afii10108;CYRILLIC SMALL LETTER TSHE +045C;afii10109;CYRILLIC SMALL LETTER KJE +045E;afii10110;CYRILLIC SMALL LETTER SHORT U +040F;afii10145;CYRILLIC CAPITAL LETTER DZHE +0462;afii10146;CYRILLIC CAPITAL LETTER YAT +0472;afii10147;CYRILLIC CAPITAL LETTER FITA +0474;afii10148;CYRILLIC CAPITAL LETTER IZHITSA +F6C6;afii10192;CYRILLIC SMALL LETTER DE VARIANT +045F;afii10193;CYRILLIC SMALL LETTER DZHE +0463;afii10194;CYRILLIC SMALL LETTER YAT +0473;afii10195;CYRILLIC SMALL LETTER FITA +0475;afii10196;CYRILLIC SMALL LETTER IZHITSA +F6C7;afii10831;CYRILLIC SMALL LETTER PE VARIANT +F6C8;afii10832;CYRILLIC SMALL LETTER TE VARIANT +04D9;afii10846;CYRILLIC SMALL LETTER SCHWA +200E;afii299;LEFT-TO-RIGHT MARK +200F;afii300;RIGHT-TO-LEFT MARK +200D;afii301;ZERO WIDTH JOINER +066A;afii57381;ARABIC PERCENT SIGN +060C;afii57388;ARABIC COMMA +0660;afii57392;ARABIC-INDIC DIGIT ZERO +0661;afii57393;ARABIC-INDIC DIGIT ONE +0662;afii57394;ARABIC-INDIC DIGIT TWO +0663;afii57395;ARABIC-INDIC DIGIT THREE +0664;afii57396;ARABIC-INDIC DIGIT FOUR +0665;afii57397;ARABIC-INDIC DIGIT FIVE +0666;afii57398;ARABIC-INDIC DIGIT SIX +0667;afii57399;ARABIC-INDIC DIGIT SEVEN +0668;afii57400;ARABIC-INDIC DIGIT EIGHT +0669;afii57401;ARABIC-INDIC DIGIT NINE +061B;afii57403;ARABIC SEMICOLON +061F;afii57407;ARABIC QUESTION MARK +0621;afii57409;ARABIC LETTER HAMZA +0622;afii57410;ARABIC LETTER ALEF WITH MADDA ABOVE +0623;afii57411;ARABIC LETTER ALEF WITH HAMZA ABOVE +0624;afii57412;ARABIC LETTER WAW WITH HAMZA ABOVE +0625;afii57413;ARABIC LETTER ALEF WITH HAMZA BELOW +0626;afii57414;ARABIC LETTER YEH WITH HAMZA ABOVE +0627;afii57415;ARABIC LETTER ALEF +0628;afii57416;ARABIC LETTER BEH +0629;afii57417;ARABIC LETTER TEH MARBUTA +062A;afii57418;ARABIC LETTER TEH +062B;afii57419;ARABIC LETTER THEH +062C;afii57420;ARABIC LETTER JEEM +062D;afii57421;ARABIC LETTER HAH +062E;afii57422;ARABIC LETTER KHAH +062F;afii57423;ARABIC LETTER DAL +0630;afii57424;ARABIC LETTER THAL +0631;afii57425;ARABIC LETTER REH +0632;afii57426;ARABIC LETTER ZAIN +0633;afii57427;ARABIC LETTER SEEN +0634;afii57428;ARABIC LETTER SHEEN +0635;afii57429;ARABIC LETTER SAD +0636;afii57430;ARABIC LETTER DAD +0637;afii57431;ARABIC LETTER TAH +0638;afii57432;ARABIC LETTER ZAH +0639;afii57433;ARABIC LETTER AIN +063A;afii57434;ARABIC LETTER GHAIN +0640;afii57440;ARABIC TATWEEL +0641;afii57441;ARABIC LETTER FEH +0642;afii57442;ARABIC LETTER QAF +0643;afii57443;ARABIC LETTER KAF +0644;afii57444;ARABIC LETTER LAM +0645;afii57445;ARABIC LETTER MEEM +0646;afii57446;ARABIC LETTER NOON +0648;afii57448;ARABIC LETTER WAW +0649;afii57449;ARABIC LETTER ALEF MAKSURA +064A;afii57450;ARABIC LETTER YEH +064B;afii57451;ARABIC FATHATAN +064C;afii57452;ARABIC DAMMATAN +064D;afii57453;ARABIC KASRATAN +064E;afii57454;ARABIC FATHA +064F;afii57455;ARABIC DAMMA +0650;afii57456;ARABIC KASRA +0651;afii57457;ARABIC SHADDA +0652;afii57458;ARABIC SUKUN +0647;afii57470;ARABIC LETTER HEH +06A4;afii57505;ARABIC LETTER VEH +067E;afii57506;ARABIC LETTER PEH +0686;afii57507;ARABIC LETTER TCHEH +0698;afii57508;ARABIC LETTER JEH +06AF;afii57509;ARABIC LETTER GAF +0679;afii57511;ARABIC LETTER TTEH +0688;afii57512;ARABIC LETTER DDAL +0691;afii57513;ARABIC LETTER RREH +06BA;afii57514;ARABIC LETTER NOON GHUNNA +06D2;afii57519;ARABIC LETTER YEH BARREE +06D5;afii57534;ARABIC LETTER AE +20AA;afii57636;NEW SHEQEL SIGN +05BE;afii57645;HEBREW PUNCTUATION MAQAF +05C3;afii57658;HEBREW PUNCTUATION SOF PASUQ +05D0;afii57664;HEBREW LETTER ALEF +05D1;afii57665;HEBREW LETTER BET +05D2;afii57666;HEBREW LETTER GIMEL +05D3;afii57667;HEBREW LETTER DALET +05D4;afii57668;HEBREW LETTER HE +05D5;afii57669;HEBREW LETTER VAV +05D6;afii57670;HEBREW LETTER ZAYIN +05D7;afii57671;HEBREW LETTER HET +05D8;afii57672;HEBREW LETTER TET +05D9;afii57673;HEBREW LETTER YOD +05DA;afii57674;HEBREW LETTER FINAL KAF +05DB;afii57675;HEBREW LETTER KAF +05DC;afii57676;HEBREW LETTER LAMED +05DD;afii57677;HEBREW LETTER FINAL MEM +05DE;afii57678;HEBREW LETTER MEM +05DF;afii57679;HEBREW LETTER FINAL NUN +05E0;afii57680;HEBREW LETTER NUN +05E1;afii57681;HEBREW LETTER SAMEKH +05E2;afii57682;HEBREW LETTER AYIN +05E3;afii57683;HEBREW LETTER FINAL PE +05E4;afii57684;HEBREW LETTER PE +05E5;afii57685;HEBREW LETTER FINAL TSADI +05E6;afii57686;HEBREW LETTER TSADI +05E7;afii57687;HEBREW LETTER QOF +05E8;afii57688;HEBREW LETTER RESH +05E9;afii57689;HEBREW LETTER SHIN +05EA;afii57690;HEBREW LETTER TAV +FB2A;afii57694;HEBREW LETTER SHIN WITH SHIN DOT +FB2B;afii57695;HEBREW LETTER SHIN WITH SIN DOT +FB4B;afii57700;HEBREW LETTER VAV WITH HOLAM +FB1F;afii57705;HEBREW LIGATURE YIDDISH YOD YOD PATAH +05F0;afii57716;HEBREW LIGATURE YIDDISH DOUBLE VAV +05F1;afii57717;HEBREW LIGATURE YIDDISH VAV YOD +05F2;afii57718;HEBREW LIGATURE YIDDISH DOUBLE YOD +FB35;afii57723;HEBREW LETTER VAV WITH DAGESH +05B4;afii57793;HEBREW POINT HIRIQ +05B5;afii57794;HEBREW POINT TSERE +05B6;afii57795;HEBREW POINT SEGOL +05BB;afii57796;HEBREW POINT QUBUTS +05B8;afii57797;HEBREW POINT QAMATS +05B7;afii57798;HEBREW POINT PATAH +05B0;afii57799;HEBREW POINT SHEVA +05B2;afii57800;HEBREW POINT HATAF PATAH +05B1;afii57801;HEBREW POINT HATAF SEGOL +05B3;afii57802;HEBREW POINT HATAF QAMATS +05C2;afii57803;HEBREW POINT SIN DOT +05C1;afii57804;HEBREW POINT SHIN DOT +05B9;afii57806;HEBREW POINT HOLAM +05BC;afii57807;HEBREW POINT DAGESH OR MAPIQ +05BD;afii57839;HEBREW POINT METEG +05BF;afii57841;HEBREW POINT RAFE +05C0;afii57842;HEBREW PUNCTUATION PASEQ +02BC;afii57929;MODIFIER LETTER APOSTROPHE +2105;afii61248;CARE OF +2113;afii61289;SCRIPT SMALL L +2116;afii61352;NUMERO SIGN +202C;afii61573;POP DIRECTIONAL FORMATTING +202D;afii61574;LEFT-TO-RIGHT OVERRIDE +202E;afii61575;RIGHT-TO-LEFT OVERRIDE +200C;afii61664;ZERO WIDTH NON-JOINER +066D;afii63167;ARABIC FIVE POINTED STAR +02BD;afii64937;MODIFIER LETTER REVERSED COMMA +00E0;agrave;LATIN SMALL LETTER A WITH GRAVE +2135;aleph;ALEF SYMBOL +03B1;alpha;GREEK SMALL LETTER ALPHA +03AC;alphatonos;GREEK SMALL LETTER ALPHA WITH TONOS +0101;amacron;LATIN SMALL LETTER A WITH MACRON +0026;ampersand;AMPERSAND +F726;ampersandsmall;SMALL CAPITAL AMPERSAND +2220;angle;ANGLE +2329;angleleft;LEFT-POINTING ANGLE BRACKET +232A;angleright;RIGHT-POINTING ANGLE BRACKET +0387;anoteleia;GREEK ANO TELEIA +0105;aogonek;LATIN SMALL LETTER A WITH OGONEK +2248;approxequal;ALMOST EQUAL TO +00E5;aring;LATIN SMALL LETTER A WITH RING ABOVE +01FB;aringacute;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +2194;arrowboth;LEFT RIGHT ARROW +21D4;arrowdblboth;LEFT RIGHT DOUBLE ARROW +21D3;arrowdbldown;DOWNWARDS DOUBLE ARROW +21D0;arrowdblleft;LEFTWARDS DOUBLE ARROW +21D2;arrowdblright;RIGHTWARDS DOUBLE ARROW +21D1;arrowdblup;UPWARDS DOUBLE ARROW +2193;arrowdown;DOWNWARDS ARROW +F8E7;arrowhorizex;HORIZONTAL ARROW EXTENDER +2190;arrowleft;LEFTWARDS ARROW +2192;arrowright;RIGHTWARDS ARROW +2191;arrowup;UPWARDS ARROW +2195;arrowupdn;UP DOWN ARROW +21A8;arrowupdnbse;UP DOWN ARROW WITH BASE +F8E6;arrowvertex;VERTICAL ARROW EXTENDER +005E;asciicircum;CIRCUMFLEX ACCENT +007E;asciitilde;TILDE +002A;asterisk;ASTERISK +2217;asteriskmath;ASTERISK OPERATOR +F6E9;asuperior;SUPERSCRIPT LATIN SMALL LETTER A +0040;at;COMMERCIAL AT +00E3;atilde;LATIN SMALL LETTER A WITH TILDE +0062;b;LATIN SMALL LETTER B +005C;backslash;REVERSE SOLIDUS +007C;bar;VERTICAL LINE +03B2;beta;GREEK SMALL LETTER BETA +2588;block;FULL BLOCK +F8F4;braceex;CURLY BRACKET EXTENDER +007B;braceleft;LEFT CURLY BRACKET +F8F3;braceleftbt;LEFT CURLY BRACKET BOTTOM +F8F2;braceleftmid;LEFT CURLY BRACKET MID +F8F1;bracelefttp;LEFT CURLY BRACKET TOP +007D;braceright;RIGHT CURLY BRACKET +F8FE;bracerightbt;RIGHT CURLY BRACKET BOTTOM +F8FD;bracerightmid;RIGHT CURLY BRACKET MID +F8FC;bracerighttp;RIGHT CURLY BRACKET TOP +005B;bracketleft;LEFT SQUARE BRACKET +F8F0;bracketleftbt;LEFT SQUARE BRACKET BOTTOM +F8EF;bracketleftex;LEFT SQUARE BRACKET EXTENDER +F8EE;bracketlefttp;LEFT SQUARE BRACKET TOP +005D;bracketright;RIGHT SQUARE BRACKET +F8FB;bracketrightbt;RIGHT SQUARE BRACKET BOTTOM +F8FA;bracketrightex;RIGHT SQUARE BRACKET EXTENDER +F8F9;bracketrighttp;RIGHT SQUARE BRACKET TOP +02D8;breve;BREVE +00A6;brokenbar;BROKEN BAR +F6EA;bsuperior;SUPERSCRIPT LATIN SMALL LETTER B +2022;bullet;BULLET +0063;c;LATIN SMALL LETTER C +0107;cacute;LATIN SMALL LETTER C WITH ACUTE +02C7;caron;CARON +21B5;carriagereturn;DOWNWARDS ARROW WITH CORNER LEFTWARDS +010D;ccaron;LATIN SMALL LETTER C WITH CARON +00E7;ccedilla;LATIN SMALL LETTER C WITH CEDILLA +0109;ccircumflex;LATIN SMALL LETTER C WITH CIRCUMFLEX +010B;cdotaccent;LATIN SMALL LETTER C WITH DOT ABOVE +00B8;cedilla;CEDILLA +00A2;cent;CENT SIGN +F6DF;centinferior;SUBSCRIPT CENT SIGN +F7A2;centoldstyle;OLDSTYLE CENT SIGN +F6E0;centsuperior;SUPERSCRIPT CENT SIGN +03C7;chi;GREEK SMALL LETTER CHI +25CB;circle;WHITE CIRCLE +2297;circlemultiply;CIRCLED TIMES +2295;circleplus;CIRCLED PLUS +02C6;circumflex;MODIFIER LETTER CIRCUMFLEX ACCENT +2663;club;BLACK CLUB SUIT +003A;colon;COLON +20A1;colonmonetary;COLON SIGN +002C;comma;COMMA +F6C3;commaaccent;COMMA BELOW +F6E1;commainferior;SUBSCRIPT COMMA +F6E2;commasuperior;SUPERSCRIPT COMMA +2245;congruent;APPROXIMATELY EQUAL TO +00A9;copyright;COPYRIGHT SIGN +F8E9;copyrightsans;COPYRIGHT SIGN SANS SERIF +F6D9;copyrightserif;COPYRIGHT SIGN SERIF +00A4;currency;CURRENCY SIGN +F6D1;cyrBreve;CAPITAL CYRILLIC BREVE +F6D2;cyrFlex;CAPITAL CYRILLIC CIRCUMFLEX +F6D4;cyrbreve;CYRILLIC BREVE +F6D5;cyrflex;CYRILLIC CIRCUMFLEX +0064;d;LATIN SMALL LETTER D +2020;dagger;DAGGER +2021;daggerdbl;DOUBLE DAGGER +F6D3;dblGrave;CAPITAL DOUBLE GRAVE ACCENT +F6D6;dblgrave;DOUBLE GRAVE ACCENT +010F;dcaron;LATIN SMALL LETTER D WITH CARON +0111;dcroat;LATIN SMALL LETTER D WITH STROKE +00B0;degree;DEGREE SIGN +03B4;delta;GREEK SMALL LETTER DELTA +2666;diamond;BLACK DIAMOND SUIT +00A8;dieresis;DIAERESIS +F6D7;dieresisacute;DIAERESIS ACUTE ACCENT +F6D8;dieresisgrave;DIAERESIS GRAVE ACCENT +0385;dieresistonos;GREEK DIALYTIKA TONOS +00F7;divide;DIVISION SIGN +2593;dkshade;DARK SHADE +2584;dnblock;LOWER HALF BLOCK +0024;dollar;DOLLAR SIGN +F6E3;dollarinferior;SUBSCRIPT DOLLAR SIGN +F724;dollaroldstyle;OLDSTYLE DOLLAR SIGN +F6E4;dollarsuperior;SUPERSCRIPT DOLLAR SIGN +20AB;dong;DONG SIGN +02D9;dotaccent;DOT ABOVE +0323;dotbelowcomb;COMBINING DOT BELOW +0131;dotlessi;LATIN SMALL LETTER DOTLESS I +F6BE;dotlessj;LATIN SMALL LETTER DOTLESS J +22C5;dotmath;DOT OPERATOR +F6EB;dsuperior;SUPERSCRIPT LATIN SMALL LETTER D +0065;e;LATIN SMALL LETTER E +00E9;eacute;LATIN SMALL LETTER E WITH ACUTE +0115;ebreve;LATIN SMALL LETTER E WITH BREVE +011B;ecaron;LATIN SMALL LETTER E WITH CARON +00EA;ecircumflex;LATIN SMALL LETTER E WITH CIRCUMFLEX +00EB;edieresis;LATIN SMALL LETTER E WITH DIAERESIS +0117;edotaccent;LATIN SMALL LETTER E WITH DOT ABOVE +00E8;egrave;LATIN SMALL LETTER E WITH GRAVE +0038;eight;DIGIT EIGHT +2088;eightinferior;SUBSCRIPT EIGHT +F738;eightoldstyle;OLDSTYLE DIGIT EIGHT +2078;eightsuperior;SUPERSCRIPT EIGHT +2208;element;ELEMENT OF +2026;ellipsis;HORIZONTAL ELLIPSIS +0113;emacron;LATIN SMALL LETTER E WITH MACRON +2014;emdash;EM DASH +2205;emptyset;EMPTY SET +2013;endash;EN DASH +014B;eng;LATIN SMALL LETTER ENG +0119;eogonek;LATIN SMALL LETTER E WITH OGONEK +03B5;epsilon;GREEK SMALL LETTER EPSILON +03AD;epsilontonos;GREEK SMALL LETTER EPSILON WITH TONOS +003D;equal;EQUALS SIGN +2261;equivalence;IDENTICAL TO +212E;estimated;ESTIMATED SYMBOL +F6EC;esuperior;SUPERSCRIPT LATIN SMALL LETTER E +03B7;eta;GREEK SMALL LETTER ETA +03AE;etatonos;GREEK SMALL LETTER ETA WITH TONOS +00F0;eth;LATIN SMALL LETTER ETH +0021;exclam;EXCLAMATION MARK +203C;exclamdbl;DOUBLE EXCLAMATION MARK +00A1;exclamdown;INVERTED EXCLAMATION MARK +F7A1;exclamdownsmall;SMALL CAPITAL INVERTED EXCLAMATION MARK +F721;exclamsmall;SMALL CAPITAL EXCLAMATION MARK +2203;existential;THERE EXISTS +0066;f;LATIN SMALL LETTER F +2640;female;FEMALE SIGN +FB00;ff;LATIN SMALL LIGATURE FF +FB03;ffi;LATIN SMALL LIGATURE FFI +FB04;ffl;LATIN SMALL LIGATURE FFL +FB01;fi;LATIN SMALL LIGATURE FI +2012;figuredash;FIGURE DASH +25A0;filledbox;BLACK SQUARE +25AC;filledrect;BLACK RECTANGLE +0035;five;DIGIT FIVE +215D;fiveeighths;VULGAR FRACTION FIVE EIGHTHS +2085;fiveinferior;SUBSCRIPT FIVE +F735;fiveoldstyle;OLDSTYLE DIGIT FIVE +2075;fivesuperior;SUPERSCRIPT FIVE +FB02;fl;LATIN SMALL LIGATURE FL +0192;florin;LATIN SMALL LETTER F WITH HOOK +0034;four;DIGIT FOUR +2084;fourinferior;SUBSCRIPT FOUR +F734;fouroldstyle;OLDSTYLE DIGIT FOUR +2074;foursuperior;SUPERSCRIPT FOUR +2044;fraction;FRACTION SLASH +2215;fraction;DIVISION SLASH;Duplicate +20A3;franc;FRENCH FRANC SIGN +0067;g;LATIN SMALL LETTER G +03B3;gamma;GREEK SMALL LETTER GAMMA +011F;gbreve;LATIN SMALL LETTER G WITH BREVE +01E7;gcaron;LATIN SMALL LETTER G WITH CARON +011D;gcircumflex;LATIN SMALL LETTER G WITH CIRCUMFLEX +0123;gcommaaccent;LATIN SMALL LETTER G WITH CEDILLA +0121;gdotaccent;LATIN SMALL LETTER G WITH DOT ABOVE +00DF;germandbls;LATIN SMALL LETTER SHARP S +2207;gradient;NABLA +0060;grave;GRAVE ACCENT +0300;gravecomb;COMBINING GRAVE ACCENT +003E;greater;GREATER-THAN SIGN +2265;greaterequal;GREATER-THAN OR EQUAL TO +00AB;guillemotleft;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00BB;guillemotright;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +2039;guilsinglleft;SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A;guilsinglright;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0068;h;LATIN SMALL LETTER H +0127;hbar;LATIN SMALL LETTER H WITH STROKE +0125;hcircumflex;LATIN SMALL LETTER H WITH CIRCUMFLEX +2665;heart;BLACK HEART SUIT +0309;hookabovecomb;COMBINING HOOK ABOVE +2302;house;HOUSE +02DD;hungarumlaut;DOUBLE ACUTE ACCENT +002D;hyphen;HYPHEN-MINUS +00AD;hyphen;SOFT HYPHEN;Duplicate +F6E5;hypheninferior;SUBSCRIPT HYPHEN-MINUS +F6E6;hyphensuperior;SUPERSCRIPT HYPHEN-MINUS +0069;i;LATIN SMALL LETTER I +00ED;iacute;LATIN SMALL LETTER I WITH ACUTE +012D;ibreve;LATIN SMALL LETTER I WITH BREVE +00EE;icircumflex;LATIN SMALL LETTER I WITH CIRCUMFLEX +00EF;idieresis;LATIN SMALL LETTER I WITH DIAERESIS +00EC;igrave;LATIN SMALL LETTER I WITH GRAVE +0133;ij;LATIN SMALL LIGATURE IJ +012B;imacron;LATIN SMALL LETTER I WITH MACRON +221E;infinity;INFINITY +222B;integral;INTEGRAL +2321;integralbt;BOTTOM HALF INTEGRAL +F8F5;integralex;INTEGRAL EXTENDER +2320;integraltp;TOP HALF INTEGRAL +2229;intersection;INTERSECTION +25D8;invbullet;INVERSE BULLET +25D9;invcircle;INVERSE WHITE CIRCLE +263B;invsmileface;BLACK SMILING FACE +012F;iogonek;LATIN SMALL LETTER I WITH OGONEK +03B9;iota;GREEK SMALL LETTER IOTA +03CA;iotadieresis;GREEK SMALL LETTER IOTA WITH DIALYTIKA +0390;iotadieresistonos;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +03AF;iotatonos;GREEK SMALL LETTER IOTA WITH TONOS +F6ED;isuperior;SUPERSCRIPT LATIN SMALL LETTER I +0129;itilde;LATIN SMALL LETTER I WITH TILDE +006A;j;LATIN SMALL LETTER J +0135;jcircumflex;LATIN SMALL LETTER J WITH CIRCUMFLEX +006B;k;LATIN SMALL LETTER K +03BA;kappa;GREEK SMALL LETTER KAPPA +0137;kcommaaccent;LATIN SMALL LETTER K WITH CEDILLA +0138;kgreenlandic;LATIN SMALL LETTER KRA +006C;l;LATIN SMALL LETTER L +013A;lacute;LATIN SMALL LETTER L WITH ACUTE +03BB;lambda;GREEK SMALL LETTER LAMDA +013E;lcaron;LATIN SMALL LETTER L WITH CARON +013C;lcommaaccent;LATIN SMALL LETTER L WITH CEDILLA +0140;ldot;LATIN SMALL LETTER L WITH MIDDLE DOT +003C;less;LESS-THAN SIGN +2264;lessequal;LESS-THAN OR EQUAL TO +258C;lfblock;LEFT HALF BLOCK +20A4;lira;LIRA SIGN +F6C0;ll;LATIN SMALL LETTER LL +2227;logicaland;LOGICAL AND +00AC;logicalnot;NOT SIGN +2228;logicalor;LOGICAL OR +017F;longs;LATIN SMALL LETTER LONG S +25CA;lozenge;LOZENGE +0142;lslash;LATIN SMALL LETTER L WITH STROKE +F6EE;lsuperior;SUPERSCRIPT LATIN SMALL LETTER L +2591;ltshade;LIGHT SHADE +006D;m;LATIN SMALL LETTER M +00AF;macron;MACRON +02C9;macron;MODIFIER LETTER MACRON;Duplicate +2642;male;MALE SIGN +2212;minus;MINUS SIGN +2032;minute;PRIME +F6EF;msuperior;SUPERSCRIPT LATIN SMALL LETTER M +00B5;mu;MICRO SIGN +03BC;mu;GREEK SMALL LETTER MU;Duplicate +00D7;multiply;MULTIPLICATION SIGN +266A;musicalnote;EIGHTH NOTE +266B;musicalnotedbl;BEAMED EIGHTH NOTES +006E;n;LATIN SMALL LETTER N +0144;nacute;LATIN SMALL LETTER N WITH ACUTE +0149;napostrophe;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +0148;ncaron;LATIN SMALL LETTER N WITH CARON +0146;ncommaaccent;LATIN SMALL LETTER N WITH CEDILLA +0039;nine;DIGIT NINE +2089;nineinferior;SUBSCRIPT NINE +F739;nineoldstyle;OLDSTYLE DIGIT NINE +2079;ninesuperior;SUPERSCRIPT NINE +2209;notelement;NOT AN ELEMENT OF +2260;notequal;NOT EQUAL TO +2284;notsubset;NOT A SUBSET OF +207F;nsuperior;SUPERSCRIPT LATIN SMALL LETTER N +00F1;ntilde;LATIN SMALL LETTER N WITH TILDE +03BD;nu;GREEK SMALL LETTER NU +0023;numbersign;NUMBER SIGN +006F;o;LATIN SMALL LETTER O +00F3;oacute;LATIN SMALL LETTER O WITH ACUTE +014F;obreve;LATIN SMALL LETTER O WITH BREVE +00F4;ocircumflex;LATIN SMALL LETTER O WITH CIRCUMFLEX +00F6;odieresis;LATIN SMALL LETTER O WITH DIAERESIS +0153;oe;LATIN SMALL LIGATURE OE +02DB;ogonek;OGONEK +00F2;ograve;LATIN SMALL LETTER O WITH GRAVE +01A1;ohorn;LATIN SMALL LETTER O WITH HORN +0151;ohungarumlaut;LATIN SMALL LETTER O WITH DOUBLE ACUTE +014D;omacron;LATIN SMALL LETTER O WITH MACRON +03C9;omega;GREEK SMALL LETTER OMEGA +03D6;omega1;GREEK PI SYMBOL +03CE;omegatonos;GREEK SMALL LETTER OMEGA WITH TONOS +03BF;omicron;GREEK SMALL LETTER OMICRON +03CC;omicrontonos;GREEK SMALL LETTER OMICRON WITH TONOS +0031;one;DIGIT ONE +2024;onedotenleader;ONE DOT LEADER +215B;oneeighth;VULGAR FRACTION ONE EIGHTH +F6DC;onefitted;PROPORTIONAL DIGIT ONE +00BD;onehalf;VULGAR FRACTION ONE HALF +2081;oneinferior;SUBSCRIPT ONE +F731;oneoldstyle;OLDSTYLE DIGIT ONE +00BC;onequarter;VULGAR FRACTION ONE QUARTER +00B9;onesuperior;SUPERSCRIPT ONE +2153;onethird;VULGAR FRACTION ONE THIRD +25E6;openbullet;WHITE BULLET +00AA;ordfeminine;FEMININE ORDINAL INDICATOR +00BA;ordmasculine;MASCULINE ORDINAL INDICATOR +221F;orthogonal;RIGHT ANGLE +00F8;oslash;LATIN SMALL LETTER O WITH STROKE +01FF;oslashacute;LATIN SMALL LETTER O WITH STROKE AND ACUTE +F6F0;osuperior;SUPERSCRIPT LATIN SMALL LETTER O +00F5;otilde;LATIN SMALL LETTER O WITH TILDE +0070;p;LATIN SMALL LETTER P +00B6;paragraph;PILCROW SIGN +0028;parenleft;LEFT PARENTHESIS +F8ED;parenleftbt;LEFT PAREN BOTTOM +F8EC;parenleftex;LEFT PAREN EXTENDER +208D;parenleftinferior;SUBSCRIPT LEFT PARENTHESIS +207D;parenleftsuperior;SUPERSCRIPT LEFT PARENTHESIS +F8EB;parenlefttp;LEFT PAREN TOP +0029;parenright;RIGHT PARENTHESIS +F8F8;parenrightbt;RIGHT PAREN BOTTOM +F8F7;parenrightex;RIGHT PAREN EXTENDER +208E;parenrightinferior;SUBSCRIPT RIGHT PARENTHESIS +207E;parenrightsuperior;SUPERSCRIPT RIGHT PARENTHESIS +F8F6;parenrighttp;RIGHT PAREN TOP +2202;partialdiff;PARTIAL DIFFERENTIAL +0025;percent;PERCENT SIGN +002E;period;FULL STOP +00B7;periodcentered;MIDDLE DOT +2219;periodcentered;BULLET OPERATOR;Duplicate +F6E7;periodinferior;SUBSCRIPT FULL STOP +F6E8;periodsuperior;SUPERSCRIPT FULL STOP +22A5;perpendicular;UP TACK +2030;perthousand;PER MILLE SIGN +20A7;peseta;PESETA SIGN +03C6;phi;GREEK SMALL LETTER PHI +03D5;phi1;GREEK PHI SYMBOL +03C0;pi;GREEK SMALL LETTER PI +002B;plus;PLUS SIGN +00B1;plusminus;PLUS-MINUS SIGN +211E;prescription;PRESCRIPTION TAKE +220F;product;N-ARY PRODUCT +2282;propersubset;SUBSET OF +2283;propersuperset;SUPERSET OF +221D;proportional;PROPORTIONAL TO +03C8;psi;GREEK SMALL LETTER PSI +0071;q;LATIN SMALL LETTER Q +003F;question;QUESTION MARK +00BF;questiondown;INVERTED QUESTION MARK +F7BF;questiondownsmall;SMALL CAPITAL INVERTED QUESTION MARK +F73F;questionsmall;SMALL CAPITAL QUESTION MARK +0022;quotedbl;QUOTATION MARK +201E;quotedblbase;DOUBLE LOW-9 QUOTATION MARK +201C;quotedblleft;LEFT DOUBLE QUOTATION MARK +201D;quotedblright;RIGHT DOUBLE QUOTATION MARK +2018;quoteleft;LEFT SINGLE QUOTATION MARK +201B;quotereversed;SINGLE HIGH-REVERSED-9 QUOTATION MARK +2019;quoteright;RIGHT SINGLE QUOTATION MARK +201A;quotesinglbase;SINGLE LOW-9 QUOTATION MARK +0027;quotesingle;APOSTROPHE +0072;r;LATIN SMALL LETTER R +0155;racute;LATIN SMALL LETTER R WITH ACUTE +221A;radical;SQUARE ROOT +F8E5;radicalex;RADICAL EXTENDER +0159;rcaron;LATIN SMALL LETTER R WITH CARON +0157;rcommaaccent;LATIN SMALL LETTER R WITH CEDILLA +2286;reflexsubset;SUBSET OF OR EQUAL TO +2287;reflexsuperset;SUPERSET OF OR EQUAL TO +00AE;registered;REGISTERED SIGN +F8E8;registersans;REGISTERED SIGN SANS SERIF +F6DA;registerserif;REGISTERED SIGN SERIF +2310;revlogicalnot;REVERSED NOT SIGN +03C1;rho;GREEK SMALL LETTER RHO +02DA;ring;RING ABOVE +F6F1;rsuperior;SUPERSCRIPT LATIN SMALL LETTER R +2590;rtblock;RIGHT HALF BLOCK +F6DD;rupiah;RUPIAH SIGN +0073;s;LATIN SMALL LETTER S +015B;sacute;LATIN SMALL LETTER S WITH ACUTE +0161;scaron;LATIN SMALL LETTER S WITH CARON +015F;scedilla;LATIN SMALL LETTER S WITH CEDILLA +F6C2;scedilla;LATIN SMALL LETTER S WITH CEDILLA;Duplicate +015D;scircumflex;LATIN SMALL LETTER S WITH CIRCUMFLEX +0219;scommaaccent;LATIN SMALL LETTER S WITH COMMA BELOW +2033;second;DOUBLE PRIME +00A7;section;SECTION SIGN +003B;semicolon;SEMICOLON +0037;seven;DIGIT SEVEN +215E;seveneighths;VULGAR FRACTION SEVEN EIGHTHS +2087;seveninferior;SUBSCRIPT SEVEN +F737;sevenoldstyle;OLDSTYLE DIGIT SEVEN +2077;sevensuperior;SUPERSCRIPT SEVEN +2592;shade;MEDIUM SHADE +03C3;sigma;GREEK SMALL LETTER SIGMA +03C2;sigma1;GREEK SMALL LETTER FINAL SIGMA +223C;similar;TILDE OPERATOR +0036;six;DIGIT SIX +2086;sixinferior;SUBSCRIPT SIX +F736;sixoldstyle;OLDSTYLE DIGIT SIX +2076;sixsuperior;SUPERSCRIPT SIX +002F;slash;SOLIDUS +263A;smileface;WHITE SMILING FACE +0020;space;SPACE +00A0;space;NO-BREAK SPACE;Duplicate +2660;spade;BLACK SPADE SUIT +F6F2;ssuperior;SUPERSCRIPT LATIN SMALL LETTER S +00A3;sterling;POUND SIGN +220B;suchthat;CONTAINS AS MEMBER +2211;summation;N-ARY SUMMATION +263C;sun;WHITE SUN WITH RAYS +0074;t;LATIN SMALL LETTER T +03C4;tau;GREEK SMALL LETTER TAU +0167;tbar;LATIN SMALL LETTER T WITH STROKE +0165;tcaron;LATIN SMALL LETTER T WITH CARON +0163;tcommaaccent;LATIN SMALL LETTER T WITH CEDILLA +021B;tcommaaccent;LATIN SMALL LETTER T WITH COMMA BELOW;Duplicate +2234;therefore;THEREFORE +03B8;theta;GREEK SMALL LETTER THETA +03D1;theta1;GREEK THETA SYMBOL +00FE;thorn;LATIN SMALL LETTER THORN +0033;three;DIGIT THREE +215C;threeeighths;VULGAR FRACTION THREE EIGHTHS +2083;threeinferior;SUBSCRIPT THREE +F733;threeoldstyle;OLDSTYLE DIGIT THREE +00BE;threequarters;VULGAR FRACTION THREE QUARTERS +F6DE;threequartersemdash;THREE QUARTERS EM DASH +00B3;threesuperior;SUPERSCRIPT THREE +02DC;tilde;SMALL TILDE +0303;tildecomb;COMBINING TILDE +0384;tonos;GREEK TONOS +2122;trademark;TRADE MARK SIGN +F8EA;trademarksans;TRADE MARK SIGN SANS SERIF +F6DB;trademarkserif;TRADE MARK SIGN SERIF +25BC;triagdn;BLACK DOWN-POINTING TRIANGLE +25C4;triaglf;BLACK LEFT-POINTING POINTER +25BA;triagrt;BLACK RIGHT-POINTING POINTER +25B2;triagup;BLACK UP-POINTING TRIANGLE +F6F3;tsuperior;SUPERSCRIPT LATIN SMALL LETTER T +0032;two;DIGIT TWO +2025;twodotenleader;TWO DOT LEADER +2082;twoinferior;SUBSCRIPT TWO +F732;twooldstyle;OLDSTYLE DIGIT TWO +00B2;twosuperior;SUPERSCRIPT TWO +2154;twothirds;VULGAR FRACTION TWO THIRDS +0075;u;LATIN SMALL LETTER U +00FA;uacute;LATIN SMALL LETTER U WITH ACUTE +016D;ubreve;LATIN SMALL LETTER U WITH BREVE +00FB;ucircumflex;LATIN SMALL LETTER U WITH CIRCUMFLEX +00FC;udieresis;LATIN SMALL LETTER U WITH DIAERESIS +00F9;ugrave;LATIN SMALL LETTER U WITH GRAVE +01B0;uhorn;LATIN SMALL LETTER U WITH HORN +0171;uhungarumlaut;LATIN SMALL LETTER U WITH DOUBLE ACUTE +016B;umacron;LATIN SMALL LETTER U WITH MACRON +005F;underscore;LOW LINE +2017;underscoredbl;DOUBLE LOW LINE +222A;union;UNION +2200;universal;FOR ALL +0173;uogonek;LATIN SMALL LETTER U WITH OGONEK +2580;upblock;UPPER HALF BLOCK +03C5;upsilon;GREEK SMALL LETTER UPSILON +03CB;upsilondieresis;GREEK SMALL LETTER UPSILON WITH DIALYTIKA +03B0;upsilondieresistonos;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03CD;upsilontonos;GREEK SMALL LETTER UPSILON WITH TONOS +016F;uring;LATIN SMALL LETTER U WITH RING ABOVE +0169;utilde;LATIN SMALL LETTER U WITH TILDE +0076;v;LATIN SMALL LETTER V +0077;w;LATIN SMALL LETTER W +1E83;wacute;LATIN SMALL LETTER W WITH ACUTE +0175;wcircumflex;LATIN SMALL LETTER W WITH CIRCUMFLEX +1E85;wdieresis;LATIN SMALL LETTER W WITH DIAERESIS +2118;weierstrass;SCRIPT CAPITAL P +1E81;wgrave;LATIN SMALL LETTER W WITH GRAVE +0078;x;LATIN SMALL LETTER X +03BE;xi;GREEK SMALL LETTER XI +0079;y;LATIN SMALL LETTER Y +00FD;yacute;LATIN SMALL LETTER Y WITH ACUTE +0177;ycircumflex;LATIN SMALL LETTER Y WITH CIRCUMFLEX +00FF;ydieresis;LATIN SMALL LETTER Y WITH DIAERESIS +00A5;yen;YEN SIGN +1EF3;ygrave;LATIN SMALL LETTER Y WITH GRAVE +007A;z;LATIN SMALL LETTER Z +017A;zacute;LATIN SMALL LETTER Z WITH ACUTE +017E;zcaron;LATIN SMALL LETTER Z WITH CARON +017C;zdotaccent;LATIN SMALL LETTER Z WITH DOT ABOVE +0030;zero;DIGIT ZERO +2080;zeroinferior;SUBSCRIPT ZERO +F730;zerooldstyle;OLDSTYLE DIGIT ZERO +2070;zerosuperior;SUPERSCRIPT ZERO +03B6;zeta;GREEK SMALL LETTER ZETA +""" + + +t1_bias = 0 +glyph_list = [] + + +def adobe_glyph_names(): + """return the list of glyph names from the adobe list""" + + lines = string.split( adobe_glyph_list, '\n' ) + glyphs = [] + + for line in lines: + if line: + fields = string.split( line, ';' ) +# print fields[0] + ' - ' + fields[1] + glyphs.append( fields[1] ) + + return glyphs + + +def adobe_glyph_values(): + """return the list of glyph names and their unicode values""" + + lines = string.split( adobe_glyph_list, '\n' ) + glyphs = [] + values = [] + + for line in lines: + if line: + fields = string.split( line, ';' ) +# print fields[0] + ' - ' + fields[1] + glyphs.append( fields[1] ) + values.append( fields[0] ) + + return glyphs, values + + +def filter_glyph_names( alist, filter ): + """filter 'alist' by taking _out_ all glyph names that are in 'filter'""" + + count = 0 + extras = [] + + for name in alist: + try: + filtered_index = filter.index( name ) + except: + extras.append( name ) + + return extras + + +def dump_mac_indices( file, all_glyphs ): + write = file.write + + write( " static const unsigned short mac_standard_names[" + \ + repr( len( mac_standard_names ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for name in mac_standard_names: + write( " " + repr( all_glyphs.index( name ) ) + ",\n" ) + + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + +def dump_glyph_list( file, base_list, adobe_list ): + write = file.write + + name_list = [] + + write( " static const char* const ps_glyph_names[] =\n" ) + write( " {\n" ) + + for name in base_list: + write( ' "' + name + '",\n' ) + name_list.append( name ) + + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "\n" ) + + for name in adobe_list: + write( ' "' + name + '",\n' ) + name_list.append( name ) + + write( "\n" ) + write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) + write( "\n" ) + write( " NULL\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + return name_list + + +def dump_unicode_values( file, sid_list, adobe_list ): + """build the glyph names to unicode values table""" + + write = file.write + + agl_names, agl_unicodes = adobe_glyph_values() + + write( "\n" ) + write( " static const unsigned short ps_names_to_unicode[" + \ + repr( len( sid_list ) + len( adobe_list ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for name in sid_list: + try: + index = agl_names.index( name ) + write( " 0x" + agl_unicodes[index] + ",\n" ) + except: + write( " 0,\n" ) + + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "\n" ) + + for name in adobe_list: + try: + index = agl_names.index( name ) + write( " 0x" + agl_unicodes[index] + ",\n" ) + except: + write( " 0,\n" ) + + write( "\n" ) + write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + write( "\n" ) + + +def dump_encoding( file, encoding_name, encoding_list ): + """dumps a given encoding""" + + write = file.write + + write( " static const unsigned short " + encoding_name + "[" + \ + repr( len( encoding_list ) + 1 ) + "] =\n" ) + write( " {\n" ) + + for value in encoding_list: + write( " " + repr( value ) + ",\n" ) + write( " 0\n" ) + write( " };\n" ) + write( "\n" ) + write( "\n" ) + + +def main(): + """main program body""" + + if len( sys.argv ) != 2: + print __doc__ % sys.argv[0] + sys.exit( 1 ) + + file = open( sys.argv[1], "w\n" ) + write = file.write + + count_sid = len( sid_standard_names ) + + # 'mac_extras' contains the list of glyph names in the Macintosh standard + # encoding which are not in either the Adobe Glyph List or the SID + # Standard Names. + # + mac_extras = filter_glyph_names( mac_standard_names, adobe_glyph_names() ) + mac_extras = filter_glyph_names( mac_extras, sid_standard_names ) + + # 'base_list' contains the first names of our final glyph names table. + # It consists of the 'mac_extras' glyph names, followed by the SID + # Standard names. + # + mac_extras_count = len( mac_extras ) + t1_bias = mac_extras_count + base_list = mac_extras + sid_standard_names + + # 'adobe_list' contains the glyph names that are in the AGL, but not in + # the base_list; they will be placed after base_list glyph names in + # our final table. + # + adobe_list = filter_glyph_names( adobe_glyph_names(), base_list ) + adobe_count = len( adobe_list ) + + write( "/***************************************************************************/\n" ) + write( "/* */\n" ) + + write( "/* %-71s*/\n" % sys.argv[1] ) + + write( "/* */\n" ) + write( "/* PostScript glyph names (specification only). */\n" ) + write( "/* */\n" ) + write( "/* Copyright 2000-2001 by */\n" ) + write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) + write( "/* */\n" ) + write( "/* This file is part of the FreeType project, and may only be used, */\n" ) + write( "/* modified, and distributed under the terms of the FreeType project */\n" ) + write( "/* license, LICENSE.TXT. By continuing to use, modify, or distribute */\n" ) + write( "/* this file you indicate that you have read the license and */\n" ) + write( "/* understand and accept it fully. */\n" ) + write( "/* */\n" ) + write( "/***************************************************************************/\n" ) + write( "\n" ) + write( "\n" ) + write( " /* this file has been generated automatically -- do not edit! */\n" ) + write( "\n" ) + write( "\n" ) + + # dump final glyph list (mac extras + sid standard names + AGL glyph names) + # + name_list = dump_glyph_list( file, base_list, adobe_list ) + + # dump t1_standard_list + write( " static const char* const * const sid_standard_names = " \ + + "ps_glyph_names + " + repr( t1_bias ) + ";\n" ) + write( "\n" ) + write( "\n" ) + + write( "#define NUM_SID_GLYPHS " + repr( len( sid_standard_names ) ) + "\n" ) + write( "\n" ) + write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) + write( "#define NUM_ADOBE_GLYPHS " + \ + repr( len( base_list ) + len( adobe_list ) - t1_bias ) + "\n" ) + write( "#else\n" ) + write( "#define NUM_ADOBE_GLYPHS " + \ + repr( len( base_list ) - t1_bias ) + "\n" ) + write( "#endif\n" ) + write( "\n" ) + write( "\n" ) + + # dump mac indices table + dump_mac_indices( file, name_list ) + + # dump unicode values table + dump_unicode_values( file, sid_standard_names, adobe_list ) + + dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) + dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) + + write( "/* END */\n" ) + + +# Now run the main routine +# +main() + + +# END diff --git a/lib/freetype/src/tools/test_bbox.c b/lib/freetype/src/tools/test_bbox.c new file mode 100644 index 0000000..e085c5b --- /dev/null +++ b/lib/freetype/src/tools/test_bbox.c @@ -0,0 +1,160 @@ +#include +#include FT_FREETYPE_H +#include FT_BBOX_H + + +#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 + + static long + get_time( void ) + { + return clock() * 10000L / CLOCKS_PER_SEC; + } + + + + + /* test bbox computations */ + +#define XSCALE 65536 +#define XX(x) ((FT_Pos)(x*XSCALE)) +#define XVEC(x,y) { XX(x), XX(y) } +#define XVAL(x) ((x)/(1.0*XSCALE)) + + /* dummy outline #1 */ + static FT_Vector dummy_vec_1[4] = + { +#if 1 + XVEC( 408.9111, 535.3164 ), + XVEC( 455.8887, 634.396 ), + XVEC( -37.8765, 786.2207 ), + XVEC( 164.6074, 535.3164 ) +#else + { (FT_Int32)0x0198E93DL , (FT_Int32)0x021750FFL }, /* 408.9111, 535.3164 */ + { (FT_Int32)0x01C7E312L , (FT_Int32)0x027A6560L }, /* 455.8887, 634.3960 */ + { (FT_Int32)0xFFDA1F9EL , (FT_Int32)0x0312387FL }, /* -37.8765, 786.2207 */ + { (FT_Int32)0x00A49B7EL , (FT_Int32)0x021750FFL } /* 164.6074, 535.3164 */ +#endif + }; + + static char dummy_tag_1[4] = + { + FT_CURVE_TAG_ON, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_CUBIC, + FT_CURVE_TAG_ON + }; + + static short dummy_contour_1[1] = + { + 3 + }; + + static FT_Outline dummy_outline_1 = + { + 1, + 4, + dummy_vec_1, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + /* dummy outline #2 */ + static FT_Vector dummy_vec_2[4] = + { + XVEC( 100.0, 100.0 ), + XVEC( 100.0, 200.0 ), + XVEC( 200.0, 200.0 ), + XVEC( 200.0, 133.0 ) + }; + + static FT_Outline dummy_outline_2 = + { + 1, + 4, + dummy_vec_2, + dummy_tag_1, + dummy_contour_1, + 0 + }; + + + static void + dump_outline( FT_Outline* outline ) + { + FT_BBox bbox; + + /* compute and display cbox */ + FT_Outline_Get_CBox( outline, &bbox ); + printf( "cbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + + /* compute and display bbox */ + FT_Outline_Get_BBox( outline, &bbox ); + printf( "bbox = [%.2f %.2f %.2f %.2f]\n", + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + } + + + + static void + profile_outline( FT_Outline* outline, + long repeat ) + { + FT_BBox bbox; + long count; + long time0; + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_CBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %5.2f cbox = [%.2f %.2f %.2f %.2f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + + + time0 = get_time(); + for ( count = repeat; count > 0; count-- ) + FT_Outline_Get_BBox( outline, &bbox ); + + time0 = get_time() - time0; + printf( "time = %5.2f bbox = [%.2f %.2f %.2f %.2f]\n", + ((double)time0/10000.0), + XVAL( bbox.xMin ), + XVAL( bbox.yMin ), + XVAL( bbox.xMax ), + XVAL( bbox.yMax ) ); + } + +#define REPEAT 100000L + + int main( int argc, char** argv ) + { + printf( "outline #1\n" ); + profile_outline( &dummy_outline_1, REPEAT ); + + printf( "outline #2\n" ); + profile_outline( &dummy_outline_2, REPEAT ); + return 0; + } + diff --git a/lib/freetype/src/tools/test_trig.c b/lib/freetype/src/tools/test_trig.c new file mode 100644 index 0000000..8c8a544 --- /dev/null +++ b/lib/freetype/src/tools/test_trig.c @@ -0,0 +1,236 @@ +#include +#include FT_FREETYPE_H +#include FT_TRIGONOMETRY_H + +#include +#include + +#define PI 3.14159265358979323846 +#define SPI (PI/FT_ANGLE_PI) + +/* the precision in 16.16 fixed float points of the checks. Expect */ +/* between 2 and 5 noise LSB bits during operations, due to */ +/* rounding errors.. */ +#define THRESHOLD 64 + + static error = 0; + + static void + test_cos( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + f1 = FT_Cos(i); + d1 = f1/65536.0; + d2 = cos( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Cos[%3d] = %.7f cos[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + + static void + test_sin( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + f1 = FT_Sin(i); + d1 = f1/65536.0; + d2 = sin( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Sin[%3d] = %.7f sin[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_tan( void ) + { + FT_Fixed f1, f2; + double d1, d2; + int i; + + for ( i = 0; i < FT_ANGLE_PI2-0x2000000; i += 0x10000 ) + { + f1 = FT_Tan(i); + d1 = f1/65536.0; + d2 = tan( i*SPI ); + f2 = (FT_Fixed)(d2*65536.0); + + if ( abs( f2-f1 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Tan[%3d] = %.7f tan[%3d] = %.7f\n", + (i >> 16), f1/65536.0, (i >> 16), d2 ); + } + } + } + + + static void + test_atan2( void ) + { + FT_Fixed c2, s2; + double l, a, c1, s1; + int i, j; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = 5.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + j = FT_Atan2( c2, s2 ); + if ( j < 0 ) + j += FT_ANGLE_2PI; + + if ( abs( i - j ) > 1 ) + { + printf( "FT_Atan2( %.7f, %.7f ) = %.5f, atan = %.5f\n", + c2/65536.0, s2/65536.0, j/65536.0, i/65536.0 ); + } + } + } + + static void + test_unit( void ) + { + FT_Vector v; + double a, c1, s1; + FT_Fixed c2, s2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + FT_Vector_Unit( &v, i ); + a = ( i*SPI ); + c1 = cos(a); + s1 = sin(a); + c2 = (FT_Fixed)(c1*65536.0); + s2 = (FT_Fixed)(s1*65536.0); + + if ( abs( v.x-c2 ) > THRESHOLD || + abs( v.y-s2 ) > THRESHOLD ) + { + error = 1; + printf( "FT_Vector_Unit[%3d] = ( %.7f, %.7f ) vec = ( %.7f, %.7f )\n", + (i >> 16), + v.x/65536.0, v.y/65536.0, + c1, s1 ); + } + } + } + + + static void + test_length( void ) + { + FT_Vector v; + FT_Fixed l, l2; + int i; + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = (FT_Fixed)(500.0*65536.0); + v.x = (FT_Fixed)( l * cos( i*SPI ) ); + v.y = (FT_Fixed)( l * sin( i*SPI ) ); + l2 = FT_Vector_Length( &v ); + + if ( abs( l2-l ) > THRESHOLD ) + { + error = 1; + printf( "FT_Length( %.7f, %.7f ) = %.5f, length = %.5f\n", + v.x/65536.0, v.y/65536.0, l2/65536.0, l/65536.0 ); + } + } + } + + + static void + test_rotate( void ) + { + FT_Fixed c2, s2, c4, s4; + FT_Vector v; + double l, ra, a, c1, s1, cra, sra, c3, s3; + int i, j, rotate; + + for ( rotate = 0; rotate < FT_ANGLE_2PI; rotate += 0x10000 ) + { + ra = rotate*SPI; + cra = cos( ra ); + sra = sin( ra ); + + for ( i = 0; i < FT_ANGLE_2PI; i += 0x10000 ) + { + l = 500.0; + a = i*SPI; + + c1 = l * cos(a); + s1 = l * sin(a); + + v.x = c2 = (FT_Fixed)(c1*65536.0); + v.y = s2 = (FT_Fixed)(s1*65536.0); + + FT_Vector_Rotate( &v, rotate ); + + c3 = c1 * cra - s1 * sra; + s3 = c1 * sra + s1 * cra; + + c4 = (FT_Fixed)(c3*65536.0); + s4 = (FT_Fixed)(s3*65536.0); + + if ( abs( c4 - v.x ) > THRESHOLD || + abs( s4 - v.y ) > THRESHOLD ) + { + error = 1; + printf( "FT_Rotate( (%.7f,%.7f), %.5f ) = ( %.7f, %.7f ), rot = ( %.7f, %.7f )\n", + c1, s1, ra, + c2/65536.0, s2/65536.0, + c4/65536.0, s4/65536.0 ); + } + } + } + } + + + int main( void ) + { + test_cos(); + test_sin(); + test_tan(); + test_atan2(); + test_unit(); + test_length(); + test_rotate(); + + if (!error) + printf( "trigonometry test ok !\n" ); + + return !error; + } diff --git a/lib/freetype/src/truetype/Jamfile b/lib/freetype/src/truetype/Jamfile new file mode 100644 index 0000000..f847f6f --- /dev/null +++ b/lib/freetype/src/truetype/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/truetype Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) truetype ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = ttdriver ttobjs ttpload ttgload ttinterp ; + } + else + { + _sources = truetype ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/truetype Jamfile diff --git a/lib/freetype/src/truetype/descrip.mms b/lib/freetype/src/truetype/descrip.mms new file mode 100644 index 0000000..e30ee1b --- /dev/null +++ b/lib/freetype/src/truetype/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 TrueType driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.truetype]) + +OBJS=truetype.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/truetype/module.mk b/lib/freetype/src/truetype/module.mk new file mode 100644 index 0000000..bb042be --- /dev/null +++ b/lib/freetype/src/truetype/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 TrueType module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_truetype_driver + +add_truetype_driver: + $(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/truetype/rules.mk b/lib/freetype/src/truetype/rules.mk new file mode 100644 index 0000000..7c1f3e3 --- /dev/null +++ b/lib/freetype/src/truetype/rules.mk @@ -0,0 +1,71 @@ +# +# FreeType 2 TrueType driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# TrueType driver directory +# +TT_DIR := $(SRC_)truetype +TT_DIR_ := $(TT_DIR)$(SEP) + + +# compilation flags for the driver +# +TT_COMPILE := $(FT_COMPILE) $I$(TT_DIR) + + +# TrueType driver sources (i.e., C files) +# +TT_DRV_SRC := $(TT_DIR_)ttobjs.c \ + $(TT_DIR_)ttpload.c \ + $(TT_DIR_)ttgload.c \ + $(TT_DIR_)ttinterp.c \ + $(TT_DIR_)ttdriver.c + +# TrueType driver headers +# +TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) \ + $(TT_DIR_)tterrors.h + + +# TrueType driver object(s) +# +# TT_DRV_OBJ_M is used during `multi' builds +# TT_DRV_OBJ_S is used during `single' builds +# +TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O) +TT_DRV_OBJ_S := $(OBJ_)truetype.$O + +# TrueType driver source file for single build +# +TT_DRV_SRC_S := $(TT_DIR_)truetype.c + + +# TrueType driver - single object +# +$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) + $(TT_COMPILE) $T$@ $(TT_DRV_SRC_S) + + +# driver - multiple objects +# +$(OBJ_)%.$O: $(TT_DIR_)%.c $(FREETYPE_H) $(TT_DRV_H) + $(TT_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(TT_DRV_OBJ_S) +DRV_OBJS_M += $(TT_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/truetype/truetype.c b/lib/freetype/src/truetype/truetype.c new file mode 100644 index 0000000..1ed3ceb --- /dev/null +++ b/lib/freetype/src/truetype/truetype.c @@ -0,0 +1,32 @@ +/***************************************************************************/ +/* */ +/* truetype.c */ +/* */ +/* FreeType TrueType driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include +#include "ttdriver.c" /* driver interface */ +#include "ttpload.c" /* tables loader */ +#include "ttgload.c" /* glyph loader */ +#include "ttobjs.c" /* object manager */ + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#include "ttinterp.c" +#endif + + +/* END */ diff --git a/lib/freetype/src/truetype/ttdriver.c b/lib/freetype/src/truetype/ttdriver.c new file mode 100644 index 0000000..0b56602 --- /dev/null +++ b/lib/freetype/src/truetype/ttdriver.c @@ -0,0 +1,428 @@ +/***************************************************************************/ +/* */ +/* ttdriver.c */ +/* */ +/* TrueType font driver implementation (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_IDS_H + +#include "ttdriver.h" +#include "ttgload.h" + +#include "tterrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttdriver + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F A C E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#undef PAIR_TAG +#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ + (FT_ULong)right ) + + + /*************************************************************************/ + /* */ + /* */ + /* Get_Kerning */ + /* */ + /* */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings, are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + Get_Kerning( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + TT_Kern0_Pair pair; + + + if ( !face ) + return TT_Err_Invalid_Face_Handle; + + kerning->x = 0; + kerning->y = 0; + + if ( face->kern_pairs ) + { + /* there are some kerning pairs in this font file! */ + FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); + FT_Long left, right; + + + left = 0; + right = face->num_kern_pairs - 1; + + while ( left <= right ) + { + FT_Int middle = left + ( ( right - left ) >> 1 ); + FT_ULong cur_pair; + + + pair = face->kern_pairs + middle; + cur_pair = PAIR_TAG( pair->left, pair->right ); + + if ( cur_pair == search_tag ) + goto Found; + + if ( cur_pair < search_tag ) + left = middle + 1; + else + right = middle - 1; + } + } + + Exit: + return TT_Err_Ok; + + Found: + kerning->x = pair->value; + goto Exit; + } + + +#undef PAIR_TAG + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** S I Z E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* Set_Char_Sizes */ + /* */ + /* */ + /* A driver method used to reset a size's character sizes (horizontal */ + /* and vertical) expressed in fractional points. */ + /* */ + /* */ + /* char_width :: The character width expressed in 26.6 */ + /* fractional points. */ + /* */ + /* char_height :: The character height expressed in 26.6 */ + /* fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution of the output device. */ + /* */ + /* vert_resolution :: The vertical resolution of the output device. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Set_Char_Sizes( TT_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) + { + FT_Size_Metrics* metrics = &size->root.metrics; + FT_Size_Metrics* metrics2 = &size->metrics; + TT_Face face = (TT_Face)size->root.face; + FT_Long dim_x, dim_y; + + + *metrics2 = *metrics; + + /* This bit flag, when set, indicates that the pixel size must be */ + /* truncated to an integer. Nearly all TrueType fonts have this */ + /* bit set, as hinting won't work really well otherwise. */ + /* */ + if ( ( face->header.Flags & 8 ) != 0 ) + { + /* we need to use rounding in the following computations. Otherwise, + * the resulting hinted outlines will be very slightly distorted + */ + dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; + dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & -64; + } + else + { + dim_x = ( ( char_width * horz_resolution + 36 ) / 72 ); + dim_y = ( ( char_height * vert_resolution + 36 ) / 72 ); + } + + /* we only modify "metrics2", not "metrics", so these changes have */ + /* no effect on the result of the auto-hinter when it is used */ + /* */ + metrics2->x_ppem = (FT_UShort)( dim_x >> 6 ); + metrics2->y_ppem = (FT_UShort)( dim_y >> 6 ); + metrics2->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); + metrics2->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); + + size->ttmetrics.valid = FALSE; +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + size->strike_index = 0xFFFF; +#endif + + return tt_size_reset( size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Set_Pixel_Sizes */ + /* */ + /* */ + /* A driver method used to reset a size's character sizes (horizontal */ + /* and vertical) expressed in integer pixels. */ + /* */ + /* */ + /* pixel_width :: The character width expressed in integer pixels. */ + /* */ + /* pixel_height :: The character height expressed in integer pixels. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Set_Pixel_Sizes( TT_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ) + { + FT_UNUSED( pixel_width ); + FT_UNUSED( pixel_height ); + + /* many things have been pre-computed by the base layer */ + + size->metrics = size->root.metrics; + size->ttmetrics.valid = FALSE; +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + size->strike_index = 0xFFFF; +#endif + + return tt_size_reset( size ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Load_Glyph */ + /* */ + /* */ + /* A driver method used to load a glyph within a given glyph slot. */ + /* */ + /* */ + /* slot :: A handle to the target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled, loaded, etc. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FTLOAD_??? constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Load_Glyph( TT_GlyphSlot slot, + TT_Size size, + FT_UShort glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + + + if ( !slot ) + return TT_Err_Invalid_Slot_Handle; + + /* check whether we want a scaled outline or bitmap */ + if ( !size ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + if ( load_flags & FT_LOAD_NO_SCALE ) + size = NULL; + + /* reset the size object if necessary */ + if ( size ) + { + /* these two object must have the same parent */ + if ( size->root.face != slot->face ) + return TT_Err_Invalid_Face_Handle; + + if ( !size->ttmetrics.valid ) + { + if ( FT_SET_ERROR( tt_size_reset( size ) ) ) + return error; + } + } + + /* now load the glyph outline if necessary */ + error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); + + /* force drop-out mode to 2 - irrelevant now */ + /* slot->outline.dropout_mode = 2; */ + + return error; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** D R I V E R I N T E R F A C E ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + static FT_Module_Interface + tt_get_interface( TT_Driver driver, + const char* tt_interface ) + { + FT_Module sfntd = FT_Get_Module( driver->root.root.library, + "sfnt" ); + SFNT_Service sfnt; + + + /* only return the default interface from the SFNT module */ + if ( sfntd ) + { + sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); + if ( sfnt ) + return sfnt->get_interface( FT_MODULE( driver ), tt_interface ); + } + + return 0; + } + + + /* The FT_DriverInterface structure is defined in ftdriver.h. */ + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec tt_driver_class = + { + { + ft_module_font_driver | + ft_module_driver_scalable | +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + ft_module_driver_has_hinter, +#else + 0, +#endif + + sizeof ( TT_DriverRec ), + + "truetype", /* driver name */ + 0x10000L, /* driver version == 1.0 */ + 0x20000L, /* driver requires FreeType 2.0 or above */ + + (void*)0, /* driver specific interface */ + + (FT_Module_Constructor)tt_driver_init, + (FT_Module_Destructor) tt_driver_done, + (FT_Module_Requester) tt_get_interface, + }, + + sizeof ( TT_FaceRec ), + sizeof ( TT_SizeRec ), + sizeof ( FT_GlyphSlotRec ), + + + (FT_Face_InitFunc) tt_face_init, + (FT_Face_DoneFunc) tt_face_done, + (FT_Size_InitFunc) tt_size_init, + (FT_Size_DoneFunc) tt_size_done, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, + + (FT_Size_ResetPointsFunc) Set_Char_Sizes, + (FT_Size_ResetPixelsFunc) Set_Pixel_Sizes, + (FT_Slot_LoadFunc) Load_Glyph, + + (FT_Face_GetKerningFunc) Get_Kerning, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/truetype/ttdriver.h b/lib/freetype/src/truetype/ttdriver.h new file mode 100644 index 0000000..f6f26e4 --- /dev/null +++ b/lib/freetype/src/truetype/ttdriver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* ttdriver.h */ +/* */ +/* High-level TrueType driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTDRIVER_H__ +#define __TTDRIVER_H__ + + +#include +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) tt_driver_class; + + +FT_END_HEADER + +#endif /* __TTDRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/truetype/tterrors.h b/lib/freetype/src/truetype/tterrors.h new file mode 100644 index 0000000..d317c70 --- /dev/null +++ b/lib/freetype/src/truetype/tterrors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* tterrors.h */ +/* */ +/* TrueType error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the TrueType error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __TTERRORS_H__ +#define __TTERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX TT_Err_ +#define FT_ERR_BASE FT_Mod_Err_TrueType + +#include FT_ERRORS_H + +#endif /* __TTERRORS_H__ */ + +/* END */ diff --git a/lib/freetype/src/truetype/ttgload.c b/lib/freetype/src/truetype/ttgload.c new file mode 100644 index 0000000..42cf13a --- /dev/null +++ b/lib/freetype/src/truetype/ttgload.c @@ -0,0 +1,1798 @@ +/***************************************************************************/ +/* */ +/* ttgload.c */ +/* */ +/* TrueType Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_SFNT_H +#include FT_TRUETYPE_TAGS_H +#include FT_OUTLINE_H + +#include "ttgload.h" + +#include "tterrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttgload + + + /*************************************************************************/ + /* */ + /* Composite font flags. */ + /* */ +#define ARGS_ARE_WORDS 0x0001 +#define ARGS_ARE_XY_VALUES 0x0002 +#define ROUND_XY_TO_GRID 0x0004 +#define WE_HAVE_A_SCALE 0x0008 +/* reserved 0x0010 */ +#define MORE_COMPONENTS 0x0020 +#define WE_HAVE_AN_XY_SCALE 0x0040 +#define WE_HAVE_A_2X2 0x0080 +#define WE_HAVE_INSTR 0x0100 +#define USE_MY_METRICS 0x0200 +#define OVERLAP_COMPOUND 0x0400 +#define SCALED_COMPONENT_OFFSET 0x0800 +#define UNSCALED_COMPONENT_OFFSET 0x1000 + + +/* Maximum recursion depth we allow for composite glyphs. + * The TrueType spec doesn't say anything about recursion, + * so it isn't clear that recursion is allowed at all. But + * we'll be generous. + */ +#define TT_MAX_COMPOSITE_RECURSE 5 + + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Get_Metrics */ + /* */ + /* */ + /* Returns the 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). */ + /* */ + /* */ + /* header :: A pointer to either the horizontal or vertical metrics */ + /* structure. */ + /* */ + /* idx :: The glyph index. */ + /* */ + /* */ + /* bearing :: The bearing, either left side or top side. */ + /* */ + /* advance :: The advance width resp. advance height. */ + /* */ + /* */ + /* This function will much probably move to another component in the */ + /* near future, but I haven't decided which yet. */ + /* */ + FT_LOCAL_DEF( void ) + TT_Get_Metrics( TT_HoriHeader* header, + FT_UInt idx, + FT_Short* bearing, + FT_UShort* advance ) + { + TT_LongMetrics longs_m; + FT_UShort k = header->number_Of_HMetrics; + + + if ( k == 0 ) + { + *bearing = *advance = 0; + return; + } + + if ( idx < (FT_UInt)k ) + { + longs_m = (TT_LongMetrics )header->long_metrics + idx; + *bearing = longs_m->bearing; + *advance = longs_m->advance; + } + else + { + *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k]; + *advance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance; + } + } + + + /*************************************************************************/ + /* */ + /* Returns the horizontal metrics in font units for a given glyph. If */ + /* `check' is true, take care of monospaced fonts by returning the */ + /* advance width maximum. */ + /* */ + static void + Get_HMetrics( TT_Face face, + FT_UInt idx, + FT_Bool check, + FT_Short* lsb, + FT_UShort* aw ) + { + TT_Get_Metrics( &face->horizontal, idx, lsb, aw ); + + if ( check && face->postscript.isFixedPitch ) + *aw = face->horizontal.advance_Width_Max; + } + + + /*************************************************************************/ + /* */ + /* Returns the advance width table for a given pixel size if it is found */ + /* in the font's `hdmx' table (if any). */ + /* */ + static FT_Byte* + Get_Advance_Widths( TT_Face face, + FT_UShort ppem ) + { + FT_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; + } + + +#define cur_to_org( n, zone ) \ + FT_MEM_COPY( (zone)->org, (zone)->cur, (n) * sizeof ( FT_Vector ) ) + +#define org_to_cur( n, zone ) \ + FT_MEM_COPY( (zone)->cur, (zone)->org, (n) * sizeof ( FT_Vector ) ) + + + /*************************************************************************/ + /* */ + /* Translates an array of coordinates. */ + /* */ + static void + translate_array( FT_UInt n, + FT_Vector* coords, + FT_Pos delta_x, + FT_Pos delta_y ) + { + FT_UInt 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; + } + + + static void + tt_prepare_zone( TT_GlyphZone zone, + FT_GlyphLoad load, + FT_UInt start_point, + FT_UInt start_contour ) + { + zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); + zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour ); + zone->org = load->extra_points + start_point; + zone->cur = load->outline.points + start_point; + zone->tags = (FT_Byte*)load->outline.tags + start_point; + zone->contours = (FT_UShort*)load->outline.contours + start_contour; + } + + +#undef IS_HINTED +#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) + + + /*************************************************************************/ + /* */ + /* The following functions are used by default with TrueType fonts. */ + /* However, they can be replaced by alternatives if we need to support */ + /* TrueType-compressed formats (like MicroType) in the future. */ + /* */ + /*************************************************************************/ + + FT_CALLBACK_DEF( FT_Error ) + TT_Access_Glyph_Frame( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ) + { + FT_Error error; + FT_Stream stream = loader->stream; + + /* for non-debug mode */ + FT_UNUSED( glyph_index ); + + + FT_TRACE5(( "Glyph %ld\n", glyph_index )); + + /* the following line sets the `error' variable through macros! */ + if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) + return error; + + return TT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + TT_Forget_Glyph_Frame( TT_Loader loader ) + { + FT_Stream stream = loader->stream; + + + FT_FRAME_EXIT(); + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Glyph_Header( TT_Loader loader ) + { + FT_Stream stream = loader->stream; + FT_Int byte_len = loader->byte_len - 10; + + + if ( byte_len < 0 ) + return TT_Err_Invalid_Outline; + + loader->n_contours = FT_GET_SHORT(); + + loader->bbox.xMin = FT_GET_SHORT(); + loader->bbox.yMin = FT_GET_SHORT(); + loader->bbox.xMax = FT_GET_SHORT(); + loader->bbox.yMax = FT_GET_SHORT(); + + FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); + FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, + loader->bbox.xMax )); + FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, + loader->bbox.yMax )); + loader->byte_len = byte_len; + + return TT_Err_Ok; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Simple_Glyph( TT_Loader load ) + { + FT_Error error; + FT_Stream stream = load->stream; + FT_GlyphLoader gloader = load->gloader; + FT_Int n_contours = load->n_contours; + FT_Outline* outline; + TT_Face face = (TT_Face)load->face; + TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph; + FT_UShort n_ins; + FT_Int n, n_points; + FT_Int byte_len = load->byte_len; + + + /* reading the contours endpoints & number of points */ + { + short* cur = gloader->current.outline.contours; + short* limit = cur + n_contours; + + + /* check space for contours array + instructions count */ + byte_len -= 2 * ( n_contours + 1 ); + if ( byte_len < 0 ) + goto Invalid_Outline; + + for ( ; cur < limit; cur++ ) + cur[0] = FT_GET_USHORT(); + + n_points = 0; + if ( n_contours > 0 ) + n_points = cur[-1] + 1; + + error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 ); + if ( error ) + goto Fail; + + /* we'd better check the contours table right now */ + outline = &gloader->current.outline; + + for ( cur = outline->contours + 1; cur < limit; cur++ ) + if ( cur[-1] >= cur[0] ) + goto Invalid_Outline; + } + + /* reading the bytecode instructions */ + slot->control_len = 0; + slot->control_data = 0; + + n_ins = FT_GET_USHORT(); + + FT_TRACE5(( " Instructions size: %d\n", n_ins )); + + if ( n_ins > face->max_profile.maxSizeOfInstructions ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions!\n" )); + error = TT_Err_Too_Many_Hints; + goto Fail; + } + + byte_len -= n_ins; + if ( byte_len < 0 ) + { + FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); + error = TT_Err_Too_Many_Hints; + goto Fail; + } + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + if ( ( load->load_flags & + ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 && + load->instructions ) + { + slot->control_len = n_ins; + slot->control_data = load->instructions; + + FT_MEM_COPY( load->instructions, stream->cursor, n_ins ); + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + stream->cursor += n_ins; + + /* reading the point tags */ + { + FT_Byte* flag = (FT_Byte*)outline->tags; + FT_Byte* limit = flag + n_points; + FT_Byte c, count; + + + while ( flag < limit ) + { + if ( --byte_len < 0 ) + goto Invalid_Outline; + + *flag++ = c = FT_GET_BYTE(); + if ( c & 8 ) + { + if ( --byte_len < 0 ) + goto Invalid_Outline; + + count = FT_GET_BYTE(); + if ( flag + count > limit ) + goto Invalid_Outline; + + for ( ; count > 0; count-- ) + *flag++ = c; + } + } + + /* check that there is enough room to load the coordinates */ + for ( flag = (FT_Byte*)outline->tags; flag < limit; flag++ ) + { + if ( *flag & 2 ) + byte_len -= 1; + else if ( ( *flag & 16 ) == 0 ) + byte_len -= 2; + + if ( *flag & 4 ) + byte_len -= 1; + else if ( ( *flag & 32 ) == 0 ) + byte_len -= 2; + } + + if ( byte_len < 0 ) + goto Invalid_Outline; + } + + /* reading the X coordinates */ + + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + n_points; + FT_Byte* flag = (FT_Byte*)outline->tags; + FT_Pos x = 0; + + + for ( ; vec < limit; vec++, flag++ ) + { + FT_Pos y = 0; + + + if ( *flag & 2 ) + { + y = FT_GET_BYTE(); + if ( ( *flag & 16 ) == 0 ) + y = -y; + } + else if ( ( *flag & 16 ) == 0 ) + y = FT_GET_SHORT(); + + x += y; + vec->x = x; + } + } + + /* reading the Y coordinates */ + + { + FT_Vector* vec = gloader->current.outline.points; + FT_Vector* limit = vec + n_points; + FT_Byte* flag = (FT_Byte*)outline->tags; + FT_Pos x = 0; + + + for ( ; vec < limit; vec++, flag++ ) + { + FT_Pos y = 0; + + + if ( *flag & 4 ) + { + y = FT_GET_BYTE(); + if ( ( *flag & 32 ) == 0 ) + y = -y; + } + else if ( ( *flag & 32 ) == 0 ) + y = FT_GET_SHORT(); + + x += y; + vec->y = x; + } + } + + /* clear the touch tags */ + for ( n = 0; n < n_points; n++ ) + outline->tags[n] &= FT_CURVE_TAG_ON; + + outline->n_points = (FT_UShort)n_points; + outline->n_contours = (FT_Short) n_contours; + + load->byte_len = byte_len; + + Fail: + return error; + + Invalid_Outline: + error = TT_Err_Invalid_Outline; + goto Fail; + } + + + FT_CALLBACK_DEF( FT_Error ) + TT_Load_Composite_Glyph( TT_Loader loader ) + { + FT_Error error; + FT_Stream stream = loader->stream; + FT_GlyphLoader gloader = loader->gloader; + FT_SubGlyph subglyph; + FT_UInt num_subglyphs; + FT_Int byte_len = loader->byte_len; + + + num_subglyphs = 0; + + do + { + FT_Fixed xx, xy, yy, yx; + + + /* check that we can load a new subglyph */ + error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 ); + if ( error ) + goto Fail; + + /* check space */ + byte_len -= 4; + if ( byte_len < 0 ) + goto Invalid_Composite; + + subglyph = gloader->current.subglyphs + num_subglyphs; + + subglyph->arg1 = subglyph->arg2 = 0; + + subglyph->flags = FT_GET_USHORT(); + subglyph->index = FT_GET_USHORT(); + + /* check space */ + byte_len -= 2; + if ( subglyph->flags & ARGS_ARE_WORDS ) + byte_len -= 2; + if ( subglyph->flags & WE_HAVE_A_SCALE ) + byte_len -= 2; + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + byte_len -= 4; + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + byte_len -= 8; + + if ( byte_len < 0 ) + goto Invalid_Composite; + + /* read arguments */ + if ( subglyph->flags & ARGS_ARE_WORDS ) + { + subglyph->arg1 = FT_GET_SHORT(); + subglyph->arg2 = FT_GET_SHORT(); + } + else + { + subglyph->arg1 = FT_GET_CHAR(); + subglyph->arg2 = FT_GET_CHAR(); + } + + /* read transform */ + xx = yy = 0x10000L; + xy = yx = 0; + + if ( subglyph->flags & WE_HAVE_A_SCALE ) + { + xx = (FT_Fixed)FT_GET_SHORT() << 2; + yy = xx; + } + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + { + xx = (FT_Fixed)FT_GET_SHORT() << 2; + yy = (FT_Fixed)FT_GET_SHORT() << 2; + } + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + { + xx = (FT_Fixed)FT_GET_SHORT() << 2; + yx = (FT_Fixed)FT_GET_SHORT() << 2; + xy = (FT_Fixed)FT_GET_SHORT() << 2; + yy = (FT_Fixed)FT_GET_SHORT() << 2; + } + + subglyph->transform.xx = xx; + subglyph->transform.xy = xy; + subglyph->transform.yx = yx; + subglyph->transform.yy = yy; + + num_subglyphs++; + + } while ( subglyph->flags & MORE_COMPONENTS ); + + gloader->current.num_subglyphs = num_subglyphs; + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + { + /* we must undo the FT_FRAME_ENTER in order to point to the */ + /* composite instructions, if we find some. */ + /* we will process them later... */ + /* */ + loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + + stream->cursor - stream->limit ); + } +#endif + + loader->byte_len = byte_len; + + Fail: + return error; + + Invalid_Composite: + error = TT_Err_Invalid_Composite; + goto Fail; + } + + + FT_LOCAL_DEF( void ) + TT_Init_Glyph_Loading( TT_Face face ) + { + face->access_glyph_frame = TT_Access_Glyph_Frame; + face->read_glyph_header = TT_Load_Glyph_Header; + face->read_simple_glyph = TT_Load_Simple_Glyph; + face->read_composite_glyph = TT_Load_Composite_Glyph; + face->forget_glyph_frame = TT_Forget_Glyph_Frame; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Process_Simple_Glyph */ + /* */ + /* */ + /* Once a simple glyph has been loaded, it needs to be processed. */ + /* Usually, this means scaling and hinting through bytecode */ + /* interpretation. */ + /* */ + static FT_Error + TT_Process_Simple_Glyph( TT_Loader load, + FT_Bool debug ) + { + FT_GlyphLoader gloader = load->gloader; + FT_Outline* outline = &gloader->current.outline; + FT_UInt n_points = outline->n_points; +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + FT_UInt n_ins; +#endif + TT_GlyphZone zone = &load->zone; + FT_Error error = TT_Err_Ok; + + FT_UNUSED( debug ); /* used by truetype interpreter only */ + + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + n_ins = load->glyph->control_len; +#endif + + /* add shadow points */ + + /* Now add the two shadow points at n and n + 1. */ + /* We need the left side bearing and advance width. */ + + { + FT_Vector* pp1; + FT_Vector* pp2; + + + /* pp1 = xMin - lsb */ + pp1 = outline->points + n_points; + pp1->x = load->bbox.xMin - load->left_bearing; + pp1->y = 0; + + /* pp2 = pp1 + aw */ + pp2 = pp1 + 1; + pp2->x = pp1->x + load->advance; + pp2->y = 0; + + outline->tags[n_points ] = 0; + outline->tags[n_points + 1] = 0; + } + + /* Note that we return two more points that are not */ + /* part of the glyph outline. */ + + n_points += 2; + + /* set up zone for hinting */ + tt_prepare_zone( zone, &gloader->current, 0, 0 ); + + /* eventually scale the glyph */ + if ( !( load->load_flags & FT_LOAD_NO_SCALE ) ) + { + FT_Vector* vec = zone->cur; + FT_Vector* limit = vec + n_points; + FT_Fixed x_scale = load->size->metrics.x_scale; + FT_Fixed y_scale = load->size->metrics.y_scale; + + + /* first scale the glyph points */ + for ( ; vec < limit; vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + } + + cur_to_org( n_points, zone ); + + /* eventually hint the glyph */ + if ( IS_HINTED( load->load_flags ) ) + { + FT_Pos x = zone->org[n_points-2].x; + + + x = ( ( x + 32 ) & -64 ) - x; + translate_array( n_points, zone->org, x, 0 ); + + org_to_cur( n_points, zone ); + + zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /* now consider hinting */ + if ( n_ins > 0 ) + { + error = TT_Set_CodeRange( load->exec, tt_coderange_glyph, + load->exec->glyphIns, n_ins ); + if ( error ) + goto Exit; + + load->exec->is_composite = FALSE; + load->exec->pedantic_hinting = (FT_Bool)( load->load_flags & + FT_LOAD_PEDANTIC ); + load->exec->pts = *zone; + load->exec->pts.n_points += 2; + + error = TT_Run_Context( load->exec, debug ); + if ( error && load->exec->pedantic_hinting ) + goto Exit; + + error = TT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */ + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + } + + /* save glyph phantom points */ + if ( !load->preserve_pps ) + { + load->pp1 = zone->cur[n_points - 2]; + load->pp2 = zone->cur[n_points - 1]; + } + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + Exit: +#endif + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* load_truetype_glyph */ + /* */ + /* */ + /* Loads a given truetype glyph. Handles composites and uses a */ + /* TT_Loader object. */ + /* */ + static FT_Error + load_truetype_glyph( TT_Loader loader, + FT_UInt glyph_index, + FT_UInt recurse_count ) + { + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + FT_Stream stream = loader->stream; +#endif + + FT_Error error; + TT_Face face = (TT_Face)loader->face; + FT_ULong offset; + FT_Int contours_count; + FT_UInt num_points, count; + FT_Fixed x_scale, y_scale; + FT_GlyphLoader gloader = loader->gloader; + FT_Bool opened_frame = 0; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + struct FT_StreamRec_ inc_stream; + FT_Data glyph_data; + FT_Bool glyph_data_loaded = 0; +#endif + + if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE ) + { + error = TT_Err_Invalid_Composite; + goto Exit; + } + + /* check glyph index */ + if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) + { + error = TT_Err_Invalid_Glyph_Index; + goto Exit; + } + + loader->glyph_index = glyph_index; + num_points = 0; + + x_scale = 0x10000L; + y_scale = 0x10000L; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + x_scale = loader->size->metrics.x_scale; + y_scale = loader->size->metrics.y_scale; + } + + /* get horizontal metrics */ + { + FT_Short left_bearing = 0; + FT_UShort advance_width = 0; + + Get_HMetrics( face, glyph_index, + (FT_Bool)!( loader->load_flags & + FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ), + &left_bearing, + &advance_width ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font see if there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + metrics.bearing_x = left_bearing; + metrics.bearing_y = 0; + metrics.advance = advance_width; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + if ( error ) + goto Exit; + left_bearing = (FT_Short)metrics.bearing_x; + advance_width = (FT_UShort)metrics.advance; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + loader->left_bearing = left_bearing; + loader->advance = advance_width; + + if ( !loader->linear_def ) + { + loader->linear_def = 1; + loader->linear = advance_width; + } + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Set `offset' to the start of the glyph program relative to the */ + /* start of the 'glyf' table, and `count' to the length of the */ + /* glyph program in bytes. */ + /* */ + /* If we are loading glyph data via the incremental interface, set */ + /* the loader stream to a memory stream reading the data returned */ + /* by the interface. */ + + if ( face->root.internal->incremental_interface ) + { + error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &glyph_data ); + if ( error ) + goto Exit; + + glyph_data_loaded = 1; + offset = 0; + count = glyph_data.length; + + FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_Stream_OpenMemory( &inc_stream, + glyph_data.pointer, glyph_data.length ); + + loader->stream = &inc_stream; + } + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + { + offset = face->glyph_locations[glyph_index]; + count = 0; + + if ( glyph_index < (FT_UInt)face->num_locations - 1 ) + count = face->glyph_locations[glyph_index + 1] - offset; + } + + if ( count == 0 ) + { + /* as described by Frederic Loyer, these are spaces, and */ + /* not the unknown glyph. */ + loader->bbox.xMin = 0; + loader->bbox.xMax = 0; + loader->bbox.yMin = 0; + loader->bbox.yMax = 0; + + loader->pp1.x = 0; + loader->pp2.x = loader->advance; + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + if ( loader->exec ) + loader->exec->glyphSize = 0; + +#endif + + error = TT_Err_Ok; + goto Exit; + } + + loader->byte_len = (FT_Int)count; + + offset = loader->glyf_offset + offset; + + /* access glyph frame */ + error = face->access_glyph_frame( loader, glyph_index, offset, count ); + if ( error ) + goto Exit; + + opened_frame = 1; + + /* read first glyph header */ + error = face->read_glyph_header( loader ); + if ( error ) + goto Fail; + + contours_count = loader->n_contours; + + count -= 10; + + loader->pp1.x = loader->bbox.xMin - loader->left_bearing; + loader->pp1.y = 0; + loader->pp2.x = loader->pp1.x + loader->advance; + loader->pp2.y = 0; + + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); + loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* if it is a simple glyph, load it */ + + if ( contours_count >= 0 ) + { + /* check that we can add the contours to the glyph */ + error = FT_GlyphLoader_CheckPoints( gloader, 0, contours_count ); + if ( error ) + goto Fail; + + error = face->read_simple_glyph( loader ); + if ( error ) + goto Fail; + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + { + TT_Size size = (TT_Size)loader->size; + + + error = TT_Process_Simple_Glyph( loader, + (FT_Bool)( size && size->debug ) ); + } + +#else + + error = TT_Process_Simple_Glyph( loader, 0 ); + +#endif + + if ( error ) + goto Fail; + + FT_GlyphLoader_Add( gloader ); + + /* Note: We could have put the simple loader source there */ + /* but the code is fat enough already :-) */ + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + /* otherwise, load a composite! */ + else if ( contours_count == -1 ) + { + TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph; + FT_UInt start_point; +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + FT_UInt start_contour; + FT_ULong ins_pos; /* position of composite instructions, if any */ +#endif + + + /* for each subglyph, read composite header */ + start_point = gloader->base.outline.n_points; +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + start_contour = gloader->base.outline.n_contours; +#endif + + error = face->read_composite_glyph( loader ); + if ( error ) + goto Fail; + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + ins_pos = loader->ins_pos; +#endif + face->forget_glyph_frame( loader ); + opened_frame = 0; + + /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ + /* `as is' in the glyph slot (the client application will be */ + /* responsible for interpreting these data)... */ + /* */ + if ( loader->load_flags & FT_LOAD_NO_RECURSE ) + { + /* set up remaining glyph fields */ + FT_GlyphLoader_Add( gloader ); + + glyph->num_subglyphs = gloader->base.num_subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + glyph->subglyphs = gloader->base.subglyphs; + + goto Exit; + } + + /*********************************************************************/ + /*********************************************************************/ + /*********************************************************************/ + + /* Now, read each subglyph independently. */ + { + FT_Int n, num_base_points, num_new_points; + FT_SubGlyph subglyph = 0; + + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; + + + FT_GlyphLoader_Add( gloader ); + + for ( n = 0; n < (FT_Int)num_subglyphs; n++ ) + { + FT_Vector pp1, pp2; + FT_Pos x, y; + + + /* Each time we call load_truetype_glyph in this loop, the */ + /* value of `gloader.base.subglyphs' can change due to table */ + /* reallocations. We thus need to recompute the subglyph */ + /* pointer on each iteration. */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + pp1 = loader->pp1; + pp2 = loader->pp2; + + num_base_points = gloader->base.outline.n_points; + + error = load_truetype_glyph( loader, subglyph->index, + recurse_count+1 ); + if ( error ) + goto Fail; + + /* restore subglyph pointer */ + subglyph = gloader->base.subglyphs + num_base_subgs + n; + + if ( subglyph->flags & USE_MY_METRICS ) + { + pp1 = loader->pp1; + pp2 = loader->pp2; + } + else + { + loader->pp1 = pp1; + loader->pp2 = pp2; + } + + num_points = gloader->base.outline.n_points; + + num_new_points = num_points - num_base_points; + + /* now perform the transform required for this subglyph */ + + if ( subglyph->flags & ( WE_HAVE_A_SCALE | + WE_HAVE_AN_XY_SCALE | + WE_HAVE_A_2X2 ) ) + { + FT_Vector* cur = gloader->base.outline.points + + num_base_points; + FT_Vector* org = gloader->base.extra_points + + num_base_points; + FT_Vector* limit = cur + num_new_points; + + + for ( ; cur < limit; cur++, org++ ) + { + FT_Vector_Transform( cur, &subglyph->transform ); + FT_Vector_Transform( org, &subglyph->transform ); + } + } + + /* apply offset */ + + if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) + { + FT_UInt k = subglyph->arg1; + FT_UInt l = subglyph->arg2; + FT_Vector* p1; + FT_Vector* p2; + + + if ( start_point + k >= (FT_UInt)num_base_points || + l >= (FT_UInt)num_new_points ) + { + error = TT_Err_Invalid_Composite; + goto Fail; + } + + l += num_base_points; + + p1 = gloader->base.outline.points + start_point + k; + p2 = gloader->base.outline.points + start_point + l; + + x = p1->x - p2->x; + y = p1->y - p2->y; + } + else + { + x = subglyph->arg1; + y = subglyph->arg2; + + /* Use a default value dependent on */ + /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */ + /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */ + +#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + if ( !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) && +#else + if ( ( subglyph->flags & SCALED_COMPONENT_OFFSET ) && +#endif + ( subglyph->flags & ( WE_HAVE_A_SCALE | + WE_HAVE_AN_XY_SCALE | + WE_HAVE_A_2X2 )) ) + { +#if 0 + + /*************************************************************************/ + /* */ + /* This algorithm is what Apple documents. But it doesn't work. */ + /* */ + int a = subglyph->transform.xx > 0 ? subglyph->transform.xx + : -subglyph->transform.xx; + int b = subglyph->transform.yx > 0 ? subglyph->transform.yx + : -subglyph->transform.yx; + int c = subglyph->transform.xy > 0 ? subglyph->transform.xy + : -subglyph->transform.xy; + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + : -subglyph->transform.yy; + int m = a > b ? a : b; + int n = c > d ? c : d; + + + if ( a - b <= 33 && a - b >= -33 ) + m *= 2; + if ( c - d <= 33 && c - d >= -33 ) + n *= 2; + x = FT_MulFix( x, m ); + y = FT_MulFix( y, n ); + +#else /* 0 */ + + /*************************************************************************/ + /* */ + /* This algorithm is a guess and works much better than the above. */ + /* */ + int mac_xscale = FT_SqrtFixed( + FT_MulFix( subglyph->transform.xx, + subglyph->transform.xx ) + + FT_MulFix( subglyph->transform.xy, + subglyph->transform.xy) ); + int mac_yscale = FT_SqrtFixed( + FT_MulFix( subglyph->transform.yy, + subglyph->transform.yy ) + + FT_MulFix( subglyph->transform.yx, + subglyph->transform.yx ) ); + + + x = FT_MulFix( x, mac_xscale ); + y = FT_MulFix( y, mac_yscale ); +#endif /* 0 */ + + } + + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + x = FT_MulFix( x, x_scale ); + y = FT_MulFix( y, y_scale ); + + if ( subglyph->flags & ROUND_XY_TO_GRID ) + { + x = ( x + 32 ) & -64; + y = ( y + 32 ) & -64; + } + } + } + + if ( x || y ) + { + translate_array( num_new_points, + gloader->base.outline.points + num_base_points, + x, y ); + + translate_array( num_new_points, + gloader->base.extra_points + num_base_points, + x, y ); + } + } + + /*******************************************************************/ + /*******************************************************************/ + /*******************************************************************/ + + /* we have finished loading all sub-glyphs; now, look for */ + /* instructions for this composite! */ + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + if ( num_subglyphs > 0 && + loader->exec && + ins_pos > 0 && + subglyph->flags & WE_HAVE_INSTR ) + { + FT_UShort n_ins; + TT_ExecContext exec = loader->exec; + TT_GlyphZone pts; + FT_Vector* pp1; + + + /* read size of instructions */ + if ( FT_STREAM_SEEK( ins_pos ) || + FT_READ_USHORT( n_ins ) ) + goto Fail; + FT_TRACE5(( " Instructions size = %d\n", n_ins )); + + /* in some fonts? */ + if ( n_ins == 0xFFFFU ) + n_ins = 0; + + /* check it */ + if ( n_ins > face->max_profile.maxSizeOfInstructions ) + { + FT_TRACE0(( "Too many instructions (%d) in composite glyph %ld\n", + n_ins, subglyph->index )); + error = TT_Err_Too_Many_Hints; + goto Fail; + } + + /* read the instructions */ + if ( FT_STREAM_READ( exec->glyphIns, n_ins ) ) + goto Fail; + + glyph->control_data = exec->glyphIns; + glyph->control_len = n_ins; + + error = TT_Set_CodeRange( exec, + tt_coderange_glyph, + exec->glyphIns, + n_ins ); + if ( error ) + goto Fail; + + /* prepare the execution context */ + tt_prepare_zone( &exec->pts, &gloader->base, + start_point, start_contour ); + pts = &exec->pts; + + pts->n_points = (short)(num_points + 2); + pts->n_contours = gloader->base.outline.n_contours; + + /* add phantom points */ + pp1 = pts->cur + num_points; + pp1[0] = loader->pp1; + pp1[1] = loader->pp2; + + pts->tags[num_points ] = 0; + pts->tags[num_points + 1] = 0; + + /* if hinting, round the phantom points */ + if ( IS_HINTED( loader->load_flags ) ) + { + pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 ); + pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 ); + } + + { + FT_UInt k; + + + for ( k = 0; k < num_points; k++ ) + pts->tags[k] &= FT_CURVE_TAG_ON; + } + + cur_to_org( num_points + 2, pts ); + + /* now consider hinting */ + if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) + { + exec->is_composite = TRUE; + exec->pedantic_hinting = + (FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC ); + error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug ); + if ( error && exec->pedantic_hinting ) + goto Fail; + } + + /* save glyph origin and advance points */ + loader->pp1 = pp1[0]; + loader->pp2 = pp1[1]; + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + } + /* end of composite loading */ + } + else + { + /* invalid composite count ( negative but not -1 ) */ + error = TT_Err_Invalid_Outline; + goto Fail; + } + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + Fail: + if ( opened_frame ) + face->forget_glyph_frame( loader ); + + Exit: + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_data_loaded ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); +#endif + + return error; + } + + + static FT_Error + compute_glyph_metrics( TT_Loader loader, + FT_UInt glyph_index ) + { + FT_BBox bbox; + TT_Face face = (TT_Face)loader->face; + FT_Fixed y_scale; + TT_GlyphSlot glyph = loader->glyph; + TT_Size size = (TT_Size)loader->size; + + + y_scale = 0x10000L; + if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) + y_scale = size->root.metrics.y_scale; + + if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) + { + glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS; + + /* copy outline to our glyph slot */ + FT_GlyphLoader_CopyPoints( glyph->internal->loader, loader->gloader ); + glyph->outline = glyph->internal->loader->base.outline; + + /* translate array so that (0,0) is the glyph's origin */ + FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); + + FT_Outline_Get_CBox( &glyph->outline, &bbox ); + + if ( IS_HINTED( loader->load_flags ) ) + { + /* grid-fit the bounding box */ + bbox.xMin &= -64; + bbox.yMin &= -64; + bbox.xMax = ( bbox.xMax + 63 ) & -64; + bbox.yMax = ( bbox.yMax + 63 ) & -64; + } + } + else + bbox = loader->bbox; + + /* get the device-independent horizontal advance. It is scaled later */ + /* by the base layer. */ + { + FT_Pos advance = loader->linear; + + + /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ + /* correctly support DynaLab fonts, which have an incorrect */ + /* `advance_Width_Max' field! It is used, to my knowledge, */ + /* exclusively in the X-TrueType font server. */ + /* */ + if ( face->postscript.isFixedPitch && + ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) + advance = face->horizontal.advance_Width_Max; + + /* we need to return the advance in font units in linearHoriAdvance, */ + /* it will be scaled later by the base layer. */ + glyph->linearHoriAdvance = advance; + } + + glyph->metrics.horiBearingX = bbox.xMin; + glyph->metrics.horiBearingY = bbox.yMax; + glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; + + /* don't forget to hint the advance when we need to */ + if ( IS_HINTED( loader->load_flags ) ) + glyph->metrics.horiAdvance = ( glyph->metrics.horiAdvance + 32 ) & -64; + + /* 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'... */ + + { + FT_Short top_bearing; /* vertical top side bearing (EM units) */ + FT_UShort advance_height; /* vertical advance height (EM units) */ + + FT_Pos left; /* scaled vertical left side bearing */ + FT_Pos top; /* scaled vertical top side bearing */ + FT_Pos advance; /* scaled vertical advance height */ + + /* Get the unscaled top bearing and advance height. */ + if ( face->vertical_info && + face->vertical.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_HoriHeader*)&face->vertical, + 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, if there is an OS/2 */ + /* table in the font. Otherwise, we use the */ + /* values defined in the horizontal header. */ + /* */ + /* NOTE2: The sTypoDescender is negative, which is why */ + /* we compute the baseline-to-baseline distance */ + /* here with: */ + /* ascender - descender + linegap */ + /* */ + if ( face->os2.version != 0xFFFFU ) + { + top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 ); + advance_height = (FT_UShort)( face->os2.sTypoAscender - + face->os2.sTypoDescender + + face->os2.sTypoLineGap ); + } + else + { + top_bearing = (FT_Short)( face->horizontal.Line_Gap / 2 ); + advance_height = (FT_UShort)( face->horizontal.Ascender + + face->horizontal.Descender + + face->horizontal.Line_Gap ); + } + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* If this is an incrementally loaded font see if there are */ + /* overriding metrics for this glyph. */ + if ( face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + FT_Error error = 0; + + metrics.bearing_x = 0; + metrics.bearing_y = top_bearing; + metrics.advance = advance_height; + error = + face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, TRUE, &metrics ); + + if ( error ) + return error; + + top_bearing = (FT_Short)metrics.bearing_y; + advance_height = (FT_UShort)metrics.advance; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* We must adjust the top_bearing value from the bounding box given */ + /* in the glyph header to the bounding box calculated with */ + /* FT_Get_Outline_CBox(). */ + + /* scale the metrics */ + if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) + { + top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale ) + - bbox.yMax; + advance = FT_MulFix( advance_height, y_scale ); + } + else + { + top = top_bearing + loader->bbox.yMax - bbox.yMax; + advance = advance_height; + } + + /* set the advance height in design units. It is scaled later by */ + /* the base layer. */ + glyph->linearVertAdvance = advance_height; + + /* XXX: for now, we have no better algorithm for the lsb, but it */ + /* should work fine. */ + /* */ + left = ( bbox.xMin - bbox.xMax ) / 2; + + /* grid-fit them if necessary */ + if ( IS_HINTED( loader->load_flags ) ) + { + 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 ( !face->postscript.isFixedPitch && size && + IS_HINTED( loader->load_flags ) ) + { + FT_Byte* widths = Get_Advance_Widths( face, + size->root.metrics.x_ppem ); + + + if ( widths ) + glyph->metrics.horiAdvance = widths[glyph_index] << 6; + } + + /* set glyph dimensions */ + glyph->metrics.width = bbox.xMax - bbox.xMin; + glyph->metrics.height = bbox.yMax - bbox.yMin; + + return 0; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Load_Glyph */ + /* */ + /* */ + /* A function used to load a single glyph within a given glyph slot, */ + /* for a given size. */ + /* */ + /* */ + /* glyph :: A handle to a target slot object where the glyph */ + /* will be loaded. */ + /* */ + /* size :: A handle to the source face size at which the glyph */ + /* must be scaled/loaded. */ + /* */ + /* glyph_index :: The index of the glyph in the font file. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UShort glyph_index, + FT_Int32 load_flags ) + { + SFNT_Service sfnt; + TT_Face face; + FT_Stream stream; + FT_Error error; + TT_LoaderRec loader; + + + face = (TT_Face)glyph->face; + sfnt = (SFNT_Service)face->sfnt; + stream = face->root.stream; + error = 0; + + if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) || + ( load_flags & FT_LOAD_NO_RECURSE ) ) + { + size = NULL; + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_NO_BITMAP; + } + + glyph->num_subglyphs = 0; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* try to load embedded bitmap if any */ + /* */ + /* XXX: The convention should be emphasized in */ + /* the documents because it can be confusing. */ + if ( size && + size->strike_index != 0xFFFFU && + sfnt->load_sbits && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + + { + TT_SBit_MetricsRec metrics; + + + error = sfnt->load_sbit_image( face, + size->strike_index, + glyph_index, + load_flags, + stream, + &glyph->bitmap, + &metrics ); + if ( !error ) + { + glyph->outline.n_points = 0; + glyph->outline.n_contours = 0; + + glyph->metrics.width = (FT_Pos)metrics.width << 6; + glyph->metrics.height = (FT_Pos)metrics.height << 6; + + glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; + glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; + glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; + + glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; + glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; + glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; + + glyph->format = FT_GLYPH_FORMAT_BITMAP; + if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) + { + glyph->bitmap_left = metrics.vertBearingX; + glyph->bitmap_top = metrics.vertBearingY; + } + else + { + glyph->bitmap_left = metrics.horiBearingX; + glyph->bitmap_top = metrics.horiBearingY; + } + return error; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* return immediately if we only want the embedded bitmaps */ + if ( load_flags & FT_LOAD_SBITS_ONLY ) + return FT_Err_Invalid_Argument; + + /* seek to the beginning of the glyph table. For Type 42 fonts */ + /* the table might be accessed from a Postscript stream or something */ + /* else... */ + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Don't look for the glyph table if this is an incremental font. */ + if ( !face->root.internal->incremental_interface ) + +#endif + + { + error = face->goto_table( face, TTAG_glyf, stream, 0 ); + if ( error ) + { + FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); + goto Exit; + } + } + + FT_MEM_ZERO( &loader, sizeof ( loader ) ); + + /* update the glyph zone bounds */ + { + FT_GlyphLoader gloader = FT_FACE_DRIVER(face)->glyph_loader; + + + loader.gloader = gloader; + + FT_GlyphLoader_Rewind( gloader ); + + tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 ); + tt_prepare_zone( &loader.base, &gloader->base, 0, 0 ); + } + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + if ( size ) + { + /* query new execution context */ + loader.exec = size->debug ? size->context : TT_New_Context( face ); + if ( !loader.exec ) + return TT_Err_Could_Not_Find_Context; + + TT_Load_Context( loader.exec, face, size ); + loader.instructions = loader.exec->glyphIns; + + /* load default graphics state - if needed */ + if ( size->GS.instruct_control & 2 ) + loader.exec->GS = tt_default_graphics_state; + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* clear all outline flags, except the `owner' one */ + glyph->outline.flags = 0; + + /* let's initialize the rest of our loader now */ + + loader.load_flags = load_flags; + + loader.face = (FT_Face)face; + loader.size = (FT_Size)size; + loader.glyph = (FT_GlyphSlot)glyph; + loader.stream = stream; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( face->root.internal->incremental_interface ) + loader.glyf_offset = 0; + else + +#endif + + loader.glyf_offset = FT_STREAM_POS(); + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /* if the cvt program has disabled hinting, the argument */ + /* is ignored. */ + if ( size && ( size->GS.instruct_control & 1 ) ) + loader.load_flags |= FT_LOAD_NO_HINTING; + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* Main loading loop */ + glyph->format = FT_GLYPH_FORMAT_OUTLINE; + glyph->num_subglyphs = 0; + + error = load_truetype_glyph( &loader, glyph_index, 0 ); + if ( !error ) + compute_glyph_metrics( &loader, glyph_index ); + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + if ( !size || !size->debug ) + TT_Done_Context( loader.exec ); + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + /* Set the `high precision' bit flag. */ + /* This is _critical_ to get correct output for monochrome */ + /* TrueType glyphs at all sizes using the bytecode interpreter. */ + /* */ + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/truetype/ttgload.h b/lib/freetype/src/truetype/ttgload.h new file mode 100644 index 0000000..0409713 --- /dev/null +++ b/lib/freetype/src/truetype/ttgload.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* ttgload.h */ +/* */ +/* TrueType Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 +#include "ttobjs.h" + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + TT_Get_Metrics( TT_HoriHeader* header, + FT_UInt index, + FT_Short* bearing, + FT_UShort* advance ); + + FT_LOCAL( void ) + TT_Init_Glyph_Loading( TT_Face face ); + + FT_LOCAL( FT_Error ) + TT_Load_Glyph( TT_Size size, + TT_GlyphSlot glyph, + FT_UShort glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __TTGLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/truetype/ttinterp.c b/lib/freetype/src/truetype/ttinterp.c new file mode 100644 index 0000000..74726a1 --- /dev/null +++ b/lib/freetype/src/truetype/ttinterp.c @@ -0,0 +1,7496 @@ +/***************************************************************************/ +/* */ +/* ttinterp.c */ +/* */ +/* TrueType bytecode interpreter (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_TRIGONOMETRY_H +#include FT_SYSTEM_H + +#include "ttinterp.h" + +#include "tterrors.h" + + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + +#define TT_MULFIX FT_MulFix +#define TT_MULDIV FT_MulDiv +#define TT_INT64 FT_Int64 + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttinterp + +#undef NO_APPLE_PATENT +#define APPLE_THRESHOLD 0x4000000L + + /*************************************************************************/ + /* */ + /* In order to detect infinite loops in the code, we set up a counter */ + /* within the run loop. A single stroke of interpretation is now */ + /* limitet to a maximal number of opcodes defined below. */ + /* */ +#define MAX_RUNNABLE_OPCODES 1000000L + + + /*************************************************************************/ + /* */ + /* There are two kinds of implementations: */ + /* */ + /* 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 fully re-entrant. */ + /* */ + /* The idea is that an indirect implementation may be slower to execute */ + /* on low-end processors that are used in some systems (like 386s or */ + /* even 486s). */ + /* */ + /* 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 code used for */ + /* development. */ + /* */ + /* - It's much more readable that way! */ + /* */ + /* - It's still open to experimentation and tuning. */ + /* */ + /*************************************************************************/ + + +#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ + +#define CUR (*exc) /* see ttobjs.h */ + +#else /* static implementation */ + +#define CUR cur + + static + TT_ExecContextRec 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 */ + + + /*************************************************************************/ + /* */ + /* The instruction argument stack. */ + /* */ +#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ + + + /*************************************************************************/ + /* */ + /* This macro is used whenever `exec' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_EXEC FT_UNUSED( CUR ) + + + /*************************************************************************/ + /* */ + /* This macro is used whenever `args' is unused in a function, to avoid */ + /* stupid warnings from pedantic compilers. */ + /* */ +#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) + + + /*************************************************************************/ + /* */ + /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ + /* increase readabilty of the code. */ + /* */ + /*************************************************************************/ + + +#define SKIP_Code() \ + SkipCode( EXEC_ARG ) + +#define GET_ShortIns() \ + GetShortIns( EXEC_ARG ) + +#define NORMalize( x, y, v ) \ + Normalize( EXEC_ARG_ x, y, v ) + +#define SET_SuperRound( scale, flags ) \ + SetSuperRound( EXEC_ARG_ scale, flags ) + +#define ROUND_None( d, c ) \ + Round_None( EXEC_ARG_ d, c ) + +#define INS_Goto_CodeRange( range, ip ) \ + Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) + +#define CUR_Func_project( x, y ) \ + CUR.func_project( EXEC_ARG_ x, y ) + +#define CUR_Func_move( z, p, d ) \ + CUR.func_move( EXEC_ARG_ z, p, d ) + +#define CUR_Func_dualproj( x, y ) \ + CUR.func_dualproj( EXEC_ARG_ x, y ) + +#define CUR_Func_freeProj( x, y ) \ + CUR.func_freeProj( EXEC_ARG_ x, y ) + +#define CUR_Func_round( d, c ) \ + CUR.func_round( EXEC_ARG_ d, c ) + +#define CUR_Func_read_cvt( index ) \ + CUR.func_read_cvt( EXEC_ARG_ index ) + +#define CUR_Func_write_cvt( index, val ) \ + CUR.func_write_cvt( EXEC_ARG_ index, val ) + +#define CUR_Func_move_cvt( index, val ) \ + CUR.func_move_cvt( EXEC_ARG_ index, val ) + +#define CURRENT_Ratio() \ + Current_Ratio( EXEC_ARG ) + +#define CURRENT_Ppem() \ + Current_Ppem( EXEC_ARG ) + +#define CUR_Ppem() \ + Cur_PPEM( EXEC_ARG ) + +#define INS_SxVTL( a, b, c, d ) \ + Ins_SxVTL( EXEC_ARG_ a, b, c, d ) + +#define COMPUTE_Funcs() \ + Compute_Funcs( EXEC_ARG ) + +#define COMPUTE_Round( a ) \ + Compute_Round( EXEC_ARG_ a ) + +#define COMPUTE_Point_Displacement( a, b, c, d ) \ + Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) + +#define MOVE_Zp2_Point( a, b, c, t ) \ + Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) + + + /*************************************************************************/ + /* */ + /* Instruction dispatch function, as used by the interpreter. */ + /* */ + typedef void (*TInstruction_Function)( INS_ARG ); + + + /*************************************************************************/ + /* */ + /* A simple bounds-checking macro. */ + /* */ +#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) + + +#undef SUCCESS +#define SUCCESS 0 + +#undef FAILURE +#define FAILURE 1 + + + /*************************************************************************/ + /* */ + /* CODERANGE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Goto_CodeRange */ + /* */ + /* */ + /* Switches to a new code range (updates the code related elements in */ + /* `exec', and `IP'). */ + /* */ + /* */ + /* range :: The new execution code range. */ + /* */ + /* IP :: The new IP in the new code range. */ + /* */ + /* */ + /* exec :: The target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ) + { + TT_CodeRange* coderange; + + + FT_ASSERT( range >= 1 && range <= 3 ); + + coderange = &exec->codeRangeTable[range - 1]; + + FT_ASSERT( coderange->base != NULL ); + + /* 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. */ + /* */ + FT_ASSERT( (FT_ULong)IP <= coderange->size ); + + exec->code = coderange->base; + exec->codeSize = coderange->size; + exec->IP = IP; + exec->curRange = range; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Set_CodeRange */ + /* */ + /* */ + /* Sets a code range. */ + /* */ + /* */ + /* range :: The code range index. */ + /* */ + /* base :: The new code base. */ + /* */ + /* length :: The range size in bytes. */ + /* */ + /* */ + /* exec :: The target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = (FT_Byte*)base; + exec->codeRangeTable[range - 1].size = length; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Clear_CodeRange */ + /* */ + /* */ + /* Clears a code range. */ + /* */ + /* */ + /* range :: The code range index. */ + /* */ + /* */ + /* exec :: The target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Does not set the Error variable. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ) + { + FT_ASSERT( range >= 1 && range <= 3 ); + + exec->codeRangeTable[range - 1].base = NULL; + exec->codeRangeTable[range - 1].size = 0; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* EXECUTION CONTEXT ROUTINES */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Destroy_Context */ + /* */ + /* */ + /* Destroys a given context. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Destroy_Context( TT_ExecContext exec, + FT_Memory memory ) + { + /* free composite load stack */ + FT_FREE( exec->loadStack ); + exec->loadSize = 0; + + /* points zone */ + exec->maxPoints = 0; + exec->maxContours = 0; + + /* free stack */ + FT_FREE( exec->stack ); + exec->stackSize = 0; + + /* free call stack */ + FT_FREE( exec->callStack ); + exec->callSize = 0; + exec->callTop = 0; + + /* free glyph code range */ + FT_FREE( exec->glyphIns ); + exec->glyphSize = 0; + + exec->size = NULL; + exec->face = NULL; + + FT_FREE( exec ); + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Init_Context */ + /* */ + /* */ + /* Initializes a context object. */ + /* */ + /* */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* face :: A handle to the source TrueType face object. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Init_Context( TT_ExecContext exec, + TT_Face face, + FT_Memory memory ) + { + FT_Error error; + + + FT_TRACE1(( "Init_Context: new object at 0x%08p, parent = 0x%08p\n", + exec, face )); + + exec->memory = memory; + exec->callSize = 32; + + if ( FT_NEW_ARRAY( exec->callStack, exec->callSize ) ) + 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->size = NULL; + + return TT_Err_Ok; + + Fail_Memory: + FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n", + (FT_Long)exec )); + TT_Destroy_Context( exec, memory ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Update_Max */ + /* */ + /* */ + /* Checks the size of a buffer and reallocates it if necessary. */ + /* */ + /* */ + /* memory :: A handle to the parent memory object. */ + /* */ + /* multiplier :: The size in bytes of each element in the buffer. */ + /* */ + /* new_max :: The new capacity (size) of the buffer. */ + /* */ + /* */ + /* size :: The address of the buffer's current size expressed */ + /* in elements. */ + /* */ + /* buff :: The address of the buffer base pointer. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + Update_Max( FT_Memory memory, + FT_ULong* size, + FT_Long multiplier, + void** buff, + FT_ULong new_max ) + { + FT_Error error; + + + if ( *size < new_max ) + { + FT_FREE( *buff ); + if ( FT_ALLOC( *buff, new_max * multiplier ) ) + return error; + *size = new_max; + } + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Load_Context */ + /* */ + /* */ + /* Prepare an execution context for glyph hinting. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* size :: A handle to the source size object. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ) + { + FT_Int i; + FT_ULong tmp; + TT_MaxProfile* maxp; + FT_Error error; + + + exec->face = face; + maxp = &face->max_profile; + exec->size = size; + + if ( size ) + { + exec->numFDefs = size->num_function_defs; + exec->maxFDefs = size->max_function_defs; + exec->numIDefs = size->num_instruction_defs; + exec->maxIDefs = size->max_instruction_defs; + exec->FDefs = size->function_defs; + exec->IDefs = size->instruction_defs; + exec->tt_metrics = size->ttmetrics; + exec->metrics = size->metrics; + + exec->maxFunc = size->max_func; + exec->maxIns = size->max_ins; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + exec->codeRangeTable[i] = size->codeRangeTable[i]; + + /* set graphics state */ + exec->GS = size->GS; + + exec->cvtSize = size->cvt_size; + exec->cvt = size->cvt; + + exec->storeSize = size->storage_size; + exec->storage = size->storage; + + exec->twilight = size->twilight; + } + + error = Update_Max( exec->memory, + &exec->loadSize, + sizeof ( TT_SubGlyphRec ), + (void**)&exec->loadStack, + exec->face->max_components + 1 ); + if ( error ) + return error; + + /* XXX: We reserve a little more elements on the stack to deal safely */ + /* with broken fonts like arialbs, courbs, timesbs, etc. */ + tmp = exec->stackSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_F26Dot6 ), + (void**)&exec->stack, + maxp->maxStackElements + 32 ); + exec->stackSize = (FT_UInt)tmp; + if ( error ) + return error; + + tmp = exec->glyphSize; + error = Update_Max( exec->memory, + &tmp, + sizeof ( FT_Byte ), + (void**)&exec->glyphIns, + maxp->maxSizeOfInstructions ); + exec->glyphSize = (FT_UShort)tmp; + if ( error ) + return error; + + exec->pts.n_points = 0; + exec->pts.n_contours = 0; + + exec->instruction_trap = FALSE; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Save_Context */ + /* */ + /* */ + /* Saves the code ranges in a `size' object. */ + /* */ + /* */ + /* exec :: A handle to the source execution context. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size size ) + { + FT_Int i; + + + /* XXXX: Will probably disappear soon with all the code range */ + /* management, which is now rather obsolete. */ + /* */ + size->num_function_defs = exec->numFDefs; + size->num_instruction_defs = exec->numIDefs; + + size->max_func = exec->maxFunc; + size->max_ins = exec->maxIns; + + for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) + size->codeRangeTable[i] = exec->codeRangeTable[i]; + + return TT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Run_Context */ + /* */ + /* */ + /* Executes one or more instructions in the execution context. */ + /* */ + /* */ + /* debug :: A Boolean flag. If set, the function sets some internal */ + /* variables and returns immediately, otherwise TT_RunIns() */ + /* is called. */ + /* */ + /* This is commented out currently. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* */ + /* TrueTyoe error code. 0 means success. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ) + { + FT_Error error; + + + if ( ( error = TT_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 1 + FT_UNUSED( debug ); + + return exec->face->interpreter( exec ); +#else + if ( !debug ) + return TT_RunIns( exec ); + else + return TT_Err_Ok; +#endif + } + + + const TT_GraphicsState tt_default_graphics_state = + { + 0, 0, 0, + { 0x4000, 0 }, + { 0x4000, 0 }, + { 0x4000, 0 }, + 1, 64, 1, + TRUE, 68, 0, 0, 9, 3, + 0, FALSE, 2, 1, 1, 1 + }; + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( TT_ExecContext ) + TT_New_Context( TT_Face face ) + { + TT_Driver driver; + TT_ExecContext exec; + FT_Memory memory; + + + if ( !face ) + return 0; + + driver = (TT_Driver)face->root.driver; + + memory = driver->root.root.memory; + exec = driver->context; + + if ( !driver->context ) + { + FT_Error error; + + + /* allocate object */ + if ( FT_NEW( exec ) ) + goto Exit; + + /* initialize it */ + error = Init_Context( exec, face, memory ); + if ( error ) + goto Fail; + + /* store it into the driver */ + driver->context = exec; + } + + Exit: + return driver->context; + + Fail: + FT_FREE( exec ); + + return 0; + } + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Done_Context */ + /* */ + /* */ + /* Discards an execution context. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Done_Context( TT_ExecContext exec ) + { + /* Nothing at all for now */ + FT_UNUSED( exec ); + + return TT_Err_Ok; + } + + + + /*************************************************************************/ + /* */ + /* 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 FT_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 FT_Char opcode_length[256] = + { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + + static + const FT_Vector Null_Vector = {0,0}; + + +#undef PACK + + +#undef NULL_Vector +#define NULL_Vector (FT_Vector*)&Null_Vector + + + /* compute (a*b)/2^14 with maximal accuracy and rounding */ + static FT_Int32 + TT_MulFix14( FT_Int32 a, + FT_Int b ) + { + FT_Int32 m, s, hi; + FT_UInt32 l, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( a & 0xFFFFU ) * b ); + m = ( a >> 16 ) * b; + + lo = l + (FT_UInt32)( m << 16 ); + hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += (l < lo); + + return ( hi << 18 ) | ( l >> 14 ); + } + + + /* compute (ax*bx+ay*by)/2^14 with maximal accuracy and rounding */ + static FT_Int32 + TT_DotFix14( FT_Int32 ax, + FT_Int32 ay, + FT_Int bx, + FT_Int by ) + { + FT_Int32 m, s, hi1, hi2, hi; + FT_UInt32 l, lo1, lo2, lo; + + + /* compute ax*bx as 64-bit value */ + l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx ); + m = ( ax >> 16 ) * bx; + + lo1 = l + (FT_UInt32)( m << 16 ); + hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l ); + + /* compute ay*by as 64-bit value */ + l = (FT_UInt32)( ( ay & 0xFFFFU ) * by ); + m = ( ay >> 16 ) * by; + + lo2 = l + (FT_UInt32)( m << 16 ); + hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l ); + + /* add them */ + lo = lo1 + lo2; + hi = hi1 + hi2 + ( lo < lo1 ); + + /* divide the result by 2^14 with rounding */ + s = hi >> 31; + l = lo + (FT_UInt32)s; + hi += s + ( l < lo ); + lo = l; + + l = lo + 0x2000U; + hi += ( l < lo ); + + return ( hi << 18 ) | ( l >> 14 ); + } + + + /* return length of given vector */ + +#if 0 + + static FT_Int32 + TT_VecLen( FT_Int32 x, + FT_Int32 y ) + { + FT_Int32 m, hi1, hi2, hi; + FT_UInt32 l, lo1, lo2, lo; + + + /* compute x*x as 64-bit value */ + lo = (FT_UInt32)( x & 0xFFFFU ); + hi = x >> 16; + + l = lo * lo; + m = hi * lo; + hi = hi * hi; + + lo1 = l + (FT_UInt32)( m << 17 ); + hi1 = hi + ( m >> 15 ) + ( lo1 < l ); + + /* compute y*y as 64-bit value */ + lo = (FT_UInt32)( y & 0xFFFFU ); + hi = y >> 16; + + l = lo * lo; + m = hi * lo; + hi = hi * hi; + + lo2 = l + (FT_UInt32)( m << 17 ); + hi2 = hi + ( m >> 15 ) + ( lo2 < l ); + + /* add them to get 'x*x+y*y' as 64-bit value */ + lo = lo1 + lo2; + hi = hi1 + hi2 + ( lo < lo1 ); + + /* compute the square root of this value */ + { + FT_UInt32 root, rem, test_div; + FT_Int count; + + + root = 0; + + { + rem = 0; + count = 32; + do + { + rem = ( rem << 2 ) | ( (FT_UInt32)hi >> 30 ); + hi = ( hi << 2 ) | ( lo >> 30 ); + lo <<= 2; + root <<= 1; + test_div = ( root << 1 ) + 1; + + if ( rem >= test_div ) + { + rem -= test_div; + root += 1; + } + } while ( --count ); + } + + return (FT_Int32)root; + } + } + +#else + + /* this version uses FT_Vector_Length which computes the same value */ + /* much, much faster.. */ + /* */ + static FT_F26Dot6 + TT_VecLen( FT_F26Dot6 X, + FT_F26Dot6 Y ) + { + FT_Vector v; + + + v.x = X; + v.y = Y; + + return FT_Vector_Length( &v ); + } + +#endif + + + /*************************************************************************/ + /* */ + /* */ + /* Current_Ratio */ + /* */ + /* */ + /* Returns the current aspect ratio scaling factor depending on the */ + /* projection vector's state and device resolutions. */ + /* */ + /* */ + /* The aspect ratio in 16.16 format, always <= 1.0 . */ + /* */ + static FT_Long + Current_Ratio( EXEC_OP ) + { + if ( CUR.tt_metrics.ratio ) + return CUR.tt_metrics.ratio; + + if ( CUR.GS.projVector.y == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; + + else if ( CUR.GS.projVector.x == 0 ) + CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; + + else + { + FT_Long x, y; + + x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 ); + y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 ); + CUR.tt_metrics.ratio = TT_VecLen( x, y ); + } + + return CUR.tt_metrics.ratio; + } + + + static FT_Long + Current_Ppem( EXEC_OP ) + { + return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* Functions related to the control value table (CVT). */ + /* */ + /*************************************************************************/ + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT( EXEC_OP_ FT_ULong idx ) + { + return CUR.cvt[idx]; + } + + + FT_CALLBACK_DEF( FT_F26Dot6 ) + Read_CVT_Stretched( EXEC_OP_ FT_ULong idx ) + { + return TT_MULFIX( CUR.cvt[idx], CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Write_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = value; + } + + + FT_CALLBACK_DEF( void ) + Write_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] = FT_DivFix( value, CURRENT_Ratio() ); + } + + + FT_CALLBACK_DEF( void ) + Move_CVT( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += value; + } + + + FT_CALLBACK_DEF( void ) + Move_CVT_Stretched( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ) + { + CUR.cvt[idx] += FT_DivFix( value, CURRENT_Ratio() ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* GetShortIns */ + /* */ + /* */ + /* Returns a short integer taken from the instruction stream at */ + /* address IP. */ + /* */ + /* */ + /* Short read at code[IP]. */ + /* */ + /* */ + /* This one could become a macro. */ + /* */ + static FT_Short + GetShortIns( EXEC_OP ) + { + /* Reading a byte stream so there is no endianess (DaveP) */ + CUR.IP += 2; + return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + + CUR.code[CUR.IP - 1] ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Ins_Goto_CodeRange */ + /* */ + /* */ + /* Goes to a certain code range in the instruction stream. */ + /* */ + /* */ + /* aRange :: The index of the code range. */ + /* */ + /* aIP :: The new IP address in the code range. */ + /* */ + /* */ + /* SUCCESS or FAILURE. */ + /* */ + static FT_Bool + Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, + FT_ULong aIP ) + { + TT_CodeRange* range; + + + if ( aRange < 1 || aRange > 3 ) + { + CUR.error = TT_Err_Bad_Argument; + return FAILURE; + } + + range = &CUR.codeRangeTable[aRange - 1]; + + if ( range->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 > range->size ) + { + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + CUR.code = range->base; + CUR.codeSize = range->size; + CUR.IP = aIP; + CUR.curRange = aRange; + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Direct_Move */ + /* */ + /* */ + /* Moves a point by a given distance along the freedom vector. The */ + /* point will be `touched'. */ + /* */ + /* */ + /* point :: The index of the point to move. */ + /* */ + /* distance :: The distance to apply. */ + /* */ + /* */ + /* zone :: The affected glyph zone. */ + /* */ + static void + Direct_Move( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_F26Dot6 v; + + + v = CUR.GS.freeVector.x; + + if ( v != 0 ) + { + +#ifdef NO_APPLE_PATENT + + if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) + zone->cur[point].x += distance; + +#else + + zone->cur[point].x += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + +#endif + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + v = CUR.GS.freeVector.y; + + if ( v != 0 ) + { + +#ifdef NO_APPLE_PATENT + + if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) + zone->cur[point].y += distance; + +#else + + zone->cur[point].y += TT_MULDIV( distance, + v * 0x10000L, + CUR.F_dot_P ); + +#endif + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* Special versions of Direct_Move() */ + /* */ + /* The following versions are used whenever both vectors are both */ + /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* */ + /*************************************************************************/ + + + static void + Direct_Move_X( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->cur[point].x += distance; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + + static void + Direct_Move_Y( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ) + { + FT_UNUSED_EXEC; + + zone->cur[point].y += distance; + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_None */ + /* */ + /* */ + /* Does not round, but adds engine compensation. */ + /* */ + /* */ + /* distance :: The distance (not) to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* The compensated distance. */ + /* */ + /* */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_None( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + if ( distance >= 0 ) + { + val = distance + compensation; + if ( val < 0 ) + val = 0; + } + else { + val = distance - compensation; + if ( val > 0 ) + val = 0; + } + return val; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_To_Grid */ + /* */ + /* */ + /* Rounds value to grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + 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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_To_Half_Grid */ + /* */ + /* */ + /* Rounds value to half grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + 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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_Down_To_Grid */ + /* */ + /* */ + /* Rounds value down to grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + 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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_Up_To_Grid */ + /* */ + /* */ + /* Rounds value up to grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + + FT_UNUSED_EXEC; + + 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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_To_Double_Grid */ + /* */ + /* */ + /* Rounds value to double grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + static FT_F26Dot6 + Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_F26Dot6 val; + + FT_UNUSED_EXEC; + + + 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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_Super */ + /* */ + /* */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + /* */ + /* The TrueType specification says very few about the relationship */ + /* between rounding and engine compensation. However, it seems from */ + /* the description of super round that we should add the compensation */ + /* before rounding. */ + /* */ + static FT_F26Dot6 + Round_Super( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_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; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Round_Super_45 */ + /* */ + /* */ + /* Super-rounds value to grid after adding engine compensation. */ + /* */ + /* */ + /* distance :: The distance to round. */ + /* */ + /* compensation :: The engine compensation. */ + /* */ + /* */ + /* Rounded distance. */ + /* */ + /* */ + /* There is a separate function for Round_Super_45() as we may need */ + /* greater precision. */ + /* */ + static FT_F26Dot6 + Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ) + { + FT_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 */ + /* */ + /* */ + /* Sets the rounding mode. */ + /* */ + /* */ + /* round_mode :: The rounding mode to be used. */ + /* */ + static void + Compute_Round( EXEC_OP_ FT_Byte round_mode ) + { + switch ( round_mode ) + { + case TT_Round_Off: + CUR.func_round = (TT_Round_Func)Round_None; + break; + + case TT_Round_To_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Grid; + break; + + case TT_Round_Up_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + break; + + case TT_Round_Down_To_Grid: + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + break; + + case TT_Round_To_Half_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + break; + + case TT_Round_To_Double_Grid: + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + break; + + case TT_Round_Super: + CUR.func_round = (TT_Round_Func)Round_Super; + break; + + case TT_Round_Super_45: + CUR.func_round = (TT_Round_Func)Round_Super_45; + break; + } + } + + + /*************************************************************************/ + /* */ + /* */ + /* SetSuperRound */ + /* */ + /* */ + /* Sets Super Round parameters. */ + /* */ + /* */ + /* GridPeriod :: Grid period */ + /* selector :: SROUND opcode */ + /* */ + static void + SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, + FT_Long selector ) + { + switch ( (FT_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 ( (FT_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 = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; + + CUR.period /= 256; + CUR.phase /= 256; + CUR.threshold /= 256; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Project */ + /* */ + /* */ + /* Computes the projection of vector given by (v2-v1) along the */ + /* current projection vector. */ + /* */ + /* */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ) + { + return TT_DotFix14( v1->x - v2->x, + v1->y - v2->y, + CUR.GS.projVector.x, + CUR.GS.projVector.y ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Dual_Project */ + /* */ + /* */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* current dual vector. */ + /* */ + /* */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Dual_Project( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ) + { + return TT_DotFix14( v1->x - v2->x, + v1->y - v2->y, + CUR.GS.dualVector.x, + CUR.GS.dualVector.y ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Free_Project */ + /* */ + /* */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* current freedom vector. */ + /* */ + /* */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Free_Project( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ) + { + return TT_DotFix14( v1->x - v2->x, + v1->y - v2->y, + CUR.GS.freeVector.x, + CUR.GS.freeVector.y ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Project_x */ + /* */ + /* */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* horizontal axis. */ + /* */ + /* */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_x( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ) + { + FT_UNUSED_EXEC; + + return ( v1->x - v2->x ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Project_y */ + /* */ + /* */ + /* Computes the projection of the vector given by (v2-v1) along the */ + /* vertical axis. */ + /* */ + /* */ + /* v1 :: First input vector. */ + /* v2 :: Second input vector. */ + /* */ + /* */ + /* The distance in F26dot6 format. */ + /* */ + static FT_F26Dot6 + Project_y( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ) + { + FT_UNUSED_EXEC; + + return ( v1->y - v2->y ); + } + + + /*************************************************************************/ + /* */ + /* */ + /* Compute_Funcs */ + /* */ + /* */ + /* Computes the projection and movement function pointers according */ + /* to the current graphics state. */ + /* */ + static void + Compute_Funcs( EXEC_OP ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + { + CUR.func_freeProj = (TT_Project_Func)Project_x; + CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; + } + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + { + CUR.func_freeProj = (TT_Project_Func)Project_y; + CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; + } + else + { + CUR.func_freeProj = (TT_Project_Func)Free_Project; + CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + + (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; + } + } + + if ( CUR.GS.projVector.x == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_x; + else + { + if ( CUR.GS.projVector.y == 0x4000 ) + CUR.func_project = (TT_Project_Func)Project_y; + else + CUR.func_project = (TT_Project_Func)Project; + } + + if ( CUR.GS.dualVector.x == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_x; + else + { + if ( CUR.GS.dualVector.y == 0x4000 ) + CUR.func_dualproj = (TT_Project_Func)Project_y; + else + CUR.func_dualproj = (TT_Project_Func)Dual_Project; + } + + CUR.func_move = (TT_Move_Func)Direct_Move; + + if ( CUR.F_dot_P == 0x40000000L ) + { + if ( CUR.GS.freeVector.x == 0x4000 ) + CUR.func_move = (TT_Move_Func)Direct_Move_X; + else + { + if ( CUR.GS.freeVector.y == 0x4000 ) + CUR.func_move = (TT_Move_Func)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.tt_metrics.ratio = 0; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Normalize */ + /* */ + /* */ + /* Norms a vector. */ + /* */ + /* */ + /* Vx :: The horizontal input vector coordinate. */ + /* Vy :: The vertical input vector coordinate. */ + /* */ + /* */ + /* R :: The normed unit vector. */ + /* */ + /* */ + /* Returns FAILURE if a vector parameter is zero. */ + /* */ + /* */ + /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ + /* R is undefined. */ + /* */ + + + static FT_Bool + Normalize( EXEC_OP_ FT_F26Dot6 Vx, + FT_F26Dot6 Vy, + FT_UnitVector* R ) + { + FT_F26Dot6 W; + FT_Bool S1, S2; + + FT_UNUSED_EXEC; + + + if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) + { + Vx *= 0x100; + Vy *= 0x100; + + W = TT_VecLen( Vx, Vy ); + + if ( W == 0 ) + { + /* XXX: UNDOCUMENTED! It seems that it is possible to try */ + /* to normalize the vector (0,0). Return immediately. */ + return SUCCESS; + } + + R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); + R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); + + return SUCCESS; + } + + W = TT_VecLen( Vx, Vy ); + + Vx = FT_MulDiv( Vx, 0x4000L, W ); + Vy = FT_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 = (FT_F2Dot14)Vx; /* Type conversion */ + R->y = (FT_F2Dot14)Vy; /* Type conversion */ + + return SUCCESS; + } + + + /*************************************************************************/ + /* */ + /* Here we start with the implementation of the various opcodes. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, + FT_UShort aIdx2, + FT_Int aOpc, + FT_UnitVector* Vec ) + { + FT_Long A, B, C; + FT_Vector* p1; + FT_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; /* counter clockwise 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 are all defined there. */ + +#define DO_SVTCA \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_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 \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_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 \ + { \ + FT_Short A, B; \ + \ + \ + A = (FT_Short)( CUR.opcode & 1 ) << 14; \ + B = A ^ (FT_Short)0x4000; \ + \ + CUR.GS.freeVector.x = A; \ + CUR.GS.freeVector.y = B; \ + \ + COMPUTE_Funcs(); \ + } + + +#define DO_SPVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_UShort)args[0], \ + CUR.opcode, \ + &CUR.GS.projVector ) == SUCCESS ) \ + { \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVTL \ + if ( INS_SxVTL( (FT_UShort)args[1], \ + (FT_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 \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_Short)args[0]; \ + X = (FT_Long)S; \ + \ + NORMalize( X, Y, &CUR.GS.projVector ); \ + \ + CUR.GS.dualVector = CUR.GS.projVector; \ + COMPUTE_Funcs(); \ + } + + +#define DO_SFVFS \ + { \ + FT_Short S; \ + FT_Long X, Y; \ + \ + \ + /* Only use low 16bits, then sign extend */ \ + S = (FT_Short)args[1]; \ + Y = (FT_Long)S; \ + S = (FT_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 = (FT_UShort)args[0]; + + +#define DO_SRP1 \ + CUR.GS.rp1 = (FT_UShort)args[0]; + + +#define DO_SRP2 \ + CUR.GS.rp2 = (FT_UShort)args[0]; + + +#define DO_RTHG \ + CUR.GS.round_state = TT_Round_To_Half_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; + + +#define DO_RTG \ + CUR.GS.round_state = TT_Round_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Grid; + + +#define DO_RTDG \ + CUR.GS.round_state = TT_Round_To_Double_Grid; \ + CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; + + +#define DO_RUTG \ + CUR.GS.round_state = TT_Round_Up_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; + + +#define DO_RDTG \ + CUR.GS.round_state = TT_Round_Down_To_Grid; \ + CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; + + +#define DO_ROFF \ + CUR.GS.round_state = TT_Round_Off; \ + CUR.func_round = (TT_Round_Func)Round_None; + + +#define DO_SROUND \ + SET_SuperRound( 0x4000, args[0] ); \ + CUR.GS.round_state = TT_Round_Super; \ + CUR.func_round = (TT_Round_Func)Round_Super; + + +#define DO_S45ROUND \ + SET_SuperRound( 0x2D41, args[0] ); \ + CUR.GS.round_state = TT_Round_Super_45; \ + CUR.func_round = (TT_Round_Func)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 = args[0]; + + +#define DO_SCVTCI \ + CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; + + +#define DO_SSWCI \ + CUR.GS.single_width_cutin = (FT_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 = (FT_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 = (FT_Short)args[0]; + + +#define DO_SDS \ + CUR.GS.delta_shift = (FT_Short)args[0]; + + +#define DO_MD /* nothing */ + + +#define DO_MPPEM \ + args[0] = CURRENT_Ppem(); + + + /* Note: The pointSize should be irrelevant in a given font program; */ + /* we thus decide to return only the ppem. */ +#if 0 + +#define DO_MPS \ + args[0] = CUR.metrics.pointSize; + +#else + +#define DO_MPS \ + args[0] = CURRENT_Ppem(); + +#endif /* 0 */ + + +#define DO_DUP \ + args[1] = args[0]; + + +#define DO_CLEAR \ + CUR.new_top = 0; + + +#define DO_SWAP \ + { \ + FT_Long L; \ + \ + \ + L = args[0]; \ + args[0] = args[1]; \ + args[1] = L; \ + } + + +#define DO_DEPTH \ + args[0] = CUR.top; + + +#define DO_CINDEX \ + { \ + FT_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 \ + { \ + FT_ULong I = (FT_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 \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.storeSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.storage[I] = args[1]; \ + } + + +#define DO_RCVT \ + { \ + FT_ULong I = (FT_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 \ + { \ + FT_ULong I = (FT_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 \ + { \ + FT_ULong I = (FT_ULong)args[0]; \ + \ + \ + if ( BOUNDS( I, CUR.cvtSize ) ) \ + { \ + if ( CUR.pedantic_hinting ) \ + { \ + ARRAY_BOUND_ERROR; \ + } \ + } \ + else \ + CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ + } + + +#define DO_DEBUG \ + CUR.error = TT_Err_Debug_OpCode; + + +#define DO_ROUND \ + args[0] = CUR_Func_round( \ + args[0], \ + CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); + + +#define DO_NROUND \ + args[0] = ROUND_None( args[0], \ + CUR.tt_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 Coordinate Axis */ + /* Opcode range: 0x00-0x01 */ + /* Stack: --> */ + /* */ + static void + Ins_SVTCA( INS_ARG ) + { + DO_SVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTCA[a]: Set PVector to Coordinate Axis */ + /* Opcode range: 0x02-0x03 */ + /* Stack: --> */ + /* */ + static void + Ins_SPVTCA( INS_ARG ) + { + DO_SPVTCA + } + + + /*************************************************************************/ + /* */ + /* SFVTCA[a]: Set FVector to Coordinate Axis */ + /* Opcode range: 0x04-0x05 */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTCA( INS_ARG ) + { + DO_SFVTCA + } + + + /*************************************************************************/ + /* */ + /* SPVTL[a]: Set PVector To Line */ + /* Opcode range: 0x06-0x07 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SPVTL( INS_ARG ) + { + DO_SPVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTL[a]: Set FVector To Line */ + /* Opcode range: 0x08-0x09 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SFVTL( INS_ARG ) + { + DO_SFVTL + } + + + /*************************************************************************/ + /* */ + /* SFVTPV[]: Set FVector To PVector */ + /* Opcode range: 0x0E */ + /* Stack: --> */ + /* */ + static void + Ins_SFVTPV( INS_ARG ) + { + DO_SFVTPV + } + + + /*************************************************************************/ + /* */ + /* SPVFS[]: Set PVector From Stack */ + /* Opcode range: 0x0A */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SPVFS( INS_ARG ) + { + DO_SPVFS + } + + + /*************************************************************************/ + /* */ + /* SFVFS[]: Set FVector From Stack */ + /* Opcode range: 0x0B */ + /* Stack: f2.14 f2.14 --> */ + /* */ + static void + Ins_SFVFS( INS_ARG ) + { + DO_SFVFS + } + + + /*************************************************************************/ + /* */ + /* GPV[]: Get Projection Vector */ + /* Opcode range: 0x0C */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GPV( INS_ARG ) + { + DO_GPV + } + + + /*************************************************************************/ + /* GFV[]: Get Freedom Vector */ + /* Opcode range: 0x0D */ + /* Stack: ef2.14 --> ef2.14 */ + /* */ + static void + Ins_GFV( INS_ARG ) + { + DO_GFV + } + + + /*************************************************************************/ + /* */ + /* SRP0[]: Set Reference Point 0 */ + /* Opcode range: 0x10 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP0( INS_ARG ) + { + DO_SRP0 + } + + + /*************************************************************************/ + /* */ + /* SRP1[]: Set Reference Point 1 */ + /* Opcode range: 0x11 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP1( INS_ARG ) + { + DO_SRP1 + } + + + /*************************************************************************/ + /* */ + /* SRP2[]: Set Reference Point 2 */ + /* Opcode range: 0x12 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SRP2( INS_ARG ) + { + DO_SRP2 + } + + + /*************************************************************************/ + /* */ + /* RTHG[]: Round To Half Grid */ + /* Opcode range: 0x19 */ + /* Stack: --> */ + /* */ + static void + Ins_RTHG( INS_ARG ) + { + DO_RTHG + } + + + /*************************************************************************/ + /* */ + /* RTG[]: Round To Grid */ + /* Opcode range: 0x18 */ + /* Stack: --> */ + /* */ + static void + Ins_RTG( INS_ARG ) + { + DO_RTG + } + + + /*************************************************************************/ + /* RTDG[]: Round To Double Grid */ + /* Opcode range: 0x3D */ + /* Stack: --> */ + /* */ + static void + Ins_RTDG( INS_ARG ) + { + DO_RTDG + } + + + /*************************************************************************/ + /* RUTG[]: Round Up To Grid */ + /* Opcode range: 0x7C */ + /* Stack: --> */ + /* */ + static void + Ins_RUTG( INS_ARG ) + { + DO_RUTG + } + + + /*************************************************************************/ + /* */ + /* RDTG[]: Round Down To Grid */ + /* Opcode range: 0x7D */ + /* Stack: --> */ + /* */ + static void + Ins_RDTG( INS_ARG ) + { + DO_RDTG + } + + + /*************************************************************************/ + /* */ + /* ROFF[]: Round OFF */ + /* Opcode range: 0x7A */ + /* Stack: --> */ + /* */ + static void + Ins_ROFF( INS_ARG ) + { + DO_ROFF + } + + + /*************************************************************************/ + /* */ + /* SROUND[]: Super ROUND */ + /* Opcode range: 0x76 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_SROUND( INS_ARG ) + { + DO_SROUND + } + + + /*************************************************************************/ + /* */ + /* S45ROUND[]: Super ROUND 45 degrees */ + /* Opcode range: 0x77 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_S45ROUND( INS_ARG ) + { + DO_S45ROUND + } + + + /*************************************************************************/ + /* */ + /* SLOOP[]: Set LOOP variable */ + /* Opcode range: 0x17 */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SLOOP( INS_ARG ) + { + DO_SLOOP + } + + + /*************************************************************************/ + /* */ + /* SMD[]: Set Minimum Distance */ + /* Opcode range: 0x1A */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SMD( INS_ARG ) + { + DO_SMD + } + + + /*************************************************************************/ + /* */ + /* SCVTCI[]: Set Control Value Table Cut In */ + /* Opcode range: 0x1D */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SCVTCI( INS_ARG ) + { + DO_SCVTCI + } + + + /*************************************************************************/ + /* */ + /* SSWCI[]: Set Single Width Cut In */ + /* Opcode range: 0x1E */ + /* Stack: f26.6 --> */ + /* */ + static void + Ins_SSWCI( INS_ARG ) + { + DO_SSWCI + } + + + /*************************************************************************/ + /* */ + /* SSW[]: Set Single Width */ + /* Opcode range: 0x1F */ + /* Stack: int32? --> */ + /* */ + static void + Ins_SSW( INS_ARG ) + { + DO_SSW + } + + + /*************************************************************************/ + /* */ + /* FLIPON[]: Set auto-FLIP to ON */ + /* Opcode range: 0x4D */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPON( INS_ARG ) + { + DO_FLIPON + } + + + /*************************************************************************/ + /* */ + /* FLIPOFF[]: Set auto-FLIP to OFF */ + /* Opcode range: 0x4E */ + /* Stack: --> */ + /* */ + static void + Ins_FLIPOFF( INS_ARG ) + { + DO_FLIPOFF + } + + + /*************************************************************************/ + /* */ + /* SANGW[]: Set ANGle Weight */ + /* Opcode range: 0x7E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SANGW( INS_ARG ) + { + /* instruction not supported anymore */ + } + + + /*************************************************************************/ + /* */ + /* SDB[]: Set Delta Base */ + /* Opcode range: 0x5E */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDB( INS_ARG ) + { + DO_SDB + } + + + /*************************************************************************/ + /* */ + /* SDS[]: Set Delta Shift */ + /* Opcode range: 0x5F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SDS( INS_ARG ) + { + DO_SDS + } + + + /*************************************************************************/ + /* */ + /* MPPEM[]: Measure Pixel Per EM */ + /* Opcode range: 0x4B */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPPEM( INS_ARG ) + { + DO_MPPEM + } + + + /*************************************************************************/ + /* */ + /* MPS[]: Measure Point Size */ + /* Opcode range: 0x4C */ + /* Stack: --> Euint16 */ + /* */ + static void + Ins_MPS( INS_ARG ) + { + DO_MPS + } + + + /*************************************************************************/ + /* */ + /* DUP[]: DUPlicate the top stack's element */ + /* Opcode range: 0x20 */ + /* Stack: StkElt --> StkElt StkElt */ + /* */ + static void + Ins_DUP( INS_ARG ) + { + DO_DUP + } + + + /*************************************************************************/ + /* */ + /* POP[]: POP the stack's top element */ + /* Opcode range: 0x21 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_POP( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* CLEAR[]: CLEAR the entire stack */ + /* Opcode range: 0x22 */ + /* Stack: StkElt... --> */ + /* */ + static void + Ins_CLEAR( INS_ARG ) + { + DO_CLEAR + } + + + /*************************************************************************/ + /* */ + /* SWAP[]: SWAP the stack's top two elements */ + /* Opcode range: 0x23 */ + /* Stack: 2 * StkElt --> 2 * StkElt */ + /* */ + static void + Ins_SWAP( INS_ARG ) + { + DO_SWAP + } + + + /*************************************************************************/ + /* */ + /* DEPTH[]: return the stack DEPTH */ + /* Opcode range: 0x24 */ + /* Stack: --> uint32 */ + /* */ + static void + Ins_DEPTH( INS_ARG ) + { + DO_DEPTH + } + + + /*************************************************************************/ + /* */ + /* CINDEX[]: Copy INDEXed element */ + /* Opcode range: 0x25 */ + /* Stack: int32 --> StkElt */ + /* */ + static void + Ins_CINDEX( INS_ARG ) + { + DO_CINDEX + } + + + /*************************************************************************/ + /* */ + /* EIF[]: End IF */ + /* Opcode range: 0x59 */ + /* Stack: --> */ + /* */ + static void + Ins_EIF( INS_ARG ) + { + /* nothing to do */ + } + + + /*************************************************************************/ + /* */ + /* JROT[]: Jump Relative On True */ + /* Opcode range: 0x78 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROT( INS_ARG ) + { + DO_JROT + } + + + /*************************************************************************/ + /* */ + /* JMPR[]: JuMP Relative */ + /* Opcode range: 0x1C */ + /* Stack: int32 --> */ + /* */ + static void + Ins_JMPR( INS_ARG ) + { + DO_JMPR + } + + + /*************************************************************************/ + /* */ + /* JROF[]: Jump Relative On False */ + /* Opcode range: 0x79 */ + /* Stack: StkElt int32 --> */ + /* */ + static void + Ins_JROF( INS_ARG ) + { + DO_JROF + } + + + /*************************************************************************/ + /* */ + /* LT[]: Less Than */ + /* Opcode range: 0x50 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LT( INS_ARG ) + { + DO_LT + } + + + /*************************************************************************/ + /* */ + /* LTEQ[]: Less Than or EQual */ + /* Opcode range: 0x51 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_LTEQ( INS_ARG ) + { + DO_LTEQ + } + + + /*************************************************************************/ + /* */ + /* GT[]: Greater Than */ + /* Opcode range: 0x52 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GT( INS_ARG ) + { + DO_GT + } + + + /*************************************************************************/ + /* */ + /* GTEQ[]: Greater Than or EQual */ + /* Opcode range: 0x53 */ + /* Stack: int32? int32? --> bool */ + /* */ + static void + Ins_GTEQ( INS_ARG ) + { + DO_GTEQ + } + + + /*************************************************************************/ + /* */ + /* EQ[]: EQual */ + /* Opcode range: 0x54 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_EQ( INS_ARG ) + { + DO_EQ + } + + + /*************************************************************************/ + /* */ + /* NEQ[]: Not EQual */ + /* Opcode range: 0x55 */ + /* Stack: StkElt StkElt --> bool */ + /* */ + static void + Ins_NEQ( INS_ARG ) + { + DO_NEQ + } + + + /*************************************************************************/ + /* */ + /* ODD[]: Is ODD */ + /* Opcode range: 0x56 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_ODD( INS_ARG ) + { + DO_ODD + } + + + /*************************************************************************/ + /* */ + /* EVEN[]: Is EVEN */ + /* Opcode range: 0x57 */ + /* Stack: f26.6 --> bool */ + /* */ + static void + Ins_EVEN( INS_ARG ) + { + DO_EVEN + } + + + /*************************************************************************/ + /* */ + /* AND[]: logical AND */ + /* Opcode range: 0x5A */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_AND( INS_ARG ) + { + DO_AND + } + + + /*************************************************************************/ + /* */ + /* OR[]: logical OR */ + /* Opcode range: 0x5B */ + /* Stack: uint32 uint32 --> uint32 */ + /* */ + static void + Ins_OR( INS_ARG ) + { + DO_OR + } + + + /*************************************************************************/ + /* */ + /* NOT[]: logical NOT */ + /* Opcode range: 0x5C */ + /* Stack: StkElt --> uint32 */ + /* */ + static void + Ins_NOT( INS_ARG ) + { + DO_NOT + } + + + /*************************************************************************/ + /* */ + /* ADD[]: ADD */ + /* Opcode range: 0x60 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_ADD( INS_ARG ) + { + DO_ADD + } + + + /*************************************************************************/ + /* */ + /* SUB[]: SUBtract */ + /* Opcode range: 0x61 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_SUB( INS_ARG ) + { + DO_SUB + } + + + /*************************************************************************/ + /* */ + /* DIV[]: DIVide */ + /* Opcode range: 0x62 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_DIV( INS_ARG ) + { + DO_DIV + } + + + /*************************************************************************/ + /* */ + /* MUL[]: MULtiply */ + /* Opcode range: 0x63 */ + /* Stack: f26.6 f26.6 --> f26.6 */ + /* */ + static void + Ins_MUL( INS_ARG ) + { + DO_MUL + } + + + /*************************************************************************/ + /* */ + /* ABS[]: ABSolute value */ + /* Opcode range: 0x64 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ABS( INS_ARG ) + { + DO_ABS + } + + + /*************************************************************************/ + /* */ + /* NEG[]: NEGate */ + /* Opcode range: 0x65 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NEG( INS_ARG ) + { + DO_NEG + } + + + /*************************************************************************/ + /* */ + /* FLOOR[]: FLOOR */ + /* Opcode range: 0x66 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_FLOOR( INS_ARG ) + { + DO_FLOOR + } + + + /*************************************************************************/ + /* */ + /* CEILING[]: CEILING */ + /* Opcode range: 0x67 */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_CEILING( INS_ARG ) + { + DO_CEILING + } + + + /*************************************************************************/ + /* */ + /* RS[]: Read Store */ + /* Opcode range: 0x43 */ + /* Stack: uint32 --> uint32 */ + /* */ + static void + Ins_RS( INS_ARG ) + { + DO_RS + } + + + /*************************************************************************/ + /* */ + /* WS[]: Write Store */ + /* Opcode range: 0x42 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WS( INS_ARG ) + { + DO_WS + } + + + /*************************************************************************/ + /* */ + /* WCVTP[]: Write CVT in Pixel units */ + /* Opcode range: 0x44 */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_WCVTP( INS_ARG ) + { + DO_WCVTP + } + + + /*************************************************************************/ + /* */ + /* WCVTF[]: Write CVT in Funits */ + /* Opcode range: 0x70 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_WCVTF( INS_ARG ) + { + DO_WCVTF + } + + + /*************************************************************************/ + /* */ + /* RCVT[]: Read CVT */ + /* Opcode range: 0x45 */ + /* Stack: uint32 --> f26.6 */ + /* */ + static void + Ins_RCVT( INS_ARG ) + { + DO_RCVT + } + + + /*************************************************************************/ + /* */ + /* AA[]: Adjust Angle */ + /* Opcode range: 0x7F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_AA( INS_ARG ) + { + /* intentionally no longer supported */ + } + + + /*************************************************************************/ + /* */ + /* DEBUG[]: DEBUG. Unsupported. */ + /* Opcode range: 0x4F */ + /* Stack: uint32 --> */ + /* */ + /* Note: The original instruction pops a value from the stack. */ + /* */ + static void + Ins_DEBUG( INS_ARG ) + { + DO_DEBUG + } + + + /*************************************************************************/ + /* */ + /* ROUND[ab]: ROUND value */ + /* Opcode range: 0x68-0x6B */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_ROUND( INS_ARG ) + { + DO_ROUND + } + + + /*************************************************************************/ + /* */ + /* NROUND[ab]: No ROUNDing of value */ + /* Opcode range: 0x6C-0x6F */ + /* Stack: f26.6 --> f26.6 */ + /* */ + static void + Ins_NROUND( INS_ARG ) + { + DO_NROUND + } + + + /*************************************************************************/ + /* */ + /* MAX[]: MAXimum */ + /* Opcode range: 0x68 */ + /* Stack: int32? int32? --> int32 */ + /* */ + static void + Ins_MAX( INS_ARG ) + { + DO_MAX + } + + + /*************************************************************************/ + /* */ + /* MIN[]: MINimum */ + /* Opcode range: 0x69 */ + /* 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 */ + /* Opcode range: 0x26 */ + /* Stack: int32? --> StkElt */ + /* */ + static void + Ins_MINDEX( INS_ARG ) + { + FT_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]; + + FT_MEM_MOVE( &CUR.stack[CUR.args - L ], + &CUR.stack[CUR.args - L + 1], + ( L - 1 ) * sizeof ( FT_Long ) ); + + CUR.stack[CUR.args - 1] = K; + } + + + /*************************************************************************/ + /* */ + /* ROLL[]: ROLL top three elements */ + /* Opcode range: 0x8A */ + /* Stack: 3 * StkElt --> 3 * StkElt */ + /* */ + static void + Ins_ROLL( INS_ARG ) + { + FT_Long A, B, C; + + FT_UNUSED_EXEC; + + + 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 specification's order. */ + /* */ + /*************************************************************************/ + + + static FT_Bool + SkipCode( EXEC_OP ) + { + CUR.IP += CUR.length; + + if ( CUR.IP < CUR.codeSize ) + { + CUR.opcode = CUR.code[CUR.IP]; + + CUR.length = opcode_length[CUR.opcode]; + if ( CUR.length < 0 ) + { + if ( CUR.IP + 1 > CUR.codeSize ) + goto Fail_Overflow; + CUR.length = CUR.code[CUR.IP + 1] + 2; + } + + if ( CUR.IP + CUR.length <= CUR.codeSize ) + return SUCCESS; + } + + Fail_Overflow: + CUR.error = TT_Err_Code_Overflow; + return FAILURE; + } + + + /*************************************************************************/ + /* */ + /* IF[]: IF test */ + /* Opcode range: 0x58 */ + /* Stack: StkElt --> */ + /* */ + static void + Ins_IF( INS_ARG ) + { + FT_Int nIfs; + FT_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 = FT_BOOL( nIfs == 1 ); + break; + + case 0x59: /* EIF */ + nIfs--; + Out = FT_BOOL( nIfs == 0 ); + break; + } + } while ( Out == 0 ); + } + + + /*************************************************************************/ + /* */ + /* ELSE[]: ELSE */ + /* Opcode range: 0x1B */ + /* Stack: --> */ + /* */ + static void + Ins_ELSE( INS_ARG ) + { + FT_Int nIfs; + + FT_UNUSED_ARG; + + + 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 specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FDEF[]: Function DEFinition */ + /* Opcode range: 0x2C */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_FDEF( INS_ARG ) + { + FT_ULong n; + TT_DefRecord* rec; + TT_DefRecord* limit; + + + /* some font programs are broken enough to redefine functions! */ + /* We will then parse the current table. */ + + rec = CUR.FDefs; + limit = rec + CUR.numFDefs; + n = args[0]; + + for ( ; rec < limit; rec++ ) + { + if ( rec->opc == n ) + break; + } + + if ( rec == limit ) + { + /* check that there is enough room for new functions */ + if ( CUR.numFDefs >= CUR.maxFDefs ) + { + CUR.error = TT_Err_Too_Many_Function_Defs; + return; + } + CUR.numFDefs++; + } + + rec->range = CUR.curRange; + rec->opc = n; + rec->start = CUR.IP + 1; + rec->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 */ + /* Opcode range: 0x2D */ + /* Stack: --> */ + /* */ + static void + Ins_ENDF( INS_ARG ) + { + TT_CallRec* pRec; + + FT_UNUSED_ARG; + + + 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: If 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 is why we do not test */ + /* the result of Ins_Goto_CodeRange() here! */ + } + + + /*************************************************************************/ + /* */ + /* CALL[]: CALL function */ + /* Opcode range: 0x2B */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_CALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + + F = args[0]; + if ( BOUNDS( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + + /* check the 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; + + Fail: + CUR.error = TT_Err_Invalid_Reference; + } + + + /*************************************************************************/ + /* */ + /* LOOPCALL[]: LOOP and CALL function */ + /* Opcode range: 0x2A */ + /* Stack: uint32? Eint16? --> */ + /* */ + static void + Ins_LOOPCALL( INS_ARG ) + { + FT_ULong F; + TT_CallRec* pCrec; + TT_DefRecord* def; + + + /* first of all, check the index */ + F = args[1]; + if ( BOUNDS( F, CUR.maxFunc + 1 ) ) + goto Fail; + + /* Except for some old Apple fonts, all functions in a TrueType */ + /* font are defined in increasing order, starting from 0. This */ + /* means that we normally have */ + /* */ + /* CUR.maxFunc+1 == CUR.numFDefs */ + /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ + /* */ + /* If this isn't true, we need to look up the function table. */ + + def = CUR.FDefs + F; + if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) + { + /* look up the FDefs table */ + TT_DefRecord* limit; + + + def = CUR.FDefs; + limit = def + CUR.numFDefs; + + while ( def < limit && def->opc != F ) + def++; + + if ( def == limit ) + goto Fail; + } + + /* check that the function is active */ + if ( !def->active ) + goto Fail; + + /* check stack */ + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + if ( args[0] > 0 ) + { + pCrec = CUR.callStack + CUR.callTop; + + pCrec->Caller_Range = CUR.curRange; + pCrec->Caller_IP = CUR.IP + 1; + pCrec->Cur_Count = (FT_Int)args[0]; + pCrec->Cur_Restart = def->start; + + CUR.callTop++; + + INS_Goto_CodeRange( def->range, def->start ); + + CUR.step_ins = FALSE; + } + return; + + Fail: + CUR.error = TT_Err_Invalid_Reference; + } + + + /*************************************************************************/ + /* */ + /* IDEF[]: Instruction DEFinition */ + /* Opcode range: 0x89 */ + /* Stack: Eint8 --> */ + /* */ + static void + Ins_IDEF( INS_ARG ) + { + TT_DefRecord* def; + TT_DefRecord* limit; + + + /* First of all, look for the same function in our table */ + + def = CUR.IDefs; + limit = def + CUR.numIDefs; + + for ( ; def < limit; def++ ) + if ( def->opc == (FT_ULong)args[0] ) + break; + + if ( def == limit ) + { + /* check that there is enough room for a new instruction */ + if ( CUR.numIDefs >= CUR.maxIDefs ) + { + CUR.error = TT_Err_Too_Many_Instruction_Defs; + return; + } + CUR.numIDefs++; + } + + def->opc = args[0]; + def->start = CUR.IP+1; + def->range = CUR.curRange; + def->active = TRUE; + + if ( (FT_ULong)args[0] > CUR.maxIns ) + CUR.maxIns = args[0]; + + /* 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 specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* NPUSHB[]: PUSH N Bytes */ + /* Opcode range: 0x40 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_NPUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_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 */ + /* Opcode range: 0x41 */ + /* Stack: --> int32... */ + /* */ + static void + Ins_NPUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_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 */ + /* Opcode range: 0xB0-0xB7 */ + /* Stack: --> uint32... */ + /* */ + static void + Ins_PUSHB( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_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 */ + /* Opcode range: 0xB8-0xBF */ + /* Stack: --> int32... */ + /* */ + static void + Ins_PUSHW( INS_ARG ) + { + FT_UShort L, K; + + + L = (FT_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 */ + /* Opcode range: 0x46-0x47 */ + /* Stack: uint32 --> f26.6 */ + /* */ + /* BULLSHIT: Measures from the original glyph must be taken along the */ + /* dual projection vector! */ + /* */ + static void + Ins_GC( INS_ARG ) + { + FT_ULong L; + FT_F26Dot6 R; + + + L = (FT_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 */ + /* Opcode range: 0x48 */ + /* Stack: f26.6 uint32 --> */ + /* */ + /* Formula: */ + /* */ + /* OA := OA + ( value - OA.p )/( f.p ) * f */ + /* */ + static void + Ins_SCFS( INS_ARG ) + { + FT_Long K; + FT_UShort L; + + + L = (FT_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 */ + /* Opcode range: 0x49-0x4A */ + /* 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 ) + { + FT_UShort K, L; + FT_F26Dot6 D; + + + K = (FT_UShort)args[1]; + L = (FT_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; + } + 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 */ + /* Opcode range: 0x86-0x87 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_SDPVTL( INS_ARG ) + { + FT_Long A, B, C; + FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ + + + p1 = (FT_UShort)args[1]; + p2 = (FT_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; + } + + { + FT_Vector* v1 = CUR.zp1.org + p2; + FT_Vector* v2 = CUR.zp2.org + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( ( CUR.opcode & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.dualVector ); + + { + FT_Vector* v1 = CUR.zp1.cur + p2; + FT_Vector* v2 = CUR.zp2.cur + p1; + + + A = v1->x - v2->x; + B = v1->y - v2->y; + } + + if ( ( CUR.opcode & 1 ) != 0 ) + { + C = B; /* counter clockwise rotation */ + B = A; + A = -C; + } + + NORMalize( A, B, &CUR.GS.projVector ); + + COMPUTE_Funcs(); + } + + + /*************************************************************************/ + /* */ + /* SZP0[]: Set Zone Pointer 0 */ + /* Opcode range: 0x13 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP0( INS_ARG ) + { + switch ( (FT_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 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP1[]: Set Zone Pointer 1 */ + /* Opcode range: 0x14 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP1( INS_ARG ) + { + switch ( (FT_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 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZP2[]: Set Zone Pointer 2 */ + /* Opcode range: 0x15 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZP2( INS_ARG ) + { + switch ( (FT_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 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* SZPS[]: Set Zone PointerS */ + /* Opcode range: 0x16 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SZPS( INS_ARG ) + { + switch ( (FT_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 = (FT_UShort)args[0]; + CUR.GS.gep1 = (FT_UShort)args[0]; + CUR.GS.gep2 = (FT_UShort)args[0]; + } + + + /*************************************************************************/ + /* */ + /* INSTCTRL[]: INSTruction ConTRoL */ + /* Opcode range: 0x8e */ + /* Stack: int32 int32 --> */ + /* */ + static void + Ins_INSTCTRL( INS_ARG ) + { + FT_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 = FT_BOOL( + ( (FT_Byte)CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L ); + } + + + /*************************************************************************/ + /* */ + /* SCANCTRL[]: SCAN ConTRoL */ + /* Opcode range: 0x85 */ + /* Stack: uint32? --> */ + /* */ + static void + Ins_SCANCTRL( INS_ARG ) + { + FT_Int A; + + + /* Get Threshold */ + A = (FT_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 0 + if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) + CUR.GS.scan_control = TRUE; +#endif + + if ( (args[0] & 0x200) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = TRUE; + + if ( (args[0] & 0x400) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = TRUE; + +#if 0 + if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) + CUR.GS.scan_control = FALSE; +#endif + + if ( (args[0] & 0x1000) != 0 && CUR.tt_metrics.rotated ) + CUR.GS.scan_control = FALSE; + + if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched ) + CUR.GS.scan_control = FALSE; + } + + + /*************************************************************************/ + /* */ + /* SCANTYPE[]: SCAN TYPE */ + /* Opcode range: 0x8D */ + /* 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 = (FT_Int)args[0]; + } + } + + + /*************************************************************************/ + /* */ + /* MANAGING OUTLINES */ + /* */ + /* Instructions appear in the specification's order. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* FLIPPT[]: FLIP PoinT */ + /* Opcode range: 0x80 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_FLIPPT( INS_ARG ) + { + FT_UShort point; + + FT_UNUSED_ARG; + + + if ( CUR.top < CUR.GS.loop ) + { + CUR.error = TT_Err_Too_Few_Arguments; + return; + } + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_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.tags[point] ^= FT_CURVE_TAG_ON; + + CUR.GS.loop--; + } + + CUR.GS.loop = 1; + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGON[]: FLIP RanGe ON */ + /* Opcode range: 0x81 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGON( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_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.tags[I] |= FT_CURVE_TAG_ON; + } + + + /*************************************************************************/ + /* */ + /* FLIPRGOFF: FLIP RanGe OFF */ + /* Opcode range: 0x82 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_FLIPRGOFF( INS_ARG ) + { + FT_UShort I, K, L; + + + K = (FT_UShort)args[1]; + L = (FT_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.tags[I] &= ~FT_CURVE_TAG_ON; + } + + + static FT_Bool + Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, + FT_F26Dot6* y, + TT_GlyphZone zone, + FT_UShort* refp ) + { + TT_GlyphZoneRec zp; + FT_UShort p; + FT_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_Reference; + return FAILURE; + } + + *zone = zp; + *refp = p; + + d = CUR_Func_project( zp.cur + p, zp.org + p ); + +#ifdef NO_APPLE_PATENT + + *x = TT_MulFix14( d, CUR.GS.freeVector.x ); + *y = TT_MulFix14( d, CUR.GS.freeVector.y ); + +#else + + *x = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.x * 0x10000L, + CUR.F_dot_P ); + *y = TT_MULDIV( d, + (FT_Long)CUR.GS.freeVector.y * 0x10000L, + CUR.F_dot_P ); + +#endif /* NO_APPLE_PATENT */ + + return SUCCESS; + } + + + static void + Move_Zp2_Point( EXEC_OP_ FT_UShort point, + FT_F26Dot6 dx, + FT_F26Dot6 dy, + FT_Bool touch ) + { + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur[point].x += dx; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur[point].y += dy; + if ( touch ) + CUR.zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; + } + } + + + /*************************************************************************/ + /* */ + /* SHP[a]: SHift Point by the last point */ + /* Opcode range: 0x32-0x33 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_SHP( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + + FT_F26Dot6 dx, + dy; + FT_UShort point; + + FT_UNUSED_ARG; + + + 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 = (FT_UShort)CUR.stack[CUR.args]; + + if ( BOUNDS( point, CUR.zp2.n_points ) ) + { + if ( CUR.pedantic_hinting ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + } + else + /* XXX: 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 */ + /* Opcode range: 0x34-35 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SHC( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, + dy; + + FT_Short contour; + FT_UShort first_point, last_point, i; + + + contour = (FT_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 = (FT_UShort)(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 = (FT_UShort)(CUR.zp2.n_points - 1); + else + last_point = 0; + } + + /* XXX: 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 */ + /* Opcode range: 0x36-37 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_SHZ( INS_ARG ) + { + TT_GlyphZoneRec zp; + FT_UShort refp; + FT_F26Dot6 dx, + dy; + + FT_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 = (FT_UShort)(CUR.zp2.n_points - 1); + else + last_point = 0; + + /* XXX: 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 */ + /* Opcode range: 0x38 */ + /* Stack: f26.6 uint32... --> */ + /* */ + static void + Ins_SHPIX( INS_ARG ) + { + FT_F26Dot6 dx, dy; + FT_UShort point; + + + if ( CUR.top < CUR.GS.loop + 1 ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + + dx = TT_MulFix14( args[0], CUR.GS.freeVector.x ); + dy = TT_MulFix14( args[0], CUR.GS.freeVector.y ); + + while ( CUR.GS.loop > 0 ) + { + CUR.args--; + + point = (FT_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 Position */ + /* Opcode range: 0x3A-0x3B */ + /* Stack: f26.6 uint32 --> */ + /* */ + static void + Ins_MSIRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + + + point = (FT_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 */ + /* Opcode range: 0x2E-0x2F */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDAP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 cur_dist, + distance; + + + point = (FT_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.tt_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 */ + /* Opcode range: 0x3E-0x3F */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_MIAP( INS_ARG ) + { + FT_ULong cvtEntry; + FT_UShort point; + FT_F26Dot6 distance, + org_dist; + + + cvtEntry = (FT_ULong)args[1]; + point = (FT_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 */ + /* specification. */ + /* */ + /* 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_MulFix14( distance, CUR.GS.freeVector.x ); + CUR.zp0.org[point].y = TT_MulFix14( distance, CUR.GS.freeVector.y ), + 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.tt_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 */ + /* Opcode range: 0xC0-0xDF */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_MDRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 org_dist, distance; + + + point = (FT_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.tt_metrics.compensations[CUR.opcode & 3] ); + else + distance = ROUND_None( + org_dist, + CUR.tt_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 */ + /* Opcode range: 0xE0-0xFF */ + /* Stack: int32? uint32 --> */ + /* */ + static void + Ins_MIRP( INS_ARG ) + { + FT_UShort point; + FT_ULong cvtEntry; + + FT_F26Dot6 cvt_dist, + distance, + cur_dist, + org_dist; + + + point = (FT_UShort)args[0]; + cvtEntry = (FT_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_MulFix14( cvt_dist, CUR.GS.freeVector.x ); + + CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y + + TT_MulFix14( cvt_dist, CUR.GS.freeVector.y ); + + 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.tt_metrics.compensations[CUR.opcode & 3] ); + } + else + distance = ROUND_None( + cvt_dist, + CUR.tt_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; + + /* XXX: UNDOCUMENTED! */ + + CUR.GS.rp2 = point; + } + + + /*************************************************************************/ + /* */ + /* ALIGNRP[]: ALIGN Relative Point */ + /* Opcode range: 0x3C */ + /* Stack: uint32 uint32... --> */ + /* */ + static void + Ins_ALIGNRP( INS_ARG ) + { + FT_UShort point; + FT_F26Dot6 distance; + + FT_UNUSED_ARG; + + + 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 = (FT_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 */ + /* Opcode range: 0x0F */ + /* Stack: 5 * uint32 --> */ + /* */ + static void + Ins_ISECT( INS_ARG ) + { + FT_UShort point, + a0, a1, + b0, b1; + + FT_F26Dot6 discriminant; + + FT_F26Dot6 dx, dy, + dax, day, + dbx, dby; + + FT_F26Dot6 val; + + FT_Vector R; + + + point = (FT_UShort)args[0]; + + a0 = (FT_UShort)args[1]; + a1 = (FT_UShort)args[2]; + b0 = (FT_UShort)args[3]; + b1 = (FT_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.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; + + discriminant = TT_MULDIV( dax, -dby, 0x40 ) + + TT_MULDIV( day, dbx, 0x40 ); + + if ( ABS( discriminant ) >= 0x40 ) + { + val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); + + 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 */ + /* Opcode range: 0x27 */ + /* Stack: uint32 uint32 --> */ + /* */ + static void + Ins_ALIGNPTS( INS_ARG ) + { + FT_UShort p1, p2; + FT_F26Dot6 distance; + + + p1 = (FT_UShort)args[0]; + p2 = (FT_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 */ + /* Opcode range: 0x39 */ + /* Stack: uint32... --> */ + /* */ + static void + Ins_IP( INS_ARG ) + { + FT_F26Dot6 org_a, org_b, org_x, + cur_a, cur_b, cur_x, + distance; + FT_UShort point; + + FT_UNUSED_ARG; + + + 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 = (FT_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 */ + /* Opcode range: 0x29 */ + /* Stack: uint32 --> */ + /* */ + static void + Ins_UTP( INS_ARG ) + { + FT_UShort point; + FT_Byte mask; + + + point = (FT_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 &= ~FT_CURVE_TAG_TOUCH_X; + + if ( CUR.GS.freeVector.y != 0 ) + mask &= ~FT_CURVE_TAG_TOUCH_Y; + + CUR.zp0.tags[point] &= mask; + } + + + /* Local variables for Ins_IUP: */ + struct LOC_Ins_IUP + { + FT_Vector* orgs; /* original and current coordinate */ + FT_Vector* curs; /* arrays */ + }; + + + static void + Shift( FT_UInt p1, + FT_UInt p2, + FT_UInt p, + struct LOC_Ins_IUP* LINK ) + { + FT_UInt i; + FT_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( FT_UInt p1, + FT_UInt p2, + FT_UInt ref1, + FT_UInt ref2, + struct LOC_Ins_IUP* LINK ) + { + FT_UInt i; + FT_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 */ + /* Opcode range: 0x30-0x31 */ + /* Stack: --> */ + /* */ + static void + Ins_IUP( INS_ARG ) + { + struct LOC_Ins_IUP V; + FT_Byte mask; + + FT_UInt first_point; /* first point of contour */ + FT_UInt end_point; /* end point (last+1) of contour */ + + FT_UInt first_touched; /* first touched point in contour */ + FT_UInt cur_touched; /* current touched point in contour */ + + FT_UInt point; /* current point */ + FT_Short contour; /* current contour */ + + FT_UNUSED_ARG; + + + if ( CUR.opcode & 1 ) + { + mask = FT_CURVE_TAG_TOUCH_X; + V.orgs = CUR.pts.org; + V.curs = CUR.pts.cur; + } + else + { + mask = FT_CURVE_TAG_TOUCH_Y; + V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); + V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); + } + + contour = 0; + point = 0; + + do + { + end_point = CUR.pts.contours[contour]; + first_point = point; + + while ( point <= end_point && (CUR.pts.tags[point] & mask) == 0 ) + point++; + + if ( point <= end_point ) + { + first_touched = point; + cur_touched = point; + + point++; + + while ( point <= end_point ) + { + if ( ( CUR.pts.tags[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( (FT_UShort)( 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 */ + /* Opcode range: 0x5D,0x71,0x72 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAP( INS_ARG ) + { + FT_ULong k, nump; + FT_UShort A; + FT_ULong C; + FT_Long B; + + + nump = (FT_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 = (FT_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 = ( (FT_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() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 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 */ + /* Opcode range: 0x73,0x74,0x75 */ + /* Stack: uint32 (2 * uint32)... --> */ + /* */ + static void + Ins_DELTAC( INS_ARG ) + { + FT_ULong nump, k; + FT_ULong A, C; + FT_Long B; + + + nump = (FT_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 = (FT_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 = ( (FT_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() == (FT_Long)C ) + { + B = ( (FT_ULong)B & 0xF ) - 8; + if ( B >= 0 ) + B++; + B = B * 64 / ( 1L << CUR.GS.delta_shift ); + + CUR_Func_move_cvt( A, B ); + } + } + } + + CUR.new_top = CUR.args; + } + + + /*************************************************************************/ + /* */ + /* MISC. INSTRUCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* GETINFO[]: GET INFOrmation */ + /* Opcode range: 0x88 */ + /* 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 ) + { + FT_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.tt_metrics.rotated ) + K |= 0x80; + + /* Has the glyph been stretched ? */ + if ( CUR.tt_metrics.stretched ) + K |= 0x100; + + args[0] = K; + } + + + static void + Ins_UNKNOWN( INS_ARG ) + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + FT_UNUSED_ARG; + + + for ( ; def < limit; def++ ) + { + if ( (FT_Byte)def->opc == CUR.opcode && def->active ) + { + TT_CallRec* call; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Stack_Overflow; + return; + } + + call = CUR.callStack + CUR.callTop++; + + call->Caller_Range = CUR.curRange; + call->Caller_IP = CUR.IP+1; + call->Cur_Count = 1; + call->Cur_Restart = def->start; + + 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_0x28 */ 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_0x7B */ Ins_UNKNOWN, + /* RUTG */ Ins_RUTG, + /* RDTG */ Ins_RDTG, + /* SANGW */ Ins_SANGW, + /* AA */ Ins_AA, + + /* FlipPT */ Ins_FLIPPT, + /* FlipRgON */ Ins_FLIPRGON, + /* FlipRgOFF */ Ins_FLIPRGOFF, + /* INS_0x83 */ Ins_UNKNOWN, + /* INS_0x84 */ 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_0x8F */ Ins_UNKNOWN, + + /* INS_0x90 */ Ins_UNKNOWN, + /* INS_0x91 */ Ins_UNKNOWN, + /* INS_0x92 */ Ins_UNKNOWN, + /* INS_0x93 */ Ins_UNKNOWN, + /* INS_0x94 */ Ins_UNKNOWN, + /* INS_0x95 */ Ins_UNKNOWN, + /* INS_0x96 */ Ins_UNKNOWN, + /* INS_0x97 */ Ins_UNKNOWN, + /* INS_0x98 */ Ins_UNKNOWN, + /* INS_0x99 */ Ins_UNKNOWN, + /* INS_0x9A */ Ins_UNKNOWN, + /* INS_0x9B */ Ins_UNKNOWN, + /* INS_0x9C */ Ins_UNKNOWN, + /* INS_0x9D */ Ins_UNKNOWN, + /* INS_0x9E */ Ins_UNKNOWN, + /* INS_0x9F */ Ins_UNKNOWN, + + /* INS_0xA0 */ Ins_UNKNOWN, + /* INS_0xA1 */ Ins_UNKNOWN, + /* INS_0xA2 */ Ins_UNKNOWN, + /* INS_0xA3 */ Ins_UNKNOWN, + /* INS_0xA4 */ Ins_UNKNOWN, + /* INS_0xA5 */ Ins_UNKNOWN, + /* INS_0xA6 */ Ins_UNKNOWN, + /* INS_0xA7 */ Ins_UNKNOWN, + /* INS_0xA8 */ Ins_UNKNOWN, + /* INS_0xA9 */ Ins_UNKNOWN, + /* INS_0xAA */ Ins_UNKNOWN, + /* INS_0xAB */ Ins_UNKNOWN, + /* INS_0xAC */ Ins_UNKNOWN, + /* INS_0xAD */ Ins_UNKNOWN, + /* INS_0xAE */ Ins_UNKNOWN, + /* INS_0xAF */ 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 /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + + /*************************************************************************/ + /* */ + /* 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 */ + /* an 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 specification's order. */ + /* */ + /*************************************************************************/ + + + /* documentation is in ttinterp.h */ + + FT_EXPORT_DEF( FT_Error ) + TT_RunIns( TT_ExecContext exc ) + { + FT_Long ins_counter = 0; /* executed instructions counter */ + + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + cur = *exc; +#endif + + /* set CVT functions */ + CUR.tt_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( (FT_Byte)exc->GS.round_state ); + + do + { + CUR.opcode = CUR.code[CUR.IP]; + + if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) + { + if ( CUR.IP + 1 > CUR.codeSize ) + goto LErrorCodeOverflow_; + + CUR.length = CUR.code[CUR.IP + 1] + 2; + } + + if ( CUR.IP + CUR.length > CUR.codeSize ) + goto LErrorCodeOverflow_; + + /* 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 + + { + FT_Long* args = CUR.stack + CUR.args; + FT_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 */ + { + FT_Short AA, BB; + + + AA = (FT_Short)( ( opcode & 1 ) << 14 ); + BB = (FT_Short)( AA ^ 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_ARG_ 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_ARG_ args ); + break; + + case 0x14: /* SZP1 */ + Ins_SZP1( EXEC_ARG_ args ); + break; + + case 0x15: /* SZP2 */ + Ins_SZP2( EXEC_ARG_ args ); + break; + + case 0x16: /* SZPS */ + Ins_SZPS( EXEC_ARG_ 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_ARG_ 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_ARG_ args ); + break; + + case 0x27: /* ALIGNPTS */ + Ins_ALIGNPTS( EXEC_ARG_ args ); + break; + + case 0x28: /* ???? */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x29: /* UTP */ + Ins_UTP( EXEC_ARG_ args ); + break; + + case 0x2A: /* LOOPCALL */ + Ins_LOOPCALL( EXEC_ARG_ args ); + break; + + case 0x2B: /* CALL */ + Ins_CALL( EXEC_ARG_ args ); + break; + + case 0x2C: /* FDEF */ + Ins_FDEF( EXEC_ARG_ args ); + break; + + case 0x2D: /* ENDF */ + Ins_ENDF( EXEC_ARG_ args ); + break; + + case 0x2E: /* MDAP */ + case 0x2F: /* MDAP */ + Ins_MDAP( EXEC_ARG_ args ); + break; + + + case 0x30: /* IUP */ + case 0x31: /* IUP */ + Ins_IUP( EXEC_ARG_ args ); + break; + + case 0x32: /* SHP */ + case 0x33: /* SHP */ + Ins_SHP( EXEC_ARG_ args ); + break; + + case 0x34: /* SHC */ + case 0x35: /* SHC */ + Ins_SHC( EXEC_ARG_ args ); + break; + + case 0x36: /* SHZ */ + case 0x37: /* SHZ */ + Ins_SHZ( EXEC_ARG_ args ); + break; + + case 0x38: /* SHPIX */ + Ins_SHPIX( EXEC_ARG_ args ); + break; + + case 0x39: /* IP */ + Ins_IP( EXEC_ARG_ args ); + break; + + case 0x3A: /* MSIRP */ + case 0x3B: /* MSIRP */ + Ins_MSIRP( EXEC_ARG_ args ); + break; + + case 0x3C: /* AlignRP */ + Ins_ALIGNRP( EXEC_ARG_ args ); + break; + + case 0x3D: /* RTDG */ + DO_RTDG + break; + + case 0x3E: /* MIAP */ + case 0x3F: /* MIAP */ + Ins_MIAP( EXEC_ARG_ args ); + break; + + case 0x40: /* NPUSHB */ + Ins_NPUSHB( EXEC_ARG_ args ); + break; + + case 0x41: /* NPUSHW */ + Ins_NPUSHW( EXEC_ARG_ 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_ARG_ args ); + break; + + case 0x48: /* SCFS */ + Ins_SCFS( EXEC_ARG_ args ); + break; + + case 0x49: /* MD */ + case 0x4A: /* MD */ + Ins_MD( EXEC_ARG_ 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_ARG_ 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_ARG_ 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_ARG_ args ); + break; + + case 0x73: /* DELTAC0 */ + case 0x74: /* DELTAC1 */ + case 0x75: /* DELTAC2 */ + Ins_DELTAC( EXEC_ARG_ 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_ARG_ 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_ARG_ args ); + break; + + case 0x81: /* FLIPRGON */ + Ins_FLIPRGON( EXEC_ARG_ args ); + break; + + case 0x82: /* FLIPRGOFF */ + Ins_FLIPRGOFF( EXEC_ARG_ args ); + break; + + case 0x83: /* UNKNOWN */ + case 0x84: /* UNKNOWN */ + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + case 0x85: /* SCANCTRL */ + Ins_SCANCTRL( EXEC_ARG_ args ); + break; + + case 0x86: /* SDPVTL */ + case 0x87: /* SDPVTL */ + Ins_SDPVTL( EXEC_ARG_ args ); + break; + + case 0x88: /* GETINFO */ + Ins_GETINFO( EXEC_ARG_ args ); + break; + + case 0x89: /* IDEF */ + Ins_IDEF( EXEC_ARG_ args ); + break; + + case 0x8A: /* ROLL */ + Ins_ROLL( EXEC_ARG_ args ); + break; + + case 0x8B: /* MAX */ + DO_MAX + break; + + case 0x8C: /* MIN */ + DO_MIN + break; + + case 0x8D: /* SCANTYPE */ + Ins_SCANTYPE( EXEC_ARG_ args ); + break; + + case 0x8E: /* INSTCTRL */ + Ins_INSTCTRL( EXEC_ARG_ args ); + break; + + case 0x8F: + Ins_UNKNOWN( EXEC_ARG_ args ); + break; + + default: + if ( opcode >= 0xE0 ) + Ins_MIRP( EXEC_ARG_ args ); + else if ( opcode >= 0xC0 ) + Ins_MDRP( EXEC_ARG_ args ); + else if ( opcode >= 0xB8 ) + Ins_PUSHW( EXEC_ARG_ args ); + else if ( opcode >= 0xB0 ) + Ins_PUSHB( EXEC_ARG_ args ); + else + Ins_UNKNOWN( EXEC_ARG_ args ); + } + + } + +#else + + Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); + +#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ + + if ( CUR.error != TT_Err_Ok ) + { + switch ( CUR.error ) + { + case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ + { + TT_DefRecord* def = CUR.IDefs; + TT_DefRecord* limit = def + CUR.numIDefs; + + + for ( ; def < limit; def++ ) + { + if ( def->active && CUR.opcode == (FT_Byte)def->opc ) + { + TT_CallRec* callrec; + + + if ( CUR.callTop >= CUR.callSize ) + { + CUR.error = TT_Err_Invalid_Reference; + goto LErrorLabel_; + } + + callrec = &CUR.callStack[CUR.callTop]; + + callrec->Caller_Range = CUR.curRange; + callrec->Caller_IP = CUR.IP + 1; + callrec->Cur_Count = 1; + callrec->Cur_Restart = def->start; + + if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) + goto LErrorLabel_; + + goto LSuiteLabel_; + } + } + } + + CUR.error = TT_Err_Invalid_Opcode; + goto LErrorLabel_; + +#if 0 + break; /* Unreachable code warning suppression. */ + /* Leave to remind in case a later change the editor */ + /* to consider break; */ +#endif + + default: + goto LErrorLabel_; + +#if 0 + break; +#endif + } + } + + 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 ) + return TT_Err_Execution_Too_Long; + + 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_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + return TT_Err_Ok; + + LErrorCodeOverflow_: + CUR.error = TT_Err_Code_Overflow; + + LErrorLabel_: + +#ifdef TT_CONFIG_OPTION_STATIC_RASTER + *exc = cur; +#endif + + return CUR.error; + } + + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + +/* END */ diff --git a/lib/freetype/src/truetype/ttinterp.h b/lib/freetype/src/truetype/ttinterp.h new file mode 100644 index 0000000..e750963 --- /dev/null +++ b/lib/freetype/src/truetype/ttinterp.h @@ -0,0 +1,317 @@ +/***************************************************************************/ +/* */ +/* ttinterp.h */ +/* */ +/* TrueType bytecode interpreter (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTINTERP_H__ +#define __TTINTERP_H__ + + +#include +#include "ttobjs.h" + + +FT_BEGIN_HEADER + + +#ifndef TT_CONFIG_OPTION_STATIC_INTEPRETER /* indirect implementation */ + +#define EXEC_OP_ TT_ExecContext exc, +#define EXEC_OP TT_ExecContext exc +#define EXEC_ARG_ exc, +#define EXEC_ARG exc + +#else /* static implementation */ + +#define EXEC_OP_ /* void */ +#define EXEC_OP /* void */ +#define EXEC_ARG_ /* void */ +#define EXEC_ARG /* void */ + +#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* 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 + + + /*************************************************************************/ + /* */ + /* Function types used by the interpreter, depending on various modes */ + /* (e.g. the rounding mode, whether to render a vertical or horizontal */ + /* line etc). */ + /* */ + /*************************************************************************/ + + /* Rounding function */ + typedef FT_F26Dot6 + (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, + FT_F26Dot6 compensation ); + + /* Point displacement along the freedom vector routine */ + typedef void + (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone zone, + FT_UShort point, + FT_F26Dot6 distance ); + + /* Distance projection along one of the projection vectors */ + typedef FT_F26Dot6 + (*TT_Project_Func)( EXEC_OP_ FT_Vector* v1, + FT_Vector* v2 ); + + /* reading a cvt value. Take care of non-square pixels if necessary */ + typedef FT_F26Dot6 + (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong idx ); + + /* setting or moving a cvt value. Take care of non-square pixels */ + /* if necessary */ + typedef void + (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong idx, + FT_F26Dot6 value ); + + + /*************************************************************************/ + /* */ + /* This structure defines a call record, used to manage function calls. */ + /* */ + typedef struct TT_CallRec_ + { + FT_Int Caller_Range; + FT_Long Caller_IP; + FT_Long Cur_Count; + FT_Long Cur_Restart; + + } TT_CallRec, *TT_CallStack; + + + /*************************************************************************/ + /* */ + /* The main structure for the interpreter which collects all necessary */ + /* variables and states. */ + /* */ + typedef struct TT_ExecContextRec_ + { + TT_Face face; + TT_Size size; + FT_Memory memory; + + /* instructions state */ + + FT_Error error; /* last execution error */ + + FT_Long top; /* top of exec. stack */ + + FT_UInt stackSize; /* size of exec. stack */ + FT_Long* stack; /* current exec. stack */ + + FT_Long args; + FT_UInt new_top; /* new top after exec. */ + + TT_GlyphZoneRec zp0, /* zone records */ + zp1, + zp2, + pts, + twilight; + + FT_Size_Metrics metrics; + TT_Size_Metrics tt_metrics; /* size metrics */ + + TT_GraphicsState GS; /* current graphics state */ + + FT_Int curRange; /* current code range number */ + FT_Byte* code; /* current code range */ + FT_Long IP; /* current instruction pointer */ + FT_Long codeSize; /* size of current range */ + + FT_Byte opcode; /* current opcode */ + FT_Int length; /* length of current opcode */ + + FT_Bool step_ins; /* true if the interpreter must */ + /* increment IP after ins. exec */ + FT_Long cvtSize; + FT_Long* cvt; + + FT_UInt glyphSize; /* glyph instructions buffer size */ + FT_Byte* glyphIns; /* glyph instructions buffer */ + + FT_UInt numFDefs; /* number of function defs */ + FT_UInt maxFDefs; /* maximum number of function defs */ + TT_DefArray FDefs; /* table of FDefs entries */ + + FT_UInt numIDefs; /* number of instruction defs */ + FT_UInt maxIDefs; /* maximum number of ins defs */ + TT_DefArray IDefs; /* table of IDefs entries */ + + FT_UInt maxFunc; /* maximum function index */ + FT_UInt maxIns; /* maximum instruction index */ + + FT_Int callTop, /* top of call stack during execution */ + callSize; /* size of call stack */ + TT_CallStack callStack; /* call stack */ + + FT_UShort maxPoints; /* capacity of this context's `pts' */ + FT_Short maxContours; /* record, expressed in points and */ + /* contours. */ + + TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ + /* useful for the debugger */ + + FT_UShort storeSize; /* size of current storage */ + FT_Long* storage; /* storage area */ + + FT_F26Dot6 period; /* values used for the */ + FT_F26Dot6 phase; /* `SuperRounding' */ + FT_F26Dot6 threshold; + +#if 0 + /* this seems to be unused */ + FT_Int cur_ppem; /* ppem along the current proj vector */ +#endif + + FT_Bool instruction_trap; /* If `True', the interpreter will */ + /* exit after each instruction */ + + TT_GraphicsState default_GS; /* graphics state resulting from */ + /* the prep program */ + FT_Bool is_composite; /* true if the glyph is composite */ + FT_Bool pedantic_hinting; /* true if pedantic interpretation */ + + /* latest interpreter additions */ + + FT_Long F_dot_P; /* dot product of freedom and projection */ + /* vectors */ + TT_Round_Func func_round; /* current rounding function */ + + TT_Project_Func func_project, /* current projection function */ + func_dualproj, /* current dual proj. function */ + func_freeProj; /* current freedom proj. func */ + + TT_Move_Func func_move; /* current point move function */ + + TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ + TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ + TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ + + FT_ULong loadSize; + TT_SubGlyph_Stack loadStack; /* loading subglyph stack */ + + } TT_ExecContextRec; + + + extern const TT_GraphicsState tt_default_graphics_state; + + + FT_LOCAL( FT_Error ) + TT_Goto_CodeRange( TT_ExecContext exec, + FT_Int range, + FT_Long IP ); + + FT_LOCAL( FT_Error ) + TT_Set_CodeRange( TT_ExecContext exec, + FT_Int range, + void* base, + FT_Long length ); + + FT_LOCAL( FT_Error ) + TT_Clear_CodeRange( TT_ExecContext exec, + FT_Int range ); + + + /*************************************************************************/ + /* */ + /* */ + /* TT_New_Context */ + /* */ + /* */ + /* Queries the face context for a given font. Note that there is */ + /* now a _single_ execution context in the TrueType driver which is */ + /* shared among faces. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* */ + /* A handle to the execution context. Initialized for `face'. */ + /* */ + /* */ + /* Only the glyph loader and debugger should call this function. */ + /* */ + FT_EXPORT( TT_ExecContext ) + TT_New_Context( TT_Face face ); + + + FT_LOCAL( FT_Error ) + TT_Done_Context( TT_ExecContext exec ); + + FT_LOCAL( FT_Error ) + TT_Destroy_Context( TT_ExecContext exec, + FT_Memory memory ); + + FT_LOCAL( FT_Error ) + TT_Load_Context( TT_ExecContext exec, + TT_Face face, + TT_Size size ); + + FT_LOCAL( FT_Error ) + TT_Save_Context( TT_ExecContext exec, + TT_Size ins ); + + FT_LOCAL( FT_Error ) + TT_Run_Context( TT_ExecContext exec, + FT_Bool debug ); + + + /*************************************************************************/ + /* */ + /* */ + /* TT_RunIns */ + /* */ + /* */ + /* Executes one or more instruction in the execution context. This */ + /* is the main function of the TrueType opcode interpreter. */ + /* */ + /* */ + /* exec :: A handle to the target execution context. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only the object manager and debugger should call this function. */ + /* */ + /* This function is publicly exported because it is directly */ + /* invoked by the TrueType debugger. */ + /* */ + FT_EXPORT( FT_Error ) + TT_RunIns( TT_ExecContext exec ); + + +FT_END_HEADER + +#endif /* __TTINTERP_H__ */ + + +/* END */ diff --git a/lib/freetype/src/truetype/ttobjs.c b/lib/freetype/src/truetype/ttobjs.c new file mode 100644 index 0000000..9d78bae --- /dev/null +++ b/lib/freetype/src/truetype/ttobjs.c @@ -0,0 +1,865 @@ +/***************************************************************************/ +/* */ +/* ttobjs.c */ +/* */ +/* Objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + +#include "ttgload.h" +#include "ttpload.h" + +#include "tterrors.h" + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#include "ttinterp.h" +#endif + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttobjs + + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* GLYPH ZONE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* tt_glyphzone_done */ + /* */ + /* */ + /* Deallocates a glyph zone. */ + /* */ + /* */ + /* zone :: A pointer to the target glyph zone. */ + /* */ + FT_LOCAL_DEF( void ) + tt_glyphzone_done( TT_GlyphZone zone ) + { + FT_Memory memory = zone->memory; + + if ( memory ) + { + FT_FREE( zone->contours ); + FT_FREE( zone->tags ); + FT_FREE( zone->cur ); + FT_FREE( zone->org ); + + zone->max_points = zone->n_points = 0; + zone->max_contours = zone->n_contours = 0; + zone->memory = NULL; + } + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_glyphzone_new */ + /* */ + /* */ + /* Allocates a new glyph zone. */ + /* */ + /* */ + /* memory :: A handle to the current memory object. */ + /* */ + /* maxPoints :: The capacity of glyph zone in points. */ + /* */ + /* maxContours :: The capacity of glyph zone in contours. */ + /* */ + /* */ + /* zone :: A pointer to the target glyph zone record. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ) + { + FT_Error error; + + + if ( maxPoints > 0 ) + maxPoints += 2; + + FT_MEM_ZERO( zone, sizeof ( *zone ) ); + zone->memory = memory; + + if ( FT_NEW_ARRAY( zone->org, maxPoints * 2 ) || + FT_NEW_ARRAY( zone->cur, maxPoints * 2 ) || + FT_NEW_ARRAY( zone->tags, maxPoints ) || + FT_NEW_ARRAY( zone->contours, maxContours ) ) + { + tt_glyphzone_done( zone ); + } + + return error; + } +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* */ + /* tt_face_init */ + /* */ + /* */ + /* Initializes a given TrueType face object. */ + /* */ + /* */ + /* stream :: The source font stream. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* */ + /* face :: The newly built face object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_init( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Library library; + SFNT_Service sfnt; + + + library = face->root.driver->root.library; + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); + if ( !sfnt ) + goto Bad_Format; + + /* create input stream from resource */ + if ( FT_STREAM_SEEK( 0 ) ) + goto Exit; + + /* check that we have a valid TrueType file */ + error = sfnt->init_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + /* We must also be able to accept Mac/GX fonts, as well as OT ones */ + if ( face->format_tag != 0x00010000L && /* MS fonts */ + face->format_tag != TTAG_true ) /* Mac fonts */ + { + FT_TRACE2(( "[not a valid TTF font]\n" )); + goto Bad_Format; + } + + /* If we are performing a simple font format check, exit immediately */ + if ( face_index < 0 ) + return TT_Err_Ok; + + /* Load font directory */ + error = sfnt->load_face( stream, face, face_index, num_params, params ); + if ( error ) + goto Exit; + + if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) + { + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + if ( !face->root.internal->incremental_interface ) + error = tt_face_load_loca( face, stream ); + if ( !error ) + error = tt_face_load_cvt ( face, stream ) || + tt_face_load_fpgm ( face, stream ); + +#else + + if ( !error ) + error = tt_face_load_loca( face, stream ) || + tt_face_load_cvt ( face, stream ) || + tt_face_load_fpgm ( face, stream ); + +#endif + + } + + /* initialize standard glyph loading routines */ + TT_Init_Glyph_Loading( face ); + + Exit: + return error; + + Bad_Format: + error = TT_Err_Unknown_File_Format; + goto Exit; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_face_done */ + /* */ + /* */ + /* Finalizes a given face object. */ + /* */ + /* */ + /* face :: A pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + tt_face_done( TT_Face face ) + { + FT_Memory memory = face->root.memory; + FT_Stream stream = face->root.stream; + + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + + /* for `extended TrueType formats' (i.e. compressed versions) */ + if ( face->extra.finalizer ) + face->extra.finalizer( face->extra.data ); + + if ( sfnt ) + sfnt->done_face( face ); + + /* freeing the locations table */ + FT_FREE( face->glyph_locations ); + face->num_locations = 0; + + /* freeing the CVT */ + FT_FREE( face->cvt ); + face->cvt_size = 0; + + /* freeing the programs */ + FT_FRAME_RELEASE( face->font_program ); + FT_FRAME_RELEASE( face->cvt_program ); + face->font_program_size = 0; + face->cvt_program_size = 0; + } + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* tt_size_init */ + /* */ + /* */ + /* Initializes a new TrueType size object. */ + /* */ + /* */ + /* size :: A handle to the size object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_init( TT_Size size ) + { + FT_Error error = TT_Err_Ok; + + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + TT_Face face = (TT_Face)size->root.face; + FT_Memory memory = face->root.memory; + FT_Int i; + + TT_ExecContext exec; + FT_UShort n_twilight; + TT_MaxProfile* maxp = &face->max_profile; + + + size->ttmetrics.valid = FALSE; + + size->max_function_defs = maxp->maxFunctionDefs; + size->max_instruction_defs = maxp->maxInstructionDefs; + + size->num_function_defs = 0; + size->num_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + + size->cvt_size = face->cvt_size; + size->storage_size = maxp->maxStorage; + + /* Set default metrics */ + { + FT_Size_Metrics* metrics = &size->root.metrics; + TT_Size_Metrics* metrics2 = &size->ttmetrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + + metrics2->rotated = FALSE; + metrics2->stretched = FALSE; + + /* set default compensation (all 0) */ + for ( i = 0; i < 4; i++ ) + metrics2->compensations[i] = 0; + } + + /* allocate function defs, instruction defs, cvt, and storage area */ + if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || + FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || + FT_NEW_ARRAY( size->cvt, size->cvt_size ) || + FT_NEW_ARRAY( size->storage, size->storage_size ) ) + + goto Fail_Memory; + + /* reserve twilight zone */ + n_twilight = maxp->maxTwilightPoints; + error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); + if ( error ) + goto Fail_Memory; + + size->twilight.n_points = n_twilight; + + /* set `face->interpreter' according to the debug hook present */ + { + FT_Library library = face->root.driver->root.library; + + + face->interpreter = (TT_Interpreter) + library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; + if ( !face->interpreter ) + face->interpreter = (TT_Interpreter)TT_RunIns; + } + + /* Fine, now execute the font program! */ + exec = size->context; + /* size objects used during debugging have their own context */ + if ( !size->debug ) + exec = TT_New_Context( face ); + + if ( !exec ) + { + error = TT_Err_Could_Not_Find_Context; + goto Fail_Memory; + } + + size->GS = tt_default_graphics_state; + TT_Load_Context( exec, face, size ); + + exec->callTop = 0; + exec->top = 0; + + exec->period = 64; + exec->phase = 0; + exec->threshold = 0; + + { + FT_Size_Metrics* metrics = &exec->metrics; + TT_Size_Metrics* tt_metrics = &exec->tt_metrics; + + + metrics->x_ppem = 0; + metrics->y_ppem = 0; + metrics->x_scale = 0; + metrics->y_scale = 0; + + tt_metrics->ppem = 0; + tt_metrics->scale = 0; + tt_metrics->ratio = 0x10000L; + } + + exec->instruction_trap = FALSE; + + exec->cvtSize = size->cvt_size; + exec->cvt = size->cvt; + + exec->F_dot_P = 0x10000L; + + /* allow font program execution */ + TT_Set_CodeRange( exec, + tt_coderange_font, + face->font_program, + face->font_program_size ); + + /* disable CVT and glyph programs coderange */ + TT_Clear_CodeRange( exec, tt_coderange_cvt ); + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + if ( face->font_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); + if ( !error ) + error = face->interpreter( exec ); + + if ( error ) + goto Fail_Exec; + } + else + error = TT_Err_Ok; + + TT_Save_Context( exec, size ); + + if ( !size->debug ) + TT_Done_Context( exec ); + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + size->ttmetrics.valid = FALSE; + return error; + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + Fail_Exec: + if ( !size->debug ) + TT_Done_Context( exec ); + + Fail_Memory: + + tt_size_done( size ); + return error; + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_size_done */ + /* */ + /* */ + /* The TrueType size object finalizer. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( void ) + tt_size_done( TT_Size size ) + { + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + FT_Memory memory = size->root.face->memory; + + + if ( size->debug ) + { + /* the debug context must be deleted by the debugger itself */ + size->context = NULL; + size->debug = FALSE; + } + + FT_FREE( size->cvt ); + size->cvt_size = 0; + + /* free storage area */ + FT_FREE( size->storage ); + size->storage_size = 0; + + /* twilight zone */ + tt_glyphzone_done( &size->twilight ); + + FT_FREE( size->function_defs ); + FT_FREE( size->instruction_defs ); + + size->num_function_defs = 0; + size->max_function_defs = 0; + size->num_instruction_defs = 0; + size->max_instruction_defs = 0; + + size->max_func = 0; + size->max_ins = 0; + +#endif + + size->ttmetrics.valid = FALSE; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Reset_Outline_Size */ + /* */ + /* */ + /* Resets a TrueType outline size when resolutions and character */ + /* dimensions have been changed. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + static FT_Error + Reset_Outline_Size( TT_Size size ) + { + TT_Face face; + FT_Error error = TT_Err_Ok; + + FT_Size_Metrics* metrics; + + + if ( size->ttmetrics.valid ) + return TT_Err_Ok; + + face = (TT_Face)size->root.face; + + metrics = &size->metrics; + + if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) + return TT_Err_Invalid_PPem; + + /* compute new transformation */ + if ( metrics->x_ppem >= metrics->y_ppem ) + { + size->ttmetrics.scale = metrics->x_scale; + size->ttmetrics.ppem = metrics->x_ppem; + size->ttmetrics.x_ratio = 0x10000L; + size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, + 0x10000L, + metrics->x_ppem ); + } + else + { + size->ttmetrics.scale = metrics->y_scale; + size->ttmetrics.ppem = metrics->y_ppem; + size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, + 0x10000L, + metrics->y_ppem ); + size->ttmetrics.y_ratio = 0x10000L; + } + + /* Compute root ascender, descender, test height, and max_advance */ + metrics->ascender = ( FT_MulFix( face->root.ascender, + metrics->y_scale ) + 32 ) & -64; + metrics->descender = ( FT_MulFix( face->root.descender, + metrics->y_scale ) + 32 ) & -64; + metrics->height = ( FT_MulFix( face->root.height, + metrics->y_scale ) + 32 ) & -64; + metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, + metrics->x_scale ) + 32 ) & -64; + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + /* set to `invalid' by default */ + size->strike_index = 0xFFFFU; +#endif + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + { + TT_ExecContext exec; + FT_UInt i, j; + + + /* Scale the cvt values to the new ppem. */ + /* We use by default the y ppem to scale the CVT. */ + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + + /* All twilight points are originally zero */ + for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ ) + { + size->twilight.org[j].x = 0; + size->twilight.org[j].y = 0; + size->twilight.cur[j].x = 0; + size->twilight.cur[j].y = 0; + } + + /* clear storage area */ + for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) + size->storage[i] = 0; + + size->GS = tt_default_graphics_state; + + /* get execution context and run prep program */ + if ( size->debug ) + exec = size->context; + else + exec = TT_New_Context( face ); + /* debugging instances have their own context */ + + if ( !exec ) + return TT_Err_Could_Not_Find_Context; + + TT_Load_Context( exec, face, size ); + + TT_Set_CodeRange( exec, + tt_coderange_cvt, + face->cvt_program, + face->cvt_program_size ); + + TT_Clear_CodeRange( exec, tt_coderange_glyph ); + + exec->instruction_trap = FALSE; + + exec->top = 0; + exec->callTop = 0; + + if ( face->cvt_program_size > 0 ) + { + error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); + if ( error ) + goto End; + + if ( !size->debug ) + error = face->interpreter( exec ); + } + else + error = TT_Err_Ok; + + size->GS = exec->GS; + /* save default graphics state */ + + End: + TT_Save_Context( exec, size ); + + if ( !size->debug ) + TT_Done_Context( exec ); + /* debugging instances keep their context */ + } + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + if ( !error ) + size->ttmetrics.valid = TRUE; + + return error; + } + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /*************************************************************************/ + /* */ + /* */ + /* Reset_SBit_Size */ + /* */ + /* */ + /* Resets a TrueType sbit size when resolutions and character */ + /* dimensions have been changed. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + static FT_Error + Reset_SBit_Size( TT_Size size ) + { + TT_Face face; + FT_Error error = TT_Err_Ok; + + FT_ULong strike_index; + FT_Size_Metrics* metrics; + FT_Size_Metrics* sbit_metrics; + SFNT_Service sfnt; + + + metrics = &size->metrics; + + if ( size->strike_index != 0xFFFFU ) + return TT_Err_Ok; + + face = (TT_Face)size->root.face; + sfnt = (SFNT_Service)face->sfnt; + + sbit_metrics = &size->strike_metrics; + + error = sfnt->set_sbit_strike(face, + metrics->x_ppem, metrics->y_ppem, + &strike_index); + + if ( !error ) + { + TT_SBit_Strike strike = face->sbit_strikes + strike_index; + + + sbit_metrics->x_ppem = metrics->x_ppem; + sbit_metrics->y_ppem = metrics->y_ppem; +#if 0 + /* + * sbit_metrics->?_scale + * are not used now. + */ + sbit_metrics->x_scale = 1 << 16; + sbit_metrics->y_scale = 1 << 16; +#endif + + sbit_metrics->ascender = strike->hori.ascender << 6; + sbit_metrics->descender = strike->hori.descender << 6; + + /* XXX: Is this correct? */ + sbit_metrics->height = sbit_metrics->ascender - + sbit_metrics->descender; + + /* XXX: Is this correct? */ + sbit_metrics->max_advance = ( strike->hori.min_origin_SB + + strike->hori.max_width + + strike->hori.min_advance_SB ) << 6; + + size->strike_index = strike_index; + } + else + { + size->strike_index = 0xFFFFU; + + sbit_metrics->x_ppem = 0; + sbit_metrics->y_ppem = 0; + sbit_metrics->ascender = 0; + sbit_metrics->descender = 0; + sbit_metrics->height = 0; + sbit_metrics->max_advance = 0; + } + + return error; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + + /*************************************************************************/ + /* */ + /* */ + /* tt_size_reset */ + /* */ + /* */ + /* Resets a TrueType size when resolutions and character dimensions */ + /* have been changed. */ + /* */ + /* */ + /* size :: A handle to the target size object. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_size_reset( TT_Size size ) + { + FT_Face face; + FT_Error error = TT_Err_Ok; + + + face = size->root.face; + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + { + if ( !size->ttmetrics.valid ) + error = Reset_Outline_Size( size ); + + if ( error ) + return error; + } + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + { + if ( size->strike_index == 0xFFFFU ) + error = Reset_SBit_Size( size ); + + if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) + size->root.metrics = size->strike_metrics; + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + return TT_Err_Ok; + else + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_driver_init */ + /* */ + /* */ + /* Initializes a given TrueType driver object. */ + /* */ + /* */ + /* driver :: A handle to the target driver object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_driver_init( TT_Driver driver ) + { + FT_Error error; + + + /* set `extra' in glyph loader */ + error = FT_GlyphLoader_CreateExtra( FT_DRIVER( driver )->glyph_loader ); + + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_driver_done */ + /* */ + /* */ + /* Finalizes a given TrueType driver. */ + /* */ + /* */ + /* driver :: A handle to the target TrueType driver. */ + /* */ + FT_LOCAL_DEF( void ) + tt_driver_done( TT_Driver driver ) + { +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + /* destroy the execution context */ + if ( driver->context ) + { + TT_Destroy_Context( driver->context, driver->root.root.memory ); + driver->context = NULL; + } +#else + FT_UNUSED( driver ); +#endif + + } + + +/* END */ diff --git a/lib/freetype/src/truetype/ttobjs.h b/lib/freetype/src/truetype/ttobjs.h new file mode 100644 index 0000000..e462d64 --- /dev/null +++ b/lib/freetype/src/truetype/ttobjs.h @@ -0,0 +1,423 @@ +/***************************************************************************/ +/* */ +/* ttobjs.h */ +/* */ +/* Objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Driver */ + /* */ + /* */ + /* A handle to a TrueType driver object. */ + /* */ + typedef struct TT_DriverRec_* TT_Driver; + + + /*************************************************************************/ + /* */ + /* */ + /* TT_Instance */ + /* */ + /* */ + /* A handle to a TrueType size object. */ + /* */ + typedef struct TT_SizeRec_* TT_Size; + + + /*************************************************************************/ + /* */ + /* */ + /* TT_GlyphSlot */ + /* */ + /* */ + /* A handle to a TrueType glyph slot object. */ + /* */ + /* */ + /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ + /* specific about the TrueType glyph slot. */ + /* */ + typedef FT_GlyphSlot TT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* */ + /* TT_GraphicsState */ + /* */ + /* */ + /* The TrueType graphics state used during bytecode interpretation. */ + /* */ + typedef struct TT_GraphicsState_ + { + FT_UShort rp0; + FT_UShort rp1; + FT_UShort rp2; + + FT_UnitVector dualVector; + FT_UnitVector projVector; + FT_UnitVector freeVector; + + FT_Long loop; + FT_F26Dot6 minimum_distance; + FT_Int round_state; + + FT_Bool auto_flip; + FT_F26Dot6 control_value_cutin; + FT_F26Dot6 single_width_cutin; + FT_F26Dot6 single_width_value; + FT_Short delta_base; + FT_Short delta_shift; + + FT_Byte instruct_control; + FT_Bool scan_control; + FT_Int scan_type; + + FT_UShort gep0; + FT_UShort gep1; + FT_UShort gep2; + + } TT_GraphicsState; + + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + FT_LOCAL( void ) + tt_glyphzone_done( TT_GlyphZone zone ); + + FT_LOCAL( FT_Error ) + tt_glyphzone_new( FT_Memory memory, + FT_UShort maxPoints, + FT_Short maxContours, + TT_GlyphZone zone ); + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + + /*************************************************************************/ + /* */ + /* EXECUTION SUBTABLES */ + /* */ + /* These sub-tables relate to instruction execution. */ + /* */ + /*************************************************************************/ + + +#define TT_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 */ + /* */ + typedef enum TT_CodeRange_Tag_ + { + tt_coderange_none = 0, + tt_coderange_font, + tt_coderange_cvt, + tt_coderange_glyph + + } TT_CodeRange_Tag; + + + typedef struct TT_CodeRange_ + { + FT_Byte* base; + FT_ULong size; + + } TT_CodeRange; + + typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; + + + /*************************************************************************/ + /* */ + /* Defines a function/instruction definition record. */ + /* */ + typedef struct TT_DefRecord_ + { + FT_Int range; /* in which code range is it located? */ + FT_Long start; /* where does it start? */ + FT_UInt opc; /* function #, or instruction code */ + FT_Bool active; /* is it active? */ + + } TT_DefRecord, *TT_DefArray; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct TT_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } TT_Transform; + + + /*************************************************************************/ + /* */ + /* Subglyph loading record. Used to load composite components. */ + /* */ + typedef struct TT_SubglyphRec_ + { + FT_Long index; /* subglyph index; initialized with -1 */ + FT_Bool is_scaled; /* is the subglyph scaled? */ + FT_Bool is_hinted; /* should it be hinted? */ + FT_Bool preserve_pps; /* preserve phantom points? */ + + FT_Long file_offset; + + FT_BBox bbox; + FT_Pos left_bearing; + FT_Pos advance; + + TT_GlyphZoneRec zone; + + FT_Long arg1; /* first argument */ + FT_Long arg2; /* second argument */ + + FT_UShort element_flag; /* current load element flag */ + + TT_Transform transform; /* transformation matrix */ + + FT_Vector pp1, pp2; /* phantom points */ + + } TT_SubGlyphRec, *TT_SubGlyph_Stack; + + + /*************************************************************************/ + /* */ + /* A note regarding non-squared pixels: */ + /* */ + /* (This text will probably go into some docs at some time; for now, it */ + /* is kept here 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, some others are used under 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, */ + /* ratio = 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 TrueType size and context objects. */ + /* */ + typedef struct TT_Size_Metrics_ + { + /* for non-square pixels */ + FT_Long x_ratio; + FT_Long y_ratio; + + FT_UShort ppem; /* maximum ppem size */ + FT_Long ratio; /* current ratio */ + FT_Fixed scale; + + FT_F26Dot6 compensations[4]; /* device-specific compensations */ + + FT_Bool valid; + + FT_Bool rotated; /* `is the glyph rotated?'-flag */ + FT_Bool stretched; /* `is the glyph stretched?'-flag */ + + } TT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* TrueType size class. */ + /* */ + typedef struct TT_SizeRec_ + { + FT_SizeRec root; + + FT_Size_Metrics metrics; /* slightly different from the root metrics */ + TT_Size_Metrics ttmetrics; + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + FT_UInt strike_index; /* 0xFFFF to indicate invalid */ + FT_Size_Metrics strike_metrics; /* current strike's metrics */ + +#endif + +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + + FT_UInt num_function_defs; /* number of function definitions */ + FT_UInt max_function_defs; + TT_DefArray function_defs; /* table of function definitions */ + + FT_UInt num_instruction_defs; /* number of ins. definitions */ + FT_UInt max_instruction_defs; + TT_DefArray instruction_defs; /* table of ins. definitions */ + + FT_UInt max_func; + FT_UInt max_ins; + + TT_CodeRangeTable codeRangeTable; + + TT_GraphicsState GS; + + FT_ULong cvt_size; /* the scaled control value table */ + FT_Long* cvt; + + FT_UShort storage_size; /* The storage area is now part of */ + FT_Long* storage; /* the instance */ + + TT_GlyphZoneRec 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. */ + + FT_Bool debug; + TT_ExecContext context; + +#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + } TT_SizeRec; + + + /*************************************************************************/ + /* */ + /* TrueType driver class. */ + /* */ + typedef struct TT_DriverRec_ + { + FT_DriverRec root; + TT_ExecContext context; /* execution context */ + TT_GlyphZoneRec zone; /* glyph loader points zone */ + + void* extension_component; + + } TT_DriverRec; + + + /*************************************************************************/ + /* */ + /* Face functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_face_init( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + tt_face_done( TT_Face face ); + + + /*************************************************************************/ + /* */ + /* Size functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_size_init( TT_Size size ); + + FT_LOCAL( void ) + tt_size_done( TT_Size size ); + + FT_LOCAL( FT_Error ) + tt_size_reset( TT_Size size ); + + + /*************************************************************************/ + /* */ + /* Driver functions */ + /* */ + FT_LOCAL( FT_Error ) + tt_driver_init( TT_Driver driver ); + + FT_LOCAL( void ) + tt_driver_done( TT_Driver driver ); + + +FT_END_HEADER + +#endif /* __TTOBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/truetype/ttpload.c b/lib/freetype/src/truetype/ttpload.c new file mode 100644 index 0000000..4066cd7 --- /dev/null +++ b/lib/freetype/src/truetype/ttpload.c @@ -0,0 +1,264 @@ +/***************************************************************************/ +/* */ +/* ttpload.c */ +/* */ +/* TrueType glyph data/program tables loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_STREAM_H +#include FT_TRUETYPE_TAGS_H + +#include "ttpload.h" + +#include "tterrors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_ttpload + + + /*************************************************************************/ + /* */ + /* */ + /* tt_face_load_loca */ + /* */ + /* */ + /* Loads the locations table. */ + /* */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* */ + /* stream :: The input stream. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_Short LongOffsets; + FT_ULong table_len; + + + FT_TRACE2(( "Locations " )); + LongOffsets = face->header.Index_To_Loc_Format; + + error = face->goto_table( face, TTAG_loca, stream, &table_len ); + if ( error ) + { + error = TT_Err_Locations_Missing; + goto Exit; + } + + if ( LongOffsets != 0 ) + { + face->num_locations = (FT_UShort)( table_len >> 2 ); + + FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); + + if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) + goto Exit; + + if ( FT_FRAME_ENTER( face->num_locations * 4L ) ) + goto Exit; + + { + FT_Long* loc = face->glyph_locations; + FT_Long* limit = loc + face->num_locations; + + + for ( ; loc < limit; loc++ ) + *loc = FT_GET_LONG(); + } + + FT_FRAME_EXIT(); + } + else + { + face->num_locations = (FT_UShort)( table_len >> 1 ); + + FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations )); + + if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) ) + goto Exit; + + if ( FT_FRAME_ENTER( face->num_locations * 2L ) ) + goto Exit; + { + FT_Long* loc = face->glyph_locations; + FT_Long* limit = loc + face->num_locations; + + + for ( ; loc < limit; loc++ ) + *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 ); + } + FT_FRAME_EXIT(); + } + + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_face_load_cvt */ + /* */ + /* */ + /* Loads the control value table into a face object. */ + /* */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_ULong table_len; + + + FT_TRACE2(( "CVT " )); + + error = face->goto_table( face, TTAG_cvt, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing!\n" )); + + face->cvt_size = 0; + face->cvt = NULL; + error = TT_Err_Ok; + + goto Exit; + } + + face->cvt_size = table_len / 2; + + if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) ) + goto Exit; + + if ( FT_FRAME_ENTER( face->cvt_size * 2L ) ) + goto Exit; + + { + FT_Short* cur = face->cvt; + FT_Short* limit = cur + face->cvt_size; + + + for ( ; cur < limit; cur++ ) + *cur = FT_GET_SHORT(); + } + + FT_FRAME_EXIT(); + FT_TRACE2(( "loaded\n" )); + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* tt_face_load_fpgm */ + /* */ + /* */ + /* Loads the font program and the cvt program. */ + /* */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* */ + /* stream :: A handle to the input stream. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_ULong table_len; + + + FT_TRACE2(( "Font program " )); + + /* The font program is optional */ + error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); + if ( error ) + { + face->font_program = NULL; + face->font_program_size = 0; + + FT_TRACE2(( "is missing!\n" )); + } + else + { + face->font_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->font_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); + } + + FT_TRACE2(( "Prep program " )); + + error = face->goto_table( face, TTAG_prep, stream, &table_len ); + if ( error ) + { + face->cvt_program = NULL; + face->cvt_program_size = 0; + error = TT_Err_Ok; + + FT_TRACE2(( "is missing!\n" )); + } + else + { + face->cvt_program_size = table_len; + if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) ) + goto Exit; + + FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); + } + + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/truetype/ttpload.h b/lib/freetype/src/truetype/ttpload.h new file mode 100644 index 0000000..3f8cd64 --- /dev/null +++ b/lib/freetype/src/truetype/ttpload.h @@ -0,0 +1,48 @@ +/***************************************************************************/ +/* */ +/* ttpload.h */ +/* */ +/* TrueType glyph data/program tables loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __TTPLOAD_H__ +#define __TTPLOAD_H__ + + +#include +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + tt_face_load_loca( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_Error ) + tt_face_load_cvt( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( FT_Error ) + tt_face_load_fpgm( TT_Face face, + FT_Stream stream ); + + +FT_END_HEADER + +#endif /* __TTPLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/Jamfile b/lib/freetype/src/type1/Jamfile new file mode 100644 index 0000000..4d966f3 --- /dev/null +++ b/lib/freetype/src/type1/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/type1 Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) type1 ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = t1afm t1driver t1objs t1load t1gload t1parse ; + } + else + { + _sources = type1 ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/type1 Jamfile diff --git a/lib/freetype/src/type1/descrip.mms b/lib/freetype/src/type1/descrip.mms new file mode 100644 index 0000000..8f028f6 --- /dev/null +++ b/lib/freetype/src/type1/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 Type1 driver compilation rules for VMS +# + + +# Copyright 1996-2000, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type1]) + +OBJS=type1.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/type1/module.mk b/lib/freetype/src/type1/module.mk new file mode 100644 index 0000000..82d9355 --- /dev/null +++ b/lib/freetype/src/type1/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 Type1 module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_type1_driver + +add_type1_driver: + $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/type1/rules.mk b/lib/freetype/src/type1/rules.mk new file mode 100644 index 0000000..49a4e4a --- /dev/null +++ b/lib/freetype/src/type1/rules.mk @@ -0,0 +1,73 @@ +# +# FreeType 2 Type1 driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# Type1 driver directory +# +T1_DIR := $(SRC_)type1 +T1_DIR_ := $(T1_DIR)$(SEP) + + +# compilation flags for the driver +# +T1_COMPILE := $(FT_COMPILE) $I$(T1_DIR) + + +# Type1 driver sources (i.e., C files) +# +T1_DRV_SRC := $(T1_DIR_)t1parse.c \ + $(T1_DIR_)t1load.c \ + $(T1_DIR_)t1driver.c \ + $(T1_DIR_)t1afm.c \ + $(T1_DIR_)t1gload.c \ + $(T1_DIR_)t1objs.c + +# Type1 driver headers +# +T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) \ + $(T1_DIR_)t1tokens.h \ + $(T1_DIR_)t1errors.h + + +# Type1 driver object(s) +# +# T1_DRV_OBJ_M is used during `multi' builds +# T1_DRV_OBJ_S is used during `single' builds +# +T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) +T1_DRV_OBJ_S := $(OBJ_)type1.$O + +# Type1 driver source file for single build +# +T1_DRV_SRC_S := $(T1_DIR_)type1.c + + +# Type1 driver - single object +# +$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) + $(T1_COMPILE) $T$@ $(T1_DRV_SRC_S) + + +# Type1 driver - multiple objects +# +$(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H) + $(T1_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(T1_DRV_OBJ_S) +DRV_OBJS_M += $(T1_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/type1/t1afm.c b/lib/freetype/src/type1/t1afm.c new file mode 100644 index 0000000..71ccd1e --- /dev/null +++ b/lib/freetype/src/type1/t1afm.c @@ -0,0 +1,282 @@ +/***************************************************************************/ +/* */ +/* t1afm.c */ +/* */ +/* AFM support for Type 1 fonts (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 "t1afm.h" +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_TYPE1_TYPES_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1afm + + + FT_LOCAL_DEF( void ) + T1_Done_AFM( FT_Memory memory, + T1_AFM* afm ) + { + FT_FREE( afm->kern_pairs ); + afm->num_pairs = 0; + FT_FREE( afm ); + } + + +#undef IS_KERN_PAIR +#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) + +#define IS_ALPHANUM( c ) ( ft_isalnum( c ) || \ + c == '_' || \ + c == '.' ) + + + /* read a glyph name and return the equivalent glyph index */ + static FT_UInt + afm_atoindex( FT_Byte** start, + FT_Byte* limit, + T1_Font type1 ) + { + FT_Byte* p = *start; + FT_PtrDist len; + FT_UInt result = 0; + char temp[64]; + + + /* skip whitespace */ + while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && + p < limit ) + p++; + *start = p; + + /* now, read glyph name */ + while ( IS_ALPHANUM( *p ) && p < limit ) + p++; + + len = p - *start; + + if ( len > 0 && len < 64 ) + { + FT_Int n; + + + /* copy glyph name to intermediate array */ + FT_MEM_COPY( temp, *start, len ); + temp[len] = 0; + + /* lookup glyph name in face array */ + for ( n = 0; n < type1->num_glyphs; n++ ) + { + char* gname = (char*)type1->glyph_names[n]; + + + if ( gname && gname[0] == temp[0] && ft_strcmp( gname, temp ) == 0 ) + { + result = n; + break; + } + } + } + *start = p; + return result; + } + + + /* read an integer */ + static int + afm_atoi( FT_Byte** start, + FT_Byte* limit ) + { + FT_Byte* p = *start; + int sum = 0; + int sign = 1; + + + /* skip everything that is not a number */ + while ( p < limit && !isdigit( *p ) ) + { + sign = 1; + if ( *p == '-' ) + sign = -1; + + p++; + } + + while ( p < limit && isdigit( *p ) ) + { + sum = sum * 10 + ( *p - '0' ); + p++; + } + *start = p; + + return sum * sign; + } + + +#undef KERN_INDEX +#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) + + + /* compare two kerning pairs */ + FT_CALLBACK_DEF( int ) + compare_kern_pairs( const void* a, + const void* b ) + { + T1_Kern_Pair* pair1 = (T1_Kern_Pair*)a; + T1_Kern_Pair* pair2 = (T1_Kern_Pair*)b; + + FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); + FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); + + + return ( index1 - index2 ); + } + + + /* parse an AFM file -- for now, only read the kerning pairs */ + FT_LOCAL_DEF( FT_Error ) + T1_Read_AFM( FT_Face t1_face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = stream->memory; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* p; + FT_Int count = 0; + T1_Kern_Pair* pair; + T1_Font type1 = &((T1_Face)t1_face)->type1; + T1_AFM* afm = 0; + + + if ( FT_FRAME_ENTER( stream->size ) ) + return error; + + start = (FT_Byte*)stream->cursor; + limit = (FT_Byte*)stream->limit; + p = start; + + /* we are now going to count the occurences of `KP' or `KPX' in */ + /* the AFM file */ + count = 0; + for ( p = start; p < limit - 3; p++ ) + { + if ( IS_KERN_PAIR( p ) ) + count++; + } + + /* Actually, kerning pairs are simply optional! */ + if ( count == 0 ) + goto Exit; + + /* allocate the pairs */ + if ( FT_NEW( afm ) || FT_NEW_ARRAY( afm->kern_pairs, count ) ) + goto Exit; + + /* now, read each kern pair */ + pair = afm->kern_pairs; + afm->num_pairs = count; + + /* save in face object */ + ((T1_Face)t1_face)->afm_data = afm; + + t1_face->face_flags |= FT_FACE_FLAG_KERNING; + + for ( p = start; p < limit - 3; p++ ) + { + if ( IS_KERN_PAIR( p ) ) + { + FT_Byte* q; + + + /* skip keyword (KP or KPX) */ + q = p + 2; + if ( *q == 'X' ) + q++; + + pair->glyph1 = afm_atoindex( &q, limit, type1 ); + pair->glyph2 = afm_atoindex( &q, limit, type1 ); + pair->kerning.x = afm_atoi( &q, limit ); + + pair->kerning.y = 0; + if ( p[2] != 'X' ) + pair->kerning.y = afm_atoi( &q, limit ); + + pair++; + } + } + + /* now, sort the kern pairs according to their glyph indices */ + ft_qsort( afm->kern_pairs, count, sizeof ( T1_Kern_Pair ), + compare_kern_pairs ); + + Exit: + if ( error ) + FT_FREE( afm ); + + FT_FRAME_EXIT(); + + return error; + } + + + /* find the kerning for a given glyph pair */ + FT_LOCAL_DEF( void ) + T1_Get_Kerning( T1_AFM* afm, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ) + { + T1_Kern_Pair *min, *mid, *max; + FT_ULong idx = KERN_INDEX( glyph1, glyph2 ); + + + /* simple binary search */ + min = afm->kern_pairs; + max = min + afm->num_pairs - 1; + + while ( min <= max ) + { + FT_ULong midi; + + + mid = min + ( max - min ) / 2; + midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); + + if ( midi == idx ) + { + *kerning = mid->kerning; + return; + } + + if ( midi < idx ) + min = mid + 1; + else + max = mid - 1; + } + + kerning->x = 0; + kerning->y = 0; + } + + +/* END */ diff --git a/lib/freetype/src/type1/t1afm.h b/lib/freetype/src/type1/t1afm.h new file mode 100644 index 0000000..77cc6a6 --- /dev/null +++ b/lib/freetype/src/type1/t1afm.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* t1afm.h */ +/* */ +/* AFM support for Type 1 fonts (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1AFM_H__ +#define __T1AFM_H__ + +#include +#include "t1objs.h" + + +FT_BEGIN_HEADER + + + typedef struct T1_Kern_Pair_ + { + FT_UInt glyph1; + FT_UInt glyph2; + FT_Vector kerning; + + } T1_Kern_Pair; + + + typedef struct T1_AFM_ + { + FT_Int num_pairs; + T1_Kern_Pair* kern_pairs; + + } T1_AFM; + + + FT_LOCAL( FT_Error ) + T1_Read_AFM( FT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + T1_Done_AFM( FT_Memory memory, + T1_AFM* afm ); + + FT_LOCAL( void ) + T1_Get_Kerning( T1_AFM* afm, + FT_UInt glyph1, + FT_UInt glyph2, + FT_Vector* kerning ); + + +FT_END_HEADER + +#endif /* __T1AFM_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1driver.c b/lib/freetype/src/type1/t1driver.c new file mode 100644 index 0000000..b255f9d --- /dev/null +++ b/lib/freetype/src/type1/t1driver.c @@ -0,0 +1,279 @@ +/***************************************************************************/ +/* */ +/* t1driver.c */ +/* */ +/* Type 1 driver interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 "t1driver.h" +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1driver + + + static FT_Error + t1_get_glyph_name( T1_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_String* gname; + + + gname = face->type1.glyph_names[glyph_index]; + + if ( buffer_max > 0 ) + { + FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); + + + if (len >= buffer_max) + len = buffer_max - 1; + + FT_MEM_COPY( buffer, gname, len ); + ((FT_Byte*)buffer)[len] = 0; + } + + return T1_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* t1_get_name_index */ + /* */ + /* */ + /* Uses the Type 1 font's `glyph_names' table to find a given glyph */ + /* name's glyph index. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* */ + /* Glyph index. 0 means `undefined character code'. */ + /* */ + static FT_UInt + t1_get_name_index( T1_Face face, + FT_String* glyph_name ) + { + FT_Int i; + FT_String* gname; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + gname = face->type1.glyph_names[i]; + + if ( !ft_strcmp( glyph_name, gname ) ) + return (FT_UInt)i; + } + + return 0; + } + + + static const char* + t1_get_ps_name( T1_Face face ) + { + return (const char*) face->type1.font_name; + } + + + /*************************************************************************/ + /* */ + /* */ + /* Get_Interface */ + /* */ + /* */ + /* Each driver can provide one or more extensions to the base */ + /* FreeType API. These can be used to access format specific */ + /* features (e.g., all TrueType/OpenType resources share a common */ + /* file structure and common tables which can be accessed through the */ + /* `sfnt' interface), or more simply generic ones (e.g., the */ + /* `postscript names' interface which can be used to retrieve the */ + /* PostScript name of a given glyph index). */ + /* */ + /* */ + /* driver :: A handle to a driver object. */ + /* */ + /* */ + /* t1_interface :: A string designing the interface. Examples are */ + /* `sfnt', `post_names', `charmaps', etc. */ + /* */ + /* */ + /* A typeless pointer to the extension's interface (normally a table */ + /* of function pointers). Returns NULL if the requested extension */ + /* isn't available (i.e., wasn't compiled in the driver at build */ + /* time). */ + /* */ + static FT_Module_Interface + Get_Interface( FT_Driver driver, + const FT_String* t1_interface ) + { + FT_UNUSED( driver ); + FT_UNUSED( t1_interface ); + + if ( ft_strcmp( (const char*)t1_interface, "glyph_name" ) == 0 ) + return (FT_Module_Interface)t1_get_glyph_name; + + if ( ft_strcmp( (const char*)t1_interface, "name_index" ) == 0 ) + return (FT_Module_Interface)t1_get_name_index; + + if ( ft_strcmp( (const char*)t1_interface, "postscript_name" ) == 0 ) + return (FT_Module_Interface)t1_get_ps_name; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + if ( ft_strcmp( (const char*)t1_interface, "get_mm" ) == 0 ) + return (FT_Module_Interface)T1_Get_Multi_Master; + + if ( ft_strcmp( (const char*)t1_interface, "set_mm_design") == 0 ) + return (FT_Module_Interface)T1_Set_MM_Design; + + if ( ft_strcmp( (const char*)t1_interface, "set_mm_blend") == 0 ) + return (FT_Module_Interface)T1_Set_MM_Blend; +#endif + return 0; + } + + +#ifndef T1_CONFIG_OPTION_NO_AFM + + /*************************************************************************/ + /* */ + /* */ + /* Get_Kerning */ + /* */ + /* */ + /* A driver method used to return the kerning vector between two */ + /* glyphs of the same face. */ + /* */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* */ + /* kerning :: The kerning vector. This is in font units for */ + /* scalable formats, and in pixels for fixed-sizes */ + /* formats. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this function. Other layouts, or more sophisticated */ + /* kernings are out of scope of this method (the basic driver */ + /* interface is meant to be simple). */ + /* */ + /* They can be implemented by format-specific interfaces. */ + /* */ + static FT_Error + Get_Kerning( T1_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ) + { + T1_AFM* afm; + + + kerning->x = 0; + kerning->y = 0; + + afm = (T1_AFM*)face->afm_data; + if ( afm ) + T1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); + + return T1_Err_Ok; + } + + +#endif /* T1_CONFIG_OPTION_NO_AFM */ + + + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec t1_driver_class = + { + { + ft_module_font_driver | + ft_module_driver_scalable | + ft_module_driver_has_hinter, + + sizeof( FT_DriverRec ), + + "type1", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + (FT_Module_Constructor)T1_Driver_Init, + (FT_Module_Destructor) T1_Driver_Done, + (FT_Module_Requester) Get_Interface, + }, + + sizeof( T1_FaceRec ), + sizeof( T1_SizeRec ), + sizeof( T1_GlyphSlotRec ), + + (FT_Face_InitFunc) T1_Face_Init, + (FT_Face_DoneFunc) T1_Face_Done, + (FT_Size_InitFunc) T1_Size_Init, + (FT_Size_DoneFunc) T1_Size_Done, + (FT_Slot_InitFunc) T1_GlyphSlot_Init, + (FT_Slot_DoneFunc) T1_GlyphSlot_Done, + + (FT_Size_ResetPointsFunc) T1_Size_Reset, + (FT_Size_ResetPixelsFunc) T1_Size_Reset, + (FT_Slot_LoadFunc) T1_Load_Glyph, + +#ifdef T1_CONFIG_OPTION_NO_AFM + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, +#else + (FT_Face_GetKerningFunc) Get_Kerning, + (FT_Face_AttachFunc) T1_Read_AFM, +#endif + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/type1/t1driver.h b/lib/freetype/src/type1/t1driver.h new file mode 100644 index 0000000..ad42944 --- /dev/null +++ b/lib/freetype/src/type1/t1driver.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* t1driver.h */ +/* */ +/* High-level Type 1 driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1DRIVER_H__ +#define __T1DRIVER_H__ + + +#include +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t1_driver_class; + + +FT_END_HEADER + +#endif /* __T1DRIVER_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1errors.h b/lib/freetype/src/type1/t1errors.h new file mode 100644 index 0000000..81221c3 --- /dev/null +++ b/lib/freetype/src/type1/t1errors.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* t1errors.h */ +/* */ +/* Type 1 error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the Type 1 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T1ERRORS_H__ +#define __T1ERRORS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX T1_Err_ +#define FT_ERR_BASE FT_Mod_Err_Type1 + +#include FT_ERRORS_H + +#endif /* __T1ERRORS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1gload.c b/lib/freetype/src/type1/t1gload.c new file mode 100644 index 0000000..6ebb872 --- /dev/null +++ b/lib/freetype/src/type1/t1gload.c @@ -0,0 +1,414 @@ +/***************************************************************************/ +/* */ +/* t1gload.c */ +/* */ +/* Type 1 Glyph Loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 "t1gload.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_OUTLINE_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1errors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1gload + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, + FT_UInt glyph_index, + FT_Data* char_string ) + { + T1_Face face = (T1_Face)decoder->builder.face; + T1_Font type1 = &face->type1; + FT_Error error = 0; + + + decoder->font_matrix = type1->font_matrix; + decoder->font_offset = type1->font_offset; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, char_string ); + else + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + /* For ordinary fonts get the character data stored in the face record. */ + { + char_string->pointer = type1->charstrings[glyph_index]; + char_string->length = type1->charstrings_len[glyph_index]; + } + + if ( !error ) + error = decoder->funcs.parse_charstrings( + decoder, (FT_Byte*)char_string->pointer, + char_string->length ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + + /* Incremental fonts can optionally override the metrics. */ + if ( !error && face->root.internal->incremental_interface && + face->root.internal->incremental_interface->funcs->get_glyph_metrics ) + { + FT_Incremental_MetricsRec metrics; + + metrics.bearing_x = decoder->builder.left_bearing.x; + metrics.bearing_y = decoder->builder.left_bearing.y; + metrics.advance = decoder->builder.advance.x; + error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( + face->root.internal->incremental_interface->object, + glyph_index, FALSE, &metrics ); + decoder->builder.left_bearing.x = metrics.bearing_x; + decoder->builder.left_bearing.y = metrics.bearing_y; + decoder->builder.advance.x = metrics.advance; + decoder->builder.advance.y = 0; + } + +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_CALLBACK_DEF( FT_Error ) + T1_Parse_Glyph( T1_Decoder decoder, + FT_UInt glyph_index ) + { + FT_Data glyph_data; + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + decoder, glyph_index, &glyph_data ); + + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !error ) + { + T1_Face face = (T1_Face)decoder->builder.face; + + + if ( face->root.internal->incremental_interface ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + } +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Int* max_advance ) + { + FT_Error error; + T1_DecoderRec decoder; + FT_Int glyph_index; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + *max_advance = 0; + + /* initialize load decoder */ + error = psaux->t1_decoder_funcs->init( &decoder, + (FT_Face)face, + 0, /* size */ + 0, /* glyph slot */ + (FT_Byte**)type1->glyph_names, + face->blend, + 0, + FT_RENDER_MODE_NORMAL, + T1_Parse_Glyph ); + if ( error ) + return error; + + decoder.builder.metrics_only = 1; + decoder.builder.load_points = 0; + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + *max_advance = 0; + + /* for each glyph, parse the glyph charstring and extract */ + /* the advance width */ + for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) + { + /* now get load the unscaled outline */ + error = T1_Parse_Glyph( &decoder, glyph_index ); + if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance ) + *max_advance = decoder.builder.advance.x; + + /* ignore the error if one occured - skip to next glyph */ + } + + return T1_Err_Ok; + } + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** UNHINTED GLYPH LOADER *********/ + /********** *********/ + /********** The following code is in charge of loading a *********/ + /********** single outline. It completely ignores hinting *********/ + /********** and is used when FT_LOAD_NO_HINTING is set. *********/ + /********** *********/ + /********** The Type 1 hinter is located in `t1hint.c' *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_LOCAL_DEF( FT_Error ) + T1_Load_Glyph( T1_GlyphSlot glyph, + T1_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T1_DecoderRec decoder; + T1_Face face = (T1_Face)glyph->root.face; + FT_Bool hinting; + T1_Font type1 = &face->type1; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; + + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_Data glyph_data; + FT_Bool glyph_data_loaded = 0; + + + if ( load_flags & FT_LOAD_NO_RECURSE ) + load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; + + glyph->x_scale = size->root.metrics.x_scale; + glyph->y_scale = size->root.metrics.y_scale; + + glyph->root.outline.n_points = 0; + glyph->root.outline.n_contours = 0; + + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && + ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + error = decoder_funcs->init( &decoder, + (FT_Face)face, + (FT_Size)size, + (FT_GlyphSlot)glyph, + (FT_Byte**)type1->glyph_names, + face->blend, + FT_BOOL( hinting ), + FT_LOAD_TARGET_MODE(load_flags), + T1_Parse_Glyph ); + if ( error ) + goto Exit; + + decoder.builder.no_recurse = FT_BOOL( + ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); + + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + + /* now load the unscaled outline */ + error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, + &glyph_data ); + if ( error ) + goto Exit; + glyph_data_loaded = 1; + + font_matrix = decoder.font_matrix; + font_offset = decoder.font_offset; + + /* save new glyph tables */ + decoder_funcs->done( &decoder ); + + /* now, set the metrics -- this is rather simple, as */ + /* the left side bearing is the xMin, and the top side */ + /* bearing the yMax */ + if ( !error ) + { + glyph->root.outline.flags &= FT_OUTLINE_OWNER; + glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL; + + /* for composite glyphs, return only left side bearing and */ + /* advance width */ + if ( load_flags & FT_LOAD_NO_RECURSE ) + { + FT_Slot_Internal internal = glyph->root.internal; + + + glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; + glyph->root.metrics.horiAdvance = decoder.builder.advance.x; + internal->glyph_matrix = font_matrix; + internal->glyph_delta = font_offset; + internal->glyph_transformed = 1; + } + else + { + FT_BBox cbox; + FT_Glyph_Metrics* metrics = &glyph->root.metrics; + + + /* copy the _unscaled_ advance width */ + metrics->horiAdvance = decoder.builder.advance.x; + glyph->root.linearHoriAdvance = decoder.builder.advance.x; + glyph->root.internal->glyph_transformed = 0; + + /* make up vertical metrics */ + metrics->vertBearingX = 0; + metrics->vertBearingY = 0; + metrics->vertAdvance = 0; + + glyph->root.linearVertAdvance = 0; + + glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; + + if ( size && size->root.metrics.y_ppem < 24 ) + glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION; + +#if 1 + /* apply the font matrix, if any */ + FT_Outline_Transform( &glyph->root.outline, &font_matrix ); + + FT_Outline_Translate( &glyph->root.outline, + font_offset.x, + font_offset.y ); +#endif + + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + { + /* scale the outline and the metrics */ + FT_Int n; + FT_Outline* cur = decoder.builder.base; + FT_Vector* vec = cur->points; + FT_Fixed x_scale = glyph->x_scale; + FT_Fixed y_scale = glyph->y_scale; + + + /* First of all, scale the points, if we are not hinting */ + if ( !hinting ) + for ( n = cur->n_points; n > 0; n--, vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } + + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* Then scale the metrics */ + metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); + metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); + + metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); + metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); + + if ( hinting ) + { + metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64; + metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64; + + metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64; + metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64; + } + } + + /* compute the other metrics */ + FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); + + /* grid fit the bounding box if necessary */ + if ( hinting ) + { + cbox.xMin &= -64; + cbox.yMin &= -64; + cbox.xMax = ( cbox.xMax+63 ) & -64; + cbox.yMax = ( cbox.yMax+63 ) & -64; + } + + metrics->width = cbox.xMax - cbox.xMin; + metrics->height = cbox.yMax - cbox.yMin; + + metrics->horiBearingX = cbox.xMin; + metrics->horiBearingY = cbox.yMax; + } + + /* Set control data to the glyph charstrings. Note that this is */ + /* _not_ zero-terminated. */ + glyph->root.control_data = (FT_Byte*)glyph_data.pointer; + glyph->root.control_len = glyph_data.length; + } + + + Exit: + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( glyph_data_loaded && face->root.internal->incremental_interface ) + { + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &glyph_data ); + + /* Set the control data to null - it is no longer available if */ + /* loaded incrementally. */ + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } +#endif + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/type1/t1gload.h b/lib/freetype/src/type1/t1gload.h new file mode 100644 index 0000000..0324a0d --- /dev/null +++ b/lib/freetype/src/type1/t1gload.h @@ -0,0 +1,46 @@ +/***************************************************************************/ +/* */ +/* t1gload.h */ +/* */ +/* Type 1 Glyph Loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1GLOAD_H__ +#define __T1GLOAD_H__ + + +#include +#include "t1objs.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + T1_Compute_Max_Advance( T1_Face face, + FT_Int* max_advance ); + + FT_LOCAL( FT_Error ) + T1_Load_Glyph( T1_GlyphSlot glyph, + T1_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + +FT_END_HEADER + +#endif /* __T1GLOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1load.c b/lib/freetype/src/type1/t1load.c new file mode 100644 index 0000000..5873ae0 --- /dev/null +++ b/lib/freetype/src/type1/t1load.c @@ -0,0 +1,1807 @@ +/***************************************************************************/ +/* */ +/* t1load.c */ +/* */ +/* Type 1 font loader (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 the new and improved Type 1 data loader for FreeType 2. The */ + /* old loader has several problems: it is slow, complex, difficult to */ + /* maintain, and contains incredible hacks to make it accept some */ + /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ + /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ + /* */ + /* This version is much simpler, much faster and also easier to read and */ + /* maintain by a great order of magnitude. The idea behind it is to */ + /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ + /* a Postscript-like interpreter) but rather to perform simple pattern */ + /* matching. */ + /* */ + /* Indeed, nearly all data definitions follow a simple pattern like */ + /* */ + /* ... /Field ... */ + /* */ + /* where can be a number, a boolean, a string, or an array of */ + /* numbers. There are a few exceptions, namely the encoding, font name, */ + /* charstrings, and subrs; they are handled with a special pattern */ + /* matching routine. */ + /* */ + /* All other common cases are handled very simply. The matching rules */ + /* are defined in the file `t1tokens.h' through the use of several */ + /* macros calls PARSE_XXX. */ + /* */ + /* This file is included twice here; the first time to generate parsing */ + /* callback functions, the second to generate a table of keywords (with */ + /* pointers to the associated callback). */ + /* */ + /* The function `parse_dict' simply scans *linearly* a given dictionary */ + /* (either the top-level or private one) and calls the appropriate */ + /* callback when it encounters an immediate keyword. */ + /* */ + /* This is by far the fastest way one can find to parse and read all */ + /* data. */ + /* */ + /* This led to tremendous code size reduction. Note that later, the */ + /* glyph loader will also be _greatly_ simplified, and the automatic */ + /* hinter will replace the clumsy `t1hinter'. */ + /* */ + /*************************************************************************/ + + +#include +#include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H +#include FT_MULTIPLE_MASTERS_H +#include FT_INTERNAL_TYPE1_TYPES_H + +#include "t1load.h" +#include "t1errors.h" + + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1load + + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MULTIPLE MASTERS SUPPORT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static FT_Error + t1_allocate_blend( T1_Face face, + FT_UInt num_designs, + FT_UInt num_axis ) + { + PS_Blend blend; + FT_Memory memory = face->root.memory; + FT_Error error = 0; + + + blend = face->blend; + if ( !blend ) + { + if ( FT_NEW( blend ) ) + goto Exit; + + face->blend = blend; + } + + /* allocate design data if needed */ + if ( num_designs > 0 ) + { + if ( blend->num_designs == 0 ) + { + FT_UInt nn; + + + /* allocate the blend `private' and `font_info' dictionaries */ + if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) || + FT_NEW_ARRAY( blend->privates[1], num_designs ) || + FT_NEW_ARRAY( blend->bboxes[1], num_designs ) || + FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) ) + goto Exit; + + blend->default_weight_vector = blend->weight_vector + num_designs; + + blend->font_infos[0] = &face->type1.font_info; + blend->privates [0] = &face->type1.private_dict; + blend->bboxes [0] = &face->type1.font_bbox; + + for ( nn = 2; nn <= num_designs; nn++ ) + { + blend->privates[nn] = blend->privates [nn - 1] + 1; + blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; + blend->bboxes[nn] = blend->bboxes [nn - 1] + 1; + } + + blend->num_designs = num_designs; + } + else if ( blend->num_designs != num_designs ) + goto Fail; + } + + /* allocate axis data if needed */ + if ( num_axis > 0 ) + { + if ( blend->num_axis != 0 && blend->num_axis != num_axis ) + goto Fail; + + blend->num_axis = num_axis; + } + + /* allocate the blend design pos table if needed */ + num_designs = blend->num_designs; + num_axis = blend->num_axis; + if ( num_designs && num_axis && blend->design_pos[0] == 0 ) + { + FT_UInt n; + + + if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) ) + goto Exit; + + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = blend->design_pos[0] + num_axis * n; + } + + Exit: + return error; + + Fail: + error = -1; + goto Exit; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ) + { + PS_Blend blend = face->blend; + FT_UInt n; + FT_Error error; + + + error = T1_Err_Invalid_Argument; + + if ( blend ) + { + master->num_axis = blend->num_axis; + master->num_designs = blend->num_designs; + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_MM_Axis* axis = master->axis + n; + PS_DesignMap map = blend->design_map + n; + + + axis->name = blend->axis_names[n]; + axis->minimum = map->design_points[0]; + axis->maximum = map->design_points[map->num_points - 1]; + } + error = 0; + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, m; + + + error = T1_Err_Invalid_Argument; + + if ( blend && blend->num_axis == num_coords ) + { + /* recompute the weight vector from the blend coordinates */ + error = T1_Err_Ok; + + for ( n = 0; n < blend->num_designs; n++ ) + { + FT_Fixed result = 0x10000L; /* 1.0 fixed */ + + + for ( m = 0; m < blend->num_axis; m++ ) + { + FT_Fixed factor; + + + /* get current blend axis position */ + factor = coords[m]; + if ( factor < 0 ) factor = 0; + if ( factor > 0x10000L ) factor = 0x10000L; + + if ( ( n & ( 1 << m ) ) == 0 ) + factor = 0x10000L - factor; + + result = FT_MulFix( result, factor ); + } + blend->weight_vector[n] = result; + } + + error = T1_Err_Ok; + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ) + { + PS_Blend blend = face->blend; + FT_Error error; + FT_UInt n, p; + + + error = T1_Err_Invalid_Argument; + if ( blend && blend->num_axis == num_coords ) + { + /* compute the blend coordinates through the blend design map */ + FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; + + + for ( n = 0; n < blend->num_axis; n++ ) + { + FT_Long design = coords[n]; + FT_Fixed the_blend; + PS_DesignMap map = blend->design_map + n; + FT_Fixed* designs = map->design_points; + FT_Fixed* blends = map->blend_points; + FT_Int before = -1, after = -1; + + + for ( p = 0; p < (FT_UInt)map->num_points; p++ ) + { + FT_Fixed p_design = designs[p]; + + + /* exact match ? */ + if ( design == p_design ) + { + the_blend = blends[p]; + goto Found; + } + + if ( design < p_design ) + { + after = p; + break; + } + + before = p; + } + + /* now, interpolate if needed */ + if ( before < 0 ) + the_blend = blends[0]; + + else if ( after < 0 ) + the_blend = blends[map->num_points - 1]; + + else + the_blend = FT_MulDiv( design - designs[before], + blends [after] - blends [before], + designs[after] - designs[before] ); + + Found: + final_blends[n] = the_blend; + } + + error = T1_Set_MM_Blend( face, num_coords, final_blends ); + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Done_Blend( T1_Face face ) + { + FT_Memory memory = face->root.memory; + PS_Blend blend = face->blend; + + + if ( blend ) + { + FT_UInt num_designs = blend->num_designs; + FT_UInt num_axis = blend->num_axis; + FT_UInt n; + + + /* release design pos table */ + FT_FREE( blend->design_pos[0] ); + for ( n = 1; n < num_designs; n++ ) + blend->design_pos[n] = 0; + + /* release blend `private' and `font info' dictionaries */ + FT_FREE( blend->privates[1] ); + FT_FREE( blend->font_infos[1] ); + FT_FREE( blend->bboxes[1] ); + + for ( n = 0; n < num_designs; n++ ) + { + blend->privates [n] = 0; + blend->font_infos[n] = 0; + blend->bboxes [n] = 0; + } + + /* release weight vectors */ + FT_FREE( blend->weight_vector ); + blend->default_weight_vector = 0; + + /* release axis names */ + for ( n = 0; n < num_axis; n++ ) + FT_FREE( blend->axis_names[n] ); + + /* release design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap dmap = blend->design_map + n; + + + FT_FREE( dmap->design_points ); + dmap->num_points = 0; + } + + FT_FREE( face->blend ); + } + } + + + static void + parse_blend_axis_types( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec axis_tokens[ T1_MAX_MM_AXIS ]; + FT_Int n, num_axis; + FT_Error error = 0; + PS_Blend blend; + FT_Memory memory; + + + /* take an array of objects */ + T1_ToTokenArray( &loader->parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", + num_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* allocate blend if necessary */ + error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); + if ( error ) + goto Exit; + + blend = face->blend; + memory = face->root.memory; + + /* each token is an immediate containing the name of the axis */ + for ( n = 0; n < num_axis; n++ ) + { + T1_Token token = axis_tokens + n; + FT_Byte* name; + FT_PtrDist len; + + + /* skip first slash, if any */ + if ( token->start[0] == '/' ) + token->start++; + + len = token->limit - token->start; + if ( len <= 0 ) + { + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + if ( FT_ALLOC( blend->axis_names[n], len + 1 ) ) + goto Exit; + + name = (FT_Byte*)blend->axis_names[n]; + FT_MEM_COPY( name, token->start, len ); + name[len] = 0; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_positions( T1_Face face, + T1_Loader loader ) + { + T1_TokenRec design_tokens[ T1_MAX_MM_DESIGNS ]; + FT_Int num_designs; + FT_Int num_axis; + T1_Parser parser = &loader->parser; + + FT_Error error = 0; + PS_Blend blend; + + + /* get the array of design tokens - compute number of designs */ + T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_blend_design_positions:" )); + FT_ERROR(( " incorrect number of designs: %d\n", + num_designs )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + { + FT_Byte* old_cursor = parser->root.cursor; + FT_Byte* old_limit = parser->root.limit; + FT_UInt n; + + + blend = face->blend; + num_axis = 0; /* make compiler happy */ + + for ( n = 0; n < (FT_UInt)num_designs; n++ ) + { + T1_TokenRec axis_tokens[ T1_MAX_MM_DESIGNS ]; + T1_Token token; + FT_Int axis, n_axis; + + + /* read axis/coordinates tokens */ + token = design_tokens + n; + parser->root.cursor = token->start - 1; + parser->root.limit = token->limit + 1; + T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); + + if ( n == 0 ) + { + num_axis = n_axis; + error = t1_allocate_blend( face, num_designs, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( n_axis != num_axis ) + { + FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* now, read each axis token into the design position */ + for ( axis = 0; axis < n_axis; axis++ ) + { + T1_Token token2 = axis_tokens + axis; + + + parser->root.cursor = token2->start; + parser->root.limit = token2->limit; + blend->design_pos[n][axis] = T1_ToFixed( parser, 0 ); + } + } + + loader->parser.root.cursor = old_cursor; + loader->parser.root.limit = old_limit; + } + + Exit: + loader->parser.root.error = error; + } + + + static void + parse_blend_design_map( T1_Face face, + T1_Loader loader ) + { + FT_Error error = 0; + T1_Parser parser = &loader->parser; + PS_Blend blend; + T1_TokenRec axis_tokens[T1_MAX_MM_AXIS]; + FT_Int n, num_axis; + FT_Byte* old_cursor; + FT_Byte* old_limit; + FT_Memory memory = face->root.memory; + + + T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", + num_axis )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + error = t1_allocate_blend( face, 0, num_axis ); + if ( error ) + goto Exit; + blend = face->blend; + + /* now, read each axis design map */ + for ( n = 0; n < num_axis; n++ ) + { + PS_DesignMap map = blend->design_map + n; + T1_Token token; + FT_Int p, num_points; + + + token = axis_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + + /* count the number of map points */ + { + FT_Byte* ptr = token->start; + FT_Byte* limit = token->limit; + + + num_points = 0; + for ( ; ptr < limit; ptr++ ) + if ( ptr[0] == '[' ) + num_points++; + } + if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) + { + FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + /* allocate design map data */ + if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) ) + goto Exit; + map->blend_points = map->design_points + num_points; + map->num_points = (FT_Byte)num_points; + + for ( p = 0; p < num_points; p++ ) + { + map->design_points[p] = T1_ToInt( parser ); + map->blend_points [p] = T1_ToFixed( parser, 0 ); + } + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + static void + parse_weight_vector( T1_Face face, + T1_Loader loader ) + { + FT_Error error = 0; + T1_Parser parser = &loader->parser; + PS_Blend blend = face->blend; + T1_TokenRec master; + FT_UInt n; + FT_Byte* old_cursor; + FT_Byte* old_limit; + + + if ( !blend || blend->num_designs == 0 ) + { + FT_ERROR(( "parse_weight_vector: too early!\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + T1_ToToken( parser, &master ); + if ( master.type != T1_TOKEN_TYPE_ARRAY ) + { + FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + + old_cursor = parser->root.cursor; + old_limit = parser->root.limit; + + parser->root.cursor = master.start; + parser->root.limit = master.limit; + + for ( n = 0; n < blend->num_designs; n++ ) + { + blend->default_weight_vector[n] = + blend->weight_vector[n] = T1_ToFixed( parser, 0 ); + } + + parser->root.cursor = old_cursor; + parser->root.limit = old_limit; + + Exit: + parser->root.error = error; + } + + + /* the keyword `/shareddict' appears in some multiple master fonts */ + /* with a lot of Postscript garbage behind it (that's completely out */ + /* of spec!); we detect it and terminate the parsing */ + /* */ + static void + parse_shared_dict( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + + FT_UNUSED( face ); + + + parser->root.cursor = parser->root.limit; + parser->root.error = 0; + } + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE 1 SYMBOL PARSING *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* First of all, define the token field static variables. This is a set */ + /* of T1_FieldRec variables used later. */ + /* */ + /*************************************************************************/ + + + static FT_Error + t1_load_keyword( T1_Face face, + T1_Loader loader, + T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects; + PS_Blend blend = face->blend; + + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) + { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now, the keyword is either a simple field, or a table of fields; */ + /* we are now going to take care of it */ + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->font_infos; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_PRIVATE: + dummy_object = &face->type1.private_dict; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->privates; + max_objects = blend->num_designs; + } + break; + + case T1_FIELD_LOCATION_BBOX: + dummy_object = &face->type1.font_bbox; + objects = &dummy_object; + max_objects = 0; + + if ( blend ) + { + objects = (void**)blend->bboxes; + max_objects = blend->num_designs; + } + break; + + default: + dummy_object = &face->type1; + objects = &dummy_object; + max_objects = 0; + } + + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + + Exit: + return error; + } + + + static int + is_space( FT_Byte c ) + { + return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); + } + + + static int + is_name_char( FT_Byte c ) + { + /* Note: PostScript allows any non-delimiting, non-whitespace */ + /* in a name (PS Ref Manual, 3rd Ed, p31) */ + /* PostScript delimiters include (,),<,>,[,],{,},/ and % */ + + return ( c != '(' && + c != ')' && + c != '<' && + c != '>' && + c != '[' && + c != ']' && + c != '{' && + c != '}' && + c != '/' && + c != '%' && + ! is_space( c ) + ); + } + + + static int + read_binary_data( T1_Parser parser, + FT_Long* size, + FT_Byte** base ) + { + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + + + /* the binary data has the following format */ + /* */ + /* `size' [white*] RD white ....... ND */ + /* */ + + T1_Skip_Spaces( parser ); + cur = parser->root.cursor; + + if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 ) + { + *size = T1_ToInt( parser ); + + T1_Skip_Spaces( parser ); + T1_Skip_Alpha ( parser ); /* `RD' or `-|' or something else */ + + /* there is only one whitespace char after the */ + /* `RD' or `-|' token */ + *base = parser->root.cursor + 1; + + parser->root.cursor += *size + 1; + return 1; + } + + FT_ERROR(( "read_binary_data: invalid size field\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return 0; + } + + + /* we will now define the routines used to handle */ + /* the `/Encoding', `/Subrs', and `/CharStrings' */ + /* dictionaries */ + + static void + parse_font_name( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Error error; + FT_Memory memory = parser->root.memory; + FT_PtrDist len; + FT_Byte* cur; + FT_Byte* cur2; + FT_Byte* limit; + + + if ( face->type1.font_name ) + /* with synthetic fonts, it's possible we get here twice */ + return; + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + limit = parser->root.limit; + + if ( cur >= limit - 1 || *cur != '/' ) + return; + + cur++; + cur2 = cur; + while ( cur2 < limit && is_name_char( *cur2 ) ) + cur2++; + + len = cur2 - cur; + if ( len > 0 ) + { + if ( FT_ALLOC( face->type1.font_name, len + 1 ) ) + { + parser->root.error = error; + return; + } + + FT_MEM_COPY( face->type1.font_name, cur, len ); + face->type1.font_name[len] = '\0'; + } + parser->root.cursor = cur2; + } + + +#if 0 + static void + parse_font_bbox( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Fixed temp[4]; + FT_BBox* bbox = &face->type1.font_bbox; + + + (void)T1_ToFixedArray( parser, 4, temp, 0 ); + bbox->xMin = FT_RoundFix( temp[0] ); + bbox->yMin = FT_RoundFix( temp[1] ); + bbox->xMax = FT_RoundFix( temp[2] ); + bbox->yMax = FT_RoundFix( temp[3] ); + } +#endif + + + static void + parse_font_matrix( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + if ( matrix->xx || matrix->yx ) + /* with synthetic fonts, it's possible we get here twice */ + return; + + (void)T1_ToFixedArray( parser, 6, temp, 3 ); + + temp_scale = ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, + temp_scale ) >> 16 ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) + { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + parse_encoding( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + FT_Byte* cur = parser->root.cursor; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + /* skip whitespace */ + while ( is_space( *cur ) ) + { + cur++; + if ( cur >= limit ) + { + FT_ERROR(( "parse_encoding: out of bounds!\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + return; + } + } + + /* if we have a number, then the encoding is an array, */ + /* and we must load it now */ + if ( (FT_Byte)( *cur - '0' ) < 10 ) + { + T1_Encoding encode = &face->type1.encoding; + FT_Int count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + + if ( encode->char_index ) + /* with synthetic fonts, it's possible we get here twice */ + return; + + /* read the number of entries in the encoding, should be 256 */ + count = (FT_Int)T1_ToInt( parser ); + if ( parser->root.error ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now, we will need to read a record of the form */ + /* ... charcode /charname ... for each entry in our table */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type1 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* We stop when we encounter a `def'. */ + + cur = parser->root.cursor; + limit = parser->root.limit; + n = 0; + + for ( ; cur < limit; ) + { + FT_Byte c; + + + c = *cur; + + /* we stop when we encounter a `def' */ + if ( c == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + is_space( cur[-1] ) && + is_space( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + break; + } + } + + /* otherwise, we must find a number before anything else */ + if ( (FT_Byte)( c - '0' ) < 10 ) + { + FT_Int charcode; + + + parser->root.cursor = cur; + charcode = (FT_Int)T1_ToInt( parser ); + cur = parser->root.cursor; + + /* skip whitespace */ + while ( cur < limit && is_space( *cur ) ) + cur++; + + if ( cur < limit && *cur == '/' ) + { + /* bingo, we have an immediate name -- it must be a */ + /* character name */ + FT_Byte* cur2 = cur + 1; + FT_PtrDist len; + + + while ( cur2 < limit && is_name_char( *cur2 ) ) + cur2++; + + len = cur2 - cur - 1; + + parser->root.error = T1_Add_Table( char_table, charcode, + cur + 1, len + 1 ); + char_table->elements[charcode][len] = '\0'; + if ( parser->root.error ) + return; + + cur = cur2; + } + } + else + cur++; + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else + { + FT_ERROR(( "parse_encoding: invalid token!\n" )); + parser->root.error = T1_Err_Invalid_File_Format; + } + } + } + + + static void + parse_subrs( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table table = &loader->subrs; + FT_Memory memory = parser->root.memory; + FT_Error error; + FT_Int n; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + if ( loader->num_subrs ) + /* with synthetic fonts, it's possible we get here twice */ + return; + + if ( parser->root.cursor + 2 > parser->root.limit && + parser->root.cursor[0] == '[' && + parser->root.cursor[1] == ']' ) + { + /* empty array */ + return; + } + + loader->num_subrs = (FT_Int)T1_ToInt( parser ); + if ( parser->root.error ) + return; + + /* position the parser right before the `dup' of the first subr */ + T1_Skip_Spaces( parser ); + T1_Skip_Alpha( parser ); /* `array' */ + T1_Skip_Spaces( parser ); + + /* initialize subrs array */ + error = psaux->ps_table_funcs->init( table, loader->num_subrs, memory ); + if ( error ) + goto Fail; + + /* the format is simple: */ + /* */ + /* `index' + binary data */ + /* */ + for ( n = 0; n < loader->num_subrs; n++ ) + { + FT_Long idx, size; + FT_Byte* base; + + + /* If the next token isn't `dup', we are also done. This */ + /* happens when there are `holes' in the Subrs array. */ + if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 ) + break; + + idx = T1_ToInt( parser ); + + if ( !read_binary_data( parser, &size, &base ) ) + return; + + /* The binary string is followed by one token, e.g. `NP' */ + /* (bound to `noaccess put') or by two separate tokens: */ + /* `noaccess' & `put'. We position the parser right */ + /* before the next `dup', if any. */ + T1_Skip_Spaces( parser ); + T1_Skip_Alpha( parser ); /* `NP' or `I' or `noaccess' */ + T1_Skip_Spaces( parser ); + + if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 ) + { + T1_Skip_Alpha( parser ); /* skip `put' */ + T1_Skip_Spaces( parser ); + } + + /* some fonts use a value of -1 for lenIV to indicate that */ + /* the charstrings are unencoded */ + /* */ + /* thanks to Tom Kacvinsky for pointing this out */ + /* */ + if ( face->type1.private_dict.lenIV >= 0 ) + { + FT_Byte* temp; + + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( table, idx, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( table, idx, base, size ); + if ( error ) + goto Fail; + } + return; + + Fail: + parser->root.error = error; + } + + + static void + parse_charstrings( T1_Face face, + T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + PS_Table swap_table = &loader->swap_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Int n; + FT_UInt notdef_index = 0; + FT_Byte notdef_found = 0; + + + if ( loader->num_glyphs ) + /* with synthetic fonts, it's possible we get here twice */ + return; + + loader->num_glyphs = (FT_Int)T1_ToInt( parser ); + if ( parser->root.error ) + return; + + /* initialize tables (leaving room for addition of .notdef, */ + /* if necessary). */ + + error = psaux->ps_table_funcs->init( code_table, + loader->num_glyphs + 1, + memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( name_table, + loader->num_glyphs + 1, + memory ); + if ( error ) + goto Fail; + + /* Initialize table for swapping index notdef_index and */ + /* index 0 names and codes (if necessary). */ + + error = psaux->ps_table_funcs->init( swap_table, 4, memory ); + + if ( error ) + goto Fail; + + n = 0; + + for (;;) + { + FT_Long size; + FT_Byte* base; + + + /* the format is simple: */ + /* `/glyphname' + binary data */ + /* */ + /* note that we stop when we find a `def' */ + /* */ + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* we stop when we find a `def' or `end' keyword */ + if ( *cur == 'd' && + cur + 3 < limit && + cur[1] == 'e' && + cur[2] == 'f' ) + break; + + if ( *cur == 'e' && + cur + 3 < limit && + cur[1] == 'n' && + cur[2] == 'd' ) + break; + + if ( *cur != '/' ) + T1_Skip_Alpha( parser ); + else + { + FT_Byte* cur2 = cur + 1; + FT_PtrDist len; + + + while ( cur2 < limit && is_name_char( *cur2 ) ) + cur2++; + len = cur2 - cur - 1; + + error = T1_Add_Table( name_table, n, cur + 1, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + /* record index of /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)(name_table->elements[n]) ) == 0 ) + { + notdef_index = n; + notdef_found = 1; + } + + parser->root.cursor = cur2; + if ( !read_binary_data( parser, &size, &base ) ) + return; + + if ( face->type1.private_dict.lenIV >= 0 ) + { + FT_Byte* temp; + + + /* t1_decrypt() shouldn't write to base -- make temporary copy */ + if ( FT_ALLOC( temp, size ) ) + goto Fail; + FT_MEM_COPY( temp, base, size ); + psaux->t1_decrypt( temp, size, 4330 ); + size -= face->type1.private_dict.lenIV; + error = T1_Add_Table( code_table, n, + temp + face->type1.private_dict.lenIV, size ); + FT_FREE( temp ); + } + else + error = T1_Add_Table( code_table, n, base, size ); + if ( error ) + goto Fail; + + n++; + if ( n >= loader->num_glyphs ) + break; + } + } + + loader->num_glyphs = n; + + /* if /.notdef is found but does not occupy index 0, do our magic. */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)name_table->elements[0] ) && + notdef_found ) + { + /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ + /* name and code entries to swap_table. Then place notdef_index name */ + /* and code entries into swap_table. Then swap name and code */ + /* entries at indices notdef_index and 0 using values stored in */ + /* swap_table. */ + + /* Index 0 name */ + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index 0 code */ + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + /* Index notdef_index name */ + error = T1_Add_Table( swap_table, 2, + name_table->elements[notdef_index], + name_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + /* Index notdef_index code */ + error = T1_Add_Table( swap_table, 3, + code_table->elements[notdef_index], + code_table->lengths [notdef_index] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, notdef_index, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, notdef_index, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, + swap_table->elements[2], + swap_table->lengths [2] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, + swap_table->elements[3], + swap_table->lengths [3] ); + if ( error ) + goto Fail; + + } + else if ( !notdef_found ) + { + /* notdef_index is already 0, or /.notdef is undefined in */ + /* charstrings dictionary. Worry about /.notdef undefined. */ + /* We take index 0 and add it to the end of the table(s) */ + /* and add our own /.notdef glyph to index 0. */ + + /* 0 333 hsbw endchar */ + FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; + char* notdef_name = (char *)".notdef"; + + + error = T1_Add_Table( swap_table, 0, + name_table->elements[0], + name_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( swap_table, 1, + code_table->elements[0], + code_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, 0, notdef_name, 8 ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, 0, notdef_glyph, 5 ); + + if ( error ) + goto Fail; + + error = T1_Add_Table( name_table, n, + swap_table->elements[0], + swap_table->lengths [0] ); + if ( error ) + goto Fail; + + error = T1_Add_Table( code_table, n, + swap_table->elements[1], + swap_table->lengths [1] ); + if ( error ) + goto Fail; + + /* we added a glyph. */ + loader->num_glyphs = n + 1; + } + + return; + + Fail: + parser->root.error = error; + } + + + static + const T1_FieldRec t1_keywords[] = + { + +#include "t1tokens.h" + + /* now add the special functions... */ + T1_FIELD_CALLBACK( "FontName", parse_font_name ) +#if 0 + T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) +#endif + T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) + T1_FIELD_CALLBACK( "Encoding", parse_encoding ) + T1_FIELD_CALLBACK( "Subrs", parse_subrs ) + T1_FIELD_CALLBACK( "CharStrings", parse_charstrings ) + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ) + T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) + T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) + T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) + T1_FIELD_CALLBACK( "shareddict", parse_shared_dict ) +#endif + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + }; + + + static FT_Error + parse_dict( T1_Face face, + T1_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T1_Parser parser = &loader->parser; + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = 0; + + { + FT_Byte* cur = base; + FT_Byte* limit = cur + size; + + + for ( ; cur < limit; cur++ ) + { + /* look for `FontDirectory', which causes problems on some fonts */ + if ( *cur == 'F' && cur + 25 < limit && + ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) + { + FT_Byte* cur2; + + + /* skip the `FontDirectory' keyword */ + cur += 13; + cur2 = cur; + + /* lookup the `known' keyword */ + while ( cur < limit && *cur != 'k' && + ft_strncmp( (char*)cur, "known", 5 ) ) + cur++; + + if ( cur < limit ) + { + T1_TokenRec token; + + + /* skip the `known' keyword and the token following it */ + cur += 5; + loader->parser.root.cursor = cur; + T1_ToToken( &loader->parser, &token ); + + /* if the last token was an array, skip it! */ + if ( token.type == T1_TOKEN_TYPE_ARRAY ) + cur2 = parser->root.cursor; + } + cur = cur2; + } + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_Byte* cur2; + FT_PtrDist len; + + + cur++; + cur2 = cur; + while ( cur2 < limit && is_name_char( *cur2 ) ) + cur2++; + + len = cur2 - cur; + if ( len > 0 && len < 22 ) + { + { + /* now, compare the immediate name to the keyword table */ + T1_Field keyword = (T1_Field)t1_keywords; + + + for (;;) + { + FT_Byte* name; + + + name = (FT_Byte*)keyword->ident; + if ( !name ) + break; + + if ( cur[0] == name[0] && + len == ft_strlen( (const char*)name ) ) + { + FT_PtrDist n; + + + for ( n = 1; n < len; n++ ) + if ( cur[n] != name[n] ) + break; + + if ( n >= len ) + { + /* we found it -- run the parsing callback! */ + parser->root.cursor = cur2; + T1_Skip_Spaces( parser ); + parser->root.error = t1_load_keyword( face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + + cur = parser->root.cursor; + break; + } + } + keyword++; + } + } + } + } + } + } + return parser->root.error; + } + + + static void + t1_init_loader( T1_Loader loader, + T1_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + loader->subrs.init = 0; + loader->swap_table.init = 0; + loader->fontdata = 0; + } + + + static void + t1_done_loader( T1_Loader loader ) + { + T1_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + T1_Release_Table( &loader->swap_table ); + T1_Release_Table( &loader->subrs ); + + /* finalize parser */ + T1_Finalize_Parser( parser ); + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Open_Face( T1_Face face ) + { + T1_LoaderRec loader; + T1_Parser parser; + T1_Font type1 = &face->type1; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t1_init_loader( &loader, face ); + + /* default lenIV */ + type1->private_dict.lenIV = 4; + + /* default blue fuzz, we put it there since 0 is a valid value */ + type1->private_dict.blue_fuzz = 1; + + parser = &loader.parser; + error = T1_New_Parser( parser, + face->root.stream, + face->root.memory, + psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); + if ( error ) + goto Exit; + + error = T1_Get_Private_Dict( parser, psaux ); + if ( error ) + goto Exit; + + error = parse_dict( face, &loader, parser->private_dict, + parser->private_len ); + if ( error ) + goto Exit; + + /* now, propagate the subrs, charstrings, and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( loader.subrs.init ) + { + loader.subrs.init = 0; + type1->num_subrs = loader.num_subrs; + type1->subrs_block = loader.subrs.block; + type1->subrs = loader.subrs.elements; + type1->subrs_len = loader.subrs.lengths; + } + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !face->root.internal->incremental_interface ) +#endif + if ( !loader.charstrings.init ) + { + FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" )); + error = T1_Err_Invalid_File_Format; + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* char_name; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* the index is then stored in type1.encoding.char_index, and */ + /* a the name to type1.encoding.char_name */ + + min_char = +32000; + max_char = -32000; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) min_char = charcode; + if ( charcode > max_char ) max_char = charcode; + } + break; + } + } + } + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t1_done_loader( &loader ); + return error; + } + + +/* END */ diff --git a/lib/freetype/src/type1/t1load.h b/lib/freetype/src/type1/t1load.h new file mode 100644 index 0000000..804a010 --- /dev/null +++ b/lib/freetype/src/type1/t1load.h @@ -0,0 +1,84 @@ +/***************************************************************************/ +/* */ +/* t1load.h */ +/* */ +/* Type 1 font loader (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1LOAD_H__ +#define __T1LOAD_H__ + + +#include +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_MULTIPLE_MASTERS_H + +#include "t1parse.h" + + +FT_BEGIN_HEADER + + + typedef struct T1_Loader_ + { + T1_ParserRec parser; /* parser used to read the stream */ + + FT_Int num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_Int num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + PS_TableRec swap_table; /* For moving .notdef glyph to index 0. */ + + FT_Int num_subrs; + PS_TableRec subrs; + FT_Bool fontdata; + + } T1_LoaderRec, *T1_Loader; + + + FT_LOCAL( FT_Error ) + T1_Open_Face( T1_Face face ); + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + FT_LOCAL( FT_Error ) + T1_Get_Multi_Master( T1_Face face, + FT_Multi_Master* master ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + T1_Set_MM_Design( T1_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + FT_LOCAL( void ) + T1_Done_Blend( T1_Face face ); + +#endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */ + + +FT_END_HEADER + +#endif /* __T1LOAD_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1objs.c b/lib/freetype/src/type1/t1objs.c new file mode 100644 index 0000000..59e7cb6 --- /dev/null +++ b/lib/freetype/src/type1/t1objs.c @@ -0,0 +1,541 @@ +/***************************************************************************/ +/* */ +/* t1objs.c */ +/* */ +/* Type 1 objects manager (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H + +#include "t1gload.h" +#include "t1load.h" + +#include "t1errors.h" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.h" +#endif + +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1objs + + + /*************************************************************************/ + /* */ + /* SIZE FUNCTIONS */ + /* */ + /* note that we store the global hints in the size's "internal" root */ + /* field */ + /* */ + /*************************************************************************/ + + + static PSH_Globals_Funcs + T1_Size_Get_Globals_Funcs( T1_Size size ) + { + T1_Face face = (T1_Face)size->root.face; + PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; + FT_Module module; + + + module = FT_Get_Module( size->root.face->driver->root.library, + "pshinter" ); + return ( module && pshinter && pshinter->get_globals_funcs ) + ? pshinter->get_globals_funcs( module ) + : 0 ; + } + + + FT_LOCAL_DEF( void ) + T1_Size_Done( T1_Size size ) + { + if ( size->root.internal ) + { + PSH_Globals_Funcs funcs; + + + funcs = T1_Size_Get_Globals_Funcs( size ); + if ( funcs ) + funcs->destroy( (PSH_Globals)size->root.internal ); + + size->root.internal = 0; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Init( T1_Size size ) + { + FT_Error error = 0; + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + + + if ( funcs ) + { + PSH_Globals globals; + T1_Face face = (T1_Face)size->root.face; + + + error = funcs->create( size->root.face->memory, + &face->type1.private_dict, &globals ); + if ( !error ) + size->root.internal = (FT_Size_Internal)(void*)globals; + } + + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Size_Reset( T1_Size size ) + { + PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size ); + FT_Error error = 0; + + + if ( funcs ) + error = funcs->set_scale( (PSH_Globals)size->root.internal, + size->root.metrics.x_scale, + size->root.metrics.y_scale, + 0, 0 ); + return error; + } + + + /*************************************************************************/ + /* */ + /* SLOT FUNCTIONS */ + /* */ + /*************************************************************************/ + + FT_LOCAL_DEF( void ) + T1_GlyphSlot_Done( T1_GlyphSlot slot ) + { + slot->root.internal->glyph_hints = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_GlyphSlot_Init( T1_GlyphSlot slot ) + { + T1_Face face; + PSHinter_Service pshinter; + + + face = (T1_Face)slot->root.face; + pshinter = (PSHinter_Service)face->pshinter; + + if ( pshinter ) + { + FT_Module module; + + + module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" ); + if (module) + { + T1_Hints_Funcs funcs; + + funcs = pshinter->get_t1_funcs( module ); + slot->root.internal->glyph_hints = (void*)funcs; + } + } + return 0; + } + + + /*************************************************************************/ + /* */ + /* FACE FUNCTIONS */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Face_Done */ + /* */ + /* */ + /* The face object destructor. */ + /* */ + /* */ + /* face :: A typeless pointer to the face object to destroy. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Face_Done( T1_Face face ) + { + FT_Memory memory; + T1_Font type1 = &face->type1; + + + if ( face ) + { + memory = face->root.memory; + +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + /* release multiple masters information */ + T1_Done_Blend( face ); + face->blend = 0; +#endif + + /* release font info strings */ + { + PS_FontInfo info = &type1->font_info; + + + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + } + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->subrs ); + FT_FREE( type1->subrs_len ); + + FT_FREE( type1->subrs_block ); + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + +#ifndef T1_CONFIG_OPTION_NO_AFM + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); +#endif + + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; + + face->root.family_name = 0; + face->root.style_name = 0; + } + } + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Face_Init */ + /* */ + /* */ + /* The face object constructor. */ + /* */ + /* */ + /* stream :: input stream where to load font data. */ + /* */ + /* face_index :: The index of the font face in the resource. */ + /* */ + /* num_params :: Number of additional generic parameters. Ignored. */ + /* */ + /* params :: Additional generic parameters. Ignored. */ + /* */ + /* */ + /* face :: The face record to build. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Face_Init( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + PSNames_Service psnames; + PSAux_Service psaux; + PSHinter_Service pshinter; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + FT_UNUSED( stream ); + + + face->root.num_faces = 1; + + face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psnames" ); + psnames = (PSNames_Service)face->psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + + face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "pshinter" ); + pshinter = (PSHinter_Service)face->pshinter; + + /* open the tokenizer, this will also check the font format */ + error = T1_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index != 0 ) + { + FT_ERROR(( "T1_Face_Init: invalid face index\n" )); + error = T1_Err_Invalid_Argument; + goto Exit; + } + + /* Now, load the font program into the face object */ + + /* Init the face object fields */ + /* Now set up root face fields */ + { + FT_Face root = (FT_Face)&face->root; + + + root->num_glyphs = face->type1.num_glyphs; + root->face_index = face_index; + + root->face_flags = FT_FACE_FLAG_SCALABLE; + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; + + if ( face->type1.font_info.is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( face->blend ) + root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + + /* XXX: TODO -- add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = face->type1.font_info.family_name; + if ( root->family_name ) + { + char* full = face->type1.font_info.full_name; + char* family = root->family_name; + + + if ( full ) + { + while ( *family && *full == *family ) + { + family++; + full++; + } + + root->style_name = ( *full == ' ' ? full + 1 + : (char *)"Regular" ); + } + else + root->style_name = (char *)"Regular"; + } + else + { + /* do we have a `/FontName'? */ + if ( face->type1.font_name ) + { + root->family_name = face->type1.font_name; + root->style_name = (char *)"Regular"; + } + } + + /* compute style flags */ + root->style_flags = 0; + if ( face->type1.font_info.italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + if ( face->type1.font_info.weight ) + { + if ( !ft_strcmp( face->type1.font_info.weight, "Bold" ) || + !ft_strcmp( face->type1.font_info.weight, "Black" ) ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + root->bbox.xMin = face->type1.font_bbox.xMin >> 16; + root->bbox.yMin = face->type1.font_bbox.yMin >> 16; + root->bbox.xMax = ( face->type1.font_bbox.xMax + 0xFFFFU ) >> 16; + root->bbox.yMax = ( face->type1.font_bbox.yMax + 0xFFFFU ) >> 16; + + /* Set units_per_EM if we didn't set it in parse_font_matrix. */ + if ( !root->units_per_EM ) + root->units_per_EM = 1000; + + root->ascender = (FT_Short)( root->bbox.yMax ); + root->descender = (FT_Short)( root->bbox.yMin ); + root->height = (FT_Short)( + ( ( root->ascender - root->descender ) * 12 ) / 10 ); + + /* now compute the maximum advance width */ + root->max_advance_width = + (FT_Short)( root->bbox.xMax ); + { + FT_Int max_advance; + + + error = T1_Compute_Max_Advance( face, &max_advance ); + + /* in case of error, keep the standard width */ + if ( !error ) + root->max_advance_width = (FT_Short)max_advance; + else + error = 0; /* clear error */ + } + + root->max_advance_height = root->height; + + root->underline_position = face->type1.font_info.underline_position; + root->underline_thickness = face->type1.font_info.underline_thickness; + + root->internal->max_points = 0; + root->internal->max_contours = 0; + } + + { + FT_Face root = &face->root; + + + if ( psnames && psaux ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthetize a Unicode charmap */ + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = 7; + clazz = NULL; + + switch ( face->type1.encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = 0; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = 1; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = 2; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = 3; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Driver_Init */ + /* */ + /* */ + /* Initializes a given Type 1 driver object. */ + /* */ + /* */ + /* driver :: A handle to the target driver object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T1_Driver_Init( T1_Driver driver ) + { + FT_UNUSED( driver ); + + return T1_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Driver_Done */ + /* */ + /* */ + /* Finalizes a given Type 1 driver. */ + /* */ + /* */ + /* driver :: A handle to the target Type 1 driver. */ + /* */ + FT_LOCAL_DEF( void ) + T1_Driver_Done( T1_Driver driver ) + { + FT_UNUSED( driver ); + } + + +/* END */ diff --git a/lib/freetype/src/type1/t1objs.h b/lib/freetype/src/type1/t1objs.h new file mode 100644 index 0000000..9aeb10d --- /dev/null +++ b/lib/freetype/src/type1/t1objs.h @@ -0,0 +1,170 @@ +/***************************************************************************/ +/* */ +/* t1objs.h */ +/* */ +/* Type 1 objects manager (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1OBJS_H__ +#define __T1OBJS_H__ + + +#include +#include FT_INTERNAL_OBJECTS_H +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /* The following structures must be defined by the hinter */ + typedef struct T1_Size_Hints_ T1_Size_Hints; + typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Driver */ + /* */ + /* */ + /* A handle to a Type 1 driver object. */ + /* */ + typedef struct T1_DriverRec_ *T1_Driver; + + + /*************************************************************************/ + /* */ + /* */ + /* T1_Size */ + /* */ + /* */ + /* A handle to a Type 1 size object. */ + /* */ + typedef struct T1_SizeRec_* T1_Size; + + + /*************************************************************************/ + /* */ + /* */ + /* T1_GlyphSlot */ + /* */ + /* */ + /* A handle to a Type 1 glyph slot object. */ + /* */ + typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* */ + /* T1_CharMap */ + /* */ + /* */ + /* A handle to a Type 1 character mapping object. */ + /* */ + /* */ + /* The Type 1 format doesn't use a charmap but an encoding table. */ + /* The driver is responsible for making up charmap objects */ + /* corresponding to these tables. */ + /* */ + typedef struct T1_CharMapRec_* T1_CharMap; + + + /*************************************************************************/ + /* */ + /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* T1_SizeRec */ + /* */ + /* */ + /* Type 1 size record. */ + /* */ + typedef struct T1_SizeRec_ + { + FT_SizeRec root; + + } T1_SizeRec; + + + FT_LOCAL( void ) + T1_Size_Done( T1_Size size ); + + FT_LOCAL( FT_Error ) + T1_Size_Reset( T1_Size size ); + + FT_LOCAL( FT_Error ) + T1_Size_Init( T1_Size size ); + + + /*************************************************************************/ + /* */ + /* */ + /* T1_GlyphSlotRec */ + /* */ + /* */ + /* Type 1 glyph slot record. */ + /* */ + typedef struct T1_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Int max_points; + FT_Int max_contours; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } T1_GlyphSlotRec; + + + FT_LOCAL( FT_Error ) + T1_Face_Init( FT_Stream stream, + T1_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + FT_LOCAL( void ) + T1_Face_Done( T1_Face face ); + + FT_LOCAL( FT_Error ) + T1_GlyphSlot_Init( T1_GlyphSlot slot ); + + FT_LOCAL( void ) + T1_GlyphSlot_Done( T1_GlyphSlot slot ); + + FT_LOCAL( FT_Error ) + T1_Driver_Init( T1_Driver driver ); + + FT_LOCAL( void ) + T1_Driver_Done( T1_Driver driver ); + + +FT_END_HEADER + +#endif /* __T1OBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1parse.c b/lib/freetype/src/type1/t1parse.c new file mode 100644 index 0000000..c1783f0 --- /dev/null +++ b/lib/freetype/src/type1/t1parse.c @@ -0,0 +1,460 @@ +/***************************************************************************/ +/* */ +/* t1parse.c */ +/* */ +/* Type 1 parser (body). */ +/* */ +/* Copyright 1996-2001, 2002 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 Type 1 parser is in charge of the following: */ + /* */ + /* - provide an implementation of a growing sequence of objects called */ + /* a `T1_Table' (used to build various tables needed by the loader). */ + /* */ + /* - opening .pfb and .pfa files to extract their top-level and private */ + /* dictionaries. */ + /* */ + /* - read numbers, arrays & strings from any dictionary. */ + /* */ + /* See `t1load.c' to see how data is loaded from the font file. */ + /* */ + /*************************************************************************/ + + +#include +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#include "t1parse.h" + +#include "t1errors.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t1parse + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INPUT STREAM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) +#define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) + +#define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) + + + typedef struct PFB_Tag_ + { + FT_UShort tag; + FT_Long size; + + } PFB_Tag; + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PFB_Tag + + + static + const FT_Frame_Field pfb_tag_fields[] = + { + FT_FRAME_START( 6 ), + FT_FRAME_USHORT ( tag ), + FT_FRAME_LONG_LE( size ), + FT_FRAME_END + }; + + + static FT_Error + read_pfb_tag( FT_Stream stream, + FT_UShort* tag, + FT_Long* size ) + { + FT_Error error; + PFB_Tag head; + + + *tag = 0; + *size = 0; + if ( !FT_STREAM_READ_FIELDS( pfb_tag_fields, &head ) ) + { + if ( head.tag == 0x8001U || head.tag == 0x8002U ) + { + *tag = head.tag; + *size = head.size; + } + } + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error; + FT_UShort tag; + FT_Long size; + + + psaux->ps_parser_funcs->init( &parser->root,0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->private_len = 0; + parser->private_dict = 0; + parser->in_pfb = 0; + parser->in_memory = 0; + parser->single_block = 0; + + /******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 1 parser, we try to locate and load */ + /* the base dictionary if this is possible (i.e. for PFB */ + /* files). Otherwise, we load the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only setup pointers */ + /* in the case of a memory-based stream. Otherwise, we */ + /* allocate and load the base dictionary in it. */ + /* */ + /* parser->in_pfb is set if we are in a binary (".pfb") font. */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + /* try to compute the size of the base dictionary; */ + /* look for a Postscript binary file tag, i.e 0x8001 */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Exit; + + if ( tag != 0x8001U ) + { + /* assume that this is a PFA file for now; an error will */ + /* be produced later when more things are checked */ + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + size = stream->size; + } + else + parser->in_pfb = 1; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + parser->base_len = size; + } + + /* Now check font format; we must see `%!PS-AdobeFont-1' */ + /* or `%!FontType' */ + { + if ( size <= 16 || + ( ft_strncmp( (const char*)parser->base_dict, + "%!PS-AdobeFont-1", 16 ) && + ft_strncmp( (const char*)parser->base_dict, + "%!FontType", 10 ) ) ) + { + FT_TRACE2(( "[not a Type1 font]\n" )); + error = T1_Err_Unknown_File_Format; + } + else + { + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + } + } + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + T1_Finalize_Parser( T1_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* always free the private dictionary */ + FT_FREE( parser->private_dict ); + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + /* return the value of an hexadecimal digit */ + static int + hexa_value( char c ) + { + unsigned int d; + + + d = (unsigned int)( c - '0' ); + if ( d <= 9 ) + return (int)d; + + d = (unsigned int)( c - 'a' ); + if ( d <= 5 ) + return (int)( d + 10 ); + + d = (unsigned int)( c - 'A' ); + if ( d <= 5 ) + return (int)( d + 10 ); + + return -1; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ) + { + FT_Stream stream = parser->stream; + FT_Memory memory = parser->root.memory; + FT_Error error = 0; + FT_Long size; + + + if ( parser->in_pfb ) + { + /* in the case of the PFB format, the private dictionary can be */ + /* made of several segments. We thus first read the number of */ + /* segments to compute the total size of the private dictionary */ + /* then re-read them into memory. */ + FT_Long start_pos = FT_STREAM_POS(); + FT_UShort tag; + + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error ) + goto Fail; + + if ( tag != 0x8002U ) + break; + + parser->private_len += size; + + if ( FT_STREAM_SKIP( size ) ) + goto Fail; + } + + /* Check that we have a private dictionary there */ + /* and allocate private dictionary buffer */ + if ( parser->private_len == 0 ) + { + FT_ERROR(( "T1_Get_Private_Dict:" )); + FT_ERROR(( " invalid private dictionary section\n" )); + error = T1_Err_Invalid_File_Format; + goto Fail; + } + + if ( FT_STREAM_SEEK( start_pos ) || + FT_ALLOC( parser->private_dict, parser->private_len ) ) + goto Fail; + + parser->private_len = 0; + for (;;) + { + error = read_pfb_tag( stream, &tag, &size ); + if ( error || tag != 0x8002U ) + { + error = T1_Err_Ok; + break; + } + + if ( FT_STREAM_READ( parser->private_dict + parser->private_len, size ) ) + goto Fail; + + parser->private_len += size; + } + } + else + { + /* we have already `loaded' the whole PFA font file into memory; */ + /* if this is a memory resource, allocate a new block to hold */ + /* the private dict. Otherwise, simply overwrite into the base */ + /* dictionary block in the heap. */ + + /* first of all, look at the `eexec' keyword */ + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Byte c; + + + for (;;) + { + c = cur[0]; + if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ + /* newline + 4 chars */ + { + if ( cur[1] == 'e' && cur[2] == 'x' && + cur[3] == 'e' && cur[4] == 'c' ) + { + cur += 6; /* we skip the newling after the `eexec' */ + + /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */ + /* skip the extra \n if we find it */ + if ( cur[0] == '\n' ) + cur++; + + break; + } + } + cur++; + if ( cur >= limit ) + { + FT_ERROR(( "T1_Get_Private_Dict:" )); + FT_ERROR(( " could not find `eexec' keyword\n" )); + error = T1_Err_Invalid_File_Format; + goto Exit; + } + } + + /* now determine where to write the _encrypted_ binary private */ + /* dictionary. We overwrite the base dictionary for disk-based */ + /* resources and allocate a new block otherwise */ + + size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); + + if ( parser->in_memory ) + { + /* note that we allocate one more byte to put a terminating `0' */ + if ( FT_ALLOC( parser->private_dict, size + 1 ) ) + goto Fail; + parser->private_len = size; + } + else + { + parser->single_block = 1; + parser->private_dict = parser->base_dict; + parser->private_len = size; + parser->base_dict = 0; + parser->base_len = 0; + } + + /* now determine whether the private dictionary is encoded in binary */ + /* or hexadecimal ASCII format -- decode it accordingly */ + + /* we need to access the next 4 bytes (after the final \r following */ + /* the `eexec' keyword); if they all are hexadecimal digits, then */ + /* we have a case of ASCII storage */ + + if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) | + hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 ) + + /* binary encoding -- `simply' copy the private dict */ + FT_MEM_COPY( parser->private_dict, cur, size ); + + else + { + /* ASCII hexadecimal encoding */ + + FT_Byte* write; + FT_Int count; + + + write = parser->private_dict; + count = 0; + + for ( ;cur < limit; cur++ ) + { + int hex1; + + + /* check for newline */ + if ( cur[0] == '\r' || cur[0] == '\n' ) + continue; + + /* exit if we have a non-hexadecimal digit that isn't a newline */ + hex1 = hexa_value( cur[0] ); + if ( hex1 < 0 || cur + 1 >= limit ) + break; + + /* otherwise, store byte */ + *write++ = (FT_Byte)( ( hex1 << 4 ) | hexa_value( cur[1] ) ); + count++; + cur++; + } + + /* put a safeguard */ + parser->private_len = write - parser->private_dict; + *write++ = 0; + } + } + + /* we now decrypt the encoded binary private dictionary */ + psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); + parser->root.base = parser->private_dict; + parser->root.cursor = parser->private_dict; + parser->root.limit = parser->root.cursor + parser->private_len; + + Fail: + Exit: + return error; + } + + +/* END */ diff --git a/lib/freetype/src/type1/t1parse.h b/lib/freetype/src/type1/t1parse.h new file mode 100644 index 0000000..ecc2067 --- /dev/null +++ b/lib/freetype/src/type1/t1parse.h @@ -0,0 +1,135 @@ +/***************************************************************************/ +/* */ +/* t1parse.h */ +/* */ +/* Type 1 parser (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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 __T1PARSE_H__ +#define __T1PARSE_H__ + + +#include +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_STREAM_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* */ + /* T1_ParserRec */ + /* */ + /* */ + /* A PS_ParserRec is an object used to parse a Type 1 fonts very */ + /* quickly. */ + /* */ + /* */ + /* root :: The root parser. */ + /* */ + /* stream :: The current input stream. */ + /* */ + /* base_dict :: A pointer to the top-level dictionary. */ + /* */ + /* base_len :: The length in bytes of the top dictionary. */ + /* */ + /* private_dict :: A pointer to the private dictionary. */ + /* */ + /* private_len :: The length in bytes of the private dictionary. */ + /* */ + /* in_pfb :: A boolean. Indicates that we are handling a PFB */ + /* file. */ + /* */ + /* in_memory :: A boolean. Indicates a memory-based stream. */ + /* */ + /* single_block :: A boolean. Indicates that the private dictionary */ + /* is stored in lieu of the base dictionary. */ + /* */ + typedef struct T1_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_Long base_len; + + FT_Byte* private_dict; + FT_Long private_len; + + FT_Byte in_pfb; + FT_Byte in_memory; + FT_Byte single_block; + + } T1_ParserRec, *T1_Parser; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) + +#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define T1_ToCoordArray( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define T1_ToTokenArray( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) + +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + FT_LOCAL( FT_Error ) + T1_New_Parser( T1_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( FT_Error ) + T1_Get_Private_Dict( T1_Parser parser, + PSAux_Service psaux ); + + FT_LOCAL( void ) + T1_Finalize_Parser( T1_Parser parser ); + + +FT_END_HEADER + +#endif /* __T1PARSE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type1/t1tokens.h b/lib/freetype/src/type1/t1tokens.h new file mode 100644 index 0000000..dea5054 --- /dev/null +++ b/lib/freetype/src/type1/t1tokens.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* t1tokens.h */ +/* */ +/* Type 1 tokenizer (specification). */ +/* */ +/* Copyright 1996-2001, 2002 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. */ +/* */ +/***************************************************************************/ + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_FontInfoRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING ( "version", version ) + T1_FIELD_STRING ( "Notice", notice ) + T1_FIELD_STRING ( "FullName", full_name ) + T1_FIELD_STRING ( "FamilyName", family_name ) + T1_FIELD_STRING ( "Weight", weight ) + + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE PS_PrivateRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_PRIVATE + + T1_FIELD_NUM ( "UniqueID", unique_id ) + T1_FIELD_NUM ( "lenIV", lenIV ) + T1_FIELD_NUM ( "LanguageGroup", language_group ) + T1_FIELD_NUM ( "password", password ) + + T1_FIELD_FIXED ( "BlueScale", blue_scale ) + T1_FIELD_NUM ( "BlueShift", blue_shift ) + T1_FIELD_NUM ( "BlueFuzz", blue_fuzz ) + + T1_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) + T1_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) + T1_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) + T1_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) + + T1_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) + T1_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) + T1_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) + + T1_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) + T1_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_NUM( "PaintType", paint_type ) + T1_FIELD_NUM( "FontType", font_type ) + T1_FIELD_NUM( "StrokeWidth", stroke_width ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_BBox +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_BBOX + + T1_FIELD_BBOX("FontBBox", xMin ) + + +/* END */ diff --git a/lib/freetype/src/type1/type1.c b/lib/freetype/src/type1/type1.c new file mode 100644 index 0000000..ccc12be --- /dev/null +++ b/lib/freetype/src/type1/type1.c @@ -0,0 +1,33 @@ +/***************************************************************************/ +/* */ +/* type1.c */ +/* */ +/* FreeType Type 1 driver component (body only). */ +/* */ +/* Copyright 1996-2001 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. */ +/* */ +/***************************************************************************/ + + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include +#include "t1parse.c" +#include "t1load.c" +#include "t1objs.c" +#include "t1driver.c" +#include "t1gload.c" + +#ifndef T1_CONFIG_OPTION_NO_AFM +#include "t1afm.c" +#endif + + +/* END */ diff --git a/lib/freetype/src/type42/Jamfile b/lib/freetype/src/type42/Jamfile new file mode 100644 index 0000000..032ac71 --- /dev/null +++ b/lib/freetype/src/type42/Jamfile @@ -0,0 +1,21 @@ +# FreeType 2 src/type42 Jamfile (c) 2002 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) type42 ; + +{ + local _sources ; + + if $(FT2_MULTI) + { + _sources = t42objs t42parse t42drivr ; + } + else + { + _sources = type42 ; + } + + Library $(FT2_LIB) : $(_sources).c ; +} + +# end of src/type42 Jamfile diff --git a/lib/freetype/src/type42/descrip.mms b/lib/freetype/src/type42/descrip.mms new file mode 100644 index 0000000..a52ba06 --- /dev/null +++ b/lib/freetype/src/type42/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 Type 42 driver compilation rules for VMS +# + + +# Copyright 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.type42]) + +OBJS=type42.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/type42/module.mk b/lib/freetype/src/type42/module.mk new file mode 100644 index 0000000..ceaea41 --- /dev/null +++ b/lib/freetype/src/type42/module.mk @@ -0,0 +1,22 @@ +# +# FreeType 2 Type42 module definition +# + + +# Copyright 2002 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. + + +make_module_list: add_type42_driver + +add_type42_driver: + $(OPEN_DRIVER)t42_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)type42 $(ECHO_DRIVER_DESC)Type 42 font files with no known extension$(ECHO_DRIVER_DONE) + +# EOF diff --git a/lib/freetype/src/type42/rules.mk b/lib/freetype/src/type42/rules.mk new file mode 100644 index 0000000..f991449 --- /dev/null +++ b/lib/freetype/src/type42/rules.mk @@ -0,0 +1,69 @@ +# +# FreeType 2 Type42 driver configuration rules +# + + +# Copyright 2002 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. + + +# Type42 driver directory +# +T42_DIR := $(SRC_)type42 +T42_DIR_ := $(T42_DIR)$(SEP) + + +# compilation flags for the driver +# +T42_COMPILE := $(FT_COMPILE) $I$(T42_DIR) + + +# Type42 driver source +# +T42_DRV_SRC := $(T42_DIR_)t42objs.c \ + $(T42_DIR_)t42parse.c \ + $(T42_DIR_)t42drivr.c + +# Type42 driver headers +# +T42_DRV_H := $(T42_DRV_SRC:%.c=%.h) \ + $(T42_DIR_)t42error.h + + +# Type42 driver object(s) +# +# T42_DRV_OBJ_M is used during `multi' builds +# T42_DRV_OBJ_S is used during `single' builds +# +T42_DRV_OBJ_M := $(T42_DRV_SRC:$(T42_DIR_)%.c=$(OBJ_)%.$O) +T42_DRV_OBJ_S := $(OBJ_)type42.$O + +# Type42 driver source file for single build +# +T42_DRV_SRC_S := $(T42_DIR_)type42.c + + +# Type42 driver - single object +# +$(T42_DRV_OBJ_S): $(T42_DRV_SRC_S) $(T42_DRV_SRC) $(FREETYPE_H) $(T42_DRV_H) + $(T42_COMPILE) $T$@ $(T42_DRV_SRC_S) + + +# Type42 driver - multiple objects +# +$(OBJ_)%.$O: $(T42_DIR_)%.c $(FREETYPE_H) $(T42_DRV_H) + $(T42_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(T42_DRV_OBJ_S) +DRV_OBJS_M += $(T42_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/type42/t42drivr.c b/lib/freetype/src/type42/t42drivr.c new file mode 100644 index 0000000..65bf2e8 --- /dev/null +++ b/lib/freetype/src/type42/t42drivr.c @@ -0,0 +1,169 @@ +/***************************************************************************/ +/* */ +/* t42drivr.c */ +/* */ +/* High-level Type 42 driver interface (body). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 driver implements Type42 fonts as described in the */ + /* Technical Note #5012 from Adobe, with these limitations: */ + /* */ + /* 1) CID Fonts are not currently supported. */ + /* 2) Incremental fonts making use of the GlyphDirectory keyword */ + /* will be loaded, but the rendering will be using the TrueType */ + /* tables. */ + /* 3) The sfnts array is expected to be ASCII, not binary. */ + /* 4) As for Type1 fonts, CDevProc is not supported. */ + /* 5) The Metrics dictionary is not supported. */ + /* 6) AFM metrics are not supported. */ + /* */ + /* In other words, this driver supports Type42 fonts derived from */ + /* TrueType fonts in a non-CID manner, as done by usual conversion */ + /* programs. */ + /* */ + /*************************************************************************/ + + +#include "t42drivr.h" +#include "t42objs.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static FT_Error + t42_get_glyph_name( T42_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ) + { + FT_String* gname; + + + gname = face->type1.glyph_names[glyph_index]; + + if ( buffer_max > 0 ) + { + FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); + + + if ( len >= buffer_max ) + len = buffer_max - 1; + + FT_MEM_COPY( buffer, gname, len ); + ((FT_Byte*)buffer)[len] = 0; + } + + return T42_Err_Ok; + } + + + static const char* + t42_get_ps_name( T42_Face face ) + { + return (const char*)face->type1.font_name; + } + + + static FT_UInt + t42_get_name_index( T42_Face face, + FT_String* glyph_name ) + { + FT_Int i; + FT_String* gname; + + + for ( i = 0; i < face->type1.num_glyphs; i++ ) + { + gname = face->type1.glyph_names[i]; + + if ( !ft_strcmp( glyph_name, gname ) ) + return ft_atoi( (const char *)face->type1.charstrings[i] ); + } + + return 0; + } + + + static FT_Module_Interface + T42_Get_Interface( FT_Driver driver, + const FT_String* t42_interface ) + { + FT_UNUSED( driver ); + + /* Any additional interface are defined here */ + if (ft_strcmp( (const char*)t42_interface, "glyph_name" ) == 0 ) + return (FT_Module_Interface)t42_get_glyph_name; + + if ( ft_strcmp( (const char*)t42_interface, "name_index" ) == 0 ) + return (FT_Module_Interface)t42_get_name_index; + + if ( ft_strcmp( (const char*)t42_interface, "postscript_name" ) == 0 ) + return (FT_Module_Interface)t42_get_ps_name; + + return 0; + } + + + const FT_Driver_ClassRec t42_driver_class = + { + { + ft_module_font_driver | + ft_module_driver_scalable | +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER + ft_module_driver_has_hinter, +#else + 0, +#endif + + sizeof ( T42_DriverRec ), + + "type42", + 0x10000L, + 0x20000L, + + 0, /* format interface */ + + (FT_Module_Constructor)T42_Driver_Init, + (FT_Module_Destructor) T42_Driver_Done, + (FT_Module_Requester) T42_Get_Interface, + }, + + sizeof ( T42_FaceRec ), + sizeof ( T42_SizeRec ), + sizeof ( T42_GlyphSlotRec ), + + (FT_Face_InitFunc) T42_Face_Init, + (FT_Face_DoneFunc) T42_Face_Done, + (FT_Size_InitFunc) T42_Size_Init, + (FT_Size_DoneFunc) T42_Size_Done, + (FT_Slot_InitFunc) T42_GlyphSlot_Init, + (FT_Slot_DoneFunc) T42_GlyphSlot_Done, + + (FT_Size_ResetPointsFunc) T42_Size_SetChars, + (FT_Size_ResetPixelsFunc) T42_Size_SetPixels, + (FT_Slot_LoadFunc) T42_GlyphSlot_Load, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/type42/t42drivr.h b/lib/freetype/src/type42/t42drivr.h new file mode 100644 index 0000000..98b7410 --- /dev/null +++ b/lib/freetype/src/type42/t42drivr.h @@ -0,0 +1,38 @@ +/***************************************************************************/ +/* */ +/* t42drivr.h */ +/* */ +/* High-level Type 42 driver interface (specification). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 __T42DRIVR_H__ +#define __T42DRIVR_H__ + + +#include +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) t42_driver_class; + + +FT_END_HEADER + + +#endif /* __T42DRIVR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type42/t42error.h b/lib/freetype/src/type42/t42error.h new file mode 100644 index 0000000..cb6642b --- /dev/null +++ b/lib/freetype/src/type42/t42error.h @@ -0,0 +1,40 @@ +/***************************************************************************/ +/* */ +/* t42error.h */ +/* */ +/* Type 42 error codes (specification only). */ +/* */ +/* Copyright 2002 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 define the Type 42 error enumeration constants. */ + /* */ + /*************************************************************************/ + +#ifndef __T42ERROR_H__ +#define __T42ERROR_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX T42_Err_ +#define FT_ERR_BASE FT_Mod_Err_T42 + +#include FT_ERRORS_H + +#endif /* __T42ERROR_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type42/t42objs.c b/lib/freetype/src/type42/t42objs.c new file mode 100644 index 0000000..c485634 --- /dev/null +++ b/lib/freetype/src/type42/t42objs.c @@ -0,0 +1,630 @@ +/***************************************************************************/ +/* */ +/* t42objs.c */ +/* */ +/* Type 42 objects manager (body). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 "t42objs.h" +#include "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_LIST_H + + +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static FT_Error + T42_Open_Face( T42_Face face ) + { + T42_LoaderRec loader; + T42_Parser parser; + T1_Font type1 = &face->type1; + FT_Memory memory = face->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + t42_loader_init( &loader, face ); + + parser = &loader.parser; + + if ( FT_ALLOC( face->ttf_data, 12 ) ) + goto Exit; + + error = t42_parser_init( parser, + face->root.stream, + memory, + psaux); + if ( error ) + goto Exit; + + error = t42_parse_dict( face, &loader, parser->base_dict, parser->base_len ); + + if ( type1->font_type != 42 ) + { + error = T42_Err_Unknown_File_Format; + goto Exit; + } + + /* now, propagate the charstrings and glyphnames tables */ + /* to the Type1 data */ + type1->num_glyphs = loader.num_glyphs; + + if ( !loader.charstrings.init ) { + FT_ERROR(( "T42_Open_Face: no charstrings array in face!\n" )); + error = T42_Err_Invalid_File_Format; + } + + loader.charstrings.init = 0; + type1->charstrings_block = loader.charstrings.block; + type1->charstrings = loader.charstrings.elements; + type1->charstrings_len = loader.charstrings.lengths; + + /* we copy the glyph names `block' and `elements' fields; */ + /* the `lengths' field must be released later */ + type1->glyph_names_block = loader.glyph_names.block; + type1->glyph_names = (FT_String**)loader.glyph_names.elements; + loader.glyph_names.block = 0; + loader.glyph_names.elements = 0; + + /* we must now build type1.encoding when we have a custom array */ + if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) + { + FT_Int charcode, idx, min_char, max_char; + FT_Byte* char_name; + FT_Byte* glyph_name; + + + /* OK, we do the following: for each element in the encoding */ + /* table, look up the index of the glyph having the same name */ + /* as defined in the CharStrings array. */ + /* The index is then stored in type1.encoding.char_index, and */ + /* the name in type1.encoding.char_name */ + + min_char = +32000; + max_char = -32000; + + charcode = 0; + for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) + { + type1->encoding.char_index[charcode] = 0; + type1->encoding.char_name [charcode] = (char *)".notdef"; + + char_name = loader.encoding_table.elements[charcode]; + if ( char_name ) + for ( idx = 0; idx < type1->num_glyphs; idx++ ) + { + glyph_name = (FT_Byte*)type1->glyph_names[idx]; + if ( ft_strcmp( (const char*)char_name, + (const char*)glyph_name ) == 0 ) + { + type1->encoding.char_index[charcode] = (FT_UShort)idx; + type1->encoding.char_name [charcode] = (char*)glyph_name; + + /* Change min/max encoded char only if glyph name is */ + /* not /.notdef */ + if ( ft_strcmp( (const char*)".notdef", + (const char*)glyph_name ) != 0 ) + { + if ( charcode < min_char ) min_char = charcode; + if ( charcode > max_char ) max_char = charcode; + } + break; + } + } + } + type1->encoding.code_first = min_char; + type1->encoding.code_last = max_char; + type1->encoding.num_chars = loader.num_chars; + } + + Exit: + t42_loader_done( &loader ); + return error; + } + + + /***************** Driver Functions *************/ + + + FT_LOCAL_DEF( FT_Error ) + T42_Face_Init( FT_Stream stream, + T42_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + PSNames_Service psnames; + PSAux_Service psaux; + FT_Face root = (FT_Face)&face->root; + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + FT_UNUSED( stream ); + + + face->ttf_face = NULL; + face->root.num_faces = 1; + + face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psnames" ); + psnames = (PSNames_Service)face->psnames; + + face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), + "psaux" ); + psaux = (PSAux_Service)face->psaux; + + /* open the tokenizer, this will also check the font format */ + error = T42_Open_Face( face ); + if ( error ) + goto Exit; + + /* if we just wanted to check the format, leave successfully now */ + if ( face_index < 0 ) + goto Exit; + + /* check the face index */ + if ( face_index != 0 ) + { + FT_ERROR(( "T42_Face_Init: invalid face index\n" )); + error = T42_Err_Invalid_Argument; + goto Exit; + } + + /* Now, load the font program into the face object */ + + /* Init the face object fields */ + /* Now set up root face fields */ + + root->num_glyphs = face->type1.num_glyphs; + root->num_charmaps = 0; + root->face_index = face_index; + + root->face_flags = FT_FACE_FLAG_SCALABLE; + root->face_flags |= FT_FACE_FLAG_HORIZONTAL; + root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; + + if ( face->type1.font_info.is_fixed_pitch ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + /* XXX: TODO -- add kerning with .afm support */ + + /* get style name -- be careful, some broken fonts only */ + /* have a `/FontName' dictionary entry! */ + root->family_name = face->type1.font_info.family_name; + if ( root->family_name ) + { + char* full = face->type1.font_info.full_name; + char* family = root->family_name; + + + if ( full ) + { + while ( *family && *full == *family ) + { + family++; + full++; + } + + root->style_name = ( *full == ' ' ? full + 1 + : (char *)"Regular" ); + } + else + root->style_name = (char *)"Regular"; + } + else + { + /* do we have a `/FontName'? */ + if ( face->type1.font_name ) + { + root->family_name = face->type1.font_name; + root->style_name = (char *)"Regular"; + } + } + + /* no embedded bitmap support */ + root->num_fixed_sizes = 0; + root->available_sizes = 0; + + /* Load the TTF font embedded in the T42 font */ + error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ), + face->ttf_data, + face->ttf_size, + 0, + &face->ttf_face ); + if ( error ) + goto Exit; + + FT_Done_Size( face->ttf_face->size ); + + /* Ignore info in FontInfo dictionary and use the info from the */ + /* loaded TTF font. The PostScript interpreter also ignores it. */ + root->bbox = face->ttf_face->bbox; + root->units_per_EM = face->ttf_face->units_per_EM; + + root->ascender = face->ttf_face->ascender; + root->descender = face->ttf_face->descender; + root->height = face->ttf_face->height; + + root->max_advance_width = face->ttf_face->max_advance_width; + root->max_advance_height = face->ttf_face->max_advance_height; + + root->underline_position = face->type1.font_info.underline_position; + root->underline_thickness = face->type1.font_info.underline_thickness; + + root->internal->max_points = 0; + root->internal->max_contours = 0; + + /* compute style flags */ + root->style_flags = 0; + if ( face->type1.font_info.italic_angle ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) + root->face_flags |= FT_FACE_FLAG_VERTICAL; + + { + if ( psnames && psaux ) + { + FT_CharMapRec charmap; + T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; + FT_CMap_Class clazz; + + + charmap.face = root; + + /* first of all, try to synthetize a Unicode charmap */ + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.encoding = FT_ENCODING_UNICODE; + + FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); + + /* now, generate an Adobe Standard encoding when appropriate */ + charmap.platform_id = 7; + clazz = NULL; + + switch ( face->type1.encoding_type ) + { + case T1_ENCODING_TYPE_STANDARD: + charmap.encoding = FT_ENCODING_ADOBE_STANDARD; + charmap.encoding_id = 0; + clazz = cmap_classes->standard; + break; + + case T1_ENCODING_TYPE_EXPERT: + charmap.encoding = FT_ENCODING_ADOBE_EXPERT; + charmap.encoding_id = 1; + clazz = cmap_classes->expert; + break; + + case T1_ENCODING_TYPE_ARRAY: + charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; + charmap.encoding_id = 2; + clazz = cmap_classes->custom; + break; + + case T1_ENCODING_TYPE_ISOLATIN1: + charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; + charmap.encoding_id = 3; + clazz = cmap_classes->unicode; + break; + + default: + ; + } + + if ( clazz ) + FT_CMap_New( clazz, NULL, &charmap, NULL ); + +#if 0 + /* Select default charmap */ + if (root->num_charmaps) + root->charmap = root->charmaps[0]; +#endif + } + } + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + T42_Face_Done( T42_Face face ) + { + T1_Font type1; + PS_FontInfo info; + FT_Memory memory; + + + if ( face ) + { + type1 = &face->type1; + info = &type1->font_info; + memory = face->root.memory; + + /* delete internal ttf face prior to freeing face->ttf_data */ + if ( face->ttf_face ) + FT_Done_Face( face->ttf_face ); + + /* release font info strings */ + FT_FREE( info->version ); + FT_FREE( info->notice ); + FT_FREE( info->full_name ); + FT_FREE( info->family_name ); + FT_FREE( info->weight ); + + /* release top dictionary */ + FT_FREE( type1->charstrings_len ); + FT_FREE( type1->charstrings ); + FT_FREE( type1->glyph_names ); + + FT_FREE( type1->charstrings_block ); + FT_FREE( type1->glyph_names_block ); + + FT_FREE( type1->encoding.char_index ); + FT_FREE( type1->encoding.char_name ); + FT_FREE( type1->font_name ); + + FT_FREE( face->ttf_data ); + +#if 0 + /* release afm data if present */ + if ( face->afm_data ) + T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); +#endif + + /* release unicode map, if any */ + FT_FREE( face->unicode_map.maps ); + face->unicode_map.num_maps = 0; + + face->root.family_name = 0; + face->root.style_name = 0; + } + } + + + /*************************************************************************/ + /* */ + /* */ + /* T42_Driver_Init */ + /* */ + /* */ + /* Initializes a given Type 42 driver object. */ + /* */ + /* */ + /* driver :: A handle to the target driver object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + T42_Driver_Init( T42_Driver driver ) + { + FT_Module ttmodule; + + + ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" ); + driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; + + return T42_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + T42_Driver_Done( T42_Driver driver ) + { + FT_UNUSED( driver ); + } + + + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_Init( T42_Size size ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + FT_Size ttsize; + FT_Error error = T42_Err_Ok; + + + error = FT_New_Size( t42face->ttf_face, &ttsize ); + size->ttsize = ttsize; + + FT_Activate_Size( ttsize ); + + return error; + } + + + FT_LOCAL_DEF( void ) + T42_Size_Done( T42_Size size ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + FT_ListNode node; + + + node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); + if ( node ) + { + FT_Done_Size( size->ttsize ); + size->ttsize = NULL; + } + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Init( T42_GlyphSlot slot ) + { + FT_Face face = slot->root.face; + T42_Face t42face = (T42_Face)face; + FT_GlyphSlot ttslot; + FT_Error error = T42_Err_Ok; + + + if ( face->glyph == NULL ) + { + /* First glyph slot for this face */ + slot->ttslot = t42face->ttf_face->glyph; + } + else + { + error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); + slot->ttslot = ttslot; + } + + return error; + } + + + FT_LOCAL_DEF( void ) + T42_GlyphSlot_Done( T42_GlyphSlot slot ) + { + FT_Face face = slot->root.face; + T42_Face t42face = (T42_Face)face; + FT_GlyphSlot cur = t42face->ttf_face->glyph; + + + while ( cur ) + { + if ( cur == slot->ttslot ) + { + FT_Done_GlyphSlot( slot->ttslot ); + break; + } + + cur = cur->next; + } + } + + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_SetChars( T42_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + + + FT_Activate_Size(size->ttsize); + + return FT_Set_Char_Size( t42face->ttf_face, + char_width, + char_height, + horz_resolution, + vert_resolution ); + } + + + FT_LOCAL_DEF( FT_Error ) + T42_Size_SetPixels( T42_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ) + { + FT_Face face = size->root.face; + T42_Face t42face = (T42_Face)face; + + + FT_Activate_Size(size->ttsize); + + return FT_Set_Pixel_Sizes( t42face->ttf_face, + pixel_width, + pixel_height ); + } + + + static void + t42_glyphslot_clear( FT_GlyphSlot slot ) + { + /* free bitmap if needed */ + ft_glyphslot_free_bitmap( slot ); + + /* clear all public fields in the glyph slot */ + FT_ZERO( &slot->metrics ); + FT_ZERO( &slot->outline ); + FT_ZERO( &slot->bitmap ); + + slot->bitmap_left = 0; + slot->bitmap_top = 0; + slot->num_subglyphs = 0; + slot->subglyphs = 0; + slot->control_data = 0; + slot->control_len = 0; + slot->other = 0; + slot->format = FT_GLYPH_FORMAT_NONE; + + slot->linearHoriAdvance = 0; + slot->linearVertAdvance = 0; + } + + + FT_LOCAL_DEF( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; + T42_Size t42size = (T42_Size)size; + FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; + + + t42_glyphslot_clear( t42slot->ttslot ); + error = ttclazz->load_glyph( t42slot->ttslot, + t42size->ttsize, + glyph_index, + load_flags | FT_LOAD_NO_BITMAP ); + + if ( !error ) + { + glyph->metrics = t42slot->ttslot->metrics; + + glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; + glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; + + glyph->format = t42slot->ttslot->format; + glyph->outline = t42slot->ttslot->outline; + + glyph->bitmap = t42slot->ttslot->bitmap; + glyph->bitmap_left = t42slot->ttslot->bitmap_left; + glyph->bitmap_top = t42slot->ttslot->bitmap_top; + + glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; + glyph->subglyphs = t42slot->ttslot->subglyphs; + + glyph->control_data = t42slot->ttslot->control_data; + glyph->control_len = t42slot->ttslot->control_len; + } + + return error; + } + + +/* END */ diff --git a/lib/freetype/src/type42/t42objs.h b/lib/freetype/src/type42/t42objs.h new file mode 100644 index 0000000..6fb1769 --- /dev/null +++ b/lib/freetype/src/type42/t42objs.h @@ -0,0 +1,126 @@ +/***************************************************************************/ +/* */ +/* t42objs.h */ +/* */ +/* Type 42 objects manager (specification). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 __T42OBJS_H__ +#define __T42OBJS_H__ + +#include +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_TYPE42_TYPES_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_POSTSCRIPT_NAMES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + /* Type42 size */ + typedef struct T42_SizeRec_ + { + FT_SizeRec root; + FT_Size ttsize; + + } T42_SizeRec, *T42_Size; + + + /* Type42 slot */ + typedef struct T42_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + FT_GlyphSlot ttslot; + + } T42_GlyphSlotRec, *T42_GlyphSlot; + + + /* Type 42 driver */ + typedef struct T42_DriverRec_ + { + FT_DriverRec root; + FT_Driver_Class ttclazz; + void* extension_component; + + } T42_DriverRec, *T42_Driver; + + + /* */ + + + FT_LOCAL( FT_Error ) + T42_Face_Init( FT_Stream stream, + T42_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + FT_LOCAL( void ) + T42_Face_Done( T42_Face face ); + + + FT_LOCAL( FT_Error ) + T42_Size_Init( T42_Size size ); + + + FT_LOCAL( FT_Error ) + T42_Size_SetChars( T42_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + FT_LOCAL( FT_Error ) + T42_Size_SetPixels( T42_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + FT_LOCAL( void ) + T42_Size_Done( T42_Size size ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Init( T42_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_GlyphSlot_Load( FT_GlyphSlot glyph, + FT_Size size, + FT_Int glyph_index, + FT_Int32 load_flags ); + + FT_LOCAL( void ) + T42_GlyphSlot_Done( T42_GlyphSlot slot ); + + + FT_LOCAL( FT_Error ) + T42_Driver_Init( T42_Driver driver ); + + FT_LOCAL( void ) + T42_Driver_Done( T42_Driver driver ); + + /* */ + +FT_END_HEADER + + +#endif /* __T42OBJS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type42/t42parse.c b/lib/freetype/src/type42/t42parse.c new file mode 100644 index 0000000..8bb2e7b --- /dev/null +++ b/lib/freetype/src/type42/t42parse.c @@ -0,0 +1,994 @@ +/***************************************************************************/ +/* */ +/* t42parse.c */ +/* */ +/* Type 42 font parser (body). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 "t42parse.h" +#include "t42error.h" +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_LIST_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_t42 + + + static void + t42_parse_font_name( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_font_bbox( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ); + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ); + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ); + + + static const + T1_FieldRec t42_keywords[] = { + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontInfo +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_INFO + + T1_FIELD_STRING ( "version", version ) + T1_FIELD_STRING ( "Notice", notice ) + T1_FIELD_STRING ( "FullName", full_name ) + T1_FIELD_STRING ( "FamilyName", family_name ) + T1_FIELD_STRING ( "Weight", weight ) + T1_FIELD_NUM ( "ItalicAngle", italic_angle ) + T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) + T1_FIELD_NUM ( "UnderlinePosition", underline_position ) + T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) + +#undef FT_STRUCTURE +#define FT_STRUCTURE T1_FontRec +#undef T1CODE +#define T1CODE T1_FIELD_LOCATION_FONT_DICT + + T1_FIELD_NUM( "PaintType", paint_type ) + T1_FIELD_NUM( "FontType", font_type ) + T1_FIELD_NUM( "StrokeWidth", stroke_width ) + + T1_FIELD_CALLBACK( "FontName", t42_parse_font_name ) + T1_FIELD_CALLBACK( "FontBBox", t42_parse_font_bbox ) + T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix ) + T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding ) + T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings ) + T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts ) + + { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } + }; + + +#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) +#define T1_Done_Table( p ) \ + do \ + { \ + if ( (p)->funcs.done ) \ + (p)->funcs.done( p ); \ + } while ( 0 ) +#define T1_Release_Table( p ) \ + do \ + { \ + if ( (p)->funcs.release ) \ + (p)->funcs.release( p ); \ + } while ( 0 ) + +#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) +#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) + +#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) +#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) + +#define T1_ToCoordArray( p, m, c ) \ + (p)->root.funcs.to_coord_array( &(p)->root, m, c ) +#define T1_ToFixedArray( p, m, f, t ) \ + (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) +#define T1_ToToken( p, t ) \ + (p)->root.funcs.to_token( &(p)->root, t ) +#define T1_ToTokenArray( p, t, m, c ) \ + (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) + +#define T1_Load_Field( p, f, o, m, pf ) \ + (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) +#define T1_Load_Field_Table( p, f, o, m, pf ) \ + (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) + + + /********************* Parsing Functions ******************/ + + FT_LOCAL_DEF( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ) + { + FT_Error error = T42_Err_Ok; + FT_Long size; + + + psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); + + parser->stream = stream; + parser->base_len = 0; + parser->base_dict = 0; + parser->in_memory = 0; + + /*******************************************************************/ + /* */ + /* Here a short summary of what is going on: */ + /* */ + /* When creating a new Type 42 parser, we try to locate and load */ + /* the base dictionary, loading the whole font into memory. */ + /* */ + /* When `loading' the base dictionary, we only setup pointers in */ + /* the case of a memory-based stream. Otherwise, we allocate */ + /* and load the base dictionary in it. */ + /* */ + /* parser->in_memory is set if we have a memory stream. */ + /* */ + + if ( FT_STREAM_SEEK( 0L ) ) + goto Exit; + + size = stream->size; + + /* now, try to load `size' bytes of the `base' dictionary we */ + /* found previously */ + + /* if it is a memory-based resource, set up pointers */ + if ( !stream->read ) + { + parser->base_dict = (FT_Byte*)stream->base + stream->pos; + parser->base_len = size; + parser->in_memory = 1; + + /* check that the `size' field is valid */ + if ( FT_STREAM_SKIP( size ) ) + goto Exit; + } + else + { + /* read segment in memory */ + if ( FT_ALLOC( parser->base_dict, size ) || + FT_STREAM_READ( parser->base_dict, size ) ) + goto Exit; + + parser->base_len = size; + } + + /* Now check font format; we must see `%!PS-TrueTypeFont' */ + if (size <= 17 || + ( ft_strncmp( (const char*)parser->base_dict, + "%!PS-TrueTypeFont", 17) ) ) + error = T42_Err_Unknown_File_Format; + else + { + parser->root.base = parser->base_dict; + parser->root.cursor = parser->base_dict; + parser->root.limit = parser->root.cursor + parser->base_len; + } + + Exit: + if ( error && !parser->in_memory ) + FT_FREE( parser->base_dict ); + + return error; + } + + + FT_LOCAL_DEF( void ) + t42_parser_done( T42_Parser parser ) + { + FT_Memory memory = parser->root.memory; + + + /* free the base dictionary only when we have a disk stream */ + if ( !parser->in_memory ) + FT_FREE( parser->base_dict ); + + parser->root.funcs.done( &parser->root ); + } + + + static int + t42_is_alpha( FT_Byte c ) + { + /* Note: we must accept "+" as a valid character, as it is used in */ + /* embedded type1 fonts in PDF documents. */ + /* */ + return ( ft_isalnum( c ) || + c == '.' || + c == '_' || + c == '-' || + c == '+' ); + } + + + static int + t42_is_space( FT_Byte c ) + { + return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); + } + + + static void + t42_parse_font_name( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Error error; + FT_Memory memory = parser->root.memory; + FT_Int len; + FT_Byte* cur; + FT_Byte* cur2; + FT_Byte* limit; + + + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + limit = parser->root.limit; + + if ( cur >= limit - 1 || + ( *cur != '/' && *cur != '(') ) + return; + + cur++; + cur2 = cur; + while ( cur2 < limit && t42_is_alpha( *cur2 ) ) + cur2++; + + len = (FT_Int)( cur2 - cur ); + if ( len > 0 ) + { + if ( FT_ALLOC( face->type1.font_name, len + 1 ) ) + { + parser->root.error = error; + return; + } + + FT_MEM_COPY( face->type1.font_name, cur, len ); + face->type1.font_name[len] = '\0'; + } + parser->root.cursor = cur2; + } + + + static void + t42_parse_font_bbox( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_BBox* bbox = &face->type1.font_bbox; + + bbox->xMin = T1_ToInt( parser ); + bbox->yMin = T1_ToInt( parser ); + bbox->xMax = T1_ToInt( parser ); + bbox->yMax = T1_ToInt( parser ); + } + + + static void + t42_parse_font_matrix( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Matrix* matrix = &face->type1.font_matrix; + FT_Vector* offset = &face->type1.font_offset; + FT_Face root = (FT_Face)&face->root; + FT_Fixed temp[6]; + FT_Fixed temp_scale; + + + (void)T1_ToFixedArray( parser, 6, temp, 3 ); + + temp_scale = ABS( temp[3] ); + + /* Set Units per EM based on FontMatrix values. We set the value to */ + /* 1000 / temp_scale, because temp_scale was already multiplied by */ + /* 1000 (in t1_tofixed, from psobjs.c). */ + + root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, + temp_scale ) >> 16 ); + + /* we need to scale the values by 1.0/temp_scale */ + if ( temp_scale != 0x10000L ) { + temp[0] = FT_DivFix( temp[0], temp_scale ); + temp[1] = FT_DivFix( temp[1], temp_scale ); + temp[2] = FT_DivFix( temp[2], temp_scale ); + temp[4] = FT_DivFix( temp[4], temp_scale ); + temp[5] = FT_DivFix( temp[5], temp_scale ); + temp[3] = 0x10000L; + } + + matrix->xx = temp[0]; + matrix->yx = temp[1]; + matrix->xy = temp[2]; + matrix->yy = temp[3]; + + /* note that the offsets must be expressed in integer font units */ + offset->x = temp[4] >> 16; + offset->y = temp[5] >> 16; + } + + + static void + t42_parse_encoding( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Byte* cur = parser->root.cursor; + FT_Byte* limit = parser->root.limit; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + + /* skip whitespace */ + while ( t42_is_space( *cur ) ) + { + cur++; + if ( cur >= limit ) + { + FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + return; + } + } + + /* if we have a number, then the encoding is an array, */ + /* and we must load it now */ + if ( (FT_Byte)( *cur - '0' ) < 10 ) + { + T1_Encoding encode = &face->type1.encoding; + FT_Int count, n; + PS_Table char_table = &loader->encoding_table; + FT_Memory memory = parser->root.memory; + FT_Error error; + + + /* read the number of entries in the encoding, should be 256 */ + count = T1_ToInt( parser ); + if ( parser->root.error ) + return; + + /* we use a T1_Table to store our charnames */ + loader->num_chars = encode->num_chars = count; + if ( FT_NEW_ARRAY( encode->char_index, count ) || + FT_NEW_ARRAY( encode->char_name, count ) || + FT_SET_ERROR( psaux->ps_table_funcs->init( + char_table, count, memory ) ) ) + { + parser->root.error = error; + return; + } + + /* We need to `zero' out encoding_table.elements */ + for ( n = 0; n < count; n++ ) + { + char* notdef = (char *)".notdef"; + + + T1_Add_Table( char_table, n, notdef, 8 ); + } + + /* Now, we will need to read a record of the form */ + /* ... charcode /charname ... for each entry in our table */ + /* */ + /* We simply look for a number followed by an immediate */ + /* name. Note that this ignores correctly the sequence */ + /* that is often seen in type1 fonts: */ + /* */ + /* 0 1 255 { 1 index exch /.notdef put } for dup */ + /* */ + /* used to clean the encoding array before anything else. */ + /* */ + /* We stop when we encounter a `def'. */ + + cur = parser->root.cursor; + limit = parser->root.limit; + n = 0; + + for ( ; cur < limit; ) + { + FT_Byte c; + + + c = *cur; + + /* we stop when we encounter a `def' */ + if ( c == 'd' && cur + 3 < limit ) + { + if ( cur[1] == 'e' && + cur[2] == 'f' && + t42_is_space( cur[-1] ) && + t42_is_space( cur[3] ) ) + { + FT_TRACE6(( "encoding end\n" )); + break; + } + } + + /* otherwise, we must find a number before anything else */ + if ( (FT_Byte)( c - '0' ) < 10 ) + { + FT_Int charcode; + + + parser->root.cursor = cur; + charcode = T1_ToInt( parser ); + cur = parser->root.cursor; + + /* skip whitespace */ + while ( cur < limit && t42_is_space( *cur ) ) + cur++; + + if ( cur < limit && *cur == '/' ) + { + /* bingo, we have an immediate name -- it must be a */ + /* character name */ + FT_Byte* cur2 = cur + 1; + FT_Int len; + + + while ( cur2 < limit && t42_is_alpha( *cur2 ) ) + cur2++; + + len = (FT_Int)( cur2 - cur - 1 ); + + parser->root.error = T1_Add_Table( char_table, charcode, + cur + 1, len + 1 ); + char_table->elements[charcode][len] = '\0'; + if ( parser->root.error ) + return; + + cur = cur2; + } + } + else + cur++; + } + + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; + } + /* Otherwise, we should have either `StandardEncoding', */ + /* `ExpertEncoding', or `ISOLatin1Encoding' */ + else + { + if ( cur + 17 < limit && + ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; + + else if ( cur + 15 < limit && + ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; + + else if ( cur + 18 < limit && + ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) + face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; + + else { + FT_ERROR(( "t42_parse_encoding: invalid token!\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + } + } + } + + + static FT_UInt + t42_hexval( FT_Byte v ) + { + FT_UInt d; + + d = (FT_UInt)( v - 'A' ); + if ( d < 6 ) + { + d += 10; + goto Exit; + } + + d = (FT_UInt)( v - 'a' ); + if ( d < 6 ) + { + d += 10; + goto Exit; + } + + d = (FT_UInt)( v - '0' ); + if ( d < 10 ) + goto Exit; + + d = 0; + + Exit: + return d; + } + + + static void + t42_parse_sfnts( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; + FT_Byte* cur = parser->root.cursor; + FT_Byte* limit = parser->root.limit; + FT_Error error; + FT_Int num_tables = 0, status; + FT_ULong count, ttf_size = 0, string_size = 0; + FT_Bool in_string = 0; + FT_Byte v = 0; + + + /* The format is `/sfnts [ <...> <...> ... ] def' */ + + while ( t42_is_space( *cur ) ) + cur++; + + if (*cur++ == '[') + { + status = 0; + count = 0; + } + else + { + FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + while ( cur < limit - 2 ) + { + while ( t42_is_space( *cur ) ) + cur++; + + switch ( *cur ) + { + case ']': + parser->root.cursor = cur++; + return; + + case '<': + in_string = 1; + string_size = 0; + cur++; + continue; + + case '>': + if ( !in_string ) + { + FT_ERROR(( "t42_parse_sfnts: found unpaired `>'!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + /* A string can have, as a last byte, */ + /* a zero byte for padding. If so, ignore it */ + if ( ( v == 0 ) && ( string_size % 2 == 1 ) ) + count--; + in_string = 0; + cur++; + continue; + + case '%': + if ( !in_string ) + { + /* Comment found; skip till end of line */ + while ( *cur != '\n' ) + cur++; + continue; + } + else + { + FT_ERROR(( "t42_parse_sfnts: found `%' in string!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + default: + if ( !ft_xdigit( *cur ) || !ft_xdigit( *(cur + 1) ) ) + { + FT_ERROR(( "t42_parse_sfnts: found non-hex characters in string" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + v = (FT_Byte)( 16 * t42_hexval( cur[0] ) + t42_hexval( cur[1] ) ); + cur += 2; + string_size++; + } + + switch ( status ) + { + case 0: /* The '[' was read, so load offset table, 12 bytes */ + if ( count < 12 ) + { + face->ttf_data[count++] = v; + continue; + } + else + { + num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; + status = 1; + ttf_size = 12 + 16 * num_tables; + + if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) + goto Fail; + } + /* No break, fall-through */ + + case 1: /* The offset table is read; read now the table directory */ + if ( count < ttf_size ) + { + face->ttf_data[count++] = v; + continue; + } + else + { + int i; + FT_ULong len; + + + for ( i = 0; i < num_tables; i++ ) + { + FT_Byte* p = face->ttf_data + 12 + 16*i + 12; + + len = FT_PEEK_ULONG( p ); + + /* Pad to a 4-byte boundary length */ + ttf_size += ( len + 3 ) & ~3; + } + + status = 2; + face->ttf_size = ttf_size; + + if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, + ttf_size + 1 ) ) + goto Fail; + } + /* No break, fall-through */ + + case 2: /* We are reading normal tables; just swallow them */ + face->ttf_data[count++] = v; + + } + } + + /* If control reaches this point, the format was not valid */ + error = T42_Err_Invalid_File_Format; + + Fail: + parser->root.error = error; + } + + + static void + t42_parse_charstrings( T42_Face face, + T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + PS_Table code_table = &loader->charstrings; + PS_Table name_table = &loader->glyph_names; + FT_Memory memory = parser->root.memory; + FT_Error error; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Byte* cur; + FT_Byte* limit = parser->root.limit; + FT_Int n; + + + loader->num_glyphs = T1_ToInt( parser ); + if ( parser->root.error ) + return; + + /* initialize tables */ + + error = psaux->ps_table_funcs->init( code_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + error = psaux->ps_table_funcs->init( name_table, + loader->num_glyphs, + memory ); + if ( error ) + goto Fail; + + n = 0; + + for (;;) + { + /* the format is simple: */ + /* `/glyphname' + index + def */ + /* */ + /* note that we stop when we find an `end' */ + /* */ + T1_Skip_Spaces( parser ); + + cur = parser->root.cursor; + if ( cur >= limit ) + break; + + /* we stop when we find an `end' keyword */ + if ( *cur == 'e' && + cur + 3 < limit && + cur[1] == 'n' && + cur[2] == 'd' ) + break; + + if ( *cur != '/' ) + T1_Skip_Alpha( parser ); + else + { + FT_Byte* cur2 = cur + 1; + FT_Int len; + + + while ( cur2 < limit && t42_is_alpha( *cur2 ) ) + cur2++; + len = (FT_Int)( cur2 - cur - 1 ); + + error = T1_Add_Table( name_table, n, cur + 1, len + 1 ); + if ( error ) + goto Fail; + + /* add a trailing zero to the name table */ + name_table->elements[n][len] = '\0'; + + parser->root.cursor = cur2; + T1_Skip_Spaces( parser ); + + cur2 = cur = parser->root.cursor; + if ( cur >= limit ) + break; + + while ( cur2 < limit && t42_is_alpha( *cur2 ) ) + cur2++; + len = (FT_Int)( cur2 - cur ); + + error = T1_Add_Table( code_table, n, cur, len + 1 ); + if ( error ) + goto Fail; + + code_table->elements[n][len] = '\0'; + + n++; + if ( n >= loader->num_glyphs ) + break; + } + } + + /* Index 0 must be a .notdef element */ + if ( ft_strcmp( (char *)name_table->elements[0], ".notdef" ) ) + { + FT_ERROR(( "t42_parse_charstrings: Index 0 is not `.notdef'!\n" )); + error = T42_Err_Invalid_File_Format; + goto Fail; + } + + loader->num_glyphs = n; + return; + + Fail: + parser->root.error = error; + } + + + static FT_Error + t42_load_keyword( T42_Face face, + T42_Loader loader, + T1_Field field ) + { + FT_Error error; + void* dummy_object; + void** objects; + FT_UInt max_objects = 0; + + + /* if the keyword has a dedicated callback, call it */ + if ( field->type == T1_FIELD_TYPE_CALLBACK ) { + field->reader( (FT_Face)face, loader ); + error = loader->parser.root.error; + goto Exit; + } + + /* now, the keyword is either a simple field, or a table of fields; */ + /* we are now going to take care of it */ + switch ( field->location ) + { + case T1_FIELD_LOCATION_FONT_INFO: + dummy_object = &face->type1.font_info; + objects = &dummy_object; + break; + + default: + dummy_object = &face->type1; + objects = &dummy_object; + } + + if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || + field->type == T1_FIELD_TYPE_FIXED_ARRAY ) + error = T1_Load_Field_Table( &loader->parser, field, + objects, max_objects, 0 ); + else + error = T1_Load_Field( &loader->parser, field, + objects, max_objects, 0 ); + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ) + { + T42_Parser parser = &loader->parser; + FT_Byte* cur = base; + FT_Byte* limit = cur + size; + FT_UInt n_keywords = sizeof ( t42_keywords ) / + sizeof ( t42_keywords[0] ); + + + parser->root.cursor = base; + parser->root.limit = base + size; + parser->root.error = 0; + + for ( ; cur < limit; cur++ ) + { + /* look for `FontDirectory', which causes problems on some fonts */ + if ( *cur == 'F' && cur + 25 < limit && + ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) + { + FT_Byte* cur2; + + + /* skip the `FontDirectory' keyword */ + cur += 13; + cur2 = cur; + + /* lookup the `known' keyword */ + while ( cur < limit && *cur != 'k' && + ft_strncmp( (char*)cur, "known", 5 ) ) + cur++; + + if ( cur < limit ) + { + T1_TokenRec token; + + + /* skip the `known' keyword and the token following it */ + cur += 5; + loader->parser.root.cursor = cur; + T1_ToToken( &loader->parser, &token ); + + /* if the last token was an array, skip it! */ + if ( token.type == T1_TOKEN_TYPE_ARRAY ) + cur2 = parser->root.cursor; + } + cur = cur2; + } + /* look for immediates */ + else if ( *cur == '/' && cur + 2 < limit ) + { + FT_Byte* cur2; + FT_UInt i, len; + + + cur++; + cur2 = cur; + while ( cur2 < limit && t42_is_alpha( *cur2 ) ) + cur2++; + + len = (FT_UInt)( cur2 - cur ); + if ( len > 0 && len < 22 ) /* XXX What shall it this 22? */ + { + /* now, compare the immediate name to the keyword table */ + + /* Loop through all known keywords */ + for ( i = 0; i < n_keywords; i++ ) + { + T1_Field keyword = (T1_Field)&t42_keywords[i]; + FT_Byte *name = (FT_Byte*)keyword->ident; + + + if ( !name ) + continue; + + if ( ( len == ft_strlen( (const char *)name ) ) && + ( ft_memcmp( cur, name, len ) == 0 ) ) + { + /* we found it -- run the parsing callback! */ + parser->root.cursor = cur2; + T1_Skip_Spaces( parser ); + parser->root.error = t42_load_keyword(face, + loader, + keyword ); + if ( parser->root.error ) + return parser->root.error; + cur = parser->root.cursor; + break; + } + } + } + } + } + return parser->root.error; + } + + + FT_LOCAL_DEF( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ) + { + FT_UNUSED( face ); + + FT_MEM_ZERO( loader, sizeof ( *loader ) ); + loader->num_glyphs = 0; + loader->num_chars = 0; + + /* initialize the tables -- simply set their `init' field to 0 */ + loader->encoding_table.init = 0; + loader->charstrings.init = 0; + loader->glyph_names.init = 0; + } + + + FT_LOCAL_DEF( void ) + t42_loader_done( T42_Loader loader ) + { + T42_Parser parser = &loader->parser; + + + /* finalize tables */ + T1_Release_Table( &loader->encoding_table ); + T1_Release_Table( &loader->charstrings ); + T1_Release_Table( &loader->glyph_names ); + + /* finalize parser */ + t42_parser_done( parser ); + } + + +/* END */ diff --git a/lib/freetype/src/type42/t42parse.h b/lib/freetype/src/type42/t42parse.h new file mode 100644 index 0000000..9bcb657 --- /dev/null +++ b/lib/freetype/src/type42/t42parse.h @@ -0,0 +1,89 @@ +/***************************************************************************/ +/* */ +/* t42parse.h */ +/* */ +/* Type 42 font parser (specification). */ +/* */ +/* Copyright 2002 by Roberto Alameda. */ +/* */ +/* 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 __T42PARSE_H__ +#define __T42PARSE_H__ + + +#include "t42objs.h" +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + typedef struct T42_ParserRec_ + { + PS_ParserRec root; + FT_Stream stream; + + FT_Byte* base_dict; + FT_Int base_len; + + FT_Byte in_memory; + + } T42_ParserRec, *T42_Parser; + + + typedef struct T42_Loader_ + { + T42_ParserRec parser; /* parser used to read the stream */ + + FT_Int num_chars; /* number of characters in encoding */ + PS_TableRec encoding_table; /* PS_Table used to store the */ + /* encoding character names */ + + FT_Int num_glyphs; + PS_TableRec glyph_names; + PS_TableRec charstrings; + + } T42_LoaderRec, *T42_Loader; + + + FT_LOCAL( FT_Error ) + t42_parser_init( T42_Parser parser, + FT_Stream stream, + FT_Memory memory, + PSAux_Service psaux ); + + FT_LOCAL( void ) + t42_parser_done( T42_Parser parser ); + + + FT_LOCAL( FT_Error ) + t42_parse_dict( T42_Face face, + T42_Loader loader, + FT_Byte* base, + FT_Long size ); + + + FT_LOCAL( void ) + t42_loader_init( T42_Loader loader, + T42_Face face ); + + FT_LOCAL( void ) + t42_loader_done( T42_Loader loader ); + + + /* */ + +FT_END_HEADER + + +#endif /* __T42PARSE_H__ */ + + +/* END */ diff --git a/lib/freetype/src/type42/type42.c b/lib/freetype/src/type42/type42.c new file mode 100644 index 0000000..d13df56 --- /dev/null +++ b/lib/freetype/src/type42/type42.c @@ -0,0 +1,25 @@ +/***************************************************************************/ +/* */ +/* type42.c */ +/* */ +/* FreeType Type 42 driver component. */ +/* */ +/* Copyright 2002 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. */ +/* */ +/***************************************************************************/ + +#define FT_MAKE_OPTION_SINGLE_OBJECT + +#include +#include "t42objs.c" +#include "t42parse.c" +#include "t42drivr.c" + +/* END */ diff --git a/lib/freetype/src/winfonts/Jamfile b/lib/freetype/src/winfonts/Jamfile new file mode 100644 index 0000000..a903f89 --- /dev/null +++ b/lib/freetype/src/winfonts/Jamfile @@ -0,0 +1,8 @@ +# FreeType 2 src/winfonts Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP $(FT2_SRC_DIR) winfonts ; + +Library $(FT2_LIB) : winfnt.c ; + +# end of src/winfonts Jamfile diff --git a/lib/freetype/src/winfonts/descrip.mms b/lib/freetype/src/winfonts/descrip.mms new file mode 100644 index 0000000..475cdbb --- /dev/null +++ b/lib/freetype/src/winfonts/descrip.mms @@ -0,0 +1,23 @@ +# +# FreeType 2 Windows FNT/FON driver compilation rules for VMS +# + + +# Copyright 2001, 2002 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. + + +CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.include],[--.src.winfonts]) + +OBJS=winfnt.obj + +all : $(OBJS) + library [--.lib]freetype.olb $(OBJS) + +# EOF diff --git a/lib/freetype/src/winfonts/fnterrs.h b/lib/freetype/src/winfonts/fnterrs.h new file mode 100644 index 0000000..ea80909 --- /dev/null +++ b/lib/freetype/src/winfonts/fnterrs.h @@ -0,0 +1,41 @@ +/***************************************************************************/ +/* */ +/* fnterrs.h */ +/* */ +/* Win FNT/FON error codes (specification only). */ +/* */ +/* Copyright 2001 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 define the Windows FNT/FON error enumeration */ + /* constants. */ + /* */ + /*************************************************************************/ + +#ifndef __FNTERRS_H__ +#define __FNTERRS_H__ + +#include FT_MODULE_ERRORS_H + +#undef __FTERRORS_H__ + +#define FT_ERR_PREFIX FNT_Err_ +#define FT_ERR_BASE FT_Mod_Err_Winfonts + +#include FT_ERRORS_H + +#endif /* __FNTERRS_H__ */ + + +/* END */ diff --git a/lib/freetype/src/winfonts/module.mk b/lib/freetype/src/winfonts/module.mk new file mode 100644 index 0000000..99be845 --- /dev/null +++ b/lib/freetype/src/winfonts/module.mk @@ -0,0 +1,21 @@ +# +# FreeType 2 Windows FNT/FON module definition +# + + +# Copyright 1996-2000 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. + + +make_module_list: add_windows_driver + +add_windows_driver: + $(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) + $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) + diff --git a/lib/freetype/src/winfonts/rules.mk b/lib/freetype/src/winfonts/rules.mk new file mode 100644 index 0000000..994eef8 --- /dev/null +++ b/lib/freetype/src/winfonts/rules.mk @@ -0,0 +1,65 @@ +# +# FreeType 2 Windows FNT/FON driver configuration rules +# + + +# Copyright 1996-2000, 2001 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. + + +# Windows driver directory +# +FNT_DIR := $(SRC_)winfonts +FNT_DIR_ := $(FNT_DIR)$(SEP) + + +FNT_COMPILE := $(FT_COMPILE) $I$(FNT_DIR) + + +# Windows driver sources (i.e., C files) +# +FNT_DRV_SRC := $(FNT_DIR_)winfnt.c + +# Windows driver headers +# +FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) \ + $(FNT_DIR_)fnterrs.h + + +# Windows driver object(s) +# +# FNT_DRV_OBJ_M is used during `multi' builds +# FNT_DRV_OBJ_S is used during `single' builds +# +FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR_)%.c=$(OBJ_)%.$O) +FNT_DRV_OBJ_S := $(OBJ_)winfnt.$O + +# Windows driver source file for single build +# +FNT_DRV_SRC_S := $(FNT_DIR_)winfnt.c + + +# Windows driver - single object +# +$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) + $(FNT_COMPILE) $T$@ $(FNT_DRV_SRC_S) + + +# Windows driver - multiple objects +# +$(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H) + $(FNT_COMPILE) $T$@ $< + + +# update main driver object lists +# +DRV_OBJS_S += $(FNT_DRV_OBJ_S) +DRV_OBJS_M += $(FNT_DRV_OBJ_M) + +# EOF diff --git a/lib/freetype/src/winfonts/winfnt.c b/lib/freetype/src/winfonts/winfnt.c new file mode 100644 index 0000000..a82f5eb --- /dev/null +++ b/lib/freetype/src/winfonts/winfnt.c @@ -0,0 +1,689 @@ +/***************************************************************************/ +/* */ +/* winfnt.c */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2001, 2002 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 FT_WINFONTS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_FNT_TYPES_H + +#include "winfnt.h" + +#include "fnterrs.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_winfnt + + + static + const FT_Frame_Field winmz_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinMZ_HeaderRec + + FT_FRAME_START( 64 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 29 * 2 ), + FT_FRAME_ULONG_LE ( lfanew ), + FT_FRAME_END + }; + + static + const FT_Frame_Field winne_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WinNE_HeaderRec + + FT_FRAME_START( 40 ), + FT_FRAME_USHORT_LE ( magic ), + FT_FRAME_SKIP_BYTES( 34 ), + FT_FRAME_USHORT_LE ( resource_tab_offset ), + FT_FRAME_USHORT_LE ( rname_tab_offset ), + FT_FRAME_END + }; + + static + const FT_Frame_Field winfnt_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE FT_WinFNT_HeaderRec + + FT_FRAME_START( 146 ), + FT_FRAME_USHORT_LE( version ), + FT_FRAME_ULONG_LE ( file_size ), + FT_FRAME_BYTES ( copyright, 60 ), + FT_FRAME_USHORT_LE( file_type ), + FT_FRAME_USHORT_LE( nominal_point_size ), + FT_FRAME_USHORT_LE( vertical_resolution ), + FT_FRAME_USHORT_LE( horizontal_resolution ), + FT_FRAME_USHORT_LE( ascent ), + FT_FRAME_USHORT_LE( internal_leading ), + FT_FRAME_USHORT_LE( external_leading ), + FT_FRAME_BYTE ( italic ), + FT_FRAME_BYTE ( underline ), + FT_FRAME_BYTE ( strike_out ), + FT_FRAME_USHORT_LE( weight ), + FT_FRAME_BYTE ( charset ), + FT_FRAME_USHORT_LE( pixel_width ), + FT_FRAME_USHORT_LE( pixel_height ), + FT_FRAME_BYTE ( pitch_and_family ), + FT_FRAME_USHORT_LE( avg_width ), + FT_FRAME_USHORT_LE( max_width ), + FT_FRAME_BYTE ( first_char ), + FT_FRAME_BYTE ( last_char ), + FT_FRAME_BYTE ( default_char ), + FT_FRAME_BYTE ( break_char ), + FT_FRAME_USHORT_LE( bytes_per_row ), + FT_FRAME_ULONG_LE ( device_offset ), + FT_FRAME_ULONG_LE ( face_name_offset ), + FT_FRAME_ULONG_LE ( bits_pointer ), + FT_FRAME_ULONG_LE ( bits_offset ), + FT_FRAME_BYTE ( reserved ), + FT_FRAME_ULONG_LE ( flags ), + FT_FRAME_USHORT_LE( A_space ), + FT_FRAME_USHORT_LE( B_space ), + FT_FRAME_USHORT_LE( C_space ), + FT_FRAME_USHORT_LE( color_table_offset ), + FT_FRAME_BYTES ( reserved1, 16 ), + FT_FRAME_END + }; + + + static void + fnt_font_done( FNT_Font font, + FT_Stream stream ) + { + if ( font->fnt_frame ) + FT_FRAME_RELEASE( font->fnt_frame ); + + font->fnt_size = 0; + font->fnt_frame = 0; + } + + + static FT_Error + fnt_font_load( FNT_Font font, + FT_Stream stream ) + { + FT_Error error; + FT_WinFNT_Header header = &font->header; + + + /* first of all, read the FNT header */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) ) + goto Exit; + + /* check header */ + if ( header->version != 0x200 && + header->version != 0x300 ) + { + FT_TRACE2(( "[not a valid FNT file]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + /* Version 2 doesn't have these fields */ + if ( header->version == 0x200 ) + { + header->flags = 0; + header->A_space = 0; + header->B_space = 0; + header->C_space = 0; + + header->color_table_offset = 0; + } + + if ( header->file_type & 1 ) + { + FT_TRACE2(( "[can't handle vector FNT fonts]\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + /* small fixup -- some fonts have the `pixel_width' field set to 0 */ + if ( header->pixel_width == 0 ) + header->pixel_width = header->pixel_height; + + /* this is a FNT file/table, we now extract its frame */ + if ( FT_STREAM_SEEK( font->offset ) || + FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) ) + goto Exit; + + Exit: + return error; + } + + + static void + fnt_face_done_fonts( FNT_Face face ) + { + FT_Memory memory = FT_FACE( face )->memory; + FT_Stream stream = FT_FACE( face )->stream; + FNT_Font cur = face->fonts; + FNT_Font limit = cur + face->num_fonts; + + + for ( ; cur < limit; cur++ ) + fnt_font_done( cur, stream ); + + FT_FREE( face->fonts ); + face->num_fonts = 0; + } + + + static FT_Error + fnt_face_get_dll_fonts( FNT_Face face ) + { + FT_Error error; + FT_Stream stream = FT_FACE( face )->stream; + FT_Memory memory = FT_FACE( face )->memory; + WinMZ_HeaderRec mz_header; + + + face->fonts = 0; + face->num_fonts = 0; + + /* does it begin with a MZ header? */ + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) + goto Exit; + + error = FNT_Err_Unknown_File_Format; + if ( mz_header.magic == WINFNT_MZ_MAGIC ) + { + /* yes, now look for a NE header in the file */ + WinNE_HeaderRec ne_header; + + + if ( FT_STREAM_SEEK( mz_header.lfanew ) || + FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) ) + goto Exit; + + error = FNT_Err_Unknown_File_Format; + if ( ne_header.magic == WINFNT_NE_MAGIC ) + { + /* good, now look in the resource table for each FNT resource */ + FT_ULong res_offset = mz_header.lfanew + + ne_header.resource_tab_offset; + + FT_UShort size_shift; + FT_UShort font_count = 0; + FT_ULong font_offset = 0; + + + if ( FT_STREAM_SEEK( res_offset ) || + FT_FRAME_ENTER( ne_header.rname_tab_offset - + ne_header.resource_tab_offset ) ) + goto Exit; + + size_shift = FT_GET_USHORT_LE(); + + for (;;) + { + FT_UShort type_id, count; + + + type_id = FT_GET_USHORT_LE(); + if ( !type_id ) + break; + + count = FT_GET_USHORT_LE(); + + if ( type_id == 0x8008 ) + { + font_count = count; + font_offset = (FT_ULong)( FT_STREAM_POS() + 4 + + ( stream->cursor - stream->limit ) ); + break; + } + + stream->cursor += 4 + count * 12; + } + FT_FRAME_EXIT(); + + if ( !font_count || !font_offset ) + { + FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); + error = FNT_Err_Unknown_File_Format; + goto Exit; + } + + if ( FT_STREAM_SEEK( font_offset ) || + FT_NEW_ARRAY( face->fonts, font_count ) ) + goto Exit; + + face->num_fonts = font_count; + + if ( FT_FRAME_ENTER( (FT_Long)font_count * 12 ) ) + goto Exit; + + /* now read the offset and position of each FNT font */ + { + FNT_Font cur = face->fonts; + FNT_Font limit = cur + font_count; + + + for ( ; cur < limit; cur++ ) + { + cur->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + cur->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift; + cur->size_shift = size_shift; + stream->cursor += 8; + } + } + FT_FRAME_EXIT(); + + /* finally, try to load each font there */ + { + FNT_Font cur = face->fonts; + FNT_Font limit = cur + font_count; + + + for ( ; cur < limit; cur++ ) + { + error = fnt_font_load( cur, stream ); + if ( error ) + goto Fail; + } + } + } + } + + Fail: + if ( error ) + fnt_face_done_fonts( face ); + + Exit: + return error; + } + + + + typedef struct FNT_CMapRec_ + { + FT_CMapRec cmap; + FT_UInt32 first; + FT_UInt32 count; + + } FNT_CMapRec, *FNT_CMap; + + + static FT_Error + fnt_cmap_init( FNT_CMap cmap ) + { + FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap ); + FNT_Font font = face->fonts; + + + cmap->first = (FT_UInt32) font->header.first_char; + cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 ); + + return 0; + } + + + static FT_UInt + fnt_cmap_char_index( FNT_CMap cmap, + FT_UInt32 char_code ) + { + FT_UInt gindex = 0; + + + char_code -= cmap->first; + if ( char_code < cmap->count ) + gindex = char_code + 1; + + return gindex; + } + + + static FT_UInt + fnt_cmap_char_next( FNT_CMap cmap, + FT_UInt32 *pchar_code ) + { + FT_UInt gindex = 0; + FT_UInt32 result = 0; + FT_UInt32 char_code = *pchar_code + 1; + + + if ( char_code <= cmap->first ) + { + result = cmap->first; + gindex = 1; + } + else + { + char_code -= cmap->first; + if ( char_code < cmap->count ) + { + result = cmap->first + char_code; + gindex = char_code + 1; + } + } + + *pchar_code = result; + return gindex; + } + + + static FT_CMap_ClassRec fnt_cmap_class_rec = + { + sizeof ( FNT_CMapRec ), + + (FT_CMap_InitFunc) fnt_cmap_init, + (FT_CMap_DoneFunc) NULL, + (FT_CMap_CharIndexFunc)fnt_cmap_char_index, + (FT_CMap_CharNextFunc) fnt_cmap_char_next + }; + + static FT_CMap_Class fnt_cmap_class = &fnt_cmap_class_rec; + + + + static void + FNT_Face_Done( FNT_Face face ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + + + fnt_face_done_fonts( face ); + + FT_FREE( face->root.available_sizes ); + face->root.num_fixed_sizes = 0; + } + + + static FT_Error + FNT_Face_Init( FT_Stream stream, + FNT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ) + { + FT_Error error; + FT_Memory memory = FT_FACE_MEMORY( face ); + + FT_UNUSED( num_params ); + FT_UNUSED( params ); + FT_UNUSED( face_index ); + + + /* try to load several fonts from a DLL */ + error = fnt_face_get_dll_fonts( face ); + if ( error ) + { + /* this didn't work, now try to load a single FNT font */ + FNT_Font font; + + + if ( FT_NEW( face->fonts ) ) + goto Exit; + + face->num_fonts = 1; + font = face->fonts; + + font->offset = 0; + font->fnt_size = stream->size; + + error = fnt_font_load( font, stream ); + if ( error ) + goto Fail; + } + + /* all right, one or more fonts were loaded; we now need to */ + /* fill the root FT_Face fields with relevant information */ + { + FT_Face root = FT_FACE( face ); + FNT_Font fonts = face->fonts; + FNT_Font limit = fonts + face->num_fonts; + FNT_Font cur; + + + root->num_faces = 1; + root->face_flags = FT_FACE_FLAG_FIXED_SIZES | + FT_FACE_FLAG_HORIZONTAL; + + if ( fonts->header.avg_width == fonts->header.max_width ) + root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; + + if ( fonts->header.italic ) + root->style_flags |= FT_STYLE_FLAG_ITALIC; + + if ( fonts->header.weight >= 800 ) + root->style_flags |= FT_STYLE_FLAG_BOLD; + + /* Setup the `fixed_sizes' array */ + if ( FT_NEW_ARRAY( root->available_sizes, face->num_fonts ) ) + goto Fail; + + root->num_fixed_sizes = face->num_fonts; + + { + FT_Bitmap_Size* size = root->available_sizes; + + + for ( cur = fonts; cur < limit; cur++, size++ ) + { + size->width = cur->header.pixel_width; + size->height = cur->header.pixel_height; + } + } + + { + FT_CharMapRec charmap; + + charmap.encoding = FT_ENCODING_UNICODE; + charmap.platform_id = 3; + charmap.encoding_id = 1; + charmap.face = root; + + error = FT_CMap_New( fnt_cmap_class, + NULL, + &charmap, + NULL ); + if ( error ) + goto Fail; + + /* Select default charmap */ + if ( root->num_charmaps ) + root->charmap = root->charmaps[0]; + } + + /* setup remaining flags */ + root->num_glyphs = fonts->header.last_char - + fonts->header.first_char + 1; + + root->family_name = (FT_String*)fonts->fnt_frame + + fonts->header.face_name_offset; + root->style_name = (char *)"Regular"; + + if ( root->style_flags & FT_STYLE_FLAG_BOLD ) + { + if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Bold Italic"; + else + root->style_name = (char *)"Bold"; + } + else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) + root->style_name = (char *)"Italic"; + } + + Fail: + if ( error ) + FNT_Face_Done( face ); + + Exit: + return error; + } + + + static FT_Error + FNT_Size_Set_Pixels( FNT_Size size ) + { + /* look up a font corresponding to the current pixel size */ + FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); + FNT_Font cur = face->fonts; + FNT_Font limit = cur + face->num_fonts; + + + size->font = 0; + for ( ; cur < limit; cur++ ) + { + /* we only compare the character height, as fonts used some strange */ + /* values */ + if ( cur->header.pixel_height == size->root.metrics.y_ppem ) + { + size->font = cur; + + size->root.metrics.ascender = cur->header.ascent * 64; + size->root.metrics.descender = ( cur->header.pixel_height - + cur->header.ascent ) * 64; + size->root.metrics.height = cur->header.pixel_height * 64; + break; + } + } + + return ( size->font ? FNT_Err_Ok : FNT_Err_Invalid_Pixel_Size ); + } + + + static FT_Error + FNT_Load_Glyph( FT_GlyphSlot slot, + FNT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FNT_Font font = size->font; + FT_Error error = 0; + FT_Byte* p; + FT_Int len; + FT_Bitmap* bitmap = &slot->bitmap; + FT_ULong offset; + FT_Bool new_format; + + FT_UNUSED( slot ); + FT_UNUSED( load_flags ); + + + if ( !font ) + { + error = FNT_Err_Invalid_Argument; + goto Exit; + } + + if ( glyph_index > 0 ) + glyph_index--; + else + glyph_index = font->header.default_char - font->header.first_char; + + new_format = FT_BOOL( font->header.version == 0x300 ); + len = new_format ? 6 : 4; + + /* jump to glyph entry */ + p = font->fnt_frame + ( new_format ? 146 : 118 ) + len * glyph_index; + + bitmap->width = FT_NEXT_SHORT_LE( p ); + + if ( new_format ) + offset = FT_NEXT_ULONG_LE( p ); + else + offset = FT_NEXT_USHORT_LE( p ); + + /* jump to glyph data */ + p = font->fnt_frame + /* font->header.bits_offset */ + offset; + + /* allocate and build bitmap */ + { + FT_Int pitch = ( bitmap->width + 7 ) >> 3; + + + bitmap->pitch = pitch; + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + /* note: we don't allocate a new buffer for the bitmap since we */ + /* already store the images in the FT_Face */ + ft_glyphslot_set_bitmap( slot, p ); + } + + slot->bitmap_left = 0; + slot->bitmap_top = font->header.ascent; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + /* now set up metrics */ + slot->metrics.horiAdvance = bitmap->width << 6; + slot->metrics.horiBearingX = 0; + slot->metrics.horiBearingY = slot->bitmap_top << 6; + + slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; + slot->format = FT_GLYPH_FORMAT_BITMAP; + + Exit: + return error; + } + + + FT_CALLBACK_TABLE_DEF + const FT_Driver_ClassRec winfnt_driver_class = + { + { + ft_module_font_driver, + sizeof ( FT_DriverRec ), + + "winfonts", + 0x10000L, + 0x20000L, + + 0, + + (FT_Module_Constructor)0, + (FT_Module_Destructor) 0, + (FT_Module_Requester) 0 + }, + + sizeof( FNT_FaceRec ), + sizeof( FNT_SizeRec ), + sizeof( FT_GlyphSlotRec ), + + (FT_Face_InitFunc) FNT_Face_Init, + (FT_Face_DoneFunc) FNT_Face_Done, + (FT_Size_InitFunc) 0, + (FT_Size_DoneFunc) 0, + (FT_Slot_InitFunc) 0, + (FT_Slot_DoneFunc) 0, + + (FT_Size_ResetPointsFunc) FNT_Size_Set_Pixels, + (FT_Size_ResetPixelsFunc) FNT_Size_Set_Pixels, + (FT_Slot_LoadFunc) FNT_Load_Glyph, + + (FT_Face_GetKerningFunc) 0, + (FT_Face_AttachFunc) 0, + (FT_Face_GetAdvancesFunc) 0 + }; + + +/* END */ diff --git a/lib/freetype/src/winfonts/winfnt.h b/lib/freetype/src/winfonts/winfnt.h new file mode 100644 index 0000000..4ba85e0 --- /dev/null +++ b/lib/freetype/src/winfonts/winfnt.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* winfnt.h */ +/* */ +/* FreeType font driver for Windows FNT/FON files */ +/* */ +/* Copyright 1996-2001, 2002 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 __WINFNT_H__ +#define __WINFNT_H__ + + +#include +#include FT_INTERNAL_DRIVER_H + + +FT_BEGIN_HEADER + + + FT_EXPORT_VAR( const FT_Driver_ClassRec ) winfnt_driver_class; + + +FT_END_HEADER + + +#endif /* __WINFNT_H__ */ + + +/* END */ diff --git a/lib/freetype/tests/Jamfile b/lib/freetype/tests/Jamfile new file mode 100644 index 0000000..0470922 --- /dev/null +++ b/lib/freetype/tests/Jamfile @@ -0,0 +1,41 @@ +# FreeType 2 src Jamfile (c) 2001 David Turner +# + +SubDir FT2_TOP tests ; + +test_programs = gview ; + +SubDirHdrs [ FT2_SubDir .. nirvana include ] ; + +NV_TOP = [ FT2_SubDir .. .. nirvana ] ; + +NIRVANA_LINKLIBS = $(NV_TOP)/objs/libnirvana$(SUFLIB) ; + +{ + local t ; + + for t in $(test_programs) + { + Main $(t) : $(t).c ; + + LinkLibraries $(t) : $(FT2_LIB) ; + + if $(WIN) + { + if $(TOOLSET) = MINGW + { + LINKKLIBS on $(t)$(SUFEXE) = "-luser32 -lgdi32" ; + } + else + { + LINKLIBS on $(t)$(SUFEXE) = user32.lib gdi32.lib ; + } + } + else + { + LINKLIBS on $(t)$(SUFEXE) = -L/usr/X11R6/lib -lX11 -lm ; + } + + NEEDLIBS on $(t)$(SUFEXE) += $(NIRVANA_LINKLIBS) ; + } +} diff --git a/lib/freetype/tests/gview.c b/lib/freetype/tests/gview.c new file mode 100644 index 0000000..0e76e19 --- /dev/null +++ b/lib/freetype/tests/gview.c @@ -0,0 +1,1488 @@ +#include +#include NV_VIEWPORT_H +#include + +#include +#include FT_FREETYPE_H + +/* include FreeType internals to debug hints */ +#include <../src/pshinter/pshrec.h> +#include <../src/pshinter/pshalgo1.h> +#include <../src/pshinter/pshalgo2.h> +#include <../src/pshinter/pshalgo3.h> + +#include <../src/autohint/ahtypes.h> + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ROOT DEFINITIONS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + +#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 + +static int first_glyph = 0; + +static NV_Renderer renderer; +static NV_Painter painter; +static NV_Pixmap target; +static NV_Error error; +static NV_Memory memory; +static NVV_Display display; +static NVV_Surface surface; + +static FT_Library freetype; +static FT_Face face; + + +static NV_Pos glyph_scale; +static NV_Pos glyph_org_x; +static NV_Pos glyph_org_y; +static NV_Transform glyph_transform; /* font units -> device pixels */ +static NV_Transform size_transform; /* subpixels -> device pixels */ + +static NV_Scale grid_scale = 1.0; + +static int glyph_index; +static int pixel_size = 12; + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** OPTIONS, COLORS and OTHERS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +static int option_show_axis = 1; +static int option_show_dots = 1; +static int option_show_stroke = 0; +static int option_show_glyph = 1; +static int option_show_grid = 1; +static int option_show_em = 0; +static int option_show_smooth = 1; +static int option_show_blues = 0; +static int option_show_edges = 0; +static int option_show_segments = 1; +static int option_show_links = 1; +static int option_show_indices = 0; + +static int option_show_ps_hints = 1; +static int option_show_horz_hints = 1; +static int option_show_vert_hints = 1; + + +static int option_hinting = 1; + +static char temp_message[1024]; + +static NV_Path symbol_dot = NULL; +static NV_Path symbol_circle = NULL; +static NV_Path symbol_square = NULL; +static NV_Path symbol_rect_h = NULL; +static NV_Path symbol_rect_v = NULL; + + + +#define AXIS_COLOR 0xFFFF0000 +#define GRID_COLOR 0xFFD0D0D0 +#define ON_COLOR 0xFFFF2000 +#define OFF_COLOR 0xFFFF0080 +#define STRONG_COLOR 0xFF404040 +#define INTERP_COLOR 0xFF206040 +#define SMOOTH_COLOR 0xF000B040 +#define BACKGROUND_COLOR 0xFFFFFFFF +#define TEXT_COLOR 0xFF000000 +#define EM_COLOR 0x80008000 +#define BLUES_TOP_COLOR 0x4000008F +#define BLUES_BOT_COLOR 0x40008F00 + +#define GHOST_HINT_COLOR 0xE00000FF +#define STEM_HINT_COLOR 0xE02020FF +#define STEM_JOIN_COLOR 0xE020FF20 + +#define EDGE_COLOR 0xF0704070 +#define SEGMENT_COLOR 0xF0206040 +#define LINK_COLOR 0xF0FFFF00 +#define SERIF_LINK_COLOR 0xF0FF808F + +/* print message and abort program */ +static void +Panic( const char* message ) +{ + fprintf( stderr, "PANIC: %s\n", message ); + exit(1); +} + + +static void +init_symbols( void ) +{ + nv_path_new_rectangle( renderer, -1, -1, 3, 3, 0, 0, &symbol_square ); + nv_path_new_rectangle( renderer, -1, -6, 2, 12, 0, 0, &symbol_rect_v ); + nv_path_new_rectangle( renderer, -6, -1, 12, 2, 0, 0, &symbol_rect_h ); + + nv_path_new_circle( renderer, 0, 0, 3., &symbol_dot ); + + nv_path_stroke( symbol_dot, 0.6, + nv_path_linecap_butt, + nv_path_linejoin_miter, 1., + &symbol_circle ); + + nv_path_destroy( symbol_dot ); + + nv_path_new_circle( renderer, 0, 0, 2., &symbol_dot ); + } + +static void +done_symbols( void ) +{ + nv_path_destroy( symbol_circle ); + nv_path_destroy( symbol_dot ); + nv_path_destroy( symbol_rect_v ); + nv_path_destroy( symbol_rect_h ); + nv_path_destroy( symbol_square ); +} + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** COMMON GRID DRAWING ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +static void +reset_scale( NV_Scale scale ) +{ + /* compute font units -> grid pixels scale factor */ + glyph_scale = target->width*0.75 / face->units_per_EM * scale; + + /* setup font units -> grid pixels transform */ + nv_transform_set_scale( &glyph_transform, glyph_scale, -glyph_scale ); + glyph_org_x = glyph_transform.delta.x = target->width*0.125; + glyph_org_y = glyph_transform.delta.y = target->height*0.875; + + /* setup subpixels -> grid pixels transform */ + nv_transform_set_scale( &size_transform, + glyph_scale/nv_fromfixed(face->size->metrics.x_scale), + - glyph_scale/nv_fromfixed(face->size->metrics.y_scale) ); + + size_transform.delta = glyph_transform.delta; +} + + +static void +reset_size( int pixel_size, NV_Scale scale ) +{ + FT_Set_Pixel_Sizes( face, pixel_size, pixel_size ); + reset_scale( scale ); +} + + +static void +clear_background( void ) +{ + nv_pixmap_fill_rect( target, 0, 0, target->width, target->height, + BACKGROUND_COLOR ); +} + + +static void +draw_grid( void ) +{ + int x = (int)glyph_org_x; + int y = (int)glyph_org_y; + + /* draw grid */ + if ( option_show_grid ) + { + NV_Scale min, max, x, step; + + /* draw vertical grid bars */ + step = 64. * size_transform.matrix.xx; + if (step > 1.) + { + min = max = glyph_org_x; + while ( min - step >= 0 ) min -= step; + while ( max + step < target->width ) max += step; + + for ( x = min; x <= max; x += step ) + nv_pixmap_fill_rect( target, (NV_Int)(x+.5), 0, + 1, target->height, GRID_COLOR ); + } + + /* draw horizontal grid bars */ + step = -64. * size_transform.matrix.yy; + if (step > 1.) + { + min = max = glyph_org_y; + while ( min - step >= 0 ) min -= step; + while ( max + step < target->height ) max += step; + + for ( x = min; x <= max; x += step ) + nv_pixmap_fill_rect( target, 0, (NV_Int)(x+.5), + target->width, 1, GRID_COLOR ); + } + } + + /* draw axis */ + if ( option_show_axis ) + { + nv_pixmap_fill_rect( target, x, 0, 1, target->height, AXIS_COLOR ); + nv_pixmap_fill_rect( target, 0, y, target->width, 1, AXIS_COLOR ); + } + + if ( option_show_em ) + { + NV_Path path; + NV_Path stroke; + NV_UInt units = (NV_UInt)face->units_per_EM; + + nv_path_new_rectangle( renderer, 0, 0, units, units, 0, 0, &path ); + nv_path_transform( path, &glyph_transform ); + + nv_path_stroke( path, 1.5, nv_path_linecap_butt, nv_path_linejoin_miter, + 4.0, &stroke ); + + nv_painter_set_color( painter, EM_COLOR, 256 ); + nv_painter_fill_path( painter, NULL, 0, stroke ); + + nv_path_destroy( stroke ); + nv_path_destroy( path ); + } + +} + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** POSTSCRIPT GLOBALS ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#include <../src/pshinter/pshglob.h> + +static void +draw_ps_blue_zones( void ) +{ + if ( option_show_blues && ps_debug_globals ) + { + PSH_Blues blues = &ps_debug_globals->blues; + PSH_Blue_Table table; + NV_Vector v; + FT_Int y1, y2; + FT_UInt count; + PSH_Blue_Zone zone; + + /* draw top zones */ + table = &blues->normal_top; + count = table->count; + zone = table->zones; + + for ( ; count > 0; count--, zone++ ) + { + v.x = 0; + if ( !ps_debug_no_horz_hints ) + { + v.y = zone->cur_ref + zone->cur_delta; + nv_vector_transform( &v, &size_transform ); + } + else + { + v.y = zone->org_ref + zone->org_delta; + nv_vector_transform( &v, &glyph_transform ); + } + y1 = (int)(v.y + 0.5); + + v.x = 0; + if ( !ps_debug_no_horz_hints ) + { + v.y = zone->cur_ref; + nv_vector_transform( &v, &size_transform ); + } + else + { + v.y = zone->org_ref; + nv_vector_transform( &v, &glyph_transform ); + } + y2 = (int)(v.y + 0.5); + + nv_pixmap_fill_rect( target, 0, y1, + target->width, y2-y1+1, + BLUES_TOP_COLOR ); + +#if 0 + printf( "top [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 ); +#endif + } + + + /* draw bottom zones */ + table = &blues->normal_bottom; + count = table->count; + zone = table->zones; + + for ( ; count > 0; count--, zone++ ) + { + v.x = 0; + v.y = zone->cur_ref; + nv_vector_transform( &v, &size_transform ); + y1 = (int)(v.y + 0.5); + + v.x = 0; + v.y = zone->cur_ref + zone->cur_delta; + nv_vector_transform( &v, &size_transform ); + y2 = (int)(v.y + 0.5); + + nv_pixmap_fill_rect( target, 0, y1, + target->width, y2-y1+1, + BLUES_BOT_COLOR ); + +#if 0 + printf( "bot [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 ); +#endif + } + } +} + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** POSTSCRIPT HINTER ALGORITHM 1 ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#include <../src/pshinter/pshalgo1.h> + +static int pshint_cpos = 0; +static int pshint_vertical = -1; + +static void +draw_ps1_hint( PSH1_Hint hint, FT_Bool vertical ) +{ + int x1, x2; + NV_Vector v; + + + if ( pshint_vertical != vertical ) + { + if (vertical) + pshint_cpos = 40; + else + pshint_cpos = 10; + + pshint_vertical = vertical; + } + + if (vertical) + { + if ( !option_show_vert_hints ) + return; + + v.x = hint->cur_pos; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.x + 0.5); + + v.x = hint->cur_pos + hint->cur_len; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.x + 0.5); + + nv_pixmap_fill_rect( target, x1, 0, 1, target->height, + psh1_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh1_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, x2, 0, 1, target->height, + psh1_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1, + STEM_JOIN_COLOR ); + } + else + { + if (!option_show_horz_hints) + return; + + v.y = hint->cur_pos; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.y + 0.5); + + v.y = hint->cur_pos + hint->cur_len; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.y + 0.5); + + nv_pixmap_fill_rect( target, 0, x1, target->width, 1, + psh1_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh1_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, 0, x2, target->width, 1, + psh1_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2, + STEM_JOIN_COLOR ); + } + +#if 0 + printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' ); +#endif + + pshint_cpos += 10; +} + + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** POSTSCRIPT HINTER ALGORITHM 2 ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#include <../src/pshinter/pshalgo2.h> + +static void +draw_ps2_hint( PSH2_Hint hint, FT_Bool vertical ) +{ + int x1, x2; + NV_Vector v; + + if ( pshint_vertical != vertical ) + { + if (vertical) + pshint_cpos = 40; + else + pshint_cpos = 10; + + pshint_vertical = vertical; + } + + if (vertical) + { + if ( !option_show_vert_hints ) + return; + + v.x = hint->cur_pos; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.x + 0.5); + + v.x = hint->cur_pos + hint->cur_len; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.x + 0.5); + + nv_pixmap_fill_rect( target, x1, 0, 1, target->height, + psh2_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh2_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, x2, 0, 1, target->height, + psh2_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1, + STEM_JOIN_COLOR ); + } + else + { + if (!option_show_horz_hints) + return; + + v.y = hint->cur_pos; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.y + 0.5); + + v.y = hint->cur_pos + hint->cur_len; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.y + 0.5); + + nv_pixmap_fill_rect( target, 0, x1, target->width, 1, + psh2_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh2_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, 0, x2, target->width, 1, + psh2_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2, + STEM_JOIN_COLOR ); + } + +#if 0 + printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' ); +#endif + + pshint_cpos += 10; +} + + +static void +ps2_draw_control_points( void ) +{ + if ( ps2_debug_glyph ) + { + PSH2_Glyph glyph = ps2_debug_glyph; + PSH2_Point point = glyph->points; + FT_UInt count = glyph->num_points; + NV_Transform transform, *trans = &transform; + NV_Path vert_rect; + NV_Path horz_rect; + NV_Path dot, circle; + + for ( ; count > 0; count--, point++ ) + { + NV_Vector vec; + + vec.x = point->cur_x; + vec.y = point->cur_y; + nv_vector_transform( &vec, &size_transform ); + + nv_transform_set_translate( trans, vec.x, vec.y ); + + if ( option_show_smooth && !psh2_point_is_smooth(point) ) + { + nv_painter_set_color( painter, SMOOTH_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_circle ); + } + + if (option_show_horz_hints) + { + if ( point->flags_y & PSH2_POINT_STRONG ) + { + nv_painter_set_color( painter, STRONG_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_rect_h ); + } + } + + if (option_show_vert_hints) + { + if ( point->flags_x & PSH2_POINT_STRONG ) + { + nv_painter_set_color( painter, STRONG_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_rect_v ); + } + } + } + } +} + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** POSTSCRIPT HINTER ALGORITHM 3 ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +#include <../src/pshinter/pshalgo3.h> + +static void +draw_ps3_hint( PSH3_Hint hint, FT_Bool vertical ) +{ + int x1, x2; + NV_Vector v; + + if ( pshint_vertical != vertical ) + { + if (vertical) + pshint_cpos = 40; + else + pshint_cpos = 10; + + pshint_vertical = vertical; + } + + if (!vertical) + { + if ( !option_show_vert_hints ) + return; + + v.x = hint->cur_pos; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.x + 0.5); + + v.x = hint->cur_pos + hint->cur_len; + v.y = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.x + 0.5); + + nv_pixmap_fill_rect( target, x1, 0, 1, target->height, + psh3_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh3_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, x2, 0, 1, target->height, + psh3_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, x1, pshint_cpos, x2+1-x1, 1, + STEM_JOIN_COLOR ); + } + else + { + if (!option_show_horz_hints) + return; + + v.y = hint->cur_pos; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x1 = (int)(v.y + 0.5); + + v.y = hint->cur_pos + hint->cur_len; + v.x = 0; + nv_vector_transform( &v, &size_transform ); + x2 = (int)(v.y + 0.5); + + nv_pixmap_fill_rect( target, 0, x1, target->width, 1, + psh3_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + if ( psh3_hint_is_ghost(hint) ) + { + x1 --; + x2 = x1 + 2; + } + else + nv_pixmap_fill_rect( target, 0, x2, target->width, 1, + psh3_hint_is_ghost(hint) + ? GHOST_HINT_COLOR : STEM_HINT_COLOR ); + + nv_pixmap_fill_rect( target, pshint_cpos, x2, 1, x1+1-x2, + STEM_JOIN_COLOR ); + } + +#if 0 + printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' ); +#endif + + pshint_cpos += 10; +} + + +static void +ps3_draw_control_points( void ) +{ + if ( ps3_debug_glyph ) + { + PSH3_Glyph glyph = ps3_debug_glyph; + PSH3_Point point = glyph->points; + FT_UInt count = glyph->num_points; + NV_Transform transform, *trans = &transform; + NV_Path vert_rect; + NV_Path horz_rect; + NV_Path dot, circle; + + for ( ; count > 0; count--, point++ ) + { + NV_Vector vec; + + vec.x = point->cur_x; + vec.y = point->cur_y; + nv_vector_transform( &vec, &size_transform ); + + nv_transform_set_translate( trans, vec.x, vec.y ); + + if ( option_show_smooth && !psh3_point_is_smooth(point) ) + { + nv_painter_set_color( painter, SMOOTH_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_circle ); + } + + if (option_show_horz_hints) + { + if ( point->flags_y & PSH3_POINT_STRONG ) + { + nv_painter_set_color( painter, STRONG_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_rect_h ); + } + } + + if (option_show_vert_hints) + { + if ( point->flags_x & PSH3_POINT_STRONG ) + { + nv_painter_set_color( painter, STRONG_COLOR, 256 ); + nv_painter_fill_path( painter, trans, 0, symbol_rect_v ); + } + } + } + } +} + + +static void +ps_print_hints( void ) +{ + if ( ps_debug_hints ) + { + FT_Int dimension; + PSH_Dimension dim; + + for ( dimension = 1; dimension >= 0; dimension-- ) + { + PS_Dimension dim = &ps_debug_hints->dimension[ dimension ]; + PS_Mask mask = dim->masks.masks; + FT_UInt count = dim->masks.num_masks; + + printf( "%s hints -------------------------\n", + dimension ? "vertical" : "horizontal" ); + + for ( ; count > 0; count--, mask++ ) + { + FT_UInt index; + + printf( "mask -> %d\n", mask->end_point ); + for ( index = 0; index < mask->num_bits; index++ ) + { + if ( mask->bytes[ index >> 3 ] & (0x80 >> (index & 7)) ) + { + PS_Hint hint = dim->hints.hints + index; + + printf( "%c [%3d %3d (%4d)]\n", dimension ? "v" : "h", + hint->pos, hint->pos + hint->len, hint->len ); + } + } + } + } + } +} + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** AUTOHINTER DRAWING ROUTINES *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +static NV_Path +ah_link_path( NV_Vector* p1, + NV_Vector* p4, + NV_Bool vertical ) +{ + NV_PathWriter writer; + NV_Vector p2, p3; + NV_Path path, stroke; + + if ( vertical ) + { + p2.x = p4->x; + p2.y = p1->y; + + p3.x = p1->x; + p3.y = p4->y; + } + else + { + p2.x = p1->x; + p2.y = p4->y; + + p3.x = p4->x; + p3.y = p1->y; + } + + nv_path_writer_new( renderer, &writer ); + nv_path_writer_moveto( writer, p1 ); + nv_path_writer_cubicto( writer, &p2, &p3, p4 ); + nv_path_writer_end( writer ); + + path = nv_path_writer_get_path( writer ); + nv_path_writer_destroy( writer ); + + nv_path_stroke( path, 1., nv_path_linecap_butt, nv_path_linejoin_round, 1., &stroke ); + + nv_path_destroy( path ); + + return stroke; +} + + +static void +ah_draw_smooth_points( void ) +{ + if ( ah_debug_hinter && option_show_smooth ) + { + AH_Outline glyph = ah_debug_hinter->glyph; + FT_UInt count = glyph->num_points; + AH_Point point = glyph->points; + + nv_painter_set_color( painter, SMOOTH_COLOR, 256 ); + + for ( ; count > 0; count--, point++ ) + { + if ( !( point->flags & AH_FLAG_WEAK_INTERPOLATION ) ) + { + NV_Transform transform, *trans = &transform; + NV_Vector vec; + + vec.x = point->x - ah_debug_hinter->pp1.x; + vec.y = point->y; + nv_vector_transform( &vec, &size_transform ); + + nv_transform_set_translate( &transform, vec.x, vec.y ); + nv_painter_fill_path( painter, trans, 0, symbol_circle ); + } + } + } +} + + +static void +ah_draw_edges( void ) +{ + if ( ah_debug_hinter ) + { + AH_Outline glyph = ah_debug_hinter->glyph; + FT_UInt count; + AH_Edge edge; + FT_Pos pp1 = ah_debug_hinter->pp1.x; + + nv_painter_set_color( painter, EDGE_COLOR, 256 ); + + if ( option_show_edges ) + { + /* draw vertical edges */ + if ( option_show_vert_hints ) + { + count = glyph->num_vedges; + edge = glyph->vert_edges; + for ( ; count > 0; count--, edge++ ) + { + NV_Vector vec; + NV_Pos x; + + vec.x = edge->pos - pp1; + vec.y = 0; + + nv_vector_transform( &vec, &size_transform ); + x = (FT_Pos)( vec.x + 0.5 ); + + nv_pixmap_fill_rect( target, x, 0, 1, target->height, EDGE_COLOR ); + } + } + + /* draw horizontal edges */ + if ( option_show_horz_hints ) + { + count = glyph->num_hedges; + edge = glyph->horz_edges; + for ( ; count > 0; count--, edge++ ) + { + NV_Vector vec; + NV_Pos x; + + vec.x = 0; + vec.y = edge->pos; + + nv_vector_transform( &vec, &size_transform ); + x = (FT_Pos)( vec.y + 0.5 ); + + nv_pixmap_fill_rect( target, 0, x, target->width, 1, EDGE_COLOR ); + } + } + } + + if ( option_show_segments ) + { + /* draw vertical segments */ + if ( option_show_vert_hints ) + { + AH_Segment seg = glyph->vert_segments; + FT_UInt count = glyph->num_vsegments; + + for ( ; count > 0; count--, seg++ ) + { + AH_PointRec *first, *last; + NV_Vector v1, v2; + NV_Pos y1, y2, x; + + first = seg->first; + last = seg->last; + + v1.x = v2.x = first->x - pp1; + + if ( first->y <= last->y ) + { + v1.y = first->y; + v2.y = last->y; + } + else + { + v1.y = last->y; + v2.y = first->y; + } + + nv_vector_transform( &v1, &size_transform ); + nv_vector_transform( &v2, &size_transform ); + + y1 = (NV_Pos)( v1.y + 0.5 ); + y2 = (NV_Pos)( v2.y + 0.5 ); + x = (NV_Pos)( v1.x + 0.5 ); + + nv_pixmap_fill_rect( target, x-1, y2, 3, ABS(y1-y2)+1, SEGMENT_COLOR ); + } + } + + /* draw horizontal segments */ + if ( option_show_horz_hints ) + { + AH_Segment seg = glyph->horz_segments; + FT_UInt count = glyph->num_hsegments; + + for ( ; count > 0; count--, seg++ ) + { + AH_PointRec *first, *last; + NV_Vector v1, v2; + NV_Pos y1, y2, x; + + first = seg->first; + last = seg->last; + + v1.y = v2.y = first->y; + + if ( first->x <= last->x ) + { + v1.x = first->x - pp1; + v2.x = last->x - pp1; + } + else + { + v1.x = last->x - pp1; + v2.x = first->x - pp1; + } + + nv_vector_transform( &v1, &size_transform ); + nv_vector_transform( &v2, &size_transform ); + + y1 = (NV_Pos)( v1.x + 0.5 ); + y2 = (NV_Pos)( v2.x + 0.5 ); + x = (NV_Pos)( v1.y + 0.5 ); + + nv_pixmap_fill_rect( target, y1, x-1, ABS(y1-y2)+1, 3, SEGMENT_COLOR ); + } + } + + + if ( option_show_vert_hints && option_show_links ) + { + AH_Segment seg = glyph->vert_segments; + FT_UInt count = glyph->num_vsegments; + + for ( ; count > 0; count--, seg++ ) + { + AH_Segment seg2 = NULL; + NV_Path link; + NV_Vector v1, v2; + + if ( seg->link ) + { + if ( seg->link > seg ) + seg2 = seg->link; + } + else if ( seg->serif ) + seg2 = seg->serif; + + if ( seg2 ) + { + v1.x = seg->first->x - pp1; + v2.x = seg2->first->x - pp1; + v1.y = (seg->first->y + seg->last->y)/2; + v2.y = (seg2->first->y + seg2->last->y)/2; + + link = ah_link_path( &v1, &v2, 1 ); + + nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 ); + nv_painter_fill_path( painter, &size_transform, 0, link ); + + nv_path_destroy( link ); + } + } + } + + if ( option_show_horz_hints && option_show_links ) + { + AH_Segment seg = glyph->horz_segments; + FT_UInt count = glyph->num_hsegments; + + for ( ; count > 0; count--, seg++ ) + { + AH_Segment seg2 = NULL; + NV_Path link; + NV_Vector v1, v2; + + if ( seg->link ) + { + if ( seg->link > seg ) + seg2 = seg->link; + } + else if ( seg->serif ) + seg2 = seg->serif; + + if ( seg2 ) + { + v1.y = seg->first->y; + v2.y = seg2->first->y; + v1.x = (seg->first->x + seg->last->x)/2 - pp1; + v2.x = (seg2->first->x + seg2->last->x)/2 - pp1; + + link = ah_link_path( &v1, &v2, 0 ); + + nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 ); + nv_painter_fill_path( painter, &size_transform, 0, link ); + + nv_path_destroy( link ); + } + } + } + } + } +} + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** MAIN LOOP(S) *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + +static void +draw_glyph( int glyph_index ) +{ + NV_Path path; + + pshint_vertical = -1; + + ps1_debug_hint_func = option_show_ps_hints ? draw_ps1_hint : 0; + ps2_debug_hint_func = option_show_ps_hints ? draw_ps2_hint : 0; + ps3_debug_hint_func = option_show_ps_hints ? draw_ps3_hint : 0; + + ah_debug_hinter = NULL; + + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_BITMAP ); + if (error) Panic( "could not load glyph" ); + + if ( face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) + Panic( "could not load glyph outline" ); + + error = nv_path_new_from_outline( renderer, + (NV_Outline*)&face->glyph->outline, + &size_transform, + &path ); + if (error) Panic( "could not create glyph path" ); + + /* tracé du glyphe plein */ + if ( option_show_glyph ) + { + nv_painter_set_color ( painter, 0xFF404080, 128 ); + nv_painter_fill_path ( painter, 0, 0, path ); + } + + if ( option_show_stroke ) + { + NV_Path stroke; + + error = nv_path_stroke( path, 0.6, + nv_path_linecap_butt, + nv_path_linejoin_miter, + 1.0, &stroke ); + if (error) Panic( "could not stroke glyph path" ); + + nv_painter_set_color ( painter, 0xFF000040, 256 ); + nv_painter_fill_path ( painter, 0, 0, stroke ); + + nv_path_destroy( stroke ); + } + + /* tracé des points de controle */ + if ( option_show_dots ) + { + NV_Path plot; + NV_Outline out; + NV_Scale r = 2; + NV_Int n, first, last; + + nv_path_get_outline( path, NULL, memory, &out ); + + first = 0; + for ( n = 0; n < out.n_contours; n++ ) + { + int m; + NV_Transform trans; + NV_Color color; + NV_SubVector* vec; + + last = out.contours[n]; + + for ( m = first; m <= last; m++ ) + { + color = (out.tags[m] & FT_CURVE_TAG_ON) + ? ON_COLOR + : OFF_COLOR; + + vec = out.points + m; + + nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 ); + + nv_painter_set_color( painter, color, 256 ); + nv_painter_fill_path( painter, &trans, 0, symbol_dot ); + + if ( option_show_indices ) + { + char temp[5]; + + sprintf( temp, "%d", m ); + nv_pixmap_cell_text( target, vec->x/64 + 4, vec->y/64 - 4, + temp, TEXT_COLOR ); + } + } + + first = last + 1; + } + } + + ah_draw_smooth_points(); + ah_draw_edges(); + + nv_path_destroy( path ); + + /* autre infos */ + { + char temp[1024]; + char temp2[64]; + + sprintf( temp, "font name : %s (%s)", face->family_name, face->style_name ); + nv_pixmap_cell_text( target, 0, 0, temp, TEXT_COLOR ); + + FT_Get_Glyph_Name( face, glyph_index, temp2, 63 ); + temp2[63] = 0; + + sprintf( temp, "glyph %4d: %s", glyph_index, temp2 ); + nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR ); + + if ( temp_message[0] ) + { + nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR ); + temp_message[0] = 0; + } + } +} + + + +#define TOGGLE_OPTION(var,prefix) \ + { \ + var = !var; \ + sprintf( temp_message, prefix " is now %s", \ + var ? "on" : "off" ); \ + break; \ + } + + +#define TOGGLE_OPTION_NEG(var,prefix) \ + { \ + var = !var; \ + sprintf( temp_message, prefix " is now %s", \ + !var ? "on" : "off" ); \ + break; \ + } + + +static void +handle_event( NVV_EventRec* ev ) +{ + switch (ev->key) + { + case NVV_Key_Left: + { + if ( glyph_index > 0 ) + glyph_index--; + break; + } + + case NVV_Key_Right: + { + if ( glyph_index+1 < face->num_glyphs ) + glyph_index++; + break; + } + + case NVV_KEY('x'): + TOGGLE_OPTION( option_show_axis, "grid axis display" ) + + case NVV_KEY('s'): + TOGGLE_OPTION( option_show_stroke, "glyph stroke display" ) + + case NVV_KEY('g'): + TOGGLE_OPTION( option_show_glyph, "glyph fill display" ) + + case NVV_KEY('d'): + TOGGLE_OPTION( option_show_dots, "control points display" ) + + case NVV_KEY('e'): + TOGGLE_OPTION( option_show_em, "EM square display" ) + + case NVV_KEY('+'): + { + grid_scale *= 1.2; + reset_scale( grid_scale ); + break; + } + + case NVV_KEY('-'): + { + if (grid_scale > 0.3) + { + grid_scale /= 1.2; + reset_scale( grid_scale ); + } + break; + } + + case NVV_Key_Up: + { + pixel_size++; + reset_size( pixel_size, grid_scale ); + sprintf( temp_message, "pixel size = %d", pixel_size ); + break; + } + + case NVV_Key_Down: + { + if (pixel_size > 1) + { + pixel_size--; + reset_size( pixel_size, grid_scale ); + sprintf( temp_message, "pixel size = %d", pixel_size ); + } + break; + } + + case NVV_KEY('z'): + TOGGLE_OPTION_NEG( ps_debug_no_vert_hints, "vertical hints processing" ) + + case NVV_KEY('a'): + TOGGLE_OPTION_NEG( ps_debug_no_horz_hints, "horizontal hints processing" ) + + case NVV_KEY('Z'): + TOGGLE_OPTION( option_show_vert_hints, "vertical hints display" ) + + case NVV_KEY('A'): + TOGGLE_OPTION( option_show_horz_hints, "horizontal hints display" ) + + case NVV_KEY('S'): + TOGGLE_OPTION( option_show_smooth, "smooth points display" ); + + case NVV_KEY('i'): + TOGGLE_OPTION( option_show_indices, "point index display" ); + + case NVV_KEY('b'): + TOGGLE_OPTION( option_show_blues, "blue zones display" ); + + case NVV_KEY('h'): + ps_debug_no_horz_hints = option_hinting; + ps_debug_no_vert_hints = option_hinting; + + TOGGLE_OPTION( option_hinting, "hinting" ) + + case NVV_KEY('H'): + ps_print_hints(); + break; + + default: + ; + } +} + + + +static void +usage() +{ + Panic( "no usage" ); +} + + +#define OPTION1(n,code) \ + case n : \ + code \ + argc--; \ + argv++; \ + break; + +#define OPTION2(n,code) \ + case n : \ + code \ + argc -= 2; \ + argv += 2; \ + break; + + +static void +parse_options( int* argc_p, char*** argv_p ) +{ + int argc = *argc_p; + char** argv = *argv_p; + + while (argc > 2 && argv[1][0] == '-') + { + switch (argv[1][1]) + { + OPTION2( 'f', first_glyph = atoi( argv[2] ); ) + + OPTION2( 's', pixel_size = atoi( argv[2] ); ) + + default: + usage(); + } + } + + *argc_p = argc; + *argv_p = argv; +} + + + +int main( int argc, char** argv ) +{ + char* filename = "/winnt/fonts/arial.ttf"; + + parse_options( &argc, &argv ); + + if ( argc >= 2 ) + filename = argv[1]; + + + /* create library */ + error = nv_renderer_new( 0, &renderer ); + if (error) Panic( "could not create Nirvana renderer" ); + + memory = nv_renderer_get_memory( renderer ); + init_symbols(); + + error = nvv_display_new( renderer, &display ); + if (error) Panic( "could not create display" ); + + error = nvv_surface_new( display, 460, 460, nv_pixmap_type_argb, &surface ); + if (error) Panic( "could not create surface" ); + + target = nvv_surface_get_pixmap( surface ); + + error = nv_painter_new( renderer, &painter ); + if (error) Panic( "could not create painter" ); + + nv_painter_set_target( painter, target ); + + clear_background(); + + error = FT_Init_FreeType( &freetype ); + if (error) Panic( "could not initialise FreeType" ); + + error = FT_New_Face( freetype, filename, 0, &face ); + if (error) Panic( "could not open font face" ); + + reset_size( pixel_size, grid_scale ); + + + nvv_surface_set_title( surface, "FreeType Glyph Viewer" ); + + { + NVV_EventRec event; + + glyph_index = first_glyph; + for ( ;; ) + { + clear_background(); + draw_grid(); + + ps_debug_hints = 0; + ah_debug_hinter = 0; + + ah_debug_disable_vert = ps_debug_no_vert_hints; + ah_debug_disable_horz = ps_debug_no_horz_hints; + + draw_ps_blue_zones(); + draw_glyph( glyph_index ); + ps3_draw_control_points(); + + nvv_surface_refresh( surface, NULL ); + + nvv_surface_listen( surface, 0, &event ); + if ( event.key == NVV_Key_Esc ) + break; + + handle_event( &event ); + switch (event.key) + { + case NVV_Key_Esc: + goto Exit; + + default: + ; + } + } + } + + Exit: + /* wait for escape */ + + + /* destroy display (and surface) */ + nvv_display_unref( display ); + + done_symbols(); + nv_renderer_unref( renderer ); + + return 0; +} diff --git a/lib/fslib/vfatlib/.cvsignore b/lib/fslib/vfatlib/.cvsignore new file mode 100755 index 0000000..c071072 --- /dev/null +++ b/lib/fslib/vfatlib/.cvsignore @@ -0,0 +1,4 @@ +vfatlib.a +*.d +*.o +*.sym diff --git a/lib/fslib/vfatlib/Makefile b/lib/fslib/vfatlib/Makefile new file mode 100755 index 0000000..8234010 --- /dev/null +++ b/lib/fslib/vfatlib/Makefile @@ -0,0 +1,14 @@ +# $Id$ + +PATH_TO_TOP = ../../.. + +TARGET_TYPE = library + +TARGET_NAME = vfatlib + +TARGET_OBJECTS = \ + vfatlib.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/lib/fslib/vfatlib/vfatlib.c b/lib/fslib/vfatlib/vfatlib.c new file mode 100755 index 0000000..c35b8d3 --- /dev/null +++ b/lib/fslib/vfatlib/vfatlib.c @@ -0,0 +1,530 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VFAT filesystem library + * FILE: vfatlib.c + * PURPOSE: Main API + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISIONS: + * CSH 05/04-2003 Created + */ +#define NDEBUG +#include +#define NTOS_MODE_USER +#include +#include +#include +#include "vfatlib.h" + + +static ULONG +GetShiftCount(ULONG Value) +{ + ULONG i = 1; + while (Value > 0) + { + i++; + Value /= 2; + } + return i - 2; +} + + +NTSTATUS +VfatInitialize() +{ + DPRINT("VfatInitialize()\n"); + + return STATUS_SUCCESS; +} + +static NTSTATUS +VfatWriteBootSector(IN HANDLE FileHandle, + IN PFAT32_BOOT_SECTOR BootSector) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + NTSTATUS Status; + PUCHAR NewBootSector; + LARGE_INTEGER FileOffset; + + /* Allocate buffer for new bootsector */ + NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(), + 0, + SECTORSIZE); + if (NewBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Zero the new bootsector */ + memset(NewBootSector, 0, SECTORSIZE); + + /* Copy FAT32 BPB to new bootsector */ + memcpy((NewBootSector + 3), + &BootSector->OEMName[0], + 87); /* FAT32 BPB length (up to (not including) Res2) */ + + /* Write sector 0 */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector); + return(Status); + } + + /* Write backup boot sector */ + if (BootSector->BootBackup != 0x0000) + { + FileOffset.QuadPart = (ULONGLONG)((ULONG) BootSector->BootBackup * SECTORSIZE); + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector); + return(Status); + } + } + + /* Free the new boot sector */ + RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector); + + return(Status); +} + + +static NTSTATUS +VfatWriteFsInfo(IN HANDLE FileHandle, + IN PFAT32_BOOT_SECTOR BootSector) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + NTSTATUS Status; + PFAT32_FSINFO FsInfo; + LARGE_INTEGER FileOffset; + + /* Allocate buffer for new sector */ + FsInfo = (PFAT32_FSINFO)RtlAllocateHeap(RtlGetProcessHeap(), + 0, + BootSector->BytesPerSector); + if (FsInfo == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Zero the new sector */ + memset(FsInfo, 0, BootSector->BytesPerSector); + + FsInfo->LeadSig = 0x41615252; + FsInfo->StrucSig = 0x61417272; + FsInfo->FreeCount = 0xffffffff; + FsInfo->NextFree = 0xffffffff; + + /* Write sector */ + FileOffset.QuadPart = BootSector->FSInfoSector * BootSector->BytesPerSector; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FsInfo, + BootSector->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo); + return(Status); + } + + /* Free the new sector buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo); + + return(Status); +} + + +static NTSTATUS +VfatWriteFAT(IN HANDLE FileHandle, + ULONG SectorOffset, + IN PFAT32_BOOT_SECTOR BootSector) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + NTSTATUS Status; + PUCHAR Buffer; + LARGE_INTEGER FileOffset; + ULONG i; + + /* Allocate buffer */ + Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(), + 0, + BootSector->BytesPerSector); + if (Buffer == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Zero the buffer */ + memset(Buffer, 0, BootSector->BytesPerSector); + + /* FAT cluster 0 */ + Buffer[0] = 0xf8; /* Media type */ + Buffer[1] = 0xff; + Buffer[2] = 0xff; + Buffer[3] = 0xff; + /* FAT cluster 1 */ + Buffer[4] = 0xcf; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */ + Buffer[5] = 0xff; + Buffer[6] = 0xff; + Buffer[7] = 0xf7; + /* FAT cluster 2 */ + Buffer[8] = 0xff; /* End of root directory */ + Buffer[9] = 0xff; + Buffer[10] = 0xff; + Buffer[11] = 0x0f; + + /* Write first sector of the FAT */ + FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BootSector->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + return(Status); + } + + /* Zero the buffer */ + memset(Buffer, 0, BootSector->BytesPerSector); + + /* Zero the rest of the FAT */ + for (i = 1; i < BootSector->FATSectors32 - 1; i++) + { + /* Zero one sector of the FAT */ + FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BootSector->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + return(Status); + } + } + + /* Free the buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + + return(Status); +} + + +static NTSTATUS +VfatWriteRootDirectory(IN HANDLE FileHandle, + IN PFAT32_BOOT_SECTOR BootSector) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; + PUCHAR Buffer; + LARGE_INTEGER FileOffset; + ULONGLONG FirstDataSector; + ULONGLONG FirstRootDirSector; + + /* Allocate buffer for the cluster */ + Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(), + 0, + BootSector->SectorsPerCluster * BootSector->BytesPerSector); + if (Buffer == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Zero the buffer */ + memset(Buffer, 0, BootSector->SectorsPerCluster * BootSector->BytesPerSector); + + DPRINT("BootSector->ReservedSectors = %lu\n", BootSector->ReservedSectors); + DPRINT("BootSector->FATSectors32 = %lu\n", BootSector->FATSectors32); + DPRINT("BootSector->RootCluster = %lu\n", BootSector->RootCluster); + DPRINT("BootSector->SectorsPerCluster = %lu\n", BootSector->SectorsPerCluster); + + /* Write cluster */ + FirstDataSector = BootSector->ReservedSectors + + (BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */; + + DPRINT("FirstDataSector = %lu\n", FirstDataSector); + + FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector; + FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector; + + DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector); + DPRINT("FileOffset = %lu\n", FileOffset.QuadPart); + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BootSector->SectorsPerCluster * BootSector->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + return(Status); + } + + /* Free the buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + + return(Status); +} + + +NTSTATUS +VfatFormat( + PUNICODE_STRING DriveRoot, + DWORD MediaFlag, + PUNICODE_STRING Label, + BOOL QuickFormat, + DWORD ClusterSize, + PFMIFSCALLBACK Callback) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + DISK_GEOMETRY DiskGeometry; + IO_STATUS_BLOCK Iosb; + HANDLE FileHandle; + SCSI_ADDRESS ScsiAddress; + PARTITION_INFORMATION PartitionInfo; + FAT32_BOOT_SECTOR BootSector; + ANSI_STRING VolumeLabel; + NTSTATUS Status; + ULONG RootDirSectors; + ULONG TmpVal1; + ULONG TmpVal2; + + DPRINT("VfatFormat(DriveRoot '%S')\n", DriveRoot->Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + DriveRoot, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status); + return Status; + } + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_GEOMETRY, + NULL, + 0, + &DiskGeometry, + sizeof(DISK_GEOMETRY)); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + if (DiskGeometry.MediaType == FixedMedia) + { + DPRINT("Cylinders %d\n", DiskGeometry.Cylinders.QuadPart); + DPRINT("TracksPerCylinder %d\n", DiskGeometry.TracksPerCylinder); + DPRINT("SectorsPerTrack %d\n", DiskGeometry.SectorsPerTrack); + DPRINT("BytesPerSector %d\n", DiskGeometry.BytesPerSector); + DPRINT("DiskSize %d\n", + DiskGeometry.Cylinders.QuadPart * + (ULONGLONG)DiskGeometry.TracksPerCylinder * + (ULONGLONG)DiskGeometry.SectorsPerTrack * + (ULONGLONG)DiskGeometry.BytesPerSector); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_PARTITION_INFO, + NULL, + 0, + &PartitionInfo, + sizeof(PARTITION_INFORMATION)); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_GET_PARTITION_INFO failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType); + DPRINT("StartingOffset %d\n", PartitionInfo.StartingOffset); + DPRINT("PartitionLength %d\n", PartitionInfo.PartitionLength); + DPRINT("HiddenSectors %d\n", PartitionInfo.HiddenSectors); + DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber); + DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator); + DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition); + DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition); + } + else + { + DPRINT1("FIXME: Removable media is not supported\n"); + NtClose(FileHandle); + return Status; + } + + memset(&BootSector, 0, sizeof(FAT32_BOOT_SECTOR)); + memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8); + BootSector.BytesPerSector = DiskGeometry.BytesPerSector; + BootSector.SectorsPerCluster = 4096 / BootSector.BytesPerSector; // 4KB clusters /* FIXME: */ + BootSector.ReservedSectors = 32; + BootSector.FATCount = 2; + BootSector.RootEntries = 0; + BootSector.Sectors = 0; + BootSector.Media = 0xf8; + BootSector.FATSectors = 0; + BootSector.SectorsPerTrack = DiskGeometry.SectorsPerTrack; + BootSector.Heads = DiskGeometry.TracksPerCylinder; + BootSector.HiddenSectors = 63; /* FIXME: */ + BootSector.SectorsHuge = PartitionInfo.PartitionLength.QuadPart >> + GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */ + BootSector.FATSectors32 = 0; /* Set later */ + BootSector.ExtFlag = 0; /* Mirror all FATs */ + BootSector.FSVersion = 0x0000; /* 0:0 */ + BootSector.RootCluster = 2; + BootSector.FSInfoSector = 1; + BootSector.BootBackup = 6; + BootSector.Drive = 0xff; /* No BIOS boot drive available */ //0x80; /* FIXME: */ + BootSector.ExtBootSignature = 0x29; + BootSector.VolumeID = 0x45768798; /* FIXME: */ + if ((Label == NULL) || (Label->Buffer == NULL)) + { + memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11); + } + else + { + RtlUnicodeStringToAnsiString(&VolumeLabel, Label, TRUE); + memset(&BootSector.VolumeLabel[0], ' ', 11); + memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer, + VolumeLabel.Length < 11 ? VolumeLabel.Length : 11); + RtlFreeAnsiString(&VolumeLabel); + } + memcpy(&BootSector.SysType[0], "FAT32 ", 8); + + RootDirSectors = ((BootSector.RootEntries * 32) + + (BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector; + TmpVal1 = BootSector.SectorsHuge - (BootSector.ReservedSectors + RootDirSectors); + TmpVal2 = (256 * BootSector.SectorsPerCluster) + BootSector.FATCount; + if (TRUE /* FAT32 */) + { + TmpVal2 /= 2; + BootSector.FATSectors = 0; + BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2; + } + + Status = VfatWriteBootSector(FileHandle, + &BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT("VfatWriteBootSector() failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + Status = VfatWriteFsInfo(FileHandle, + &BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT("VfatWriteFsInfo() failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + /* Write first FAT copy */ + Status = VfatWriteFAT(FileHandle, + 0, + &BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT("VfatWriteFAT() failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + /* Write second FAT copy */ + Status = VfatWriteFAT(FileHandle, + BootSector.FATSectors32, + &BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT("VfatWriteFAT() failed with status 0x%.08x.\n", Status); + NtClose(FileHandle); + return Status; + } + + Status = VfatWriteRootDirectory(FileHandle, + &BootSector); + if (!NT_SUCCESS(Status)) + { + DPRINT("VfatWriteRootDirectory() failed with status 0x%.08x\n", Status); + NtClose(FileHandle); + return Status; + } + + NtClose(FileHandle); + + DPRINT("VfatFormat() done. Status 0x%.08x\n", Status); + + return Status; +} + + +NTSTATUS +VfatCleanup() +{ + DPRINT("VfatCleanup()\n"); + + return STATUS_SUCCESS; +} diff --git a/lib/fslib/vfatlib/vfatlib.h b/lib/fslib/vfatlib/vfatlib.h new file mode 100755 index 0000000..c5acfb3 --- /dev/null +++ b/lib/fslib/vfatlib/vfatlib.h @@ -0,0 +1,57 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VFAT filesystem library + * FILE: vfatlib.h + */ +#define NDEBUG +#include +#define NTOS_MODE_USER +#include +#include + +#define SECTORSIZE 512 + +typedef struct _FAT32_BOOT_SECTOR +{ + unsigned char magic0; // 0 + unsigned char res0; // 1 + unsigned char magic1; // 2 + unsigned char OEMName[8]; // 3 + unsigned short BytesPerSector; // 11 + unsigned char SectorsPerCluster; // 13 + unsigned short ReservedSectors; // 14 + unsigned char FATCount; // 16 + unsigned short RootEntries; // 17 + unsigned short Sectors; // 19 + unsigned char Media; // 21 + unsigned short FATSectors; // 22 + unsigned short SectorsPerTrack; // 24 + unsigned short Heads; // 22 + unsigned long HiddenSectors; // 24 + unsigned long SectorsHuge; // 28 + unsigned long FATSectors32; // 36 + unsigned short ExtFlag; // 40 + unsigned short FSVersion; // 42 + unsigned long RootCluster; // 44 + unsigned short FSInfoSector; // 48 + unsigned short BootBackup; // 50 + unsigned char Res3[12]; // 52 + unsigned char Drive; // 64 + unsigned char Res4; // 65 + unsigned char ExtBootSignature; // 66 + unsigned long VolumeID; // 67 + unsigned char VolumeLabel[11]; // 71 + unsigned char SysType[8]; // 82 + unsigned char Res2[418]; // 90 + unsigned long Signature1; // 508 +} __attribute__((packed)) FAT32_BOOT_SECTOR, *PFAT32_BOOT_SECTOR; + +typedef struct _FAT32_FSINFO +{ + unsigned int LeadSig; // 0 + unsigned char Res1[480]; // 4 + unsigned int StrucSig; // 484 + unsigned int FreeCount; // 488 + unsigned int NextFree; // 492 + unsigned int Res2; // 496 +} __attribute__((packed)) FAT32_FSINFO, *PFAT32_FSINFO; diff --git a/lib/gdi32/main/.cvsignore b/lib/gdi32/main/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/gdi32/main/.cvsignore +++ b/lib/gdi32/main/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/gdi32/makefile b/lib/gdi32/makefile index bf1fe50..78a1f62 100644 --- a/lib/gdi32/makefile +++ b/lib/gdi32/makefile @@ -18,23 +18,30 @@ TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a -TARGET_OBJECTS = $(TARGET_NAME).o +MAIN_OBJECTS = main/dllmain.o -TARGET_CLEAN = main/*.o misc/*.o objects/*.o +MISC_OBJECTS = misc/stubs.o misc/stubsa.o misc/stubsw.o misc/win32k.o -include $(PATH_TO_TOP)/rules.mak +OBJECTS_OBJECTS = \ + objects/dc.o \ + objects/line.o \ + objects/pen.o \ + objects/bitblt.o \ + objects/text.o \ + objects/region.o \ + objects/brush.o \ + objects/fillshap.o -include $(TOOLS_PATH)/helper.mk +TARGET_OBJECTS = $(MAIN_OBJECTS) $(MISC_OBJECTS) $(OBJECTS_OBJECTS) -MAIN_OBJECTS = main/dllmain.o +DEP_OBJECTS = $(TARGET_OBJECTS) -MISC_OBJECTS = misc/stubs.o misc/stubsa.o misc/stubsw.o misc/win32k.o +DEP_EXCLUDE_FILTER = misc/win32k.% -OBJECTS_OBJECTS = objects/dc.o objects/line.o objects/pen.o objects/bitblt.o objects/text.o objects/region.o objects/brush.o +include $(PATH_TO_TOP)/rules.mak -OBJECTS = $(MAIN_OBJECTS) $(MISC_OBJECTS) $(OBJECTS_OBJECTS) +include $(TOOLS_PATH)/helper.mk -$(TARGET_NAME).o: $(OBJECTS) - $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o +include $(TOOLS_PATH)/depend.mk # EOF diff --git a/lib/gdi32/misc/.cvsignore b/lib/gdi32/misc/.cvsignore index 397312b..ce71ca0 100644 --- a/lib/gdi32/misc/.cvsignore +++ b/lib/gdi32/misc/.cvsignore @@ -1,2 +1,3 @@ win32k.c *.o +.*.d diff --git a/lib/gdi32/misc/stubs.c b/lib/gdi32/misc/stubs.c index 8c52686..dbe4789 100644 --- a/lib/gdi32/misc/stubs.c +++ b/lib/gdi32/misc/stubs.c @@ -665,17 +665,6 @@ GetPixelFormat( -int -STDCALL -GetPolyFillMode( - HDC a0 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - BOOL STDCALL @@ -1255,18 +1244,6 @@ SetPixelFormat( -int -STDCALL -SetPolyFillMode( - HDC a0, - int a1 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - BOOL STDCALL @@ -2091,48 +2068,6 @@ DPtoLP( BOOL STDCALL -LPtoDP( - HDC a0, - LPPOINT a1, - int a2 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - - -BOOL -STDCALL -Polygon( - HDC a0, - CONST POINT *a1, - int a2 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - - -BOOL -STDCALL -Polyline( - HDC a0, - CONST POINT *a1, - int a2 - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - - -BOOL -STDCALL PolyBezier( HDC a0, CONST POINT *a1, diff --git a/lib/gdi32/misc/stubsa.c b/lib/gdi32/misc/stubsa.c index ab5ce9f..a325ebd 100644 --- a/lib/gdi32/misc/stubsa.c +++ b/lib/gdi32/misc/stubsa.c @@ -238,7 +238,7 @@ APIENTRY GetOutlineTextMetricsA( HDC a0, UINT a1, - LPOUTLINETEXTMETRIC a2 + LPOUTLINETEXTMETRICA a2 ) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); diff --git a/lib/gdi32/misc/stubsw.c b/lib/gdi32/misc/stubsw.c index 77d382b..95b6fc3 100644 --- a/lib/gdi32/misc/stubsw.c +++ b/lib/gdi32/misc/stubsw.c @@ -236,7 +236,7 @@ APIENTRY GetOutlineTextMetricsW( HDC a0, UINT a1, - LPOUTLINETEXTMETRIC a2 + LPOUTLINETEXTMETRICW a2 ) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); diff --git a/lib/gdi32/objects/.cvsignore b/lib/gdi32/objects/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/gdi32/objects/.cvsignore +++ b/lib/gdi32/objects/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/gdi32/objects/dc.c b/lib/gdi32/objects/dc.c index 47d2dba..326cb44 100644 --- a/lib/gdi32/objects/dc.c +++ b/lib/gdi32/objects/dc.c @@ -20,6 +20,14 @@ GetClipBox(HDC hDc, LPRECT Rect) return(W32kGetClipBox(hDc, Rect)); } +int +STDCALL +GetPolyFillMode( + HDC a0 + ) +{ + return W32kGetPolyFillMode(a0); +} HDC STDCALL @@ -197,4 +205,24 @@ RealizePalette( } +BOOL +STDCALL +LPtoDP( + HDC a0, + LPPOINT a1, + int a2 + ) +{ + return W32kLPtoDP(a0, a1, a2); +} + +int +STDCALL +SetPolyFillMode( + HDC a0, + int a1 + ) +{ + return W32kSetPolyFillMode(a0, a1); +} diff --git a/lib/gdi32/objects/fillshap.c b/lib/gdi32/objects/fillshap.c new file mode 100644 index 0000000..f8192b1 --- /dev/null +++ b/lib/gdi32/objects/fillshap.c @@ -0,0 +1,29 @@ +#ifdef UNICODE +#undef UNICODE +#endif + +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include + +BOOL +STDCALL +Polygon(HDC hDC, + CONST POINT *lpPoints, + int nCount) +{ + return W32kPolygon(hDC, (CONST PPOINT)lpPoints, nCount); +} + +BOOL +STDCALL +Rectangle(HDC hDC, + int LeftRect, + int TopRect, + int RightRect, + int BottomRect) +{ + return W32kRectangle(hDC, LeftRect, TopRect, RightRect, BottomRect); +} + diff --git a/lib/gdi32/objects/line.c b/lib/gdi32/objects/line.c index abb9ec6..7c456d3 100644 --- a/lib/gdi32/objects/line.c +++ b/lib/gdi32/objects/line.c @@ -23,12 +23,7 @@ MoveToEx(HDC hDC, int X, int Y, LPPOINT Point) BOOL STDCALL -Rectangle(HDC hDC, - int LeftRect, - int TopRect, - int RightRect, - int BottomRect) +Polyline( HDC hdc, CONST POINT *lppt, int cPoints ) { - // MOVE to fillshap.c - return W32kRectangle(hDC, LeftRect, TopRect, RightRect, BottomRect); + return W32kPolyline(hdc, (CONST LPPOINT) lppt, cPoints); } diff --git a/lib/gdi32/objects/text.c b/lib/gdi32/objects/text.c index b0e9390..3a9977e 100644 --- a/lib/gdi32/objects/text.c +++ b/lib/gdi32/objects/text.c @@ -55,17 +55,17 @@ BOOL STDCALL GetTextMetricsA( HDC hdc, - LPTEXTMETRIC tm + LPTEXTMETRICA tm ) { - return W32kGetTextMetrics(hdc, tm); + return W32kGetTextMetrics(hdc, (LPTEXTMETRICW) tm); } BOOL STDCALL GetTextMetricsW( HDC hdc, - LPTEXTMETRIC tm + LPTEXTMETRICW tm ) { return W32kGetTextMetrics(hdc, tm); @@ -152,20 +152,20 @@ ExtTextOutW( HFONT STDCALL CreateFontIndirectA( - CONST LOGFONT *lf + CONST LOGFONTA *lf ) { ANSI_STRING StringA; UNICODE_STRING StringU; HFONT ret; - LOGFONT tlf; + LOGFONTW tlf; RtlInitAnsiString(&StringA, (LPSTR)lf->lfFaceName); RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE); - memcpy(&tlf, lf, sizeof(LOGFONT)); + memcpy(&tlf, lf, sizeof(LOGFONTA)); memcpy(&tlf.lfFaceName, &StringU.Buffer, StringU.Length); - ret = CreateFontIndirectW((CONST LOGFONT *)&lf); + ret = CreateFontIndirectW(&tlf); RtlFreeUnicodeString(&StringU); @@ -175,10 +175,10 @@ CreateFontIndirectA( HFONT STDCALL CreateFontIndirectW( - CONST LOGFONT *lf + CONST LOGFONTW *lf ) { - return W32kCreateFontIndirect((CONST LPLOGFONT)lf); + return W32kCreateFontIndirect((CONST LPLOGFONTW)lf); } HFONT diff --git a/lib/iphlpapi/makefile b/lib/iphlpapi/makefile index 4bf95de..a30d9a6 100644 --- a/lib/iphlpapi/makefile +++ b/lib/iphlpapi/makefile @@ -14,6 +14,11 @@ TARGET_SDKLIBS = ntdll.a kernel32.a TARGET_OBJECTS = $(TARGET_NAME).o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + diff --git a/lib/iprtprio/makefile b/lib/iprtprio/makefile index 14403d3..66ee0c3 100644 --- a/lib/iprtprio/makefile +++ b/lib/iprtprio/makefile @@ -14,6 +14,11 @@ TARGET_SDKLIBS = ntdll.a kernel32.a TARGET_OBJECTS = $(TARGET_NAME).o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + diff --git a/lib/kernel32/.cvsignore b/lib/kernel32/.cvsignore index f16a880..b9946b3 100644 --- a/lib/kernel32/.cvsignore +++ b/lib/kernel32/.cvsignore @@ -4,6 +4,7 @@ kernel32.nostrip.dll kernel32.sym kernel32.lib kernel32.coff +errcodes.rc base.tmp junk.tmp temp.exp diff --git a/lib/kernel32/MSG00409.bin b/lib/kernel32/MSG00409.bin deleted file mode 100644 index 5ca7b783a1032ceda40e0fbe6cacc3716f39b70a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292 zcmXBPKMMhI9LMnwHh%^Yi^<w$uuk#shPy3GOfU4H)sb+NL^z5q|~E*+}SQ2!c9vfI>SE8Ick~( zX-@_vxlC+^)JlH#WK)}UL^la~|(uJC!CSB + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* FUNCTIONS *****************************************************************/ + +BOOL WINAPI DebugBreakProcess(HANDLE Process) +{ + NTSTATUS nErrCode = DbgUiIssueRemoteBreakin(Process); + + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return FALSE; + } + + return TRUE; +} + +/* EOF */ diff --git a/lib/kernel32/debug/debugger.c b/lib/kernel32/debug/debugger.c new file mode 100644 index 0000000..47dc292 --- /dev/null +++ b/lib/kernel32/debug/debugger.c @@ -0,0 +1,75 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/debug/debugger.c + * PURPOSE: Win32 Debugger API + * PROGRAMMER: ??? + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* FUNCTIONS *****************************************************************/ + +BOOL WINAPI CheckRemoteDebuggerPresent(HANDLE hProcess, PBOOL pbDebuggerPresent) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI ContinueDebugEvent +( + DWORD dwProcessId, + DWORD dwThreadId, + DWORD dwContinueStatus +) +{ + CLIENT_ID ClientId; + NTSTATUS Status; + + ClientId.UniqueProcess = (HANDLE)dwProcessId; + ClientId.UniqueThread = (HANDLE)dwThreadId; + + Status = DbgUiContinue(&ClientId, dwContinueStatus); + + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; +} + +BOOL WINAPI DebugActiveProcess(DWORD dwProcessId) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI DebugActiveProcessStop(DWORD dwProcessId) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI DebugSetProcessKillOnExit(BOOL KillOnExit) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI IsDebuggerPresent(VOID) +{ + return (WINBOOL)NtCurrentPeb()->BeingDebugged; +} + +BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT lpDebugEvent, DWORD dwMilliseconds) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/* EOF */ diff --git a/lib/kernel32/debug/output.c b/lib/kernel32/debug/output.c new file mode 100644 index 0000000..7c89577 --- /dev/null +++ b/lib/kernel32/debug/output.c @@ -0,0 +1,490 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/kernel32/debug/debugger.c + * PURPOSE: OutputDebugString() + * PROGRAMMER: KJK::Hyperion + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* FUNCTIONS *****************************************************************/ + +/* Open or create the mutex used to communicate with the debug monitor */ +HANDLE K32CreateDBMonMutex(void) +{ + static SID_IDENTIFIER_AUTHORITY siaNTAuth = SECURITY_NT_AUTHORITY; + static SID_IDENTIFIER_AUTHORITY siaWorldAuth = SECURITY_WORLD_SID_AUTHORITY; + + HANDLE hMutex; + + /* SIDs to be used in the DACL */ + PSID psidSystem = NULL; + PSID psidAdministrators = NULL; + PSID psidEveryone = NULL; + + /* buffer for the DACL */ + PVOID pDaclBuf = NULL; + + /* + minimum size of the DACL: an ACL descriptor and three ACCESS_ALLOWED_ACE + headers. We'll add the size of SIDs when we'll know it + */ + SIZE_T nDaclBufSize = + sizeof(ACL) + + ( + sizeof(ACCESS_ALLOWED_ACE) - + sizeof(((ACCESS_ALLOWED_ACE*)0)->SidStart) + ) * 3; + + /* security descriptor of the mutex */ + SECURITY_DESCRIPTOR sdMutexSecurity; + + /* attributes of the mutex object we'll create */ + SECURITY_ATTRIBUTES saMutexAttribs = + { + sizeof(saMutexAttribs), + &sdMutexSecurity, + TRUE + }; + + NTSTATUS nErrCode; + + /* first, try to open the mutex */ + hMutex = OpenMutexW + ( + SYNCHRONIZE | READ_CONTROL | MUTANT_QUERY_STATE, + TRUE, + L"DBWinMutex" + ); + + if(hMutex != NULL) + { + /* success */ + return hMutex; + } + /* error other than the mutex not being found */ + else if(GetLastError() != ERROR_FILE_NOT_FOUND) + { + /* failure */ + return NULL; + } + + /* if the mutex doesn't exist, create it */ +#if 0 /* please uncomment when GCC supports SEH */ + __try + { +#else +#define __leave goto l_Cleanup +#endif + /* first, set up the mutex security */ + /* allocate the NT AUTHORITY\SYSTEM SID */ + nErrCode = RtlAllocateAndInitializeSid + ( + &siaNTAuth, + 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &psidSystem + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* allocate the BUILTIN\Administrators SID */ + nErrCode = RtlAllocateAndInitializeSid + ( + &siaNTAuth, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &psidAdministrators + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* allocate the Everyone SID */ + nErrCode = RtlAllocateAndInitializeSid + ( + &siaWorldAuth, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &psidEveryone + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* allocate space for the SIDs too */ + nDaclBufSize += RtlLengthSid(psidSystem); + nDaclBufSize += RtlLengthSid(psidAdministrators); + nDaclBufSize += RtlLengthSid(psidEveryone); + + /* allocate the buffer for the DACL */ + pDaclBuf = GlobalAlloc(GMEM_FIXED, nDaclBufSize); + + /* failure */ + if(pDaclBuf == NULL) __leave; + + /* create the DACL */ + nErrCode = RtlCreateAcl(pDaclBuf, nDaclBufSize, ACL_REVISION); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* grant the minimum required access to Everyone */ + nErrCode = RtlAddAccessAllowedAce + ( + pDaclBuf, + ACL_REVISION, + SYNCHRONIZE | READ_CONTROL | MUTANT_QUERY_STATE, + psidEveryone + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* grant full access to BUILTIN\Administrators */ + nErrCode = RtlAddAccessAllowedAce + ( + pDaclBuf, + ACL_REVISION, + MUTANT_ALL_ACCESS, + psidAdministrators + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* grant full access to NT AUTHORITY\SYSTEM */ + nErrCode = RtlAddAccessAllowedAce + ( + pDaclBuf, + ACL_REVISION, + MUTANT_ALL_ACCESS, + psidSystem + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* create the security descriptor */ + nErrCode = RtlCreateSecurityDescriptor + ( + &sdMutexSecurity, + SECURITY_DESCRIPTOR_REVISION + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* set the descriptor's DACL to the ACL we created */ + nErrCode = RtlSetDaclSecurityDescriptor + ( + &sdMutexSecurity, + TRUE, + pDaclBuf, + FALSE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) __leave; + + /* create the mutex */ + hMutex = CreateMutexW(&saMutexAttribs, FALSE, L"DBWinMutex"); +#if 0 + } + __finally + { +#else +l_Cleanup: +#endif + /* free the buffers */ + if(pDaclBuf) GlobalFree(pDaclBuf); + if(psidEveryone) RtlFreeSid(psidEveryone); + if(psidAdministrators) RtlFreeSid(psidAdministrators); + if(psidSystem) RtlFreeSid(psidSystem); +#if 0 + } +#endif + + return hMutex; +} + +VOID WINAPI OutputDebugStringA(LPCSTR _OutputString) +{ +#if 0 +/* FIXME: this will be pointless until GCC does SEH */ + __try + { + ULONG_PTR a_nArgs[2]; + + a_nArgs[0] = (ULONG_PTR)(strlen(_OutputString) + 1); + a_nArgs[1] = (ULONG_PTR)_OutputString; + + /* send the string to the user-mode debugger */ + RaiseException(0x40010006, 0, 2, a_nArgs); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { +#endif + /* + no user-mode debugger: try the systemwide debug message monitor, or the + kernel debugger as a last resort + */ + + /* mutex used to synchronize invocations of OutputDebugString */ + static HANDLE s_hDBMonMutex = NULL; + /* true if we already attempted to open/create the mutex */ + static BOOL s_bDBMonMutexTriedOpen = FALSE; + + /* local copy of the mutex handle */ + HANDLE hDBMonMutex = s_hDBMonMutex; + /* handle to the Section of the shared buffer */ + HANDLE hDBMonBuffer = NULL; + /* + pointer to the mapped view of the shared buffer. It consist of the current + process id followed by the message string + */ + struct { DWORD ProcessId; CHAR Buffer[1]; } * pDBMonBuffer = NULL; + /* + event: signaled by the debug message monitor when OutputDebugString can write + to the shared buffer + */ + HANDLE hDBMonBufferReady = NULL; + /* + event: to be signaled by OutputDebugString when it's done writing to the + shared buffer + */ + HANDLE hDBMonDataReady = NULL; + + /* mutex not opened, and no previous attempts to open/create it */ + if(hDBMonMutex == NULL && !s_bDBMonMutexTriedOpen) + { + /* open/create the mutex */ + hDBMonMutex = K32CreateDBMonMutex(); + /* store the handle */ + s_hDBMonMutex = hDBMonMutex; + } + +#if 0 + __try + { +#endif + /* opening the mutex failed */ + if(hDBMonMutex == NULL) + { + /* remember next time */ + s_bDBMonMutexTriedOpen = TRUE; + } + /* opening the mutex succeeded */ + else + { + do + { + /* synchronize with other invocations of OutputDebugString */ + WaitForSingleObject(hDBMonMutex, INFINITE); + + /* buffer of the system-wide debug message monitor */ + hDBMonBuffer = OpenFileMappingW(SECTION_MAP_WRITE, FALSE, L"DBWIN_BUFFER"); + + /* couldn't open the buffer: send the string to the kernel debugger */ + if(hDBMonBuffer == NULL) break; + + /* map the buffer */ + pDBMonBuffer = MapViewOfFile + ( + hDBMonBuffer, + SECTION_MAP_READ | SECTION_MAP_WRITE, + 0, + 0, + 0 + ); + + /* couldn't map the buffer: send the string to the kernel debugger */ + if(pDBMonBuffer == NULL) break; + + /* open the event signaling that the buffer can be accessed */ + hDBMonBufferReady = OpenEventW(SYNCHRONIZE, FALSE, L"DBWIN_BUFFER_READY"); + + /* couldn't open the event: send the string to the kernel debugger */ + if(hDBMonBufferReady == NULL) break; + + /* open the event to be signaled when the buffer has been filled */ + hDBMonDataReady = + OpenEventW(EVENT_MODIFY_STATE, FALSE, L"DBWIN_DATA_READY"); + } + while(0); + + /* + we couldn't connect to the system-wide debug message monitor: send the + string to the kernel debugger + */ + if(hDBMonDataReady == NULL) ReleaseMutex(hDBMonMutex); + } + +#if 0 + __try +#else + do +#endif + { + /* size of the current output block */ + SIZE_T nRoundLen; + /* size of the remainder of the string */ + SIZE_T nOutputStringLen; + + for + ( + /* output the whole string */ + nOutputStringLen = strlen(_OutputString); + /* repeat until the string has been fully output */ + nOutputStringLen > 0; + /* move to the next block */ + _OutputString += nRoundLen, nOutputStringLen -= nRoundLen + ) + { + /* + we're connected to the debug monitor: write the current block to the + shared buffer + */ + if(hDBMonDataReady) + { + /* + wait a maximum of 10 seconds for the debug monitor to finish processing + the shared buffer + */ + if(WaitForSingleObject(hDBMonBufferReady, 10000) != WAIT_OBJECT_0) + { + /* timeout or failure: give up */ + break; + } + + /* write the process id into the buffer */ + pDBMonBuffer->ProcessId = GetCurrentProcessId(); + + /* write only as many bytes as they fit in the buffer */ + if(nOutputStringLen > (PAGE_SIZE - sizeof(DWORD) - 1)) + nRoundLen = PAGE_SIZE - sizeof(DWORD) - 1; + else + nRoundLen = nOutputStringLen; + + /* copy the current block into the buffer */ + memcpy(pDBMonBuffer->Buffer, _OutputString, nOutputStringLen); + + /* null-terminate the current block */ + pDBMonBuffer->Buffer[nOutputStringLen] = 0; + + /* signal that the data contains meaningful data and can be read */ + SetEvent(hDBMonDataReady); + } + /* else, send the current block to the kernel debugger */ + else + { + /* output in blocks of 512 characters */ + CHAR a_cBuffer[512]; + + /* write a maximum of 511 bytes */ + if(nOutputStringLen > (sizeof(a_cBuffer) - 1)) + nRoundLen = sizeof(a_cBuffer) - 1; + else + nRoundLen = nOutputStringLen; + + /* copy the current block */ + memcpy(a_cBuffer, _OutputString, nRoundLen); + + /* null-terminate the current block */ + a_cBuffer[nRoundLen] = 0; + + /* send the current block to the kernel debugger */ + DbgPrint("%s", a_cBuffer); + } + } + } +#if 0 + /* ignore access violations and let other exceptions fall through */ + __except + ( + (GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH + ) + { + /* string copied verbatim from Microsoft's kernel32.dll */ + DbgPrint("\nOutputDebugString faulted during output\n"); + } +#else + while(0); +#endif + +#if 0 + } + __finally + { +#endif + /* close all the still open resources */ + if(hDBMonBufferReady) CloseHandle(hDBMonBufferReady); + if(pDBMonBuffer) UnmapViewOfFile(pDBMonBuffer); + if(hDBMonBuffer) CloseHandle(hDBMonBuffer); + if(hDBMonDataReady) CloseHandle(hDBMonDataReady); + + /* leave the critical section */ + ReleaseMutex(hDBMonMutex); +#if 0 + } + } +#endif +} + +VOID WINAPI OutputDebugStringW(LPCWSTR _OutputString) +{ + UNICODE_STRING wstrOut; + ANSI_STRING strOut; + NTSTATUS nErrCode; + + /* convert the string in ANSI */ + RtlInitUnicodeString(&wstrOut, _OutputString); + nErrCode = RtlUnicodeStringToAnsiString(&strOut, &wstrOut, TRUE); + + if(!NT_SUCCESS(nErrCode)) + { + /* + Microsoft's kernel32.dll always prints something, even in case the conversion + fails + */ + OutputDebugStringA(""); + } + else + { + /* output the converted string */ + OutputDebugStringA(strOut.Buffer); + + /* free the converted string */ + RtlFreeAnsiString(&strOut); + } +} + +/* EOF */ diff --git a/lib/kernel32/errcodes.rc b/lib/kernel32/errcodes.rc deleted file mode 100644 index 482dc4f..0000000 --- a/lib/kernel32/errcodes.rc +++ /dev/null @@ -1,7 +0,0 @@ -/* This file is generated with wmc version 1.0.0 (12-Jun-2000). Do not edit! */ -/* Source : kernel32.mc */ -/* Cmdline: wmc -H ../../include/reactos/errcodes.h -o errcodes.rc kernel32.mc */ -/* Date : Tue Dec 10 02:07:21 2002 */ - -LANGUAGE 0x9, 0x1 -1 MESSAGETABLE "MSG00409.bin" diff --git a/lib/kernel32/errormsg.mak b/lib/kernel32/errormsg.mak deleted file mode 100644 index 8981ebe..0000000 --- a/lib/kernel32/errormsg.mak +++ /dev/null @@ -1,18 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../.. - -#TARGET_TYPE = dynlink - -TARGETNAME = kernel32 - -errcodes.rc: $(TARGETNAME).mc - $(MC) \ - -H $(PATH_TO_TOP)/include/reactos/errcodes.h \ - -o errcodes.rc \ - $(TARGETNAME).mc - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - diff --git a/lib/kernel32/file/cnotify.c b/lib/kernel32/file/cnotify.c index 7c065b0..e16c187 100644 --- a/lib/kernel32/file/cnotify.c +++ b/lib/kernel32/file/cnotify.c @@ -11,11 +11,14 @@ #include +#define NDEBUG +#include WINBOOL STDCALL FindCloseChangeNotification (HANDLE hChangeHandle) { - return FALSE; + NtClose(hChangeHandle); + return TRUE; } @@ -27,34 +30,34 @@ FindFirstChangeNotificationA ( DWORD dwNotifyFilter ) { -#if 0 UNICODE_STRING PathNameU; ANSI_STRING PathName; - HANDLE Result; + HANDLE hNotify; RtlInitAnsiString (&PathName, (LPSTR)lpPathName); /* convert ansi (or oem) string to unicode */ if (bIsFileApiAnsi) + { RtlAnsiStringToUnicodeString (&PathNameU, &PathName, TRUE); + } else + { RtlOemStringToUnicodeString (&PathNameU, &PathName, TRUE); + } - Result = FindFirstChangeNotificationW (PathNameU.Buffer, - bWatchSubtree, - dwNotifyFilter); + hNotify = FindFirstChangeNotificationW (PathNameU.Buffer, + bWatchSubtree, + dwNotifyFilter); - RtlFreeHeap (RtlGetProcessHeap (), - 0, - RootPathNameU.Buffer); + RtlFreeUnicodeString(&PathNameU); - return Result; -#endif + return hNotify; } @@ -66,7 +69,63 @@ FindFirstChangeNotificationW ( DWORD dwNotifyFilter ) { - return NULL; + NTSTATUS Status; + UNICODE_STRING NtPathU; + IO_STATUS_BLOCK IoStatus; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hDir; + + /* + RtlDosPathNameToNtPathName takes a fully qualified file name "C:\Projects\LoadLibrary\Debug\TestDll.dll" + and returns something like "\??\C:\Projects\LoadLibrary\Debug\TestDll.dll." + If the file name cannot be interpreted, then the routine returns STATUS_OBJECT_PATH_SYNTAX_BAD and + ends execution. + */ + + if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpPathName, + &NtPathU, + NULL, + NULL)) + { + SetLastErrorByStatus(STATUS_PATH_SYNTAX_BAD); + return INVALID_HANDLE_VALUE; + } + + InitializeObjectAttributes (&ObjectAttributes, + &NtPathU, + 0, + NULL, + NULL); + + Status = NtOpenFile (hDir, + SYNCHRONIZE|FILE_LIST_DIRECTORY, + &ObjectAttributes, + &IoStatus, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, + FILE_DIRECTORY_FILE); + + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return INVALID_HANDLE_VALUE; + } + + Status = NtNotifyChangeDirectoryFile(hDir, + NULL, + NULL, + NULL, + &IoStatus, + NULL,//Buffer, + 0,//BufferLength, + dwNotifyFilter, + bWatchSubtree); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return INVALID_HANDLE_VALUE; + } + + return hDir; } @@ -76,7 +135,26 @@ FindNextChangeNotification ( HANDLE hChangeHandle ) { - return FALSE; + IO_STATUS_BLOCK IoStatus; + NTSTATUS Status; + + Status = NtNotifyChangeDirectoryFile(hChangeHandle, + NULL, + NULL, + NULL, + &IoStatus, + NULL,//Buffer, + 0,//BufferLength, + FILE_NOTIFY_CHANGE_SECURITY,//meaningless for subsequent calls, but must contain a valid flag(s) + 0//meaningless for subsequent calls + ); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; } /* EOF */ diff --git a/lib/kernel32/file/copy.c b/lib/kernel32/file/copy.c index 52f5ffb..28e5961 100644 --- a/lib/kernel32/file/copy.c +++ b/lib/kernel32/file/copy.c @@ -175,7 +175,7 @@ SetLastWriteTime( } else { - FileBasic.LastWriteTime = LastWriteTime; + FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart; errCode = NtSetInformationFile (FileHandle, &IoStatusBlock, &FileBasic, @@ -265,8 +265,10 @@ CopyFileExW ( } else { - errCode = SetLastWriteTime(FileHandleDest, - FileBasic.LastWriteTime); + TIME t; + + t.QuadPart = FileBasic.LastWriteTime.QuadPart; + errCode = SetLastWriteTime(FileHandleDest, t); if (!NT_SUCCESS(errCode)) { SetLastErrorByStatus(errCode); diff --git a/lib/kernel32/file/create.c b/lib/kernel32/file/create.c index c6ca94e..b872b16 100644 --- a/lib/kernel32/file/create.c +++ b/lib/kernel32/file/create.c @@ -80,6 +80,8 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName, HANDLE FileHandle; NTSTATUS Status; ULONG Flags = 0; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; DPRINT("CreateFileW(lpFileName %S)\n",lpFileName); @@ -200,6 +202,46 @@ HANDLE STDCALL CreateFileW (LPCWSTR lpFileName, dwDesiredAccess |= FILE_GENERIC_EXECUTE; } + /* check for console output */ + if (0 == _wcsicmp(L"CONOUT$", lpFileName)) + { + /* FIXME: Send required access rights to Csrss */ + Request.Type = CSRSS_GET_OUTPUT_HANDLE; + Status = CsrClientCallServer(&Request, + &Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus(Status); + return INVALID_HANDLE_VALUE; + } + else + { + return Reply.Data.GetOutputHandleReply.OutputHandle; + } + } + + /* check for console input */ + if (0 == _wcsicmp(L"CONIN$", lpFileName)) + { + /* FIXME: Send required access rights to Csrss */ + Request.Type = CSRSS_GET_INPUT_HANDLE; + Status = CsrClientCallServer(&Request, + &Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus(Status); + return INVALID_HANDLE_VALUE; + } + else + { + return Reply.Data.GetInputHandleReply.InputHandle; + } + } + /* build the object attributes */ InitializeObjectAttributes( &ObjectAttributes, diff --git a/lib/kernel32/file/curdir.c b/lib/kernel32/file/curdir.c index 3f092ec..d6b928b 100644 --- a/lib/kernel32/file/curdir.c +++ b/lib/kernel32/file/curdir.c @@ -81,7 +81,7 @@ GetCurrentDirectoryW ( { ULONG Length; - Length = RtlGetCurrentDirectory_U (nBufferLength, + Length = RtlGetCurrentDirectory_U (nBufferLength * sizeof(WCHAR), lpBuffer); return (Length / sizeof (WCHAR)); diff --git a/lib/kernel32/file/dir.c b/lib/kernel32/file/dir.c index 8736996..9c08898 100644 --- a/lib/kernel32/file/dir.c +++ b/lib/kernel32/file/dir.c @@ -598,6 +598,7 @@ SearchPathW ( len * sizeof(WCHAR)); if (EnvironmentBufferW == NULL) { + SetLastError(ERROR_OUTOFMEMORY); return 0; } @@ -614,13 +615,18 @@ SearchPathW ( lpPath = EnvironmentBufferW; } - retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension, nBufferLength, lpBuffer, lpFilePart); + retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension, + nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart); if (EnvironmentBufferW != NULL) { RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW); } - return retCode; + if (retCode == 0) + { + SetLastError(ERROR_FILE_NOT_FOUND); + } + return retCode / sizeof(WCHAR); } /* EOF */ diff --git a/lib/kernel32/file/file.c b/lib/kernel32/file/file.c index 79061ad..72572f6 100644 --- a/lib/kernel32/file/file.c +++ b/lib/kernel32/file/file.c @@ -245,75 +245,72 @@ SetFilePointer(HANDLE hFile, DWORD STDCALL GetFileType(HANDLE hFile) { - FILE_FS_DEVICE_INFORMATION DeviceInfo; - IO_STATUS_BLOCK StatusBlock; - NTSTATUS Status; - - /* get real handle */ - switch ((ULONG)hFile) - { - case STD_INPUT_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdInput; - - break; - - case STD_OUTPUT_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdOutput; - - break; - - case STD_ERROR_HANDLE: - hFile = NtCurrentPeb()->ProcessParameters->hStdError; - - break; - } - - /* check console handles */ - if (IsConsoleHandle(hFile)) - { -// if (VerifyConsoleHandle(hFile)) - return FILE_TYPE_CHAR; - } - - Status = NtQueryVolumeInformationFile(hFile, - &StatusBlock, - &DeviceInfo, - sizeof(FILE_FS_DEVICE_INFORMATION), - FileFsDeviceInformation); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return FILE_TYPE_UNKNOWN; - } - - switch (DeviceInfo.DeviceType) - { - case FILE_DEVICE_CD_ROM: - case FILE_DEVICE_CD_ROM_FILE_SYSTEM: - case FILE_DEVICE_CONTROLLER: - case FILE_DEVICE_DATALINK: - case FILE_DEVICE_DFS: - case FILE_DEVICE_DISK: - case FILE_DEVICE_DISK_FILE_SYSTEM: - case FILE_DEVICE_VIRTUAL_DISK: - return FILE_TYPE_DISK; - - case FILE_DEVICE_KEYBOARD: - case FILE_DEVICE_MOUSE: - case FILE_DEVICE_NULL: - case FILE_DEVICE_PARALLEL_PORT: - case FILE_DEVICE_PRINTER: - case FILE_DEVICE_SERIAL_PORT: - case FILE_DEVICE_SCREEN: - case FILE_DEVICE_SOUND: - case FILE_DEVICE_MODEM: - return FILE_TYPE_CHAR; - - case FILE_DEVICE_NAMED_PIPE: - return FILE_TYPE_PIPE; - } - - return FILE_TYPE_UNKNOWN; + FILE_FS_DEVICE_INFORMATION DeviceInfo; + IO_STATUS_BLOCK StatusBlock; + NTSTATUS Status; + + /* Get real handle */ + switch ((ULONG)hFile) + { + case STD_INPUT_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdInput; + break; + + case STD_OUTPUT_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; + + case STD_ERROR_HANDLE: + hFile = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(hFile)) + { + if (VerifyConsoleIoHandle(hFile)) + return FILE_TYPE_CHAR; + } + + Status = NtQueryVolumeInformationFile(hFile, + &StatusBlock, + &DeviceInfo, + sizeof(FILE_FS_DEVICE_INFORMATION), + FileFsDeviceInformation); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FILE_TYPE_UNKNOWN; + } + + switch (DeviceInfo.DeviceType) + { + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + case FILE_DEVICE_CONTROLLER: + case FILE_DEVICE_DATALINK: + case FILE_DEVICE_DFS: + case FILE_DEVICE_DISK: + case FILE_DEVICE_DISK_FILE_SYSTEM: + case FILE_DEVICE_VIRTUAL_DISK: + return FILE_TYPE_DISK; + + case FILE_DEVICE_KEYBOARD: + case FILE_DEVICE_MOUSE: + case FILE_DEVICE_NULL: + case FILE_DEVICE_PARALLEL_PORT: + case FILE_DEVICE_PRINTER: + case FILE_DEVICE_SERIAL_PORT: + case FILE_DEVICE_SCREEN: + case FILE_DEVICE_SOUND: + case FILE_DEVICE_MODEM: + return FILE_TYPE_CHAR; + + case FILE_DEVICE_NAMED_PIPE: + return FILE_TYPE_PIPE; + } + + return FILE_TYPE_UNKNOWN; } @@ -526,36 +523,64 @@ GetFileAttributesA(LPCSTR lpFileName) DWORD STDCALL GetFileAttributesW(LPCWSTR lpFileName) { - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileBasic; - HANDLE hFile; - NTSTATUS errCode; - - hFile = CreateFileW(lpFileName, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - return 0xFFFFFFFF; - } - - errCode = NtQueryInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - SetLastErrorByStatus(errCode); - return 0xFFFFFFFF; - } - CloseHandle(hFile); - return (DWORD)FileBasic.FileAttributes; + FILE_BASIC_INFORMATION FileInformation; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileName; + HANDLE FileHandle; + NTSTATUS Status; + + DPRINT ("GetFileAttributeW(%S) called\n", lpFileName); + + /* Validate and translate the filename */ + if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName, + &FileName, + NULL, + NULL)) + { + DPRINT ("Invalid path\n"); + SetLastError (ERROR_BAD_PATHNAME); + return 0xFFFFFFFF; + } + DPRINT ("FileName: \'%wZ\'\n", &FileName); + + /* build the object attributes */ + InitializeObjectAttributes (&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the file */ + Status = NtOpenFile (&FileHandle, + SYNCHRONIZE | FILE_READ_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + RtlFreeUnicodeString (&FileName); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); + SetLastErrorByStatus (Status); + return 0xFFFFFFFF; + } + + /* Get file attributes */ + Status = NtQueryInformationFile (FileHandle, + &IoStatusBlock, + &FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + NtClose (FileHandle); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); + SetLastErrorByStatus (Status); + return 0xFFFFFFFF; + } + + return (DWORD)FileInformation.FileAttributes; } @@ -563,29 +588,29 @@ WINBOOL STDCALL SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes) { - UNICODE_STRING FileNameU; - ANSI_STRING FileName; - WINBOOL Result; + UNICODE_STRING FileNameU; + ANSI_STRING FileName; + WINBOOL Result; - RtlInitAnsiString(&FileName, + RtlInitAnsiString (&FileName, (LPSTR)lpFileName); - /* convert ansi (or oem) string to unicode */ - if (bIsFileApiAnsi) - RtlAnsiStringToUnicodeString(&FileNameU, + /* convert ansi (or oem) string to unicode */ + if (bIsFileApiAnsi) + RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE); else - RtlOemStringToUnicodeString(&FileNameU, + RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE); - Result = SetFileAttributesW(FileNameU.Buffer, + Result = SetFileAttributesW (FileNameU.Buffer, dwFileAttributes); - RtlFreeUnicodeString(&FileNameU); + RtlFreeUnicodeString (&FileNameU); - return Result; + return Result; } @@ -593,51 +618,77 @@ WINBOOL STDCALL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes) { - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileBasic; - HANDLE hFile; - NTSTATUS errCode; - - hFile = CreateFileW(lpFileName, - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (INVALID_HANDLE_VALUE == hFile) - { - DPRINT("SetFileAttributes CreateFileW failed with code %d\n", GetLastError()); - return FALSE; - } + FILE_BASIC_INFORMATION FileInformation; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING FileName; + HANDLE FileHandle; + NTSTATUS Status; + + DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes); + + /* Validate and translate the filename */ + if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName, + &FileName, + NULL, + NULL)) + { + DPRINT ("Invalid path\n"); + SetLastError (ERROR_BAD_PATHNAME); + return FALSE; + } + DPRINT ("FileName: \'%wZ\'\n", &FileName); + + /* build the object attributes */ + InitializeObjectAttributes (&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the file */ + Status = NtOpenFile (&FileHandle, + SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + RtlFreeUnicodeString (&FileName); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); + SetLastErrorByStatus (Status); + return FALSE; + } - errCode = NtQueryInformationFile(hFile, - &IoStatusBlock, - &FileBasic, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - DPRINT("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", errCode); - SetLastErrorByStatus(errCode); - return FALSE; - } - FileBasic.FileAttributes = dwFileAttributes; - errCode = NtSetInformationFile(hFile, + Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, - &FileBasic, + &FileInformation, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); - if (!NT_SUCCESS(errCode)) - { - CloseHandle(hFile); - DPRINT("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", errCode); - SetLastErrorByStatus(errCode); - return FALSE; - } - CloseHandle(hFile); - return TRUE; + if (!NT_SUCCESS(Status)) + { + DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status); + NtClose (FileHandle); + SetLastErrorByStatus (Status); + return FALSE; + } + + FileInformation.FileAttributes = dwFileAttributes; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + NtClose (FileHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status); + SetLastErrorByStatus (Status); + return FALSE; + } + + return TRUE; } diff --git a/lib/kernel32/file/find.c b/lib/kernel32/file/find.c index 455e51b..10f76c1 100644 --- a/lib/kernel32/file/find.c +++ b/lib/kernel32/file/find.c @@ -88,34 +88,100 @@ InternalFindFirstFile ( UNICODE_STRING NtPathU; UNICODE_STRING PatternStr; NTSTATUS Status; - PWSTR End; + PWSTR e1, e2; + WCHAR CurrentDir[256]; + PWSTR SearchPath; + PWCHAR SearchPattern; + ULONG Length; + BOOLEAN bResult; DPRINT("FindFirstFileW(lpFileName %S)\n", lpFileName); - if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName, - &NtPathU, - &End, - NULL)) - return FALSE; + e1 = wcsrchr(lpFileName, L'/'); + e2 = wcsrchr(lpFileName, L'\\'); + SearchPattern = max(e1, e2); + SearchPath = CurrentDir; + + if (NULL == SearchPattern) + { + CHECKPOINT; + SearchPattern = (PWCHAR)lpFileName; + Length = GetCurrentDirectoryW(sizeof(CurrentDir) / sizeof(WCHAR), SearchPath); + if (0 == Length) + { + return NULL; + } + if (Length > sizeof(CurrentDir) / sizeof(WCHAR)) + { + SearchPath = RtlAllocateHeap(hProcessHeap, + HEAP_ZERO_MEMORY, + Length * sizeof(WCHAR)); + if (NULL == SearchPath) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + GetCurrentDirectoryW(Length, SearchPath); + } + } + else + { + CHECKPOINT; + SearchPattern++; + Length = SearchPattern - lpFileName; + if (Length + 1 > sizeof(CurrentDir) / sizeof(WCHAR)) + { + SearchPath = RtlAllocateHeap(hProcessHeap, + HEAP_ZERO_MEMORY, + (Length + 1) * sizeof(WCHAR)); + if (NULL == SearchPath) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + } + memcpy(SearchPath, lpFileName, Length * sizeof(WCHAR)); + SearchPath[Length] = 0; + } + + bResult = RtlDosPathNameToNtPathName_U ((LPWSTR)SearchPath, + &NtPathU, + NULL, + NULL); + if (SearchPath != CurrentDir) + { + RtlFreeHeap(hProcessHeap, + 0, + SearchPath); + } + if (FALSE == bResult) + { + return NULL; + } - DPRINT("NtPathU \'%S\' End \'%S\'\n", NtPathU.Buffer, End); + DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer); IData = RtlAllocateHeap (hProcessHeap, HEAP_ZERO_MEMORY, sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE); - - /* move seach pattern to separate string */ - RtlCreateUnicodeString (&PatternStr, - End); - *End = 0; - NtPathU.Length = wcslen(NtPathU.Buffer)*sizeof(WCHAR); + if (NULL == IData) + { + RtlFreeHeap (hProcessHeap, + 0, + NtPathU.Buffer); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } /* change pattern: "*.*" --> "*" */ - if (!wcscmp (PatternStr.Buffer, L"*.*")) + if (!wcscmp (SearchPattern, L"*.*")) + { + RtlInitUnicodeStringFromLiteral(&PatternStr, L"*"); + } + else { - PatternStr.Buffer[1] = 0; - PatternStr.Length = sizeof(WCHAR); + RtlInitUnicodeString(&PatternStr, SearchPattern); } DPRINT("NtPathU \'%S\' Pattern \'%S\'\n", @@ -140,7 +206,6 @@ InternalFindFirstFile ( if (!NT_SUCCESS(Status)) { - RtlFreeHeap (hProcessHeap, 0, PatternStr.Buffer); RtlFreeHeap (hProcessHeap, 0, IData); SetLastErrorByStatus (Status); return(NULL); @@ -159,7 +224,6 @@ InternalFindFirstFile ( TRUE, &PatternStr, TRUE); - RtlFreeHeap (hProcessHeap, 0, PatternStr.Buffer); if (!NT_SUCCESS(Status)) { DPRINT("Status %lx\n", Status); @@ -406,11 +470,11 @@ FindFirstFileW ( memcpy (lpFindFileData->cFileName, IData->pFileInfo->FileName, IData->pFileInfo->FileNameLength); - lpFindFileData->cFileName[IData->pFileInfo->FileNameLength] = 0; + lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0; memcpy (lpFindFileData->cAlternateFileName, IData->pFileInfo->ShortName, IData->pFileInfo->ShortNameLength); - lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength] = 0; + lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0; return IData; } @@ -447,11 +511,11 @@ FindNextFileW ( memcpy (lpFindFileData->cFileName, IData->pFileInfo->FileName, IData->pFileInfo->FileNameLength); - lpFindFileData->cFileName[IData->pFileInfo->FileNameLength] = 0; + lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0; memcpy (lpFindFileData->cAlternateFileName, IData->pFileInfo->ShortName, IData->pFileInfo->ShortNameLength); - lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength] = 0; + lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0; return TRUE; } diff --git a/lib/kernel32/file/iocompl.c b/lib/kernel32/file/iocompl.c index c452eb2..dea9a51 100644 --- a/lib/kernel32/file/iocompl.c +++ b/lib/kernel32/file/iocompl.c @@ -14,23 +14,6 @@ #include - -typedef struct _FILE_COMPLETION_INFORMATION { - HANDLE CompletionPort; - ULONG CompletionKey; -} FILE_COMPLETION_INFORMATION; -typedef FILE_COMPLETION_INFORMATION *PFILE_COMPLETION_INFORMATION; - - -VOID -STDCALL -FileIOCompletionRoutine( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped - ); - - HANDLE STDCALL CreateIoCompletionPort( @@ -40,99 +23,146 @@ CreateIoCompletionPort( DWORD NumberOfConcurrentThreads ) { - HANDLE CompletionPort = NULL; - NTSTATUS errCode; - FILE_COMPLETION_INFORMATION CompletionInformation; - IO_STATUS_BLOCK IoStatusBlock; - - if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) { - SetLastErrorByStatus (STATUS_INVALID_PARAMETER); - return FALSE; - } - - if ( ExistingCompletionPort != NULL ) { - CompletionPort = ExistingCompletionPort; - } - else { - errCode = NtCreateIoCompletion(&CompletionPort,GENERIC_ALL,&IoStatusBlock,NumberOfConcurrentThreads); - if (!NT_SUCCESS(errCode) ) { - SetLastErrorByStatus (errCode); - return FALSE; - } - - } - if ( FileHandle != INVALID_HANDLE_VALUE ) { - - CompletionInformation.CompletionPort = CompletionPort; - CompletionInformation.CompletionKey = CompletionKey; - - errCode = NtSetInformationFile(FileHandle, &IoStatusBlock,&CompletionInformation,sizeof(FILE_COMPLETION_INFORMATION),FileCompletionInformation); - if ( !NT_SUCCESS(errCode) ) { - if ( ExistingCompletionPort == NULL ) - NtClose(CompletionPort); - SetLastErrorByStatus (errCode); - return FALSE; - } - } - - return CompletionPort; + HANDLE CompletionPort = NULL; + NTSTATUS errCode; + FILE_COMPLETION_INFORMATION CompletionInformation; + IO_STATUS_BLOCK IoStatusBlock; + + if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) + { + SetLastErrorByStatus (STATUS_INVALID_PARAMETER); + return FALSE; + } + + if ( ExistingCompletionPort != NULL ) + { + CompletionPort = ExistingCompletionPort; + } + else + { + + errCode = NtCreateIoCompletion(&CompletionPort, + IO_COMPLETION_ALL_ACCESS, + NULL,//ObjectAttributes + NumberOfConcurrentThreads); + + if (!NT_SUCCESS(errCode) ) + { + SetLastErrorByStatus (errCode); + return FALSE; + } + + } + + if ( FileHandle != INVALID_HANDLE_VALUE ) + { + CompletionInformation.IoCompletionHandle = CompletionPort; + CompletionInformation.CompletionKey = CompletionKey; + + errCode = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &CompletionInformation, + sizeof(FILE_COMPLETION_INFORMATION), + FileCompletionInformation); + + if ( !NT_SUCCESS(errCode) ) + { + if ( ExistingCompletionPort == NULL ) + { + NtClose(CompletionPort); + } + + SetLastErrorByStatus (errCode); + return FALSE; + } + } + + return CompletionPort; } WINBOOL STDCALL GetQueuedCompletionStatus( - HANDLE CompletionPort, - LPDWORD lpNumberOfBytesTransferred, - LPDWORD lpCompletionKey, - LPOVERLAPPED *lpOverlapped, - DWORD dwMilliseconds - ) + HANDLE CompletionHandle, + LPDWORD lpNumberOfBytesTransferred, + LPDWORD lpCompletionKey, + LPOVERLAPPED *lpOverlapped, + DWORD dwMilliseconds + ) { - NTSTATUS errCode; - ULONG CompletionStatus; - LARGE_INTEGER TimeToWait; + NTSTATUS errCode; + IO_STATUS_BLOCK IoStatus; + LARGE_INTEGER Interval; + + if (!lpNumberOfBytesTransferred||!lpCompletionKey||!lpOverlapped) + { + return ERROR_INVALID_PARAMETER; + } + + if (dwMilliseconds != INFINITE) + { + /* + * System time units are 100 nanoseconds (a nanosecond is a billionth of + * a second). + */ + Interval.QuadPart = dwMilliseconds; + Interval.QuadPart = -(Interval.QuadPart * 10000); + } + else + { + /* Approximately 292000 years hence */ + Interval.QuadPart = -0x7FFFFFFFFFFFFFFF; + } + + errCode = NtRemoveIoCompletion(CompletionHandle, + lpCompletionKey, + lpNumberOfBytesTransferred, + &IoStatus, + &Interval); + + if (!NT_SUCCESS(errCode) ) { + *lpOverlapped = NULL; + SetLastErrorByStatus(errCode); + return FALSE; + } + + *lpOverlapped = (LPOVERLAPPED)IoStatus.Information; + + if (!NT_SUCCESS(IoStatus.Status)){ + //failed io operation + SetLastErrorByStatus (IoStatus.Status); + return FALSE; + } + + return TRUE; - errCode = NtRemoveIoCompletion(CompletionPort,(PULONG)lpCompletionKey,(PIO_STATUS_BLOCK)lpOverlapped,&CompletionStatus,&TimeToWait); - if (!NT_SUCCESS(errCode) ) { - SetLastErrorByStatus (errCode); - return FALSE; - } - - return TRUE; } WINBOOL STDCALL PostQueuedCompletionStatus( - HANDLE CompletionPort, - DWORD dwNumberOfBytesTransferred, - DWORD dwCompletionKey, - LPOVERLAPPED lpOverlapped -) -{ - NTSTATUS errCode; - errCode = NtSetIoCompletion(CompletionPort, dwCompletionKey, (PIO_STATUS_BLOCK)lpOverlapped , 0, (PULONG)&dwNumberOfBytesTransferred ); - - if ( !NT_SUCCESS(errCode) ) { - SetLastErrorByStatus (errCode); - return FALSE; - } - return TRUE; -} - - -// this should be a place holder ?????????????????? -VOID -STDCALL -FileIOCompletionRoutine( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped - ) + HANDLE CompletionHandle, + DWORD dwNumberOfBytesTransferred, + DWORD dwCompletionKey, + LPOVERLAPPED lpOverlapped + ) { - return; + NTSTATUS errCode; + + errCode = NtSetIoCompletion(CompletionHandle, + dwCompletionKey, + dwNumberOfBytesTransferred,//CompletionValue + 0, //IoStatusBlock->Status + (ULONG)lpOverlapped ); //IoStatusBlock->Information + + if ( !NT_SUCCESS(errCode) ) + { + SetLastErrorByStatus (errCode); + return FALSE; + } + return TRUE; } diff --git a/lib/kernel32/k32.h b/lib/kernel32/k32.h index 018d32a..6b400f9 100755 --- a/lib/kernel32/k32.h +++ b/lib/kernel32/k32.h @@ -24,3 +24,4 @@ #include #include #include +#include diff --git a/lib/kernel32/kernel32.def b/lib/kernel32/kernel32.def index eaa0e93..60deca5 100644 --- a/lib/kernel32/kernel32.def +++ b/lib/kernel32/kernel32.def @@ -579,7 +579,6 @@ SetHandleCount@4 SetHandleInformation@12 SetLastConsoleEventActive@0 SetLastError@4 -SetLastErrorByStatus@4 SetLocalTime@4 SetLocaleInfoA@12 SetLocaleInfoW@12 diff --git a/lib/kernel32/kernel32.edf b/lib/kernel32/kernel32.edf index f1b0355..b1a770a 100644 --- a/lib/kernel32/kernel32.edf +++ b/lib/kernel32/kernel32.edf @@ -108,7 +108,7 @@ CreateVirtualBuffer=CreateVirtualBuffer@12 CreateWaitableTimerA=CreateWaitableTimerA@12 CreateWaitableTimerW=CreateWaitableTimerW@12 DebugActiveProcess=DebugActiveProcess@4 -DebugBreak=DebugBreak@0 +DebugBreak=NTDLL.DbgBreakPoint DefineDosDeviceA=DefineDosDeviceA@12 DefineDosDeviceW=DefineDosDeviceW@12 DeleteAtom=DeleteAtom@4 @@ -584,7 +584,6 @@ SetHandleCount=SetHandleCount@4 SetHandleInformation=SetHandleInformation@12 SetLastConsoleEventActive=SetLastConsoleEventActive@0 SetLastError=SetLastError@4 -SetLastErrorByStatus=SetLastErrorByStatus@4 SetLocalTime=SetLocalTime@4 SetLocaleInfoA=SetLocaleInfoA@12 SetLocaleInfoW=SetLocaleInfoW@12 diff --git a/lib/kernel32/makefile b/lib/kernel32/makefile index c783173..1e8cd08 100644 --- a/lib/kernel32/makefile +++ b/lib/kernel32/makefile @@ -8,30 +8,15 @@ TARGET_NAME = kernel32 TARGET_BASE = 0x77f00000 -TARGET_CFLAGS = -DKERNEL32_BASE=$(TARGET_DLLBASE) -I./ +TARGET_LFLAGS = -nostartfiles -nostdlib -TARGET_LFLAGS = -nostartfiles - -TARGET_SDKLIBS = ntdll.a +TARGET_SDKLIBS = rosrtl.a ntdll.a TARGET_GCCLIBS = gcc TARGET_PCH = k32.h -TARGET_OBJECTS = $(TARGET_NAME).o - -TARGET_CLEAN = except/*.o file/*.o mem/*.o misc/*.o nls/*.o \ - process/*.o string/*.o synch/*.o thread/*.o - - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - -depends: - make -f errormsg.mak - -.PHONY: depends +TARGET_CLEAN = errcodes.rc msg?????.bin SYNCH_OBJECTS = synch/critical.o synch/event.o synch/intrlck.o synch/mutex.o \ synch/sem.o synch/timer.o synch/wait.o @@ -40,7 +25,7 @@ MISC_OBJECTS = misc/error.o misc/atom.o misc/handle.o misc/env.o \ misc/dllmain.o misc/comm.o misc/errormsg.o \ misc/console.o misc/time.o misc/toolhelp.o \ misc/stubs.o misc/ldr.o misc/res.o \ - misc/debug.o misc/sysinfo.o misc/profile.o \ + misc/sysinfo.o misc/profile.o \ misc/mbchars.o misc/muldiv.o misc/getname.o \ misc/perfcnt.o @@ -54,7 +39,6 @@ FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \ MEM_OBJECTS = mem/global.o mem/heap.o mem/isbad.o mem/local.o \ mem/procmem.o mem/section.o mem/virtual.o - NLS_OBJECTS = nls/codepage.o nls/cpmisc.o \ nls/cptable.o nls/lctable.o \ nls/lcAFK.o nls/lcBEL.o nls/lcBGR.o nls/lcCAT.o \ @@ -91,7 +75,6 @@ NLS_CP_OBJECTS = \ nls/cp10000.o nls/cp10006.o nls/cp10007.o \ nls/cp10029.o nls/cp10079.o nls/cp10081.o - THREAD_OBJECTS = \ thread/fiber.o \ thread/thread.o \ @@ -107,15 +90,29 @@ STRING_OBJECTS = string/lstring.o EXCEPT_OBJECTS = except/except.o -OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \ - $(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \ - $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) +DEBUG_OBJECTS = debug/debugger.o debug/output.o debug/break.o + +TARGET_OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \ + $(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \ + $(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) $(DEBUG_OBJECTS) #$(NLS_OBJECTS) +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +$(TARGET_NAME).coff: errcodes.rc -$(TARGET_NAME).o: $(OBJECTS) errcodes.rc - $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o +errcodes.rc: $(TARGET_NAME).mc + $(MC) \ + -H $(PATH_TO_TOP)/include/reactos/errcodes.h \ + -o errcodes.rc \ + $(TARGET_NAME).mc %/TAGS: etags -o $(@D)/TAGS $(@D)/\*.c diff --git a/lib/kernel32/mem/isbad.c b/lib/kernel32/mem/isbad.c index ec1afa8..0c4e2fa 100644 --- a/lib/kernel32/mem/isbad.c +++ b/lib/kernel32/mem/isbad.c @@ -7,6 +7,9 @@ */ #include +#define NDEBUG +#include + /* FIXME: Stubs. What is it for? */ UINT wcsnlen ( @@ -14,6 +17,8 @@ wcsnlen ( UINT ucchMax ) { + DPRINT1("wcsnlen stub called\n"); + return 0; } @@ -25,6 +30,8 @@ strnlen ( UINT uiMax ) { + DPRINT1("strnlen stub called\n"); + return 0; } @@ -41,7 +48,7 @@ IsBadReadPtr ( if ( ucb == 0 ) { - return FALSE; + return TRUE; } VirtualQuery ( @@ -52,25 +59,25 @@ IsBadReadPtr ( if ( MemoryInformation.State != MEM_COMMIT ) { - return FALSE; + return TRUE; } if ( MemoryInformation.RegionSize < ucb ) { - return FALSE; + return TRUE; } if ( MemoryInformation.Protect == PAGE_EXECUTE ) { - return FALSE; + return TRUE; } if ( MemoryInformation.Protect == PAGE_NOACCESS ) { - return FALSE; + return TRUE; } - return TRUE; + return FALSE; } @@ -103,17 +110,17 @@ IsBadCodePtr ( if ( MemoryInformation.State != MEM_COMMIT ) { - return FALSE; + return TRUE; } if ( (MemoryInformation.Protect == PAGE_EXECUTE) || (MemoryInformation.Protect == PAGE_EXECUTE_READ) ) { - return TRUE; + return FALSE; } - return FALSE; + return TRUE; } @@ -128,7 +135,7 @@ IsBadWritePtr ( if ( ucb == 0 ) { - return FALSE; + return TRUE; } VirtualQuery ( @@ -139,33 +146,33 @@ IsBadWritePtr ( if ( MemoryInformation.State != MEM_COMMIT ) { - return FALSE; + return TRUE; } if ( MemoryInformation.RegionSize < ucb ) { - return FALSE; + return TRUE; } if ( MemoryInformation.Protect == PAGE_READONLY) { - return FALSE; + return TRUE; } if ( (MemoryInformation.Protect == PAGE_EXECUTE) || (MemoryInformation.Protect == PAGE_EXECUTE_READ) ) { - return FALSE; + return TRUE; } if ( MemoryInformation.Protect == PAGE_NOACCESS ) { - return FALSE; + return TRUE; } - return TRUE; + return FALSE; } diff --git a/lib/kernel32/misc/console.c b/lib/kernel32/misc/console.c index bb2a5c0..117d364 100644 --- a/lib/kernel32/misc/console.c +++ b/lib/kernel32/misc/console.c @@ -56,17 +56,35 @@ ConsoleMenuControl (HANDLE hConsole, return FALSE; } -BOOL STDCALL +HANDLE STDCALL DuplicateConsoleHandle (HANDLE hConsole, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) - /* - * Undocumented - */ + DWORD dwDesiredAccess, + BOOL bInheritHandle, + DWORD dwOptions) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + + if (IsConsoleHandle (hConsole) == FALSE) + { + SetLastError (ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + + Request.Type = CSRSS_DUPLICATE_HANDLE; + Request.Data.DuplicateHandleRequest.Handle = hConsole; + Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId(); + Status = CsrClientCallServer(&Request, + &Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status)) + { + SetLastErrorByStatus(Status); + return INVALID_HANDLE_VALUE; + } + return Reply.Data.DuplicateHandleReply.Handle; } DWORD STDCALL @@ -500,16 +518,39 @@ ShowConsoleCursor (DWORD Unknown0, return 0; } -DWORD STDCALL -VerifyConsoleIoHandle (DWORD Unknown0) - /* - * Undocumented - */ + +/* + * FUNCTION: Checks whether the given handle is a valid console handle. + * ARGUMENTS: + * Handle - Handle to be checked + * RETURNS: + * TRUE: Handle is a valid console handle + * FALSE: Handle is not a valid console handle. + * STATUS: Officially undocumented + */ +BOOL STDCALL +VerifyConsoleIoHandle(HANDLE Handle) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + + Request.Type = CSRSS_VERIFY_HANDLE; + Request.Data.VerifyHandleRequest.Handle = Handle; + Status = CsrClientCallServer(&Request, + &Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return (BOOL)NT_SUCCESS(Reply.Status); } + DWORD STDCALL WriteConsoleInputVDMA (DWORD Unknown0, DWORD Unknown1, @@ -530,21 +571,38 @@ WriteConsoleInputVDMW (DWORD Unknown0, return 0; } -WINBOOL STDCALL +WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle) /* * Undocumented */ { + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + if (IsConsoleHandle (Handle) == FALSE) { SetLastError (ERROR_INVALID_PARAMETER); return FALSE; } - /* FIXME: call CSRSS */ - return TRUE/*FALSE*/; + + Request.Type = CSRSS_CLOSE_HANDLE; + Request.Data.CloseHandleRequest.Handle = Handle; + Status = CsrClientCallServer(&Request, + &Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + + return TRUE; } + BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle) { @@ -567,14 +625,20 @@ GetStdHandle(DWORD nStdHandle) */ { PRTL_USER_PROCESS_PARAMETERS Ppb; - - Ppb = NtCurrentPeb()->ProcessParameters; + + Ppb = NtCurrentPeb()->ProcessParameters; switch (nStdHandle) { - case STD_INPUT_HANDLE: return Ppb->hStdInput; - case STD_OUTPUT_HANDLE: return Ppb->hStdOutput; - case STD_ERROR_HANDLE: return Ppb->hStdError; + case STD_INPUT_HANDLE: + return Ppb->hStdInput; + + case STD_OUTPUT_HANDLE: + return Ppb->hStdOutput; + + case STD_ERROR_HANDLE: + return Ppb->hStdError; } + SetLastError (ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } @@ -592,29 +656,33 @@ SetStdHandle(DWORD nStdHandle, */ { PRTL_USER_PROCESS_PARAMETERS Ppb; - + Ppb = NtCurrentPeb()->ProcessParameters; - + /* More checking needed? */ if (hHandle == INVALID_HANDLE_VALUE) { SetLastError (ERROR_INVALID_HANDLE); return FALSE; } - + SetLastError(ERROR_SUCCESS); /* OK */ + switch (nStdHandle) { - case STD_INPUT_HANDLE: - Ppb->hStdInput = hHandle; - return TRUE; - case STD_OUTPUT_HANDLE: - Ppb->hStdOutput = hHandle; - return TRUE; - case STD_ERROR_HANDLE: - Ppb->hStdError = hHandle; - return TRUE; + case STD_INPUT_HANDLE: + Ppb->hStdInput = hHandle; + return TRUE; + + case STD_OUTPUT_HANDLE: + Ppb->hStdOutput = hHandle; + return TRUE; + + case STD_ERROR_HANDLE: + Ppb->hStdError = hHandle; + return TRUE; } + SetLastError (ERROR_INVALID_PARAMETER); return FALSE; } @@ -635,7 +703,7 @@ WriteConsoleA(HANDLE hConsoleOutput, NTSTATUS Status; USHORT Size; ULONG MessageSize; - + Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST) + @@ -645,7 +713,7 @@ WriteConsoleA(HANDLE hConsoleOutput, SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } - + Request->Type = CSRSS_WRITE_CONSOLE; Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput; if (lpNumberOfCharsWritten != NULL) @@ -661,7 +729,7 @@ WriteConsoleA(HANDLE hConsoleOutput, Size = nNumberOfCharsToWrite; } Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size; - + memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size); MessageSize = CSRSS_REQUEST_HEADER_SIZE + @@ -670,7 +738,7 @@ WriteConsoleA(HANDLE hConsoleOutput, &Reply, MessageSize, sizeof(CSRSS_API_REPLY)); - + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { RtlFreeHeap(GetProcessHeap(), 0, Request); @@ -680,7 +748,9 @@ WriteConsoleA(HANDLE hConsoleOutput, nNumberOfCharsToWrite -= Size; lpBuffer += Size; } + RtlFreeHeap(GetProcessHeap(), 0, Request); + return TRUE; } @@ -786,6 +856,7 @@ WINBOOL STDCALL AllocConsole(VOID) CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; NTSTATUS Status; + HANDLE hStdError; Request.Type = CSRSS_ALLOC_CONSOLE; Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); @@ -796,7 +867,11 @@ WINBOOL STDCALL AllocConsole(VOID) } SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle ); SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle ); - SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle ); + hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + SetStdHandle( STD_ERROR_HANDLE, hStdError ); return TRUE; } @@ -2125,7 +2200,6 @@ GenerateConsoleCtrlEvent( /*-------------------------------------------------------------- * GetConsoleTitleW */ -#define MAX_CONSOLE_TITLE_LENGTH 80 WINBASEAPI DWORD @@ -2135,60 +2209,51 @@ GetConsoleTitleW( DWORD nSize ) { - union { - CSRSS_API_REQUEST quest; - CSRSS_API_REPLY ply; - } Re; - NTSTATUS Status; - - /* Marshall data */ - Re.quest.Type = CSRSS_GET_TITLE; - Re.quest.Data.GetTitleRequest.ConsoleHandle = - GetStdHandle (STD_INPUT_HANDLE); - - /* Call CSRSS */ - Status = CsrClientCallServer ( - & Re.quest, - & Re.ply, - (sizeof (CSRSS_GET_TITLE_REQUEST) + - sizeof (LPC_MESSAGE) + - sizeof (ULONG)), - sizeof (CSRSS_API_REPLY) - ); - if ( !NT_SUCCESS(Status) - || !NT_SUCCESS (Status = Re.ply.Status) - ) - { - SetLastErrorByStatus (Status); - return (0); - } + CSRSS_API_REQUEST Request; + PCSRSS_API_REPLY Reply; + NTSTATUS Status; + HANDLE hConsole; - /* Convert size in characters to size in bytes */ - nSize = sizeof (WCHAR) * nSize; + hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hConsole == INVALID_HANDLE_VALUE) + { + return 0; + } - /* Unmarshall data */ - if (nSize < Re.ply.Data.GetTitleReply.Length) - { - DbgPrint ("%s: ret=%d\n", __FUNCTION__, Re.ply.Data.GetTitleReply.Length); - nSize /= sizeof (WCHAR); - if (nSize > 1) - { - wcsncpy ( - lpConsoleTitle, - Re.ply.Data.GetTitleReply.Title, - (nSize - 1) - ); - /* Add null */ - lpConsoleTitle [nSize --] = L'\0'; - } - } - else - { - nSize = Re.ply.Data.GetTitleReply.Length / sizeof (WCHAR); - wcscpy (lpConsoleTitle, Re.ply.Data.GetTitleReply.Title); - } + Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); + if(Reply == NULL) + { + CloseHandle(hConsole); + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } - return nSize; + Request.Type = CSRSS_GET_TITLE; + Request.Data.GetTitleRequest.ConsoleHandle = hConsole; + + Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR)); + CloseHandle(hConsole); + if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status))) + { + SetLastErrorByStatus(Status); + RtlFreeHeap(GetProcessHeap(), 0, Reply); + return 0; + } + + if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length) + { + wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1); + lpConsoleTitle[nSize--] = L'\0'; + } + else + { + nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR); + wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title); + lpConsoleTitle[nSize] = L'\0'; + } + + RtlFreeHeap(GetProcessHeap(), 0, Reply); + return nSize; } @@ -2205,14 +2270,14 @@ GetConsoleTitleA( DWORD nSize ) { - wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH]; + wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH]; DWORD nWideTitle = sizeof WideTitle; -// DWORD nWritten; + DWORD nWritten; if (!lpConsoleTitle || !nSize) return 0; nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle ); if (!nWideTitle) return 0; -#if 0 + if ( (nWritten = WideCharToMultiByte( CP_ACP, // ANSI code page 0, // performance and mapping flags @@ -2227,7 +2292,7 @@ GetConsoleTitleA( lpConsoleTitle[nWritten] = '\0'; return nWritten; } -#endif + return 0; } @@ -2246,18 +2311,26 @@ SetConsoleTitleW( CSRSS_API_REPLY Reply; NTSTATUS Status; unsigned int c; + HANDLE hConsole; + + hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hConsole == INVALID_HANDLE_VALUE) + { + return FALSE; + } Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); if (Request == NULL) { + CloseHandle(hConsole); SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } Request->Type = CSRSS_SET_TITLE; - Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE ); + Request->Data.SetTitleRequest.Console = hConsole; for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ ) Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; @@ -2266,12 +2339,10 @@ SetConsoleTitleW( Request->Data.SetTitleRequest.Length = c; Status = CsrClientCallServer(Request, &Reply, - sizeof(CSRSS_SET_TITLE_REQUEST) + - c + - sizeof( LPC_MESSAGE ) + - sizeof( ULONG ), + sizeof(CSRSS_API_REQUEST) + + c * sizeof(WCHAR), sizeof(CSRSS_API_REPLY)); - + CloseHandle(hConsole); if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) ) { RtlFreeHeap( GetProcessHeap(), 0, Request ); @@ -2299,18 +2370,26 @@ SetConsoleTitleA( CSRSS_API_REPLY Reply; NTSTATUS Status; unsigned int c; + HANDLE hConsole; + + hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hConsole == INVALID_HANDLE_VALUE) + { + return FALSE; + } Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST); if (Request == NULL) { + CloseHandle(hConsole); SetLastError(ERROR_OUTOFMEMORY); return(FALSE); } Request->Type = CSRSS_SET_TITLE; - Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE ); + Request->Data.SetTitleRequest.Console = hConsole; for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ ) Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c]; @@ -2319,12 +2398,10 @@ SetConsoleTitleA( Request->Data.SetTitleRequest.Length = c; Status = CsrClientCallServer(Request, &Reply, - sizeof(CSRSS_SET_TITLE_REQUEST) + - c + - sizeof( LPC_MESSAGE ) + - sizeof( ULONG ), + sizeof(CSRSS_API_REQUEST) + + c * sizeof(WCHAR), sizeof(CSRSS_API_REPLY)); - + CloseHandle(hConsole); if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) ) { RtlFreeHeap( GetProcessHeap(), 0, Request ); diff --git a/lib/kernel32/misc/debug.c b/lib/kernel32/misc/debug.c deleted file mode 100644 index 78e2279..0000000 --- a/lib/kernel32/misc/debug.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS system libraries - * FILE: lib/kernel32/misc/debug.c - * PURPOSE: Application debugger support functions - * PROGRAMMER: ??? - */ - -/* INCLUDES ******************************************************************/ - -#include - - -/* FUNCTIONS *****************************************************************/ - -WINBOOL -STDCALL -ContinueDebugEvent ( - DWORD dwProcessId, - DWORD dwThreadId, - DWORD dwContinueStatus - ) -{ - CLIENT_ID ClientId; - NTSTATUS Status; - - ClientId.UniqueProcess = (HANDLE)dwProcessId; - ClientId.UniqueThread = (HANDLE)dwThreadId; - - Status = DbgUiContinue (&ClientId, - dwContinueStatus); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus (Status); - return FALSE; - } - return TRUE; -} - - -WINBOOL -STDCALL -DebugActiveProcess ( - DWORD dwProcessId - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -VOID -STDCALL -DebugBreak ( - VOID - ) -{ - DbgBreakPoint (); -} - - -WINBOOL -STDCALL -IsDebuggerPresent ( - VOID - ) -{ - return (WINBOOL)NtCurrentPeb ()->BeingDebugged; -} - - -/* - * NOTE: Don't call DbgService()! - * It's a ntdll internal function and is NOT exported! - */ - -VOID STDCALL OutputDebugStringA(LPCSTR lpOutputString) -{ - DbgPrint( (PSTR)lpOutputString ); -} - -VOID STDCALL OutputDebugStringW(LPCWSTR lpOutputString) -{ - UNICODE_STRING UnicodeOutput; - ANSI_STRING AnsiString; - char buff[512]; - - UnicodeOutput.Buffer = (WCHAR *)lpOutputString; - UnicodeOutput.Length = lstrlenW(lpOutputString)*sizeof(WCHAR); - UnicodeOutput.MaximumLength = UnicodeOutput.Length; - AnsiString.Buffer = buff; - AnsiString.MaximumLength = 512; - AnsiString.Length = 0; - if( UnicodeOutput.Length > 512 ) - UnicodeOutput.Length = 512; - if( NT_SUCCESS( RtlUnicodeStringToAnsiString( &AnsiString, &UnicodeOutput, FALSE ) ) ) - DbgPrint( AnsiString.Buffer ); -} - - -WINBOOL -STDCALL -WaitForDebugEvent ( - LPDEBUG_EVENT lpDebugEvent, - DWORD dwMilliseconds - ) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/* EOF */ diff --git a/lib/kernel32/misc/dllmain.c b/lib/kernel32/misc/dllmain.c index 25d0529..ccef239 100644 --- a/lib/kernel32/misc/dllmain.c +++ b/lib/kernel32/misc/dllmain.c @@ -26,139 +26,135 @@ HANDLE hBaseDir = NULL; static WINBOOL DllInitialized = FALSE; -WINBOOL STDCALL DllMain (HANDLE hInst, - ULONG ul_reason_for_call, - LPVOID lpReserved); +BOOL STDCALL +DllMain(HANDLE hInst, + DWORD dwReason, + LPVOID lpReserved); /* Critical section for various kernel32 data structures */ CRITICAL_SECTION DllLock; /* FUNCTIONS *****************************************************************/ -static NTSTATUS +static NTSTATUS OpenBaseDirectory(PHANDLE DirHandle) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name = UNICODE_STRING_INITIALIZER(L"\\BaseNamedObjects"); - NTSTATUS Status; - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_PERMANENT, - NULL, - NULL); - - Status = NtOpenDirectoryObject(DirHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - Status = NtCreateDirectoryObject(DirHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DbgPrint("NtCreateDirectoryObject() failed\n"); - } - - return Status; - } + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name = UNICODE_STRING_INITIALIZER(L"\\BaseNamedObjects"); + NTSTATUS Status; + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + NULL, + NULL); + + Status = NtOpenDirectoryObject(DirHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + Status = NtCreateDirectoryObject(DirHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DbgPrint("NtCreateDirectoryObject() failed\n"); + } + + return Status; + } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } -BOOL WINAPI -DllMainCRTStartup(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) -{ - return(DllMain(hDll,dwReason,lpReserved)); -} - -WINBOOL STDCALL -DllMain(HANDLE hInst, - ULONG ul_reason_for_call, +BOOL STDCALL +DllMain(HANDLE hDll, + DWORD dwReason, LPVOID lpReserved) { - (void)lpReserved; + NTSTATUS Status; - DPRINT("DllMain(hInst %x, ul_reason_for_call %d)\n", - hInst, ul_reason_for_call); + (void)lpReserved; - switch (ul_reason_for_call) - { + DPRINT("DllMain(hInst %lx, dwReason %lu)\n", + hInst, dwReason); + + switch (dwReason) + { case DLL_PROCESS_ATTACH: + DPRINT("DLL_PROCESS_ATTACH\n"); + + LdrDisableThreadCalloutsForDll ((PVOID)hDll); + + /* + * Connect to the csrss server + */ + Status = CsrClientConnectToServer(); + if (!NT_SUCCESS(Status)) { - NTSTATUS Status; - - DPRINT("DLL_PROCESS_ATTACH\n"); - - LdrDisableThreadCalloutsForDll ((PVOID)hInst); - - /* - * Connect to the csrss server - */ - Status = CsrClientConnectToServer(); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to connect to csrss.exe: expect trouble " - "Status was %X\n", Status); - ZwTerminateProcess(NtCurrentProcess(), Status); - } - - hProcessHeap = RtlGetProcessHeap(); - - /* - * Initialize WindowsDirectory and SystemDirectory - */ - DPRINT("NtSystemRoot: %S\n", - SharedUserData->NtSystemRoot); - RtlCreateUnicodeString (&WindowsDirectory, - SharedUserData->NtSystemRoot); - SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18; - SystemDirectory.Length = WindowsDirectory.Length + 18; - SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap, - 0, - SystemDirectory.MaximumLength); - wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer); - wcscat (SystemDirectory.Buffer, L"\\System32"); - - /* Open object base directory */ - Status = OpenBaseDirectory(&hBaseDir); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to open object base directory: expect trouble\n"); - } - - /* Initialize the DLL critical section */ - RtlInitializeCriticalSection(&DllLock); - - /* Insert more dll attach stuff here! */ - - DllInitialized = TRUE; - - break; + DbgPrint("Failed to connect to csrss.exe (Status %lx)\n", + Status); + ZwTerminateProcess(NtCurrentProcess(), Status); + return FALSE; } + + hProcessHeap = RtlGetProcessHeap(); + + /* + * Initialize WindowsDirectory and SystemDirectory + */ + DPRINT("NtSystemRoot: %S\n", + SharedUserData->NtSystemRoot); + RtlCreateUnicodeString (&WindowsDirectory, + SharedUserData->NtSystemRoot); + SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18; + SystemDirectory.Length = WindowsDirectory.Length + 18; + SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap, + 0, + SystemDirectory.MaximumLength); + wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer); + wcscat (SystemDirectory.Buffer, L"\\System32"); + + /* Open object base directory */ + Status = OpenBaseDirectory(&hBaseDir); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to open object base directory (Status %lx)\n", + Status); + return FALSE; + } + + /* Initialize the DLL critical section */ + RtlInitializeCriticalSection(&DllLock); + + /* Insert more dll attach stuff here! */ + + DllInitialized = TRUE; + break; + case DLL_PROCESS_DETACH: + DPRINT("DLL_PROCESS_DETACH\n"); + if (DllInitialized == TRUE) { - DPRINT("DLL_PROCESS_DETACH\n"); - if (DllInitialized == TRUE) - { - /* Insert more dll detach stuff here! */ - - /* Delete DLL critical section */ - RtlDeleteCriticalSection (&DllLock); - - /* Close object base directory */ - NtClose(hBaseDir); - - RtlFreeUnicodeString (&SystemDirectory); - RtlFreeUnicodeString (&WindowsDirectory); - } - break; + /* Insert more dll detach stuff here! */ + + /* Delete DLL critical section */ + RtlDeleteCriticalSection (&DllLock); + + /* Close object base directory */ + NtClose(hBaseDir); + + RtlFreeUnicodeString (&SystemDirectory); + RtlFreeUnicodeString (&WindowsDirectory); } + break; + default: break; } + return TRUE; } diff --git a/lib/kernel32/misc/env.c b/lib/kernel32/misc/env.c index 0e32c9e..03021cf 100644 --- a/lib/kernel32/misc/env.c +++ b/lib/kernel32/misc/env.c @@ -309,11 +309,8 @@ GetVersionExA( gives extra work to RtlUnicodeStringToAnsiString, but spares us an RtlInitUnicodeString round */ - sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * - sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) - - 1, - sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * - sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]), + 0, + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion), oviVerInfo.szCSDVersion }; @@ -321,9 +318,7 @@ GetVersionExA( ANSI_STRING strVerStr = { 0, - sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion) * - sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion[0]) - - 1, + sizeof(((LPOSVERSIONINFOA)NULL)->szCSDVersion), lpVersionInformation->szCSDVersion }; @@ -355,10 +350,11 @@ GetVersionExA( /* null-terminate, just in case */ oviVerInfo.szCSDVersion [ - sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) * + sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion) / sizeof(((LPOSVERSIONINFOW)NULL)->szCSDVersion[0]) - 1 ] = 0; + wstrVerStr.Length = wcslen(wstrVerStr.Buffer) * sizeof(WCHAR); /* convert the version string */ nErrCode = RtlUnicodeStringToAnsiString(&strVerStr, &wstrVerStr, FALSE); diff --git a/lib/kernel32/misc/error.c b/lib/kernel32/misc/error.c index 31194ac..972ecc2 100644 --- a/lib/kernel32/misc/error.c +++ b/lib/kernel32/misc/error.c @@ -10,19 +10,6 @@ #include -/* INTERNAL */ -DWORD -STDCALL -SetLastErrorByStatus ( - NTSTATUS Status - ) -{ - DWORD Error = RtlNtStatusToDosError (Status); - SetLastError (Error); - return (Error); -} - - VOID STDCALL SetLastError ( diff --git a/lib/kernel32/misc/errormsg.c b/lib/kernel32/misc/errormsg.c index 162f964..7e08c48 100644 --- a/lib/kernel32/misc/errormsg.c +++ b/lib/kernel32/misc/errormsg.c @@ -250,7 +250,7 @@ DWORD WINAPI FormatMessageA( from = NULL; if (dwFlags & FORMAT_MESSAGE_FROM_STRING) { - from = HeapAlloc( GetProcessHeap(), 0, strlen((LPSTR)lpSource)+1 ); + from = RtlAllocateHeap(RtlGetProcessHeap(), 0, strlen((LPSTR)lpSource)+1 ); strcpy( from, (LPSTR)lpSource ); } else { @@ -295,17 +295,17 @@ DWORD WINAPI FormatMessageA( return 0; } - from = HeapAlloc( GetProcessHeap(), 0, bufsize + 1 ); + from = RtlAllocateHeap(RtlGetProcessHeap(), 0, bufsize + 1 ); load_messageA(hmodule,dwMessageId,dwLanguageId,from,bufsize+1); } - target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100); + target = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 100); t = target; talloced= 100; #define ADD_TO_T(c) do { \ *t++=c;\ if (t-target == talloced) {\ - target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\ + target = (char*)RtlReAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\ t = target+talloced;\ talloced*=2;\ }\ @@ -351,17 +351,17 @@ DWORD WINAPI FormatMessageA( f++; if (NULL!=(x=strchr(f,'!'))) { *x='\0'; - fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + fmtstr=RtlAllocateHeap(RtlGetProcessHeap(),0,strlen(f)+2); sprintf(fmtstr,"%%%s",f); f=x+1; } else { - fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + fmtstr=RtlAllocateHeap(RtlGetProcessHeap(),0,strlen(f)+2); sprintf(fmtstr,"%%%s",f); f+=strlen(f); /*at \0*/ } } else { if(!args) break; - fmtstr = HeapAlloc(GetProcessHeap(),0,3); + fmtstr = RtlAllocateHeap(RtlGetProcessHeap(),0,3); strcpy( fmtstr, "%s" ); } if (args) { @@ -376,17 +376,17 @@ DWORD WINAPI FormatMessageA( /* FIXME: precision and width components are not handled correctly */ if ( (strcmp(fmtstr, "%ls") == 0) || (strcmp(fmtstr,"%S") == 0) ) { sz = WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, NULL, 0, NULL, NULL); - b = HeapAlloc(GetProcessHeap(), 0, sz); + b = RtlAllocateHeap(RtlGetProcessHeap(), 0, sz); WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, b, sz, NULL, NULL); } else { - b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000); + b = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000); /* CMF - This makes a BIG assumption about va_list */ TRACE("A BIG assumption\n"); //vsnprintf(b, sz, fmtstr, (va_list) argliststart); } for (x=b; *x; x++) ADD_TO_T(*x); - HeapFree(GetProcessHeap(),0,b); + RtlFreeHeap(RtlGetProcessHeap(),0,b); } else { /* NULL args - copy formatstr * (probably wrong) @@ -395,7 +395,7 @@ DWORD WINAPI FormatMessageA( ADD_TO_T(*lastf++); } } - HeapFree(GetProcessHeap(),0,fmtstr); + RtlFreeHeap(GetProcessHeap(),0,fmtstr); break; case 'n': ADD_TO_T('\r'); @@ -444,7 +444,7 @@ DWORD WINAPI FormatMessageA( } talloced = strlen(target)+1; if (nSize && talloced 0 && !MultiByteToWideChar( CP_ACP, 0, target, -1, lpBuffer, nSize )) lpBuffer[nSize-1] = 0; } - HeapFree(GetProcessHeap(),0,target); - if (from) HeapFree(GetProcessHeap(),0,from); + RtlFreeHeap(RtlGetProcessHeap(),0,target); + if (from) RtlFreeHeap(RtlGetProcessHeap(),0,from); return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? strlenW(*(LPWSTR*)lpBuffer): strlenW(lpBuffer); diff --git a/lib/kernel32/misc/handle.c b/lib/kernel32/misc/handle.c index 129b9b3..5b8233a 100644 --- a/lib/kernel32/misc/handle.c +++ b/lib/kernel32/misc/handle.c @@ -16,6 +16,17 @@ #define NDEBUG #include +/* GLOBALS *******************************************************************/ + +WINBOOL STDCALL +GetProcessId (HANDLE hProcess, LPDWORD lpProcessId); + +HANDLE STDCALL +DuplicateConsoleHandle (HANDLE hConsole, + DWORD dwDesiredAccess, + BOOL bInheritHandle, + DWORD dwOptions); + /* FUNCTIONS *****************************************************************/ WINBOOL WINAPI GetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags) @@ -119,18 +130,20 @@ WINBOOL STDCALL DuplicateHandle(HANDLE hSourceProcessHandle, DWORD dwOptions) { NTSTATUS errCode; + DWORD SourceProcessId, TargetProcessId; if (IsConsoleHandle(hSourceHandle)) { - /* FIXME: call CSRSS for console handle duplication */ - if (hSourceProcessHandle == hTargetProcessHandle) + if (FALSE == GetProcessId(hSourceProcessHandle, &SourceProcessId) || + FALSE == GetProcessId(hTargetProcessHandle, &TargetProcessId) || + SourceProcessId != TargetProcessId || + SourceProcessId != GetCurrentProcessId()) { - *lpTargetHandle = hSourceHandle; - return TRUE; - } - else - { - return FALSE; + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } + + *lpTargetHandle = DuplicateConsoleHandle(hSourceHandle, dwDesiredAccess, bInheritHandle, dwOptions); + return *lpTargetHandle != INVALID_HANDLE_VALUE ? TRUE : FALSE; } errCode = NtDuplicateObject(hSourceProcessHandle, diff --git a/lib/kernel32/misc/res.c b/lib/kernel32/misc/res.c index f603ef0..7edd10e 100644 --- a/lib/kernel32/misc/res.c +++ b/lib/kernel32/misc/res.c @@ -103,48 +103,15 @@ FindResourceExW ( PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry = NULL; LDR_RESOURCE_INFO ResourceInfo; NTSTATUS Status; - int i,l; - ULONG nType = 0, nName = 0; - + if ( hModule == NULL ) hModule = GetModuleHandle(NULL); - if ( HIWORD(lpName) != 0 ) { - if ( lpName[0] == L'#' ) { - l = lstrlenW(lpName) -1; - - for(i=0;iMaxCharSize = 1; + CodePageInfo->DefaultChar[0] = '?'; + for (i = 1; i < MAX_DEFAULTCHAR; i++) + { + CodePageInfo->DefaultChar[i] = '\0'; + } + for (i = 0; i < MAX_LEADBYTES; i++) + { + CodePageInfo->LeadByte[i] = '\0'; + } + + return TRUE; } #endif diff --git a/lib/kernel32/process/create.c b/lib/kernel32/process/create.c index 776057c..f871c97 100644 --- a/lib/kernel32/process/create.c +++ b/lib/kernel32/process/create.c @@ -18,17 +18,94 @@ /* FUNCTIONS ****************************************************************/ -WINBOOL STDCALL -CreateProcessA (LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +__declspec(dllimport) +PRTL_BASE_PROCESS_START_ROUTINE RtlBaseProcessStartRoutine; + +typedef NTSTATUS STDCALL (K32_MBSTR_TO_WCSTR) +( + UNICODE_STRING *, + ANSI_STRING *, + BOOLEAN +); + +NTSTATUS STDCALL K32MbStrToWcStr +( + IN K32_MBSTR_TO_WCSTR * True, + UNICODE_STRING * DestStr, + ANSI_STRING * SourceStr, + BOOLEAN Allocate +) +{ + if(SourceStr->Buffer == NULL) + { + DestStr->Length = DestStr->MaximumLength = 0; + DestStr->Buffer = NULL; + return STATUS_SUCCESS; + } + + return True(DestStr, SourceStr, Allocate); +} + +VOID STDCALL RtlRosR32AttribsToNativeAttribs +( + OUT OBJECT_ATTRIBUTES * NativeAttribs, + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL +) +{ + NativeAttribs->Length = sizeof(*NativeAttribs); + NativeAttribs->ObjectName = NULL; + NativeAttribs->RootDirectory = NULL; + NativeAttribs->Attributes = 0; + NativeAttribs->SecurityQualityOfService = NULL; + + + if(Ros32Attribs != NULL && Ros32Attribs->nLength >= sizeof(*Ros32Attribs)) + { + NativeAttribs->SecurityDescriptor = Ros32Attribs->lpSecurityDescriptor; + + if(Ros32Attribs->bInheritHandle) + NativeAttribs->Attributes |= OBJ_INHERIT; + } + else + NativeAttribs->SecurityDescriptor = NULL; +} + +VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed +( + OUT OBJECT_ATTRIBUTES * NativeAttribs, + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL, + OUT UNICODE_STRING * NativeName OPTIONAL, + IN WCHAR * Ros32Name OPTIONAL, + IN HANDLE Ros32NameRoot OPTIONAL +) +{ + if(!NativeAttribs) return; + + RtlRosR32AttribsToNativeAttribs(NativeAttribs, Ros32Attribs); + + if(Ros32Name != NULL && NativeName != NULL) + { + RtlInitUnicodeString(NativeName, Ros32Name); + + NativeAttribs->ObjectName = NativeName; + NativeAttribs->RootDirectory = Ros32NameRoot; + NativeAttribs->Attributes |= OBJ_CASE_INSENSITIVE; + } +} + +BOOL STDCALL CreateProcessA +( + LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) /* * FUNCTION: The CreateProcess function creates a new process and its * primary thread. The new process executes the specified executable file @@ -46,112 +123,185 @@ CreateProcessA (LPCSTR lpApplicationName, * lpProcessInformation = Pointer to process information */ { - PWCHAR lpEnvironmentW = NULL; - UNICODE_STRING ApplicationNameU; - UNICODE_STRING CurrentDirectoryU; - UNICODE_STRING CommandLineU; - ANSI_STRING ApplicationName; - ANSI_STRING CurrentDirectory; - ANSI_STRING CommandLine; - WINBOOL Result; - CHAR TempCurrentDirectoryA[256]; - - DPRINT("CreateProcessA(%s)\n", lpApplicationName); - DPRINT("dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, " - "lpStartupInfo %x, lpProcessInformation %x\n", dwCreationFlags, - lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); - - if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) - { - PCHAR ptr = lpEnvironment; - ULONG len = 0; - UNICODE_STRING EnvironmentU; - ANSI_STRING EnvironmentA; - while (*ptr) - { - RtlInitAnsiString(&EnvironmentA, ptr); - if (bIsFileApiAnsi) - len += RtlAnsiStringToUnicodeSize(&EnvironmentA) + sizeof(WCHAR); - else - len += RtlOemStringToUnicodeSize(&EnvironmentA) + sizeof(WCHAR); - ptr += EnvironmentA.MaximumLength; - } - len += sizeof(WCHAR); - lpEnvironmentW = (PWCHAR)RtlAllocateHeap(GetProcessHeap(), - HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, - len); - if (lpEnvironmentW == NULL) - { - return FALSE; - } - ptr = lpEnvironment; - EnvironmentU.Buffer = lpEnvironmentW; - EnvironmentU.Length = 0; - EnvironmentU.MaximumLength = len; - while (*ptr) - { - RtlInitAnsiString(&EnvironmentA, ptr); - if (bIsFileApiAnsi) - RtlAnsiStringToUnicodeString(&EnvironmentU, &EnvironmentA, FALSE); - else - RtlOemStringToUnicodeString(&EnvironmentU, &EnvironmentA, FALSE); - ptr += EnvironmentA.MaximumLength; - EnvironmentU.Buffer += (EnvironmentU.Length / sizeof(WCHAR) + 1); - EnvironmentU.MaximumLength -= (EnvironmentU.Length + sizeof(WCHAR)); - EnvironmentU.Length = 0; - } - - EnvironmentU.Buffer[0] = 0; - } - - RtlInitAnsiString (&CommandLine, - lpCommandLine); - RtlInitAnsiString (&ApplicationName, - (LPSTR)lpApplicationName); - if (lpCurrentDirectory != NULL) - { - RtlInitAnsiString (&CurrentDirectory, - (LPSTR)lpCurrentDirectory); - } - - /* convert ansi (or oem) strings to unicode */ - if (bIsFileApiAnsi) - { - RtlAnsiStringToUnicodeString (&CommandLineU, &CommandLine, TRUE); - RtlAnsiStringToUnicodeString (&ApplicationNameU, &ApplicationName, TRUE); - if (lpCurrentDirectory != NULL) - RtlAnsiStringToUnicodeString (&CurrentDirectoryU, &CurrentDirectory, TRUE); - } - else - { - RtlOemStringToUnicodeString (&CommandLineU, &CommandLine, TRUE); - RtlOemStringToUnicodeString (&ApplicationNameU, &ApplicationName, TRUE); - if (lpCurrentDirectory != NULL) - RtlOemStringToUnicodeString (&CurrentDirectoryU, &CurrentDirectory, TRUE); - } - - Result = CreateProcessW (ApplicationNameU.Buffer, - CommandLineU.Buffer, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - dwCreationFlags & CREATE_UNICODE_ENVIRONMENT ? lpEnvironment : lpEnvironmentW, - (lpCurrentDirectory == NULL) ? NULL : CurrentDirectoryU.Buffer, - (LPSTARTUPINFOW)lpStartupInfo, - lpProcessInformation); - - RtlFreeUnicodeString (&ApplicationNameU); - RtlFreeUnicodeString (&CommandLineU); - if (lpCurrentDirectory != NULL) - RtlFreeUnicodeString (&CurrentDirectoryU); - - if (lpEnvironmentW) - { - RtlFreeHeap(GetProcessHeap(), 0, lpEnvironmentW); - } - - return Result; + PWCHAR pwcEnv = NULL; + UNICODE_STRING wstrApplicationName; + UNICODE_STRING wstrCurrentDirectory; + UNICODE_STRING wstrCommandLine; + UNICODE_STRING wstrReserved; + UNICODE_STRING wstrDesktop; + UNICODE_STRING wstrTitle; + ANSI_STRING strApplicationName; + ANSI_STRING strCurrentDirectory; + ANSI_STRING strCommandLine; + ANSI_STRING strReserved; + ANSI_STRING strDesktop; + ANSI_STRING strTitle; + BOOL bRetVal; + STARTUPINFOW wsiStartupInfo; + + NTSTATUS STDCALL (*pTrue) + ( + UNICODE_STRING *, + ANSI_STRING *, + BOOLEAN + ); + + ULONG STDCALL (*pRtlMbStringToUnicodeSize)(ANSI_STRING *); + + DPRINT("CreateProcessA(%s)\n", lpApplicationName); + + DPRINT + ( + "dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, " + "lpStartupInfo %x, lpProcessInformation %x\n", + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation + ); + + /* invalid parameter */ + if(lpStartupInfo == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* multibyte strings are ANSI */ + if(bIsFileApiAnsi) + { + pTrue = RtlAnsiStringToUnicodeString; + pRtlMbStringToUnicodeSize = RtlAnsiStringToUnicodeSize; + } + /* multibyte strings are OEM */ + else + { + pTrue = RtlOemStringToUnicodeString; + pRtlMbStringToUnicodeSize = RtlOemStringToUnicodeSize; + } + + /* convert the environment */ + if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + PCHAR pcScan; + SIZE_T nEnvLen = 0; + UNICODE_STRING wstrEnvVar; + ANSI_STRING strEnvVar; + + /* scan the environment to calculate its Unicode size */ + for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.MaximumLength) + { + /* add the size of the current variable */ + RtlInitAnsiString(&strEnvVar, pcScan); + nEnvLen += pRtlMbStringToUnicodeSize(&strEnvVar) + sizeof(WCHAR); + } + + /* add the size of the final NUL character */ + nEnvLen += sizeof(WCHAR); + + /* environment too large */ + if(nEnvLen > ~((USHORT)0)) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + /* allocate the Unicode environment */ + pwcEnv = (PWCHAR)RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, nEnvLen); + + /* failure */ + if(pwcEnv == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + wstrEnvVar.Buffer = pwcEnv; + wstrEnvVar.Length = 0; + wstrEnvVar.MaximumLength = nEnvLen; + + /* scan the environment to convert it */ + for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.MaximumLength) + { + /* convert the current variable */ + RtlInitAnsiString(&strEnvVar, pcScan); + K32MbStrToWcStr(pTrue, &wstrEnvVar, &strEnvVar, FALSE); + + /* advance the buffer to the next variable */ + wstrEnvVar.Buffer += (wstrEnvVar.Length / sizeof(WCHAR) + 1); + wstrEnvVar.MaximumLength -= (wstrEnvVar.Length + sizeof(WCHAR)); + wstrEnvVar.Length = 0; + } + + /* final NUL character */ + wstrEnvVar.Buffer[0] = 0; + } + + /* convert the strings */ + RtlInitAnsiString(&strCommandLine, lpCommandLine); + RtlInitAnsiString(&strApplicationName, (LPSTR)lpApplicationName); + RtlInitAnsiString(&strCurrentDirectory, (LPSTR)lpCurrentDirectory); + RtlInitAnsiString(&strReserved, (LPSTR)lpStartupInfo->lpReserved); + RtlInitAnsiString(&strDesktop, (LPSTR)lpStartupInfo->lpDesktop); + RtlInitAnsiString(&strTitle, (LPSTR)lpStartupInfo->lpTitle); + + K32MbStrToWcStr(pTrue, &wstrCommandLine, &strCommandLine, TRUE); + K32MbStrToWcStr(pTrue, &wstrApplicationName, &strApplicationName, TRUE); + K32MbStrToWcStr(pTrue, &wstrCurrentDirectory, &strCurrentDirectory, TRUE); + K32MbStrToWcStr(pTrue, &wstrReserved, &strReserved, TRUE); + K32MbStrToWcStr(pTrue, &wstrDesktop, &strDesktop, TRUE); + K32MbStrToWcStr(pTrue, &wstrTitle, &strTitle, TRUE); + + /* convert the startup information */ + memcpy(&wsiStartupInfo, lpStartupInfo, sizeof(wsiStartupInfo)); + + wsiStartupInfo.lpReserved = wstrReserved.Buffer; + wsiStartupInfo.lpDesktop = wstrDesktop.Buffer; + wsiStartupInfo.lpTitle = wstrTitle.Buffer; + + DPRINT("wstrApplicationName %wZ\n", &wstrApplicationName); + DPRINT("wstrCommandLine %wZ\n", &wstrCommandLine); + DPRINT("wstrCurrentDirectory %wZ\n", &wstrCurrentDirectory); + DPRINT("wstrReserved %wZ\n", &wstrReserved); + DPRINT("wstrDesktop %wZ\n", &wstrDesktop); + DPRINT("wstrTitle %wZ\n", &wstrTitle); + + DPRINT("wstrApplicationName.Buffer %p\n", wstrApplicationName.Buffer); + DPRINT("wstrCommandLine.Buffer %p\n", wstrCommandLine.Buffer); + DPRINT("wstrCurrentDirectory.Buffer %p\n", wstrCurrentDirectory.Buffer); + DPRINT("wstrReserved.Buffer %p\n", wstrReserved.Buffer); + DPRINT("wstrDesktop.Buffer %p\n", wstrDesktop.Buffer); + DPRINT("wstrTitle.Buffer %p\n", wstrTitle.Buffer); + + DPRINT("sizeof(STARTUPINFOA) %lu\n", sizeof(STARTUPINFOA)); + DPRINT("sizeof(STARTUPINFOW) %lu\n", sizeof(STARTUPINFOW)); + + /* call the Unicode function */ + bRetVal = CreateProcessW + ( + wstrApplicationName.Buffer, + wstrCommandLine.Buffer, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + dwCreationFlags & CREATE_UNICODE_ENVIRONMENT ? lpEnvironment : pwcEnv, + wstrCurrentDirectory.Buffer, + &wsiStartupInfo, + lpProcessInformation + ); + + RtlFreeUnicodeString(&wstrApplicationName); + RtlFreeUnicodeString(&wstrCommandLine); + RtlFreeUnicodeString(&wstrCurrentDirectory); + RtlFreeUnicodeString(&wstrReserved); + RtlFreeUnicodeString(&wstrDesktop); + RtlFreeUnicodeString(&wstrTitle); + + RtlFreeHeap(GetProcessHeap(), 0, pwcEnv); + + return bRetVal; } static int _except_recursion_trap = 0; @@ -168,29 +318,32 @@ _except_handler( struct _CONTEXT *ContextRecord, void * DispatcherContext ) { - DPRINT("Process terminated abnormally...\n"); + DPRINT1("Process terminated abnormally due to unhandled exception\n"); - if (++_except_recursion_trap > 3) { - DPRINT("_except_handler(...) appears to be recursing.\n"); - DPRINT("Process HALTED.\n"); - for (;;) {} - } - - if (/* FIXME: */ TRUE) /* Not a service */ - { - DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n"); - //ExitProcess(0); - ExitThread(0); - } - else + if (3 < ++_except_recursion_trap) + { + DPRINT1("_except_handler(...) appears to be recursing.\n"); + DPRINT1("Process HALTED.\n"); + for (;;) { - DPRINT(" calling ExitThread(0) . . .\n"); - ExitThread(0); } + } - DPRINT(" We should not get to here !!!\n"); - /* We should not get to here */ - return ExceptionContinueSearch; + if (/* FIXME: */ TRUE) /* Not a service */ + { + DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n"); + /* ExitProcess(0); */ + ExitThread(0); + } + else + { + DPRINT(" calling ExitThread(0) . . .\n"); + ExitThread(0); + } + + DPRINT1(" We should not get to here !!!\n"); + /* We should not get to here */ + return ExceptionContinueSearch; } VOID STDCALL @@ -199,7 +352,7 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress, { UINT uExitCode = 0; - DPRINT("\nBaseProcessStart(..) - setting up exception frame.\n\n"); + DPRINT("BaseProcessStart(..) - setting up exception frame.\n"); __try1(_except_handler) { @@ -208,185 +361,111 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress, { } - DPRINT("\nBaseProcessStart(..) - cleaned up exception frame.\n\n"); + DPRINT("BaseProcessStart(..) - cleaned up exception frame.\n"); ExitThread(uExitCode); } -HANDLE STDCALL -KlCreateFirstThread(HANDLE ProcessHandle, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - ULONG StackReserve, - ULONG StackCommit, - LPTHREAD_START_ROUTINE lpStartAddress, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL KlCreateFirstThread +( + HANDLE ProcessHandle, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + PSECTION_IMAGE_INFORMATION Sii, + LPTHREAD_START_ROUTINE lpStartAddress, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - NTSTATUS Status; - HANDLE ThreadHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - BOOLEAN CreateSuspended = FALSE; - ULONG OldPageProtection; - ULONG ResultLength; - ULONG InitialStack[6]; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - if (lpThreadAttributes != NULL) - { - if (lpThreadAttributes->bInheritHandle) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = - lpThreadAttributes->lpSecurityDescriptor; - } - ObjectAttributes.SecurityQualityOfService = NULL; - - if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) - CreateSuspended = TRUE; - else - CreateSuspended = FALSE; - - InitialTeb.StackReserve = (StackReserve < 0x100000) ? 0x100000 : StackReserve; - /* FIXME: use correct commit size */ -#if 0 - InitialTeb.StackCommit = (StackCommit < PAGE_SIZE) ? PAGE_SIZE : StackCommit; -#endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - - /* size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; - - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: %p\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack page(s) */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page(s)!\n"); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - DPRINT("StackLimit: %p\n", - InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = (ULONG)BaseProcessStart; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = USER_DS; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 6*4; - ThreadContext.EFlags = (1<<1) + (1<<9); - - DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); - - /* - * Write in the initial stack. - */ - InitialStack[0] = 0; - InitialStack[1] = (DWORD)lpStartAddress; - InitialStack[2] = PEB_BASE; - - Status = ZwWriteVirtualMemory(ProcessHandle, - (PVOID)ThreadContext.Esp, - InitialStack, - sizeof(InitialStack), - &ResultLength); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to write initial stack.\n"); - return(INVALID_HANDLE_VALUE); - } - - Status = NtCreateThread(&ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &ClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - if (lpThreadId != NULL) - { - memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG)); - } - - return(ThreadHandle); + OBJECT_ATTRIBUTES oaThreadAttribs; + CLIENT_ID cidClientId; + PVOID pTrueStartAddress; + NTSTATUS nErrCode; + HANDLE hThread; + + /* convert the thread attributes */ + RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes); + + /* native image */ + if(Sii->Subsystem != IMAGE_SUBSYSTEM_NATIVE) + pTrueStartAddress = (PVOID)BaseProcessStart; + /* Win32 image */ + else + pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine; + + DPRINT + ( + "RtlRosCreateUserThreadVa\n" + "(\n" + " ProcessHandle %p,\n" + " ObjectAttributes %p,\n" + " CreateSuspended %d,\n" + " StackZeroBits %d,\n" + " StackReserve %lu,\n" + " StackCommit %lu,\n" + " StartAddress %p,\n" + " ThreadHandle %p,\n" + " ClientId %p,\n" + " ParameterCount %u,\n" + " Parameters[0] %p,\n" + " Parameters[1] %p\n" + ")\n", + ProcessHandle, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + Sii->StackReserve, + Sii->StackCommit, + pTrueStartAddress, + &hThread, + &cidClientId, + 2, + lpStartAddress, + PEB_BASE + ); + + /* create the first thread */ + nErrCode = RtlRosCreateUserThreadVa + ( + ProcessHandle, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + &(Sii->StackReserve), + &(Sii->StackCommit), + pTrueStartAddress, + &hThread, + &cidClientId, + 2, + (ULONG_PTR)lpStartAddress, + (ULONG_PTR)PEB_BASE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return NULL; + } + + DPRINT + ( + "StackReserve %p\n" + "StackCommit %p\n" + "ThreadHandle %p\n" + "ClientId.UniqueThread %p\n", + Sii->StackReserve, + Sii->StackCommit, + hThread, + cidClientId.UniqueThread + ); + + /* success */ + if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; + return hThread; } -HANDLE -KlMapFile(LPCWSTR lpApplicationName) +HANDLE KlMapFile(LPCWSTR lpApplicationName) { HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; @@ -455,20 +534,22 @@ KlMapFile(LPCWSTR lpApplicationName) return(hSection); } -static NTSTATUS -KlInitPeb (HANDLE ProcessHandle, - PRTL_USER_PROCESS_PARAMETERS Ppb, - PVOID* ImageBaseAddress) +static NTSTATUS KlInitPeb +( + HANDLE ProcessHandle, + PRTL_USER_PROCESS_PARAMETERS Ppb, + PVOID * ImageBaseAddress +) { - NTSTATUS Status; - PVOID PpbBase; - ULONG PpbSize; - ULONG BytesWritten; - ULONG Offset; - PVOID ParentEnv = NULL; - PVOID EnvPtr = NULL; - PWCHAR ptr; - ULONG EnvSize = 0, EnvSize1 = 0; + NTSTATUS Status; + PVOID PpbBase; + ULONG PpbSize; + ULONG BytesWritten; + ULONG Offset; + PVOID ParentEnv = NULL; + PVOID EnvPtr = NULL; + PWCHAR ptr; + ULONG EnvSize = 0, EnvSize1 = 0; /* create the Environment */ if (Ppb->Environment != NULL) @@ -573,16 +654,19 @@ KlInitPeb (HANDLE ProcessHandle, WINBOOL STDCALL -CreateProcessW(LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +CreateProcessW +( + LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + WINBOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) { HANDLE hSection, hProcess, hThread; NTSTATUS Status; @@ -641,7 +725,7 @@ CreateProcessW(LPCWSTR lpApplicationName, { if (lpCommandLine[0] == L'"') { - wcscpy(TempApplicationNameW, &lpCommandLine[0]); + wcscpy(TempApplicationNameW, lpCommandLine + 1); s = wcschr(TempApplicationNameW, L'"'); if (s == NULL) { @@ -672,7 +756,10 @@ CreateProcessW(LPCWSTR lpApplicationName, return FALSE; } - if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName), ImagePathName, &s)) + DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n", + lpApplicationName, lpCommandLine); + + if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s)) { return FALSE; } @@ -688,7 +775,7 @@ CreateProcessW(LPCWSTR lpApplicationName, wcscat(TempCommandLineNameW, lpApplicationName); lpCommandLine = TempCommandLineNameW; wcscpy(TempApplicationNameW, L"cmd.exe"); - if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName), ImagePathName, &s)) + if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s)) { return FALSE; } @@ -738,7 +825,6 @@ CreateProcessW(LPCWSTR lpApplicationName, TempCurrentDirectoryW); } - /* * Create a section for the executable */ @@ -926,7 +1012,7 @@ CreateProcessW(LPCWSTR lpApplicationName, /* * Get some information about the process */ - ZwQueryInformationProcess(hProcess, + NtQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcessBasicInfo, sizeof(ProcessBasicInfo), @@ -934,13 +1020,19 @@ CreateProcessW(LPCWSTR lpApplicationName, DPRINT("ProcessBasicInfo.UniqueProcessId %d\n", ProcessBasicInfo.UniqueProcessId); lpProcessInformation->dwProcessId = ProcessBasicInfo.UniqueProcessId; - + /* * Tell the csrss server we are creating a new process */ CsrRequest.Type = CSRSS_CREATE_PROCESS; CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessBasicInfo.UniqueProcessId; + if (Sii.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) + { + /* Do not create a console for GUI applications */ + dwCreationFlags &= ~CREATE_NEW_CONSOLE; + dwCreationFlags |= DETACHED_PROCESS; + } CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags; Status = CsrClientCallServer(&CsrRequest, &CsrReply, @@ -1007,7 +1099,21 @@ CreateProcessW(LPCWSTR lpApplicationName, } if (IsConsoleHandle(Ppb->hStdError)) { - Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle; + CsrRequest.Type = CSRSS_DUPLICATE_HANDLE; + CsrRequest.Data.DuplicateHandleRequest.ProcessId = ProcessBasicInfo.UniqueProcessId; + CsrRequest.Data.DuplicateHandleRequest.Handle = CsrReply.Data.CreateProcessReply.OutputHandle; + Status = CsrClientCallServer(&CsrRequest, + &CsrReply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status)) + { + Ppb->hStdError = INVALID_HANDLE_VALUE; + } + else + { + Ppb->hStdError = CsrReply.Data.DuplicateHandleReply.Handle; + } } else { @@ -1066,12 +1172,12 @@ CreateProcessW(LPCWSTR lpApplicationName, /* * Create the thread for the kernel */ - DPRINT("Creating thread for process\n"); + DPRINT("Creating thread for process (EntryPoint = 0x%.08x)\n", + ImageBaseAddress + (ULONG)Sii.EntryPoint); hThread = KlCreateFirstThread(hProcess, lpThreadAttributes, - Sii.StackReserve, - Sii.StackCommit, - ImageBaseAddress + (ULONG)Sii.EntryPoint, + &Sii, + ImageBaseAddress + (ULONG)Sii.EntryPoint, dwCreationFlags, &lpProcessInformation->dwThreadId); if (hThread == INVALID_HANDLE_VALUE) diff --git a/lib/kernel32/process/proc.c b/lib/kernel32/process/proc.c index 71a3926..651d888 100644 --- a/lib/kernel32/process/proc.c +++ b/lib/kernel32/process/proc.c @@ -33,38 +33,58 @@ GetProcessId (HANDLE hProcess, LPDWORD lpProcessId); /* FUNCTIONS ****************************************************************/ -WINBOOL STDCALL -GetProcessAffinityMask(HANDLE hProcess, - LPDWORD lpProcessAffinityMask, - LPDWORD lpSystemAffinityMask) +BOOL STDCALL +GetProcessAffinityMask (HANDLE hProcess, + LPDWORD lpProcessAffinityMask, + LPDWORD lpSystemAffinityMask) { - if ((NULL == lpProcessAffinityMask) - || (NULL == lpSystemAffinityMask)) + PROCESS_BASIC_INFORMATION ProcessInfo; + ULONG BytesWritten; + NTSTATUS Status; + + Status = NtQueryInformationProcess (hProcess, + ProcessBasicInformation, + (PVOID)&ProcessInfo, + sizeof(PROCESS_BASIC_INFORMATION), + &BytesWritten); + if (!NT_SUCCESS(Status)) { - SetLastError(ERROR_BAD_ARGUMENTS); - return(FALSE); + SetLastError (Status); + return FALSE; } - /* FIXME: check hProcess is actually a process */ - /* FIXME: query the kernel process object */ - *lpProcessAffinityMask = 0x00000001; + *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask; + + /* FIXME */ *lpSystemAffinityMask = 0x00000001; - return(TRUE); + return TRUE; } BOOL STDCALL -SetProcessAffinityMask(HANDLE hProcess, - DWORD dwProcessAffinityMask) +SetProcessAffinityMask (HANDLE hProcess, + DWORD dwProcessAffinityMask) { - return(FALSE); + NTSTATUS Status; + + Status = NtSetInformationProcess (hProcess, + ProcessAffinityMask, + (PVOID)&dwProcessAffinityMask, + sizeof(DWORD)); + if (!NT_SUCCESS(Status)) + { + SetLastError (Status); + return FALSE; + } + + return TRUE; } WINBOOL STDCALL -GetProcessShutdownParameters(LPDWORD lpdwLevel, - LPDWORD lpdwFlags) +GetProcessShutdownParameters (LPDWORD lpdwLevel, + LPDWORD lpdwFlags) { CSRSS_API_REQUEST CsrRequest; CSRSS_API_REPLY CsrReply; @@ -89,8 +109,8 @@ GetProcessShutdownParameters(LPDWORD lpdwLevel, WINBOOL STDCALL -SetProcessShutdownParameters(DWORD dwLevel, - DWORD dwFlags) +SetProcessShutdownParameters (DWORD dwLevel, + DWORD dwFlags) { CSRSS_API_REQUEST CsrRequest; CSRSS_API_REPLY CsrReply; @@ -115,9 +135,9 @@ SetProcessShutdownParameters(DWORD dwLevel, WINBOOL STDCALL -GetProcessWorkingSetSize(HANDLE hProcess, - LPDWORD lpMinimumWorkingSetSize, - LPDWORD lpMaximumWorkingSetSize) +GetProcessWorkingSetSize (HANDLE hProcess, + LPDWORD lpMinimumWorkingSetSize, + LPDWORD lpMaximumWorkingSetSize) { QUOTA_LIMITS QuotaLimits; NTSTATUS Status; @@ -544,6 +564,10 @@ ExitProcess(UINT uExitCode) NtTerminateProcess (NtCurrentProcess (), uExitCode); + + /* should never get here */ + assert(0); + while(1); } @@ -690,14 +714,14 @@ SetPriorityClass (HANDLE hProcess, DWORD STDCALL -GetProcessVersion (DWORD ProcessId) +GetProcessVersion (DWORD ProcessId) { DWORD Version = 0; PIMAGE_NT_HEADERS NtHeader = NULL; PVOID BaseAddress = NULL; /* Caller's */ - if (0 == ProcessId) + if (0 == ProcessId || GetCurrentProcessId() == ProcessId) { BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress; NtHeader = RtlImageNtHeader (BaseAddress); diff --git a/lib/kernel32/synch/wait.c b/lib/kernel32/synch/wait.c index 0bdf016..e9daa2e 100644 --- a/lib/kernel32/synch/wait.c +++ b/lib/kernel32/synch/wait.c @@ -33,50 +33,77 @@ WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable) { - NTSTATUS errCode; - PLARGE_INTEGER TimePtr; - LARGE_INTEGER Time; - - if (dwMilliseconds == INFINITE) - { - TimePtr = NULL; - } - else - { - Time.QuadPart = -10000 * dwMilliseconds; - TimePtr = &Time; - } - - errCode = NtWaitForSingleObject(hHandle, - (BOOLEAN) bAlertable, - TimePtr); - if (errCode == STATUS_TIMEOUT) - { - return WAIT_TIMEOUT; - } - else if ((errCode == WAIT_OBJECT_0) || - (errCode == WAIT_ABANDONED_0)) - { - return(errCode); - } - - SetLastErrorByStatus (errCode); - - return(WAIT_FAILED); + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + NTSTATUS Status; + + /* Get real handle */ + switch ((ULONG)hHandle) + { + case STD_INPUT_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdInput; + break; + + case STD_OUTPUT_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; + + case STD_ERROR_HANDLE: + hHandle = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(hHandle)) + { + if (VerifyConsoleIoHandle(hHandle)) + { + DPRINT1("Console handles are not supported yet!\n"); + SetLastError(ERROR_INVALID_HANDLE); + return WAIT_FAILED; + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtWaitForSingleObject(hHandle, + (BOOLEAN) bAlertable, + TimePtr); + if (Status == STATUS_TIMEOUT) + { + return WAIT_TIMEOUT; + } + else if ((Status == WAIT_OBJECT_0) || + (Status == WAIT_ABANDONED_0)) + { + return Status; + } + + SetLastErrorByStatus (Status); + + return WAIT_FAILED; } DWORD STDCALL WaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll, - DWORD dwMilliseconds) + CONST HANDLE *lpHandles, + BOOL bWaitAll, + DWORD dwMilliseconds) { - return WaitForMultipleObjectsEx(nCount, - lpHandles, - bWaitAll ? WaitAll : WaitAny, - dwMilliseconds, - FALSE); + return WaitForMultipleObjectsEx(nCount, + lpHandles, + bWaitAll, + dwMilliseconds, + FALSE); } @@ -87,44 +114,89 @@ WaitForMultipleObjectsEx(DWORD nCount, DWORD dwMilliseconds, BOOL bAlertable) { - NTSTATUS errCode; - LARGE_INTEGER Time; - PLARGE_INTEGER TimePtr; - - DPRINT("nCount %lu\n", nCount); - - if (dwMilliseconds == INFINITE) - { - TimePtr = NULL; - } - else - { - Time.QuadPart = -10000 * dwMilliseconds; - TimePtr = &Time; - } - - errCode = NtWaitForMultipleObjects (nCount, - (PHANDLE)lpHandles, - (CINT)bWaitAll, - (BOOLEAN)bAlertable, - TimePtr); - - if (errCode == STATUS_TIMEOUT) - { - return WAIT_TIMEOUT; - } - else if (((errCode >= WAIT_OBJECT_0) && - (errCode <= WAIT_OBJECT_0 + nCount - 1)) || - ((errCode >= WAIT_ABANDONED_0) && - (errCode <= WAIT_ABANDONED_0 + nCount - 1))) - { - return(errCode); - } - - DPRINT("errCode %lx\n", errCode); - SetLastErrorByStatus (errCode); - - return(WAIT_FAILED); + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + PHANDLE HandleBuffer; + DWORD i; + NTSTATUS Status; + + DPRINT("nCount %lu\n", nCount); + + HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nCount * sizeof(HANDLE)); + if (HandleBuffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return WAIT_FAILED; + } + + for (i = 0; i < nCount; i++) + { + switch ((DWORD)lpHandles[i]) + { + case STD_INPUT_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdInput; + break; + + case STD_OUTPUT_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; + + case STD_ERROR_HANDLE: + HandleBuffer[i] = NtCurrentPeb()->ProcessParameters->hStdError; + break; + + default: + HandleBuffer[i] = lpHandles[i]; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(HandleBuffer[i])) + { + if (VerifyConsoleIoHandle(HandleBuffer[i])) + { + DPRINT1("Console handles are not supported yet!\n"); + RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtWaitForMultipleObjects (nCount, + HandleBuffer, + bWaitAll ? WaitAll : WaitAny, + (BOOLEAN)bAlertable, + TimePtr); + + RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); + + if (Status == STATUS_TIMEOUT) + { + return WAIT_TIMEOUT; + } + else if (((Status >= WAIT_OBJECT_0) && + (Status <= WAIT_OBJECT_0 + nCount - 1)) || + ((Status >= WAIT_ABANDONED_0) && + (Status <= WAIT_ABANDONED_0 + nCount - 1))) + { + return Status; + } + + DPRINT("Status %lx\n", Status); + SetLastErrorByStatus (Status); + + return WAIT_FAILED; } @@ -134,7 +206,58 @@ SignalObjectAndWait(HANDLE hObjectToSignal, DWORD dwMilliseconds, BOOL bAlertable) { - UNIMPLEMENTED + PLARGE_INTEGER TimePtr; + LARGE_INTEGER Time; + NTSTATUS Status; + + /* Get real handle */ + switch ((ULONG)hObjectToWaitOn) + { + case STD_INPUT_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdInput; + break; + + case STD_OUTPUT_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdOutput; + break; + + case STD_ERROR_HANDLE: + hObjectToWaitOn = NtCurrentPeb()->ProcessParameters->hStdError; + break; + } + + /* Check for console handle */ + if (IsConsoleHandle(hObjectToWaitOn)) + { + if (VerifyConsoleIoHandle(hObjectToWaitOn)) + { + DPRINT1("Console handles are not supported yet!\n"); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + } + + if (dwMilliseconds == INFINITE) + { + TimePtr = NULL; + } + else + { + Time.QuadPart = -10000 * dwMilliseconds; + TimePtr = &Time; + } + + Status = NtSignalAndWaitForSingleObject (hObjectToSignal, + hObjectToWaitOn, + TimePtr, + (BOOLEAN)bAlertable); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus (Status); + return FALSE; + } + + return TRUE; } /* EOF */ diff --git a/lib/kernel32/thread/thread.c b/lib/kernel32/thread/thread.c index e4a9423..0000791 100644 --- a/lib/kernel32/thread/thread.c +++ b/lib/kernel32/thread/thread.c @@ -17,15 +17,15 @@ #define NDEBUG #include - //static VOID ThreadAttachDlls (VOID); /* FUNCTIONS *****************************************************************/ +/* FIXME: please put this in some header */ static EXCEPTION_DISPOSITION __cdecl -_except_handler(struct _EXCEPTION_RECORD *ExceptionRecord, +_except_handler(EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, - struct _CONTEXT *ContextRecord, + CONTEXT *ContextRecord, void * DispatcherContext) { ExitThread(0); @@ -54,184 +54,190 @@ ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress, } -HANDLE STDCALL -CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL CreateThread +( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - return(CreateRemoteThread(NtCurrentProcess(), - lpThreadAttributes, - dwStackSize, - lpStartAddress, - lpParameter, - dwCreationFlags, - lpThreadId)); + return CreateRemoteThread + ( + NtCurrentProcess(), + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId + ); } -HANDLE STDCALL -CreateRemoteThread(HANDLE hProcess, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL CreateRemoteThread +( + HANDLE hProcess, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - HANDLE ThreadHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - BOOLEAN CreateSuspended = FALSE; - PVOID BaseAddress; - ULONG OldPageProtection; - NTSTATUS Status; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - if (lpThreadAttributes != NULL) - { - if (lpThreadAttributes->bInheritHandle) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = - lpThreadAttributes->lpSecurityDescriptor; - } - ObjectAttributes.SecurityQualityOfService = NULL; - - if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) - CreateSuspended = TRUE; - else - CreateSuspended = FALSE; - - InitialTeb.StackReserve = 0x100000; /* 1MByte */ - /* FIXME: use correct commit size */ -#if 0 - InitialTeb.StackCommit = (dwStackSize == 0) ? PAGE_SIZE : dwStackSize; + PSECURITY_DESCRIPTOR pSD = NULL; + HANDLE hThread; + CLIENT_ID cidClientId; + NTSTATUS nErrCode; + ULONG_PTR nStackReserve; + ULONG_PTR nStackCommit; + OBJECT_ATTRIBUTES oaThreadAttribs; + PIMAGE_NT_HEADERS pinhHeader = + RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); + + DPRINT + ( + "hProcess %08X\n" + "lpThreadAttributes %08X\n" + "dwStackSize %08X\n" + "lpStartAddress %08X\n" + "lpParameter %08X\n" + "dwCreationFlags %08X\n" + "lpThreadId %08X\n", + hProcess, + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId + ); + + /* FIXME: do more checks - e.g. the image may not have an optional header */ + if(pinhHeader == NULL) + { + nStackReserve = 0x100000; + nStackCommit = PAGE_SIZE; + } + else + { + nStackReserve = pinhHeader->OptionalHeader.SizeOfStackReserve; + nStackCommit = pinhHeader->OptionalHeader.SizeOfStackCommit; + } + + /* FIXME: this should be defined in winbase.h */ +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 #endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - - /* size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; - - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(hProcess, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - DPRINT("StackDeallocation: %p ReserveSize: 0x%lX\n", - InitialTeb.StackDeallocation, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - DPRINT("StackBase: %p\nStackCommit: 0x%lX\n", - InitialTeb.StackBase, - InitialTeb.StackCommit); - - /* Commit stack pages */ - Status = NtAllocateVirtualMemory(hProcess, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page(s)!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - DPRINT("StackLimit: %p\n", - InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(hProcess, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = (LONG)ThreadStartup; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = TEB_SELECTOR; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 12; - ThreadContext.EFlags = (1<<1) + (1<<9); - - /* initialize call stack */ - *((PULONG)((ULONG)InitialTeb.StackBase - 4)) = (ULONG)lpParameter; - *((PULONG)((ULONG)InitialTeb.StackBase - 8)) = (ULONG)lpStartAddress; - *((PULONG)((ULONG)InitialTeb.StackBase - 12)) = 0xdeadbeef; - - DPRINT("Esp: %p\n", ThreadContext.Esp); - DPRINT("Eip: %p\n", ThreadContext.Eip); - - Status = NtCreateThread(&ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - hProcess, - &ClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("NtCreateThread() failed!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - if (lpThreadId != NULL) - memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG)); - - return(ThreadHandle); + /* use defaults */ + if(dwStackSize == 0); + /* dwStackSize specifies the size to reserve */ + else if(dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) + nStackReserve = dwStackSize; + /* dwStackSize specifies the size to commit */ + else + nStackCommit = dwStackSize; + + /* fix the stack reserve size */ + if(nStackCommit > nStackReserve) + nStackReserve = ROUNDUP(nStackCommit, 0x100000); + + /* initialize the attributes for the thread object */ + InitializeObjectAttributes + ( + &oaThreadAttribs, + NULL, + 0, + NULL, + NULL + ); + + if(lpThreadAttributes) + { + /* make the handle inheritable */ + if(lpThreadAttributes->bInheritHandle) + oaThreadAttribs.Attributes |= OBJ_INHERIT; + + /* user-defined security descriptor */ + oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor; + } + + DPRINT + ( + "RtlRosCreateUserThreadVa\n" + "(\n" + " ProcessHandle %p,\n" + " ObjectAttributes %p,\n" + " CreateSuspended %d,\n" + " StackZeroBits %d,\n" + " StackReserve %lu,\n" + " StackCommit %lu,\n" + " StartAddress %p,\n" + " ThreadHandle %p,\n" + " ClientId %p,\n" + " ParameterCount %u,\n" + " Parameters[0] %p,\n" + " Parameters[1] %p\n" + ")\n", + hProcess, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + nStackReserve, + nStackCommit, + ThreadStartup, + &hThread, + &cidClientId, + 2, + lpStartAddress, + lpParameter + ); + + /* create the thread */ + nErrCode = RtlRosCreateUserThreadVa + ( + hProcess, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + &nStackReserve, + &nStackCommit, + (PTHREAD_START_ROUTINE)ThreadStartup, + &hThread, + &cidClientId, + 2, + lpStartAddress, + lpParameter + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return NULL; + } + + DPRINT + ( + "StackReserve %p\n" + "StackCommit %p\n" + "ThreadHandle %p\n" + "ClientId.UniqueThread %p\n", + nStackReserve, + nStackCommit, + hThread, + cidClientId.UniqueThread + ); + + /* success */ + if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; + return hThread; } - PTEB GetTeb(VOID) { @@ -477,27 +483,14 @@ WINBOOL STDCALL SetThreadPriority(HANDLE hThread, int nPriority) { - THREAD_BASIC_INFORMATION ThreadBasic; - ULONG DataWritten; + ULONG Prio = nPriority; NTSTATUS Status; - Status = NtQueryInformationThread(hThread, - ThreadBasicInformation, - &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION), - &DataWritten); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus(Status); - return(FALSE); - } - - ThreadBasic.BasePriority = nPriority; - Status = NtSetInformationThread(hThread, - ThreadBasicInformation, - &ThreadBasic, - sizeof(THREAD_BASIC_INFORMATION)); + ThreadBasePriority, + &Prio, + sizeof(ULONG)); + if (!NT_SUCCESS(Status)) { SetLastErrorByStatus(Status); diff --git a/lib/kernel32/thread/tls.c b/lib/kernel32/thread/tls.c index 98b368f..2f83b20 100644 --- a/lib/kernel32/thread/tls.c +++ b/lib/kernel32/thread/tls.c @@ -72,12 +72,20 @@ TlsFree(DWORD dwTlsIndex) LPVOID STDCALL TlsGetValue(DWORD dwTlsIndex) { + LPVOID Value; + if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE) { SetLastErrorByStatus(STATUS_INVALID_PARAMETER); return(NULL); } - return(NtCurrentTeb()->TlsSlots[dwTlsIndex]); + + Value = NtCurrentTeb()->TlsSlots[dwTlsIndex]; + if (Value == 0) + { + SetLastError(NO_ERROR); + } + return Value; } WINBOOL STDCALL diff --git a/lib/makefile b/lib/makefile index 6a32b6c..4f582db 100644 --- a/lib/makefile +++ b/lib/makefile @@ -5,10 +5,10 @@ BASE_CFLAGS = -I../include all: $(LIBRARIES) ntdll: dummy - make -C ntdll + $(MAKE) -C ntdll kernel32: dummy - make -C kernel32 + $(MAKE) -C kernel32 dummy: diff --git a/lib/msafd/makefile b/lib/msafd/makefile index 6844b1e..734f881 100644 --- a/lib/msafd/makefile +++ b/lib/msafd/makefile @@ -20,23 +20,18 @@ TARGET_CFLAGS = \ TARGET_LFLAGS = -nostartfiles -nostdlib -TARGET_OBJECTS = $(TARGET_NAME).o +MISC_OBJECTS = \ + misc/dllmain.o misc/event.o misc/helpers.o \ + misc/sndrcv.o misc/stubs.o -TARGET_CLEAN = misc/*.o +TARGET_OBJECTS = $(MISC_OBJECTS) +DEP_OBJECTS = $(TARGET_OBJECTS) include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk - -MISC_OBJECTS = \ - misc/dllmain.o misc/event.o misc/helpers.o \ - misc/sndrcv.o misc/stubs.o - -OBJECTS = $(MISC_OBJECTS) - -$(TARGET_NAME).o: $(OBJECTS) - $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o +include $(TOOLS_PATH)/depend.mk # EOF diff --git a/lib/msafd/misc/.cvsignore b/lib/msafd/misc/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/msafd/misc/.cvsignore +++ b/lib/msafd/misc/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/msvcrt/Makefile b/lib/msvcrt/Makefile index 6b5916d..a176257 100644 --- a/lib/msvcrt/Makefile +++ b/lib/msvcrt/Makefile @@ -34,6 +34,7 @@ TARGET_CLEAN = \ process/*.o \ search/*.o \ setjmp/*.o \ + setjmp/i386/*.o \ signal/*.o \ stdio/*.o \ stdlib/*.o \ @@ -173,7 +174,6 @@ MATH_OBJECTS = \ math/floor.o \ math/fmod.o \ math/frexp.o \ - math/ftol.o \ math/huge_val.o \ math/hypot.o \ math/j0_y0.o \ @@ -251,6 +251,7 @@ MISC_OBJECTS = \ misc/amsg.o \ misc/assert.o \ misc/crtmain.o \ + misc/cpp.o \ misc/dllmain.o \ misc/environ.o \ misc/getargs.o \ @@ -273,7 +274,7 @@ SEARCH_OBJECTS = \ search/lsearch.o SETJMP_OBJECTS = \ - setjmp/setjmp.o + setjmp/i386/setjmp.o SIGNAL_OBJECTS = \ signal/signal.o diff --git a/lib/msvcrt/ctype/toupper.c b/lib/msvcrt/ctype/toupper.c index 0b926b8..7b05bad 100644 --- a/lib/msvcrt/ctype/toupper.c +++ b/lib/msvcrt/ctype/toupper.c @@ -11,7 +11,7 @@ int toupper(int c) } #undef towupper -wchar_t towupper(wchar_t c) +int towupper(wint_t c) { if (iswctype (c, _LOWER)) return (c + (L'A' - L'a')); diff --git a/lib/msvcrt/except/seh.s b/lib/msvcrt/except/seh.s index da4008c..5e8e785 100755 --- a/lib/msvcrt/except/seh.s +++ b/lib/msvcrt/except/seh.s @@ -56,6 +56,7 @@ .globl __local_unwind2 .globl __except_handler3 +.globl __EH_prolog // EAX = value to print _do_debug: @@ -364,3 +365,15 @@ _except_finish: // We should never get here ret + +// Copied from Wine. +__EH_prolog: + pushl $-1 + pushl %eax + pushl %fs:0 + movl %esp, %fs:0 + movl 12(%esp), %eax + movl %ebp, 12(%esp) + leal 12(%esp), %ebp + pushl %eax + ret diff --git a/lib/msvcrt/math/ftol.c b/lib/msvcrt/math/ftol.c deleted file mode 100644 index 1753090..0000000 --- a/lib/msvcrt/math/ftol.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -long _ftol(double fl) -{ - return (long)fl; -} diff --git a/lib/msvcrt/misc/cpp.c b/lib/msvcrt/misc/cpp.c new file mode 100644 index 0000000..2f86892 --- /dev/null +++ b/lib/msvcrt/misc/cpp.c @@ -0,0 +1,533 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS C runtime + * FILE: cpp.c + * PURPOSE: C++ runtime + * PROGRAMMERS: Ge van Geldorp (ge@gse.nl) + * NOTES: Copied from Wine and slightly adapter for ReactOS + */ + +#include +#include +#include + +#define CXX_FRAME_MAGIC 0x19930520 +#define CXX_EXCEPTION 0xe06d7363 + +typedef void (*v_table_ptr)(); + +typedef struct __type_info +{ + v_table_ptr *vtable; + void *data; + char name[1]; +} type_info; + +/* the exception frame used by CxxFrameHandler */ +typedef struct __cxx_exception_frame +{ + EXCEPTION_REGISTRATION frame; /* the standard exception frame */ + int trylevel; + DWORD ebp; +} cxx_exception_frame; + +/* info about a single catch {} block */ +typedef struct __catchblock_info +{ + UINT flags; /* flags (see below) */ + type_info *type_info; /* C++ type caught by this block */ + int offset; /* stack offset to copy exception object to */ + void (*handler)(); /* catch block handler code */ +} catchblock_info; +#define TYPE_FLAG_CONST 1 +#define TYPE_FLAG_VOLATILE 2 +#define TYPE_FLAG_REFERENCE 8 + +/* info about a single try {} block */ +typedef struct __tryblock_info +{ + int start_level; /* start trylevel of that block */ + int end_level; /* end trylevel of that block */ + int catch_level; /* initial trylevel of the catch block */ + int catchblock_count; /* count of catch blocks in array */ + catchblock_info *catchblock; /* array of catch blocks */ +} tryblock_info; + +/* info about the unwind handler for a given trylevel */ +typedef struct __unwind_info +{ + int prev; /* prev trylevel unwind handler, to run after this one */ + void (*handler)(); /* unwind handler */ +} unwind_info; + +/* descriptor of all try blocks of a given function */ +typedef struct __cxx_function_descr +{ + UINT magic; /* must be CXX_FRAME_MAGIC */ + UINT unwind_count; /* number of unwind handlers */ + unwind_info *unwind_table; /* array of unwind handlers */ + UINT tryblock_count; /* number of try blocks */ + tryblock_info *tryblock; /* array of try blocks */ + UINT unknown[3]; +} cxx_function_descr; + +/* complete information about a C++ type */ +typedef struct __cxx_type_info +{ + UINT flags; /* flags (see CLASS_* flags below) */ + type_info *type_info; /* C++ type info */ + int this_offset; /* offset of base class this pointer from start of object */ + int vbase_descr; /* offset of virtual base class descriptor */ + int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ + size_t size; /* object size */ + void (*copy_ctor)(); /* copy constructor */ +} cxx_type_info; +#define CLASS_IS_SIMPLE_TYPE 1 +#define CLASS_HAS_VIRTUAL_BASE_CLASS 4 + +/* table of C++ types that apply for a given object */ +typedef struct __cxx_type_info_table +{ + UINT count; /* number of types */ + cxx_type_info *info[1]; /* array of types */ +} cxx_type_info_table; + +typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame*, + PCONTEXT, PEXCEPTION_REGISTRATION*, + cxx_function_descr*, int nested_trylevel, + PEXCEPTION_REGISTRATION nested_frame, + DWORD unknown3 ); + +/* type information for an exception object */ +typedef struct __cxx_exception_type +{ + UINT flags; /* TYPE_FLAG flags */ + void (*destructor)(); /* exception object destructor */ + cxx_exc_custom_handler custom_handler; /* custom handler for this exception */ + cxx_type_info_table *type_info_table; /* list of types for this exception object */ +} cxx_exception_type; + +/* ??1type_info@@UAE@XZ (MSVCRT.@) */ +void MSVCRT_type_info_dtor(type_info * _this) +{ + if (_this->data) + { + free(_this->data); + } +} + +static DWORD cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame, + PCONTEXT exc_context, PEXCEPTION_REGISTRATION* dispatch, + cxx_function_descr *descr, PEXCEPTION_REGISTRATION nested_frame, + int nested_trylevel, CONTEXT_X86 *context ); + +/* call a function with a given ebp */ +inline static void *call_ebp_func( void *func, void *ebp ) +{ + void *ret; + __asm__ __volatile__ ("pushl %%ebp; movl %2,%%ebp; call *%%eax; popl %%ebp" \ + : "=a" (ret) : "0" (func), "g" (ebp) : "ecx", "edx", "memory" ); + return ret; +} + +/* call a copy constructor */ +inline static void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) +{ +#if 0 + TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); +#endif + if (has_vbase) + /* in that case copy ctor takes an extra bool indicating whether to copy the base class */ + __asm__ __volatile__("pushl $1; pushl %2; call *%0" + : : "r" (func), "c" (this), "g" (src) : "eax", "edx", "memory" ); + else + __asm__ __volatile__("pushl %2; call *%0" + : : "r" (func), "c" (this), "g" (src) : "eax", "edx", "memory" ); +} + +/* call the destructor of the exception object */ +inline static void call_dtor( void *func, void *object ) +{ + __asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" ); +} + + +static void dump_type( cxx_type_info *type ) +{ +#if 0 + DPRINTF( "flags %x type %p", type->flags, type->type_info ); + if (type->type_info) DPRINTF( " (%p %s)", type->type_info->data, type->type_info->name ); + DPRINTF( " offset %d vbase %d,%d size %d copy ctor %p\n", type->this_offset, + type->vbase_descr, type->vbase_offset, type->size, type->copy_ctor ); +#endif +} + +static void dump_exception_type( cxx_exception_type *type ) +{ +#if 0 + int i; + + DPRINTF( "exception type:\n" ); + DPRINTF( "flags %x destr %p handler %p type info %p\n", + type->flags, type->destructor, type->custom_handler, type->type_info_table ); + for (i = 0; i < type->type_info_table->count; i++) + { + DPRINTF( " %d: ", i ); + dump_type( type->type_info_table->info[i] ); + } +#endif +} + +static void dump_function_descr( cxx_function_descr *descr, cxx_exception_type *info ) +{ +#if 0 + int i, j; + + DPRINTF( "function descr:\n" ); + DPRINTF( "magic %x\n", descr->magic ); + DPRINTF( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count ); + for (i = 0; i < descr->unwind_count; i++) + { + DPRINTF( " %d: prev %d func %p\n", i, + descr->unwind_table[i].prev, descr->unwind_table[i].handler ); + } + DPRINTF( "try table: %p %d\n", descr->tryblock, descr->tryblock_count ); + for (i = 0; i < descr->tryblock_count; i++) + { + DPRINTF( " %d: start %d end %d catchlevel %d catch %p %d\n", i, + descr->tryblock[i].start_level, descr->tryblock[i].end_level, + descr->tryblock[i].catch_level, descr->tryblock[i].catchblock, + descr->tryblock[i].catchblock_count ); + for (j = 0; j < descr->tryblock[i].catchblock_count; j++) + { + catchblock_info *ptr = &descr->tryblock[i].catchblock[j]; + DPRINTF( " %d: flags %x offset %d handler %p type %p", + j, ptr->flags, ptr->offset, ptr->handler, ptr->type_info ); + if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info->data, ptr->type_info->name ); + DPRINTF( "\n" ); + } + } +#endif +} + +/* compute the this pointer for a base class of a given type */ +static void *get_this_pointer( cxx_type_info *type, void *object ) +{ + void *this_ptr; + int *offset_ptr; + + if (!object) return NULL; + this_ptr = (char *)object + type->this_offset; + if (type->vbase_descr >= 0) + { + /* move this ptr to vbase descriptor */ + this_ptr = (char *)this_ptr + type->vbase_descr; + /* and fetch additional offset from vbase descriptor */ + offset_ptr = (int *)(*(char **)this_ptr + type->vbase_offset); + this_ptr = (char *)this_ptr + *offset_ptr; + } + return this_ptr; +} + +/* check if the exception type is caught by a given catch block, and return the type that matched */ +static cxx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock ) +{ + UINT i; + + for (i = 0; i < exc_type->type_info_table->count; i++) + { + cxx_type_info *type = exc_type->type_info_table->info[i]; + + if (!catchblock->type_info) return type; /* catch(...) matches any type */ + if (catchblock->type_info != type->type_info) + { + if (strcmp( catchblock->type_info->name, type->type_info->name )) continue; + } + /* type is the same, now check the flags */ + if ((exc_type->flags & TYPE_FLAG_CONST) && + !(catchblock->flags & TYPE_FLAG_CONST)) continue; + if ((exc_type->flags & TYPE_FLAG_VOLATILE) && + !(catchblock->flags & TYPE_FLAG_VOLATILE)) continue; + return type; /* it matched */ + } + return NULL; +} + + +/* copy the exception object where the catch block wants it */ +static void copy_exception( void *object, cxx_exception_frame *frame, + catchblock_info *catchblock, cxx_type_info *type ) +{ + void **dest_ptr; + + if (!catchblock->type_info || !catchblock->type_info->name[0]) return; + if (!catchblock->offset) return; + dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset); + + if (catchblock->flags & TYPE_FLAG_REFERENCE) + { + *dest_ptr = get_this_pointer( type, object ); + } + else if (type->flags & CLASS_IS_SIMPLE_TYPE) + { + memmove( dest_ptr, object, type->size ); + /* if it is a pointer, adjust it */ + if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( type, *dest_ptr ); + } + else /* copy the object */ + { + if (type->copy_ctor) + call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(type,object), + (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) ); + else + memmove( dest_ptr, get_this_pointer(type,object), type->size ); + } +} + +/* unwind the local function up to a given trylevel */ +static void cxx_local_unwind( cxx_exception_frame* frame, cxx_function_descr *descr, int last_level) +{ + void (*handler)(); + int trylevel = frame->trylevel; + + while (trylevel != last_level) + { + if (trylevel < 0 || trylevel >= descr->unwind_count) + { + OutputDebugString( "invalid trylevel\n" ); + _exit(1); + } + handler = descr->unwind_table[trylevel].handler; + if (handler) + { +#if 0 + TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n", + handler, trylevel, last_level, &frame->ebp ); +#endif + call_ebp_func( handler, &frame->ebp ); + } + trylevel = descr->unwind_table[trylevel].prev; + } + frame->trylevel = last_level; +} + +/* exception frame for nested exceptions in catch block */ +struct catch_func_nested_frame +{ + EXCEPTION_REGISTRATION frame; /* standard exception frame */ + EXCEPTION_RECORD *prev_rec; /* previous record to restore in thread data */ + cxx_exception_frame *cxx_frame; /* frame of parent exception */ + cxx_function_descr *descr; /* descriptor of parent exception */ + int trylevel; /* current try level */ +}; + +/* handler for exceptions happening while calling a catch function */ +static EXCEPTION_DISPOSITION catch_function_nested_handler(PEXCEPTION_RECORD rec, + PEXCEPTION_REGISTRATION frame, + PCONTEXT context, + PVOID DispatcherContext) +{ + struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame; + + if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) + { + GetThreadData()->exc_record = nested_frame->prev_rec; + return ExceptionContinueSearch; + } + else + { +#if 0 + TRACE( "got nested exception in catch function\n" ); +#endif + return cxx_frame_handler( rec, nested_frame->cxx_frame, context, + NULL, nested_frame->descr, &nested_frame->frame, + nested_frame->trylevel, context ); + } +} + +static inline PEXCEPTION_REGISTRATION __wine_push_frame( PEXCEPTION_REGISTRATION frame ) +{ +#if defined(__GNUC__) && defined(__i386__) + PEXCEPTION_REGISTRATION prev; + __asm__ __volatile__(".byte 0x64\n\tmovl (0),%0" + "\n\tmovl %0,(%1)" + "\n\t.byte 0x64\n\tmovl %1,(0)" + : "=&r" (prev) : "r" (frame) : "memory" ); + return prev; +#else + NT_TIB *teb = (NT_TIB *)NtCurrentTeb(); + frame->prev = (void *)teb->ExceptionList; + teb->ExceptionList = (void *)frame; + return frame->prev; +#endif +} + +static inline PEXCEPTION_REGISTRATION __wine_pop_frame( PEXCEPTION_REGISTRATION frame ) +{ +#if defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__(".byte 0x64\n\tmovl %0,(0)" + : : "r" (frame->prev) : "memory" ); + return frame->prev; + +#else + NT_TIB *teb = (NT_TIB *)NtCurrentTeb(); + teb->ExceptionList = (void *)frame->prev; + return frame->prev; +#endif +} + +/* find and call the appropriate catch block for an exception */ +/* returns the address to continue execution to after the catch block was called */ +inline static void *call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame, + cxx_function_descr *descr, int nested_trylevel, + cxx_exception_type *info ) +{ + int i, j; + void *addr, *object = (void *)rec->ExceptionInformation[1]; + struct catch_func_nested_frame nested_frame; + int trylevel = frame->trylevel; + PTHREADDATA thread_data = GetThreadData(); + + for (i = 0; i < descr->tryblock_count; i++) + { + tryblock_info *tryblock = &descr->tryblock[i]; + + if (trylevel < tryblock->start_level) continue; + if (trylevel > tryblock->end_level) continue; + + /* got a try block */ + for (j = 0; j < tryblock->catchblock_count; j++) + { + catchblock_info *catchblock = &tryblock->catchblock[j]; + cxx_type_info *type = find_caught_type( info, catchblock ); + if (!type) continue; + +#if 0 + TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j ); +#endif + + /* copy the exception to its destination on the stack */ + copy_exception( object, frame, catchblock, type ); + + /* unwind the stack */ + RtlUnwind( &(frame->frame), 0, rec, 0 ); + cxx_local_unwind( frame, descr, tryblock->start_level ); + frame->trylevel = tryblock->end_level + 1; + + /* call the catch block */ +#if 0 + TRACE( "calling catch block %p for type %p addr %p ebp %p\n", + catchblock, type, catchblock->handler, &frame->ebp ); +#endif + + /* setup an exception block for nested exceptions */ + + nested_frame.frame.handler = catch_function_nested_handler; + nested_frame.prev_rec = thread_data->exc_record; + nested_frame.cxx_frame = frame; + nested_frame.descr = descr; + nested_frame.trylevel = nested_trylevel + 1; + + __wine_push_frame( &nested_frame.frame ); + thread_data->exc_record = rec; + addr = call_ebp_func( catchblock->handler, &frame->ebp ); + thread_data->exc_record = nested_frame.prev_rec; + __wine_pop_frame( &nested_frame.frame ); + + if (info->destructor) call_dtor( info->destructor, object ); +#if 0 + TRACE( "done, continuing at %p\n", addr ); +#endif + return addr; + } + } + return NULL; +} + + +/********************************************************************* + * cxx_frame_handler + * + * Implementation of __CxxFrameHandler. + */ +static DWORD cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame, + PCONTEXT exc_context, PEXCEPTION_REGISTRATION* dispatch, + cxx_function_descr *descr, PEXCEPTION_REGISTRATION nested_frame, + int nested_trylevel, CONTEXT_X86 *context ) +{ + cxx_exception_type *exc_type; + void *next_ip; + + if (descr->magic != CXX_FRAME_MAGIC) + { + OutputDebugString( "invalid frame magic\n" ); + return ExceptionContinueSearch; + } + if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) + { + if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 ); + return ExceptionContinueSearch; + } + if (!descr->tryblock_count) return ExceptionContinueSearch; + + exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; + if (rec->ExceptionCode == CXX_EXCEPTION && + rec->ExceptionInformation[0] > CXX_FRAME_MAGIC && + exc_type->custom_handler) + { + return exc_type->custom_handler( rec, frame, exc_context, dispatch, + descr, nested_trylevel, nested_frame, 0 ); + } + + if (!exc_type) /* nested exception, fetch info from original exception */ + { + rec = GetThreadData()->exc_record; + exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; + } + +#if 0 + if (TRACE_ON(seh)) + { + TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n", + rec, frame, frame->trylevel, descr, nested_frame ); + dump_exception_type( exc_type ); + dump_function_descr( descr, exc_type ); + } +#endif + + next_ip = call_catch_block( rec, frame, descr, frame->trylevel, exc_type ); + + if (!next_ip) return ExceptionContinueSearch; + rec->ExceptionFlags &= ~EH_NONCONTINUABLE; + context->Eip = (DWORD)next_ip; + context->Ebp = (DWORD)&frame->ebp; + context->Esp = ((DWORD*)frame)[-1]; + return ExceptionContinueExecution; +} + + +/********************************************************************* + * __CxxFrameHandler (MSVCRT.@) + */ +void __CxxFrameHandler( PEXCEPTION_RECORD rec, PEXCEPTION_REGISTRATION frame, + PCONTEXT exc_context, PEXCEPTION_REGISTRATION* dispatch, + CONTEXT_X86 *context ) +{ + cxx_function_descr *descr = (cxx_function_descr *)context->Eax; + context->Eax = cxx_frame_handler( rec, (cxx_exception_frame *)frame, + exc_context, dispatch, descr, NULL, 0, context ); +} + +/********************************************************************* + * _CxxThrowException (MSVCRT.@) + */ +void _CxxThrowException( void *object, cxx_exception_type *type ) +{ + DWORD args[3]; + + args[0] = CXX_FRAME_MAGIC; + args[1] = (DWORD)object; + args[2] = (DWORD)type; + RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); +} diff --git a/lib/msvcrt/misc/crtmain.c b/lib/msvcrt/misc/crtmain.c index 2693522..02e5af2 100644 --- a/lib/msvcrt/misc/crtmain.c +++ b/lib/msvcrt/misc/crtmain.c @@ -31,21 +31,8 @@ _local_unwind2(void) return 0; } -int -STDCALL -_spawnlp(int a, const char* b, const char* args, ...) -{ - return 0; -} - #else /*__GNUC__*/ -int -_spawnlp(int a, const char* b, const char* args, ...) -{ - return 0; -} - #endif /*__GNUC__*/ diff --git a/lib/msvcrt/misc/dllmain.c b/lib/msvcrt/misc/dllmain.c index 65f908e..c23e4e0 100644 --- a/lib/msvcrt/misc/dllmain.c +++ b/lib/msvcrt/misc/dllmain.c @@ -42,6 +42,7 @@ extern unsigned int _winver; extern char* _acmdln; /* pointer to ascii command line */ #undef _environ extern char** _environ; /* pointer to environment block */ +extern char** __initenv; /* pointer to initial environment block */ /* LIBRARY GLOBAL VARIABLES ***************************************************/ @@ -125,7 +126,11 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) /* destroy heap */ if (nAttachCount == 0) { - + if (__initenv && __initenv != _environ) + { + free(__initenv); + __initenv = NULL; + } if (_environ) { FreeEnvironmentStringsA(_environ[0]); diff --git a/lib/msvcrt/misc/environ.c b/lib/msvcrt/misc/environ.c index 7dc8d43..df0fef9 100644 --- a/lib/msvcrt/misc/environ.c +++ b/lib/msvcrt/misc/environ.c @@ -44,9 +44,13 @@ int BlockEnvToEnviron(void) if (_environ) { FreeEnvironmentStringsA(_environ[0]); - free(_environ); - _environ = NULL; + if (__initenv == _environ) { + __initenv[0] == NULL; + } else { + free(_environ); + } } + _environ = NULL; ptr2 = ptr = (char*)GetEnvironmentStringsA(); if (ptr == NULL) { DPRINT("GetEnvironmentStringsA() returnd NULL\n"); @@ -67,6 +71,10 @@ int BlockEnvToEnviron(void) while (*ptr++); } _environ[i] = NULL; + if (__initenv == NULL) + { + __initenv = _environ; + } return 0; } diff --git a/lib/msvcrt/misc/getargs.c b/lib/msvcrt/misc/getargs.c index b48b72b..9ce3a2c 100644 --- a/lib/msvcrt/misc/getargs.c +++ b/lib/msvcrt/misc/getargs.c @@ -45,7 +45,7 @@ int add(char* name) return 0; } -int expand(char* name) +int expand(char* name, int flag) { char* s; WIN32_FIND_DATA fd; @@ -55,7 +55,7 @@ int expand(char* name) int pos; s = strpbrk(name, "*?"); - if (s) { + if (s && flag) { hFile = FindFirstFile(name, &fd); if (hFile != INVALID_HANDLE_VALUE) { while(s != name && *s != '/' && *s != '\\') @@ -98,7 +98,7 @@ int __getmainargs(int* argc, char*** argv, char*** env, int flag) while (_acmdln[i]) { if (_acmdln[i] == ' ') { - expand(strndup(_acmdln + afterlastspace, i - afterlastspace)); + expand(strndup(_acmdln + afterlastspace, i - afterlastspace), flag); i++; while (_acmdln[i]==' ') i++; @@ -109,7 +109,7 @@ int __getmainargs(int* argc, char*** argv, char*** env, int flag) } if (_acmdln[afterlastspace] != 0) { - expand(strndup(_acmdln+afterlastspace, i - afterlastspace)); + expand(strndup(_acmdln+afterlastspace, i - afterlastspace), flag); } HeapValidate(hHeap, 0, NULL); *argc = __argc; diff --git a/lib/msvcrt/msvcrt.def b/lib/msvcrt/msvcrt.def index c51ce23..e74c312 100644 --- a/lib/msvcrt/msvcrt.def +++ b/lib/msvcrt/msvcrt.def @@ -21,9 +21,11 @@ EXPORTS ; ??1bad_cast@@UAE@XZ ; ??1bad_typeid@@UAE@XZ ; ??1exception@@UAE@XZ -; ??1type_info@@UAE@XZ -; ??2@YAPAXI@Z -; ??3@YAXPAX@Z +??1type_info@@UAE@XZ=MSVCRT_type_info_dtor +??2@YAPAXI@Z=MSVCRT_operator_new +??_U@YAPAXI@Z=MSVCRT_operator_new +??3@YAXPAX@Z=MSVCRT_operator_delete +??_V@YAXPAX@Z=MSVCRT_operator_delete ; ??4__non_rtti_object@@QAEAAV0@ABV0@@Z ; ??4bad_cast@@QAEAAV0@ABV0@@Z ; ??4bad_typeid@@QAEAAV0@ABV0@@Z @@ -44,8 +46,8 @@ EXPORTS ; ??_Gexception@@UAEPAXI@Z ; ?_query_new_handler@@YAP6AHI@ZXZ ; ?_query_new_mode@@YAHXZ -; ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z -; ?_set_new_mode@@YAHH@Z +?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z=MSVCRT__set_new_handler +?_set_new_mode@@YAHH@Z=MSVCRT__set_new_mode ; ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z ; ?before@type_info@@QBEHABV1@@Z ; ?name@type_info@@QBEPBDXZ @@ -75,15 +77,15 @@ _CIsinh _CIsqrt _CItan _CItanh -; _CxxThrowException -; _EH_prolog +_CxxThrowException +_EH_prolog ; _Getdays ; _Getmonths ; _Gettnames _HUGE DATA ; _Strftime _XcptFilter -; __CxxFrameHandler +__CxxFrameHandler ; __CxxLongjmpUnwind ; __RTCastToVoid ; __RTDynamicCast @@ -122,7 +124,7 @@ __p__commode __p__environ ; __p__fileinfo __p__fmode -; __p__iob +__p__iob ; __p__mbcasemap ; __p__mbctype __p__osver @@ -251,7 +253,7 @@ _fsopen _fstat _fstati64 ; _ftime -_ftol +_ftol=NTDLL._ftol _fullpath _futime _gcvt @@ -434,7 +436,7 @@ _searchenv ; _set_sbh_threshold _seterrormode _setjmp -; _setjmp3 +_setjmp3 ; _setmaxstdio ; _setmbcp _setmode diff --git a/lib/msvcrt/process/process.c b/lib/msvcrt/process/process.c index 6590cac..b088618 100644 --- a/lib/msvcrt/process/process.c +++ b/lib/msvcrt/process/process.c @@ -150,6 +150,7 @@ valisttos(const char* arg0, va_list alist, char delim) { len = strlen(arg0); memcpy(ptr, arg0, len); + ptr += len; *ptr++ = delim; arg0 = va_arg(alist2, char*); } @@ -385,6 +386,26 @@ int _spawnvp(int mode, const char* cmdname, char* const* argv) return _spawnv(mode, find_exec(cmdname, pathname), argv); } +int _spawnlp(int mode, const char* cmdname, const char* arg0, .../*, NULL*/) +{ + va_list argp; + char* args; + int ret = -1; + char pathname[FILENAME_MAX]; + + DPRINT("_spawnlp('%s')\n", cmdname); + + va_start(argp, arg0); + args = valisttos(arg0, argp, ' '); + if (args) + { + ret = do_spawn(mode, find_exec(cmdname, pathname), args, NULL); + free(args); + } + return ret; +} + + int _spawnlpe(int mode, const char* cmdname, const char* arg0, .../*, NULL, const char* const* envp*/) { va_list argp; diff --git a/lib/msvcrt/process/threadx.c b/lib/msvcrt/process/threadx.c index 12a63f6..3d92997 100644 --- a/lib/msvcrt/process/threadx.c +++ b/lib/msvcrt/process/threadx.c @@ -14,13 +14,30 @@ unsigned long _beginthreadex( unsigned initflag, unsigned* thrdaddr) { + HANDLE NewThread; + + /* + * Just call the API function. Any CRT specific processing is done in + * DllMain DLL_THREAD_ATTACH + */ + NewThread = CreateThread(security, stack_size, start_address, arglist, initflag, thrdaddr); + if (NULL == NewThread) + { + /* FIXME map GetLastError() to errno */ errno = ENOSYS; - return (unsigned long)-1; + } + + return (unsigned long) NewThread; } void _endthreadex(unsigned retval) { + /* + * Just call the API function. Any CRT specific processing is done in + * DllMain DLL_THREAD_DETACH + */ + ExitThread(retval); } /* EOF */ diff --git a/lib/msvcrt/setjmp/.cvsignore b/lib/msvcrt/setjmp/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/lib/msvcrt/setjmp/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/lib/msvcrt/setjmp/i386/.cvsignore b/lib/msvcrt/setjmp/i386/.cvsignore new file mode 100644 index 0000000..2806cdc --- /dev/null +++ b/lib/msvcrt/setjmp/i386/.cvsignore @@ -0,0 +1,2 @@ +.*.d +*.o \ No newline at end of file diff --git a/lib/msvcrt/setjmp/i386/setjmp.s b/lib/msvcrt/setjmp/i386/setjmp.s new file mode 100644 index 0000000..2ac1d2d --- /dev/null +++ b/lib/msvcrt/setjmp/i386/setjmp.s @@ -0,0 +1,111 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * PURPOSE: Implementation of _setjmp/longjmp + * FILE: lib/msvcrt/i386/setjmp.s + * PROGRAMMER: Ge van Geldorp (ge@gse.nl) + * NOTES: Implementation is not complete, see Wine source for a more + * complete implementation + */ + +#define JB_BP 0 +#define JB_BX 1 +#define JB_DI 2 +#define JB_SI 3 +#define JB_SP 4 +#define JB_IP 5 + +#define PCOFF 0 + +#define JMPBUF 4 + +/* + * int + * _setjmp(jmp_buf env); + * + * Parameters: + * [ESP+04h] - jmp_buf env + * Registers: + * None + * Returns: + * 0 + * Notes: + * Sets up the jmp_buf + */ +.globl __setjmp +__setjmp: + xorl %eax, %eax + movl JMPBUF(%esp), %edx + + /* Save registers. */ + movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ + movl %ebx, (JB_BX*4)(%edx) + movl %edi, (JB_DI*4)(%edx) + movl %esi, (JB_SI*4)(%edx) + leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ + movl %ecx, (JB_SP*4)(%edx) + movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */ + movl %ecx, (JB_IP*4)(%edx) + ret + +/* + * int + * _setjmp3(jmp_buf env, int nb_args, ...); + * + * Parameters: + * [ESP+04h] - jmp_buf env + * Registers: + * None + * Returns: + * 0 + * Notes: + * Sets up the jmp_buf + */ +.globl __setjmp3 +__setjmp3: + xorl %eax, %eax + movl JMPBUF(%esp), %edx + + /* Save registers. */ + movl %ebp, (JB_BP*4)(%edx) /* Save caller's frame pointer. */ + movl %ebx, (JB_BX*4)(%edx) + movl %edi, (JB_DI*4)(%edx) + movl %esi, (JB_SI*4)(%edx) + leal JMPBUF(%esp), %ecx /* Save SP as it will be after we return. */ + movl %ecx, (JB_SP*4)(%edx) + movl PCOFF(%esp), %ecx /* Save PC we are returning to now. */ + movl %ecx, (JB_IP*4)(%edx) + ret + +#define VAL 8 + +/* + * void + * longjmp(jmp_buf env, int value); + * + * Parameters: + * [ESP+04h] - jmp_buf setup by _setjmp + * [ESP+08h] - int value to return + * Registers: + * None + * Returns: + * Doesn't return + * Notes: + * Non-local goto + */ +.globl _longjmp +_longjmp: + movl JMPBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ + + movl VAL(%esp), %eax /* Second argument is return value. */ + /* Save the return address now. */ + movl (JB_IP*4)(%ecx), %edx + /* Restore registers. */ + movl (JB_BP*4)(%ecx), %ebp + movl (JB_BX*4)(%ecx), %ebx + movl (JB_DI*4)(%ecx), %edi + movl (JB_SI*4)(%ecx), %esi + movl (JB_SP*4)(%ecx), %esp + /* Jump to saved PC. */ + jmp *%edx diff --git a/lib/msvcrt/setjmp/setjmp.c b/lib/msvcrt/setjmp/setjmp.c deleted file mode 100644 index 25202e2..0000000 --- a/lib/msvcrt/setjmp/setjmp.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -/* modified by Boudewijn Dekker */ -/* ms uses a smaller jmp_buf structure */ -/* might do a realloc in setjmp */ - -typedef struct { - unsigned int __eax, __ebx, __ecx, __edx, __esi; - unsigned int __edi, __ebp, __esp, __eip, __eflags; - unsigned short __cs, __ds, __es, __fs, __gs, __ss; - unsigned long __sigmask; /* for POSIX signals only */ - unsigned long __signum; /* for expansion */ - unsigned long __exception_ptr; /* pointer to previous exception */ - unsigned char __fpu_state[108]; /* for future use */ -} jmp_buf[1]; - - -/* jumps back to position specified in jmp_buf */ - -int longjmp( jmp_buf env, int value ) -{ - //push ebp generated by the compiler - //mov ebp, esp - -#ifdef __GNUC__ - __asm__ __volatile__ ( - "movl 8(%ebp),%edi\n\t" /* get jmp_buf */ - "movl 12(%ebp),%eax\n\t" /* store retval in j->eax */ - "movl %eax,0(%edi)\n\t" - - "movw 46(%edi),%fs\n\t" - "movw 48(%edi),%gs\n\t" - "movl 4(%edi),%ebx\n\t" - "movl 8(%edi),%ecx\n\t" - "movl 12(%edi),%edx\n\t" - "movl 24(%edi),%ebp\n\t" - - /* Now for some uglyness. The jmp_buf structure may be ABOVE the - point on the new SS:ESP we are moving to. We don't allow overlap, - but do force that it always be valid. We will use ES:ESI for - our new stack before swapping to it. */ - - "movw 50(%edi),%es\n\t" - "movl 28(%edi),%esi\n\t" - "subl $28,%esi\n\t" /* We need 7 working longwords on stack */ - - "movl 60(%edi),%eax\n\t" - "es\n\t" - "movl %eax,(%esi)\n\t" /* Exception pointer */ - - "movzwl 42(%edi),%eax\n\t" - "es\n\t" - "movl %eax,4(%esi)\n\t" /* DS */ - - "movl 20(%edi),%eax\n\t" - "es\n\t" - "movl %eax,8(%esi)\n\t" /* EDI */ - - "movl 16(%edi),%eax\n\t" - "es\n\t" - "movl %eax,12(%esi)\n\t" /* ESI */ - - "movl 32(%edi),%eax\n\t" - "es\n\t" - "movl %eax,16(%esi)\n\t" /* EIP - start of IRET frame */ - - "movl 40(%edi),%eax\n\t" - "es\n\t" - "movl %eax,20(%esi)\n\t" /* CS */ - - "movl 36(%edi),%eax\n\t" - "es\n\t" - "movl %eax,24(%esi)\n\t" /* EFLAGS */ - - "movl 0(%edi),%eax\n\t" - "movw 44(%edi),%es\n\t" - - "movw 50(%edi),%ss\n\t" - "movl %esi,%esp\n\t" - - //"popl ___djgpp_exception_state_ptr\n\t" - "popl %edi\n\t" // dummy popl instead of djgpp_exception_state_ptr - "popl %ds\n\t" - "popl %edi\n\t" - "popl %esi\n\t" - - "iret\n\t" /* actually jump to new cs:eip loading flags */ - ); - -#else -#endif /*__GNUC__*/ - return value; // dummy return never reached -} - -#ifdef __GNUC__ - -int _setjmp( jmp_buf env ) -{ - //push ebp generated by the compiler - //mov ebp, esp - __asm__ __volatile__ ( - "pushl %edi\n\t" - "movl 8(%ebp),%edi\n\t" - - "movl %eax, (%edi)\n\t" - "movl %ebx,4(%edi)\n\t" - "movl %ecx,8(%edi)\n\t" - "movl %edx,12(%edi)\n\t" - "movl %esi,16(%edi)\n\t" - - "movl -4(%ebp),%eax\n\t" - "movl %eax,20(%edi)\n\t" - - "movl (%ebp),%eax\n\t" - "movl %eax,24(%edi)\n\t" - - "movl %esp,%eax\n\t" - "addl $12,%eax\n\t" - "movl %eax,28(%edi)\n\t" - - "movl 4(%ebp),%eax\n\t" - "movl %eax,32(%edi)\n\t" - - "pushfl\n\t" - "popl 36(%edi)\n\t" - - "movw %cs, 40(%edi)\n\t" - "movw %ds, 42(%edi)\n\t" - "movw %es, 44(%edi)\n\t" - "movw %fs, 46(%edi)\n\t" - "movw %gs, 48(%edi)\n\t" - "movw %ss, 50(%edi)\n\t" - - //movl ___djgpp_exception_state_ptr, %eax - //movl %eax, 60(%edi) - - "popl %edi\n\t" - ); - return 0; -} - -#else -#endif /*__GNUC__*/ diff --git a/lib/msvcrt/stdio/stdhnd.c b/lib/msvcrt/stdio/stdhnd.c index c4fc04d..be272fe 100644 --- a/lib/msvcrt/stdio/stdhnd.c +++ b/lib/msvcrt/stdio/stdhnd.c @@ -36,5 +36,7 @@ FILE _iob[5] = } }; - - +FILE *__p__iob(void) +{ + return &_iob[0]; +} diff --git a/lib/msvcrt/stdio/vfprintf.c b/lib/msvcrt/stdio/vfprintf.c index 971c5f1..b9aa7f0 100644 --- a/lib/msvcrt/stdio/vfprintf.c +++ b/lib/msvcrt/stdio/vfprintf.c @@ -307,10 +307,11 @@ static int numberf(FILE * f, double __n, char exp_sign, int size, int precision } else { while ( intr > 0.0 ) { + p = intr; intr/=10.0L; - p = modf(intr, &intr); + modf(intr, &intr); - p *=10; + p -= 10.0*intr; buf[i++] = (int)p + '0'; size--; @@ -510,10 +511,11 @@ static int numberfl(FILE * f, long double __n, char exp_sign, int size, int pre } else { while ( intr > 0.0 ) { + p=intr; intr/=10.0L; - p = modfl(intr, &intr); + modfl(intr, &intr); - p *=10; + p -= 10.0L*intr; buf[i++] = (int)p + '0'; size--; diff --git a/lib/msvcrt/stdio/vfwprint.c b/lib/msvcrt/stdio/vfwprint.c index bb2af01..ff70999 100644 --- a/lib/msvcrt/stdio/vfwprint.c +++ b/lib/msvcrt/stdio/vfwprint.c @@ -313,10 +313,11 @@ static int numberf(FILE * f, double __n, wchar_t exp_sign, int size, int precis } else { while ( intr > 0.0 ) { - intr/=10.0L; - p = modf(intr, &intr); + p = intr; + intr/=10.0L; + modf(intr, &intr); - p *=10; + p -= 10.0*intr; buf[i++] = (int)p + L'0'; size--; @@ -515,10 +516,11 @@ static int numberfl(FILE * f, long double __n, wchar_t exp_sign, int size, int } else { while ( intr > 0.0 ) { + p = intr; intr/=10.0L; - p = modfl(intr, &intr); + modfl(intr, &intr); - p *=10; + p -=10.0*intr; buf[i++] = (int)p + L'0'; size--; diff --git a/lib/msvcrt/stdlib/malloc.c b/lib/msvcrt/stdlib/malloc.c index 8353267..010d6f6 100644 --- a/lib/msvcrt/stdlib/malloc.c +++ b/lib/msvcrt/stdlib/malloc.c @@ -3,6 +3,40 @@ extern HANDLE hHeap; +typedef void (*MSVCRT_new_handler_func)(unsigned long size); +static MSVCRT_new_handler_func MSVCRT_new_handler; +static int MSVCRT_new_mode; + +/* ??2@YAPAXI@Z (MSVCRT.@) */ +void* MSVCRT_operator_new(unsigned long size) +{ + void *retval = HeapAlloc(GetProcessHeap(), 0, size); + +/* FIXME: LOCK_HEAP; */ + if(!retval && MSVCRT_new_handler) + (*MSVCRT_new_handler)(size); +/* FIXME: UNLOCK_HEAP; */ + + return retval; +} + +/* ??3@YAXPAX@Z (MSVCRT.@) */ +void MSVCRT_operator_delete(void *mem) +{ + HeapFree(GetProcessHeap(), 0, mem); +} + +/* ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@) */ +MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func) +{ + MSVCRT_new_handler_func old_handler; +/* FIXME: LOCK_HEAP; */ + old_handler = MSVCRT_new_handler; + MSVCRT_new_handler = func; +/* FIXME: UNLOCK_HEAP; */ + return old_handler; +} + void* malloc(size_t _size) { return HeapAlloc(hHeap, HEAP_ZERO_MEMORY, _size); @@ -19,6 +53,17 @@ void* calloc(size_t _nmemb, size_t _size) } void* realloc(void* _ptr, size_t _size) -{ +{ return HeapReAlloc(hHeap, 0, _ptr, _size); } + +/* ?_set_new_mode@@YAHH@Z (MSVCRT.@) */ +int MSVCRT__set_new_mode(int mode) +{ + int old_mode; +/* FIXME: LOCK_HEAP; */ + old_mode = MSVCRT_new_mode; + MSVCRT_new_mode = mode; +/* FIXME: UNLOCK_HEAP; */ + return old_mode; +} diff --git a/lib/msvcrt/sys_stat/stat.c b/lib/msvcrt/sys_stat/stat.c index 242c0bf..7dc1b67 100644 --- a/lib/msvcrt/sys_stat/stat.c +++ b/lib/msvcrt/sys_stat/stat.c @@ -12,6 +12,7 @@ int _stat(const char* path, struct stat* buffer) { HANDLE findHandle; WIN32_FIND_DATAA findData; + char* ext; if (!buffer) { @@ -46,7 +47,15 @@ int _stat(const char* path, struct stat* buffer) if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) buffer->st_mode |= S_IFDIR; else + { buffer->st_mode |= S_IFREG; + ext = strrchr(path, '.'); + if (ext && (!stricmp(ext, ".exe") || + !stricmp(ext, ".com") || + !stricmp(ext, ".bat") || + !stricmp(ext, ".cmd"))) + buffer->st_mode |= S_IEXEC; + } if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) buffer->st_mode |= S_IWRITE; diff --git a/lib/ntdll/dbg/brkpoint.c b/lib/ntdll/dbg/brkpoint.c index f41af1a..46fe99a 100644 --- a/lib/ntdll/dbg/brkpoint.c +++ b/lib/ntdll/dbg/brkpoint.c @@ -12,18 +12,33 @@ /* INCLUDES *****************************************************************/ #include - +#include /* FUNCTIONS *****************************************************************/ -VOID STDCALL DbgBreakPoint(VOID) -{ - __asm__("int $3\n\t"); -} +#if 0 +/* + FIXME: DbgBreakPoint must not have a stack frame, but GCC doesn't support + __declspec(naked) yet +*/ +__declspec(naked) VOID STDCALL DbgBreakPoint(VOID) +{ __asm__(ASM_BREAKPOINT_STR); } VOID STDCALL DbgUserBreakPoint(VOID) -{ - __asm__("int $3\n\t"); -} +{ __asm__(ASM_BREAKPOINT_STR); } +#else +#define DBG_BP_FUNC(__NAME__) \ +__asm__ \ +( \ + "\n" \ + ".global _" #__NAME__ "@0\n" \ + "_" #__NAME__ "@0:\n" \ + ASM_BREAKPOINT \ + "ret $0\n" \ +) + +DBG_BP_FUNC(DbgBreakPoint); +DBG_BP_FUNC(DbgUserBreakPoint); +#endif /* EOF */ diff --git a/lib/ntdll/dbg/debug.c b/lib/ntdll/dbg/debug.c index 9604ded..3fb9950 100644 --- a/lib/ntdll/dbg/debug.c +++ b/lib/ntdll/dbg/debug.c @@ -169,4 +169,41 @@ DbgUiWaitStateChange(ULONG Unknown1, return STATUS_NOT_IMPLEMENTED; } +NTSTATUS STDCALL DbgUiRemoteBreakin(VOID) +{ + DbgBreakPoint(); + + RtlExitUserThread(0); + + DbgBreakPoint(); +} + +NTSTATUS STDCALL DbgUiIssueRemoteBreakin(HANDLE Process) +{ + HANDLE hThread; + CLIENT_ID cidClientId; + NTSTATUS nErrCode; + ULONG nStackSize = PAGE_SIZE; + + nErrCode = RtlCreateUserThread + ( + Process, + NULL, + FALSE, + 0, + &nStackSize, + &nStackSize, + (PTHREAD_START_ROUTINE)DbgUiRemoteBreakin, + NULL, + &hThread, + &cidClientId + ); + + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + NtClose(hThread); + + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/lib/ntdll/def/ntdll.def b/lib/ntdll/def/ntdll.def index 02dc323..af1c9d9 100644 --- a/lib/ntdll/def/ntdll.def +++ b/lib/ntdll/def/ntdll.def @@ -28,6 +28,8 @@ DbgSsHandleKmApiMsg@8 DbgSsInitialize@16 DbgUiConnectToDbg@0 DbgUiContinue@8 +DbgUiIssueRemoteBreakin@4 +DbgUiRemoteBreakin@0 DbgUiWaitStateChange@8 DbgUserBreakPoint@0 ;KiRaiseUserExceptionDispatcher @@ -302,6 +304,7 @@ RtlAreAnyAccessesGranted@8 RtlAreBitsClear@12 RtlAreBitsSet@12 RtlAssert@16 +RtlBaseProcessStartRoutine DATA ;RtlCaptureStackBackTrace RtlCharToInteger@12 RtlCheckRegistryKey@8 @@ -387,6 +390,7 @@ RtlEqualSid@8 RtlEqualString@12 RtlEqualUnicodeString@12 RtlEraseUnicodeString@4 +RtlExitUserThread@4 RtlExpandEnvironmentStrings_U@16 ;RtlExtendHeap RtlExtendedIntegerMultiply@12 @@ -456,7 +460,7 @@ RtlIntegerToUnicodeString@12 RtlIsDosDeviceName_U@4 ;RtlIsGenericTableEmpty RtlIsNameLegalDOS8Dot3@12 -;RtlIsTextUnicode +RtlIsTextUnicode@12 RtlIsValidHandle@8 RtlIsValidIndexHandle@12 RtlLargeIntegerAdd@16 @@ -523,8 +527,8 @@ RtlReleasePebLock@0 RtlReleaseResource@4 ;RtlRemoteCall ;RtlResetRtlTranslations -;RtlRunDecodeUnicodeString -;RtlRunEncodeUnicodeString +RtlRunDecodeUnicodeString@8 +RtlRunEncodeUnicodeString@8 RtlSecondsSince1970ToTime@8 RtlSecondsSince1980ToTime@8 RtlSelfRelativeToAbsoluteSD@44 @@ -882,6 +886,7 @@ isspace isupper iswalpha iswctype +iswspace isxdigit labs log diff --git a/lib/ntdll/def/ntdll.edf b/lib/ntdll/def/ntdll.edf index d88ec47..bd8f5d7 100644 --- a/lib/ntdll/def/ntdll.edf +++ b/lib/ntdll/def/ntdll.edf @@ -28,6 +28,8 @@ DbgSsHandleKmApiMsg=DbgSsHandleKmApiMsg@8 DbgSsInitialize=DbgSsInitialize@16 DbgUiConnectToDbg=DbgUiConnectToDbg@0 DbgUiContinue=DbgUiContinue@8 +DbgUiIssueRemoteBreakin=DbgUiIssueRemoteBreakin@4 +DbgUiRemoteBreakin=DbgUiRemoteBreakin@0 DbgUiWaitStateChange=DbgUiWaitStateChange@8 DbgUserBreakPoint=DbgUserBreakPoint@0 ;KiRaiseUserExceptionDispatcher @@ -302,6 +304,7 @@ RtlAreAnyAccessesGranted=RtlAreAnyAccessesGranted@8 RtlAreBitsClear=RtlAreBitsClear@12 RtlAreBitsSet=RtlAreBitsSet@12 RtlAssert=RtlAssert@16 +RtlBaseProcessStartRoutine DATA ;RtlCaptureStackBackTrace RtlCharToInteger=RtlCharToInteger@12 RtlCheckRegistryKey=RtlCheckRegistryKey@8 @@ -387,6 +390,7 @@ RtlEqualSid=RtlEqualSid@8 RtlEqualString=RtlEqualString@12 RtlEqualUnicodeString=RtlEqualUnicodeString@12 RtlEraseUnicodeString=RtlEraseUnicodeString@4 +RtlExitUserThread=RtlExitUserThread@4 RtlExpandEnvironmentStrings_U=RtlExpandEnvironmentStrings_U@16 ;RtlExtendHeap RtlExtendedIntegerMultiply=RtlExtendedIntegerMultiply@12 @@ -455,7 +459,7 @@ RtlIntegerToUnicodeString=RtlIntegerToUnicodeString@12 RtlIsDosDeviceName_U=RtlIsDosDeviceName_U@4 ;RtlIsGenericTableEmpty RtlIsNameLegalDOS8Dot3=RtlIsNameLegalDOS8Dot3@12 -;RtlIsTextUnicode +RtlIsTextUnicode=RtlIsTextUnicode@12 RtlIsValidHandle=RtlIsValidHandle@8 RtlIsValidIndexHandle=RtlIsValidIndexHandle@12 RtlLargeIntegerAdd=RtlLargeIntegerAdd@16 @@ -522,8 +526,8 @@ RtlReleasePebLock=RtlReleasePebLock@0 RtlReleaseResource=RtlReleaseResource@4 ;RtlRemoteCall ;RtlResetRtlTranslations -;RtlRunDecodeUnicodeString -;RtlRunEncodeUnicodeString +RtlRunDecodeUnicodeString=RtlRunDecodeUnicodeString@8 +RtlRunEncodeUnicodeString=RtlRunEncodeUnicodeString@8 RtlSecondsSince1970ToTime=RtlSecondsSince1970ToTime@8 RtlSecondsSince1980ToTime=RtlSecondsSince1980ToTime@8 RtlSelfRelativeToAbsoluteSD=RtlSelfRelativeToAbsoluteSD@44 @@ -885,6 +889,7 @@ isspace isupper iswalpha iswctype +iswspace isxdigit labs log diff --git a/lib/ntdll/ldr/entry.S b/lib/ntdll/ldr/entry.S new file mode 100755 index 0000000..78d6190 --- /dev/null +++ b/lib/ntdll/ldr/entry.S @@ -0,0 +1,18 @@ +#include + +.extern ___true_LdrInitializeThunk@16 + +.globl _LdrInitializeThunk@16 +_LdrInitializeThunk@16: +#if defined(_M_IX86) + nop /* breakin overwrites this with "int 3" */ + jmp ___true_LdrInitializeThunk@16 +#elif defined(_M_ALPHA) + nop /* breakin overwrites this with "call_pal bpt" */ + br ___true_LdrInitializeThunk@16 +#elif defined(_M_MIPS) + nop /* breakin overwrites this with "break" */ + j ___true_LdrInitializeThunk@16 +#else +#error Unsupported architecture. +#endif diff --git a/lib/ntdll/ldr/res.c b/lib/ntdll/ldr/res.c index f3f7f35..b5878b1 100644 --- a/lib/ntdll/ldr/res.c +++ b/lib/ntdll/ldr/res.c @@ -88,8 +88,8 @@ LdrFindResource_U(PVOID BaseAddress, for (; EntryCount--; ResEntry++) { /* Scan entries for equal name */ if (ResEntry->Name & 0x80000000) { - ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF)); - if (!wcsncmp((PWCHAR)Id, ws + 1, *ws) && + ws = (PWCHAR)((ULONG)ResBase + (ResEntry->Name & 0x7FFFFFFF)); + if (!_wcsnicmp((PWCHAR)Id, ws + 1, *ws) && wcslen((PWCHAR)Id) == (int)*ws) { goto found; } diff --git a/lib/ntdll/ldr/startup.c b/lib/ntdll/ldr/startup.c index 845a334..0961243 100644 --- a/lib/ntdll/ldr/startup.c +++ b/lib/ntdll/ldr/startup.c @@ -40,7 +40,7 @@ ULONG NtGlobalFlag = 0; /* FUNCTIONS *****************************************************************/ VOID STDCALL -LdrInitializeThunk (ULONG Unknown1, +__true_LdrInitializeThunk (ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, ULONG Unknown4) @@ -92,6 +92,11 @@ LdrInitializeThunk (ULONG Unknown1, ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL); } + Peb->OSMajorVersion = 4; + Peb->OSMinorVersion = 0; + Peb->OSBuildNumber = 0; + Peb->OSPlatformId = VER_PLATFORM_WIN32_NT; + NtGlobalFlag = Peb->NtGlobalFlag; /* If MZ header exists */ diff --git a/lib/ntdll/ldr/utils.c b/lib/ntdll/ldr/utils.c index e9cb9ea..151f279 100644 --- a/lib/ntdll/ldr/utils.c +++ b/lib/ntdll/ldr/utils.c @@ -227,7 +227,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, *BaseAddress = NtCurrentPeb()->ImageBaseAddress; return STATUS_SUCCESS; } - + + *BaseAddress = NULL; DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n", @@ -417,7 +418,8 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, DLL_PROCESS_ATTACH, NULL)) { - DPRINT("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n", + /* Do this as a DPRINT1 for now, until clean up and fail implemented */ + DPRINT1("NTDLL.LDR: DLL \"%wZ\" failed to initialize\n", &Module->BaseDllName); /* FIXME: should clean up and fail */ } @@ -516,6 +518,8 @@ LdrFindEntryForName(PUNICODE_STRING Name, PLIST_ENTRY ModuleListHead; PLIST_ENTRY Entry; PLDR_MODULE ModulePtr; + BOOLEAN ContainsPath; + unsigned i; DPRINT("NTDLL.LdrFindEntryForName(Name %wZ)\n", Name); @@ -534,13 +538,22 @@ LdrFindEntryForName(PUNICODE_STRING Name, return(STATUS_SUCCESS); } + ContainsPath = (2 <= Name->Length && L':' == Name->Buffer[1]); + for (i = 0; ! ContainsPath && i < Name->Length; i++) + { + ContainsPath = L'\\' == Name->Buffer[i] || + L'/' == Name->Buffer[i]; + } while (Entry != ModuleListHead) { ModulePtr = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList); DPRINT("Scanning %wZ %wZ\n", &ModulePtr->BaseDllName, Name); - if (RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE) == 0) + if ((! ContainsPath && + 0 == RtlCompareUnicodeString(&ModulePtr->BaseDllName, Name, TRUE)) || + (ContainsPath && + 0 == RtlCompareUnicodeString(&ModulePtr->FullDllName, Name, TRUE))) { *Module = ModulePtr; return(STATUS_SUCCESS); @@ -659,9 +672,9 @@ LdrGetExportByOrdinal ( DbgPrint( "LdrGetExportByOrdinal(Ordinal %d) = %x\n", Ordinal, - ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]] + RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] ) ); - return(ExFunctions[ExOrdinals[Ordinal - ExportDir->Base]]); + return(RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )); } @@ -678,6 +691,8 @@ LdrGetExportByOrdinal ( * REVISIONS * * NOTE + * AddressOfNames and AddressOfNameOrdinals are paralell tables, + * both with NumberOfNames entries. * */ static PVOID @@ -697,7 +712,7 @@ LdrGetExportByName(PVOID BaseAddress, ULONG ExportDirSize; DPRINT("LdrGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint); - + ExportDir = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData(BaseAddress, TRUE, @@ -708,7 +723,15 @@ LdrGetExportByName(PVOID BaseAddress, DbgPrint("LdrGetExportByName(): no export directory!\n"); return NULL; } - + + + //The symbol names may be missing entirely + if (ExportDir->AddressOfNames == 0) + { + DPRINT("LdrGetExportByName(): symbol names missing entirely\n"); + return NULL; + } + /* * Get header pointers */ @@ -722,7 +745,7 @@ LdrGetExportByName(PVOID BaseAddress, /* * Check the hint first */ - if (Hint < ExportDir->NumberOfFunctions) + if (Hint < ExportDir->NumberOfNames) { ExName = RVA(BaseAddress, ExNames[Hint]); if (strcmp(ExName, SymbolName) == 0) @@ -744,7 +767,7 @@ LdrGetExportByName(PVOID BaseAddress, * Try a binary search first */ minn = 0; - maxn = ExportDir->NumberOfFunctions; + maxn = ExportDir->NumberOfNames; while (minn <= maxn) { ULONG mid; @@ -786,7 +809,7 @@ LdrGetExportByName(PVOID BaseAddress, * Fall back on a linear search */ DPRINT("LdrGetExportByName(): Falling back on a linear search of export table\n"); - for (i = 0; i < ExportDir->NumberOfFunctions; i++) + for (i = 0; i < ExportDir->NumberOfNames; i++) { ExName = RVA(BaseAddress, ExNames[i]); if (strcmp(ExName,SymbolName) == 0) @@ -838,6 +861,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, int i; PIMAGE_DATA_DIRECTORY RelocationDDir; ULONG OldProtect; + ULONG OldProtect2; NTSTATUS Status; PIMAGE_SECTION_HEADER Sections; ULONG MaxExtend; @@ -860,7 +884,7 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, RelocationDDir = &NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; RelocationRVA = RelocationDDir->VirtualAddress; - + if (RelocationRVA) { RelocationDir = @@ -895,6 +919,27 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, DPRINT1("Failed to unprotect relocation target.\n"); return(Status); } + + if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend) + { + Status = NtProtectVirtualMemory(NtCurrentProcess(), + ImageBase + + RelocationDir->VirtualAddress + PAGE_SIZE, + PAGE_SIZE, + PAGE_READWRITE, + &OldProtect2); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to unprotect relocation target (2).\n"); + NtProtectVirtualMemory(NtCurrentProcess(), + ImageBase + + RelocationDir->VirtualAddress, + PAGE_SIZE, + OldProtect, + &OldProtect); + return(Status); + } + } for (i = 0; i < NumberOfEntries; i++) { @@ -948,6 +993,21 @@ static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, return(Status); } + if (RelocationDir->VirtualAddress + PAGE_SIZE < MaxExtend) + { + Status = NtProtectVirtualMemory(NtCurrentProcess(), + ImageBase + + RelocationDir->VirtualAddress + PAGE_SIZE, + PAGE_SIZE, + OldProtect2, + &OldProtect2); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to protect relocation target2.\n"); + return(Status); + } + } + RelocationRVA += RelocationDir->SizeOfBlock; RelocationDir = (PRELOCATION_DIRECTORY) (ImageBase + RelocationRVA); @@ -1032,7 +1092,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, /* * Get the import address list. */ - ImportAddressList = (PVOID *)(NTHeaders->OptionalHeader.ImageBase + ImportAddressList = (PVOID *)(ImageBase + ImportModuleDirectory->dwRVAFunctionAddressList); /* @@ -1685,7 +1745,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, return STATUS_SUCCESS; } } - DbgPrint("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name); + DPRINT("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name); } else { @@ -1696,7 +1756,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]); return STATUS_SUCCESS; } - DbgPrint("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal); + DPRINT("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal); } return STATUS_PROCEDURE_NOT_FOUND; diff --git a/lib/ntdll/makefile b/lib/ntdll/makefile index 65de6e7..d93fefa 100644 --- a/lib/ntdll/makefile +++ b/lib/ntdll/makefile @@ -2,16 +2,22 @@ PATH_TO_TOP = ../.. +TARGET_BOOTSTRAP = yes + TARGET_TYPE = dynlink TARGET_NAME = ntdll TARGET_CFLAGS = -g -D__NTDLL__ +TARGET_ASFLAGS = -I $(PATH_TO_TOP)/include + TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ -nostartfiles +TARGET_SDKLIBS = rosrtl.a + TARGET_GCCLIBS = gcc TARGET_BASE = 0x77f60000 @@ -26,7 +32,8 @@ DBG_OBJECTS = dbg/brkpoint.o dbg/debug.o dbg/print.o #dbg/winedbg.o RTL_I386_OBJECTS = \ rtl/i386/exception.o \ - rtl/i386/except.o + rtl/i386/except.o \ + rtl/i386/ftol.o RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \ rtl/math.o rtl/mem.o rtl/nls.o rtl/process.o rtl/sd.o \ @@ -35,7 +42,8 @@ RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \ rtl/access.o rtl/apc.o rtl/callback.o rtl/luid.o rtl/misc.o \ rtl/registry.o rtl/exception.o rtl/intrlck.o rtl/resource.o \ rtl/handle.o rtl/atom.o rtl/message.o rtl/timezone.o \ - rtl/propvar.o rtl/security.o rtl/dos8dot3.o rtl/compress.o + rtl/propvar.o rtl/security.o rtl/dos8dot3.o rtl/compress.o \ + rtl/encode.o STDIO_OBJECTS = stdio/sprintf.o stdio/swprintf.o @@ -60,6 +68,7 @@ ARCH_OBJECTS = \ TARGET_OBJECTS = \ napi.o \ + ldr/entry.o \ ldr/startup.o \ $(ARCH_OBJECTS) \ $(DBG_OBJECTS) \ @@ -72,10 +81,15 @@ TARGET_OBJECTS = \ ldr/utils.o \ $(CSR_OBJECTS) +DEP_OBJECTS = $(TARGET_OBJECTS) +DEP_EXCLUDE_FILTER = napi.% + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk +include $(TOOLS_PATH)/depend.mk + %/TAGS: etags -o $(@D)/TAGS $(@D)/\*.c diff --git a/lib/ntdll/rtl/encode.c b/lib/ntdll/rtl/encode.c new file mode 100644 index 0000000..551f90f --- /dev/null +++ b/lib/ntdll/rtl/encode.c @@ -0,0 +1,75 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Security descriptor functions + * FILE: lib/ntdll/rtl/encode.c + * PROGRAMMER: KJK::Hyperion + * REVISION HISTORY: + * 02/04/2003: created (code contributed by crazylord + * ) + */ + +/* INCLUDES *****************************************************************/ + +#include + +#include + +/* FUNCTIONS ***************************************************************/ + +VOID NTAPI RtlRunDecodeUnicodeString +( + IN UCHAR hash, + IN OUT PUNICODE_STRING uString +) +{ + UCHAR *ptr; + WORD i; + + ptr = (UCHAR *) uString->Buffer; + if (uString->Length > 1) { + for (i=uString->Length; i>1; i--) { + ptr[i-1] ^= ptr[i-2] ^ hash; + } + } + + if (uString->Length >= 1) { + ptr[0] ^= hash | (UCHAR) 0x43; + } +} + +VOID NTAPI RtlRunEncodeUnicodeString +( + IN OUT PUCHAR hash, + IN OUT PUNICODE_STRING uString +) +{ + NTSTATUS ntS; + UCHAR *ptr; + TIME CurrentTime; + WORD i; + + ptr = (UCHAR *) uString->Buffer; + if (*hash == 0) { + ntS = NtQuerySystemTime(&CurrentTime); + if (NT_SUCCESS(ntS)) { + for (i=1; iLength >= 1) { + ptr[0] ^= (*hash) | (UCHAR) 0x43; + if (uString->Length > 1) { + for (i=1; iLength; i++) { + ptr[i] ^= ptr[i-1] ^ (*hash); + } + } + } +} + +/* EOF */ diff --git a/lib/ntdll/rtl/exception.c b/lib/ntdll/rtl/exception.c index f56caac..a68f50a 100644 --- a/lib/ntdll/rtl/exception.c +++ b/lib/ntdll/rtl/exception.c @@ -18,6 +18,13 @@ /* FUNCTIONS ***************************************************************/ +VOID STDCALL +RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress, + PVOID Parameter); + +__declspec(dllexport) +PRTL_BASE_PROCESS_START_ROUTINE RtlBaseProcessStartRoutine = RtlBaseProcessStart; + ULONG RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context); @@ -51,7 +58,18 @@ KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, VOID STDCALL RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord) { - DbgPrint("RtlRaiseException()"); + DPRINT("RtlRaiseException()\n"); } +VOID STDCALL +RtlBaseProcessStart(PTHREAD_START_ROUTINE StartAddress, + PVOID Parameter) +{ + NTSTATUS ExitStatus = STATUS_SUCCESS; + + ExitStatus = (NTSTATUS) (StartAddress)(Parameter); + + NtTerminateProcess(NtCurrentProcess(), ExitStatus); + } + /* EOF */ diff --git a/lib/ntdll/rtl/i386/.cvsignore b/lib/ntdll/rtl/i386/.cvsignore index 5761abc..31dc307 100644 --- a/lib/ntdll/rtl/i386/.cvsignore +++ b/lib/ntdll/rtl/i386/.cvsignore @@ -1 +1,2 @@ +*.d *.o diff --git a/lib/ntdll/rtl/i386/ftol.c b/lib/ntdll/rtl/i386/ftol.c new file mode 100644 index 0000000..0832486 --- /dev/null +++ b/lib/ntdll/rtl/i386/ftol.c @@ -0,0 +1,35 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Security manager + * FILE: lib/ntdll/rtl/i386/ftol.c + * PROGRAMER: Ge van Geldorp (ge@gse.nl) + * REVISION HISTORY: 2003/04/24 Created + */ + +/* + * This routine is called by MSVC-generated code to convert from floating point + * to integer representation. The floating point number to be converted is + * on the top of the floating point stack. + */ +long long __cdecl _ftol(void) +{ + unsigned short cw_orig; + unsigned short cw_round_chop; + long long ll; + + /* Set "round towards zero" mode */ + __asm__("fstcw %0\n\t" : "=m" (cw_orig)); + __asm__("fwait\n\t"); + cw_round_chop = cw_orig | 0x0c00; + __asm__("fldcw %0\n\t" : : "m" (cw_round_chop)); + + /* Do the actual conversion */ + __asm__("fistpq %0\n\t" : "=m" (ll) ); + + /* And restore the rounding mode */ + __asm__("fldcw %0\n\t" : : "m" (cw_orig)); + + return ll; +} diff --git a/lib/ntdll/rtl/math.c b/lib/ntdll/rtl/math.c index 028951b..bb098e6 100644 --- a/lib/ntdll/rtl/math.c +++ b/lib/ntdll/rtl/math.c @@ -24,7 +24,6 @@ double ceil (double __x); double cos (double __x); double fabs (double __x); double floor (double __x); -long _ftol (double fl); double log (double __x); double __log2 (double __x); double pow (double __x, double __y); @@ -92,11 +91,6 @@ double floor (double __x) return __value; } -long _ftol (double fl) -{ - return (long)fl; -} - double log (double __x) { register double __value; diff --git a/lib/ntdll/rtl/nls.c b/lib/ntdll/rtl/nls.c index 428d39d..b65e453 100644 --- a/lib/ntdll/rtl/nls.c +++ b/lib/ntdll/rtl/nls.c @@ -22,7 +22,9 @@ */ #include -//#include + +#define NDEBUG +#include BOOLEAN @@ -103,7 +105,7 @@ RtlCustomCPToUnicodeN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -161,7 +163,7 @@ RtlMultiByteToUnicodeN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -231,7 +233,7 @@ RtlOemToUnicodeN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -274,7 +276,7 @@ RtlUnicodeToCustomCPN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -320,7 +322,7 @@ RtlUnicodeToMultiByteN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -344,7 +346,8 @@ RtlUnicodeToMultiByteSize ( { /* multi-byte code page */ /* FIXME */ - + *MbSize = 0; + assert(FALSE); } return STATUS_SUCCESS; @@ -390,7 +393,7 @@ RtlUnicodeToOemN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -438,7 +441,7 @@ RtlUpcaseUnicodeToCustomCPN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -486,7 +489,7 @@ RtlUpcaseUnicodeToMultiByteN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; @@ -534,7 +537,7 @@ RtlUpcaseUnicodeToOemN ( { /* multi-byte code page */ /* FIXME */ - + assert(FALSE); } return STATUS_SUCCESS; diff --git a/lib/ntdll/rtl/path.c b/lib/ntdll/rtl/path.c index dcdb1c2..2b79c3a 100644 --- a/lib/ntdll/rtl/path.c +++ b/lib/ntdll/rtl/path.c @@ -104,6 +104,11 @@ static VOID RtlpEatPath (PWSTR Path) } } } + if (Path[2] == 0) + { + Path[2] = L'\\'; + Path[3] = 0; + } } @@ -252,9 +257,9 @@ RtlGetCurrentDirectory_U(ULONG MaximumLength, DPRINT ("RtlGetCurrentDirectory %lu %p\n", MaximumLength, Buffer); - cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); - RtlAcquirePebLock(); + + cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); Length = cd->DosPath.Length / sizeof(WCHAR); if (cd->DosPath.Buffer[Length - 1] == L'\\' && cd->DosPath.Buffer[Length - 2] != L':') @@ -304,7 +309,7 @@ RtlSetCurrentDirectory_U(PUNICODE_STRING name) DPRINT ("RtlSetCurrentDirectory %wZ\n", name); RtlAcquirePebLock (); - cd = (PCURDIR)&NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName; + cd = (PCURDIR)&NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName; size = cd->DosPath.MaximumLength; buf = RtlAllocateHeap (RtlGetProcessHeap(), @@ -516,7 +521,7 @@ CHECKPOINT; RtlAcquirePebLock(); - cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); + cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); DPRINT("type %ld\n", type); switch (type) { @@ -707,7 +712,7 @@ RtlDosPathNameToNtPathName_U(PWSTR dosname, if (nah) { memset (nah, 0, sizeof(CURDIR)); - cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); + cd = (PCURDIR)&(NtCurrentPeb ()->ProcessParameters->CurrentDirectoryName); if (Type == 5 && cd->Handle && !_wcsnicmp (cd->DosPath.Buffer, fullname, cd->DosPath.Length / 2)) { diff --git a/lib/ntdll/rtl/process.c b/lib/ntdll/rtl/process.c index 7dfb963..df4e99a 100644 --- a/lib/ntdll/rtl/process.c +++ b/lib/ntdll/rtl/process.c @@ -22,160 +22,29 @@ /* FUNCTIONS ****************************************************************/ -static NTSTATUS -RtlpCreateFirstThread(HANDLE ProcessHandle, - ULONG StackReserve, - ULONG StackCommit, - LPTHREAD_START_ROUTINE lpStartAddress, - PCLIENT_ID ClientId, - PHANDLE ThreadHandle) +static NTSTATUS RtlpCreateFirstThread +( + HANDLE ProcessHandle, + ULONG StackReserve, + ULONG StackCommit, + LPTHREAD_START_ROUTINE lpStartAddress, + PCLIENT_ID ClientId, + PHANDLE ThreadHandle +) { - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - ULONG OldPageProtection; - CLIENT_ID Cid; - ULONG InitialStack[5]; - ULONG ResultLength; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - ObjectAttributes.SecurityQualityOfService = NULL; - - if (StackReserve > 0x100000) - InitialTeb.StackReserve = StackReserve; - else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ - - /* FIXME */ -#if 0 - if (StackCommit > PAGE_SIZE) - InitialTeb.StackCommit = StackCommit; - else - InitialTeb.StackCommit = PAGE_SIZE; -#endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - - /* add guard page size */ - InitialTeb.StackCommit += PAGE_SIZE; - - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - return(Status); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page(s)!\n"); - return(Status); - } - - DPRINT("StackLimit: %p\n", InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - return(Status); - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = (ULONG)lpStartAddress; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = TEB_SELECTOR; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 20; - ThreadContext.EFlags = (1<<1) + (1<<9); - - DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); - - /* - * Write in the initial stack. - */ - InitialStack[0] = 0; - InitialStack[1] = PEB_BASE; - Status = ZwWriteVirtualMemory(ProcessHandle, - (PVOID)ThreadContext.Esp, - InitialStack, - sizeof(InitialStack), - &ResultLength); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to write initial stack.\n"); - return(Status); - } - - Status = NtCreateThread(ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &Cid, - &ThreadContext, - &InitialTeb, - FALSE); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - return(Status); - } - - if (ClientId != NULL) - { - memcpy(&ClientId->UniqueThread, &Cid.UniqueThread, sizeof(ULONG)); - } - - return(STATUS_SUCCESS); + return RtlCreateUserThread + ( + ProcessHandle, + NULL, + FALSE, + 0, + &StackReserve, + &StackCommit, + lpStartAddress, + (PVOID)PEB_BASE, + ThreadHandle, + ClientId + ); } static NTSTATUS @@ -335,7 +204,7 @@ static NTSTATUS KlInitPeb (HANDLE ProcessHandle, return(Status); } - DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength); + DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize); /* write process parameters block*/ RtlDeNormalizeProcessParams (Ppb); diff --git a/lib/ntdll/rtl/resource.c b/lib/ntdll/rtl/resource.c index b311924..c3cdae6 100644 --- a/lib/ntdll/rtl/resource.c +++ b/lib/ntdll/rtl/resource.c @@ -299,4 +299,4 @@ RtlDumpResource(PRTL_RESOURCE Resource) } } -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/lib/ntdll/rtl/thread.c b/lib/ntdll/rtl/thread.c index 0bd496c..fc39ff3 100644 --- a/lib/ntdll/rtl/thread.c +++ b/lib/ntdll/rtl/thread.c @@ -7,267 +7,140 @@ * REVISION HISTORY: * 09/07/99: Created * 09/10/99: Cleanup and full stack support. + * 25/04/03: Near rewrite. Made code more readable, replaced + * INITIAL_TEB with USER_STACK, added support for + * fixed-size stacks + * 28/04/03: Moved all code to a new statically linked + * library (ROSRTL) so it can be shared with + * kernel32.dll without exporting non-standard + * functions from ntdll.dll */ /* INCLUDES *****************************************************************/ #include -#include #include #include +#include #define NDEBUG #include - /* FUNCTIONS ***************************************************************/ - -NTSTATUS STDCALL -RtlCreateUserThread(HANDLE ProcessHandle, - PSECURITY_DESCRIPTOR SecurityDescriptor, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PVOID Parameter, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId) +NTSTATUS STDCALL RtlCreateUserThread +( + HANDLE ProcessHandle, + PSECURITY_DESCRIPTOR SecurityDescriptor, + BOOLEAN CreateSuspended, + LONG StackZeroBits, + PULONG StackReserve, + PULONG StackCommit, + PTHREAD_START_ROUTINE StartAddress, + PVOID Parameter, + PHANDLE ThreadHandle, + PCLIENT_ID ClientId +) { - HANDLE LocalThreadHandle; - CLIENT_ID LocalClientId; - OBJECT_ATTRIBUTES ObjectAttributes; - INITIAL_TEB InitialTeb; - CONTEXT ThreadContext; - ULONG OldPageProtection; - NTSTATUS Status; - - /* initialize initial teb */ - if ((StackReserve != NULL) && (*StackReserve > 0x100000)) - InitialTeb.StackReserve = *StackReserve; - else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ - - /* FIXME: use correct commit size */ -#if 0 - if ((StackCommit != NULL) && (*StackCommit > PAGE_SIZE)) - InitialTeb.StackCommit = *StackCommit; - else - InitialTeb.StackCommit = PAGE_SIZE; -#endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - - /* add size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; - - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - return(Status); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page!\n"); - return(Status); - } - - DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", - InitialTeb.StackLimit, - InitialTeb.StackCommit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error protecting guard page!\n"); - return(Status); - } - - /* initialize thread context */ - RtlInitializeContext(ProcessHandle, - &ThreadContext, - Parameter, - StartAddress, - &InitialTeb); - - /* create the thread */ - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = SecurityDescriptor; - ObjectAttributes.SecurityQualityOfService = NULL; - - Status = NtCreateThread(&LocalThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &LocalClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error creating thread!\n"); - return(Status); - } - - /* return committed stack size */ - if (StackCommit) - *StackCommit = InitialTeb.StackCommit; - - /* return reserved stack size */ - if (StackReserve) - *StackReserve = InitialTeb.StackReserve; - - /* return thread handle */ - if (ThreadHandle) - *ThreadHandle = LocalThreadHandle; - - /* return client id */ - if (ClientId) - { - ClientId->UniqueProcess = LocalClientId.UniqueProcess; - ClientId->UniqueThread = LocalClientId.UniqueThread; - } - - return(STATUS_SUCCESS); + OBJECT_ATTRIBUTES oaThreadAttribs; + + InitializeObjectAttributes + ( + &oaThreadAttribs, + NULL, + 0, + NULL, + SecurityDescriptor + ); + + return RtlRosCreateUserThreadEx + ( + ProcessHandle, + &oaThreadAttribs, + CreateSuspended, + StackZeroBits, + StackReserve, + StackCommit, + StartAddress, + ThreadHandle, + ClientId, + 1, + (ULONG_PTR *)&Parameter + ); } - -NTSTATUS STDCALL -RtlInitializeContext(HANDLE ProcessHandle, - PCONTEXT Context, - PVOID Parameter, - PTHREAD_START_ROUTINE StartAddress, - PINITIAL_TEB InitialTeb) +NTSTATUS STDCALL RtlInitializeContext +( + HANDLE ProcessHandle, + PCONTEXT Context, + PVOID Parameter, + PTHREAD_START_ROUTINE StartAddress, + PUSER_STACK UserStack +) { - ULONG Buffer[2]; - ULONG BytesWritten; - NTSTATUS Status; - - memset (Context, 0, sizeof(CONTEXT)); - Context->Eip = (LONG)StartAddress; - Context->SegGs = USER_DS; - Context->SegFs = TEB_SELECTOR; - Context->SegEs = USER_DS; - Context->SegDs = USER_DS; - Context->SegCs = USER_CS; - Context->SegSs = USER_DS; - Context->Esp = (ULONG)InitialTeb->StackBase - 8; - Context->EFlags = (1<<1) + (1<<9); - - /* prepare the thread stack for execution */ - if (ProcessHandle == NtCurrentProcess()) - { - *((PULONG)(InitialTeb->StackBase - 4)) = (ULONG)Parameter; - *((PULONG)(InitialTeb->StackBase - 8)) = 0xdeadbeef; - } - else - { - Buffer[0] = (ULONG)Parameter; - Buffer[1] = 0xdeadbeef; - - Status = NtWriteVirtualMemory(ProcessHandle, - (PVOID)((ULONG)InitialTeb->StackBase - 8), - Buffer, - 2 * sizeof(ULONG), - &BytesWritten); - return Status; - } - - return STATUS_SUCCESS; + return RtlRosInitializeContextEx + ( + ProcessHandle, + Context, + StartAddress, + UserStack, + 1, + (ULONG_PTR *)&Parameter + ); } - -NTSTATUS STDCALL -RtlFreeUserThreadStack(HANDLE ProcessHandle, - HANDLE ThreadHandle) +NTSTATUS STDCALL RtlFreeUserThreadStack +( + HANDLE ProcessHandle, + HANDLE ThreadHandle +) { - THREAD_BASIC_INFORMATION ThreadInfo; - NTSTATUS Status; - ULONG BytesRead; - ULONG RegionSize; - PVOID StackBase; - PTEB Teb; - - Status = NtQueryInformationThread(ThreadHandle, - ThreadBasicInformation, - &ThreadInfo, - sizeof(THREAD_BASIC_INFORMATION), - NULL); - if (!NT_SUCCESS(Status)) - return(Status); - - if (ThreadInfo.TebBaseAddress == NULL) - return(Status); - - Teb = (PTEB)ThreadInfo.TebBaseAddress; - Status = NtReadVirtualMemory(ProcessHandle, - &Teb->DeallocationStack, - &StackBase, - sizeof(PVOID), - &BytesRead); - if (!NT_SUCCESS(Status)) - return(Status); - - if (StackBase == NULL) - return(Status); + THREAD_BASIC_INFORMATION tbiInfo; + NTSTATUS nErrCode; + ULONG nDummy; + ULONG nSize = 0; + PVOID pStackBase; + PTEB pTeb; + + /* query basic information about the thread */ + nErrCode = NtQueryInformationThread + ( + ThreadHandle, + ThreadBasicInformation, + &tbiInfo, + sizeof(tbiInfo), + NULL + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + if(tbiInfo.TebBaseAddress == NULL) return STATUS_ACCESS_VIOLATION; + + pTeb = (PTEB)tbiInfo.TebBaseAddress; + + /* read the base address of the stack to be deallocated */ + nErrCode = NtReadVirtualMemory + ( + ProcessHandle, + &pTeb->DeallocationStack, + &pStackBase, + sizeof(pStackBase), + &nDummy + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + if(pStackBase == NULL) return STATUS_ACCESS_VIOLATION; + + /* deallocate the stack */ + nErrCode = NtFreeVirtualMemory(ProcessHandle, pStackBase, &nSize, MEM_RELEASE); + + return nErrCode; +} - RegionSize = 0; - Status = NtFreeVirtualMemory(ProcessHandle, - StackBase, - &RegionSize, - MEM_RELEASE); - return(Status); +NTSTATUS STDCALL RtlExitUserThread(NTSTATUS nErrCode) +{ + return NtTerminateThread(NtCurrentThread(), nErrCode); } /* EOF */ diff --git a/lib/ntdll/rtl/unicode.c b/lib/ntdll/rtl/unicode.c index fa0512a..7278792 100644 --- a/lib/ntdll/rtl/unicode.c +++ b/lib/ntdll/rtl/unicode.c @@ -873,6 +873,61 @@ RtlIntegerToUnicodeString( } +#define ITU_IMPLEMENTED_TESTS (IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE) + +ULONG STDCALL +RtlIsTextUnicode (PVOID Buffer, + ULONG Length, + ULONG *Flags) +{ + PWSTR s = Buffer; + ULONG in_flags = (ULONG)-1; + ULONG out_flags = 0; + + if (Length == 0) + goto done; + + if (Flags != 0) + in_flags = *Flags; + + /* + * Apply various tests to the text string. According to the + * docs, each test "passed" sets the corresponding flag in + * the output flags. But some of the tests are mutually + * exclusive, so I don't see how you could pass all tests ... + */ + + /* Check for an odd length ... pass if even. */ + if (!(Length & 1)) + out_flags |= IS_TEXT_UNICODE_ODD_LENGTH; + + /* Check for the BOM (byte order mark). */ + if (*s == 0xFEFF) + out_flags |= IS_TEXT_UNICODE_SIGNATURE; + +#if 0 + /* Check for the reverse BOM (byte order mark). */ + if (*s == 0xFFFE) + out_flags |= IS_TEXT_UNICODE_REVERSE_SIGNATURE; +#endif + + /* FIXME: Add more tests */ + + /* + * Check whether the string passed all of the tests. + */ + in_flags &= ITU_IMPLEMENTED_TESTS; + if ((out_flags & in_flags) != in_flags) + Length = 0; + +done: + if (Flags != 0) + *Flags = out_flags; + + return Length; +} + + NTSTATUS STDCALL RtlLargeIntegerToChar( diff --git a/lib/ntdll/string/ctype.c b/lib/ntdll/string/ctype.c index 21d58cd..0261555 100644 --- a/lib/ntdll/string/ctype.c +++ b/lib/ntdll/string/ctype.c @@ -372,6 +372,11 @@ int iswdigit(wint_t c) return (iswctype (c, _DIGIT)); } +int iswspace(wint_t c) +{ + return (iswctype (c, _SPACE)); +} + int iswlower(wint_t c) { return (iswctype (c, _LOWER)); diff --git a/lib/psapi/enum/module.c b/lib/psapi/enum/module.c deleted file mode 100644 index dc9a0fa..0000000 --- a/lib/psapi/enum/module.c +++ /dev/null @@ -1,274 +0,0 @@ -/* $Id$ -*/ -/* - * COPYRIGHT: See COPYING in the top level directory - * LICENSE: See LGPL.txt in the top level directory - * PROJECT: ReactOS system libraries - * FILE: reactos/lib/psapi/enum/module.c - * PURPOSE: Enumerate system and process modules - * PROGRAMMER: KJK::Hyperion - * UPDATE HISTORY: - * 10/06/2002: Created - * 29/08/2002: Generalized the interface to improve reusability, - * more efficient use of memory operations - */ - -#include -#include -#include -#include - -NTSTATUS -STDCALL -PsaEnumerateSystemModules -( - IN PSYSMOD_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -) -{ - ULONG nSize; - register NTSTATUS nErrCode = STATUS_SUCCESS; - register PULONG pnModuleCount = &nSize; - register PSYSTEM_MODULE_ENTRY psmeCurModule; - register ULONG nModuleCount; - - /* initial probe */ - nErrCode = NtQuerySystemInformation - ( - SystemModuleInformation, - pnModuleCount, - sizeof(nSize), - NULL - ); - - if(nErrCode != STATUS_INFO_LENGTH_MISMATCH && !NT_SUCCESS(nErrCode)) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); - return nErrCode; - } - - /* RATIONALE: the loading of a system module is a rare occurrence. To minimize - memory operations that could be expensive, or fragment the pool/heap, we try - to determine the buffer size in advance, knowing that the number of elements - is unlikely to change */ - nSize = sizeof(ULONG) + nSize * sizeof(SYSTEM_MODULE_ENTRY); - pnModuleCount = NULL; - - do - { - register void * pTmp; - - /* free the buffer, and reallocate it to the new size. RATIONALE: since we - ignore the buffer's content at this point, there's no point in a realloc(), - that could end up copying a large chunk of data we'd discard anyway */ - free(pnModuleCount); - pTmp = malloc(nSize); - - if(pTmp == NULL) - { - /* failure */ - nErrCode = STATUS_NO_MEMORY; - goto esm_Finalize; - } - - pnModuleCount = pTmp; - - /* query the information */ - nErrCode = NtQuerySystemInformation - ( - SystemModuleInformation, - pnModuleCount, - nSize, - NULL - ); - - /* double the buffer for the next loop */ - nSize += nSize; - } - /* repeat until the buffer is big enough */ - while(nErrCode == STATUS_INFO_LENGTH_MISMATCH); - - if(!NT_SUCCESS(nErrCode)) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); - goto esm_Finalize; - } - - /* the array of modules starts right after an ULONG storing their count */ - psmeCurModule = (PSYSTEM_MODULE_ENTRY)(pnModuleCount + 1); - - nModuleCount = *pnModuleCount; - - /* repeat until all modules have been returned */ - while(nModuleCount > 0) - { - /* return current module to the callback */ - nErrCode = Callback(nModuleCount, psmeCurModule, CallbackContext); - - if(!NT_SUCCESS(nErrCode)) - /* failure */ - goto esm_Finalize; - - /* next module */ - psmeCurModule ++; - nModuleCount --; - } - -esm_Finalize: - /* free the buffer */ - free(pnModuleCount); - - return (nErrCode); -} - -NTSTATUS -STDCALL -PsaEnumerateProcessModules -( - IN HANDLE ProcessHandle, - IN PPROCMOD_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -) -{ - register NTSTATUS nErrCode; - - /* current process - use direct memory copy */ - if(ProcessHandle == NtCurrentProcess()) - { - register PLIST_ENTRY pleListHead; - register PLIST_ENTRY pleCurEntry; - -#if 0 - /* FIXME: activate this when GCC supports SEH */ - __try - { -#endif - pleListHead = &(NtCurrentPeb()->Ldr->InLoadOrderModuleList); - pleCurEntry = pleListHead->Flink; - - while(pleCurEntry != pleListHead) - { - register PLDR_MODULE plmModule = CONTAINING_RECORD - ( - pleCurEntry, - LDR_MODULE, - InLoadOrderModuleList - ); - - /* return the current module to the callback */ - nErrCode = Callback(ProcessHandle, plmModule, CallbackContext); - - if(!NT_SUCCESS(nErrCode)) - /* failure */ - goto epm_Failure; - - pleCurEntry = plmModule->InLoadOrderModuleList.Flink; - } -#if 0 - /* FIXME: activate this when GCC supports SEH */ - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - return GetExceptionCode(); - } -#endif - } - /* another process */ - else - { - PROCESS_BASIC_INFORMATION pbiInfo; - PPEB_LDR_DATA ppldLdrData; - LDR_MODULE lmModule; - PLIST_ENTRY pleListHead; - PLIST_ENTRY pleCurEntry; - - /* query the process basic information (includes the PEB address) */ - nErrCode = NtQueryInformationProcess - ( - ProcessHandle, - ProcessBasicInformation, - &pbiInfo, - sizeof(pbiInfo), - NULL - ); - - if(!NT_SUCCESS(nErrCode)) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "NtQueryInformationProcess", nErrCode); - goto epm_Failure; - } - - /* get the address of the PE Loader data */ - nErrCode = NtReadVirtualMemory - ( - ProcessHandle, - &(pbiInfo.PebBaseAddress->Ldr), - &ppldLdrData, - sizeof(ppldLdrData), - NULL - ); - - if(!NT_SUCCESS(nErrCode)) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); - goto epm_Failure; - } - - /* head of the module list: the last element in the list will point to this */ - pleListHead = &ppldLdrData->InLoadOrderModuleList; - - /* get the address of the first element in the list */ - nErrCode = NtReadVirtualMemory - ( - ProcessHandle, - &(ppldLdrData->InLoadOrderModuleList.Flink), - &pleCurEntry, - sizeof(pleCurEntry), - NULL - ); - - while(pleCurEntry != pleListHead) - { - /* read the current module */ - nErrCode = NtReadVirtualMemory - ( - ProcessHandle, - CONTAINING_RECORD(pleCurEntry, LDR_MODULE, InLoadOrderModuleList), - &lmModule, - sizeof(lmModule), - NULL - ); - - if(!NT_SUCCESS(nErrCode)) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "NtReadVirtualMemory", nErrCode); - goto epm_Failure; - } - - /* return the current module to the callback */ - nErrCode = Callback(ProcessHandle, &lmModule, CallbackContext); - - if(!NT_SUCCESS(nErrCode)) - /* failure */ - goto epm_Failure; - - /* address of the next module in the list */ - pleCurEntry = lmModule.InLoadOrderModuleList.Flink; - } - - } - - /* success */ - return (STATUS_SUCCESS); - -epm_Failure: - /* failure */ - return (nErrCode); -} - -/* EOF */ diff --git a/lib/psapi/enum/process.c b/lib/psapi/enum/process.c deleted file mode 100644 index f6e934d..0000000 --- a/lib/psapi/enum/process.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $Id$ -*/ -/* - * COPYRIGHT: See COPYING in the top level directory - * LICENSE: See LGPL.txt in the top level directory - * PROJECT: ReactOS system libraries - * FILE: reactos/lib/psapi/enum/process.c - * PURPOSE: Enumerate processes - * PROGRAMMER: KJK::Hyperion - * UPDATE HISTORY: - * 10/06/2002: Created - * 29/08/2002: Generalized the interface to improve reusability, - * more efficient use of memory operations - */ - -#include -#include -#include -#include - -NTSTATUS -STDCALL -PsaEnumerateProcesses -( - IN PPROC_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -) -{ - register NTSTATUS nErrCode = STATUS_SUCCESS; - PSYSTEM_PROCESS_INFORMATION pInfoBuffer = NULL; - PSYSTEM_PROCESS_INFORMATION pInfoHead = NULL; - ULONG nSize = 32768; - - /* FIXME: if the system has loaded several processes and threads, the buffer - could get really big. But if there's several processes and threads, the - system is already under stress, and a huge buffer could only make things - worse. The function should be profiled to see what's the average minimum - buffer size, to succeed on the first shot */ - do - { - void * pTmp; - - /* free the buffer, and reallocate it to the new size. RATIONALE: since we - ignore the buffer's contents at this point, there's no point in a realloc() - that could end up copying a large chunk of data we'd discard anyway */ - free(pInfoBuffer); - pTmp = malloc(nSize); - - if(pTmp == NULL) - { - /* failure */ - DPRINT(FAILED_WITH_STATUS, "malloc", STATUS_NO_MEMORY); - nErrCode = STATUS_NO_MEMORY; - goto esp_Finalize; - } - - pInfoBuffer = pTmp; - - /* query the information */ - nErrCode = NtQuerySystemInformation - ( - SystemProcessesAndThreadsInformation, - pInfoBuffer, - nSize, - NULL - ); - - /* double the buffer size */ - nSize += nSize; - } - /* repeat until the buffer is big enough */ - while(nErrCode == STATUS_INFO_LENGTH_MISMATCH); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) - { - DPRINT(FAILED_WITH_STATUS, "NtQuerySystemInformation", nErrCode); - goto esp_Finalize; - } - - /* list head */ - pInfoHead = pInfoBuffer; - - /* scan the list */ - while(1) - { - /* notify the callback */ - nErrCode = Callback(pInfoHead, CallbackContext); - - /* if the callback returned an error or this is the end of the process list, - break out */ - if(!NT_SUCCESS(nErrCode) || pInfoHead->RelativeOffset == 0) - break; - - /* move to the next process */ - pInfoHead = - (SYSTEM_PROCESS_INFORMATION*) - ((ULONG)pInfoHead + pInfoHead->RelativeOffset); - } - -esp_Finalize: - /* free the buffer */ - free(pInfoBuffer); - - /* return the last status */ - return (nErrCode); -} - -/* EOF */ - diff --git a/lib/psapi/include/internal/psapi.h b/lib/psapi/include/internal/psapi.h deleted file mode 100644 index 76e6fb9..0000000 --- a/lib/psapi/include/internal/psapi.h +++ /dev/null @@ -1,90 +0,0 @@ -/* $Id$ -*/ -/* - * internal/psapi.h - * - * Process Status Helper API, native interface - * - * This file is part of the ReactOS Operating System. - * - * Contributors: - * Created by KJK::Hyperion - * - * THIS SOFTWARE IS NOT COPYRIGHTED - * - * This source code is offered for use in the public domain. You may - * use, modify or distribute it freely. - * - * This code is distributed in the hope that it will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - */ - -#ifndef __INTERNAL_PSAPI_H_INCLUDED__ -#define __INTERNAL_PSAPI_H_INCLUDED__ - -/* INCLUDES */ -#include -#include - -/* OBJECTS */ - -/* TYPES */ -typedef NTSTATUS STDCALL (*PPROC_ENUM_ROUTINE) -( - IN PSYSTEM_PROCESS_INFORMATION CurrentProcess, - IN OUT PVOID CallbackContext -); - -typedef NTSTATUS STDCALL (*PSYSMOD_ENUM_ROUTINE) -( - IN ULONG ModuleCount, - IN PSYSTEM_MODULE_ENTRY CurrentModule, - IN OUT PVOID CallbackContext -); - -typedef NTSTATUS STDCALL (*PPROCMOD_ENUM_ROUTINE) -( - IN HANDLE ProcessHandle, - IN PLDR_MODULE CurrentModule, - IN OUT PVOID CallbackContext -); - -/* CONSTANTS */ -#define FAILED_WITH_STATUS DEFINE_DBG_MSG("%s() failed, status 0x%08X") - -/* PROTOTYPES */ -NTSTATUS -STDCALL -PsaEnumerateProcesses -( - IN PPROC_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -); - -NTSTATUS -STDCALL -PsaEnumerateSystemModules -( - IN PSYSMOD_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -); - -NTSTATUS -STDCALL -PsaEnumerateProcessModules -( - IN HANDLE ProcessHandle, - IN PPROCMOD_ENUM_ROUTINE Callback, - IN OUT PVOID CallbackContext -); - -/* MACROS */ -#define DEFINE_DBG_MSG(__str__) "PSAPI: " __str__ "\n" - -#endif /* __INTERNAL_PSAPI_H_INCLUDED__ */ - -/* EOF */ - diff --git a/lib/psapi/makefile b/lib/psapi/makefile index 91b5995..2931dee 100644 --- a/lib/psapi/makefile +++ b/lib/psapi/makefile @@ -6,9 +6,11 @@ TARGET_TYPE = dynlink TARGET_NAME = psapi -TARGET_SDKLIBS = ntdll.a kernel32.a +TARGET_SDKLIBS = epsapi.a ntdll.a kernel32.a -TARGET_CFLAGS = -I./include -Wall +TARGET_CFLAGS = -I./include + +TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_BASE = 0x68F70000 @@ -16,11 +18,14 @@ TARGET_OBJECTS = \ misc/dllmain.o \ misc/malloc.o \ misc/stubs.o \ - misc/win32.o \ - enum/module.o \ - enum/process.o + misc/win32.o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak + include $(TOOLS_PATH)/helper.mk +include $(TOOLS_PATH)/depend.mk + # EOF diff --git a/lib/psapi/misc/malloc.c b/lib/psapi/misc/malloc.c index 9baeb64..24142c3 100644 --- a/lib/psapi/misc/malloc.c +++ b/lib/psapi/misc/malloc.c @@ -9,6 +9,8 @@ * PROGRAMMER: KJK::Hyperion * UPDATE HISTORY: * 10/06/2002: Created + * 12/02/2003: malloc and free renamed to PsaiMalloc and PsaiFree, + * for better reusability */ #include @@ -46,17 +48,17 @@ PVOID STDCALL MemAlloc return pBuf; } -void *malloc(size_t size) +void *PsaiMalloc(SIZE_T size) { return MemAlloc(NULL, NULL, size); } -void *realloc(void *ptr, size_t size) +void *PsaiRealloc(void *ptr, SIZE_T size) { return MemAlloc(NULL, ptr, size); } -void free(void *ptr) +void PsaiFree(void *ptr) { MemAlloc(NULL, ptr, 0); } diff --git a/lib/psapi/misc/win32.c b/lib/psapi/misc/win32.c index c19bdc3..5b0c9be 100644 --- a/lib/psapi/misc/win32.c +++ b/lib/psapi/misc/win32.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include /* EmptyWorkingSet */ BOOL STDCALL EmptyWorkingSet(HANDLE hProcess) @@ -73,8 +73,7 @@ typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT /* callback routine */ NTSTATUS STDCALL EnumDeviceDriversCallback ( - IN ULONG ModuleCount, - IN PSYSTEM_MODULE_ENTRY CurrentModule, + IN PSYSTEM_MODULE_INFORMATION CurrentModule, IN OUT PVOID CallbackContext ) { @@ -86,7 +85,7 @@ NTSTATUS STDCALL EnumDeviceDriversCallback return STATUS_INFO_LENGTH_MISMATCH; /* return current module */ - *(peddcContext->lpImageBase) = CurrentModule->BaseAddress; + *(peddcContext->lpImageBase) = CurrentModule->Base; /* go to next array slot */ (peddcContext->lpImageBase) ++; @@ -143,7 +142,7 @@ typedef struct _ENUM_PROCESSES_CONTEXT /* callback routine */ NTSTATUS STDCALL EnumProcessesCallback ( - IN PSYSTEM_PROCESS_INFORMATION CurrentProcess, + IN PSYSTEM_PROCESSES CurrentProcess, IN OUT PVOID CallbackContext ) { @@ -165,7 +164,7 @@ NTSTATUS STDCALL EnumProcessesCallback } /* exported interface */ -/* +/*! @brief Enumerate the process identifiers of the currently active processes @param lpidProcess Array that receives the list of process identifiers @@ -194,7 +193,11 @@ BOOL STDCALL EnumProcesses } /* enumerate the process ids */ - nErrCode = PsaEnumerateProcesses(&EnumProcessesCallback, &epcContext); + nErrCode = PsaEnumerateProcesses + ( + &EnumProcessesCallback, + &epcContext + ); *lpcbNeeded = (cb - epcContext.nCount) * sizeof(DWORD); @@ -305,8 +308,7 @@ typedef struct _GET_DEVICE_DRIVER_NAME_CONTEXT /* common callback routine */ NTSTATUS STDCALL GetDeviceDriverNameCallback ( - IN ULONG ModuleCount, - IN PSYSTEM_MODULE_ENTRY CurrentModule, + IN PSYSTEM_MODULE_INFORMATION CurrentModule, IN OUT PVOID CallbackContext ) { @@ -314,16 +316,16 @@ NTSTATUS STDCALL GetDeviceDriverNameCallback (PGET_DEVICE_DRIVER_NAME_CONTEXT) CallbackContext; /* module found */ - if(pgddncContext->ImageBase == CurrentModule->BaseAddress) + if(pgddncContext->ImageBase == CurrentModule->Base) { register PCHAR pcModuleName; register ULONG l; /* get the full name or just the filename part */ if(pgddncContext->bFullName) - pcModuleName = &CurrentModule->Name[0]; + pcModuleName = &CurrentModule->ImageName[0]; else - pcModuleName = &CurrentModule->Name[CurrentModule->PathLength]; + pcModuleName = &CurrentModule->ImageName[CurrentModule->ModuleNameOffset]; /* get the length of the name */ l = strlen(pcModuleName); @@ -492,7 +494,7 @@ DWORD FASTCALL internalGetMappedFileName( nBufSize = nSize * sizeof(WCHAR); /* allocate the memory */ - pmsnName = malloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer)); + pmsnName = PsaiMalloc(nBufSize + offsetof(MEMORY_SECTION_NAME, NameBuffer)); if(pmsnName == NULL) { @@ -527,7 +529,7 @@ DWORD FASTCALL internalGetMappedFileName( #if 0 #else /* free the buffer */ - free(pmsnName); + PsaiFree(pmsnName); #endif return 0; } @@ -546,7 +548,7 @@ DWORD FASTCALL internalGetMappedFileName( #if 0 #else /* free the buffer */ - free(pmsnName); + PsaiFree(pmsnName); #endif if(pmsnName->SectionFileName.Length < nSize) @@ -572,7 +574,7 @@ DWORD FASTCALL internalGetMappedFileName( #if 0 #else /* free the buffer */ - free(pmsnName); + PsaiFree(pmsnName); #endif if(strAnsi.Length < nSize) @@ -589,7 +591,7 @@ DWORD FASTCALL internalGetMappedFileName( } __finally { - free(pmsnName); + PsaiFree(pmsnName); } #endif } @@ -715,7 +717,7 @@ NTSTATUS STDCALL GetModuleInformationCallback UNICODE_STRING wstrUnicodeBuf; /* allocate the local buffer */ - pwcUnicodeBuf = malloc(pwstrSource->Length); + pwcUnicodeBuf = PsaiMalloc(pwstrSource->Length); #if 0 __try @@ -767,7 +769,7 @@ NTSTATUS STDCALL GetModuleInformationCallback __finally { /* free the buffer */ - free(pwcUnicodeBuf); + PsaiFree(pwcUnicodeBuf); } #else /* success */ @@ -775,7 +777,7 @@ NTSTATUS STDCALL GetModuleInformationCallback exitWithStatus: /* free the buffer */ - free(pwcUnicodeBuf); + PsaiFree(pwcUnicodeBuf); return nErrCode; #endif } diff --git a/lib/rosrtl/makefile b/lib/rosrtl/makefile new file mode 100644 index 0000000..c86b8a8 --- /dev/null +++ b/lib/rosrtl/makefile @@ -0,0 +1,23 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = library + +TARGET_NAME = rosrtl + +THREAD_OBJECTS = \ + thread/context.o \ + thread/create.o + +TARGET_OBJECTS = $(THREAD_OBJECTS) + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +# EOF diff --git a/lib/rosrtl/thread/context.c b/lib/rosrtl/thread/context.c new file mode 100644 index 0000000..bfaa535 --- /dev/null +++ b/lib/rosrtl/thread/context.c @@ -0,0 +1,105 @@ +/* $Id$ +*/ +/* +*/ + +#include +#include + +#if defined(_M_IX86) +#include +#include +#else +#error Unsupported architecture +#endif + +NTSTATUS NTAPI RtlRosInitializeContextEx +( + IN HANDLE ProcessHandle, + IN PCONTEXT Context, + IN PTHREAD_START_ROUTINE StartAddress, + IN PUSER_STACK UserStack, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +) +{ + ULONG nDummy; + PCHAR pStackBase; + PCHAR pStackLimit; + ULONG_PTR nRetAddr = 0xDEADBEEF; + SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR); + NTSTATUS nErrCode; + + /* fixed-size stack */ + if(UserStack->FixedStackBase && UserStack->FixedStackLimit) + { + pStackBase = UserStack->FixedStackBase; + pStackLimit = UserStack->FixedStackLimit; + } + /* expandable stack */ + else if(UserStack->ExpandableStackBase && UserStack->ExpandableStackLimit) + { + pStackBase = UserStack->ExpandableStackBase; + pStackLimit = UserStack->ExpandableStackLimit; + } + /* bad initial stack */ + else + return STATUS_BAD_INITIAL_STACK; + + /* stack base lower than the limit */ + if(pStackBase <= pStackLimit) + return STATUS_BAD_INITIAL_STACK; + +#if defined(_M_IX86) + /* Intel x86: all parameters passed on the stack */ + /* too many parameters */ + if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit)) + return STATUS_STACK_OVERFLOW; + + memset(Context, 0, sizeof(CONTEXT)); + + /* initialize the context */ + Context->ContextFlags = CONTEXT_FULL; + Context->FloatSave.ControlWord = FLOAT_SAVE_CONTROL; + Context->FloatSave.StatusWord = FLOAT_SAVE_STATUS; + Context->FloatSave.TagWord = FLOAT_SAVE_TAG; + Context->FloatSave.DataSelector = FLOAT_SAVE_DATA; + Context->Eip = (ULONG_PTR)StartAddress; + Context->SegGs = USER_DS; + Context->SegFs = TEB_SELECTOR; + Context->SegEs = USER_DS; + Context->SegDs = USER_DS; + Context->SegCs = USER_CS; + Context->SegSs = USER_DS; + Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR)); + Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9); + + /* write the parameters */ + nErrCode = NtWriteVirtualMemory + ( + ProcessHandle, + ((PUCHAR)pStackBase) - nParamsSize, + Parameters, + nParamsSize, + &nDummy + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + /* write the return address */ + return NtWriteVirtualMemory + ( + ProcessHandle, + ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)), + &nRetAddr, + sizeof(ULONG_PTR), + &nDummy + ); + +#else +#error Unsupported architecture +#endif +} + +/* EOF */ diff --git a/lib/rosrtl/thread/create.c b/lib/rosrtl/thread/create.c new file mode 100644 index 0000000..da9887c --- /dev/null +++ b/lib/rosrtl/thread/create.c @@ -0,0 +1,260 @@ +/* $Id$ +*/ +/* +*/ + +#include +#include +#include + +#define NDEBUG +#include + +NTSTATUS STDCALL RtlRosCreateUserThreadEx +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +) +{ + USER_STACK usUserStack; + OBJECT_ATTRIBUTES oaThreadAttribs; + /* FIXME: read the defaults from the executable image */ + ULONG_PTR nStackReserve = 0x100000; + /* FIXME: when we finally have exception handling, make this PAGE_SIZE */ + ULONG_PTR nStackCommit = 0x100000; + ULONG_PTR nSize = 0; + PVOID pStackLowest = NULL; + ULONG nDummy; + CONTEXT ctxInitialContext; + NTSTATUS nErrCode; + HANDLE hThread; + CLIENT_ID cidClientId; + + if(ThreadHandle == NULL) ThreadHandle = &hThread; + if(ClientId == NULL) ClientId = &cidClientId; + + if(StackReserve == NULL) StackReserve = &nStackReserve; + else ROUNDUP(*StackReserve, PAGE_SIZE); + + if(StackCommit == NULL) StackCommit = &nStackCommit; + else ROUNDUP(*StackCommit, PAGE_SIZE); + +#if 0 + /* the stack commit size must be equal to or less than the reserve size */ + if(*StackCommit > *StackReserve) *StackCommit = *StackReserve; +#else + /* FIXME: no SEH, no guard pages */ + *StackCommit = *StackReserve; +#endif + + usUserStack.FixedStackBase = NULL; + usUserStack.FixedStackLimit = NULL; + usUserStack.ExpandableStackBase = NULL; + usUserStack.ExpandableStackLimit = NULL; + usUserStack.ExpandableStackBottom = NULL; + + /* FIXME: this code assumes a stack growing downwards */ + /* fixed stack */ + if(*StackCommit == *StackReserve) + { + usUserStack.FixedStackLimit = NULL; + + /* allocate the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.FixedStackLimit), + StackZeroBits, + StackReserve, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + /* store the highest (first) address of the stack */ + usUserStack.FixedStackBase = + (PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve; + + *StackCommit = *StackReserve; + } + /* expandable stack */ + else + { + ULONG_PTR nGuardSize = PAGE_SIZE; + PVOID pGuardBase; + + DPRINT("Expandable stack\n"); + + usUserStack.FixedStackLimit = NULL; + usUserStack.FixedStackBase = NULL; + usUserStack.ExpandableStackBottom = NULL; + + /* reserve the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackBottom), + StackZeroBits, + StackReserve, + MEM_RESERVE, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + DPRINT("Reserved %08X bytes\n", *StackReserve); + + /* expandable stack base - the highest address of the stack */ + usUserStack.ExpandableStackBase = + (PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve; + + /* expandable stack limit - the lowest committed address of the stack */ + usUserStack.ExpandableStackLimit = + (PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit; + + DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase); + DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit); + DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom); + + /* commit as much stack as requested */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackLimit), + 0, + StackCommit, + MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + assert((*StackReserve - *StackCommit) >= PAGE_SIZE); + assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0); + + pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE; + + DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); + + /* set up the guard page */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &pGuardBase, + 0, + &nGuardSize, + MEM_COMMIT, + PAGE_READWRITE | PAGE_GUARD + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); + } + + /* initialize the registers and stack for the thread */ + nErrCode = RtlRosInitializeContextEx + ( + ProcessHandle, + &ctxInitialContext, + StartAddress, + &usUserStack, + ParameterCount, + Parameters + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + /* create the thread object */ + nErrCode = NtCreateThread + ( + ThreadHandle, + THREAD_ALL_ACCESS, + ObjectAttributes, + ProcessHandle, + ClientId, + &ctxInitialContext, + &usUserStack, + CreateSuspended + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + /* success */ + return STATUS_SUCCESS; + + /* deallocate the stack */ +l_Cleanup: + if(usUserStack.FixedStackLimit) + pStackLowest = usUserStack.FixedStackLimit; + else if(usUserStack.ExpandableStackBottom) + pStackLowest = usUserStack.ExpandableStackBottom; + + /* free the stack, if it was allocated */ + if(pStackLowest != NULL) + NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE); + + /* failure */ +l_Fail: + assert(!NT_SUCCESS(nErrCode)); + return nErrCode; +} + +NTSTATUS CDECL RtlRosCreateUserThreadVa +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + ... +) +{ + va_list vaArgs; + NTSTATUS nErrCode; + + va_start(vaArgs, ParameterCount); + + /* FIXME: this code assumes a stack growing downwards */ + nErrCode = RtlRosCreateUserThreadEx + ( + ProcessHandle, + ObjectAttributes, + CreateSuspended, + StackZeroBits, + StackReserve, + StackCommit, + StartAddress, + ThreadHandle, + ClientId, + ParameterCount, + (ULONG_PTR *)vaArgs + ); + + va_end(vaArgs); + + return nErrCode; +} + +/* EOF */ diff --git a/lib/tgetopt/Makefile b/lib/tgetopt/Makefile new file mode 100644 index 0000000..193312b --- /dev/null +++ b/lib/tgetopt/Makefile @@ -0,0 +1,19 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = library + +TARGET_NAME = tgetopt + +TARGET_OBJECTS = getopt.o _wgetopt.o + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +# EOF diff --git a/lib/tgetopt/_wgetopt.c b/lib/tgetopt/_wgetopt.c new file mode 100644 index 0000000..91efed4 --- /dev/null +++ b/lib/tgetopt/_wgetopt.c @@ -0,0 +1,15 @@ +/* $Id$ +*/ +/* + tgetopt -- POSIX-compliant implementation of getopt() with string-type-generic + semantics + + This is public domain software +*/ + +#include + +#define _UNICODE +#include "getopt.c" + +/* EOF */ diff --git a/lib/tgetopt/getopt.c b/lib/tgetopt/getopt.c new file mode 100644 index 0000000..505a447 --- /dev/null +++ b/lib/tgetopt/getopt.c @@ -0,0 +1,135 @@ +/* $Id$ +*/ +/* + tgetopt -- POSIX-compliant implementation of getopt() with string-type-generic + semantics + + This is public domain software +*/ + +#include +#include +#include +#include + +int _topterr = 1; +int _toptind = 1; +int _toptopt; +_TCHAR * _toptarg; + +int _tgetopt(int argc, _TCHAR * const argv[], const _TCHAR * optstring) +{ + static int s_nArgChar = 0; + _TCHAR * pcOptChar; + + /* we're done */ + if(_toptind >= argc) return -1; + + /* last time we reached the end of argv[_toptind] */ + if(s_nArgChar != 0 && argv[_toptind][s_nArgChar] == 0) + { + /* scan the next argument */ + ++ _toptind; + + /* we're done */ + if(_toptind >= argc) return -1; + + s_nArgChar = 0; + } + + /* first time we scan argv[_toptind] */ + if(s_nArgChar == 0) + { + /* argument is NULL - we're done */ + if(argv[_toptind] == NULL) + return (int)-1; + /* argument is empty - we're done */ + else if(argv[_toptind][0] == 0) + return (int)-1; + /* argument begins with '-' */ + else if(argv[_toptind][0] == _T('-')) + { + /* argument is "--" */ + if(argv[_toptind][1] == _T('-')) + { + /* increment optind */ + ++ _toptind; + s_nArgChar = 0; + + /* we're done */ + return (int)-1; + } + /* argument is "-" */ + else if(argv[_toptind][1] == 0) + { + /* we're done */ + return (int)-1; + } + /* possible option */ + else + ++ s_nArgChar; + } + /* argument doesn't begin with a dash - we're done */ + else + return (int)-1; + } + + /* return the current character */ + _toptopt = argv[_toptind][s_nArgChar]; + + /* advance to the next character */ + ++ s_nArgChar; + + /* unrecognized option */ + if(_toptopt == _T(':') || (pcOptChar = _tcschr(optstring, _toptopt)) == NULL) + { + /* print an error message */ + if(_topterr && optstring[0] != _T(':')) + _ftprintf(stderr, _T("%s: illegal option -- %c\n"), argv[0], _toptopt);; + + /* return an error */ + return _T('?'); + } + + /* the option requires an argument */ + if(pcOptChar[1] == _T(':')) + { + /* we are at the end of the argument */ + if(argv[_toptind][s_nArgChar] == 0) + { + /* the argument of the option is the next argument */ + ++ _toptind; + s_nArgChar = 0; + + /* this is the last argument */ + if(_toptopt >= argc) + { + /* print an error message */ + if(_topterr && optstring[0] != _T(':')) + { + _ftprintf + ( + stderr, + _T("%s: option requires an argument -- %c\n"), + argv[0], + _toptopt + ); + } + + /* return an error */ + return ((optstring[0] == _T(':')) ? _T(':') : _T('?')); + } + + /* return the argument */ + _toptarg = argv[_toptind]; + } + /* the rest of the argument is the argument of the option */ + else + _toptarg = argv[_toptind] + s_nArgChar; + } + + /* success */ + return _toptopt; +} + +/* EOF */ diff --git a/lib/user32/Makefile b/lib/user32/Makefile index 3769634..c0ce20d 100644 --- a/lib/user32/Makefile +++ b/lib/user32/Makefile @@ -19,14 +19,6 @@ TARGET_CFLAGS = \ TARGET_LFLAGS = -nostartfiles -nostdlib -TARGET_OBJECTS = $(TARGET_NAME).o - -TARGET_CLEAN = controls/*.o misc/*.o windows/*.o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - CONTROLS_OBJECTS = \ controls/combobox.o \ controls/listbox.o \ @@ -72,12 +64,19 @@ WINDOWS_OBJECTS = \ windows/rect.o \ windows/text.o -OBJECTS = \ +TARGET_OBJECTS = \ $(MISC_OBJECTS) \ $(WINDOWS_OBJECTS) \ $(CONTROLS_OBJECTS) -$(TARGET_NAME).o: $(OBJECTS) - $(LD) -r $(OBJECTS) -o $(TARGET_NAME).o +DEP_OBJECTS = $(TARGET_OBJECTS) + +DEP_EXCLUDE_FILTER = misc/win32k.% + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk # EOF diff --git a/lib/user32/controls/scrollbar.c b/lib/user32/controls/scrollbar.c index 393c56c..5ee30a4 100644 --- a/lib/user32/controls/scrollbar.c +++ b/lib/user32/controls/scrollbar.c @@ -10,8 +10,6 @@ */ /* INCLUDES ******************************************************************/ -/* INCLUDES ******************************************************************/ - #include #include #include @@ -73,7 +71,8 @@ static INT SCROLL_TrackingPos = 0; static enum SCROLL_HITTEST SCROLL_trackHitTest; /* Hit test code of the last button-down event */ static BOOL SCROLL_trackVertical; -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS +*****************************************************************/ HBRUSH DefWndControlColor (HDC hDC, UINT ctlType); HPEN STDCALL GetSysColorPen (int nIndex); @@ -91,7 +90,8 @@ GetScrollBarInfo (HWND hwnd, LONG idObject, PSCROLLBARINFO psbi) /* Ported from WINE20020904 */ /* Draw the scroll bar interior (everything except the arrows). */ static void -SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, INT arrowSize, PSCROLLBARINFO psbi) +SCROLL_DrawInterior (HWND hwnd, HDC hdc, INT nBar, BOOL vertical, INT +arrowSize, PSCROLLBARINFO psbi) { INT thumbSize = psbi->xyThumbBottom - psbi->xyThumbTop; HPEN hSavePen; @@ -111,82 +111,82 @@ DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); * The window-owned scrollbars need to call DefWndControlColor * to correctly setup default scrollbar colors */ - if (nBar == SB_CTL) - { - hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, - (WPARAM) hdc, (LPARAM) hwnd); - } + if ( nBar == SB_CTL ) + { + hBrush = (HBRUSH) NtUserSendMessage (GetParent (hwnd), WM_CTLCOLORSCROLLBAR, (WPARAM) hdc, (LPARAM) hwnd); + } else - { -/* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME */ /* DefWndControlColor */ - hBrush = GetSysColorBrush(COLOR_SCROLLBAR); - } + { +/* hBrush = NtUserGetControlColor (hdc, CTLCOLOR_SCROLLBAR); FIXME +*/ /* DefWndControlColor */ + hBrush = GetSysColorBrush(COLOR_SCROLLBAR); + } hSavePen = SelectObject (hdc, GetSysColorPen (COLOR_WINDOWFRAME)); hSaveBrush = SelectObject (hdc, hBrush); /* Calculate the scroll rectangle */ - if (nBar == SB_VERT) - { - psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; - psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - } - else if (nBar == SB_HORZ) - { - psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; - psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - } + if (vertical) + { + psbi->rcScrollBar.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; + psbi->rcScrollBar.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + } + else + { + psbi->rcScrollBar.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP; + psbi->rcScrollBar.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + } /* Draw the scroll rectangles and thumb */ if (!psbi->dxyLineButton) /* No thumb to draw */ - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - PATCOPY); - - /* cleanup and return */ - SelectObject (hdc, hSavePen); - SelectObject (hdc, hSaveBrush); - return; - } + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + PATCOPY); + + /* cleanup and return */ + SelectObject (hdc, hSavePen); + SelectObject (hdc, hSaveBrush); + return; + } - if (nBar == SB_VERT) - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), - top_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top + thumbSize, - psbi->rcScrollBar.right - psbi->rcScrollBar.left, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize, - bottom_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize; - } - else if (nBar == SB_HORZ) - { - PatBlt (hdc, - psbi->rcScrollBar.left, - psbi->rcScrollBar.top, - psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - top_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); - PatBlt (hdc, - psbi->rcScrollBar.left + thumbSize, - psbi->rcScrollBar.top, - psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize, - psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, - bottom_selected ? 0x0f0000 : PATCOPY); - psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize; - } + if (vertical) + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), + top_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.top += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top + thumbSize, + psbi->rcScrollBar.right - psbi->rcScrollBar.left, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top - thumbSize, + bottom_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.bottom = psbi->rcScrollBar.top + thumbSize; + } + else + { + PatBlt (hdc, + psbi->rcScrollBar.left, + psbi->rcScrollBar.top, + psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP), + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + top_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.left += psbi->dxyLineButton - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP); + PatBlt (hdc, + psbi->rcScrollBar.left + thumbSize, + psbi->rcScrollBar.top, + psbi->rcScrollBar.right - psbi->rcScrollBar.left - thumbSize, + psbi->rcScrollBar.bottom - psbi->rcScrollBar.top, + bottom_selected ? 0x0f0000 : PATCOPY); + psbi->rcScrollBar.right = psbi->rcScrollBar.left + thumbSize; + } /* Draw the thumb */ DrawEdge (hdc, &psbi->rcScrollBar, EDGE_RAISED, BF_RECT | BF_MIDDLE); @@ -198,14 +198,14 @@ DbgPrint("[SCROLL_DrawInterior:%d]\n", nBar); /* Ported from WINE20020904 */ static void -SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumbSize, PSCROLLBARINFO psbi) +SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, BOOL vertical, int arrowSize, int thumbSize, PSCROLLBARINFO psbi) { INT pos = SCROLL_TrackingPos; INT max_size; - if (nBar == SB_VERT) + if ( vertical ) max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top; - else if (nBar == SB_HORZ) + else max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left; max_size -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP) + thumbSize; @@ -215,7 +215,7 @@ SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumb else if (pos > max_size) pos = max_size; - SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, arrowSize, psbi); + SCROLL_DrawInterior (SCROLL_TrackingWin, hdc, SCROLL_TrackingBar, vertical, arrowSize, psbi); SCROLL_MovingThumb = !SCROLL_MovingThumb; } @@ -224,41 +224,35 @@ SCROLL_DrawMovingThumb (HDC hdc, RECT * rect, int nBar, int arrowSize, int thumb /* Draw the scroll bar arrows. */ static void SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info, - RECT * rect, INT arrowSize, int nBar, - BOOL top_pressed, BOOL bottom_pressed) + RECT * rect, INT arrowSize, BOOL vertical, + BOOL top_pressed, BOOL bottom_pressed) { - RECT r; + RECT r1, r2; int scrollDirFlag1, scrollDirFlag2; - if (nBar == SB_VERT) + r1 = r2 = *rect; + if (vertical) { scrollDirFlag1 = DFCS_SCROLLUP; scrollDirFlag2 = DFCS_SCROLLDOWN; + r1.bottom = r1.top + arrowSize; + r2.top = r2.bottom - arrowSize; } - else if (nBar == SB_HORZ) + else { scrollDirFlag1 = DFCS_SCROLLLEFT; scrollDirFlag2 = DFCS_SCROLLRIGHT; + r1.right = r1.left + arrowSize; + r2.left = r2.right - arrowSize; } - r = *rect; - if (nBar == SB_VERT) - r.bottom = r.top + arrowSize; - else if (nBar == SB_HORZ) - r.right = r.left + arrowSize; - - DrawFrameControl (hdc, &r, DFC_SCROLL, - scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) - /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */ + DrawFrameControl (hdc, &r1, DFC_SCROLL, + scrollDirFlag1 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0) */ ); - r = *rect; - if (nBar == SB_VERT) - r.top = r.bottom - arrowSize; - else if (nBar == SB_HORZ) - r.left = r.right - arrowSize; - DrawFrameControl (hdc, &r, DFC_SCROLL, - scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) - /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */ + DrawFrameControl (hdc, &r2, DFC_SCROLL, + scrollDirFlag2 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0) + /* | (info.flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) */ ); } @@ -266,32 +260,47 @@ SCROLL_DrawArrows (HDC hdc, PSCROLLBARINFO info, /* Redraw the whole scrollbar. */ void SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, - BOOL arrows, BOOL interior) + BOOL arrows, BOOL interior) { INT arrowSize = 0; INT thumbSize; SCROLLBARINFO info; BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb; + BOOL vertical; info.cbSize = sizeof(SCROLLBARINFO); GetScrollBarInfo (hwnd, nBar, &info); thumbSize = info.xyThumbBottom - info.xyThumbTop; - if (nBar == SB_HORZ) - { - arrowSize = GetSystemMetrics(SM_CYHSCROLL); - } else - if (nBar == SB_VERT) + switch ( nBar ) { - arrowSize = GetSystemMetrics(SM_CXVSCROLL); + case SB_HORZ: + vertical = FALSE; + break; + case SB_VERT: + vertical = TRUE; + break; + case SB_CTL: + vertical = (GetWindowLong(hwnd,GWL_STYLE)&SBS_VERT) != 0; + break; +#ifdef DBG + default: + DASSERT(!"SCROLL_DrawScrollBar() called with invalid nBar"); + break; +#endif /* DBG */ } + if (vertical) + arrowSize = GetSystemMetrics(SM_CXVSCROLL); + else + arrowSize = GetSystemMetrics(SM_CYHSCROLL); + if (IsRectEmpty (&(info.rcScrollBar))) goto END; if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) { - SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), nBar, arrowSize, thumbSize, &info); + SCROLL_DrawMovingThumb (hdc, &(info.rcScrollBar), vertical, arrowSize, thumbSize, &info); } /* Draw the arrows */ @@ -299,36 +308,36 @@ SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, { if (SCROLL_trackVertical == TRUE /* && GetCapture () == hwnd */) { - SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical, (SCROLL_trackHitTest == SCROLL_TOP_ARROW), (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW)); } else { - SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, nBar, FALSE, FALSE); + SCROLL_DrawArrows (hdc, &info, &(info.rcScrollBar), arrowSize, vertical, FALSE, FALSE); } } if (interior) { - SCROLL_DrawInterior (hwnd, hdc, nBar, arrowSize, &info); + SCROLL_DrawInterior (hwnd, hdc, nBar, vertical, arrowSize, &info); } if (Save_SCROLL_MovingThumb && (SCROLL_TrackingWin == hwnd) && (SCROLL_TrackingBar == nBar)) - SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, nBar, arrowSize, thumbSize, &info); + SCROLL_DrawMovingThumb (hdc, &info.rcScrollBar, vertical, arrowSize, thumbSize, &info); /* if scroll bar has focus, reposition the caret */ /* if (hwnd == GetFocus () && (nBar == SB_CTL)) { if (nBar == SB_HORZ) - { - SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1); - } + { + SetCaretPos (info.dxyLineButton + 1, info.rcScrollBar.top + 1); + } else if (nBAR == SB_VERT) - { - SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1); - } + { + SetCaretPos (info.rcScrollBar.top + 1, info.dxyLineButton + 1); + } } */ END:; /* WIN_ReleaseWndPtr(wndPtr); */ diff --git a/lib/user32/misc/desktop.c b/lib/user32/misc/desktop.c index 6c9c5d7..7f866e7 100644 --- a/lib/user32/misc/desktop.c +++ b/lib/user32/misc/desktop.c @@ -39,7 +39,7 @@ SystemParametersInfoW(UINT uiAction, /* FIXME: This should be obtained from the registry */ static LOGFONT CaptionFont = { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, - 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Timmons" }; + 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"Helmet" }; switch (uiAction) { diff --git a/lib/user32/misc/resources.c b/lib/user32/misc/resources.c index 0e35d36..5e93586 100644 --- a/lib/user32/misc/resources.c +++ b/lib/user32/misc/resources.c @@ -3,6 +3,11 @@ #include #include +/* FIXME: Currently IsBadWritePtr is implemented using VirtualQuery which + does not seem to work properly for stack address space. */ +/* kill `left-hand operand of comma expression has no effect' warning */ +#define IsBadWritePtr(lp, n) ((DWORD)lp==n?0:0) + BOOL STDCALL _InternalLoadString ( HINSTANCE hInstance, @@ -11,6 +16,7 @@ BOOL STDCALL _InternalLoadString ) { HRSRC hrsStringTable; + HGLOBAL hResource; PWCHAR pStringTable; unsigned i; unsigned l = uID % 16; /* (1) */ @@ -40,7 +46,13 @@ BOOL STDCALL _InternalLoadString if(hrsStringTable == NULL) return FALSE; /* load the string table into memory */ - pStringTable = LoadResource((HMODULE)hInstance, hrsStringTable); + hResource = LoadResource((HMODULE)hInstance, hrsStringTable); + + /* failure */ + if(hResource == NULL) return FALSE; + + /* lock the resource into memory */ + pStringTable = LockResource(hResource); /* failure */ if(pStringTable == NULL) return FALSE; @@ -65,8 +77,8 @@ BOOL STDCALL _InternalLoadString return FALSE; /* 3 */ } - /* string length */ - pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable); + /* string length in bytes */ + pwstrDest->Length = pwstrDest->MaximumLength = (*pStringTable) * sizeof(WCHAR); /* string */ pwstrDest->Buffer = pStringTable + 1; @@ -117,7 +129,7 @@ int STDCALL LoadStringA if(!NT_SUCCESS(nErrCode)) { /* failure */ - SetLastErrorByStatus(nErrCode); + RtlNtStatusToDosError(nErrCode); return 0; } diff --git a/lib/user32/misc/stubs.c b/lib/user32/misc/stubs.c index ba49db1..8ad3185 100644 --- a/lib/user32/misc/stubs.c +++ b/lib/user32/misc/stubs.c @@ -10,6 +10,7 @@ * 08-05-2001 CSH Created */ #include +#include WINBOOL STDCALL @@ -538,5 +539,29 @@ SetWindowsHookExW( return 0; } +VOID +STDCALL +keybd_event( + BYTE bVk, + BYTE bScan, + DWORD dwFlags, + DWORD dwExtraInfo) + + +{ + UNIMPLEMENTED +} + +VOID +STDCALL +mouse_event( + DWORD dwFlags, + DWORD dx, + DWORD dy, + DWORD cButtons, + DWORD dwExtraInfo) +{ + UNIMPLEMENTED +} /* EOF */ diff --git a/lib/user32/misc/timer.c b/lib/user32/misc/timer.c index 4406d96..923d9c2 100644 --- a/lib/user32/misc/timer.c +++ b/lib/user32/misc/timer.c @@ -29,6 +29,7 @@ /* INCLUDES ******************************************************************/ #include +#include #include #include @@ -38,18 +39,44 @@ WINBOOL STDCALL KillTimer( HWND hWnd, - UINT_PTR uIDEvent) + UINT_PTR IDEvent) { - return FALSE; + + NTSTATUS Status; + + Status = NtUserKillTimer(hWnd, IDEvent); + + if (!NT_SUCCESS(Status)) + { + RtlNtStatusToDosError(Status); + return FALSE; + } + + return TRUE; + } + UINT_PTR STDCALL SetTimer( HWND hWnd, - UINT_PTR nIDEvent, - UINT uElapse, - TIMERPROC lpTimerFunc) + UINT_PTR IDEvent, + UINT Period, + TIMERPROC TimerFunc) { - return (UINT_PTR)0; + NTSTATUS Status; + + Status = NtUserSetTimer(hWnd, &IDEvent, Period, TimerFunc); + + if (!NT_SUCCESS(Status)) + { + RtlNtStatusToDosError(Status); + return FALSE; + } + + if (hWnd == NULL) + return IDEvent; + + return TRUE; } diff --git a/lib/user32/resources/obm_close.bmp b/lib/user32/resources/obm_close.bmp index f800b069add07cbc778fb05a66c9eea7c5d8f8ba..58a0a34a2d873332d011d8fa0d60869de9153ae2 100644 GIT binary patch literal 246 zcmZ?r{l)+RWk5;;hy|dSk%0v)(Eui~5kMJ`WJ3dl0+K)`5H~O!IB)v%%L}wdhvrDe?;U~Enrn&2e3`Dps%YucK)7CWzfh!bJ`5P8)+NKwTbGykU zz|E|MZJ^$4Efayxv$qK3`Yd#U+^#u-T+Ko!$cG-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP si=(j_1qET^0t^T?0|O&WTmYyI#uh|YgNqHa0cIw4wlNqOf!u=(0AHICT>t<8 diff --git a/lib/user32/resources/obm_dnarrowd.bmp b/lib/user32/resources/obm_dnarrowd.bmp deleted file mode 100644 index 51b38e90f7576543ddcb28b729243df3ce2beaee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP=upG|}Qrf)D`GfR8NzR0dPSzzAmx f09_0d2TC)-*n&uEaI!%*!^|YeR)PSKdSn0qN^lGH diff --git a/lib/user32/resources/obm_dnarrowi.bmp b/lib/user32/resources/obm_dnarrowi.bmp deleted file mode 100644 index 3cbf4fbba4cf728c361ad1a2ac2f24576df47145..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP zivyX$f`V|ivLT!;q+|?dD=8@(Le&TXO@fOHDIu#zW+Ryiv;uBER<O#07Y~Y AfdBvi diff --git a/lib/user32/resources/obm_lfarrow.bmp b/lib/user32/resources/obm_lfarrow.bmp deleted file mode 100644 index 6ceef25255015b43b5808ed4acedb2be38cbb6b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP ri=(j_1qET^0!VD2Qkb{^5*zFzZ0ZG(^nz@Fslm=R1_L9IdyoMDRHhL> diff --git a/lib/user32/resources/obm_lfarrowd.bmp b/lib/user32/resources/obm_lfarrowd.bmp deleted file mode 100644 index bb446c3e0400a3fda7cafbf0c98805a87529ec5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP=upG|}Qrf)D`GfR8NzR0dPSfM5$S hFfhWzfzog`vbZ3UdO>7!KsLk7B*<2R0FZiQ002|43=;qV diff --git a/lib/user32/resources/obm_lfarrowi.bmp b/lib/user32/resources/obm_lfarrowi.bmp deleted file mode 100644 index c81363d484fc9f85582f6bf06e25db861776046e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP zivyX$f`V|iGJ-9nXlw`*2kM5gg^<{SKsH>j5RzU&WH!(Wm^mPeG1ZSqyz>k Y%z{8$83mDOK@b4)$)t_JKm}$s08Dxn00000 diff --git a/lib/user32/resources/obm_restore.bmp b/lib/user32/resources/obm_restore.bmp deleted file mode 100644 index a22d3ddff44ef854de968e9da099bdfe38a8c0df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmZ?reZ~L*Wk5;;hy{R{4~Q8VSb!vMuz&x4hMPBUGSt`CGyMPmAGbn0GS0?eVBjPO n1_n+*%NYd)fwZ6?It`S7$RpE&V1+>aV2ub`2@DKeAix0tJ)swL diff --git a/lib/user32/resources/obm_restored.bmp b/lib/user32/resources/obm_restored.bmp deleted file mode 100644 index 6958dc2ca1553d2360b553650880d5946b326b8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmZ?reZ~L*Wk5;;hy{R{4~Q8VSb!vMuz&x4hMPBUGSt`CGyMPmAGbm*GA>ZSqyz>k r%z{8gf`UMrQBVM#WνG-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP xi=(j_1qI>a3~;sp0|O&W9LQ!sV#CD+1rh261(D4GS^+l`E87?hj6m)|1^`r|5kCL` diff --git a/lib/user32/resources/obm_rgarrowd.bmp b/lib/user32/resources/obm_rgarrowd.bmp deleted file mode 100644 index abf3f7c99f207f9671776c128b51abdef8e23d52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP=upG|}Qrf)D`GfR8NzR0dNczzAmp fg^<~dFg3{Hf=KEGk<9_w3^S7;TL}U{>X88eQ*aCu diff --git a/lib/user32/resources/obm_rgarrowi.bmp b/lib/user32/resources/obm_rgarrowi.bmp deleted file mode 100644 index a90b836a7392e14ed6ede6e0ce1b9dd06fde2ddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP zivyX$f`V|ivLT#ptYi#h3n?in8$#6p*-A*_iZC|N5F~RHk=Q^h;O1jx8-sxnx~Bk4 CPZNOv diff --git a/lib/user32/resources/obm_uparrow.bmp b/lib/user32/resources/obm_uparrow.bmp deleted file mode 100644 index ce3aa0e29ae0f609da861858e4d86e6506edab32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP ti=(my7z71j;yBm>Ky7d}3=E8LHnMs_Mua&a8(?N)XB&fo5y(Br003eO5nTWP diff --git a/lib/user32/resources/obm_uparrowd.bmp b/lib/user32/resources/obm_uparrowd.bmp deleted file mode 100644 index 872dc323044903f728efb046520a9cb15b9f304a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmZ?rbz)=ygEAng0mOn(%*en37RN>G-@l)szP=upG|}Qrf)D`GfRD|G-@l)szP_H}|NsBEln^D(qyzyV#mvZTK`>AP zivyX)hJrA*kP=q5u#u9mAykbJ&?LBeB_%~TTS!R|&K6WeVgs#!nGdoUlWhzJM(Cab E0AU&vp8x;= diff --git a/lib/user32/resources/obm_zoom.bmp b/lib/user32/resources/obm_zoom.bmp deleted file mode 100644 index a3838ebaea15aa4c710af4cfc79153dbab26fd7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 230 zcmZ?reZ~L*Wk5;;hy{R{4~Q8VSb!vMuz&x4hMPBUGSt`CGyMPmAGbn0GS0?eVBjPO c1_n+b%NYcLG>|Vq3Juc-rIoZSqyz>k h%z_|Aj6j-EP*9K*8m13M1GNhZsxTXafeJ_z1ONtop = rect->left = 0; rect->right = WindowRect.right - WindowRect.left; rect->bottom = WindowRect.bottom - WindowRect.top; @@ -211,224 +287,187 @@ void UserGetInsideRectNC( HWND hwnd, RECT *rect ) } } -void UserDrawSysButton( HWND hwnd, HDC hdc, BOOL down ) +void UserDrawSysMenuButton( HWND hWnd, HDC hDC, BOOL down ) { - RECT rect; - HDC hdcMem; - HBITMAP hbitmap; - ULONG Style; - - Style = GetWindowLong(hwnd, GWL_STYLE); - UserGetInsideRectNC( hwnd, &rect ); - hdcMem = CreateCompatibleDC( hdc ); - hbitmap = SelectObject( hdcMem, hbitmapClose ); - BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), - GetSystemMetrics(SM_CYSIZE), hdcMem, - (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0, - down ? NOTSRCCOPY : SRCCOPY ); - SelectObject( hdcMem, hbitmap ); - DeleteDC( hdcMem ); + RECT Rect; + HDC hDcMem; + HBITMAP hSavedBitmap; + + hbSysMenu = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE)); + UserGetInsideRectNC(hWnd, &Rect); + hDcMem = CreateCompatibleDC(hDC); + hSavedBitmap = SelectObject(hDcMem, hbSysMenu); + BitBlt(hDC, Rect.left + 2, Rect.top + + 2, 16, 16, hDcMem, + (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ? + GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY); + SelectObject(hDcMem, hSavedBitmap); + DeleteDC(hDcMem); } -static void UserDrawMaxButton( HWND hwnd, HDC hdc, BOOL down ) +/* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and + wasting precious CPU cycles) every time */ + +static void UserDrawCloseButton ( HWND hWnd, HDC hDC, BOOL bDown ) { RECT rect; - HDC hdcMem; - - UserGetInsideRectNC( hwnd, &rect ); - hdcMem = CreateCompatibleDC( hdc ); - SelectObject( hdcMem, (IsZoomed(hwnd) - ? (down ? hbitmapRestoreD : hbitmapRestore) - : (down ? hbitmapMaximizeD : hbitmapMaximize)) ); - BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top, - GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE), hdcMem, 0, 0, - SRCCOPY ); - DeleteDC( hdcMem ); -} - -static void UserDrawMinButton( HWND hwnd, HDC hdc, BOOL down) -{ - RECT rect; - HDC hdcMem; - - UserGetInsideRectNC(hwnd, &rect); - hdcMem = CreateCompatibleDC(hdc); - SelectObject(hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize)); - if (GetWindowLong(hwnd, GWL_STYLE) & WS_MAXIMIZEBOX) + + BOOL bToolWindow = GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW; + INT iBmpWidth = (bToolWindow ? GetSystemMetrics(SM_CXSMSIZE) : + GetSystemMetrics(SM_CXSIZE)) - 2; + INT iBmpHeight = (bToolWindow ? GetSystemMetrics(SM_CYSMSIZE) : + GetSystemMetrics(SM_CYSIZE) - 4); + INT OffsetX = UIGetFrameSizeY( hWnd ); + INT OffsetY = UIGetFrameSizeY( hWnd ); + + + if(!(GetWindowLong( hWnd, GWL_STYLE ) & WS_SYSMENU)) { - rect.right -= GetSystemMetrics(SM_CXSMSIZE)+1; + return; } - BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSMSIZE) - 1, rect.top, - GetSystemMetrics(SM_CXSMSIZE) + 1, GetSystemMetrics(SM_CYSMSIZE), - hdcMem, 0, 0, - SRCCOPY ); - DeleteDC( hdcMem ); + GetWindowRect( hWnd, &rect ); + + rect.right = rect.right - rect.left; + rect.bottom = rect.bottom - rect.top; + rect.left = rect.top = 0; + SetRect(&rect, + rect.right - OffsetX - iBmpWidth - 3, + OffsetY + 2, + rect.right - OffsetX - 3, + rect.top + iBmpHeight + OffsetY + 2 ); + + DrawFrameControl( hDC, &rect, DFC_CAPTION, + (DFCS_CAPTIONCLOSE | + (bDown ? DFCS_PUSHED : 0) | + (IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)) ); } - -static void UserDrawCaptionNC( HDC hdc, RECT *rect, HWND hwnd, - DWORD style, BOOL active ) + +static void UserDrawMaxButton( HWND hWnd, HDC hDC, BOOL bDown ) { - RECT r = *rect; - char buffer[256]; - if (!hbitmapClose) - { - hbitmapClose = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_CLOSE)); - hbitmapMinimize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCE) ); - hbitmapMinimizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_REDUCED) ); - hbitmapMaximize = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOM) ); - hbitmapMaximizeD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_ZOOMD) ); - hbitmapRestore = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORE) ); - hbitmapRestoreD = LoadBitmapW( 0, MAKEINTRESOURCE(OBM_RESTORED) ); - } + RECT rect; + INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2; + INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4; + + INT OffsetX = UIGetFrameSizeY( hWnd ); + INT OffsetY = UIGetFrameSizeY( hWnd ); + + GetWindowRect( hWnd, &rect ); + + if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd)) + return; + if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE) + return; /* ToolWindows don't have min/max buttons */ + + rect.right = rect.right - rect.left; + rect.bottom = rect.bottom - rect.top; + rect.left = rect.top = 0; + SetRect(&rect, + rect.right - OffsetX - (iBmpWidth*2) - 5, + OffsetY + 2, + rect.right - iBmpWidth - OffsetX - 5, + rect.top + iBmpHeight + OffsetY + 2 ); + + DrawFrameControl( hDC, &rect, DFC_CAPTION, + (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) | + (bDown ? DFCS_PUSHED : 0) | + (IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE) ); + +} - if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME) - { - HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) ); - PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY ); - PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); - PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY ); - r.left++; - r.right--; - SelectObject( hdc, hbrushOld ); - } +static void UserDrawMinButton( HWND hWnd, HDC hDC, BOOL bDown ) +{ - MoveToEx( hdc, r.left, r.bottom, NULL ); - LineTo( hdc, r.right, r.bottom ); + RECT rect; + INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2; + INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4; + + INT OffsetX = UIGetFrameSizeX( hWnd ); + INT OffsetY = UIGetFrameSizeY( hWnd ); + + GetWindowRect( hWnd, &rect ); + + if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd)) + return; + if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE) + return; /* ToolWindows don't have min/max buttons */ + + rect.right = rect.right - rect.left; + rect.bottom = rect.bottom - rect.top; + rect.left = rect.top = 0; + SetRect(&rect, + rect.right - OffsetX - (iBmpWidth*3) - 5, + OffsetY + 2, + rect.right - (iBmpWidth * 2) - OffsetX - 5, + rect.top + iBmpHeight + OffsetY + 2 ); + DrawFrameControl( hDC, &rect, DFC_CAPTION, + DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) | + (IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE) ); +} - if (style & WS_SYSMENU) - { - UserDrawSysButton( hwnd, hdc, FALSE ); - r.left += GetSystemMetrics(SM_CXSIZE) + 1; - MoveToEx( hdc, r.left - 1, r.top, NULL ); - LineTo( hdc, r.left - 1, r.bottom ); - } - if (style & WS_MAXIMIZEBOX) - { - UserDrawMaxButton( hwnd, hdc, FALSE ); - r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; - } - if (style & WS_MINIMIZEBOX) +static void UserDrawCaptionNC( HDC hDC, RECT *rect, HWND hWnd, + DWORD style, BOOL active ) +{ + RECT r = *rect; + char buffer[256]; + /* Implement and Use DrawCaption() */ + SelectObject( hDC, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) ); + PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top + + GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2) - 1, rect->top + + GetSystemMetrics(SM_CYCAPTION) - 1, PATCOPY ); + + if (style & WS_SYSMENU) { - UserDrawMinButton( hwnd, hdc, FALSE ); - r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; + UserDrawSysMenuButton( hWnd, hDC, FALSE); + r.left += GetSystemMetrics(SM_CXSIZE) + 1; + UserDrawCloseButton( hWnd, hDC, FALSE); + r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; + UserDrawMinButton(hWnd, hDC, FALSE); + UserDrawMaxButton(hWnd, hDC, FALSE); } - - FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : - COLOR_INACTIVECAPTION) ); - - if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) + if (GetWindowTextA( hWnd, buffer, sizeof(buffer) )) { - NONCLIENTMETRICS nclm; - HFONT hFont, hOldFont; - - nclm.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0); - if (style & WS_EX_TOOLWINDOW) - hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont); - else - hFont = CreateFontIndirectW(&nclm.lfCaptionFont); - hOldFont = SelectObject(hdc, hFont); - - if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) ); - else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ); - SetBkMode( hdc, TRANSPARENT ); - /*DrawTextA( hdc, buffer, -1, &r, - DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );*/ - TextOutA(hdc, r.left+5, r.top+2, buffer, strlen(buffer)); - DeleteObject (SelectObject (hdc, hOldFont)); + NONCLIENTMETRICS nclm; + HFONT hFont, hOldFont; + + nclm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0); + SetTextColor(hDC, SysColours[ active ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]); + SetBkMode( hDC, TRANSPARENT ); + if (style & WS_EX_TOOLWINDOW) + hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont); + else + hFont = CreateFontIndirectW(&nclm.lfCaptionFont); + hOldFont = SelectObject(hDC, hFont); + TextOutA(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), (r.top / 2) + (((int) nclm.lfCaptionFont.lfHeight) / 2) + (GetSystemMetrics(SM_CXDLGFRAME) / 2), buffer, strlen(buffer)); + DeleteObject (SelectObject (hDC, hOldFont)); } } VOID -UserDrawFrameNC(HDC hdc, RECT* rect, BOOL dlgFrame, BOOL active) +UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active) { - INT width, height; - - if (dlgFrame) - { - width = GetSystemMetrics(SM_CXDLGFRAME) - 1; - height = GetSystemMetrics(SM_CYDLGFRAME) - 1; - SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : - COLOR_INACTIVECAPTION) ); - } - else - { - width = GetSystemMetrics(SM_CXFRAME) - 2; - height = GetSystemMetrics(SM_CYFRAME) - 2; - SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER : - COLOR_INACTIVEBORDER) ); - } - - /* Draw frame */ - PatBlt( hdc, rect->left, rect->top, - rect->right - rect->left, height, PATCOPY ); - PatBlt( hdc, rect->left, rect->top, - width, rect->bottom - rect->top, PATCOPY ); - PatBlt( hdc, rect->left, rect->bottom - 1, - rect->right - rect->left, -height, PATCOPY ); - PatBlt( hdc, rect->right - 1, rect->top, - -width, rect->bottom - rect->top, PATCOPY ); - - if (dlgFrame) - { - InflateRect( rect, -width, -height ); - } - else - { - INT decYOff = GetSystemMetrics(SM_CXFRAME) + - GetSystemMetrics(SM_CXSIZE) - 1; - INT decXOff = GetSystemMetrics(SM_CYFRAME) + - GetSystemMetrics(SM_CYSIZE) - 1; - - /* Draw inner rectangle */ - - SelectObject( hdc, GetStockObject(NULL_BRUSH) ); - Rectangle( hdc, rect->left + width, rect->top + height, - rect->right - width , rect->bottom - height ); - - /* Draw the decorations */ - - MoveToEx( hdc, rect->left, rect->top + decYOff, NULL ); - LineTo( hdc, rect->left + width, rect->top + decYOff ); - MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL ); - LineTo( hdc, rect->right - width - 1, rect->top + decYOff ); - MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL ); - LineTo( hdc, rect->left + width, rect->bottom - decYOff ); - MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL ); - LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff ); - - MoveToEx( hdc, rect->left + decXOff, rect->top, NULL ); - LineTo( hdc, rect->left + decXOff, rect->top + height); - MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL ); - LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 ); - MoveToEx( hdc, rect->right - decXOff, rect->top, NULL ); - LineTo( hdc, rect->right - decXOff, rect->top + height ); - MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL ); - LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 ); - - InflateRect( rect, -width - 1, -height - 1 ); - } + SelectObject( hDC, GetSysColorBrush(COLOR_WINDOW) ); + DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE); } -void SCROLL_DrawScrollBar (HWND hwnd, HDC hdc, INT nBar, BOOL arrows, BOOL interior); +void SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior); VOID DefWndDoPaintNC(HWND hWnd, HRGN clip) { ULONG Active; - HDC hDc; + HDC hDC; RECT rect; ULONG Style; ULONG ExStyle; - Active = GetWindowLongW(hWnd, GWL_STYLE) & WIN_NCACTIVATED; Style = GetWindowLong(hWnd, GWL_STYLE); ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); - hDc = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW | + hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW | ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0)); - if (hDc == 0) + if (hDC == 0) { return; } @@ -439,45 +478,37 @@ DefWndDoPaintNC(HWND hWnd, HRGN clip) rect.right = rect.right - rect.left; rect.bottom = rect.bottom - rect.top; rect.top = rect.left = 0; - - SelectObject(hDc, GetSysColorPen(COLOR_WINDOWFRAME)); - if (UserHasAnyFrameStyle(Style, ExStyle)) - { - SelectObject(hDc, GetStockObject(NULL_BRUSH)); - Rectangle(hDc, 0, 0, rect.right, rect.bottom); - InflateRect(&rect, -1, -1); - } - + SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME)); if (UserHasThickFrameStyle(Style, ExStyle)) { - UserDrawFrameNC(hDc, &rect, FALSE, Active); + UserDrawFrameNC(hDC, &rect, FALSE, Active); } else if (UserHasDlgFrameStyle(Style, ExStyle)) { - UserDrawFrameNC(hDc, &rect, TRUE, Active); + UserDrawFrameNC(hDC, &rect, TRUE, Active); } - if (Style & WS_CAPTION) { RECT r = rect; r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE); rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER); - UserDrawCaptionNC(hDc, &r, hWnd, Style, Active); + UserDrawCaptionNC(hDC, &r, hWnd, Style, Active); } - /* FIXME: Draw menu bar. */ +/* FIXME: Draw menu bar. */ -DbgPrint("drawing scrollbars..\n"); - /* Draw scrollbars */ + DbgPrint("drawing scrollbars..\n"); +/* Draw scrollbars */ if (Style & WS_VSCROLL) - SCROLL_DrawScrollBar(hWnd, hDc, SB_VERT, TRUE, TRUE); + SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE); if (Style & WS_HSCROLL) - SCROLL_DrawScrollBar(hWnd, hDc, SB_HORZ, TRUE, TRUE); + SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE); - /* FIXME: Draw size box. */ + /* FIXME: Draw size box.*/ - ReleaseDC(hWnd, hDc); + ReleaseDC(hWnd, hDC); + } LRESULT @@ -505,9 +536,9 @@ DefWndHitTestNC(HWND hWnd, POINT Point) ULONG ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); GetWindowRect(hWnd, &WindowRect); - if (!PtInRect(&WindowRect, Point)) { + return(HTNOWHERE); } if (Style & WS_MINIMIZE) @@ -597,15 +628,20 @@ DefWndHitTestNC(HWND hWnd, POINT Point) if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW)) { WindowRect.left += GetSystemMetrics(SM_CXSIZE); + WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1; } if (Point.x <= WindowRect.left) { return(HTSYSMENU); } + if (WindowRect.right <= Point.x) + { + return(HTCLOSE); + } - if (Style & WS_MAXIMIZEBOX) + if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX) { - WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; + WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2; } if (Point.x >= WindowRect.right) { @@ -614,7 +650,7 @@ DefWndHitTestNC(HWND hWnd, POINT Point) if (Style & WS_MINIMIZEBOX) { - WindowRect.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; + WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2; } if (Point.x >= WindowRect.right) { @@ -667,167 +703,116 @@ DefWndHitTestNC(HWND hWnd, POINT Point) } VOID -DefWndTrackMinMaxBox(HWND hWnd, WPARAM wParam) -{ - HDC hDC = GetWindowDC(hWnd); - BOOL Pressed = TRUE; - MSG Msg; - - SetCapture(hWnd); - - if (wParam == HTMINBUTTON) - { - UserDrawMinButton(hWnd, hDC, TRUE); - } - else - { - UserDrawMaxButton(hWnd, hDC, TRUE); - } - - for(;;) - { - BOOL OldState = Pressed; - - GetMessageA(hWnd, &Msg, 0, 0); - if (Msg.message == WM_LBUTTONUP) - { - break; - } - if (Msg.message != WM_MOUSEMOVE) - { - continue; - } - - Pressed = DefWndHitTestNC(hWnd, Msg.pt) == (LRESULT) wParam; - if (Pressed != OldState) - { - if (wParam == HTMINBUTTON) - { - UserDrawMinButton(hWnd, hDC, Pressed); - } - else - { - UserDrawMaxButton(hWnd, hDC, Pressed); - } - } - } - - if (Pressed) - { - if (wParam == HTMINBUTTON) - { - UserDrawMinButton(hWnd, hDC, FALSE); - } - else - { - UserDrawMaxButton(hWnd, hDC, FALSE); - } - } - - ReleaseCapture(); - ReleaseDC(hWnd, hDC); - - if (!Pressed) - { - return; - } - - if (wParam == HTMINBUTTON) - { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, - MAKELONG(Msg.pt.x, Msg.pt.y)); - } - else - { - SendMessageA(hWnd, WM_SYSCOMMAND, - IsZoomed(hWnd) ? SC_RESTORE : SC_MAXIMIZE, - MAKELONG(Msg.pt.x, Msg.pt.y)); - } -} - -VOID DefWndDrawSysButton(HWND hWnd, HDC hDC, BOOL Down) { - RECT Rect; - HDC hDcMem; - HBITMAP hSavedBitmap; - - UserGetInsideRectNC(hWnd, &Rect); - hDcMem = CreateCompatibleDC(hDC); - hSavedBitmap = SelectObject(hDcMem, hbitmapClose); - BitBlt(hDC, Rect.left, Rect.top, GetSystemMetrics(SM_CXSIZE), - GetSystemMetrics(SM_CYSIZE), hDcMem, - (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ? - GetSystemMetrics(SM_CXSIZE): 0, 0, Down ? NOTSRCCOPY : SRCCOPY); - SelectObject(hDcMem, hSavedBitmap); - DeleteDC(hDcMem); } LRESULT DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam) { - switch (wParam) + switch (wParam) { - case HTCAPTION: - { - HWND hTopWnd = GetAncestor(hWnd, GA_ROOT); - if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd) - { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam); - } - break; - } - case HTSYSMENU: - { - if (GetWindowLong(hWnd, GWL_STYLE) & WS_SYSMENU) - { - if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE)) - { - HDC hDC = GetWindowDC(hWnd); - DefWndDrawSysButton(hWnd, hDC, TRUE); - ReleaseDC(hWnd, hDC); - } - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, - lParam); - } - break; - } - - case HTMENU: - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam); - break; - - case HTHSCROLL: - SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam); - break; - - case HTVSCROLL: - SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam); - break; - - case HTMINBUTTON: - case HTMAXBUTTON: - DefWndTrackMinMaxBox(hWnd, wParam); - break; - - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTBOTTOM: - case HTTOPLEFT: - case HTTOPRIGHT: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam); - break; + case HTCAPTION: + { + HWND hTopWnd = GetDesktopWindow(); //GetAncestor(hWnd, GA_ROOT); temp fix. + if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd) + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam); + } + break; + } + case HTSYSMENU: + { + if (GetWindowLong(hWnd, GWL_STYLE) & WS_SYSMENU) + { + if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE)) + { + HDC hDC = GetWindowDC(hWnd); + DefWndDrawSysButton(hWnd, hDC, TRUE); + ReleaseDC(hWnd, hDC); + } + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, + lParam); + } + break; + } + case HTMENU: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam); + break; + } + case HTHSCROLL: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam); + break; + } + case HTVSCROLL: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam); + break; + } + case HTMINBUTTON: + { + UserDrawMinButton(hWnd, GetWindowDC(hWnd), IsMinBoxActive(hWnd) ); + break; + } + case HTMAXBUTTON: + { + UserDrawMaxButton(hWnd,GetWindowDC(hWnd), IsMaxBoxActive(hWnd) ); + break; + } + case HTCLOSE: + { + UserDrawCloseButton(hWnd,GetWindowDC(hWnd),TRUE); + break; + } + case HTLEFT: + case HTRIGHT: + case HTTOP: + case HTBOTTOM: + case HTTOPLEFT: + case HTTOPRIGHT: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam); + break; + } } - return(0); + return(0); } LRESULT DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam) { - /* FIXME: Implement this. */ + return(0); +} + +LRESULT +DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + UserDrawMinButton(hWnd,GetWindowDC(hWnd),FALSE); + UserDrawMaxButton(hWnd,GetWindowDC(hWnd),FALSE); + UserDrawCloseButton(hWnd,GetWindowDC(hWnd),FALSE); + switch (wParam) + { + case HTMINBUTTON: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); + break; + } + case HTMAXBUTTON: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + break; + } + case HTCLOSE: + { + SendMessageA(hWnd, WM_CLOSE, 0, 0); + SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); + break; + } + } return(0); } @@ -994,8 +979,7 @@ DefWndNCCalcSize(HWND hWnd, RECT* Rect) LRESULT DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos) { - /* FIXME: Implement this. */ - return(0); + return 0; } LRESULT STDCALL @@ -1011,7 +995,10 @@ User32DefWindowProc(HWND hWnd, { return(DefWndPaintNC(hWnd, (HRGN)wParam)); } - + case WM_WINDOWPOSCHANGING: + { + DbgPrint("WM_WINDOWPOSCHANGING\n\n"); + } case WM_NCHITTEST: { POINT Point; @@ -1025,6 +1012,11 @@ User32DefWindowProc(HWND hWnd, return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam)); } + case WM_NCLBUTTONUP: + { + return(DefWndHandleLButtonUpNC(hWnd, wParam, lParam)); + } + case WM_LBUTTONDBLCLK: case WM_NCLBUTTONDBLCLK: { @@ -1039,7 +1031,10 @@ User32DefWindowProc(HWND hWnd, } break; } - + case WM_LBUTTONUP: + { + break; + } case WM_RBUTTONUP: { POINT Pt; @@ -1125,9 +1120,10 @@ User32DefWindowProc(HWND hWnd, case WM_PAINT: { PAINTSTRUCT Ps; - HDC hDc = BeginPaint(hWnd, &Ps); - if (hDc) + HDC hDC = BeginPaint(hWnd, &Ps); + if (hDC) { + HICON hIcon; if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE && (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL) @@ -1139,8 +1135,8 @@ User32DefWindowProc(HWND hWnd, GetSystemMetrics(SM_CXICON)) / 2; y = (WindowRect.bottom - WindowRect.top - GetSystemMetrics(SM_CYICON)) / 2; - DrawIcon(hDc, x, y, hIcon); - } + DrawIcon(hDC, x, y, hIcon); + } EndPaint(hWnd, &Ps); } return(0); @@ -1227,6 +1223,7 @@ User32DefWindowProc(HWND hWnd, case WM_ERASEBKGND: case WM_ICONERASEBKGND: { + RECT Rect; HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND); GetClipBox((HDC)wParam, &Rect); @@ -1283,13 +1280,13 @@ User32DefWindowProc(HWND hWnd, { return(0); } - /* FIXME: Check for a popup window. */ + /* FIXME: Not done correctly */ if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) || (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam)) { return(0); } - ShowWindow(hWnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE); + ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE); break; } @@ -1478,7 +1475,6 @@ DefWindowProcA(HWND hWnd, { GlobalDeleteAtom((ATOM)(ULONG)WindowTextAtom); } - /* FIXME: Destroy scroll bars here as well. */ return(0); } @@ -1583,7 +1579,7 @@ DefWindowProcW(HWND hWnd, { GlobalDeleteAtom((ATOM)(DWORD)WindowTextAtom); } - /* FIXME: Destroy scroll bars here as well. */ + return(0); } diff --git a/lib/user32/windows/draw.c b/lib/user32/windows/draw.c index c9a9aa1..6713bbc 100644 --- a/lib/user32/windows/draw.c +++ b/lib/user32/windows/draw.c @@ -117,7 +117,6 @@ static const signed char LTRBInnerFlat[] = { -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, }; - /* FUNCTIONS *****************************************************************/ @@ -450,7 +449,6 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER || (uType & BDR_OUTER) == BDR_OUTER) && !(uFlags & (BF_FLAT|BF_MONO)) ); - /* Init some vars */ LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)GetStockObject(NULL_PEN); SavePen = (HPEN)SelectObject(hdc, LTInnerPen); @@ -473,8 +471,8 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, * otherwise. * Dennis Björklund, 10 June, 99 */ -/* if( TWEAK_WineLook == WIN98_LOOK && LTInnerI != -1 ) - LTInnerI = RBInnerI = COLOR_BTNFACE; */ +/* if( TWEAK_WineLook == WIN98_LOOK && LTInnerI != -1 ) */ + LTInnerI = RBInnerI = COLOR_BTNFACE; } else if(uFlags & BF_SOFT) { @@ -500,7 +498,11 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, if(LTOuterI != -1) LTOuterPen = GetSysColorPen(LTOuterI); if(RBInnerI != -1) RBInnerPen = GetSysColorPen(RBInnerI); if(RBOuterI != -1) RBOuterPen = GetSysColorPen(RBOuterI); - + if((uFlags & BF_MIDDLE) && retval) + { + FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ? + COLOR_WINDOW : COLOR_BTNFACE)); + } MoveToEx(hdc, 0, 0, &SavePoint); /* Draw the outer edge */ @@ -518,13 +520,13 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, SelectObject(hdc, RBOuterPen); if(uFlags & BF_BOTTOM) { - MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); - LineTo(hdc, InnerRect.left-1, InnerRect.bottom-1); + MoveToEx(hdc, InnerRect.right, InnerRect.bottom-1, NULL); + LineTo(hdc, InnerRect.left, InnerRect.bottom-1); } if(uFlags & BF_RIGHT) { - MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL); - LineTo(hdc, InnerRect.right-1, InnerRect.top-1); + MoveToEx(hdc, InnerRect.right-1, InnerRect.bottom, NULL); + LineTo(hdc, InnerRect.right-1, InnerRect.top); } /* Draw the inner edge */ @@ -542,13 +544,13 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, SelectObject(hdc, RBInnerPen); if(uFlags & BF_BOTTOM) { - MoveToEx(hdc, InnerRect.right-1-RBpenplus, InnerRect.bottom-2, NULL); - LineTo(hdc, InnerRect.left-1+LBpenplus, InnerRect.bottom-2); + MoveToEx(hdc, InnerRect.right-RBpenplus, InnerRect.bottom-2, NULL); + LineTo(hdc, InnerRect.left+LBpenplus, InnerRect.bottom-2); } if(uFlags & BF_RIGHT) { - MoveToEx(hdc, InnerRect.right-2, InnerRect.bottom-1-RBpenplus, NULL); - LineTo(hdc, InnerRect.right-2, InnerRect.top-1+RTpenplus); + MoveToEx(hdc, InnerRect.right-2, InnerRect.bottom-RBpenplus, NULL); + LineTo(hdc, InnerRect.right-2, InnerRect.top+RTpenplus); } if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) ) @@ -561,12 +563,6 @@ static BOOL UITOOLS95_DrawRectEdge(HDC hdc, LPRECT rc, if(uFlags & BF_TOP) InnerRect.top += add; if(uFlags & BF_BOTTOM) InnerRect.bottom -= add; - if((uFlags & BF_MIDDLE) && retval) - { - FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ? - COLOR_WINDOW : COLOR_BTNFACE)); - } - if(uFlags & BF_ADJUST) *rc = InnerRect; } @@ -894,7 +890,12 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) COLORREF clrsave; SIZE size; - UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00); + //UITOOLS95_DFC_ButtonPush(dc, r, uFlags & 0xff00); + if(uFlags & DFCS_PUSHED) + UITOOLS95_DrawRectEdge(dc,r,EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_SOFT); + else + UITOOLS95_DrawRectEdge(dc,r,BDR_RAISEDINNER | BDR_RAISEDOUTER, BF_RECT | + BF_SOFT | BF_MIDDLE); switch(uFlags & 0xff) { @@ -937,7 +938,6 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) start.y++; } - /* now use the width of each line */ width -= numLines - 1; for (i = 0; i < numLines; i++) @@ -945,11 +945,12 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) MoveToEx(dc, start.x + i, start.y, &oldPos); LineTo(dc, start.x + i + width, start.y + height); - MoveToEx(dc, start.x + i, start.y + height - 1, &oldPos); - LineTo(dc, start.x + i + width, start.y - 1); + MoveToEx(dc, start.x + i, start.y + height, &oldPos); + LineTo(dc, start.x + i + width, start.y); } SelectObject(dc, hpsave); + return TRUE; } @@ -1041,10 +1042,8 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) return FALSE; } - /* Here the drawing takes place */ if(uFlags & DFCS_INACTIVE) { - /* If we have an inactive button, then you see a shadow */ hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(COLOR_BTNHIGHLIGHT)); hpsave = (HPEN)SelectObject(dc, GetSysColorPen(COLOR_BTNHIGHLIGHT)); Polygon(dc, Line1, Line1N); @@ -1054,7 +1053,6 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) SelectObject(dc, hbsave); } - /* Correct for the shadow shift */ if (!(uFlags & DFCS_PUSHED)) { for(i = 0; i < Line1N; i++) @@ -1069,7 +1067,6 @@ static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) } } - /* Make the final picture */ hbsave = (HBRUSH)SelectObject(dc, GetSysColorBrush(colorIdx)); hpsave = (HPEN)SelectObject(dc, GetSysColorPen(colorIdx)); @@ -1332,10 +1329,10 @@ static BOOL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags) BOOL WINAPI DrawFrameControl( HDC hdc, LPRECT rc, UINT uType, UINT uState ) { - /* Win95 doesn't support drawing in other mapping modes */ + /* Win95 doesn't support drawing in other mapping modes if(GetMapMode(hdc) != MM_TEXT) return FALSE; - + */ switch(uType) { case DFC_BUTTON: @@ -1344,20 +1341,20 @@ BOOL WINAPI DrawFrameControl( HDC hdc, LPRECT rc, UINT uType, return UITOOLS95_DrawFrameCaption(hdc, rc, uState); case DFC_MENU: return UITOOLS95_DrawFrameMenu(hdc, rc, uState); + /* + case DFC_POPUPMENU: + break; + */ case DFC_SCROLL: return UITOOLS95_DrawFrameScroll(hdc, rc, uState); default: - DbgPrint("(%x,%p,%d,%x), bad type!\n", hdc,rc,uType,uState ); + DbgPrint("(%p,%p,%d,%x), bad type!\n", hdc,rc,uType,uState ); } return FALSE; } - /* Ported from WINE20020904 */ BOOL WINAPI DrawEdge( HDC hdc, LPRECT rc, UINT edge, UINT flags ) { - DbgPrint("%04x %d,%d-%d,%d %04x %04x\n", - hdc, rc->left, rc->top, rc->right, rc->bottom, edge, flags ); - if(flags & BF_DIAGONAL) return UITOOLS95_DrawDiagEdge(hdc, rc, edge, flags); else diff --git a/lib/user32/windows/message.c b/lib/user32/windows/message.c index fe2a423..64efa1c 100644 --- a/lib/user32/windows/message.c +++ b/lib/user32/windows/message.c @@ -309,6 +309,7 @@ STDCALL PostQuitMessage( int nExitCode) { + (void) NtUserPostMessage(NULL, WM_QUIT, nExitCode, 0); } WINBOOL diff --git a/lib/user32/windows/messagebox.c b/lib/user32/windows/messagebox.c index 24d1b87..63a8663 100644 --- a/lib/user32/windows/messagebox.c +++ b/lib/user32/windows/messagebox.c @@ -42,7 +42,7 @@ MessageBoxA( LPCSTR lpCaption, UINT uType) { - return 0; + return MessageBoxExA(hWnd, lpText, lpCaption, uType, 0); } int @@ -93,5 +93,13 @@ MessageBoxW( LPCWSTR lpCaption, UINT uType) { - return 0; + return MessageBoxExW(hWnd, lpText, lpCaption, uType, 0); +} + +DWORD +STDCALL +SoftModalMessageBox (DWORD Unknown0) +{ + return 0; } +/* EOF */ diff --git a/lib/user32/windows/paint.c b/lib/user32/windows/paint.c index b2df394..059ff60 100644 --- a/lib/user32/windows/paint.c +++ b/lib/user32/windows/paint.c @@ -30,6 +30,7 @@ #include #include +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ @@ -84,7 +85,7 @@ InvalidateRect( CONST RECT *lpRect, WINBOOL bErase) { - return FALSE; + return NtUserInvalidateRect( hWnd, lpRect, bErase ); } WINBOOL @@ -94,8 +95,9 @@ InvalidateRgn( HRGN hRgn, WINBOOL bErase) { - return FALSE; + return NtUserInvalidateRgn( hWnd, hRgn, bErase ); } + WINBOOL STDCALL RedrawWindow( @@ -104,8 +106,17 @@ RedrawWindow( HRGN hrgnUpdate, UINT flags) { - return FALSE; + NTSTATUS Status; + + Status = NtUserRedrawWindow(hWnd, lprcUpdate, hrgnUpdate, flags); + if (! NT_SUCCESS(Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + } + + return NT_SUCCESS(Status); } + WINBOOL STDCALL ScrollDC( @@ -133,7 +144,7 @@ STDCALL UpdateWindow( HWND hWnd) { - return FALSE; + return NtUserUpdateWindow( hWnd ); } WINBOOL STDCALL diff --git a/lib/user32/windows/window.c b/lib/user32/windows/window.c index 24d70e7..a95151b 100644 --- a/lib/user32/windows/window.c +++ b/lib/user32/windows/window.c @@ -18,6 +18,12 @@ #include /* FUNCTIONS *****************************************************************/ +ULONG + WinHasThickFrameStyle(ULONG Style, ULONG ExStyle) +{ + return((Style & WS_THICKFRAME) && + (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))); +} NTSTATUS STDCALL User32SendNCCALCSIZEMessageForKernel(PVOID Arguments, ULONG ArgumentLength) @@ -161,6 +167,59 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength) return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS)); } +static void NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle) +{ + int adjust; + if(style & WS_ICONIC) return; + + if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == + WS_EX_STATICEDGE) + { + adjust = 1; /* for the outer frame always present */ + } + else + { + adjust = 0; + if ((exStyle & WS_EX_DLGMODALFRAME) || + (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */ + } + if (style & WS_THICKFRAME) + adjust += ( GetSystemMetrics (SM_CXFRAME) + - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */ + if ((style & (WS_BORDER|WS_DLGFRAME)) || + (exStyle & WS_EX_DLGMODALFRAME)) + adjust++; /* The other border */ + + InflateRect (rect, adjust, adjust); + + if ((style & WS_CAPTION) == WS_CAPTION) + { + if (exStyle & WS_EX_TOOLWINDOW) + rect->top -= GetSystemMetrics(SM_CYSMCAPTION); + else + rect->top -= GetSystemMetrics(SM_CYCAPTION); + } + if (menu) rect->top -= GetSystemMetrics(SM_CYMENU); +} + +static void +NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle) +{ + if(style & WS_ICONIC) return; + + if (exStyle & WS_EX_CLIENTEDGE) + InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); + + if (style & WS_VSCROLL) + { + if((exStyle & WS_EX_LEFTSCROLLBAR) != 0) + rect->left -= GetSystemMetrics(SM_CXVSCROLL); + else + rect->right += GetSystemMetrics(SM_CXVSCROLL); + } + if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL); +} + WINBOOL STDCALL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, @@ -175,7 +234,16 @@ AdjustWindowRectEx(LPRECT lpRect, WINBOOL bMenu, DWORD dwExStyle) { - return(FALSE); + dwStyle &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD); + dwExStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | + WS_EX_STATICEDGE | WS_EX_TOOLWINDOW); + if (dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME; + + NC_AdjustRectOuter95( lpRect, dwStyle, bMenu, dwExStyle ); + NC_AdjustRectInner95( lpRect, dwStyle, dwExStyle ); + lpRect->right += 2; + lpRect->bottom += 2; + return TRUE; } WINBOOL STDCALL @@ -238,7 +306,10 @@ ChildWindowFromPointEx(HWND hwndParent, WINBOOL STDCALL CloseWindow(HWND hWnd) { - return FALSE; + SendMessageA(hWnd, WM_CLOSE, 0, 0); + SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0); + + return (WINBOOL)(hWnd); } HWND STDCALL @@ -472,7 +543,10 @@ DeferWindowPos(HDWP hWinPosInfo, WINBOOL STDCALL DestroyWindow(HWND hWnd) { - return FALSE; + SendMessageW(hWnd, WM_DESTROY, 0, 0); + SendMessageW(hWnd, WM_NCDESTROY, 0, 0); + + return NtUserDestroyWindow(hWnd); } WINBOOL STDCALL @@ -577,7 +651,7 @@ GetAncestor(HWND hwnd, UINT gaFlags) WINBOOL STDCALL GetClientRect(HWND hWnd, LPRECT lpRect) { - return FALSE; + return(NtUserGetClientRect(hWnd, lpRect)); } HWND STDCALL @@ -608,7 +682,7 @@ GetLastActivePopup(HWND hWnd) HWND STDCALL GetParent(HWND hWnd) { - return (HWND)0; + return NtUserGetAncestor(hWnd, GA_PARENT); } WINBOOL STDCALL @@ -757,7 +831,9 @@ IsWindowVisible(HWND hWnd) WINBOOL STDCALL IsZoomed(HWND hWnd) { - return FALSE; + ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE); + + return (uStyle & WS_MAXIMIZE); } WINBOOL STDCALL @@ -774,7 +850,7 @@ MoveWindow(HWND hWnd, int nHeight, WINBOOL bRepaint) { - return FALSE; + return NtUserMoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint); } WINBOOL STDCALL @@ -919,8 +995,9 @@ MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints) NtUserGetClientOrigin(hWndFrom, &FromOffset); NtUserGetClientOrigin(hWndTo, &ToOffset); - XMove = ToOffset.x - FromOffset.x; - YMove = ToOffset.y - FromOffset.y; + XMove = FromOffset.x - ToOffset.x; + YMove = FromOffset.y - ToOffset.y; + for (i = 0; i < cPoints; i++) { lpPoints[i].x += XMove; diff --git a/lib/winedbgc/Makefile b/lib/winedbgc/Makefile index 057066d..42ecff4 100644 --- a/lib/winedbgc/Makefile +++ b/lib/winedbgc/Makefile @@ -25,6 +25,7 @@ TARGET_OBJECTS = \ debug.o \ libmain.o \ porting.o \ + trace.o \ winedbgc.o \ winedbgc.dll.dbg.o diff --git a/lib/winedbgc/trace.c b/lib/winedbgc/trace.c new file mode 100644 index 0000000..b5ac2d5 --- /dev/null +++ b/lib/winedbgc/trace.c @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////// +// Diagnostic Trace +// +#include +#include +#define WIN32_LEAN_AND_MEAN +#include "windows.h" +#include "trace.h" + + +#ifdef _DEBUG + +#ifdef WIN32 +//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +//#include +//#include +//WINBASEAPI VOID WINAPI DebugBreak(VOID); +//WINBASEAPI VOID WINAPI OutputDebugStringA(LPCSTR lpOutputString); +//WINBASEAPI VOID WINAPI OutputDebugStringW(LPCWSTR lpOutputString); +//void __stdcall DebugBreak(void); +//void __stdcall OutputDebugStringA(char* lpOutputString); +//void __stdcall OutputDebugStringW(wchar_t* lpOutputString); +#ifdef UNICODE +#define OutputDebugString OutputDebugStringW +#else +#define OutputDebugString OutputDebugStringA +#endif // !UNICODE + +#else +#include "hardware.h" +#endif // WIN32 + + +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; + +void _DebugBreak(void) +{ + DebugBreak(); +} + +void Trace(TCHAR* lpszFormat, ...) +{ + va_list args; + int nBuf; + TCHAR szBuffer[512]; + + va_start(args, lpszFormat); +// nBuf = vsprintf(szBuffer, lpszFormat, args); +// nBuf = _vsntprintf(szBuffer, _countof(szBuffer), lpszFormat, args); +#ifdef _UNICODE + nBuf = _vsnwprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), lpszFormat, args); +#else + nBuf = _vsnprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), lpszFormat, args); +#endif + OutputDebugString(szBuffer); + // was there an error? was the expanded string too long? +// ASSERT(nBuf >= 0); + va_end(args); +} + +void Assert(void* assert, TCHAR* file, int line, void* msg) +{ + if (msg == NULL) { + printf("ASSERT -- %s occured on line %u of file %s.\n", + assert, line, file); + } else { + printf("ASSERT -- %s occured on line %u of file %s: Message = %s.\n", + assert, line, file, msg); + } +} + + +#else + +//inline void Trace(TCHAR* lpszFormat, ...) { }; +//inline void Assert(void* assert, TCHAR* file, int line, void* msg) { }; +void Trace(TCHAR* lpszFormat, ...) { }; +void Assert(void* assert, TCHAR* file, int line, void* msg) { }; + +#endif //_DEBUG +///////////////////////////////////////////////////////////////////////////// diff --git a/lib/winedbgc/trace.h b/lib/winedbgc/trace.h new file mode 100644 index 0000000..bbd863a --- /dev/null +++ b/lib/winedbgc/trace.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////// +// +#ifndef __TRACE_H__ +#define __TRACE_H__ + +#ifdef _DEBUG + +//============================================================================= +// BreakPoint() macro. +//============================================================================= + +#ifdef _X86_ +#define BreakPoint() _asm { int 3h } +#else +#define BreakPoint() _DebugBreak() +#endif + +//============================================================================= +// MACRO: ASSERT() +//============================================================================= + +#ifndef ASSERT +#define ASSERT(exp) \ +{ \ + if ( !(exp) ) \ + { \ + Assert(#exp, __FILE__, __LINE__, NULL); \ + BreakPoint(); \ + } \ +} \ + +#define ASSERTMSG(exp, msg) \ +{ \ + if ( !(exp) ) \ + { \ + Assert(#exp, __FILE__, __LINE__, msg); \ + BreakPoint(); \ + } \ +} +#endif + +//============================================================================= +// MACRO: TRACE() +//============================================================================= + +void Assert(void* assert, TCHAR* file, int line, void* msg); +void Trace(TCHAR* lpszFormat, ...); +void Trace1(int code, TCHAR* lpszFormat, ...); + +#define TRACE Trace +#define TRACE0 Trace + +#else // _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) +#define ASSERTMSG(exp, msg) +#endif + +//#define TRACE0 TRACE +//#define TRACE1 TRACE + +void Assert(void* assert, TCHAR* file, int line, void* msg); +void Trace(TCHAR* lpszFormat, ...); + +#define TRACE 0 ? (void)0 : Trace + + +#endif // !_DEBUG + +#endif // __TRACE_H__ +///////////////////////////////////////////////////////////////////////////// diff --git a/lib/winedbgc/winedbgc.c b/lib/winedbgc/winedbgc.c index f382f3d..729a49e 100644 --- a/lib/winedbgc/winedbgc.c +++ b/lib/winedbgc/winedbgc.c @@ -1,15 +1,15 @@ /* - * Debugging channels functions for WINE + * Debugging channels functions for WINE support on ROS. */ #include #include #include #include "porting.h" +#include "trace.h" //#include #include -//DECLARE_DEBUG_CHANNEL(tid); DECLARE_DEBUG_CHANNEL(winedbgc); @@ -39,7 +39,7 @@ static inline struct debug_info *get_info(void) if (!RtlGetProcessHeap()) return &tmp; /* setup the temp structure in case HeapAlloc wants to print something */ NtCurrentTeb()->WineDebugInfo = &tmp; - info = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(*info) ); + info = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*info)); info->str_pos = info->strings; info->out_pos = info->output; NtCurrentTeb()->WineDebugInfo = info; @@ -59,16 +59,16 @@ static void *gimme1(int n) } /* release extra space that we requested in gimme1() */ -static inline void release( void *ptr ) +static inline void release(void *ptr) { struct debug_info *info = NtCurrentTeb()->WineDebugInfo; info->str_pos = ptr; } /*********************************************************************** - * wine_dbgstr_an (NTDLL.@) + * wine_dbgstr_an (NTDLL.@) */ -const char *wine_dbgstr_an( const char *src, int n ) +const char *wine_dbgstr_an(const char *src, int n) { char *dst, *res; @@ -118,9 +118,9 @@ const char *wine_dbgstr_an( const char *src, int n ) } /*********************************************************************** - * wine_dbgstr_wn (NTDLL.@) + * wine_dbgstr_wn (NTDLL.@) */ -const char *wine_dbgstr_wn( const WCHAR *src, int n ) +const char *wine_dbgstr_wn(const WCHAR *src, int n) { char *dst, *res; @@ -133,7 +133,7 @@ const char *wine_dbgstr_wn( const WCHAR *src, int n ) } if (n < 0) n = 0; else if (n > 200) n = 200; - dst = res = gimme1 (n * 5 + 7); + dst = res = gimme1(n * 5 + 7); *dst++ = 'L'; *dst++ = '"'; while (n-- > 0 && *src) @@ -165,56 +165,53 @@ const char *wine_dbgstr_wn( const WCHAR *src, int n ) *dst++ = '.'; } *dst++ = '\0'; - release( dst ); + release(dst); return res; } /*********************************************************************** - * wine_dbgstr_guid (NTDLL.@) + * wine_dbgstr_guid (NTDLL.@) */ -const char *wine_dbgstr_guid( const GUID *id ) +const char *wine_dbgstr_guid(const GUID *id) { char *str; if (!id) return "(null)"; - if (!((WORD)(DWORD)(id) >> 16)) - { + if (!((WORD)(DWORD)(id) >> 16)) { str = gimme1(12); - sprintf( str, "", (WORD)(DWORD)(id) ); - } - else - { + sprintf(str, "", (WORD)(DWORD)(id)); + } else { str = gimme1(40); - sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - id->Data1, id->Data2, id->Data3, - id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], - id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); + sprintf(str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + id->Data1, id->Data2, id->Data3, + id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], + id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7]); } return str; } /*********************************************************************** - * wine_dbg_vprintf (NTDLL.@) + * wine_dbg_vprintf (NTDLL.@) */ -int wine_dbg_vprintf( const char *format, va_list args ) +int wine_dbg_vprintf(const char *format, va_list args) { struct debug_info *info = get_info(); char *p; - int ret = _vsnprintf( info->out_pos, sizeof(info->output) - (info->out_pos - info->output), - format, args ); + int ret = _vsnprintf(info->out_pos, sizeof(info->output) - (info->out_pos - info->output), + format, args); - p = strrchr( info->out_pos, '\n' ); - if (!p) info->out_pos += ret; - else - { + p = strrchr(info->out_pos, '\n'); + if (!p) { + info->out_pos += ret; + } else { char *pos = info->output; - char saved_ch; + char saved_ch; p++; - saved_ch = *p; - *p = 0; + saved_ch = *p; + *p = 0; DbgPrint(pos); - *p = saved_ch; + *p = saved_ch; /* move beginning of next line to start of buffer */ while ((*pos = *p++)) pos++; info->out_pos = pos; @@ -223,7 +220,7 @@ int wine_dbg_vprintf( const char *format, va_list args ) } /*********************************************************************** - * wine_dbg_printf (NTDLL.@) + * wine_dbg_printf (NTDLL.@) */ int wine_dbg_printf(const char *format, ...) { @@ -231,16 +228,19 @@ int wine_dbg_printf(const char *format, ...) va_list valist; va_start(valist, format); - ret = wine_dbg_vprintf( format, valist ); +// + Trace(format, valist); +// + ret = wine_dbg_vprintf(format, valist); va_end(valist); return ret; } /*********************************************************************** - * wine_dbg_log (NTDLL.@) + * wine_dbg_log (NTDLL.@) */ int wine_dbg_log(enum __DEBUG_CLASS cls, const char *channel, - const char *function, const char *format, ... ) + const char *function, const char *format, ...) { static const char *classes[__DBCL_COUNT] = { "fixme", "err", "warn", "trace" }; va_list valist; @@ -248,11 +248,11 @@ int wine_dbg_log(enum __DEBUG_CLASS cls, const char *channel, va_start(valist, format); if (TRACE_ON(winedbgc)) - ret = wine_dbg_printf( "%08lx:", NtCurrentTeb()->Cid.UniqueThread); + ret = wine_dbg_printf("%08lx:", NtCurrentTeb()->Cid.UniqueThread); if (cls < __DBCL_COUNT) - ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel + 1, function ); + ret += wine_dbg_printf("%s:%s:%s ", classes[cls], channel + 1, function); if (format) - ret += wine_dbg_vprintf( format, valist ); + ret += wine_dbg_vprintf(format, valist); va_end(valist); return ret; } diff --git a/lib/winmm/dllmain.c b/lib/winmm/dllmain.c index 98404da..7d5c54c 100644 --- a/lib/winmm/dllmain.c +++ b/lib/winmm/dllmain.c @@ -19,8 +19,6 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) { - DbgPrint("WINMM: DllMain() called\n"); - switch (dwReason) { case DLL_PROCESS_ATTACH: @@ -30,7 +28,5 @@ DllMain(PVOID hinstDll, break; } - DbgPrint("WINMM: DllMain() done\n"); - return TRUE; } diff --git a/lib/winmm/misc/stubs.c b/lib/winmm/misc/stubs.c index 4744cb5..8965254 100644 --- a/lib/winmm/misc/stubs.c +++ b/lib/winmm/misc/stubs.c @@ -132,3 +132,27 @@ midiOutLongMsg(HWAVEOUT hWaveOut, LPCSTR pszSoundA, DbgPrint("midiOutLongMsg stub\n"); return 1; } + +UINT/*MMRESULT*/ +STDCALL +timeBeginPeriod(UINT uPeriod) +{ + DbgPrint("timeBeginPeriod stub\n"); + return 97/*TIMERR_NOCANDO*/; +} + +DWORD +STDCALL +timeGetTime(VOID) +{ + DbgPrint("timeGetTime stub\n"); + return 0; +} + +UINT/*MMRESULT*/ +STDCALL +timeEndPeriod(UINT uPeriod) +{ + DbgPrint("timeEndPeriod stub\n"); + return 97/*TIMERR_NOCANDO*/; +} diff --git a/lib/winmm/winmm.def b/lib/winmm/winmm.def index d0a9cbb..2d4307c 100644 --- a/lib/winmm/winmm.def +++ b/lib/winmm/winmm.def @@ -13,4 +13,7 @@ waveOutOpen@24 waveOutClose@4 waveOutUnprepareHeader@12 midiOutPrepareHeader@12 -midiOutLongMsg@12 \ No newline at end of file +midiOutLongMsg@12 +timeBeginPeriod@4 +timeEndPeriod@4 +timeGetTime@0 diff --git a/lib/winmm/winmm.edf b/lib/winmm/winmm.edf index e53abcd..cd74e47 100644 --- a/lib/winmm/winmm.edf +++ b/lib/winmm/winmm.edf @@ -13,4 +13,7 @@ waveOutOpen=waveOutOpen@24 waveOutClose=waveOutClose@4 waveOutUnprepareHeader=waveOutUnprepareHeader@12 midiOutPrepareHeader=midiOutPrepareHeader@12 -midiOutLongMsg=midiOutLongMsg@12 \ No newline at end of file +midiOutLongMsg=midiOutLongMsg@12 +timeBeginPeriod=timeBeginPeriod@4 +timeEndPeriod=timeEndPeriod@4 +timeGetTime=timeGetTime@0 \ No newline at end of file diff --git a/lib/winspool/.cvsignore b/lib/winspool/.cvsignore new file mode 100644 index 0000000..3eb5368 --- /dev/null +++ b/lib/winspool/.cvsignore @@ -0,0 +1,9 @@ +winspool.a +winspool.drv +winspool.nostrip.drv +winspool.coff +winspool.sym +base.tmp +junk.tmp +temp.exp +.*.d \ No newline at end of file diff --git a/lib/winspool/Makefile b/lib/winspool/Makefile new file mode 100644 index 0000000..2ba1307 --- /dev/null +++ b/lib/winspool/Makefile @@ -0,0 +1,38 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = dynlink + +TARGET_NAME = winspool + +TARGET_EXTENSION = .drv + +TARGET_BASE = 0x77800000 + +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -DUNICODE \ + -DLE \ + -DDBG + +TARGET_LFLAGS = -nostartfiles -nostdlib + +TARGET_SDKLIBS = kernel32.a + +TARGET_OBJECTS = stubs.o + +TARGET_CLEAN = $(DEP_FILES) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS := $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk + +# EOF diff --git a/lib/winspool/stubs.c b/lib/winspool/stubs.c new file mode 100644 index 0000000..204ba8b --- /dev/null +++ b/lib/winspool/stubs.c @@ -0,0 +1,1073 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS winspool DRV + * FILE: stubs.c + * PURPOSE: Stub functions + * PROGRAMMERS: Ge van Geldorp (ge@gse.nl) + * REVISIONS: + */ + +#include + +BOOL +STDCALL +DllMain(HINSTANCE InstDLL, + DWORD Reason, + LPVOID Reserved) +{ + return TRUE; +} + +BOOL +STDCALL +AbortPrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool AbortPrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddFormA(HANDLE Printer, DWORD Level, PBYTE Form) +{ + OutputDebugStringW(L"winspool AddFormA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddFormW(HANDLE Printer, DWORD Level, PBYTE Form) +{ + OutputDebugStringW(L"winspool AddFormW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddJobA(HANDLE Printer, DWORD Level, PBYTE Data, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool AddJobA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddJobW(HANDLE Printer, DWORD Level, PBYTE Data, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool AddJobW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddMonitorA(LPSTR Name, DWORD Level, PBYTE Monitors) +{ + OutputDebugStringW(L"winspool AddMonitorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddMonitorW(LPWSTR Name, DWORD Level, PBYTE Monitors) +{ + OutputDebugStringW(L"winspool AddMonitorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPortA(LPSTR Name, HWND Wnd, LPSTR MonitorName) +{ + OutputDebugStringW(L"winspool stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPortW(LPWSTR Name, HWND Wnd, LPWSTR MonitorName) +{ + OutputDebugStringW(L"winspool AddPortW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +HANDLE +STDCALL +AddPrinterA(LPSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return NULL; +} + +HANDLE +STDCALL +AddPrinterW(LPWSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return NULL; +} + +BOOL +STDCALL +AddPrinterConnectionA(LPSTR Name) +{ + OutputDebugStringW(L"winspool AddPrinterConnectionA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrinterConnectionW(LPWSTR Name) +{ + OutputDebugStringW(L"winspool AddPrinterConnectionW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrinterDriverA(LPSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrinterDriverA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrinterDriverW(LPWSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrinterDriverW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrintProcessorA(LPSTR Name, LPSTR Environment, LPSTR PathName, LPSTR PrintProcessorName) +{ + OutputDebugStringW(L"winspool AddPrintProcessorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrintProcessorW(LPWSTR Name, LPWSTR Environment, LPWSTR PathName, LPWSTR PrintProcessorName) +{ + OutputDebugStringW(L"winspool AddPrintProcessorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrintProvidorA(LPSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrintProvidorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +AddPrintProvidorW(LPWSTR Name, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool AddPrintProvidorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +LONG +STDCALL +AdvancedDocumentPropertiesA(HWND Wnd, HANDLE Printer, LPSTR DeviceName, PDEVMODEA DevModeOut, PDEVMODEA DevModeIn) +{ + OutputDebugStringW(L"winspool AdvancedDocumentPropertiesA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +LONG +STDCALL +AdvancedDocumentPropertiesW(HWND Wnd, HANDLE Printer, LPWSTR DeviceName, PDEVMODEW DevModeOut, PDEVMODEW DevModeIn) +{ + OutputDebugStringW(L"winspool AdvancedDocumentPropertiesW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +BOOL +STDCALL +ClosePrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool ClosePrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ConfigurePortA(LPSTR Name, HWND Wnd, LPSTR PortName) +{ + OutputDebugStringW(L"winspool ConfigurePortA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ConfigurePortW(LPWSTR Name, HWND Wnd, LPWSTR PortName) +{ + OutputDebugStringW(L"winspool ConfigurePortW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +HANDLE +STDCALL +ConnectToPrinterDlg(HWND Wnd, DWORD Flags) +{ + OutputDebugStringW(L"winspool ConnectToPrinterDlg stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return NULL; +} + +BOOL +STDCALL +DeleteFormA(HANDLE Printer, LPSTR Name) +{ + OutputDebugStringW(L"winspool DeleteFormA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeleteFormW(HANDLE Printer, LPWSTR Name) +{ + OutputDebugStringW(L"winspool DeleteFormW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeleteMonitorA(LPSTR Name, LPSTR Environment, LPSTR MonitorName) +{ + OutputDebugStringW(L"winspool DeleteMonitorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeleteMonitorW(LPWSTR Name, LPWSTR Environment, LPWSTR MonitorName) +{ + OutputDebugStringW(L"winspool DeleteMonitorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePortA(LPSTR Name, HWND Wnd, LPSTR PortName) +{ + OutputDebugStringW(L"winspool DeletePortA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePortW(LPWSTR Name, HWND Wnd, LPWSTR PortName) +{ + OutputDebugStringW(L"winspool DeletePortW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool DeletePrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrinterConnectionA(LPSTR Name) +{ + OutputDebugStringW(L"winspool DeletePrinterConnectionA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrinterConnectionW(LPWSTR Name) +{ + OutputDebugStringW(L"winspool DeletePrinterConnectionW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +DeletePrinterDataA(HANDLE Printer, LPSTR Name) +{ + OutputDebugStringW(L"winspool DeletePrinterDataA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +DeletePrinterDataW(HANDLE Printer, LPWSTR Name) +{ + OutputDebugStringW(L"winspool DeletePrinterDataW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrinterDriverA(LPSTR Name, LPSTR Environment, LPSTR Driver) +{ + OutputDebugStringW(L"winspool DeletePrinterDriverA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrinterDriverW(LPWSTR Name, LPWSTR Environment, LPWSTR Driver) +{ + OutputDebugStringW(L"winspool DeletePrinterDriverW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrintProcessorA(LPSTR Name, LPSTR Environment, LPSTR PrintProcessor) +{ + OutputDebugStringW(L"winspool DeletePrintProcessorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrintProcessorW(LPWSTR Name, LPWSTR Environment, LPWSTR PrintProcessor) +{ + OutputDebugStringW(L"winspool DeletePrintProcessorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrintProvidorA(LPSTR Name, LPSTR Environment, LPSTR PrintProvidor) +{ + OutputDebugStringW(L"winspool DeletePrintProvidorA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +DeletePrintProvidorW(LPWSTR Name, LPWSTR Environment, LPWSTR PrintProvidor) +{ + OutputDebugStringW(L"winspool DeletePrintProvidorW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +int +STDCALL +DeviceCapabilitiesA(LPCSTR Device, LPCSTR Port, WORD Capability, LPSTR Buffer, CONST DEVMODEA *DevMode) +{ + OutputDebugStringW(L"winspool DeviceCapabilitiesA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return -1; +} + +int +STDCALL +DeviceCapabilitiesW(LPCWSTR Device, LPCWSTR Port, WORD Capability, LPWSTR Buffer, CONST DEVMODEW *DevMode) +{ + OutputDebugStringW(L"winspool DeviceCapabilitiesW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return -1; +} + +LONG +STDCALL +DocumentPropertiesA(HWND Wnd, HANDLE Printer, LPSTR Device, PDEVMODEA DevModeOut, PDEVMODEA DevModeIn, DWORD Mode) +{ + OutputDebugStringW(L"winspool DocumentPropertiesA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return -1L; +} + +LONG +STDCALL +DocumentPropertiesW(HWND Wnd, HANDLE Printer, LPWSTR Device, PDEVMODEW DevModeOut, PDEVMODEW DevModeIn, DWORD Mode) +{ + OutputDebugStringW(L"winspool DocumentPropertiesW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EndDocPrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool EndDocPrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EndPagePrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool EndPagePrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumFormsA(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumFormsA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumFormsW(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumFormsW stub called\n"); + + return FALSE; +} + +BOOL +STDCALL +EnumJobsA(HANDLE Printer, DWORD First, DWORD NoJobs, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumJobsA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumJobsW(HANDLE Printer, DWORD First, DWORD NoJobs, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumJobsW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumMonitorsA(LPSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumMonitorsA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumMonitorsW(LPWSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumMonitorsW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPortsA(LPSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPortsA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPortsW(LPWSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPortsW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +EnumPrinterDataA(HANDLE Printer, DWORD Index, LPSTR Name, DWORD NameSize, PDWORD NameReturned, PDWORD Type, PBYTE Buffer, DWORD BufSize, PDWORD BufReturned) +{ + OutputDebugStringW(L"winspool EnumPrinterDataA stub called\n"); + + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD +STDCALL +EnumPrinterDataW(HANDLE Printer, DWORD Index, LPWSTR Name, DWORD NameSize, PDWORD NameReturned, PDWORD Type, PBYTE Buffer, DWORD BufSize, PDWORD BufReturned) +{ + OutputDebugStringW(L"winspool EnumPrinterDataW stub called\n"); + + return ERROR_CALL_NOT_IMPLEMENTED; +} + +BOOL +STDCALL +EnumPrinterDriversA(LPSTR Name, LPSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrinterDriversA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrinterDriversW(LPWSTR Name, LPWSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrinterDriversW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintersA(DWORD Flags, LPSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintersA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintersW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintProcessorDatatypesA(LPSTR Name, LPSTR PrintProcessor, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintProcessorDatatypesA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintProcessorDatatypesW(LPWSTR Name, LPWSTR PrintProcessor, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintProcessorDatatypesW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintProcessorsA(LPSTR Name, LPSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintProcessorsA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +EnumPrintProcessorsW(LPWSTR Name, LPWSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed, PDWORD Returned) +{ + OutputDebugStringW(L"winspool EnumPrintProcessorsW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +FindClosePrinterChangeNotification(HANDLE Printer) +{ + OutputDebugStringW(L"winspool FindClosePrinterChangeNotification stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +HANDLE +STDCALL +FindFirstPrinterChangeNotification(HANDLE Printer, DWORD Flags, DWORD Options, PVOID NotifyOptions) +{ + OutputDebugStringW(L"winspool FindFirstPrinterChangeNotification stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return INVALID_HANDLE_VALUE; +} + +HANDLE +STDCALL +FindNextPrinterChangeNotification(HANDLE Printer, PDWORD Change, PVOID NotifyOptions, PVOID* NotifyInfo) +{ + OutputDebugStringW(L"winspool FindNextPrinterChangeNotification stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return INVALID_HANDLE_VALUE; +} + +BOOL +STDCALL +FreePrinterNotifyInfo(PVOID /* Really PPRINTER_NOTIFY_INFO */ NotifyInfo) +{ + OutputDebugStringW(L"winspool FreePrinterNotifyInfo stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetFormA(HANDLE Printer, LPSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetFormA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetFormW(HANDLE Printer, LPWSTR Name, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetFormW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetJobA(HANDLE Printer, DWORD Job, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetJobA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetJobW(HANDLE Printer, DWORD Job, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetJobW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetPrinterA(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +GetPrinterW(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +GetPrinterDataA(HANDLE Printer, LPSTR Name, PDWORD Type, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDataA stub called\n"); + + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD +STDCALL +GetPrinterDataW(HANDLE Printer, LPWSTR Name, PDWORD Type, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDataW stub called\n"); + + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD +STDCALL +GetPrinterDriverA(HANDLE Printer, LPSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDriverA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +GetPrinterDriverW(HANDLE Printer, LPWSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDriverW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +GetPrinterDriverDirectoryA(LPSTR Name, LPSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDriverDirectoryA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +GetPrinterDriverDirectoryW(LPWSTR Name, LPWSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrinterDriverDirectoryW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +GetPrintProcessorDirectoryA(LPSTR Name, LPSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrintProcessorDirectoryA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +GetPrintProcessorDirectoryW(LPWSTR Name, LPWSTR Environment, DWORD Level, PBYTE Buffer, DWORD BufSize, PDWORD Needed) +{ + OutputDebugStringW(L"winspool GetPrintProcessorDirectoryW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +BOOL +STDCALL +OpenPrinterA(LPSTR Name, PHANDLE Printer, LPPRINTER_DEFAULTSA Defaults) +{ + OutputDebugStringW(L"winspool OpenPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +OpenPrinterW(LPWSTR Name, PHANDLE Printer, LPPRINTER_DEFAULTSW Defaults) +{ + OutputDebugStringW(L"winspool OpenPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +PrinterMessageBoxA(HANDLE Printer, DWORD Error, HWND Wnd, LPSTR Text, LPSTR Caption, DWORD Type) +{ + OutputDebugStringW(L"winspool PrinterMessageBoxA stub called\n"); + + return IDCANCEL; +} + +DWORD +STDCALL +PrinterMessageBoxW(HANDLE Printer, DWORD Error, HWND Wnd, LPWSTR Text, LPWSTR Caption, DWORD Type) +{ + OutputDebugStringW(L"winspool PrinterMessageBoxW stub called\n"); + + return IDCANCEL; +} + +BOOL +STDCALL +PrinterProperties(HWND Wnd, HANDLE Printer) +{ + OutputDebugStringW(L"winspool PrinterProperties stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ReadPrinter(HANDLE Printer, PVOID Buffer, DWORD BufSize, PDWORD Received) +{ + OutputDebugStringW(L"winspool ReadPrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ResetPrinterA(HANDLE Printer, LPPRINTER_DEFAULTSA Defaults) +{ + OutputDebugStringW(L"winspool ResetPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ResetPrinterW(HANDLE Printer, LPPRINTER_DEFAULTSW Defaults) +{ + OutputDebugStringW(L"winspool ResetPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +ScheduleJob(HANDLE Printer, DWORD Job) +{ + OutputDebugStringW(L"winspool ScheduleJob stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetFormA(HANDLE Printer, LPSTR Form, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool SetFormA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetFormW(HANDLE Printer, LPWSTR Form, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool SetFormW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetJobA(HANDLE Printer, DWORD Job, DWORD Level, PBYTE Buffer, DWORD Command) +{ + OutputDebugStringW(L"winspool SetJobA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetJobW(HANDLE Printer, DWORD Job, DWORD Level, PBYTE Buffer, DWORD Command) +{ + OutputDebugStringW(L"winspool SetJobW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetPrinterA(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD Command) +{ + OutputDebugStringW(L"winspool SetPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetPrinterW(HANDLE Printer, DWORD Level, PBYTE Buffer, DWORD Command) +{ + OutputDebugStringW(L"winspool SetPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetPrinterDataA(HANDLE Printer, LPSTR Name, DWORD Type, PBYTE Buffer, DWORD BufSize) +{ + OutputDebugStringW(L"winspool SetPrinterDataA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +BOOL +STDCALL +SetPrinterDataW(HANDLE Printer, LPWSTR Name, DWORD Type, PBYTE Buffer, DWORD BufSize) +{ + OutputDebugStringW(L"winspool SetPrinterDataW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +StartDocPrinterA(HANDLE Printer, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool StartDocPrinterA stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +DWORD +STDCALL +StartDocPrinterW(HANDLE Printer, DWORD Level, PBYTE Buffer) +{ + OutputDebugStringW(L"winspool StartDocPrinterW stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +BOOL +STDCALL +StartPagePrinter(HANDLE Printer) +{ + OutputDebugStringW(L"winspool StartPagePrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} + +DWORD +STDCALL +WaitForPrinterChange(HANDLE Printer, DWORD Flags) +{ + OutputDebugStringW(L"winspool WaitForPrinterChange stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return 0; +} + +BOOL +STDCALL +WritePrinter(HANDLE Printer, PVOID Buffer, DWORD BufSize, PDWORD Written) +{ + OutputDebugStringW(L"winspool WritePrinter stub called\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + + return FALSE; +} diff --git a/lib/winspool/winspool.def b/lib/winspool/winspool.def new file mode 100644 index 0000000..de89f7c --- /dev/null +++ b/lib/winspool/winspool.def @@ -0,0 +1,114 @@ +; $Id$ +; +; winspool.drv - Printer spooler + +LIBRARY winspool.drv + +EXPORTS +AbortPrinter@4 +AddFormA@12 +AddFormW@12 +AddJobA@20 +AddJobW@20 +AddMonitorA@12 +AddMonitorW@12 +AddPortA@12 +AddPortW@12 +AddPrinterA@12 +AddPrinterConnectionA@4 +AddPrinterConnectionW@4 +AddPrinterDriverA@12 +AddPrinterDriverW@12 +AddPrinterW@12 +AddPrintProcessorA@16 +AddPrintProcessorW@16 +AddPrintProvidorA@12 +AddPrintProvidorW@12 +AdvancedDocumentPropertiesA@20 +AdvancedDocumentPropertiesW@20 +ClosePrinter@4 +ConfigurePortA@12 +ConfigurePortW@12 +ConnectToPrinterDlg@8 +DeleteFormA@8 +DeleteFormW@8 +DeleteMonitorA@12 +DeleteMonitorW@12 +DeletePortA@12 +DeletePortW@12 +DeletePrinter@4 +DeletePrinterConnectionA@4 +DeletePrinterConnectionW@4 +DeletePrinterDataA@8 +DeletePrinterDataW@8 +DeletePrinterDriverA@12 +DeletePrinterDriverW@12 +DeletePrintProcessorA@12 +DeletePrintProcessorW@12 +DeletePrintProvidorA@12 +DeletePrintProvidorW@12 +DeviceCapabilitiesA@20 +DeviceCapabilitiesW@20 +DllMain@12 +DocumentPropertiesA@24 +DocumentPropertiesW@24 +EndDocPrinter@4 +EndPagePrinter@4 +EnumFormsA@24 +EnumFormsW@24 +EnumJobsA@32 +EnumJobsW@32 +EnumMonitorsA@24 +EnumMonitorsW@24 +EnumPortsA@24 +EnumPortsW@24 +EnumPrinterDataA@36 +EnumPrinterDataW@36 +EnumPrinterDriversA@28 +EnumPrinterDriversW@28 +EnumPrintersA@28 +EnumPrintersW@28 +EnumPrintProcessorDatatypesA@28 +EnumPrintProcessorDatatypesW@28 +EnumPrintProcessorsA@28 +EnumPrintProcessorsW@28 +FindClosePrinterChangeNotification@4 +FindFirstPrinterChangeNotification@16 +FindNextPrinterChangeNotification@16 +FreePrinterNotifyInfo@4 +GetFormA@24 +GetFormW@24 +GetJobA@24 +GetJobW@24 +GetPrinterA@20 +GetPrinterDataA@24 +GetPrinterDataW@24 +GetPrinterDriverA@24 +GetPrinterDriverDirectoryA@24 +GetPrinterDriverDirectoryW@24 +GetPrinterDriverW@24 +GetPrinterW@20 +GetPrintProcessorDirectoryA@24 +GetPrintProcessorDirectoryW@24 +OpenPrinterA@12 +OpenPrinterW@12 +PrinterMessageBoxA@24 +PrinterMessageBoxW@24 +PrinterProperties@8 +ReadPrinter@16 +ResetPrinterA@8 +ResetPrinterW@8 +ScheduleJob@8 +SetFormA@16 +SetFormW@16 +SetJobA@20 +SetJobW@20 +SetPrinterA@16 +SetPrinterDataA@20 +SetPrinterDataW@20 +SetPrinterW@16 +StartDocPrinterA@12 +StartDocPrinterW@12 +StartPagePrinter@4 +WaitForPrinterChange@8 +WritePrinter@16 diff --git a/lib/winspool/winspool.edf b/lib/winspool/winspool.edf new file mode 100644 index 0000000..e764fc7 --- /dev/null +++ b/lib/winspool/winspool.edf @@ -0,0 +1,114 @@ +; $Id$ +; +; winspool.drv - Printer spooler + +LIBRARY winspool.drv + +EXPORTS +AbortPrinter=AbortPrinter@4 +AddFormA=AddFormA@12 +AddFormW=AddFormW@12 +AddJobA=AddJobA@20 +AddJobW=AddJobW@20 +AddMonitorA=AddMonitorA@12 +AddMonitorW=AddMonitorW@12 +AddPortA=AddPortA@12 +AddPortW=AddPortW@12 +AddPrinterA=AddPrinterA@12 +AddPrinterConnectionA=AddPrinterConnectionA@4 +AddPrinterConnectionW=AddPrinterConnectionW@4 +AddPrinterDriverA=AddPrinterDriverA@12 +AddPrinterDriverW=AddPrinterDriverW@12 +AddPrinterW=AddPrinterW@12 +AddPrintProcessorA=AddPrintProcessorA@16 +AddPrintProcessorW=AddPrintProcessorW@16 +AddPrintProvidorA=AddPrintProvidorA@12 +AddPrintProvidorW=AddPrintProvidorW@12 +AdvancedDocumentPropertiesA=AdvancedDocumentPropertiesA@20 +AdvancedDocumentPropertiesW=AdvancedDocumentPropertiesW@20 +ClosePrinter=ClosePrinter@4 +ConfigurePortA=ConfigurePortA@12 +ConfigurePortW=ConfigurePortW@12 +ConnectToPrinterDlg=ConnectToPrinterDlg@8 +DeleteFormA=DeleteFormA@8 +DeleteFormW=DeleteFormW@8 +DeleteMonitorA=DeleteMonitorA@12 +DeleteMonitorW=DeleteMonitorW@12 +DeletePortA=DeletePortA@12 +DeletePortW=DeletePortW@12 +DeletePrinter=DeletePrinter@4 +DeletePrinterConnectionA=DeletePrinterConnectionA@4 +DeletePrinterConnectionW=DeletePrinterConnectionW@4 +DeletePrinterDataA=DeletePrinterDataA@8 +DeletePrinterDataW=DeletePrinterDataW@8 +DeletePrinterDriverA=DeletePrinterDriverA@12 +DeletePrinterDriverW=DeletePrinterDriverW@12 +DeletePrintProcessorA=DeletePrintProcessorA@12 +DeletePrintProcessorW=DeletePrintProcessorW@12 +DeletePrintProvidorA=DeletePrintProvidorA@12 +DeletePrintProvidorW=DeletePrintProvidorW@12 +DeviceCapabilitiesA=DeviceCapabilitiesA@20 +DeviceCapabilitiesW=DeviceCapabilitiesW@20 +DllMain=DllMain@12 +DocumentPropertiesA=DocumentPropertiesA@24 +DocumentPropertiesW=DocumentPropertiesW@24 +EndDocPrinter=EndDocPrinter@4 +EndPagePrinter=EndPagePrinter@4 +EnumFormsA=EnumFormsA@24 +EnumFormsW=EnumFormsW@24 +EnumJobsA=EnumJobsA@32 +EnumJobsW=EnumJobsW@32 +EnumMonitorsA=EnumMonitorsA@24 +EnumMonitorsW=EnumMonitorsW@24 +EnumPortsA=EnumPortsA@24 +EnumPortsW=EnumPortsW@24 +EnumPrinterDataA=EnumPrinterDataA@36 +EnumPrinterDataW=EnumPrinterDataW@36 +EnumPrinterDriversA=EnumPrinterDriversA@28 +EnumPrinterDriversW=EnumPrinterDriversW@28 +EnumPrintersA=EnumPrintersA@28 +EnumPrintersW=EnumPrintersW@28 +EnumPrintProcessorDatatypesA=EnumPrintProcessorDatatypesA@28 +EnumPrintProcessorDatatypesW=EnumPrintProcessorDatatypesW@28 +EnumPrintProcessorsA=EnumPrintProcessorsA@28 +EnumPrintProcessorsW=EnumPrintProcessorsW@28 +FindClosePrinterChangeNotification=FindClosePrinterChangeNotification@4 +FindFirstPrinterChangeNotification=FindFirstPrinterChangeNotification@16 +FindNextPrinterChangeNotification=FindNextPrinterChangeNotification@16 +FreePrinterNotifyInfo=FreePrinterNotifyInfo@4 +GetFormA=GetFormA@24 +GetFormW=GetFormW@24 +GetJobA=GetJobA@24 +GetJobW=GetJobW@24 +GetPrinterA=GetPrinterA@20 +GetPrinterDataA=GetPrinterDataA@24 +GetPrinterDataW=GetPrinterDataW@24 +GetPrinterDriverA=GetPrinterDriverA@24 +GetPrinterDriverDirectoryA=GetPrinterDriverDirectoryA@24 +GetPrinterDriverDirectoryW=GetPrinterDriverDirectoryW@24 +GetPrinterDriverW=GetPrinterDriverW@24 +GetPrinterW=GetPrinterW@20 +GetPrintProcessorDirectoryA=GetPrintProcessorDirectoryA@24 +GetPrintProcessorDirectoryW=GetPrintProcessorDirectoryW@24 +OpenPrinterA=OpenPrinterA@12 +OpenPrinterW=OpenPrinterW@12 +PrinterMessageBoxA=PrinterMessageBoxA@24 +PrinterMessageBoxW=PrinterMessageBoxW@24 +PrinterProperties=PrinterProperties@8 +ReadPrinter=ReadPrinter@16 +ResetPrinterA=ResetPrinterA@8 +ResetPrinterW=ResetPrinterW@8 +ScheduleJob=ScheduleJob@8 +SetFormA=SetFormA@16 +SetFormW=SetFormW@16 +SetJobA=SetJobA@20 +SetJobW=SetJobW@20 +SetPrinterA=SetPrinterA@16 +SetPrinterDataA=SetPrinterDataA@20 +SetPrinterDataW=SetPrinterDataW@20 +SetPrinterW=SetPrinterW@16 +StartDocPrinterA=StartDocPrinterA@12 +StartDocPrinterW=StartDocPrinterW@12 +StartPagePrinter=StartPagePrinter@4 +WaitForPrinterChange=WaitForPrinterChange@8 +WritePrinter=WritePrinter@16 diff --git a/lib/winspool/winspool.rc b/lib/winspool/winspool.rc new file mode 100644 index 0000000..bcfa2fb --- /dev/null +++ b/lib/winspool/winspool.rc @@ -0,0 +1,41 @@ +/* $Id$ */ + +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "Windows printer spooler\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "winspool\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "winspool.drv\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + diff --git a/lib/ws2_32/makefile b/lib/ws2_32/makefile index 66a48ce..cf81213 100644 --- a/lib/ws2_32/makefile +++ b/lib/ws2_32/makefile @@ -26,10 +26,12 @@ TARGET_OBJECTS = \ misc/event.o misc/handle.o misc/ns.o \ misc/sndrcv.o misc/stubs.o misc/upcall.o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk -TARGET_CLEAN = misc/*.o +include $(TOOLS_PATH)/depend.mk # EOF diff --git a/lib/ws2_32/misc/.cvsignore b/lib/ws2_32/misc/.cvsignore index 5761abc..c6ebd86 100644 --- a/lib/ws2_32/misc/.cvsignore +++ b/lib/ws2_32/misc/.cvsignore @@ -1 +1,2 @@ *.o +.*.d diff --git a/lib/ws2help/makefile b/lib/ws2help/makefile index 0756122..530ed19 100644 --- a/lib/ws2help/makefile +++ b/lib/ws2help/makefile @@ -21,6 +21,10 @@ TARGET_SDKLIBS = ntdll.a kernel32.a ws2_32.a TARGET_OBJECTS = $(TARGET_NAME).o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk diff --git a/lib/wshirda/makefile b/lib/wshirda/makefile index 76a240c..a66aa2b 100644 --- a/lib/wshirda/makefile +++ b/lib/wshirda/makefile @@ -14,6 +14,10 @@ TARGET_SDKLIBS = ntdll.a kernel32.a TARGET_OBJECTS = $(TARGET_NAME).o +DEP_OBJECTS = $(TARGET_OBJECTS) + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk diff --git a/lib/wsock32/.cvsignore b/lib/wsock32/.cvsignore new file mode 100644 index 0000000..8381dc6 --- /dev/null +++ b/lib/wsock32/.cvsignore @@ -0,0 +1,9 @@ +wsock32.a +wsock32.dll +wsock32.nostrip.dll +wsock32.coff +wsock32.sym +base.tmp +junk.tmp +temp.exp +.*.d \ No newline at end of file diff --git a/lib/wsock32/Makefile b/lib/wsock32/Makefile new file mode 100644 index 0000000..5440ab0 --- /dev/null +++ b/lib/wsock32/Makefile @@ -0,0 +1,36 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = dynlink + +TARGET_NAME = wsock32 + +TARGET_BASE = 0x75050000 + +TARGET_CFLAGS = \ + -I./include \ + -Wall \ + -Werror \ + -fno-builtin \ + -DUNICODE \ + -DLE \ + -DDBG + +TARGET_LFLAGS = -nostartfiles -nostdlib + +TARGET_SDKLIBS = kernel32.a + +TARGET_OBJECTS = stubs.o + +TARGET_CLEAN = $(DEP_FILES) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS := $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk + +# EOF diff --git a/lib/wsock32/stubs.c b/lib/wsock32/stubs.c new file mode 100644 index 0000000..1143fdf --- /dev/null +++ b/lib/wsock32/stubs.c @@ -0,0 +1,834 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS WinSock DLL + * FILE: stubs.c + * PURPOSE: Stub functions + * PROGRAMMERS: Ge van Geldorp (ge@gse.nl) + * REVISIONS: + */ + +#include +#include + +BOOL +STDCALL +AcceptEx(SOCKET ListenSocket, + SOCKET AcceptSocket, + PVOID OutputBuffer, + DWORD ReceiveDataLength, + DWORD LocalAddressLength, + DWORD RemoteAddressLength, + LPDWORD BytesReceived, + LPOVERLAPPED Overlapped) +{ + OutputDebugString(L"w32sock AcceptEx stub called\n"); + + return FALSE; +} + +INT +STDCALL +EnumProtocolsA(LPINT ProtocolCount, + LPVOID ProtocolBuffer, + LPDWORD BufferLength) +{ + OutputDebugString(L"w32sock EnumProtocolsA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +EnumProtocolsW(LPINT ProtocolCount, + LPVOID ProtocolBuffer, + LPDWORD BufferLength) +{ + OutputDebugString(L"w32sock EnumProtocolsW stub called\n"); + + return SOCKET_ERROR; +} + +VOID +STDCALL +GetAcceptExSockaddrs(PVOID OutputBuffer, + DWORD ReceiveDataLength, + DWORD LocalAddressLength, + DWORD RemoteAddressLength, + LPSOCKADDR* LocalSockaddr, + LPINT LocalSockaddrLength, + LPSOCKADDR* RemoteSockaddr, + LPINT RemoteSockaddrLength) +{ + OutputDebugString(L"w32sock GetAcceptExSockaddrs stub called\n"); +} + +INT +STDCALL +GetAddressByNameA(DWORD NameSpace, + LPGUID ServiceType, + LPSTR ServiceName, + LPINT Protocols, + DWORD Resolution, + LPVOID /* really LPSERVICE_ASYNC_INFO */ ServiceAsyncInfo, + LPVOID CsaddrBuffer, + LPDWORD BufferLength, + LPSTR AliasBuffer, + LPDWORD AliasBufferLength) +{ + OutputDebugString(L"w32sock GetAddressByNameA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetAddressByNameW(DWORD NameSpace, + LPGUID ServiceType, + LPWSTR ServiceName, + LPINT Protocols, + DWORD Resolution, + LPVOID /* really LPSERVICE_ASYNC_INFO */ ServiceAsyncInfo, + LPVOID CsaddrBuffer, + LPDWORD BufferLength, + LPWSTR AliasBuffer, + LPDWORD AliasBufferLength) +{ + OutputDebugString(L"w32sock GetAddressByNameW stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetNameByTypeA(LPGUID ServiceType, + LPSTR ServiceName, + DWORD NameLength) +{ + OutputDebugString(L"w32sock GetNameByTypeA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetNameByTypeW(LPGUID ServiceType, + LPWSTR ServiceName, + DWORD NameLength) +{ + OutputDebugString(L"w32sock GetNameByTypeW stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetServiceA(DWORD NameSpace, + LPGUID Guid, + LPSTR ServiceName, + DWORD Properties, + LPVOID Buffer, + LPDWORD BufferSize, + LPVOID /* Really LPSERVICE_ASYNC_INFO */ ServiceAsyncInfo) +{ + OutputDebugString(L"w32sock GetServiceA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetServiceW(DWORD NameSpace, + LPGUID Guid, + LPWSTR ServiceName, + DWORD Properties, + LPVOID Buffer, + LPDWORD BufferSize, + LPVOID /* Really LPSERVICE_ASYNC_INFO */ ServiceAsyncInfo) +{ + OutputDebugString(L"w32sock GetServiceW stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetTypeByNameA(LPSTR ServiceName, + LPGUID ServiceType) +{ + OutputDebugString(L"w32sock GetTypeByNameA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +GetTypeByNameW(LPWSTR ServiceName, + LPGUID ServiceType) +{ + OutputDebugString(L"w32sock GetTypeByNameW stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +SetServiceA(DWORD NameSpace, + DWORD Operation, + DWORD Flags, + LPVOID /* Really LPSERVICE_INFO */ ServiceInfo, + LPVOID /* Really LPSERVICE_ASYNC_INFOA */ ServiceAsyncInfo, + LPDWORD dwStatusFlags) +{ + OutputDebugString(L"w32sock SetServiceA stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +SetServiceW(DWORD NameSpace, + DWORD Operation, + DWORD Flags, + LPVOID /* Really LPSERVICE_INFO */ ServiceInfo, + LPVOID /* Really LPSERVICE_ASYNC_INFOW */ ServiceAsyncInfo, + LPDWORD dwStatusFlags) +{ + OutputDebugString(L"w32sock SetServiceW stub called\n"); + + return SOCKET_ERROR; +} + +BOOL +STDCALL +TransmitFile(SOCKET Socket, + HANDLE File, + DWORD NumberOfBytesToWrite, + DWORD NumberOfBytesPerSend, + LPOVERLAPPED Overlapped, + LPVOID /* really LPTRANSMIT_FILE_BUFFERS */ TransmitBuffers, + DWORD Flags) +{ + OutputDebugString(L"w32sock TransmitFile stub called\n"); + + return FALSE; +} + +HANDLE +STDCALL +WSAAsyncGetHostByAddr(HWND Wnd, + unsigned int Msg, + const char *Addr, + int Len, + int Type, + char *Buf, + int BufLen) +{ + OutputDebugString(L"w32sock WSAAsyncGetHostByAddr stub called\n"); + + return NULL; +} + +HANDLE +STDCALL +WSAAsyncGetHostByName(HWND Wnd, + unsigned int Msg, + const char *Name, + char *Buf, + int BufLen) +{ + OutputDebugString(L"w32sock WSAAsyncGetHostByName stub called\n"); + + return NULL; +} + +HANDLE +STDCALL +WSAAsyncGetProtoByName(HWND Wnd, + unsigned int Msg, + const char *Name, + char *Buf, + int Buflen) +{ + OutputDebugString(L"w32sock WSAAsyncGetProtoByName stub called\n"); + + return NULL; +} + +HANDLE +STDCALL +WSAAsyncGetProtoByNumber(HWND Wnd, + unsigned int Msg, + int Number, + char *Buf, + int BufLen) +{ + OutputDebugString(L"w32sock WSAAsyncGetProtoByNumber stub called\n"); + + return NULL; +} + +HANDLE +STDCALL +WSAAsyncGetServByName(HWND Wnd, + unsigned int Msg, + const char *Name, + const char *Proto, + char *Buf, + int BufLen) +{ + OutputDebugString(L"w32sock WSAAsyncGetServByName stub called\n"); + + return NULL; +} + +HANDLE +STDCALL +WSAAsyncGetServByPort(HWND Wnd, + unsigned int Msg, + int Port, + const char *Proto, + char *Buf, + int BufLen) +{ + OutputDebugString(L"w32sock WSAAsyncGetServByPort stub called\n"); + + return NULL; +} + +INT +STDCALL +WSAAsyncSelect(SOCKET Sock, + HWND Wnd, + UINT Msg, + LONG Event) +{ + OutputDebugString(L"w32sock WSAAsyncSelect stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +WSACancelAsyncRequest(HANDLE AsyncTaskHandle) +{ + OutputDebugString(L"w32sock WSACancelAsyncRequest stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +WSACancelBlockingCall() +{ + OutputDebugString(L"w32sock WSACancelBlockingCall stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +WSACleanup() +{ + OutputDebugString(L"w32sock WSACleanup stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +WSAGetLastError(void) +{ + OutputDebugString(L"w32sock WSAGetLastError stub called\n"); + + return WSANOTINITIALISED; +} + +BOOL +STDCALL +WSAIsBlocking(VOID) +{ + OutputDebugString(L"w32sock WSAIsBlocking stub called\n"); + + return FALSE; +} + +int +STDCALL +WSARecvEx(SOCKET Sock, + char *Buf, + int Len, + int *Flags) +{ + OutputDebugString(L"w32sock WSARecvEx stub called\n"); + + return SOCKET_ERROR; +} + +FARPROC +STDCALL +WSASetBlockingHook(FARPROC BlockFunc) +{ + OutputDebugString(L"w32sock WSASetBlockingHook stub called\n"); + + return NULL; +} + +void +STDCALL WSASetLastError(int Error) +{ + OutputDebugString(L"w32sock WSASetLastError stub called\n"); +} + +int +STDCALL +WSAStartup(WORD VersionRequested, + LPWSADATA WSAData) +{ + OutputDebugString(L"w32sock WSAStartup stub called\n"); + + return WSASYSNOTREADY; +} + +int +STDCALL +WSAUnhookBlockingHook(void) +{ + OutputDebugString(L"w32sock WSAUnhookBlockingHook stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +WSApSetPostRoutine(LPVOID /* really LPWPUPOSTMESSAGE */ PostRoutine) +{ + OutputDebugString(L"w32sock WSApSetPostRoutine stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +__WSAFDIsSet(SOCKET Sock, + fd_set *Set) +{ + OutputDebugString(L"w32sock __WSAFDIsSet stub called\n"); + + return 0; +} + +SOCKET +STDCALL +accept(SOCKET Sock, + struct sockaddr *Addr, + int *AddrLen) +{ + OutputDebugString(L"w32sock accept stub called\n"); + + return INVALID_SOCKET; +} + +INT +STDCALL +bind(SOCKET Sock, + CONST LPSOCKADDR Name, + INT NameLen) +{ + OutputDebugString(L"w32sock bind stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +closesocket(SOCKET Sock) +{ + OutputDebugString(L"w32sock closesocket stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +connect(SOCKET Sock, + CONST LPSOCKADDR Name, + INT NameLen) +{ + OutputDebugString(L"w32sock connect stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +dn_expand(unsigned char *MessagePtr, + unsigned char *EndofMesOrig, + unsigned char *CompDomNam, + unsigned char *ExpandDomNam, + int Length) +{ + OutputDebugString(L"w32sock dn_expand stub called\n"); + + return SOCKET_ERROR; +} + +LPHOSTENT +STDCALL +gethostbyaddr(CONST CHAR *Addr, + INT Len, + INT Type) +{ + OutputDebugString(L"w32sock gethostbyaddr stub called\n"); + + return NULL; +} + +struct hostent * +STDCALL +gethostbyname(const char *Name) +{ + OutputDebugString(L"w32sock gethostbyname stub called\n"); + + return NULL; +} + +int +STDCALL +gethostname(char *Name, + int NameLen) +{ + OutputDebugString(L"w32sock gethostname stub called\n"); + + return SOCKET_ERROR; +} + +struct netent * +STDCALL +getnetbyname(char *Name) +{ + OutputDebugString(L"w32sock getnetbyname stub called\n"); + + return NULL; +} + +int +STDCALL +getpeername(SOCKET Sock, + struct sockaddr *Name, + int *NameLen) +{ + OutputDebugString(L"w32sock getpeername stub called\n"); + + return SOCKET_ERROR; +} + +LPPROTOENT +STDCALL +getprotobyname(CONST CHAR *Name) +{ + OutputDebugString(L"w32sock getprotobyname stub called\n"); + + return NULL; +} + +LPPROTOENT +STDCALL +getprotobynumber(INT Number) +{ + OutputDebugString(L"w32sock getprotobynumber stub called\n"); + + return NULL; +} + +struct servent * +STDCALL +getservbyname(const char *Name, + const char *Proto) +{ + OutputDebugString(L"w32sock getservbyname stub called\n"); + + return NULL; +} + +struct servent * +STDCALL +getservbyport(int Port, + const char *Proto) +{ + OutputDebugString(L"w32sock getservbyport stub called\n"); + + return NULL; +} + +int +STDCALL +getsockname(SOCKET Sock, + struct sockaddr *Name, + int *NameLen) +{ + OutputDebugString(L"w32sock getsockname stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +getsockopt(SOCKET Sock, + int Level, + int OptName, + char *OptVal, + int *OptLen) +{ + OutputDebugString(L"w32sock getsockopt stub called\n"); + + return SOCKET_ERROR; +} + +ULONG +STDCALL +htonl(ULONG HostLong) +{ + return (((HostLong << 24) & 0xff000000) | + ((HostLong << 8) & 0x00ff0000) | + ((HostLong >> 8) & 0x0000ff00) | + ((HostLong >> 24) & 0x000000ff)); +} + +USHORT +STDCALL +htons(USHORT HostShort) +{ + return (((HostShort << 8) & 0xff00) | + ((HostShort >> 8) & 0x00ff)); +} + +ULONG +STDCALL +inet_addr(CONST CHAR *cp) +{ + OutputDebugString(L"w32sock inet_addr stub called\n"); + + return INADDR_NONE; +} + +unsigned long +STDCALL +inet_network(const char *cp) +{ + OutputDebugString(L"w32sock inet_network stub called\n"); + + return INADDR_NONE; +} + +char * +STDCALL +inet_ntoa(struct in_addr in) +{ + OutputDebugString(L"w32sock inet_ntoa stub called\n"); + + return NULL; +} + +INT +STDCALL +ioctlsocket(SOCKET Sock, + LONG Cmd, + ULONG *Argp) +{ + OutputDebugString(L"w32sock ioctlsocket stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +listen(SOCKET Sock, + int BackLog) +{ + OutputDebugString(L"w32sock listen stub called\n"); + + return SOCKET_ERROR; +} + + +ULONG +STDCALL +ntohl(ULONG NetLong) +{ + return (((NetLong << 24) & 0xff000000) | + ((NetLong << 8) & 0x00ff0000) | + ((NetLong >> 8) & 0x0000ff00) | + ((NetLong >> 24) & 0x000000ff)); +} + +USHORT +STDCALL +ntohs(USHORT NetShort) +{ + return (((NetShort << 8) & 0xff00) | + ((NetShort >> 8) & 0x00ff)); +} + +SOCKET +STDCALL +rcmd(char **AHost, + USHORT InPort, + char *LocUser, + char *RemUser, + char *Cmd, + int *Fd2p) +{ + OutputDebugString(L"w32sock rcmd stub called\n"); + + return INVALID_SOCKET; +} + +int +STDCALL +recv(SOCKET Sock, + char *Buf, + int Len, + int Flags) +{ + OutputDebugString(L"w32sock recv stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +recvfrom(SOCKET Sock, + char *Buf, + int Len, + int Flags, + struct sockaddr *From, + int *FromLen) +{ + OutputDebugString(L"w32sock recvfrom stub called\n"); + + return SOCKET_ERROR; +} + +SOCKET +STDCALL +rexec(char **AHost, + int InPort, + char *User, + char *Passwd, + char *Cmd, + int *Fd2p) +{ + OutputDebugString(L"w32sock rexec stub called\n"); + + return INVALID_SOCKET; +} + + +SOCKET +STDCALL +rresvport(int *port) +{ + OutputDebugString(L"w32sock rresvport stub called\n"); + + return INVALID_SOCKET; +} + +void +STDCALL +s_perror(const char *str) +{ + OutputDebugString(L"w32sock s_perror stub called\n"); +} + +INT +STDCALL +select(INT NumFds, + LPFD_SET ReadFds, + LPFD_SET WriteFds, + LPFD_SET ExceptFds, + CONST LPTIMEVAL TimeOut) +{ + OutputDebugString(L"w32sock select stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +send(SOCKET Sock, + const char *Buf, + int Len, + int Flags) +{ + OutputDebugString(L"w32sock send stub called\n"); + + return SOCKET_ERROR; +} + +INT +STDCALL +sendto(SOCKET Sock, + CONST CHAR *Buf, + INT Len, + INT Flags, + CONST LPSOCKADDR To, + INT ToLen) +{ + OutputDebugString(L"w32sock sendto stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +sethostname(char *Name, int NameLen) +{ + OutputDebugString(L"w32sock sethostname stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +setsockopt(SOCKET Sock, + int Level, + int OptName, + const char *OptVal, + int OptLen) +{ + OutputDebugString(L"w32sock setsockopt stub called\n"); + + return SOCKET_ERROR; +} + +int +STDCALL +shutdown(SOCKET Sock, + int How) +{ + OutputDebugString(L"w32sock shutdown stub called\n"); + + return SOCKET_ERROR; +} + +SOCKET +STDCALL +socket(int AF, + int Type, + int Protocol) +{ + OutputDebugString(L"w32sock socket stub called\n"); + + return INVALID_SOCKET; +} + +BOOL +STDCALL +DllMain(HINSTANCE InstDLL, + DWORD Reason, + LPVOID Reserved) +{ + return TRUE; +} + diff --git a/lib/wsock32/wsock32.def b/lib/wsock32/wsock32.def new file mode 100644 index 0000000..115c566 --- /dev/null +++ b/lib/wsock32/wsock32.def @@ -0,0 +1,54 @@ +; $Id$ +; +; WSOCK32.DLL - Windows Sockets 2 DLL + +LIBRARY wsock32.dll + +EXPORTS +WSAAsyncGetHostByAddr@28 +WSAAsyncGetHostByName@20 +WSAAsyncGetProtoByName@20 +WSAAsyncGetProtoByNumber@20 +WSAAsyncGetServByName@24 +WSAAsyncGetServByPort@24 +WSAAsyncSelect@16 +WSACancelAsyncRequest@4 +WSACancelBlockingCall@0 +WSACleanup@0 +WSAGetLastError@0 +WSAIsBlocking@0 +WSASetBlockingHook@4 +WSASetLastError@4 +WSAStartup@8 +WSAUnhookBlockingHook@0 +__WSAFDIsSet@8 +accept@12 +bind@12 +closesocket@4 +connect@12 +gethostbyaddr@12 +gethostbyname@4 +gethostname@8 +getpeername@12 +getprotobyname@4 +getprotobynumber@4 +getservbyname@8 +getservbyport@8 +getsockname@12 +getsockopt@20 +htonl@4 +htons@4 +inet_addr@4 +inet_ntoa@4 +ioctlsocket@12 +listen@8 +ntohl@4 +ntohs@4 +recv@16 +recvfrom@24 +select@20 +send@16 +sendto@24 +setsockopt@20 +shutdown@8 +socket@12 diff --git a/lib/wsock32/wsock32.edf b/lib/wsock32/wsock32.edf new file mode 100644 index 0000000..d56a9c2 --- /dev/null +++ b/lib/wsock32/wsock32.edf @@ -0,0 +1,56 @@ +; $Id$ +; +; WSOCK32.DLL - Windows Sockets 2 DLL + +LIBRARY wsock32.dll + +EXPORTS +WSAAsyncGetHostByAddr=WSAAsyncGetHostByAddr@28 +WSAAsyncGetHostByName=WSAAsyncGetHostByName@20 +WSAAsyncGetProtoByName=WSAAsyncGetProtoByName@20 +WSAAsyncGetProtoByNumber=WSAAsyncGetProtoByNumber@20 +WSAAsyncGetServByName=WSAAsyncGetServByName@24 +WSAAsyncGetServByPort=WSAAsyncGetServByPort@24 +WSAAsyncSelect=WSAAsyncSelect@16 +WSACancelAsyncRequest=WSACancelAsyncRequest@4 +WSACancelBlockingCall=WSACancelBlockingCall@0 +WSACleanup=WSACleanup@0 +WSAGetLastError=WSAGetLastError@0 +WSAIsBlocking=WSAIsBlocking@0 +WSASetBlockingHook=WSASetBlockingHook@4 +WSASetLastError=WSASetLastError@4 +WSAStartup=WSAStartup@8 +WSAUnhookBlockingHook=WSAUnhookBlockingHook@0 +__WSAFDIsSet=__WSAFDIsSet@8 +accept=accept@12 +bind=bind@12 +closesocket=closesocket@4 +connect=connect@12 +gethostbyaddr=gethostbyaddr@12 +gethostbyname=gethostbyname@4 +gethostname=gethostname@8 +getpeername=getpeername@12 +getprotobyname=getprotobyname@4 +getprotobynumber=getprotobynumber@4 +getservbyname=getservbyname@8 +getservbyport=getservbyport@8 +getsockname=getsockname@12 +getsockopt=getsockopt@20 +htonl=htonl@4 +htons=htons@4 +inet_addr=inet_addr@4 +inet_ntoa=inet_ntoa@4 +ioctlsocket=ioctlsocket@12 +listen=listen@8 +ntohl=ntohl@4 +ntohs=ntohs@4 +recv=recv@16 +recvfrom=recvfrom@24 +select=select@20 +send=send@16 +sendto=sendto@24 +setsockopt=setsockopt@20 +shutdown=shutdown@8 +socket=socket@12 + +; EOF diff --git a/lib/wsock32/wsock32.rc b/lib/wsock32/wsock32.rc new file mode 100644 index 0000000..8777877 --- /dev/null +++ b/lib/wsock32/wsock32.rc @@ -0,0 +1,41 @@ +/* $Id$ */ + +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "Windows Sockets 2 DLL\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "wsock32\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "wsock32.dll\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + diff --git a/drivers/lib/zlib/.cvsignore b/lib/zlib/.cvsignore similarity index 100% rename from drivers/lib/zlib/.cvsignore rename to lib/zlib/.cvsignore diff --git a/drivers/lib/zlib/ChangeLog b/lib/zlib/ChangeLog similarity index 100% rename from drivers/lib/zlib/ChangeLog rename to lib/zlib/ChangeLog diff --git a/drivers/lib/zlib/FAQ b/lib/zlib/FAQ similarity index 100% rename from drivers/lib/zlib/FAQ rename to lib/zlib/FAQ diff --git a/drivers/lib/zlib/INDEX b/lib/zlib/INDEX similarity index 100% rename from drivers/lib/zlib/INDEX rename to lib/zlib/INDEX diff --git a/lib/zlib/Make_vms.com b/lib/zlib/Make_vms.com new file mode 100644 index 0000000..3788817 --- /dev/null +++ b/lib/zlib/Make_vms.com @@ -0,0 +1,115 @@ +$! make libz under VMS +$! written by Martin P.J. Zinser +$! +$! Look for the compiler used +$! +$ ccopt = "" +$ if f$getsyi("HW_MODEL").ge.1024 +$ then +$ ccopt = "/prefix=all"+ccopt +$ comp = "__decc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ comp = "__vaxc__=1" +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ else +$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: +$ ccopt = "/decc/prefix=all"+ccopt +$ comp = "__decc__=1" +$ endif +$ endif +$! +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if f$search("SYS$SYSTEM:MMS.EXE").eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - + gzio.c zutil.h zlib.h zconf.h +$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" - + infblock.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" - + infcodes.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" - + infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ else +$ mms/macro=('comp') +$ endif +$ write sys$output "Zlib build completed" +$ exit +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE diff --git a/lib/zlib/Makefile b/lib/zlib/Makefile new file mode 100644 index 0000000..5b5f089 --- /dev/null +++ b/lib/zlib/Makefile @@ -0,0 +1,25 @@ +# $Id$ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = library + +TARGET_NAME = zlib + +TARGET_CFLAGS = \ + -MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +TARGET_OBJECTS = \ + adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o \ + inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +# EOF diff --git a/drivers/lib/zlib/Makefile.in b/lib/zlib/Makefile.in similarity index 100% rename from drivers/lib/zlib/Makefile.in rename to lib/zlib/Makefile.in diff --git a/drivers/lib/zlib/Makefile.riscos b/lib/zlib/Makefile.riscos similarity index 100% rename from drivers/lib/zlib/Makefile.riscos rename to lib/zlib/Makefile.riscos diff --git a/drivers/lib/zlib/README b/lib/zlib/README similarity index 100% rename from drivers/lib/zlib/README rename to lib/zlib/README diff --git a/drivers/lib/zlib/adler32.c b/lib/zlib/adler32.c similarity index 100% rename from drivers/lib/zlib/adler32.c rename to lib/zlib/adler32.c diff --git a/drivers/lib/zlib/algorithm.txt b/lib/zlib/algorithm.txt similarity index 100% rename from drivers/lib/zlib/algorithm.txt rename to lib/zlib/algorithm.txt diff --git a/drivers/lib/zlib/amiga/Makefile.pup b/lib/zlib/amiga/Makefile.pup similarity index 100% rename from drivers/lib/zlib/amiga/Makefile.pup rename to lib/zlib/amiga/Makefile.pup diff --git a/drivers/lib/zlib/amiga/Makefile.sas b/lib/zlib/amiga/Makefile.sas similarity index 100% rename from drivers/lib/zlib/amiga/Makefile.sas rename to lib/zlib/amiga/Makefile.sas diff --git a/drivers/lib/zlib/compress.c b/lib/zlib/compress.c similarity index 100% rename from drivers/lib/zlib/compress.c rename to lib/zlib/compress.c diff --git a/drivers/lib/zlib/configure b/lib/zlib/configure similarity index 100% rename from drivers/lib/zlib/configure rename to lib/zlib/configure diff --git a/drivers/lib/zlib/contrib/README.contrib b/lib/zlib/contrib/README.contrib similarity index 100% rename from drivers/lib/zlib/contrib/README.contrib rename to lib/zlib/contrib/README.contrib diff --git a/drivers/lib/zlib/contrib/asm386/gvmat32.asm b/lib/zlib/contrib/asm386/gvmat32.asm similarity index 100% rename from drivers/lib/zlib/contrib/asm386/gvmat32.asm rename to lib/zlib/contrib/asm386/gvmat32.asm diff --git a/drivers/lib/zlib/contrib/asm386/gvmat32c.c b/lib/zlib/contrib/asm386/gvmat32c.c similarity index 100% rename from drivers/lib/zlib/contrib/asm386/gvmat32c.c rename to lib/zlib/contrib/asm386/gvmat32c.c diff --git a/drivers/lib/zlib/contrib/asm386/mkgvmt32.bat b/lib/zlib/contrib/asm386/mkgvmt32.bat similarity index 100% rename from drivers/lib/zlib/contrib/asm386/mkgvmt32.bat rename to lib/zlib/contrib/asm386/mkgvmt32.bat diff --git a/drivers/lib/zlib/contrib/asm386/zlibvc.def b/lib/zlib/contrib/asm386/zlibvc.def similarity index 100% rename from drivers/lib/zlib/contrib/asm386/zlibvc.def rename to lib/zlib/contrib/asm386/zlibvc.def diff --git a/lib/zlib/contrib/asm386/zlibvc.dsp b/lib/zlib/contrib/asm386/zlibvc.dsp new file mode 100644 index 0000000..38bc9b8 --- /dev/null +++ b/lib/zlib/contrib/asm386/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!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 "zlibvc.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 "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - 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 Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - 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 "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.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" +# End Group +# End Target +# End Project diff --git a/lib/zlib/contrib/asm386/zlibvc.dsw b/lib/zlib/contrib/asm386/zlibvc.dsw new file mode 100644 index 0000000..850c7a9 --- /dev/null +++ b/lib/zlib/contrib/asm386/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/drivers/lib/zlib/contrib/asm586/README.586 b/lib/zlib/contrib/asm586/README.586 similarity index 100% rename from drivers/lib/zlib/contrib/asm586/README.586 rename to lib/zlib/contrib/asm586/README.586 diff --git a/drivers/lib/zlib/contrib/asm586/match.S b/lib/zlib/contrib/asm586/match.S similarity index 100% rename from drivers/lib/zlib/contrib/asm586/match.S rename to lib/zlib/contrib/asm586/match.S diff --git a/drivers/lib/zlib/contrib/asm686/README.686 b/lib/zlib/contrib/asm686/README.686 similarity index 100% rename from drivers/lib/zlib/contrib/asm686/README.686 rename to lib/zlib/contrib/asm686/README.686 diff --git a/drivers/lib/zlib/contrib/asm686/match.S b/lib/zlib/contrib/asm686/match.S similarity index 100% rename from drivers/lib/zlib/contrib/asm686/match.S rename to lib/zlib/contrib/asm686/match.S diff --git a/drivers/lib/zlib/contrib/delphi/zlib.mak b/lib/zlib/contrib/delphi/zlib.mak similarity index 100% rename from drivers/lib/zlib/contrib/delphi/zlib.mak rename to lib/zlib/contrib/delphi/zlib.mak diff --git a/drivers/lib/zlib/contrib/delphi/zlibdef.pas b/lib/zlib/contrib/delphi/zlibdef.pas similarity index 100% rename from drivers/lib/zlib/contrib/delphi/zlibdef.pas rename to lib/zlib/contrib/delphi/zlibdef.pas diff --git a/drivers/lib/zlib/contrib/delphi2/d_zlib.bpr b/lib/zlib/contrib/delphi2/d_zlib.bpr similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/d_zlib.bpr rename to lib/zlib/contrib/delphi2/d_zlib.bpr diff --git a/drivers/lib/zlib/contrib/delphi2/d_zlib.cpp b/lib/zlib/contrib/delphi2/d_zlib.cpp similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/d_zlib.cpp rename to lib/zlib/contrib/delphi2/d_zlib.cpp diff --git a/drivers/lib/zlib/contrib/delphi2/readme.txt b/lib/zlib/contrib/delphi2/readme.txt similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/readme.txt rename to lib/zlib/contrib/delphi2/readme.txt diff --git a/drivers/lib/zlib/contrib/delphi2/zlib.bpg b/lib/zlib/contrib/delphi2/zlib.bpg similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib.bpg rename to lib/zlib/contrib/delphi2/zlib.bpg diff --git a/drivers/lib/zlib/contrib/delphi2/zlib.bpr b/lib/zlib/contrib/delphi2/zlib.bpr similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib.bpr rename to lib/zlib/contrib/delphi2/zlib.bpr diff --git a/drivers/lib/zlib/contrib/delphi2/zlib.cpp b/lib/zlib/contrib/delphi2/zlib.cpp similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib.cpp rename to lib/zlib/contrib/delphi2/zlib.cpp diff --git a/drivers/lib/zlib/contrib/delphi2/zlib.pas b/lib/zlib/contrib/delphi2/zlib.pas similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib.pas rename to lib/zlib/contrib/delphi2/zlib.pas diff --git a/drivers/lib/zlib/contrib/delphi2/zlib32.bpr b/lib/zlib/contrib/delphi2/zlib32.bpr similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib32.bpr rename to lib/zlib/contrib/delphi2/zlib32.bpr diff --git a/drivers/lib/zlib/contrib/delphi2/zlib32.cpp b/lib/zlib/contrib/delphi2/zlib32.cpp similarity index 100% rename from drivers/lib/zlib/contrib/delphi2/zlib32.cpp rename to lib/zlib/contrib/delphi2/zlib32.cpp diff --git a/drivers/lib/zlib/contrib/iostream/test.cpp b/lib/zlib/contrib/iostream/test.cpp similarity index 100% rename from drivers/lib/zlib/contrib/iostream/test.cpp rename to lib/zlib/contrib/iostream/test.cpp diff --git a/drivers/lib/zlib/contrib/iostream/zfstream.cpp b/lib/zlib/contrib/iostream/zfstream.cpp similarity index 100% rename from drivers/lib/zlib/contrib/iostream/zfstream.cpp rename to lib/zlib/contrib/iostream/zfstream.cpp diff --git a/drivers/lib/zlib/contrib/iostream/zfstream.h b/lib/zlib/contrib/iostream/zfstream.h similarity index 100% rename from drivers/lib/zlib/contrib/iostream/zfstream.h rename to lib/zlib/contrib/iostream/zfstream.h diff --git a/drivers/lib/zlib/contrib/iostream2/zstream.h b/lib/zlib/contrib/iostream2/zstream.h similarity index 100% rename from drivers/lib/zlib/contrib/iostream2/zstream.h rename to lib/zlib/contrib/iostream2/zstream.h diff --git a/drivers/lib/zlib/contrib/iostream2/zstream_test.cpp b/lib/zlib/contrib/iostream2/zstream_test.cpp similarity index 100% rename from drivers/lib/zlib/contrib/iostream2/zstream_test.cpp rename to lib/zlib/contrib/iostream2/zstream_test.cpp diff --git a/drivers/lib/zlib/contrib/minizip/ChangeLogUnzip b/lib/zlib/contrib/minizip/ChangeLogUnzip similarity index 100% rename from drivers/lib/zlib/contrib/minizip/ChangeLogUnzip rename to lib/zlib/contrib/minizip/ChangeLogUnzip diff --git a/drivers/lib/zlib/contrib/minizip/Makefile b/lib/zlib/contrib/minizip/Makefile similarity index 100% rename from drivers/lib/zlib/contrib/minizip/Makefile rename to lib/zlib/contrib/minizip/Makefile diff --git a/drivers/lib/zlib/contrib/minizip/miniunz.c b/lib/zlib/contrib/minizip/miniunz.c similarity index 100% rename from drivers/lib/zlib/contrib/minizip/miniunz.c rename to lib/zlib/contrib/minizip/miniunz.c diff --git a/drivers/lib/zlib/contrib/minizip/minizip.c b/lib/zlib/contrib/minizip/minizip.c similarity index 100% rename from drivers/lib/zlib/contrib/minizip/minizip.c rename to lib/zlib/contrib/minizip/minizip.c diff --git a/drivers/lib/zlib/contrib/minizip/readme.txt b/lib/zlib/contrib/minizip/readme.txt similarity index 100% rename from drivers/lib/zlib/contrib/minizip/readme.txt rename to lib/zlib/contrib/minizip/readme.txt diff --git a/drivers/lib/zlib/contrib/minizip/unzip.c b/lib/zlib/contrib/minizip/unzip.c similarity index 100% rename from drivers/lib/zlib/contrib/minizip/unzip.c rename to lib/zlib/contrib/minizip/unzip.c diff --git a/drivers/lib/zlib/contrib/minizip/unzip.def b/lib/zlib/contrib/minizip/unzip.def similarity index 100% rename from drivers/lib/zlib/contrib/minizip/unzip.def rename to lib/zlib/contrib/minizip/unzip.def diff --git a/drivers/lib/zlib/contrib/minizip/unzip.h b/lib/zlib/contrib/minizip/unzip.h similarity index 100% rename from drivers/lib/zlib/contrib/minizip/unzip.h rename to lib/zlib/contrib/minizip/unzip.h diff --git a/drivers/lib/zlib/contrib/minizip/zip.c b/lib/zlib/contrib/minizip/zip.c similarity index 100% rename from drivers/lib/zlib/contrib/minizip/zip.c rename to lib/zlib/contrib/minizip/zip.c diff --git a/drivers/lib/zlib/contrib/minizip/zip.def b/lib/zlib/contrib/minizip/zip.def similarity index 100% rename from drivers/lib/zlib/contrib/minizip/zip.def rename to lib/zlib/contrib/minizip/zip.def diff --git a/drivers/lib/zlib/contrib/minizip/zip.h b/lib/zlib/contrib/minizip/zip.h similarity index 100% rename from drivers/lib/zlib/contrib/minizip/zip.h rename to lib/zlib/contrib/minizip/zip.h diff --git a/drivers/lib/zlib/contrib/minizip/zlibvc.def b/lib/zlib/contrib/minizip/zlibvc.def similarity index 100% rename from drivers/lib/zlib/contrib/minizip/zlibvc.def rename to lib/zlib/contrib/minizip/zlibvc.def diff --git a/lib/zlib/contrib/minizip/zlibvc.dsp b/lib/zlib/contrib/minizip/zlibvc.dsp new file mode 100644 index 0000000..38bc9b8 --- /dev/null +++ b/lib/zlib/contrib/minizip/zlibvc.dsp @@ -0,0 +1,651 @@ +# Microsoft Developer Studio Project File - Name="zlibvc" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (ALPHA) Dynamic-Link Library" 0x0602 + +CFG=zlibvc - Win32 Release +!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 "zlibvc.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 "zlibvc.mak" CFG="zlibvc - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlibvc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseAxp" (based on\ + "Win32 (ALPHA) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutAsm" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlibvc - Win32 ReleaseWithoutCrtdll" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlibvc - 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 Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - 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 "" +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\zlib.dll" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc__" +# PROP BASE Intermediate_Dir "zlibvc__" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc__" +# PROP Intermediate_Dir "zlibvc__" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +CPP=cl.exe +# ADD BASE CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /Gt0 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 crtdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /machine:ALPHA /nodefaultlib /out:"zlibvc__\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_0" +# PROP BASE Intermediate_Dir "zlibvc_0" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_0" +# PROP Intermediate_Dir "zlibvc_0" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_0\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlibvc_1" +# PROP BASE Intermediate_Dir "zlibvc_1" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "zlibvc_1" +# PROP Intermediate_Dir "zlibvc_1" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_WINDLL" /D "_WIN32" /D "BUILD_ZLIBDLL" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FR /FD /c +# SUBTRACT CPP /YX +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\Release\zlib.dll" +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 gvmat32.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib crtdll.lib /nologo /subsystem:windows /dll /map /machine:I386 /nodefaultlib /out:".\zlibvc_1\zlib.dll" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "zlibvc - Win32 Release" +# Name "zlibvc - Win32 Debug" +# Name "zlibvc - Win32 ReleaseAxp" +# Name "zlibvc - Win32 ReleaseWithoutAsm" +# Name "zlibvc - Win32 ReleaseWithoutCrtdll" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\adler32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ADLER=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\compress.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_COMPR=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\crc32.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_CRC32=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\deflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_DEFLA=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gvmat32c.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gzio.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_GZIO_=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infblock.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFBL=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infcodes.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFCO=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inffast.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFFA=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inffast.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inflate.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFLA=\ + ".\infblock.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\inftrees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFTR=\ + ".\inftrees.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\infutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_INFUT=\ + ".\infblock.h"\ + ".\infcodes.h"\ + ".\inftrees.h"\ + ".\infutil.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\trees.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_TREES=\ + ".\deflate.h"\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\uncompr.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_UNCOM=\ + ".\zconf.h"\ + ".\zlib.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\unzip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zip.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zlib.rc +# End Source File +# Begin Source File + +SOURCE=.\zlibvc.def +# End Source File +# Begin Source File + +SOURCE=.\zutil.c + +!IF "$(CFG)" == "zlibvc - Win32 Release" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 Debug" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseAxp" + +DEP_CPP_ZUTIL=\ + ".\zconf.h"\ + ".\zlib.h"\ + ".\zutil.h"\ + + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutAsm" + +!ELSEIF "$(CFG)" == "zlibvc - Win32 ReleaseWithoutCrtdll" + +!ENDIF + +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\deflate.h +# End Source File +# Begin Source File + +SOURCE=.\infblock.h +# End Source File +# Begin Source File + +SOURCE=.\infcodes.h +# End Source File +# Begin Source File + +SOURCE=.\inffast.h +# End Source File +# Begin Source File + +SOURCE=.\inftrees.h +# End Source File +# Begin Source File + +SOURCE=.\infutil.h +# End Source File +# Begin Source File + +SOURCE=.\zconf.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# Begin Source File + +SOURCE=.\zutil.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" +# End Group +# End Target +# End Project diff --git a/lib/zlib/contrib/minizip/zlibvc.dsw b/lib/zlib/contrib/minizip/zlibvc.dsw new file mode 100644 index 0000000..850c7a9 --- /dev/null +++ b/lib/zlib/contrib/minizip/zlibvc.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "zlibstat"=.\zlibstat.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "zlibvc"=.\zlibvc.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/drivers/lib/zlib/contrib/untgz/Makefile b/lib/zlib/contrib/untgz/Makefile similarity index 100% rename from drivers/lib/zlib/contrib/untgz/Makefile rename to lib/zlib/contrib/untgz/Makefile diff --git a/drivers/lib/zlib/contrib/untgz/makefile.w32 b/lib/zlib/contrib/untgz/makefile.w32 similarity index 100% rename from drivers/lib/zlib/contrib/untgz/makefile.w32 rename to lib/zlib/contrib/untgz/makefile.w32 diff --git a/drivers/lib/zlib/contrib/untgz/untgz.c b/lib/zlib/contrib/untgz/untgz.c similarity index 100% rename from drivers/lib/zlib/contrib/untgz/untgz.c rename to lib/zlib/contrib/untgz/untgz.c diff --git a/drivers/lib/zlib/contrib/visual-basic.txt b/lib/zlib/contrib/visual-basic.txt similarity index 100% rename from drivers/lib/zlib/contrib/visual-basic.txt rename to lib/zlib/contrib/visual-basic.txt diff --git a/drivers/lib/zlib/crc32.c b/lib/zlib/crc32.c similarity index 100% rename from drivers/lib/zlib/crc32.c rename to lib/zlib/crc32.c diff --git a/drivers/lib/zlib/deflate.c b/lib/zlib/deflate.c similarity index 100% rename from drivers/lib/zlib/deflate.c rename to lib/zlib/deflate.c diff --git a/drivers/lib/zlib/deflate.h b/lib/zlib/deflate.h similarity index 100% rename from drivers/lib/zlib/deflate.h rename to lib/zlib/deflate.h diff --git a/drivers/lib/zlib/descrip.mms b/lib/zlib/descrip.mms similarity index 100% rename from drivers/lib/zlib/descrip.mms rename to lib/zlib/descrip.mms diff --git a/drivers/lib/zlib/example.c b/lib/zlib/example.c similarity index 100% rename from drivers/lib/zlib/example.c rename to lib/zlib/example.c diff --git a/drivers/lib/zlib/gzio.c b/lib/zlib/gzio.c similarity index 100% rename from drivers/lib/zlib/gzio.c rename to lib/zlib/gzio.c diff --git a/drivers/lib/zlib/infblock.c b/lib/zlib/infblock.c similarity index 100% rename from drivers/lib/zlib/infblock.c rename to lib/zlib/infblock.c diff --git a/drivers/lib/zlib/infblock.h b/lib/zlib/infblock.h similarity index 100% rename from drivers/lib/zlib/infblock.h rename to lib/zlib/infblock.h diff --git a/drivers/lib/zlib/infcodes.c b/lib/zlib/infcodes.c similarity index 100% rename from drivers/lib/zlib/infcodes.c rename to lib/zlib/infcodes.c diff --git a/drivers/lib/zlib/infcodes.h b/lib/zlib/infcodes.h similarity index 100% rename from drivers/lib/zlib/infcodes.h rename to lib/zlib/infcodes.h diff --git a/drivers/lib/zlib/inffast.c b/lib/zlib/inffast.c similarity index 100% rename from drivers/lib/zlib/inffast.c rename to lib/zlib/inffast.c diff --git a/drivers/lib/zlib/inffast.h b/lib/zlib/inffast.h similarity index 100% rename from drivers/lib/zlib/inffast.h rename to lib/zlib/inffast.h diff --git a/lib/zlib/inffixed.h b/lib/zlib/inffixed.h new file mode 100644 index 0000000..77f7e76 --- /dev/null +++ b/lib/zlib/inffixed.h @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff --git a/drivers/lib/zlib/inflate.c b/lib/zlib/inflate.c similarity index 100% rename from drivers/lib/zlib/inflate.c rename to lib/zlib/inflate.c diff --git a/drivers/lib/zlib/inftrees.c b/lib/zlib/inftrees.c similarity index 100% rename from drivers/lib/zlib/inftrees.c rename to lib/zlib/inftrees.c diff --git a/drivers/lib/zlib/inftrees.h b/lib/zlib/inftrees.h similarity index 100% rename from drivers/lib/zlib/inftrees.h rename to lib/zlib/inftrees.h diff --git a/drivers/lib/zlib/infutil.c b/lib/zlib/infutil.c similarity index 100% rename from drivers/lib/zlib/infutil.c rename to lib/zlib/infutil.c diff --git a/drivers/lib/zlib/infutil.h b/lib/zlib/infutil.h similarity index 100% rename from drivers/lib/zlib/infutil.h rename to lib/zlib/infutil.h diff --git a/drivers/lib/zlib/maketree.c b/lib/zlib/maketree.c similarity index 100% rename from drivers/lib/zlib/maketree.c rename to lib/zlib/maketree.c diff --git a/drivers/lib/zlib/minigzip.c b/lib/zlib/minigzip.c similarity index 100% rename from drivers/lib/zlib/minigzip.c rename to lib/zlib/minigzip.c diff --git a/drivers/lib/zlib/msdos/Makefile.b32 b/lib/zlib/msdos/Makefile.b32 similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.b32 rename to lib/zlib/msdos/Makefile.b32 diff --git a/drivers/lib/zlib/msdos/Makefile.bor b/lib/zlib/msdos/Makefile.bor similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.bor rename to lib/zlib/msdos/Makefile.bor diff --git a/drivers/lib/zlib/msdos/Makefile.dj2 b/lib/zlib/msdos/Makefile.dj2 similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.dj2 rename to lib/zlib/msdos/Makefile.dj2 diff --git a/drivers/lib/zlib/msdos/Makefile.emx b/lib/zlib/msdos/Makefile.emx similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.emx rename to lib/zlib/msdos/Makefile.emx diff --git a/drivers/lib/zlib/msdos/Makefile.msc b/lib/zlib/msdos/Makefile.msc similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.msc rename to lib/zlib/msdos/Makefile.msc diff --git a/drivers/lib/zlib/msdos/Makefile.tc b/lib/zlib/msdos/Makefile.tc similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.tc rename to lib/zlib/msdos/Makefile.tc diff --git a/drivers/lib/zlib/msdos/Makefile.w32 b/lib/zlib/msdos/Makefile.w32 similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.w32 rename to lib/zlib/msdos/Makefile.w32 diff --git a/drivers/lib/zlib/msdos/Makefile.wat b/lib/zlib/msdos/Makefile.wat similarity index 100% rename from drivers/lib/zlib/msdos/Makefile.wat rename to lib/zlib/msdos/Makefile.wat diff --git a/drivers/lib/zlib/msdos/zlib.def b/lib/zlib/msdos/zlib.def similarity index 100% rename from drivers/lib/zlib/msdos/zlib.def rename to lib/zlib/msdos/zlib.def diff --git a/drivers/lib/zlib/msdos/zlib.rc b/lib/zlib/msdos/zlib.rc similarity index 100% rename from drivers/lib/zlib/msdos/zlib.rc rename to lib/zlib/msdos/zlib.rc diff --git a/drivers/lib/zlib/nt/Makefile.emx b/lib/zlib/nt/Makefile.emx similarity index 100% rename from drivers/lib/zlib/nt/Makefile.emx rename to lib/zlib/nt/Makefile.emx diff --git a/drivers/lib/zlib/nt/Makefile.gcc b/lib/zlib/nt/Makefile.gcc similarity index 100% rename from drivers/lib/zlib/nt/Makefile.gcc rename to lib/zlib/nt/Makefile.gcc diff --git a/drivers/lib/zlib/nt/Makefile.nt b/lib/zlib/nt/Makefile.nt similarity index 100% rename from drivers/lib/zlib/nt/Makefile.nt rename to lib/zlib/nt/Makefile.nt diff --git a/drivers/lib/zlib/nt/zlib.dnt b/lib/zlib/nt/zlib.dnt similarity index 100% rename from drivers/lib/zlib/nt/zlib.dnt rename to lib/zlib/nt/zlib.dnt diff --git a/drivers/lib/zlib/os2/Makefile.os2 b/lib/zlib/os2/Makefile.os2 similarity index 100% rename from drivers/lib/zlib/os2/Makefile.os2 rename to lib/zlib/os2/Makefile.os2 diff --git a/drivers/lib/zlib/os2/zlib.def b/lib/zlib/os2/zlib.def similarity index 100% rename from drivers/lib/zlib/os2/zlib.def rename to lib/zlib/os2/zlib.def diff --git a/drivers/lib/zlib/trees.c b/lib/zlib/trees.c similarity index 100% rename from drivers/lib/zlib/trees.c rename to lib/zlib/trees.c diff --git a/drivers/lib/zlib/trees.h b/lib/zlib/trees.h similarity index 100% rename from drivers/lib/zlib/trees.h rename to lib/zlib/trees.h diff --git a/drivers/lib/zlib/uncompr.c b/lib/zlib/uncompr.c similarity index 100% rename from drivers/lib/zlib/uncompr.c rename to lib/zlib/uncompr.c diff --git a/drivers/lib/zlib/zconf.h b/lib/zlib/zconf.h similarity index 100% rename from drivers/lib/zlib/zconf.h rename to lib/zlib/zconf.h diff --git a/drivers/lib/zlib/zlib.3 b/lib/zlib/zlib.3 similarity index 100% rename from drivers/lib/zlib/zlib.3 rename to lib/zlib/zlib.3 diff --git a/drivers/lib/zlib/zlib.h b/lib/zlib/zlib.h similarity index 100% rename from drivers/lib/zlib/zlib.h rename to lib/zlib/zlib.h diff --git a/drivers/lib/zlib/zlib.html b/lib/zlib/zlib.html similarity index 100% rename from drivers/lib/zlib/zlib.html rename to lib/zlib/zlib.html diff --git a/drivers/lib/zlib/zutil.c b/lib/zlib/zutil.c similarity index 100% rename from drivers/lib/zlib/zutil.c rename to lib/zlib/zutil.c diff --git a/drivers/lib/zlib/zutil.h b/lib/zlib/zutil.h similarity index 100% rename from drivers/lib/zlib/zutil.h rename to lib/zlib/zutil.h diff --git a/loaders/boot/boot.asm b/loaders/boot/boot.asm deleted file mode 100644 index 525380e..0000000 --- a/loaders/boot/boot.asm +++ /dev/null @@ -1,309 +0,0 @@ -; -; File: -; boot.asm -; Description: -; DOS-C boot -; -; Copyright (c) 1997; -; Svante Frey -; All Rights Reserved -; -; This file is part of DOS-C. -; -; DOS-C 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. -; -; DOS-C 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 DOS-C; see the file COPYING. If not, -; write to the Free Software Foundation, 675 Mass Ave, -; Cambridge, MA 02139, USA. -; -; $Logfile: C:/dos-c/src/boot/boot.asv $ -; -; $Header$ -; -; $Log$ -; Revision 1.4 2003/02/12 22:32:53 short -; update for HEAD-2003021201 -; -; Revision 1.4 2000/06/25 03:59:14 dwelch -; -; Removed from redundant files from the mm directory -; Added some preliminary work on the pager -; Fixed ntoskrnl/mm/npool.c (This may have been the cause of the -; problems reported with loading win32k.sys) -; Fixed problems with reporting space used to store physical page -; information -; Added code to support MmSafeCopy{To/From}User interface work -; (untested) -; Added Event member of the PHYSICAL_PAGE structure to implement Philip -; Susi's suggestion -; Reworked section page-in code (not really tested) -; Replaced inline string functions with gcc builtins to make debugging easier -; -; Revision 1.3 1998/08/25 04:37:43 rex -; new release cleanup -; -; Revision 1.1.1.2 1998/08/25 04:27:38 rex -; A much Needed Update -; -; -; Rev 1.5 10 Jan 1997 4:58:06 patv -; Corrected copyright -; -; Rev 1.4 10 Jan 1997 4:52:50 patv -; Re-written to support C drive and eliminate restrictions on IPL.SYS -; -; Rev 1.3 29 Aug 1996 13:06:50 patv -; Bug fixes for v0.91b -; -; Rev 1.2 01 Sep 1995 17:56:44 patv -; First GPL release. -; -; Rev 1.1 30 Jul 1995 20:37:38 patv -; Initialized stack before use. -; -; Rev 1.0 02 Jul 1995 10:57:52 patv -; Initial revision. -; - -section .text - - org 0 -Entry: jmp real_start - -; bp is initialized to 7c00h -%define oem [bp+3] -%define bytesPerSector [bp+0bh] -%define sectPerCluster [bp+0dh] -%define resSectors [bp+0eh] -%define nFats [bp+10h] -%define nRootDir [bp+11h] -%define nSectors [bp+13h] -%define MID [bp+15h] -%define sectPerFat [bp+16h] -%define sectPerTrack [bp+18h] -%define nHeads [bp+1ah] -%define nHidden [bp+1ch] -%define nHidden_hi [bp+1eh] -%define nSectorHuge [bp+20h] -%define drive [bp+24h] -%define extBoot [bp+26h] -%define volid [bp+27h] -%define vollabel [bp+2bh] -%define filesys 36h - -LOADSEG equ 2000h - -FATBUF equ 4000h ; offset of temporary buffer for FAT - ; chain -RETRYCOUNT equ 5 ; number of retries on disk errors - -; Some extra variables that are created on the stack frame - -%define fat_start [bp-4] ; first FAT sector -%define fat_start_hi [bp-2] -%define root_dir_start [bp-8] ; first root directory sector -%define root_dir_start_hi [bp-6] -%define data_start [bp-12] ; first data sector -%define data_start_hi [bp-10] - -; -; Include macros for filesystem access -; -%include "boot.inc" - -; -; -; - TIMES 3eh-($-$$) DB 0 - -%define tempbuf [bp+3eh] -load_seg dw LOADSEG - -real_start: cli - cld - mov ax, cs - mov ss, ax ; initialize stack - mov bp, 7c00h - lea sp, [bp-20h] - sti - - mov es, ax - mov ds, ax - mov drive, dl ; BIOS passes drive number in DL - - GETDRIVEPARMS - - FINDFILE ; locate file in root directory - jc boot_error ; fail if not found - - GETFATCHAIN ; read FAT chain - LOADFILE ; load file (jumps to boot_sucess if successful) - -boot_error: mov cx, ERRMSGLEN - mov si, errmsg+7c00h - -next_char: lodsb ; print error message - mov ah, 0eh - xor bh, bh - int 10h - loop next_char - - xor ah, ah - int 16h ; wait for keystroke - int 19h ; invoke bootstrap loader - -boot_success: mov dl, drive - - db 0eah ; far jump to LOADSEG:0000 - dw 0 - dw LOADSEG - - -; readDisk: Reads a number of sectors into memory. -; -; Call with: DX:AX = 32-bit DOS sector number -; DI = number of sectors to read -; ES:BX = destination buffer -; ES must be 64k aligned (1000h, 2000h etc). -; -; Returns: CF set on error -; ES:BX points one byte after the last byte read. - -readDisk: - push si -read_next: push dx - push ax - - ; - ; translate sector number to BIOS parameters - ; - - ; - ; abs = sector offset in track - ; + head * sectPerTrack offset in cylinder - ; + track * sectPerTrack * nHeads offset in platter - ; - ; t1 = abs / sectPerTrack (ax has t1) - ; sector = abs mod sectPerTrack (cx has sector) - ; - div word sectPerTrack - mov cx, dx - - ; - ; t1 = head + track * nHeads - ; - ; track = t1 / nHeads (ax has track) - ; head = t1 mod nHeads (dl has head) - ; - xor dx, dx - div word nHeads - - ; the following manipulations are necessary in order to - ; properly place parameters into registers. - ; ch = cylinder number low 8 bits - ; cl = 7-6: cylinder high two bits - ; 5-0: sector - mov dh, dl ; save head into dh for bios - ror ah, 1 ; move track high bits into - ror ah, 1 ; bits 7-6 (assumes top = 0) - xchg al, ah ; swap for later - mov dl, byte sectPerTrack - sub dl, cl - inc cl ; sector offset from 1 - or cx, ax ; merge cylinder into sector - mov al, dl ; al has # of sectors left - - ; Calculate how many sectors can be transfered in this read - ; due to dma boundary conditions. - push dx - - mov si, di ; temp register save - ; this computes remaining bytes because of modulo 65536 - ; nature of dma boundary condition - mov ax, bx ; get offset pointer - neg ax ; and convert to bytes - jz ax_min_1 ; started at seg:0, skip ahead - - xor dx, dx ; convert to sectors - div word bytesPerSector - - cmp ax, di ; check remainder vs. asked - jb ax_min_1 ; less, skip ahead - mov si, ax ; transfer only what we can - -ax_min_1: pop dx - - ; Check that request sectors do not exceed track boundary - mov si, sectPerTrack - inc si - mov ax, cx ; get the sector/cyl byte - and ax, 03fh ; and mask out sector - sub si, ax ; si has how many we can read - mov ax, di - cmp si, di ; see if asked <= available - jge ax_min_2 - mov ax, si ; get what can be xfered - -ax_min_2: mov si, RETRYCOUNT - mov ah, 2 - mov dl, drive - -retry: push ax - int 13h - pop ax - jnc read_ok - push ax - xor ax, ax ; reset the drive - int 13h - pop ax - dec si - jnz retry - stc - pop ax - pop dx - pop si - ret - -read_next_jmp: jmp short read_next -read_ok: xor ah, ah - mov si, ax ; AX = SI = number of sectors read - mul word bytesPerSector ; AX = number of bytes read - add bx, ax ; add number of bytes read to BX - jnc no_incr_es ; if overflow... - - mov ax, es - add ah, 10h ; ...add 1000h to ES - mov es, ax - -no_incr_es: pop ax - pop dx ; DX:AX = last sector number - - add ax, si - adc dx, 0 ; DX:AX = next sector to read - sub di, si ; if there is anything left to read, - jg read_next_jmp ; continue - - clc - pop si - ret - -errmsg db "Boot error" -ERRMSGLEN equ $ - errmsg - - -;filename db "OSLDR BIN" -filename db "KERNEL BIN" - - TIMES 510-($-$$) DB 0 -sign dw 0aa55h - - diff --git a/loaders/boot/boot.inc b/loaders/boot/boot.inc deleted file mode 100644 index 0491007..0000000 --- a/loaders/boot/boot.inc +++ /dev/null @@ -1,196 +0,0 @@ -; To save space, functions that are just called once are -; implemented as macros instead. Four bytes are saved by -; avoiding the call / ret instructions. - - -; FINDFILE: Searches for the file in the root directory. -; -; Returns: -; -; If file not found: CF set -; -; If file found: CF clear -; AX = first cluster of file - - -%macro FINDFILE 0 - ; First, read the whole root directory - ; into the temporary buffer. - - mov ax, word root_dir_start - mov dx, word root_dir_start_hi - mov di, nRootDir - xor bx, bx - mov es, tempbuf - call readDisk - jc ffDone - - xor di, di - -next_entry: mov cx, 11 - mov si, filename+7c00h - push di - repe cmpsb - pop di - mov ax, [es:di+1ah] ; get cluster number from directory entry - clc - je ffDone - - add di, 20h ; go to next directory entry - cmp byte [es:di], 0 ; if the first byte of the name is 0, - jnz next_entry ; there is no more files in the directory - - stc -ffDone: -%endmacro - -; GETDRIVEPARMS: Calculate start of some disk areas. - -%macro GETDRIVEPARMS 0 - mov si, word nHidden - mov di, word nHidden_hi - add si, word resSectors - adc di, 0 ; DI:SI = first FAT sector - - mov word fat_start, si - mov word fat_start_hi, di - - mov al, nFats - xor ah, ah - mul word sectPerFat ; DX:AX = total number of FAT sectors - - add si, ax - adc di, dx ; DI:SI = first root directory sector - mov word root_dir_start, si - mov word root_dir_start_hi, di - - ; Calculate how many sectors the root directory occupies. - mov bx, bytesPerSector - mov cl, 5 ; divide BX by 32 - shr bx, cl ; BX = directory entries per sector - - mov ax, nRootDir - xor dx, dx - div bx - - mov nRootDir, ax ; AX = sectors per root directory - - add si, ax - adc di, 0 ; DI:SI = first data sector - - mov data_start, si - mov data_start_hi, di -%endmacro - -; GETFATCHAIN: -; -; Reads the FAT chain and stores it in a temporary buffer in the first -; 64 kb. The FAT chain is stored an array of 16-bit cluster numbers, -; ending with 0. -; -; The file must fit in conventional memory, so it can't be larger than -; 640 kb. The sector size must be at least 512 bytes, so the FAT chain -; can't be larger than around 3 kb. -; -; Call with: AX = first cluster in chain -; -; Returns: CF clear on success, set on error - -%macro GETFATCHAIN 0 - push ax ; store first cluster number - - ; Load the complete FAT into memory. The FAT can't be larger - ; than 128 kb, so it should fit in the temporary buffer. - - mov es, tempbuf - xor bx, bx - mov di, sectPerFat - mov ax, word fat_start - mov dx, word fat_start_hi - call readDisk - pop ax ; restore first cluster number - jc boot_error - - ; Set ES:DI to the temporary storage for the FAT chain. - push ds - push es - pop ds - pop es - mov di, FATBUF - -next_clust: stosw ; store cluster number - mov si, ax ; SI = cluster number - cmp byte extBoot, 29h - jne fat_12 - cmp byte [bp+filesys+4], '6' ; check for FAT-16 system - je fat_16 - - ; This is a FAT-12 disk. - -fat_12: add si, si ; multiply cluster number by 3... - add si, ax - shr si, 1 ; ...and divide by 2 - lodsw - - ; If the cluster number was even, the cluster value is now in - ; bits 0-11 of AX. If the cluster number was odd, the cluster - ; value is in bits 4-15, and must be shifted right 4 bits. If - ; the number was odd, CF was set in the last shift instruction. - - jnc fat_even - mov cl, 4 - shr ax, cl ; shift the cluster number - -fat_even: and ah, 0fh ; mask off the highest 4 bits - cmp ax, 0fffh ; check for EOF - jmp short next_test - - ; This is a FAT-16 disk. The maximal size of a 16-bit FAT - ; is 128 kb, so it may not fit within a single 64 kb segment. - -fat_16: mov dx, tempbuf - add si, si ; multiply cluster number by two - jnc first_half ; if overflow... - add dh, 10h ; ...add 64 kb to segment value - -first_half: mov ds, dx ; DS:SI = pointer to next cluster - lodsw ; AX = next cluster - - cmp ax, 0fff8h ; >= FFF8 = 16-bit EOF -next_test: jb next_clust ; continue if not EOF - -finished: ; Mark end of FAT chain with 0, so we have a single - ; EOF marker for both FAT-12 and FAT-16 systems. - - xor ax, ax - stosw -fatError: -%endmacro - - -; loadFile: Loads the file into memory, one cluster at a time. - -%macro LOADFILE 0 - mov es, tempbuf ; set ES:BX to load address - xor bx, bx - - mov si, FATBUF ; set DS:SI to the FAT chain - push cs - pop ds - -next_cluster: lodsw ; AX = next cluster to read - or ax, ax ; if EOF... - je boot_success ; ...boot was successful - - dec ax ; cluster numbers start with 2 - dec ax - - mov di, word sectPerCluster - and di, 0ffh ; DI = sectors per cluster - mul di - add ax, data_start - adc dx, data_start_hi ; DX:AX = first sector to read - call readDisk - jnc next_cluster - -%endmacro diff --git a/loaders/boot/boot.mak b/loaders/boot/boot.mak deleted file mode 100644 index 9dbd842..0000000 --- a/loaders/boot/boot.mak +++ /dev/null @@ -1,77 +0,0 @@ -# -# makefile for DOS-C boot -# -# $Header$ -# -# $Log$ -# Revision 1.4 2003/02/12 22:32:53 short -# update for HEAD-2003021201 -# -# Revision 1.4 2000/06/25 03:59:14 dwelch -# -# Removed from redundant files from the mm directory -# Added some preliminary work on the pager -# Fixed ntoskrnl/mm/npool.c (This may have been the cause of the -# problems reported with loading win32k.sys) -# Fixed problems with reporting space used to store physical page -# information -# Added code to support MmSafeCopy{To/From}User interface work -# (untested) -# Added Event member of the PHYSICAL_PAGE structure to implement Philip -# Susi's suggestion -# Reworked section page-in code (not really tested) -# Replaced inline string functions with gcc builtins to make debugging easier -# -# Revision 1.3 1998/08/25 04:39:40 rex -# Release cleanup -# -# Revision 1.1.1.2 1998/08/25 04:27:38 rex -# A much Needed Update -# -# -# Rev 1.3 10 Jan 1997 4:51:54 patv -#Changed to use FreeDOS exe2bin and support new boot code -# -# Rev 1.2 17 Dec 1996 12:52:32 patv -#Converted to FreeDOS exe2bin. -#. -#d -# -# Rev 1.1 29 Aug 1996 13:06:50 patv -#Bug fixes for v0.91b -# -# Rev 1.0 02 Jul 1995 9:11:26 patv -#Initial revision. -# - -# -# Uncomment the following for a debug version -# -#AFLAGS = /zi /DDEBUG -#LFLAGS = /v - -PRODUCT = boot.bin - -all: $(PRODUCT) - -production: all - copy boot.bin ..\..\dist\boot.bin - del *.bin - del *.map - -boot.bin: boot.asm - tasm $(AFLAGS) boot,, - tlink $(LFLAGS) boot - ..\utils\exe2bin boot boot.bin - del boot.obj - del boot.exe - -clean: - del *.lst - del *.map - del *.bin - del *.bak - del *.las - del *.obj - del *.exe - diff --git a/loaders/boot/bootbk.asm b/loaders/boot/bootbk.asm deleted file mode 100644 index d73d1a9..0000000 --- a/loaders/boot/bootbk.asm +++ /dev/null @@ -1,313 +0,0 @@ -; -; File: -; boot.asm -; Description: -; DOS-C boot -; -; Copyright (c) 1997; -; Svante Frey -; All Rights Reserved -; -; This file is part of DOS-C. -; -; DOS-C 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. -; -; DOS-C 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 DOS-C; see the file COPYING. If not, -; write to the Free Software Foundation, 675 Mass Ave, -; Cambridge, MA 02139, USA. -; -; $Logfile: C:/dos-c/src/boot/boot.asv $ -; -; $Header$ -; -; $Log$ -; Revision 1.4 2003/02/12 22:32:53 short -; update for HEAD-2003021201 -; -; Revision 1.4 2000/06/25 03:59:14 dwelch -; -; Removed from redundant files from the mm directory -; Added some preliminary work on the pager -; Fixed ntoskrnl/mm/npool.c (This may have been the cause of the -; problems reported with loading win32k.sys) -; Fixed problems with reporting space used to store physical page -; information -; Added code to support MmSafeCopy{To/From}User interface work -; (untested) -; Added Event member of the PHYSICAL_PAGE structure to implement Philip -; Susi's suggestion -; Reworked section page-in code (not really tested) -; Replaced inline string functions with gcc builtins to make debugging easier -; -; Revision 1.3 1998/08/25 04:40:47 rex -; Release cleanup -; -; Revision 1.1.1.2 1998/08/25 04:27:38 rex -; A much Needed Update -; -; -; Rev 1.5 10 Jan 1997 4:58:06 patv -; Corrected copyright -; -; Rev 1.4 10 Jan 1997 4:52:50 patv -; Re-written to support C drive and eliminate restrictions on IPL.SYS -; -; Rev 1.3 29 Aug 1996 13:06:50 patv -; Bug fixes for v0.91b -; -; Rev 1.2 01 Sep 1995 17:56:44 patv -; First GPL release. -; -; Rev 1.1 30 Jul 1995 20:37:38 patv -; Initialized stack before use. -; -; Rev 1.0 02 Jul 1995 10:57:52 patv -; Initial revision. -; - -.text - -BASE equ 0 - - - org BASE -Entry: jmp real_start - -; bp is initialized to 7c00h -oem equ [bp+3] -bytesPerSector equ [bp+0bh] -sectPerCluster equ [bp+0dh] -resSectors equ [bp+0eh] -nFats equ [bp+10h] -nRootDir equ [bp+11h] -nSectors equ [bp+13h] -MID equ [bp+15h] -sectPerFat equ [bp+16h] -sectPerTrack equ [bp+18h] -nHeads equ [bp+1ah] -nHidden equ [bp+1ch] -nSectorHuge equ [bp+20h] -drive equ [bp+24h] -extBoot equ [bp+26h] -volid equ [bp+27h] -vollabel equ [bp+2bh] -filesys equ [bp+36h] - -LOADSEG equ 2000h - -FATBUF equ 4000h ; offset of temporary buffer for FAT - ; chain -RETRYCOUNT equ 5 ; number of retries on disk errors - -; Some extra variables that are created on the stack frame - -fat_start equ [bp-4] ; first FAT sector -root_dir_start equ [bp-8] ; first root directory sector -data_start equ [bp-12] ; first data sector - - -; -; Include macros for filesystem access -; -include boot.inc - -; -; -; - org BASE+3eh - -tempbuf equ [bp+3eh] -load_seg dw LOADSEG - -real_start: cli - cld - mov ax, cs - mov ss, ax ; initialize stack - mov bp, 7c00h - lea sp, [bp-20h] - sti - - mov es, ax - mov ds, ax - mov drive, dl ; BIOS passes drive number in DL - - GETDRIVEPARMS - - FINDFILE ; locate file in root directory - jc boot_error ; fail if not found - - GETFATCHAIN ; read FAT chain - LOADFILE ; load file (jumps to boot_sucess if successful) - -boot_error: mov cx, ERRMSGLEN - mov si, offset errmsg+7c00h - -next_char: lodsb ; print error message - mov ah, 0eh - xor bh, bh - int 10h - loop next_char - - xor ah, ah - int 16h ; wait for keystroke - int 19h ; invoke bootstrap loader - -boot_success: mov dl, drive - - db 0eah ; far jump to LOADSEG:0000 - dw 0 - dw LOADSEG - - -; readDisk: Reads a number of sectors into memory. -; -; Call with: DX:AX = 32-bit DOS sector number -; DI = number of sectors to read -; ES:BX = destination buffer -; ES must be 64k aligned (1000h, 2000h etc). -; -; Returns: CF set on error -; ES:BX points one byte after the last byte read. - -readDisk proc - push si -read_next: push dx - push ax - - ; - ; translate sector number to BIOS parameters - ; - - ; - ; abs = sector offset in track - ; + head * sectPerTrack offset in cylinder - ; + track * sectPerTrack * nHeads offset in platter - ; - ; t1 = abs / sectPerTrack (ax has t1) - ; sector = abs mod sectPerTrack (cx has sector) - ; - div word ptr sectPerTrack - mov cx, dx - - ; - ; t1 = head + track * nHeads - ; - ; track = t1 / nHeads (ax has track) - ; head = t1 mod nHeads (dl has head) - ; - xor dx, dx - div word ptr nHeads - - ; the following manipulations are necessary in order to - ; properly place parameters into registers. - ; ch = cylinder number low 8 bits - ; cl = 7-6: cylinder high two bits - ; 5-0: sector - mov dh, dl ; save head into dh for bios - ror ah, 1 ; move track high bits into - ror ah, 1 ; bits 7-6 (assumes top = 0) - xchg al, ah ; swap for later - mov dl, byte ptr sectPerTrack - sub dl, cl - inc cl ; sector offset from 1 - or cx, ax ; merge cylinder into sector - mov al, dl ; al has # of sectors left - - ; Calculate how many sectors can be transfered in this read - ; due to dma boundary conditions. - push dx - - mov si, di ; temp register save - ; this computes remaining bytes because of modulo 65536 - ; nature of dma boundary condition - mov ax, bx ; get offset pointer - neg ax ; and convert to bytes - jz ax_min_1 ; started at seg:0, skip ahead - - xor dx, dx ; convert to sectors - div word ptr bytesPerSector - - cmp ax, di ; check remainder vs. asked - jb ax_min_1 ; less, skip ahead - mov si, ax ; transfer only what we can - -ax_min_1: pop dx - - ; Check that request sectors do not exceed track boundary - mov si, sectPerTrack - inc si - mov ax, cx ; get the sector/cyl byte - and ax, 03fh ; and mask out sector - sub si, ax ; si has how many we can read - mov ax, di - cmp si, di ; see if asked <= available - jge ax_min_2 - mov ax, si ; get what can be xfered - -ax_min_2: mov si, RETRYCOUNT - mov ah, 2 - mov dl, drive - -retry: push ax - int 13h - pop ax - jnc read_ok - push ax - xor ax, ax ; reset the drive - int 13h - pop ax - dec si - jnz retry - stc - pop ax - pop dx - pop si - ret - -read_next_jmp: jmp short read_next -read_ok: xor ah, ah - mov si, ax ; AX = SI = number of sectors read - mul word ptr bytesPerSector ; AX = number of bytes read - add bx, ax ; add number of bytes read to BX - jnc no_incr_es ; if overflow... - - mov ax, es - add ah, 10h ; ...add 1000h to ES - mov es, ax - -no_incr_es: pop ax - pop dx ; DX:AX = last sector number - - add ax, si - adc dx, 0 ; DX:AX = next sector to read - sub di, si ; if there is anything left to read, - jg read_next_jmp ; continue - - clc - pop si - ret -readDisk endp - -errmsg db "Boot error" -ERRMSGLEN equ $ - errmsg - - -;filename db "OSLDR BIN" -filename db "KERNEL BIN" - - org BASE+01feh -sign dw 0aa55h - -TEXT ENDS - end - - diff --git a/loaders/boot/osldr.asm b/loaders/boot/osldr.asm deleted file mode 100644 index 0915d18..0000000 --- a/loaders/boot/osldr.asm +++ /dev/null @@ -1,340 +0,0 @@ -; -; Loads the kernel and any required modules -; - -org 0 - -; -; Segment where we are loaded -; -LOADSEG equ 02000h - -; -; Segment used for temporay storage -; -WORKSEG equ 01000h - - -KERNELBASE equ 05000h - -; -; Offsets of work areas -; -FAT_CHAIN equ 0h - -DIR_BUFFER equ 4000h -END_DIR_BUFFER equ 0ffe0h - -FAT_SEG equ 03000h - - -; -; These are all on the stack -; -%define oem [bp+3] -%define bytesPerSector [bp+0bh] -%define sectPerCluster [bp+0dh] -%define resSectors [bp+0eh] -%define nFats [bp+10h] -%define nRootDir [bp+11h] -%define nSectors [bp+13h] -%define MID [bp+15h] -%define sectPerFat [bp+16h] -%define sectPerTrack [bp+18h] -%define nHeads [bp+1ah] -%define nHidden [bp+1ch] -%define nHidden_hi [bp+1eh] -%define nSectorHuge [bp+20h] -%define drive [bp+24h] -%define extBoot [bp+26h] -%define volid [bp+27h] -%define vollabel [bp+2bh] -%define filesys 36h - -RETRYCOUNT equ 5 - -%define fat_start [bp-4] ; first FAT sector -%define fat_start_hi [bp-2] -%define root_dir_start [bp-8] ; first root directory sector -%define root_dir_start_hi [bp-6] -%define data_start [bp-12] ; first data sector -%define data_start_hi [bp-10] - - -entry: - mov drive,dl - - mov ax,LOADSEG - mov ds,ax - - - ; - ; Print out a message - ; - mov di,loadmsg - call printmsg - - - ; - ; Check here for shift pressed and if so display boot menu - ; - - ; - ; Load the entire fat - ; -; mov ax,fat_start -; mov dx,fat_start_hi -; mov di,sectPerFat -; mov ax,FAT_SEG -; mov es,ax -; mov bx,0 -; call readDisk - - - ; - ; Load root directory - ; - mov ax,WORKSEG - mov es,ax - - mov dx,root_dir_start_hi - mov ax,root_dir_start - mov bx,DIR_BUFFER - mov di,nRootDir - shr di,4 - mov di,1 - call readDisk - jc disk_error - - ; - ; Look for a directory called boot - ; - mov di,DIR_BUFFER - cld - mov cx,4 -l1: - mov si,boot_dir_name -; cmp byte [di],0 -; je boot_error - repe cmpsb - je found_it - or di,31 - inc di - cmp di,END_DIR_BUFFER - jge boot_error - jmp l1 - - -boot_error: - mov di,errormsg - call printmsg -l3: - jmp l3 - -disk_error: - mov di,errormsg1 - call printmsg - jmp l3 - - - -found_it: - mov di,msg1 - call printmsg - - ; - ; Load the boot directory found above - ; - sub di,4 - call readFile - -l2: - jmp l2 - -; -; readFile -; -%define file_length [di+01ch] -%define start_cluster [di+01ah] -readFile: - cmp byte extBoot, 29h - jne fat_12 - cmp byte [bp+filesys+4], '6' ; check for FAT-16 system - je fat_16 - -fat_12: - mov di,msg2 - call printmsg -l4: - jmp l4 - -fat_16: - mov di,msg3 - call printmsg - jmp l4 - - - -; readDisk: Reads a number of sectors into memory. -; -; Call with: DX:AX = 32-bit DOS sector number -; DI = number of sectors to read -; ES:BX = destination buffer -; ES must be 64k aligned (1000h, 2000h etc). -; -; Returns: CF set on error -; ES:BX points one byte after the last byte read. - -readDisk: - push bp - push si -read_next: push dx - push ax - - ; - ; translate sector number to BIOS parameters - ; - - ; - ; abs = sector offset in track - ; + head * sectPerTrack offset in cylinder - ; + track * sectPerTrack * nHeads offset in platter - ; - ; t1 = abs / sectPerTrack (ax has t1) - ; sector = abs mod sectPerTrack (cx has sector) - ; - div word sectPerTrack - mov cx, dx - - ; - ; t1 = head + track * nHeads - ; - ; track = t1 / nHeads (ax has track) - ; head = t1 mod nHeads (dl has head) - ; - xor dx, dx - div word nHeads - - ; the following manipulations are necessary in order to - ; properly place parameters into registers. - ; ch = cylinder number low 8 bits - ; cl = 7-6: cylinder high two bits - ; 5-0: sector - mov dh, dl ; save head into dh for bios - ror ah, 1 ; move track high bits into - ror ah, 1 ; bits 7-6 (assumes top = 0) - xchg al, ah ; swap for later - mov dl, byte sectPerTrack - sub dl, cl - inc cl ; sector offset from 1 - or cx, ax ; merge cylinder into sector - mov al, dl ; al has # of sectors left - - ; Calculate how many sectors can be transfered in this read - ; due to dma boundary conditions. - push dx - - mov si, di ; temp register save - ; this computes remaining bytes because of modulo 65536 - ; nature of dma boundary condition - mov ax, bx ; get offset pointer - neg ax ; and convert to bytes - jz ax_min_1 ; started at seg:0, skip ahead - - xor dx, dx ; convert to sectors - div word bytesPerSector - - cmp ax, di ; check remainder vs. asked - jb ax_min_1 ; less, skip ahead - mov si, ax ; transfer only what we can - -ax_min_1: pop dx - - ; Check that request sectors do not exceed track boundary - mov si, sectPerTrack - inc si - mov ax, cx ; get the sector/cyl byte - and ax, 03fh ; and mask out sector - sub si, ax ; si has how many we can read - mov ax, di - cmp si, di ; see if asked <= available - jge ax_min_2 - mov ax, si ; get what can be xfered - -ax_min_2: mov si, RETRYCOUNT - mov ah, 2 - mov dl, drive - -retry: push ax - int 13h - pop ax - jnc read_ok - push ax - xor ax, ax ; reset the drive - int 13h - pop ax - dec si - jnz retry - stc - pop ax - pop dx - pop si - pop bp - ret - -read_next_jmp: jmp short read_next -read_ok: xor ah, ah - mov si, ax ; AX = SI = number of sectors read - mul word bytesPerSector ; AX = number of bytes read - add bx, ax ; add number of bytes read to BX - jnc no_incr_es ; if overflow... - - mov ax, es - add ah, 10h ; ...add 1000h to ES - mov es, ax - -no_incr_es: pop ax - pop dx ; DX:AX = last sector number - - add ax, si - adc dx, 0 ; DX:AX = next sector to read - sub di, si ; if there is anything left to read, - jg read_next_jmp ; continue - - clc - pop si - pop bp - ret - -; -; Print string (DI = start) -; -printmsg: - push ax - push bx - push di - mov ah,0eh - mov bh,0 - mov bl,07h -.l1 - mov al,[di] - cmp al,0 - je .l2 - inc di - int 10h - jmp .l1 -.l2 - pop di - pop bx - pop ax - ret - - - -loadmsg db "Starting ReactOS...",0xd,0xa,0 -boot_dir_name db 'BOOT' -errormsg db "Files missing on boot disk",0 -errormsg1 db "Disk read error",0 -msg1 db "Found boot directory",0xd,0xa,0 -msg2 db 'FAT12',0 -msg3 db 'FAT16',0 diff --git a/loaders/boot/osldr.txt b/loaders/boot/osldr.txt deleted file mode 100644 index 8ef4f0d..0000000 --- a/loaders/boot/osldr.txt +++ /dev/null @@ -1,12 +0,0 @@ -Mem layout for osldr - -0000 - 07C0 = BIOS data and stack -07C0 - 1000 = Boot sector -1000 - 1400 = Tempory storage for fat chains -1400 - 2000 = Tempory storage for directory entries -2000 - 3000 = OSLDR -3000 - 5000 = FAT -5000 - a000 = Kernel and modules load area - - - diff --git a/loaders/dos/loadros.asm b/loaders/dos/loadros.asm index 720b050..5fc2984 100644 --- a/loaders/dos/loadros.asm +++ b/loaders/dos/loadros.asm @@ -256,6 +256,20 @@ entry: push di mov dx, di + ; Check if it is a binary hive file + cmp byte [bx-5],'.' + je .checkForSymbol + cmp byte [bx-4],'.' + je .checkForSymbol + cmp byte [bx-3],'.' + je .checkForSymbol + cmp byte [bx-2],'.' + je .checkForSymbol + + call sym_load_module + jmp .after_copy + +.checkForSymbol: ; Check if it is a symbol file cmp byte [bx-5],'.' jne .checkForHive @@ -270,7 +284,7 @@ entry: jmp .after_copy .checkForHive: - ; Check if it is a symbol file + ; Check if it is a hive file cmp byte [bx-5],'.' jne .lst_copy cmp byte [bx-4],'h' diff --git a/ntoskrnl/Makefile b/ntoskrnl/Makefile index e89e6b9..6e719f3 100644 --- a/ntoskrnl/Makefile +++ b/ntoskrnl/Makefile @@ -215,7 +215,8 @@ OBJECTS_OB = \ ob/namespc.o \ ob/ntobj.o \ ob/object.o \ - ob/security.o + ob/security.o \ + ob/symlink.o # Process Manager (Ps) OBJECTS_PS = \ @@ -518,6 +519,7 @@ $(TARGETNAME).nostrip.exe: $(TARGETNAME).o $(IE_DATA) -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,--base-file,base.tmp \ $(TARGETNAME).o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -539,6 +541,7 @@ $(TARGETNAME).nostrip.exe: $(TARGETNAME).o $(IE_DATA) -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,temp.exp \ $(TARGETNAME).o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -555,6 +558,7 @@ $(TARGETNAME).exe: $(TARGETNAME).o $(LINKER_SCRIPT) $(DDK_PATH_LIB)/hal.a -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,--base-file,base.tmp \ $(TARGETNAME).o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -576,6 +580,7 @@ $(TARGETNAME).exe: $(TARGETNAME).o $(LINKER_SCRIPT) $(DDK_PATH_LIB)/hal.a -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,temp.exp \ $(TARGETNAME).o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -595,6 +600,7 @@ $(TARGETNAME).dbg: $(TARGETNAME).dbg.o $(TARGETNAME).a $(TARGETNAME).dbg.lnk -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,--base-file,base.tmp \ $(TARGETNAME).dbg.o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -616,6 +622,7 @@ $(TARGETNAME).dbg: $(TARGETNAME).dbg.o $(TARGETNAME).a $(TARGETNAME).dbg.lnk -Wl,--image-base,0xc0000000 \ -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ + -Wl,--entry,_NtProcessStartup \ -Wl,temp.exp \ $(TARGETNAME).dbg.o -lgcc \ $(DDK_PATH_LIB)/hal.a @@ -663,6 +670,15 @@ clean: .PHONY: clean +ifneq ($(BOOTCD_INSTALL),) + +install: all $(INSTALL_DIR)/$(TARGETNAME).exe + +$(INSTALL_DIR)/$(TARGETNAME).exe: $(TARGETNAME).exe + $(CP) $(TARGETNAME).exe $(INSTALL_DIR)/$(TARGETNAME).exe + +else # BOOTCD_INSTALL + install: all $(INSTALL_DIR)/system32/$(TARGETNAME).exe $(INSTALL_DIR)/symbols/$(TARGETNAME).sym $(INSTALL_DIR)/system32/$(TARGETNAME).exe: $(TARGETNAME).exe @@ -671,6 +687,9 @@ $(INSTALL_DIR)/system32/$(TARGETNAME).exe: $(TARGETNAME).exe $(INSTALL_DIR)/symbols/$(TARGETNAME).sym: $(TARGETNAME).sym $(CP) $(TARGETNAME).sym $(INSTALL_DIR)/symbols/$(TARGETNAME).sym +endif # BOOTCD_INSTALL + + .PHONY: install dist: $(DIST_DIR)/$(TARGETNAME).exe @@ -680,6 +699,14 @@ $(DIST_DIR)/$(TARGETNAME).exe: $(TARGETNAME).exe .PHONY: dist +bootcd: all $(BOOTCD_DIR)/reactos/$(TARGETNAME).exe + +$(BOOTCD_DIR)/reactos/$(TARGETNAME).exe: $(TARGETNAME).exe + $(CP) $(TARGETNAME).exe $(BOOTCD_DIR)/reactos/$(TARGETNAME).exe + +.PHONY: bootcd + + ex/napi.o: ex/napi.c $(PATH_TO_TOP)/include/ntdll/napi.h ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h diff --git a/ntoskrnl/cc/copy.c b/ntoskrnl/cc/copy.c index 158c160..f0685bb 100644 --- a/ntoskrnl/cc/copy.c +++ b/ntoskrnl/cc/copy.c @@ -234,7 +234,7 @@ WriteCacheSegment(PCACHE_SEGMENT CacheSeg) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatus.Status; } - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) { DPRINT1("IoPageWrite failed, Status %x\n", Status); CacheSeg->Dirty = TRUE; @@ -268,7 +268,7 @@ CcCopyRead (IN PFILE_OBJECT FileObject, FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, Buffer, IoStatus); - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; ReadOffset = FileOffset->QuadPart; DPRINT("AllocationSize %d, FileSize %d\n", @@ -369,7 +369,7 @@ CcCopyWrite (IN PFILE_OBJECT FileObject, "Length %d, Wait %d, Buffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart, Length, Wait, Buffer); - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; WriteOffset = (ULONG)FileOffset->QuadPart; if (!Wait) @@ -472,9 +472,6 @@ CcZeroData (IN PFILE_OBJECT FileObject, Length = EndOffset->u.LowPart - StartOffset->u.LowPart; - /* - * FIXME: NT uses the shared cache map field for cached/non cached detection - */ if (FileObject->SectionObjectPointers->SharedCacheMap == NULL) { /* File is not cached */ @@ -535,7 +532,7 @@ CcZeroData (IN PFILE_OBJECT FileObject, PHYSICAL_ADDRESS page; Start = StartOffset->u.LowPart; - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; if (Wait) { /* testing, if the requested datas are available */ diff --git a/ntoskrnl/cc/misc.c b/ntoskrnl/cc/misc.c index 0fbbbb9..c677581 100644 --- a/ntoskrnl/cc/misc.c +++ b/ntoskrnl/cc/misc.c @@ -13,6 +13,14 @@ /* GLOBALS *******************************************************************/ +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) +#define ROUND_DOWN(N, S) (((N) % (S)) ? ROUND_UP(N, S) - S : N) + +extern FAST_MUTEX ViewLock; +extern ULONG DirtyPageCount; + +NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); + /* FUNCTIONS *****************************************************************/ /********************************************************************** @@ -73,6 +81,8 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, PBCB Bcb; PLIST_ENTRY current_entry; PCACHE_SEGMENT current; + LIST_ENTRY FreeListHead; + NTSTATUS Status; DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n", FileObject, FileSizes); @@ -81,31 +91,66 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, (ULONG)FileSizes->FileSize.QuadPart, (ULONG)FileSizes->ValidDataLength.QuadPart); - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; - - DPRINT("Bcb 0x%.08x\n", Bcb); - - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; + assert(Bcb); + if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart) - { - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) - { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - current_entry = current_entry->Flink; - if (current->FileOffset > FileSizes->AllocationSize.QuadPart) - { - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - CcRosFreeCacheSegment(Bcb, current); - KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); - current_entry = Bcb->BcbSegmentListHead.Flink; - } - } - } - Bcb->AllocationSize = FileSizes->AllocationSize; - Bcb->FileSize = FileSizes->FileSize; - KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + { + InitializeListHead(&FreeListHead); + ExAcquireFastMutex(&ViewLock); + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + if (current->FileOffset > FileSizes->AllocationSize.QuadPart) + { + if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty)) + { + RemoveEntryList(¤t->BcbSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentListEntry); + RemoveEntryList(¤t->CacheSegmentLRUListEntry); + if (current->Dirty) + { + RemoveEntryList(¤t->DirtySegmentListEntry); + DirtyPageCount -= Bcb->CacheSegmentSize / PAGE_SIZE; + } + InsertHeadList(&FreeListHead, ¤t->BcbSegmentListEntry); + } + else + { + DPRINT1("Anyone has referenced a cache segment behind the new size.\n"); + KeBugCheck(0); + } + } + } + + Bcb->AllocationSize = FileSizes->AllocationSize; + Bcb->FileSize = FileSizes->FileSize; + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + ExReleaseFastMutex(&ViewLock); + + current_entry = FreeListHead.Flink; + while(current_entry != &FreeListHead) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); + current_entry = current_entry->Flink; + Status = CcRosInternalFreeCacheSegment(current); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CcRosInternalFreeCacheSegment failed, status = %x\n"); + KeBugCheck(0); + } + } + } + else + { + KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); + Bcb->AllocationSize = FileSizes->AllocationSize; + Bcb->FileSize = FileSizes->FileSize; + KeReleaseSpinLock(&Bcb->BcbLock, oldirql); + } } diff --git a/ntoskrnl/cc/pin.c b/ntoskrnl/cc/pin.c index 1df84da..5eb8899 100644 --- a/ntoskrnl/cc/pin.c +++ b/ntoskrnl/cc/pin.c @@ -51,7 +51,7 @@ CcMapData (IN PFILE_OBJECT FileObject, Length, Wait, pBcb, pBuffer); ReadOffset = FileOffset->QuadPart; - Bcb = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->Bcb; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; assert(Bcb); DPRINT("AllocationSize %d, FileSize %d\n", diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 8a346f3..be8e239 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -82,9 +82,9 @@ static LIST_ENTRY DirtySegmentListHead; static LIST_ENTRY CacheSegmentListHead; static LIST_ENTRY CacheSegmentLRUListHead; static LIST_ENTRY ClosedListHead; -static ULONG DirtyPageCount=0; +ULONG DirtyPageCount=0; -static FAST_MUTEX ViewLock; +FAST_MUTEX ViewLock; #ifdef CACHE_BITMAP #define CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024) @@ -197,7 +197,7 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count) PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE; Status = CcRosFlushCacheSegment(current); ExReleaseFastMutex(¤t->Lock); - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) { DPRINT1("CC: Failed to flush cache segment.\n"); } @@ -994,18 +994,19 @@ VOID CcRosDereferenceCache(PFILE_OBJECT FileObject) } NTSTATUS STDCALL -CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb) +CcRosReleaseFileCache(PFILE_OBJECT FileObject) /* * FUNCTION: Called by the file system when a handle to a file object * has been closed. */ { - assert(Bcb); + PBCB Bcb; ExAcquireFastMutex(&ViewLock); if (FileObject->SectionObjectPointers->SharedCacheMap != NULL) { + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; if (FileObject->PrivateCacheMap != NULL) { FileObject->PrivateCacheMap = NULL; @@ -1033,52 +1034,53 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb) NTSTATUS STDCALL CcRosInitializeFileCache(PFILE_OBJECT FileObject, - PBCB* Bcb, ULONG CacheSegmentSize) /* * FUNCTION: Initializes a BCB for a file object */ { + PBCB Bcb; DPRINT("CcRosInitializeFileCache(FileObject %x, *Bcb %x, CacheSegmentSize %d)\n", FileObject, Bcb, CacheSegmentSize); ExAcquireFastMutex(&ViewLock); - if (*Bcb == NULL) + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; + if (Bcb == NULL) { - (*Bcb) = ExAllocateFromNPagedLookasideList(&BcbLookasideList); - if ((*Bcb) == NULL) + Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList); + if (Bcb == NULL) { ExReleaseFastMutex(&ViewLock); return(STATUS_UNSUCCESSFUL); } - memset((*Bcb), 0, sizeof(BCB)); + memset(Bcb, 0, sizeof(BCB)); ObReferenceObjectByPointer(FileObject, FILE_ALL_ACCESS, NULL, KernelMode); - (*Bcb)->FileObject = FileObject; - (*Bcb)->CacheSegmentSize = CacheSegmentSize; + Bcb->FileObject = FileObject; + Bcb->CacheSegmentSize = CacheSegmentSize; if (FileObject->FsContext) { - (*Bcb)->AllocationSize = + Bcb->AllocationSize = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->AllocationSize; - (*Bcb)->FileSize = + Bcb->FileSize = ((REACTOS_COMMON_FCB_HEADER*)FileObject->FsContext)->FileSize; } - KeInitializeSpinLock(&(*Bcb)->BcbLock); - InitializeListHead(&(*Bcb)->BcbSegmentListHead); - FileObject->SectionObjectPointers->SharedCacheMap = *Bcb; + KeInitializeSpinLock(&Bcb->BcbLock); + InitializeListHead(&Bcb->BcbSegmentListHead); + FileObject->SectionObjectPointers->SharedCacheMap = Bcb; } if (FileObject->PrivateCacheMap == NULL) { - FileObject->PrivateCacheMap = *Bcb; - (*Bcb)->RefCount++; + FileObject->PrivateCacheMap = Bcb; + Bcb->RefCount++; } - if ((*Bcb)->BcbRemoveListEntry.Flink != NULL) + if (Bcb->BcbRemoveListEntry.Flink != NULL) { - RemoveEntryList(&(*Bcb)->BcbRemoveListEntry); - (*Bcb)->BcbRemoveListEntry.Flink = NULL; + RemoveEntryList(&Bcb->BcbRemoveListEntry); + Bcb->BcbRemoveListEntry.Flink = NULL; } ExReleaseFastMutex(&ViewLock); diff --git a/ntoskrnl/cm/cm.h b/ntoskrnl/cm/cm.h index 394d5c4..69f6866 100644 --- a/ntoskrnl/cm/cm.h +++ b/ntoskrnl/cm/cm.h @@ -21,6 +21,7 @@ #define REG_USERS_KEY_NAME L"\\Registry\\User" #define REG_USER_KEY_NAME L"\\Registry\\User\\CurrentUser" #define SYSTEM_REG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM" +#define SYSTEM_LOG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM.log" #define SOFTWARE_REG_FILE L"\\SystemRoot\\System32\\Config\\SOFTWARE" #define USER_REG_FILE L"\\SystemRoot\\System32\\Config\\DEFAULT" #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM" @@ -63,11 +64,11 @@ typedef struct _HIVE_HEADER /* Hive identifier "regf" (0x66676572) */ ULONG BlockId; - /* File version ? */ - ULONG Version; + /* Update counter */ + ULONG UpdateCounter1; - /* File version ? - same as Version */ - ULONG VersionOld; + /* Update counter */ + ULONG UpdateCounter2; /* When this hive file was last modified */ FILETIME DateModified; @@ -241,33 +242,38 @@ typedef struct _DATA_CELL typedef struct _REGISTRY_HIVE { - LIST_ENTRY HiveList; + LIST_ENTRY HiveList; ULONG Flags; - UNICODE_STRING Filename; + UNICODE_STRING HiveFileName; + UNICODE_STRING LogFileName; ULONG FileSize; - PFILE_OBJECT FileObject; - PVOID Bcb; PHIVE_HEADER HiveHeader; + ULONG UpdateCounter; ULONG BlockListSize; PHBIN *BlockList; ULONG FreeListSize; ULONG FreeListMax; PCELL_HEADER *FreeList; BLOCK_OFFSET *FreeListOffset; - ERESOURCE HiveResource; + ERESOURCE HiveResource; - RTL_BITMAP DirtyBitMap; - BOOLEAN HiveDirty; - -// NTSTATUS (*Extend)(ULONG NewSize); -// PVOID (*Flush)(VOID); + PULONG BitmapBuffer; + RTL_BITMAP DirtyBitMap; + BOOLEAN HiveDirty; } REGISTRY_HIVE, *PREGISTRY_HIVE; /* REGISTRY_HIVE.Flags constants */ +/* When set, the hive is volatile. It will not be sync'ed to disk. */ #define HIVE_VOLATILE 0x00000001 +/* When set, the hive uses pointers instead of offsets. */ +#define HIVE_POINTER 0x00000002 +/* When set, the hive is temporary. It will not be sync'ed to disk. */ +#define HIVE_TEMPORARY 0x00000004 #define IsVolatileHive(Hive)(Hive->Flags & HIVE_VOLATILE) -#define IsPermanentHive(Hive)(!(Hive->Flags & HIVE_VOLATILE)) +#define IsPointerHive(Hive)(Hive->Flags & HIVE_POINTER) +#define IsTemporaryHive(Hive)(Hive->Flags & HIVE_TEMPORARY) + #define IsFreeCell(Cell)(Cell->CellSize >= 0) #define IsUsedCell(Cell)(Cell->CellSize < 0) @@ -375,11 +381,18 @@ NTSTATUS STDCALL CmiObjectCreate(PVOID ObjectBody, PVOID Parent, PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes); + POBJECT_ATTRIBUTES ObjectAttributes); VOID STDCALL CmiObjectDelete(PVOID DeletedObject); +NTSTATUS STDCALL +CmiObjectSecurity(PVOID ObjectBody, + SECURITY_OPERATION_CODE OperationCode, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR SecurityDescriptor, + PULONG BufferLength); + VOID CmiAddKeyToList(PKEY_OBJECT ParentKey, IN PKEY_OBJECT NewKey); @@ -518,24 +531,25 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive, OUT PHBIN * ppBin); VOID -CmiLockBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block); - -VOID -CmiReleaseBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block); - -VOID CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, BLOCK_OFFSET BlockOffset); +VOID +CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive, + BLOCK_OFFSET BinOffset); + NTSTATUS CmiAddFree(PREGISTRY_HIVE RegistryHive, - PCELL_HEADER FreeBlock, - BLOCK_OFFSET FreeOffset); + PCELL_HEADER FreeBlock, + BLOCK_OFFSET FreeOffset, + BOOLEAN MergeFreeBlocks); + +NTSTATUS +CmiConnectHive(PREGISTRY_HIVE RegistryHive, + PUNICODE_STRING KeyName); NTSTATUS -CmiInitHives(BOOLEAN SetUpBoot); +CmiInitHives(BOOLEAN SetupBoot); ULONG CmiGetPackedNameLength(IN PUNICODE_STRING Name, diff --git a/ntoskrnl/cm/import.c b/ntoskrnl/cm/import.c index 3f693e0..652f8d4 100644 --- a/ntoskrnl/cm/import.c +++ b/ntoskrnl/cm/import.c @@ -7,9 +7,6 @@ * PROGRAMMERS: Rex Jolliff */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include @@ -19,12 +16,18 @@ #include #include #include +#include #define NDEBUG #include #include "cm.h" -#endif + +/* GLOBALS ******************************************************************/ + +static BOOLEAN CmiHardwareHiveImported = FALSE; + +/* FUNCTIONS ****************************************************************/ static PCHAR checkAndSkipMagic (PCHAR regChunk) @@ -490,8 +493,8 @@ setKeyValue (HANDLE currentKey, } VOID -CmImportHive(PCHAR ChunkBase, - ULONG ChunkSize) +CmImportTextHive(PCHAR ChunkBase, + ULONG ChunkSize) { HANDLE currentKey = INVALID_HANDLE_VALUE; int newKeySize; @@ -612,3 +615,398 @@ CmImportHive(PCHAR ChunkBase, } +static BOOLEAN +CmImportBinaryHive (PCHAR ChunkBase, + ULONG ChunkSize, + ULONG Flags, + PREGISTRY_HIVE *RegistryHive) +{ + PREGISTRY_HIVE Hive; + PCELL_HEADER FreeBlock; + BLOCK_OFFSET BlockOffset; + PHBIN Bin; + ULONG i, j; + ULONG FreeOffset; + NTSTATUS Status; + ULONG BitmapSize; + + *RegistryHive = NULL; + + if (strncmp (ChunkBase, "regf", 4) != 0) + { + DPRINT1 ("Found invalid '%*s' magic\n", 4, ChunkBase); + return FALSE; + } + + /* Create a new hive */ + Hive = ExAllocatePool (NonPagedPool, + sizeof(REGISTRY_HIVE)); + if (Hive == NULL) + { + return FALSE; + } + RtlZeroMemory (Hive, + sizeof(REGISTRY_HIVE)); + + /* Set hive flags */ + Hive->Flags = Flags; + + /* Allocate hive header */ + Hive->HiveHeader = (PHIVE_HEADER)ExAllocatePool (NonPagedPool, + sizeof(HIVE_HEADER)); + if (Hive->HiveHeader == NULL) + { + DPRINT1 ("Allocating hive header failed\n"); + ExFreePool (Hive); + return FALSE; + } + + /* Import the hive header */ + RtlCopyMemory (Hive->HiveHeader, + ChunkBase, + sizeof(HIVE_HEADER)); + + /* Read update counter */ + Hive->UpdateCounter = Hive->HiveHeader->UpdateCounter1; + + /* Set the hive's size */ + Hive->FileSize = ChunkSize; + + /* Set the size of the block list */ + Hive->BlockListSize = (Hive->FileSize / 4096) - 1; + + /* Allocate block list */ + DPRINT("Space needed for block list describing hive: 0x%x\n", + sizeof(PHBIN *) * Hive->BlockListSize); + Hive->BlockList = ExAllocatePool (NonPagedPool, + sizeof(PHBIN *) * Hive->BlockListSize); + if (Hive->BlockList == NULL) + { + DPRINT1 ("Allocating block list failed\n"); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Allocate the hive block */ + Hive->BlockList[0] = ExAllocatePool (PagedPool, + Hive->FileSize - 4096); + if (Hive->BlockList[0] == NULL) + { + DPRINT1 ("Allocating the first hive block failed\n"); + ExFreePool (Hive->BlockList); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Import the hive block */ + RtlCopyMemory (Hive->BlockList[0], + ChunkBase + 4096, + Hive->FileSize - 4096); + + /* Initialize the free block list */ + Hive->FreeListSize = 0; + Hive->FreeListMax = 0; + Hive->FreeList = NULL; + + BlockOffset = 0; + for (i = 0; i < Hive->BlockListSize; i++) + { + Hive->BlockList[i] = (PHBIN) (((ULONG_PTR)Hive->BlockList[0]) + BlockOffset); + Bin = (PHBIN) (((ULONG_PTR)Hive->BlockList[i])); + if (Bin->BlockId != REG_BIN_ID) + { + DPRINT1 ("Bad BlockId %x, offset %x\n", Bin->BlockId, BlockOffset); + /* FIXME: */ + assert(FALSE); +// return STATUS_INSUFFICIENT_RESOURCES; + } + + assertmsg((Bin->BlockSize % 4096) == 0, ("BlockSize (0x%.08x) must be multiplum of 4K\n", Bin->BlockSize)); + + if (Bin->BlockSize > 4096) + { + for (j = 1; j < Bin->BlockSize / 4096; j++) + { + Hive->BlockList[i + j] = Hive->BlockList[i]; + } + i = i + j - 1; + } + + /* Search free blocks and add to list */ + FreeOffset = REG_HBIN_DATA_OFFSET; + while (FreeOffset < Bin->BlockSize) + { + FreeBlock = (PCELL_HEADER) ((ULONG_PTR)Hive->BlockList[i] + FreeOffset); + if (FreeBlock->CellSize > 0) + { + Status = CmiAddFree(Hive, + FreeBlock, + Hive->BlockList[i]->BlockOffset + FreeOffset, + FALSE); + if (!NT_SUCCESS(Status)) + { + /* FIXME: */ + assert(FALSE); + } + + FreeOffset += FreeBlock->CellSize; + } + else + { + FreeOffset -= FreeBlock->CellSize; + } + } + BlockOffset += Bin->BlockSize; + } + + if (!(Hive->Flags & HIVE_VOLATILE)) + { + /* Calculate bitmap size in bytes (always a multiple of 32 bits) */ + BitmapSize = ROUND_UP (Hive->BlockListSize, sizeof(ULONG) * 8) / 8; + DPRINT ("Hive->BlockListSize: %lu\n", Hive->BlockListSize); + DPRINT ("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); + + /* Allocate bitmap */ + Hive->BitmapBuffer = (PULONG)ExAllocatePool (PagedPool, + BitmapSize); + if (Hive->BitmapBuffer == NULL) + { + DPRINT1 ("Allocating the hive bitmap failed\n"); + ExFreePool (Hive->BlockList[0]); + ExFreePool (Hive->BlockList); + ExFreePool (Hive->HiveHeader); + ExFreePool (Hive); + return FALSE; + } + + /* Initialize bitmap */ + RtlInitializeBitMap (&Hive->DirtyBitMap, + Hive->BitmapBuffer, + BitmapSize * 8); + RtlClearAllBits (&Hive->DirtyBitMap); + Hive->HiveDirty = FALSE; + } + + /* Initialize the hive's executive resource */ + ExInitializeResourceLite(&Hive->HiveResource); + + /* Acquire hive list lock exclusively */ + ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); + + /* Add the new hive to the hive list */ + InsertTailList(&CmiHiveListHead, &Hive->HiveList); + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiHiveListLock); + + *RegistryHive = Hive; + + return TRUE; +} + + +BOOLEAN +CmImportSystemHive(PCHAR ChunkBase, + ULONG ChunkSize) +{ + PREGISTRY_HIVE RegistryHive; + UNICODE_STRING KeyName; + NTSTATUS Status; + + DPRINT ("CmImportSystemHive() called\n"); + + if (strncmp (ChunkBase, "REGEDIT4", 8) == 0) + { + DPRINT ("Found 'REGEDIT4' magic\n"); + CmImportTextHive (ChunkBase, ChunkSize); + return TRUE; + } + else if (strncmp (ChunkBase, "regf", 4) != 0) + { + DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase); + return FALSE; + } + + DPRINT ("Found '%.*s' magic\n", 4, ChunkBase); + + /* Import the binary system hive (non-volatile, offset-based, permanent) */ + if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, &RegistryHive)) + { + DPRINT1 ("CmiImportBinaryHive() failed\n", Status); + return FALSE; + } + + /* Attach it to the machine key */ + RtlInitUnicodeString (&KeyName, + L"\\Registry\\Machine\\System"); + Status = CmiConnectHive (RegistryHive, + &KeyName); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status); +// CmiRemoveRegistryHive(RegistryHive); + return FALSE; + } + + /* Set the hive filename */ + RtlCreateUnicodeString (&RegistryHive->HiveFileName, + SYSTEM_REG_FILE); + + /* Set the log filename */ + RtlCreateUnicodeString (&RegistryHive->LogFileName, + SYSTEM_LOG_FILE); + + return TRUE; +} + + +BOOLEAN +CmImportHardwareHive(PCHAR ChunkBase, + ULONG ChunkSize) +{ + PREGISTRY_HIVE RegistryHive; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE HardwareKey; + ULONG Disposition; + NTSTATUS Status; + + DPRINT ("CmImportHardwareHive() called\n"); + + if (CmiHardwareHiveImported == TRUE) + return TRUE; + + if (ChunkBase == NULL && + ChunkSize == 0) + { + /* Create '\Registry\Machine\HARDWARE' key. */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\HARDWARE"); + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + 0, + NULL, + NULL); + Status = NtCreateKey (&HardwareKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + NtClose (HardwareKey); + + /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"); + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + 0, + NULL, + NULL); + Status = NtCreateKey (&HardwareKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + NtClose (HardwareKey); + + /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP"); + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + 0, + NULL, + NULL); + Status = NtCreateKey (&HardwareKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + NtClose (HardwareKey); + + /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"); + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + 0, + NULL, + NULL); + Status = NtCreateKey (&HardwareKey, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + &Disposition); + if (!NT_SUCCESS(Status)) + { + return FALSE; + } + NtClose (HardwareKey); + + return TRUE; + } + + if (strncmp (ChunkBase, "regf", 4) != 0) + { + DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase); + return FALSE; + } + + DPRINT ("Found '%.*s' magic\n", 4, ChunkBase); + DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase, ChunkSize); + + /* Import the binary system hive (volatile, offset-based, permanent) */ + if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_VOLATILE, &RegistryHive)) + { + DPRINT1 ("CmiImportBinaryHive() failed\n", Status); + return FALSE; + } + + /* Attach it to the machine key */ + RtlInitUnicodeString (&KeyName, + L"\\Registry\\Machine\\HARDWARE"); + Status = CmiConnectHive (RegistryHive, + &KeyName); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status); +// CmiRemoveRegistryHive(RegistryHive); + return FALSE; + } + + /* Set the hive filename */ + RtlInitUnicodeString (&RegistryHive->HiveFileName, + NULL); + + /* Set the log filename */ + RtlInitUnicodeString (&RegistryHive->LogFileName, + NULL); + + CmiHardwareHiveImported = TRUE; + + return TRUE; +} + +/* EOF */ diff --git a/ntoskrnl/cm/ntfunc.c b/ntoskrnl/cm/ntfunc.c index 8d0a316..91a3f95 100644 --- a/ntoskrnl/cm/ntfunc.c +++ b/ntoskrnl/cm/ntfunc.c @@ -8,9 +8,6 @@ /* INCLUDES *****************************************************************/ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include #include @@ -23,7 +20,6 @@ #include #include "cm.h" -#endif /* GLOBALS ******************************************************************/ @@ -102,7 +98,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, if (End != NULL) { ObDereferenceObject(Object); - return STATUS_UNSUCCESSFUL; + return STATUS_OBJECT_NAME_NOT_FOUND; } DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object); @@ -143,6 +139,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, CreateOptions); if (!NT_SUCCESS(Status)) { + DPRINT("CmiAddSubKey() failed (Status %lx)\n", Status); /* Release hive lock */ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -198,7 +195,6 @@ NtDeleteKey(IN HANDLE KeyHandle) DPRINT("KeyHandle %x\n", KeyHandle); /* Verify that the handle is valid and is a registry key */ -CHECKPOINT1; Status = ObReferenceObjectByHandle(KeyHandle, KEY_WRITE, CmiKeyType, @@ -207,32 +203,37 @@ CHECKPOINT1; NULL); if (!NT_SUCCESS(Status)) { -CHECKPOINT1; return(Status); } -CHECKPOINT1; /* Acquire hive lock */ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); -CHECKPOINT1; VERIFY_KEY_OBJECT(KeyObject); - /* Set the marked for delete bit in the key object */ - KeyObject->Flags |= KO_MARKED_FOR_DELETE; -CHECKPOINT1; + /* Check for subkeys */ + if (KeyObject->NumberOfSubKeys != 0) + { + Status = STATUS_CANNOT_DELETE; + } + else + { + /* Set the marked for delete bit in the key object */ + KeyObject->Flags |= KO_MARKED_FOR_DELETE; + Status = STATUS_SUCCESS; + } /* Release hive lock */ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); - DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); + DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); /* Dereference the object */ ObDereferenceObject(KeyObject); if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive) ObDereferenceObject(KeyObject); - DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); + DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject)); /* * Note: @@ -241,7 +242,7 @@ CHECKPOINT1; * have been released. */ - return(STATUS_SUCCESS); + return(Status); } @@ -332,7 +333,21 @@ NtEnumerateKey( } else { + if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1) + { + return(STATUS_NO_MORE_ENTRIES); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + } + HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); + if (HashTableBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + return STATUS_UNSUCCESSFUL; + } SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive, HashTableBlock, Index); @@ -404,7 +419,6 @@ NtEnumerateKey( wcsncpy(NodeInformation->Name + SubKeyCell->NameSize , (PWCHAR) pClassData->Data, SubKeyCell->ClassSize); - CmiReleaseBlock(RegistryHive, pClassData); } } break; @@ -445,12 +459,10 @@ NtEnumerateKey( wcsncpy(FullInformation->Class, (PWCHAR) pClassData->Data, SubKeyCell->ClassSize); - CmiReleaseBlock(RegistryHive, pClassData); } } break; } - CmiReleaseBlock(RegistryHive, SubKeyCell); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -588,7 +600,6 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, RtlCopyMemory(ValuePartialInformation->Data, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); } else { @@ -655,7 +666,6 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, + ValueFullInformation->DataOffset, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); } else { @@ -686,18 +696,8 @@ NtFlushKey(IN HANDLE KeyHandle) NTSTATUS Status; PKEY_OBJECT KeyObject; PREGISTRY_HIVE RegistryHive; -#if 0 - WCHAR LogName[MAX_PATH]; - UNICODE_STRING TmpFileName; - HANDLE FileHandle; -// HANDLE FileHandleLog; - OBJECT_ATTRIBUTES ObjectAttributes; - LARGE_INTEGER fileOffset; - DWORD * pEntDword; - ULONG i; -#endif - DPRINT("KeyHandle %x\n", KeyHandle); + DPRINT("NtFlushKey (KeyHandle %lx) called\n", KeyHandle); /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, @@ -719,202 +719,16 @@ NtFlushKey(IN HANDLE KeyHandle) ExAcquireResourceExclusiveLite(&RegistryHive->HiveResource, TRUE); - if (IsPermanentHive(RegistryHive)) - { - /* Flush non-volatile hive */ - Status = CmiFlushRegistryHive(RegistryHive); - } - else + if (IsVolatileHive(RegistryHive)) { Status = STATUS_SUCCESS; } - - -#if 0 - /* Then write changed blocks in .log */ - wcscpy(LogName,RegistryHive->Filename.Buffer); - wcscat(LogName,L".log"); - RtlInitUnicodeString (&TmpFileName, LogName); - InitializeObjectAttributes(&ObjectAttributes, - &TmpFileName, - 0, - NULL, - NULL); - -/* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files - so we can't create log file - Status = ZwCreateFile(&FileHandleLog, - FILE_ALL_ACCESS, - &ObjectAttributes, - NULL, - 0, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_SUPERSEDE, - 0, - NULL, - 0); - - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(KeyObject); - return Status; - } - - Status = ZwWriteFile(FileHandleLog, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - 0, - 0); - - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandleLog); - ObDereferenceObject(KeyObject); - return Status; - } - - for (i = 0; i < RegistryHive->BlockListSize ; i++) - { - if ( RegistryHive->BlockList[i]->DateModified.dwHighDateTime - > RegistryHive->HiveHeader->DateModified.dwHighDateTime - || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime - == RegistryHive->HiveHeader->DateModified.dwHighDateTime - && RegistryHive->BlockList[i]->DateModified.dwLowDateTime - > RegistryHive->HiveHeader->DateModified.dwLowDateTime - ) - ) - - Status = ZwWriteFile(FileHandleLog, - 0, - 0, - 0, - 0, - RegistryHive->BlockList[i], - RegistryHive->BlockList[i]->BlockSize , - 0, - 0); - - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandleLog); - ObDereferenceObject(KeyObject); - return Status; - } - } - ZwClose(FileHandleLog); -END FIXME*/ - - /* Update header of RegistryHive with Version >VersionOld */ - /* this allow recover if system crash while updating hove file */ - InitializeObjectAttributes(&ObjectAttributes, - &RegistryHive->Filename, - 0, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - NULL, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); - ObDereferenceObject(KeyObject); - return Status; - } - - RegistryHive->HiveHeader->Version++; - - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - 0, - 0); - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); - ObDereferenceObject(KeyObject); - return Status; - } - - /* Update changed blocks in file */ - fileOffset.u.HighPart = 0; - for (i = 0; i < RegistryHive->BlockListSize ; i++) - { - if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime - > RegistryHive->HiveHeader->DateModified.dwHighDateTime - || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime - == RegistryHive->HiveHeader->DateModified.dwHighDateTime - && RegistryHive->BlockList[i]->DateModified.dwLowDateTime - > RegistryHive->HiveHeader->DateModified.dwLowDateTime)) - { - fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096; - Status = NtWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->BlockList[i], - RegistryHive->BlockList[i]->BlockSize, - &fileOffset, - 0); - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); - ObDereferenceObject(KeyObject); - return(Status); - } - } - } - - /* Change version in header */ - RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version; - ZwQuerySystemTime((PTIME) &RegistryHive->HiveHeader->DateModified); - - /* Calculate checksum */ - RegistryHive->HiveHeader->Checksum = 0; - pEntDword = (DWORD *) RegistryHive->HiveHeader; - for (i = 0; i < 127 ; i++) - { - RegistryHive->HiveHeader->Checksum ^= pEntDword[i]; - } - - /* Write new header */ - fileOffset.u.LowPart = 0; - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - &fileOffset, - 0); - - if (!NT_SUCCESS(Status)) + else { - ZwClose(FileHandle); - ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); - ObDereferenceObject(KeyObject); - return Status; + /* Flush non-volatile hive */ + Status = CmiFlushRegistryHive(RegistryHive); } - ZwClose(FileHandle); -#endif - ExReleaseResourceLite(&RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -1013,14 +827,11 @@ NtQueryKey(IN HANDLE KeyHandle, NULL); if (!NT_SUCCESS(Status)) { -CHECKPOINT1; return Status; } -CHECKPOINT1; /* Acquire hive lock */ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); -CHECKPOINT1; VERIFY_KEY_OBJECT(KeyObject); @@ -1032,7 +843,6 @@ CHECKPOINT1; switch (KeyInformationClass) { case KeyBasicInformation: -CHECKPOINT1; /* Check size of buffer */ if (Length < sizeof(KEY_BASIC_INFORMATION) + KeyObject->NameSize * sizeof(WCHAR)) @@ -1053,7 +863,6 @@ CHECKPOINT1; *ResultLength = sizeof(KEY_BASIC_INFORMATION) + KeyObject->NameSize * sizeof(WCHAR); } -CHECKPOINT1; break; case KeyNodeInformation: @@ -1087,7 +896,6 @@ CHECKPOINT1; wcsncpy(NodeInformation->Name + KeyObject->NameSize * sizeof(WCHAR), (PWCHAR)pClassData->Data, KeyCell->ClassSize); - CmiReleaseBlock(RegistryHive, pClassData); } *ResultLength = sizeof(KEY_NODE_INFORMATION) + KeyObject->NameSize * sizeof(WCHAR) @@ -1128,18 +936,14 @@ CHECKPOINT1; wcsncpy(FullInformation->Class, (PWCHAR)pClassData->Data, KeyCell->ClassSize); - CmiReleaseBlock(RegistryHive, pClassData); } *ResultLength = sizeof(KEY_FULL_INFORMATION) + KeyCell->ClassSize; } break; } -CHECKPOINT1; ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); -CHECKPOINT1; ObDereferenceObject(KeyObject); -CHECKPOINT1; return(Status); } @@ -1268,7 +1072,6 @@ NtQueryValueKey(IN HANDLE KeyHandle, RtlCopyMemory(ValuePartialInformation->Data, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); } else { @@ -1333,7 +1136,6 @@ NtQueryValueKey(IN HANDLE KeyHandle, + ValueFullInformation->DataOffset, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); } else { @@ -1377,8 +1179,8 @@ NtSetValueKey(IN HANDLE KeyHandle, PHBIN pBin; ULONG DesiredAccess; - DPRINT("NtSetValueKey(KeyHandle %x ValueName %S Type %d)\n", - KeyHandle, ValueName? ValueName->Buffer : NULL, Type); + DPRINT("NtSetValueKey(KeyHandle %x ValueName '%wZ' Type %d)\n", + KeyHandle, ValueName, Type); DesiredAccess = KEY_SET_VALUE; if (Type == REG_LINK) @@ -1409,7 +1211,7 @@ NtSetValueKey(IN HANDLE KeyHandle, &VBOffset); if (!NT_SUCCESS(Status)) { - DPRINT1("Value not found. Status 0x%X\n", Status); + DPRINT("Value not found. Status 0x%X\n", Status); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -1432,7 +1234,7 @@ NtSetValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) { - DPRINT1("Cannot add value. Status 0x%X\n", Status); + DPRINT("Cannot add value. Status 0x%X\n", Status); ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); @@ -1467,12 +1269,11 @@ NtSetValueKey(IN HANDLE KeyHandle, RtlCopyMemory(DataCell->Data, Data, DataSize); ValueCell->DataSize = DataSize; ValueCell->DataType = Type; - CmiReleaseBlock(RegistryHive, DataCell); /* Update time of heap */ - if (IsPermanentHive(RegistryHive)) + if (!IsVolatileHive(RegistryHive)) { - ZwQuerySystemTime((PTIME) &pBin->DateModified); + NtQuerySystemTime((PTIME) &pBin->DateModified); } CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); } @@ -1512,7 +1313,6 @@ NtSetValueKey(IN HANDLE KeyHandle, RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize); ValueCell->DataSize = DataSize; ValueCell->DataType = Type; - CmiReleaseBlock(RegistryHive, NewDataCell); ValueCell->DataOffset = NewOffset; CmiMarkBlockDirty(RegistryHive, ValueCell->DataOffset); } @@ -1526,9 +1326,9 @@ NtSetValueKey(IN HANDLE KeyHandle, } /* Update time of heap */ - if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) + if (!IsVolatileHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) { - ZwQuerySystemTime((PTIME) &pBin->DateModified); + NtQuerySystemTime((PTIME) &pBin->DateModified); } ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); @@ -1581,21 +1381,31 @@ NtDeleteValueKey(IN HANDLE KeyHandle, return Status; } - +/* + * NOTE: + * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and + * KeyObjectAttributes->Name specifies the name of the key to load. + */ NTSTATUS STDCALL -NtLoadKey(PHANDLE KeyHandle, - POBJECT_ATTRIBUTES ObjectAttributes) +NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes) { - return NtLoadKey2(KeyHandle, ObjectAttributes, 0); + return NtLoadKey2(KeyObjectAttributes, FileObjectAttributes, 0); } +/* + * NOTE: + * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and + * KeyObjectAttributes->Name specifies the name of the key to load. + */ NTSTATUS STDCALL -NtLoadKey2(IN PHANDLE KeyHandle, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG Flags) +NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes, + IN ULONG Flags) { - UNIMPLEMENTED; + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } @@ -1692,9 +1502,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, if (ValueCell->DataSize > 0) { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); - RtlCopyMemory(DataPtr, DataCell->Data, ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); + DataCell = CmiGetBlock(RegistryHive, + ValueCell->DataOffset, + NULL); + RtlCopyMemory(DataPtr, + DataCell->Data, + ValueCell->DataSize & LONG_MAX); } else { @@ -1771,8 +1584,13 @@ NtSetInformationKey( } +/* + * NOTE: + * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and + * KeyObjectAttributes->Name specifies the name of the key to unload. + */ NTSTATUS STDCALL -NtUnloadKey(IN HANDLE KeyHandle) +NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes) { UNIMPLEMENTED; } diff --git a/ntoskrnl/cm/regfile.c b/ntoskrnl/cm/regfile.c index ea67394..a03290a 100644 --- a/ntoskrnl/cm/regfile.c +++ b/ntoskrnl/cm/regfile.c @@ -6,9 +6,6 @@ * UPDATE HISTORY: */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include #include @@ -17,17 +14,29 @@ #include #include #include +#include #define NDEBUG #include #include "cm.h" -#endif + + +/* uncomment to enable hive checks (incomplete and probably buggy) */ +// #define HIVE_CHECK + +/* LOCAL MACROS *************************************************************/ #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) +#define ROUND_DOWN(N, S) ((N) - ((N) % (S))) + +#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V)) BOOLEAN CmiDoVerify = FALSE; +static ULONG +CmiCalcChecksum(PULONG Buffer); + /* FUNCTIONS ****************************************************************/ VOID @@ -36,9 +45,10 @@ CmiCreateDefaultHiveHeader(PHIVE_HEADER Header) assert(Header); RtlZeroMemory(Header, sizeof(HIVE_HEADER)); Header->BlockId = REG_HIVE_ID; + Header->UpdateCounter1 = 0; + Header->UpdateCounter2 = 0; Header->DateModified.dwLowDateTime = 0; Header->DateModified.dwHighDateTime = 0; - Header->Version = 1; Header->Unused3 = 1; Header->Unused4 = 3; Header->Unused5 = 0; @@ -68,14 +78,10 @@ CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell) { assert(RootKeyCell); RtlZeroMemory(RootKeyCell, sizeof(KEY_CELL)); -#ifdef WIN32_REGDBG - RootKeyCell->CellSize = -(LONG)sizeof(KEY_CELL); -#else RootKeyCell->CellSize = -sizeof(KEY_CELL); -#endif RootKeyCell->Id = REG_KEY_CELL_ID; RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE; - ZwQuerySystemTime((PTIME) &RootKeyCell->LastWriteTime); + NtQuerySystemTime((PTIME) &RootKeyCell->LastWriteTime); RootKeyCell->ParentKeyOffset = 0; RootKeyCell->NumberOfSubKeys = 0; RootKeyCell->HashTableOffset = -1; @@ -342,7 +348,7 @@ CmiVerifyHiveHeader(PHIVE_HEADER Header) assert(Header->Unused7 == 1); } - } + } } @@ -358,7 +364,8 @@ CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive) } -NTSTATUS +#if 0 +static NTSTATUS CmiPopulateHive(HANDLE FileHandle) { IO_STATUS_BLOCK IoStatusBlock; @@ -383,15 +390,15 @@ CmiPopulateHive(HANDLE FileHandle) // Add free blocks so we don't need to expand // the file for a while - for (i = 0; i < 50; i++) + for (i = 1; i < 50; i++) { // Block offset of this bin - BinCell->BlockOffset = (2 + i) * REG_BLOCK_SIZE; + BinCell->BlockOffset = i * REG_BLOCK_SIZE; FileOffset.u.HighPart = 0; - FileOffset.u.LowPart = (2 + i) * REG_BLOCK_SIZE; + FileOffset.u.LowPart = (i + 1) * REG_BLOCK_SIZE; - Status = ZwWriteFile(FileHandle, + Status = NtWriteFile(FileHandle, NULL, NULL, NULL, @@ -412,9 +419,10 @@ CmiPopulateHive(HANDLE FileHandle) return Status; } +#endif -NTSTATUS +static NTSTATUS CmiCreateNewRegFile(HANDLE FileHandle) { IO_STATUS_BLOCK IoStatusBlock; @@ -447,7 +455,7 @@ CmiCreateNewRegFile(HANDLE FileHandle) /* The rest of the block is free */ FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL)); - Status = ZwWriteFile(FileHandle, + Status = NtWriteFile(FileHandle, NULL, NULL, NULL, @@ -461,21 +469,284 @@ CmiCreateNewRegFile(HANDLE FileHandle) assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); -#if 1 + if (!NT_SUCCESS(Status)) + { + return(Status); + } + +#if 0 if (NT_SUCCESS(Status)) { CmiPopulateHive(FileHandle); } #endif - return Status; + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + + return(Status); } -NTSTATUS -CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, - PWSTR Filename, - BOOLEAN CreateNew) +#ifdef HIVE_CHECK +static NTSTATUS +CmiCheckAndFixHive(PREGISTRY_HIVE RegistryHive) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + FILE_STANDARD_INFORMATION fsi; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE HiveHandle = INVALID_HANDLE_VALUE; + HANDLE LogHandle = INVALID_HANDLE_VALUE; + PHIVE_HEADER HiveHeader = NULL; + PHIVE_HEADER LogHeader = NULL; + LARGE_INTEGER FileOffset; + ULONG FileSize; + ULONG BufferSize; + ULONG BitmapSize; + RTL_BITMAP BlockBitMap; + NTSTATUS Status; + + DPRINT("CmiCheckAndFixHive() called\n"); + + /* Try to open the hive file */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->HiveFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&HiveHandle, + FILE_READ_DATA | FILE_READ_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + return(STATUS_SUCCESS); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); + } + + /* Try to open the log file */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->LogFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&LogHandle, + FILE_READ_DATA | FILE_READ_ATTRIBUTES, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + LogHandle = INVALID_HANDLE_VALUE; + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + NtClose(HiveHandle); + return(Status); + } + + /* Allocate hive header */ + HiveHeader = ExAllocatePool(PagedPool, + sizeof(HIVE_HEADER)); + if (HiveHeader == NULL) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; + } + + /* Read hive base block */ + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(HiveHandle, + 0, + 0, + 0, + &IoStatusBlock, + HiveHeader, + sizeof(HIVE_HEADER), + &FileOffset, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + goto ByeBye; + } + + if (LogHandle == INVALID_HANDLE_VALUE) + { + if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) || + HiveHeader->UpdateCounter1 != HiveHeader->UpdateCounter2) + { + /* There is no way to fix the hive without log file - BSOD! */ + DPRINT("Hive header inconsistent and no log file available!\n"); + KeBugCheck(CONFIG_LIST_FAILED); + } + + Status = STATUS_SUCCESS; + goto ByeBye; + } + else + { + /* Allocate hive header */ + LogHeader = ExAllocatePool(PagedPool, + sizeof(HIVE_HEADER)); + if (LogHeader == NULL) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; + } + + /* Read log file header */ + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(LogHandle, + 0, + 0, + 0, + &IoStatusBlock, + LogHeader, + sizeof(HIVE_HEADER), + &FileOffset, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + goto ByeBye; + } + + /* Check log file header integrity */ + if (LogHeader->Checksum != CmiCalcChecksum((PULONG)LogHeader) || + LogHeader->UpdateCounter1 != LogHeader->UpdateCounter2) + { + if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) || + HiveHeader->UpdateCounter1 != HiveHeader->UpdateCounter2) + { + DPRINT("Hive file and log file are inconsistent!\n"); + KeBugCheck(CONFIG_LIST_FAILED); + } + + /* Log file damaged but hive is okay */ + Status = STATUS_SUCCESS; + goto ByeBye; + } + + if (HiveHeader->UpdateCounter1 == HiveHeader->UpdateCounter2 && + HiveHeader->UpdateCounter1 == LogHeader->UpdateCounter1) + { + /* Hive and log file are up-to-date */ + Status = STATUS_SUCCESS; + goto ByeBye; + } + + /* + * Hive needs an update! + */ + + /* Get file size */ + Status = NtQueryInformationFile(LogHandle, + &IoStatusBlock, + &fsi, + sizeof(fsi), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + goto ByeBye; + } + FileSize = fsi.EndOfFile.u.LowPart; + + /* Calculate bitmap and block size */ + BitmapSize = ROUND_UP((FileSize / 4096) - 1, sizeof(ULONG) * 8) / 8; + BufferSize = sizeof(HIVE_HEADER) + + sizeof(ULONG) + + BitmapSize; + BufferSize = ROUND_UP(BufferSize, 4096); + + /* Reallocate log header block */ + ExFreePool(LogHeader); + LogHeader = ExAllocatePool(PagedPool, + BufferSize); + if (LogHeader == NULL) + { + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto ByeBye; + } + + /* Read log file header */ + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(LogHandle, + 0, + 0, + 0, + &IoStatusBlock, + LogHeader, + BufferSize, + &FileOffset, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + goto ByeBye; + } + + /* Initialize bitmap */ + RtlInitializeBitMap(&BlockBitMap, + (PVOID)((ULONG)LogHeader + 4096 + sizeof(ULONG)), + BitmapSize * 8); + + /* FIXME: Update dirty blocks */ + + + /* FIXME: Update hive header */ + + + Status = STATUS_SUCCESS; + } + + + /* Clean up the mess */ +ByeBye: + if (HiveHeader != NULL) + ExFreePool(HiveHeader); + + if (LogHeader != NULL) + ExFreePool(LogHeader); + + if (LogHandle != INVALID_HANDLE_VALUE) + NtClose(LogHandle); + + NtClose(HiveHandle); + + return(Status); +} +#endif + + +static NTSTATUS +CmiInitNonVolatileRegistryHive(PREGISTRY_HIVE RegistryHive, + PWSTR Filename, + BOOLEAN CreateNew) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION fsi; @@ -490,20 +761,49 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, PHBIN tmpBin; ULONG i, j; ULONG BitmapSize; - PULONG BitmapBuffer; - DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew); + DPRINT("CmiInitNonVolatileRegistryHive(%p, %S, %d) called\n", + RegistryHive, Filename, CreateNew); /* Duplicate Filename */ - Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename); + Status = RtlCreateUnicodeString(&RegistryHive->HiveFileName, + Filename); if (!NT_SUCCESS(Status)) { - DPRINT1("CmiInitPermanentRegistryHive() - Failed 1.\n"); - return Status; + DPRINT("RtlCreateUnicodeString() failed (Status %lx)\n", Status); + return(Status); + } + + /* Create log file name */ + RegistryHive->LogFileName.Length = (wcslen(Filename) + 4) * sizeof(WCHAR); + RegistryHive->LogFileName.MaximumLength = RegistryHive->LogFileName.Length + sizeof(WCHAR); + RegistryHive->LogFileName.Buffer = ExAllocatePool(NonPagedPool, + RegistryHive->LogFileName.MaximumLength); + if (RegistryHive->LogFileName.Buffer == NULL) + { + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + DPRINT("ExAllocatePool() failed\n"); + return(STATUS_INSUFFICIENT_RESOURCES); + } + wcscpy(RegistryHive->LogFileName.Buffer, + Filename); + wcscat(RegistryHive->LogFileName.Buffer, + L".log"); + +#ifdef HIVE_CHECK + /* Check and eventually fix a hive */ + Status = CmiCheckAndFixHive(RegistryHive); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); + DPRINT1("CmiCheckAndFixHive() failed (Status %lx)\n", Status); + return(Status); } +#endif InitializeObjectAttributes(&ObjectAttributes, - &RegistryHive->Filename, + &RegistryHive->HiveFileName, 0, NULL, NULL); @@ -536,8 +836,9 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, 0); if (!NT_SUCCESS(Status)) { - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); return(Status); } @@ -550,29 +851,14 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, Status = CmiCreateNewRegFile(FileHandle); if (!NT_SUCCESS(Status)) { - DPRINT1("CmiCreateNewRegFile() failed (Status %lx)\n", Status); - RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiCreateNewRegFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); return(Status); } } - Status = ObReferenceObjectByHandle(FileHandle, - FILE_ALL_ACCESS, - IoFileObjectType, - UserMode, - (PVOID*)&RegistryHive->FileObject, - NULL); - - assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); - - if (!NT_SUCCESS(Status)) - { - NtClose(FileHandle); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT1("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status); - return Status; - } - /* Read hive header */ FileOffset.u.HighPart = 0; FileOffset.u.LowPart = 0; @@ -589,50 +875,33 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); if (!NT_SUCCESS(Status)) { - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed 4.\n"); + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); return Status; } + /* Read update counter */ + RegistryHive->UpdateCounter = RegistryHive->HiveHeader->UpdateCounter1; + Status = NtQueryInformationFile(FileHandle, &IoSB, &fsi, sizeof(fsi), FileStandardInformation); - assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); - - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status) || fsi.EndOfFile.u.LowPart == 0) { - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed 5.\n"); + DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); return Status; } -#if 0 - /* We have a reference to the file object so we don't need the handle anymore */ - ZwClose(FileHandle); -#endif - RegistryHive->FileSize = fsi.EndOfFile.u.LowPart; -#ifdef WIN32_REGDBG -// assert(RegistryHive->FileSize); - if (RegistryHive->FileSize) - { - RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; - } - else - { - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n"); - return STATUS_INSUFFICIENT_RESOURCES; - } -#else RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; -#endif DPRINT("Space needed for block list describing hive: 0x%x\n", sizeof(PHBIN *) * RegistryHive->BlockListSize); @@ -643,55 +912,30 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, if (RegistryHive->BlockList == NULL) { ExFreePool(RegistryHive->BlockList); - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed 6.\n"); + NtClose(FileHandle); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); + DPRINT("CmiInitNonVolatileRegistryHive() - Failed 6.\n"); return STATUS_INSUFFICIENT_RESOURCES; } -#if 0 - /* Map hive into cache memory (readonly) (skip the base block) */ - FileOffset.u.HighPart = 0; - FileOffset.u.LowPart = 4096; - Success = CcMapData(RegistryHive->FileObject, /* File object */ - &FileOffset, /* File offset */ - RegistryHive->FileSize - 4096, /* Region length */ - TRUE, /* Wait if needed */ - &RegistryHive->Bcb, /* OUT: Buffer Control Block */ - (PVOID*) &RegistryHive->BlockList[0]); /* OUT: Mapped data pointer */ - - assertmsg(Success, ("Success: %d\n", Success)); - - if (!Success) - { - ExFreePool(RegistryHive->BlockList); - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed 7.\n"); - return Status; - } - -#else - RegistryHive->BlockList[0] = ExAllocatePool(PagedPool, RegistryHive->FileSize - 4096); -#ifdef WIN32_REGDBG - RtlZeroMemory(RegistryHive->BlockList[0], RegistryHive->FileSize - 4096); -#endif - if (RegistryHive->BlockList[0] == NULL) { ExFreePool(RegistryHive->BlockList); - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed 8.\n"); + NtClose(FileHandle); + RtlFreeUnicodeString(&RegistryHive->HiveFileName); + RtlFreeUnicodeString(&RegistryHive->LogFileName); + DPRINT("CmiInitNonVolatileRegistryHive() - Failed 8.\n"); return STATUS_INSUFFICIENT_RESOURCES; } FileOffset.u.HighPart = 0; FileOffset.u.LowPart = 4096; - DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]); + DPRINT(" Attempting to NtReadFile(%d) for %d bytes into %p\n", + FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]); Status = NtReadFile(FileHandle, 0, 0, @@ -705,7 +949,6 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); NtClose(FileHandle); -#endif RegistryHive->FreeListSize = 0; RegistryHive->FreeListMax = 0; @@ -743,7 +986,8 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, { Status = CmiAddFree(RegistryHive, FreeBlock, - RegistryHive->BlockList[i]->BlockOffset + FreeOffset); + RegistryHive->BlockList[i]->BlockOffset + FreeOffset, + FALSE); if (!NT_SUCCESS(Status)) { @@ -761,35 +1005,41 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, BlockOffset += tmpBin->BlockSize; } - /* Create block bitmap and clear all bits */ - + /* + * Create block bitmap and clear all bits + */ /* Calculate bitmap size in bytes (always a multiple of 32 bits) */ BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; - DPRINT1("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize); - DPRINT1("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); - BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, - BitmapSize); + DPRINT("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize); + DPRINT("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); + + /* Allocate bitmap */ + RegistryHive->BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, + BitmapSize); RtlInitializeBitMap(&RegistryHive->DirtyBitMap, - BitmapBuffer, + RegistryHive->BitmapBuffer, BitmapSize * 8); + + /* Initialize bitmap */ RtlClearAllBits(&RegistryHive->DirtyBitMap); RegistryHive->HiveDirty = FALSE; - DPRINT1("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew); + DPRINT("CmiInitNonVolatileRegistryHive(%p, %S, %d) - Finished.\n", + RegistryHive, Filename, CreateNew); return(STATUS_SUCCESS); } -NTSTATUS +static NTSTATUS CmiInitVolatileRegistryHive(PREGISTRY_HIVE RegistryHive) { PKEY_CELL RootKeyCell; - RegistryHive->Flags |= HIVE_VOLATILE; + RegistryHive->Flags |= (HIVE_VOLATILE | HIVE_POINTER); CmiCreateDefaultHiveHeader(RegistryHive->HiveHeader); - + RootKeyCell = (PKEY_CELL) ExAllocatePool(NonPagedPool, sizeof(KEY_CELL)); if (RootKeyCell == NULL) @@ -805,8 +1055,8 @@ CmiInitVolatileRegistryHive(PREGISTRY_HIVE RegistryHive) NTSTATUS CmiCreateRegistryHive(PWSTR Filename, - PREGISTRY_HIVE *RegistryHive, - BOOLEAN CreateNew) + PREGISTRY_HIVE *RegistryHive, + BOOLEAN CreateNew) { PREGISTRY_HIVE Hive; NTSTATUS Status; @@ -834,7 +1084,7 @@ CmiCreateRegistryHive(PWSTR Filename, if (Filename != NULL) { - Status = CmiInitPermanentRegistryHive(Hive, Filename, CreateNew); + Status = CmiInitNonVolatileRegistryHive(Hive, Filename, CreateNew); } else { @@ -854,7 +1104,7 @@ CmiCreateRegistryHive(PWSTR Filename, ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE); /* Add the new hive to the hive list */ - InsertHeadList(&CmiHiveListHead, &Hive->HiveList); + InsertTailList(&CmiHiveListHead, &Hive->HiveList); /* Release hive list lock */ ExReleaseResourceLite(&CmiHiveListLock); @@ -895,34 +1145,56 @@ CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive) } -NTSTATUS -CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) +static ULONG +CmiCalcChecksum(PULONG Buffer) { - ULONG BlockIndex; - ULONG BlockOffset; - PVOID BlockPtr; - LARGE_INTEGER FileOffset; + ULONG Sum = 0; + ULONG i; + + for (i = 0; i < 127; i++) + Sum += Buffer[i]; + + return(Sum); +} + + +static NTSTATUS +CmiStartLogUpdate(PREGISTRY_HIVE RegistryHive) +{ + FILE_END_OF_FILE_INFORMATION EndOfFileInfo; + FILE_ALLOCATION_INFORMATION FileAllocationInfo; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; + LARGE_INTEGER FileOffset; + ULONG BufferSize; + ULONG BitmapSize; + PUCHAR Buffer; + PUCHAR Ptr; + ULONG BlockIndex; + PVOID BlockPtr; NTSTATUS Status; + DPRINT("CmiStartLogUpdate() called\n"); + BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; + BufferSize = sizeof(HIVE_HEADER) + + sizeof(ULONG) + + BitmapSize; + BufferSize = ROUND_UP(BufferSize, 4096); + DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); - DPRINT("CmiFlushRegistryHive() called\n"); - - if (RegistryHive->HiveDirty == FALSE) + Buffer = (PUCHAR)ExAllocatePool(NonPagedPool, BufferSize); + if (Buffer == NULL) { - return(STATUS_SUCCESS); + DPRINT("ExAllocatePool() failed\n"); + return(STATUS_INSUFFICIENT_RESOURCES); } - DPRINT1("Hive '%wZ' is dirty\n", &RegistryHive->Filename); - - - /* Open hive for writing */ + /* Open log file for writing */ InitializeObjectAttributes(&ObjectAttributes, - &RegistryHive->Filename, + &RegistryHive->LogFileName, 0, NULL, NULL); @@ -934,41 +1206,76 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) NULL, FILE_ATTRIBUTE_NORMAL, 0, - FILE_OPEN, + FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { - DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + ExFreePool(Buffer); return(Status); } + /* Update firt update counter and checksum */ + RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader); + /* Copy hive header */ + RtlCopyMemory(Buffer, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER)); + Ptr = Buffer + sizeof(HIVE_HEADER); + RtlCopyMemory(Ptr, + "DIRT", + 4); + Ptr += 4; + RtlCopyMemory(Ptr, + RegistryHive->DirtyBitMap.Buffer, + BitmapSize); + + /* Write hive block and block bitmap */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BufferSize, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + ExFreePool(Buffer); + return(Status); + } + ExFreePool(Buffer); + + /* Write dirty blocks */ + FileOffset.QuadPart = (ULONGLONG)BufferSize; BlockIndex = 0; while (TRUE) { - BlockIndex = RtlFindSetBitsAndClear(&RegistryHive->DirtyBitMap, - 1, - BlockIndex); - if (BlockIndex == (ULONG)-1) + BlockIndex = RtlFindSetBits(&RegistryHive->DirtyBitMap, + 1, + BlockIndex); + if ((BlockIndex == (ULONG)-1) || + (BlockIndex >= RegistryHive->BlockListSize)) { DPRINT("No more set bits\n"); + Status = STATUS_SUCCESS; break; } - DPRINT1("Block %lu is dirty\n", BlockIndex); - - BlockOffset = RegistryHive->BlockList[BlockIndex]->BlockOffset; - DPRINT1("Block offset %lx\n", BlockOffset); - - BlockPtr = RegistryHive->BlockList[BlockIndex] + ((BlockIndex * 4096) - BlockOffset); - DPRINT1("BlockPtr %p\n", BlockPtr); - - FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL; - DPRINT1("File offset %I64x\n", FileOffset.QuadPart); + DPRINT("Block %lu is dirty\n", BlockIndex); + BlockPtr = RegistryHive->BlockList[BlockIndex]; + DPRINT("BlockPtr %p\n", BlockPtr); + DPRINT("File offset %I64x\n", FileOffset.QuadPart); /* Write hive block */ Status = NtWriteFile(FileHandle, @@ -987,13 +1294,496 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) return(Status); } + BlockIndex++; + FileOffset.QuadPart += 4096ULL; + } + /* Truncate log file */ + EndOfFileInfo.EndOfFile.QuadPart = FileOffset.QuadPart; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &EndOfFileInfo, + sizeof(FILE_END_OF_FILE_INFORMATION), + FileEndOfFileInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); } - NtClose(FileHandle); + FileAllocationInfo.AllocationSize.QuadPart = FileOffset.QuadPart; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileAllocationInfo, + sizeof(FILE_ALLOCATION_INFORMATION), + FileAllocationInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + /* Flush the log file */ + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtFlushBuffersFile() failed (Status %lx)\n", Status); + } - /* Clear dirty flag */ + NtClose(FileHandle); + + return(Status); +} + + +static NTSTATUS +CmiFinishLogUpdate(PREGISTRY_HIVE RegistryHive) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + LARGE_INTEGER FileOffset; + ULONG BufferSize; + ULONG BitmapSize; + PUCHAR Buffer; + PUCHAR Ptr; + NTSTATUS Status; + + DPRINT("CmiFinishLogUpdate() called\n"); + + BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; + BufferSize = sizeof(HIVE_HEADER) + + sizeof(ULONG) + + BitmapSize; + BufferSize = ROUND_UP(BufferSize, 4096); + + DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); + + Buffer = (PUCHAR)ExAllocatePool(NonPagedPool, BufferSize); + if (Buffer == NULL) + { + DPRINT("ExAllocatePool() failed\n"); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Open log file for writing */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->LogFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + ExFreePool(Buffer); + return(Status); + } + + /* Update first and second update counter and checksum */ + RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->UpdateCounter2 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader); + + /* Copy hive header */ + RtlCopyMemory(Buffer, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER)); + Ptr = Buffer + sizeof(HIVE_HEADER); + + /* Write empty block bitmap */ + RtlCopyMemory(Ptr, + "DIRT", + 4); + Ptr += 4; + RtlZeroMemory(Ptr, + BitmapSize); + + /* Write hive block and block bitmap */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + BufferSize, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + ExFreePool(Buffer); + return(Status); + } + + ExFreePool(Buffer); + + /* Flush the log file */ + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtFlushBuffersFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + + return(Status); +} + + +static NTSTATUS +CmiCleanupLogUpdate(PREGISTRY_HIVE RegistryHive) +{ + FILE_END_OF_FILE_INFORMATION EndOfFileInfo; + FILE_ALLOCATION_INFORMATION FileAllocationInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + ULONG BufferSize; + ULONG BitmapSize; + NTSTATUS Status; + + DPRINT("CmiCleanupLogUpdate() called\n"); + + BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; + BufferSize = sizeof(HIVE_HEADER) + + sizeof(ULONG) + + BitmapSize; + BufferSize = ROUND_UP(BufferSize, 4096); + + DPRINT("Bitmap size %lu buffer size: %lu\n", BitmapSize, BufferSize); + + /* Open log file for writing */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->LogFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); + } + + /* Truncate log file */ + EndOfFileInfo.EndOfFile.QuadPart = (ULONGLONG)BufferSize; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &EndOfFileInfo, + sizeof(FILE_END_OF_FILE_INFORMATION), + FileEndOfFileInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + FileAllocationInfo.AllocationSize.QuadPart = (ULONGLONG)BufferSize; + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileAllocationInfo, + sizeof(FILE_ALLOCATION_INFORMATION), + FileAllocationInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + /* Flush the log file */ + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtFlushBuffersFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + + return(Status); +} + + +static NTSTATUS +CmiStartHiveUpdate(PREGISTRY_HIVE RegistryHive) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + LARGE_INTEGER FileOffset; + ULONG BlockIndex; + PVOID BlockPtr; + NTSTATUS Status; + + DPRINT("CmiStartHiveUpdate() called\n"); + + /* Open hive for writing */ + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->HiveFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); + } + + /* Update firt update counter and checksum */ + RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader); + + /* Write hive block */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + BlockIndex = 0; + while (TRUE) + { + BlockIndex = RtlFindSetBits(&RegistryHive->DirtyBitMap, + 1, + BlockIndex); + if ((BlockIndex == (ULONG)-1) || + (BlockIndex >= RegistryHive->BlockListSize)) + { + DPRINT("No more set bits\n"); + Status = STATUS_SUCCESS; + break; + } + + DPRINT("Block %lu is dirty\n", BlockIndex); + + BlockPtr = RegistryHive->BlockList[BlockIndex]; + DPRINT("BlockPtr %p\n", BlockPtr); + + FileOffset.QuadPart = (ULONGLONG)(BlockIndex + 1) * 4096ULL; + DPRINT("File offset %I64x\n", FileOffset.QuadPart); + + /* Write hive block */ + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + BlockPtr, + REG_BLOCK_SIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + BlockIndex++; + } + + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtFlushBuffersFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + + return(Status); +} + + +static NTSTATUS +CmiFinishHiveUpdate(PREGISTRY_HIVE RegistryHive) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + LARGE_INTEGER FileOffset; + HANDLE FileHandle; + NTSTATUS Status; + + DPRINT("CmiFinishHiveUpdate() called\n"); + + InitializeObjectAttributes(&ObjectAttributes, + &RegistryHive->HiveFileName, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); + } + + /* Update second update counter and checksum */ + RegistryHive->HiveHeader->UpdateCounter1 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->UpdateCounter2 = RegistryHive->UpdateCounter + 1; + RegistryHive->HiveHeader->Checksum = CmiCalcChecksum((PULONG)RegistryHive->HiveHeader); + + /* Write hive block */ + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + Status = NtFlushBuffersFile(FileHandle, + &IoStatusBlock); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtFlushBuffersFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + + return(Status); +} + + +NTSTATUS +CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) +{ + NTSTATUS Status; + + DPRINT("CmiFlushRegistryHive() called\n"); + + if (RegistryHive->HiveDirty == FALSE) + { + return(STATUS_SUCCESS); + } + + DPRINT("Hive '%wZ' is dirty\n", + &RegistryHive->HiveFileName); + DPRINT("Log file: '%wZ'\n", + &RegistryHive->LogFileName); + + /* Update hive header modification time */ + NtQuerySystemTime((PTIME)&RegistryHive->HiveHeader->DateModified); + + /* Start log update */ + Status = CmiStartLogUpdate(RegistryHive); + if (!NT_SUCCESS(Status)) + { + DPRINT("CmiStartLogUpdate() failed (Status %lx)\n", Status); + return(Status); + } + + /* Finish log update */ + Status = CmiFinishLogUpdate(RegistryHive); + if (!NT_SUCCESS(Status)) + { + DPRINT("CmiFinishLogUpdate() failed (Status %lx)\n", Status); + return(Status); + } + + /* Start hive update */ + Status = CmiStartHiveUpdate(RegistryHive); + if (!NT_SUCCESS(Status)) + { + DPRINT("CmiStartHiveUpdate() failed (Status %lx)\n", Status); + return(Status); + } + + /* Finish the hive update */ + Status = CmiFinishHiveUpdate(RegistryHive); + if (!NT_SUCCESS(Status)) + { + DPRINT("CmiFinishHiveUpdate() failed (Status %lx)\n", Status); + return(Status); + } + + /* Cleanup log update */ + Status = CmiCleanupLogUpdate(RegistryHive); + if (!NT_SUCCESS(Status)) + { + DPRINT("CmiFinishLogUpdate() failed (Status %lx)\n", Status); + return(Status); + } + + /* Increment hive update counter */ + RegistryHive->UpdateCounter++; + + /* Clear dirty bitmap and dirty flag */ + RtlClearAllBits(&RegistryHive->DirtyBitMap); RegistryHive->HiveDirty = FALSE; DPRINT("CmiFlushRegistryHive() done\n"); @@ -1004,7 +1794,7 @@ CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive) ULONG CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; @@ -1017,33 +1807,37 @@ CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive, HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); if (HashBlock == NULL) { + DPRINT("CmiGetBlock() failed\n"); return 0; } for (i = 0; i < HashBlock->HashTableSize; i++) { - if (HashBlock->Table[i].KeyOffset != 0) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset, - NULL); - if (MaxName < CurSubKeyCell->NameSize) - { - MaxName = CurSubKeyCell->NameSize; - } - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } + if (HashBlock->Table[i].KeyOffset != 0) + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (CurSubKeyCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return 0; + } + + if (MaxName < CurSubKeyCell->NameSize) + { + MaxName = CurSubKeyCell->NameSize; + } + } } - CmiReleaseBlock(RegistryHive, HashBlock); - return MaxName; } ULONG CmiGetMaxClassLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; @@ -1056,33 +1850,37 @@ CmiGetMaxClassLength(PREGISTRY_HIVE RegistryHive, HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); if (HashBlock == NULL) { + DPRINT("CmiGetBlock() failed\n"); return 0; } for (i = 0; i < HashBlock->HashTableSize; i++) { if (HashBlock->Table[i].KeyOffset != 0) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset, - NULL); - if (MaxClass < CurSubKeyCell->ClassSize) - { - MaxClass = CurSubKeyCell->ClassSize; - } - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } - } + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (CurSubKeyCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return 0; + } - CmiReleaseBlock(RegistryHive, HashBlock); + if (MaxClass < CurSubKeyCell->ClassSize) + { + MaxClass = CurSubKeyCell->ClassSize; + } + } + } return MaxClass; } -ULONG +ULONG CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -1091,35 +1889,40 @@ CmiGetMaxValueNameLength(PREGISTRY_HIVE RegistryHive, VERIFY_KEY_CELL(KeyCell); - ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); MaxValueName = 0; + ValueListCell = CmiGetBlock(RegistryHive, + KeyCell->ValuesOffset, + NULL); if (ValueListCell == NULL) { + DPRINT("CmiGetBlock() failed\n"); return 0; } for (i = 0; i < KeyCell->NumberOfValues; i++) { - CurValueCell = CmiGetBlock(RegistryHive, - ValueListCell->Values[i], - NULL); + CurValueCell = CmiGetBlock (RegistryHive, + ValueListCell->Values[i], + NULL); + if (CurValueCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + } + if (CurValueCell != NULL && MaxValueName < CurValueCell->NameSize) { MaxValueName = CurValueCell->NameSize; } - CmiReleaseBlock(RegistryHive, CurValueCell); } - CmiReleaseBlock(RegistryHive, ValueListCell); - return MaxValueName; } -ULONG +ULONG CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive, - PKEY_CELL KeyCell) + PKEY_CELL KeyCell) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; @@ -1128,8 +1931,8 @@ CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive, VERIFY_KEY_CELL(KeyCell); - ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); MaxValueData = 0; + ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); if (ValueListCell == NULL) { return 0; @@ -1144,27 +1947,24 @@ CmiGetMaxValueDataLength(PREGISTRY_HIVE RegistryHive, { MaxValueData = CurValueCell->DataSize & LONG_MAX; } - CmiReleaseBlock(RegistryHive, CurValueCell); } - CmiReleaseBlock(RegistryHive, ValueListCell); - return MaxValueData; } NTSTATUS CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - OUT PKEY_CELL *SubKeyCell, - OUT BLOCK_OFFSET *BlockOffset, - IN PCHAR KeyName, - IN ACCESS_MASK DesiredAccess, - IN ULONG Attributes) + IN PKEY_CELL KeyCell, + OUT PKEY_CELL *SubKeyCell, + OUT BLOCK_OFFSET *BlockOffset, + IN PCHAR KeyName, + IN ACCESS_MASK DesiredAccess, + IN ULONG Attributes) { PHASH_TABLE_CELL HashBlock; PKEY_CELL CurSubKeyCell; - WORD KeyLength; + USHORT KeyLength; ULONG i; VERIFY_KEY_CELL(KeyCell); @@ -1173,27 +1973,40 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, assert(RegistryHive); - KeyLength = strlen(KeyName); + *SubKeyCell = NULL; + + /* The key does not have any subkeys */ + if (KeyCell->HashTableOffset == (BLOCK_OFFSET)-1) + { + return STATUS_SUCCESS; + } + /* Get hash table */ HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); - *SubKeyCell = NULL; if (HashBlock == NULL) { - return STATUS_SUCCESS; + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; } - for (i = 0; (i < KeyCell->NumberOfSubKeys) - && (i < HashBlock->HashTableSize); i++) + KeyLength = strlen(KeyName); + for (i = 0; (i < KeyCell->NumberOfSubKeys) && (i < HashBlock->HashTableSize); i++) { if (Attributes & OBJ_CASE_INSENSITIVE) - { - if ((HashBlock->Table[i].KeyOffset != 0) && - (HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1) && - (_strnicmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4) == 0)) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset, - NULL); + { + if ((HashBlock->Table[i].KeyOffset != 0) && + (HashBlock->Table[i].KeyOffset != (ULONG_PTR)-1) && + (_strnicmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4) == 0)) + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (CurSubKeyCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + if ((CurSubKeyCell->NameSize == KeyLength) && (_strnicmp(KeyName, CurSubKeyCell->Name, KeyLength) == 0)) { @@ -1201,20 +2014,23 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, *BlockOffset = HashBlock->Table[i].KeyOffset; break; } - else - { - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } } - } + } else - { - if (HashBlock->Table[i].KeyOffset != 0 && - HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 && - !strncmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4)) - { - CurSubKeyCell = CmiGetBlock(RegistryHive, - HashBlock->Table[i].KeyOffset,NULL); + { + if (HashBlock->Table[i].KeyOffset != 0 && + HashBlock->Table[i].KeyOffset != (ULONG_PTR) -1 && + !strncmp(KeyName, (PCHAR) &HashBlock->Table[i].HashValue, 4)) + { + CurSubKeyCell = CmiGetBlock(RegistryHive, + HashBlock->Table[i].KeyOffset, + NULL); + if (CurSubKeyCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + if (CurSubKeyCell->NameSize == KeyLength && !_strnicmp(KeyName, CurSubKeyCell->Name, KeyLength)) { @@ -1222,16 +2038,10 @@ CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive, *BlockOffset = HashBlock->Table[i].KeyOffset; break; } - else - { - CmiReleaseBlock(RegistryHive, CurSubKeyCell); - } } - } + } } - - CmiReleaseBlock(RegistryHive, HashBlock); - + return STATUS_SUCCESS; } @@ -1272,10 +2082,9 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, NewBlockSize = sizeof(KEY_CELL) + NameSize; Status = CmiAllocateBlock(RegistryHive, - (PVOID) &NewKeyCell, - NewBlockSize, - &NKBOffset); - + (PVOID) &NewKeyCell, + NewBlockSize, + &NKBOffset); if (NewKeyCell == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1319,8 +2128,8 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, SubKey->KeyCell = NewKeyCell; SubKey->BlockOffset = NKBOffset; - /* Don't modify hash table if key is volatile and parent is not */ - if (IsVolatileHive(RegistryHive) && (!IsVolatileHive(Parent->RegistryHive))) + /* Don't modify hash table if key is located in a pointer-based hive and parent key is not */ + if (IsPointerHive(RegistryHive) && (!IsPointerHive(Parent->RegistryHive))) { return(Status); } @@ -1339,6 +2148,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, else { HashBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); + if (HashBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + if (((KeyCell->NumberOfSubKeys + 1) >= HashBlock->HashTableSize)) { BLOCK_OFFSET HTOffset; @@ -1386,17 +2201,87 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, PKEY_OBJECT SubKey) { PHASH_TABLE_CELL HashBlock; + PVALUE_LIST_CELL ValueList; + PVALUE_CELL ValueCell; + PDATA_CELL DataCell; + ULONG i; + + DPRINT("CmiRemoveSubKey() called\n"); + + /* Remove all values */ + if (SubKey->KeyCell->NumberOfValues != 0) + { + /* Get pointer to the value list cell */ + ValueList = CmiGetBlock(RegistryHive, + SubKey->KeyCell->ValuesOffset, + NULL); + if (ValueList == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + + if (ValueList != NULL) + { + /* Enumerate all values */ + for (i = 0; i < SubKey->KeyCell->NumberOfValues; i++) + { + /* Get pointer to value cell */ + ValueCell = CmiGetBlock(RegistryHive, + ValueList->Values[i], + NULL); + if (ValueCell != NULL) + { + if (ValueCell->DataSize > 4) + { + DataCell = CmiGetBlock(RegistryHive, + ValueCell->DataOffset, + NULL); + if (DataCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + + if (DataCell != NULL) + { + /* Destroy data cell */ + CmiDestroyBlock(RegistryHive, + DataCell, + ValueCell->DataOffset); + } + } + + /* Destroy value cell */ + CmiDestroyBlock(RegistryHive, + ValueCell, + ValueList->Values[i]); + } + } + } + + /* Destroy value list cell */ + CmiDestroyBlock(RegistryHive, + ValueList, + SubKey->KeyCell->ValuesOffset); - DPRINT1("CmiRemoveSubKey() called\n"); + SubKey->KeyCell->NumberOfValues = 0; + SubKey->KeyCell->ValuesOffset = -1; + } /* Remove the key from the parent key's hash block */ - if (ParentKey->KeyCell->HashTableOffset != -1) + if (ParentKey->KeyCell->HashTableOffset != (BLOCK_OFFSET) -1) { - DPRINT1("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset) + DPRINT("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset) HashBlock = CmiGetBlock(RegistryHive, ParentKey->KeyCell->HashTableOffset, NULL); - DPRINT1("ParentKey HashBlock %p\n", HashBlock) + if (HashBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + DPRINT("ParentKey HashBlock %p\n", HashBlock) if (HashBlock != NULL) { CmiRemoveKeyFromHashTable(RegistryHive, @@ -1408,13 +2293,18 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, } /* Remove the key's hash block */ - if (SubKey->KeyCell->HashTableOffset != -1) + if (SubKey->KeyCell->HashTableOffset != (BLOCK_OFFSET) -1) { - DPRINT1("SubKey HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset) + DPRINT("SubKey HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset) HashBlock = CmiGetBlock(RegistryHive, SubKey->KeyCell->HashTableOffset, NULL); - DPRINT1("SubKey HashBlock %p\n", HashBlock) + if (HashBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + DPRINT("SubKey HashBlock %p\n", HashBlock) if (HashBlock != NULL) { CmiDestroyBlock(RegistryHive, @@ -1427,18 +2317,34 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, /* Decrement the number of the parent key's sub keys */ if (ParentKey != NULL) { - DPRINT1("ParentKey %p\n", ParentKey) + DPRINT("ParentKey %p\n", ParentKey) ParentKey->KeyCell->NumberOfSubKeys--; - NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime); - CmiMarkBlockDirty(RegistryHive, - ParentKey->BlockOffset); /* Remove the parent key's hash table */ if (ParentKey->KeyCell->NumberOfSubKeys == 0) { - DPRINT1("FIXME: Remove parent key hash table\n") - + DPRINT("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset) + HashBlock = CmiGetBlock(RegistryHive, + ParentKey->KeyCell->HashTableOffset, + NULL); + if (HashBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + DPRINT("ParentKey HashBlock %p\n", HashBlock) + if (HashBlock != NULL) + { + CmiDestroyBlock(RegistryHive, + HashBlock, + ParentKey->KeyCell->HashTableOffset); + ParentKey->KeyCell->HashTableOffset = -1; + } } + + NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime); + CmiMarkBlockDirty(RegistryHive, + ParentKey->BlockOffset); } /* Destroy key cell */ @@ -1448,31 +2354,34 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive, SubKey->BlockOffset = -1; SubKey->KeyCell = NULL; - /* FIXME: Merge free blocks within the Bin */ - return(STATUS_SUCCESS); } NTSTATUS CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN PUNICODE_STRING ValueName, - OUT PVALUE_CELL *ValueCell, - OUT BLOCK_OFFSET *VBOffset) + IN PKEY_CELL KeyCell, + IN PUNICODE_STRING ValueName, + OUT PVALUE_CELL *ValueCell, + OUT BLOCK_OFFSET *VBOffset) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; ULONG i; - ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); - *ValueCell = NULL; + /* The key does not have any values */ + if (KeyCell->ValuesOffset == (BLOCK_OFFSET)-1) + { + return STATUS_SUCCESS; + } + + ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); if (ValueListCell == NULL) { DPRINT("ValueListCell is NULL\n"); - return STATUS_SUCCESS; + return STATUS_UNSUCCESSFUL; } VERIFY_VALUE_LIST_CELL(ValueListCell); @@ -1482,64 +2391,72 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive, CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL); + if (CurValueCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } if ((CurValueCell != NULL) && CmiComparePackedNames(ValueName, CurValueCell->Name, CurValueCell->NameSize, CurValueCell->Flags & REG_VALUE_NAME_PACKED)) - { - *ValueCell = CurValueCell; - if (VBOffset) - *VBOffset = ValueListCell->Values[i]; - //DPRINT("Found value %s\n", ValueName); - break; - } - CmiReleaseBlock(RegistryHive, CurValueCell); + { + *ValueCell = CurValueCell; + if (VBOffset) + *VBOffset = ValueListCell->Values[i]; + //DPRINT("Found value %s\n", ValueName); + break; + } } - CmiReleaseBlock(RegistryHive, ValueListCell); - return STATUS_SUCCESS; } NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN ULONG Index, - OUT PVALUE_CELL *ValueCell) + IN PKEY_CELL KeyCell, + IN ULONG Index, + OUT PVALUE_CELL *ValueCell) { PVALUE_LIST_CELL ValueListCell; PVALUE_CELL CurValueCell; - ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); - *ValueCell = NULL; - if (ValueListCell == NULL) + if (KeyCell->ValuesOffset == (BLOCK_OFFSET)-1) { return STATUS_NO_MORE_ENTRIES; } - VERIFY_VALUE_LIST_CELL(ValueListCell); - if (Index >= KeyCell->NumberOfValues) { return STATUS_NO_MORE_ENTRIES; } - CurValueCell = CmiGetBlock(RegistryHive, - ValueListCell->Values[Index], - NULL); - if (CurValueCell != NULL) + ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); + if (ValueListCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + + VERIFY_VALUE_LIST_CELL(ValueListCell); + + + CurValueCell = CmiGetBlock(RegistryHive, + ValueListCell->Values[Index], + NULL); + if (CurValueCell == NULL) { - *ValueCell = CurValueCell; + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; } - CmiReleaseBlock(RegistryHive, CurValueCell); - CmiReleaseBlock(RegistryHive, ValueListCell); + *ValueCell = CurValueCell; return STATUS_SUCCESS; } @@ -1547,10 +2464,10 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, - IN PKEY_CELL KeyCell, - IN PUNICODE_STRING ValueName, - OUT PVALUE_CELL *pValueCell, - OUT BLOCK_OFFSET *pVBOffset) + IN PKEY_CELL KeyCell, + IN PUNICODE_STRING ValueName, + OUT PVALUE_CELL *pValueCell, + OUT BLOCK_OFFSET *pVBOffset) { PVALUE_LIST_CELL NewValueListCell; PVALUE_LIST_CELL ValueListCell; @@ -1560,16 +2477,16 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, NTSTATUS Status; Status = CmiAllocateValueCell(RegistryHive, - &NewValueCell, - &VBOffset, - ValueName); - *pVBOffset = VBOffset; - + &NewValueCell, + &VBOffset, + ValueName); if (!NT_SUCCESS(Status)) { return Status; } + DPRINT("KeyCell->ValuesOffset %lu\n", (ULONG)KeyCell->ValuesOffset); + ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); if (ValueListCell == NULL) @@ -1580,44 +2497,45 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, &VLBOffset); if (!NT_SUCCESS(Status)) - { - CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset); - return Status; - } + { + CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset); + return Status; + } KeyCell->ValuesOffset = VLBOffset; } - else if ((KeyCell->NumberOfValues - >= (ULONG) ((LONG) (ValueListCell->CellSize - 4)) / (LONG) sizeof(BLOCK_OFFSET))) + else if (KeyCell->NumberOfValues >= + (((ULONG)ABS_VALUE(ValueListCell->CellSize) - 4) / sizeof(BLOCK_OFFSET))) { Status = CmiAllocateBlock(RegistryHive, - (PVOID) &NewValueListCell, - sizeof(BLOCK_OFFSET) * (KeyCell->NumberOfValues + REG_VALUE_LIST_CELL_MULTIPLE), - &VLBOffset); - + (PVOID) &NewValueListCell, + (KeyCell->NumberOfValues + REG_VALUE_LIST_CELL_MULTIPLE) * + sizeof(BLOCK_OFFSET), + &VLBOffset); if (!NT_SUCCESS(Status)) - { - CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset); - return Status; - } + { + CmiDestroyValueCell(RegistryHive, NewValueCell, VBOffset); + return Status; + } RtlCopyMemory(&NewValueListCell->Values[0], - &ValueListCell->Values[0], - sizeof(BLOCK_OFFSET) * KeyCell->NumberOfValues); + &ValueListCell->Values[0], + sizeof(BLOCK_OFFSET) * KeyCell->NumberOfValues); CmiDestroyBlock(RegistryHive, ValueListCell, KeyCell->ValuesOffset); KeyCell->ValuesOffset = VLBOffset; ValueListCell = NewValueListCell; } - DPRINT("KeyCell->NumberOfValues %d, ValueListCell->CellSize %d (%d %x)\n", - KeyCell->NumberOfValues, ValueListCell->CellSize, - -(ValueListCell->CellSize - 4) / sizeof(BLOCK_OFFSET), - -(ValueListCell->CellSize - 4) / sizeof(BLOCK_OFFSET)); + DPRINT("KeyCell->NumberOfValues %lu, ValueListCell->CellSize %lu (%lu %lx)\n", + KeyCell->NumberOfValues, + (ULONG)ABS_VALUE(ValueListCell->CellSize), + ((ULONG)ABS_VALUE(ValueListCell->CellSize) - 4) / sizeof(BLOCK_OFFSET), + ((ULONG)ABS_VALUE(ValueListCell->CellSize) - 4) / sizeof(BLOCK_OFFSET)); ValueListCell->Values[KeyCell->NumberOfValues] = VBOffset; KeyCell->NumberOfValues++; - CmiReleaseBlock(RegistryHive, ValueListCell); - CmiReleaseBlock(RegistryHive, NewValueCell); + *pValueCell = NewValueCell; + *pVBOffset = VBOffset; return STATUS_SUCCESS; } @@ -1637,6 +2555,7 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, if (ValueListCell == NULL) { + DPRINT("CmiGetBlock() failed\n"); return STATUS_SUCCESS; } @@ -1645,32 +2564,35 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, for (i = 0; i < KeyCell->NumberOfValues; i++) { CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL); + if (CurValueCell == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } if ((CurValueCell != NULL) && CmiComparePackedNames(ValueName, CurValueCell->Name, CurValueCell->NameSize, CurValueCell->Flags & REG_VALUE_NAME_PACKED)) - { - if ((KeyCell->NumberOfValues - 1) < i) - { - RtlCopyMemory(&ValueListCell->Values[i], - &ValueListCell->Values[i + 1], - sizeof(BLOCK_OFFSET) * (KeyCell->NumberOfValues - 1 - i)); - } - else - { - RtlZeroMemory(&ValueListCell->Values[i], sizeof(BLOCK_OFFSET)); - } + { + CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]); - KeyCell->NumberOfValues -= 1; - CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]); - break; - } - CmiReleaseBlock(RegistryHive, CurValueCell); - } + if ((KeyCell->NumberOfValues - 1) < i) + { + RtlCopyMemory(&ValueListCell->Values[i], + &ValueListCell->Values[i + 1], + sizeof(BLOCK_OFFSET) * (KeyCell->NumberOfValues - 1 - i)); + } + else + { + RtlZeroMemory(&ValueListCell->Values[i], sizeof(BLOCK_OFFSET)); + } - CmiReleaseBlock(RegistryHive, ValueListCell); + KeyCell->NumberOfValues -= 1; + break; + } + } if (KeyCell->NumberOfValues == 0) { @@ -1727,8 +2649,8 @@ CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, PKEY_CELL CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive, - PHASH_TABLE_CELL HashBlock, - ULONG Index) + PHASH_TABLE_CELL HashBlock, + ULONG Index) { BLOCK_OFFSET KeyOffset; PKEY_CELL KeyCell; @@ -1736,7 +2658,7 @@ CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive, if (HashBlock == NULL) return NULL; - if (IsVolatileHive(RegistryHive)) + if (IsPointerHive(RegistryHive)) { KeyCell = (PKEY_CELL) HashBlock->Table[Index].KeyOffset; } @@ -1745,7 +2667,6 @@ CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive, KeyOffset = HashBlock->Table[Index].KeyOffset; KeyCell = CmiGetBlock(RegistryHive, KeyOffset, NULL); } - CmiLockBlock(RegistryHive, KeyCell); return KeyCell; } @@ -1753,9 +2674,9 @@ CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive, - PHASH_TABLE_CELL HashBlock, - PKEY_CELL NewKeyCell, - BLOCK_OFFSET NKBOffset) + PHASH_TABLE_CELL HashBlock, + PKEY_CELL NewKeyCell, + BLOCK_OFFSET NKBOffset) { ULONG i; @@ -1796,9 +2717,9 @@ CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, - PVALUE_CELL *ValueCell, - BLOCK_OFFSET *VBOffset, - IN PUNICODE_STRING ValueName) + PVALUE_CELL *ValueCell, + BLOCK_OFFSET *VBOffset, + IN PUNICODE_STRING ValueName) { PVALUE_CELL NewValueCell; NTSTATUS Status; @@ -1852,19 +2773,27 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, - PVALUE_CELL ValueCell, - BLOCK_OFFSET VBOffset) + PVALUE_CELL ValueCell, + BLOCK_OFFSET VBOffset) { NTSTATUS Status; PVOID pBlock; PHBIN pBin; + DPRINT("CmiDestroyValueCell(Cell %p Offset %lx)\n", ValueCell, VBOffset); + VERIFY_VALUE_CELL(ValueCell); - /* First, release data: */ + /* Destroy the data cell */ if (ValueCell->DataSize > 4) { pBlock = CmiGetBlock(RegistryHive, ValueCell->DataOffset, &pBin); + if (pBlock == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } + Status = CmiDestroyBlock(RegistryHive, pBlock, ValueCell->DataOffset); if (!NT_SUCCESS(Status)) { @@ -1872,16 +2801,17 @@ CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, } /* Update time of heap */ - if (IsPermanentHive(RegistryHive)) - ZwQuerySystemTime((PTIME) &pBin->DateModified); + if (!IsVolatileHive(RegistryHive)) + NtQuerySystemTime((PTIME) &pBin->DateModified); } + /* Destroy the value cell */ Status = CmiDestroyBlock(RegistryHive, ValueCell, VBOffset); /* Update time of heap */ - if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) + if (!IsVolatileHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) { - ZwQuerySystemTime((PTIME) &pBin->DateModified); + NtQuerySystemTime((PTIME) &pBin->DateModified); } return Status; @@ -1890,8 +2820,8 @@ CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiAddBin(PREGISTRY_HIVE RegistryHive, - PVOID *NewBlock, - BLOCK_OFFSET *NewBlockOffset) + PVOID *NewBlock, + BLOCK_OFFSET *NewBlockOffset) { PCELL_HEADER tmpBlock; PHBIN * tmpBlockList; @@ -1922,14 +2852,15 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, if (RegistryHive->BlockListSize > 0) { - memcpy(tmpBlockList, - RegistryHive->BlockList, - sizeof(PHBIN *)*(RegistryHive->BlockListSize)); + RtlCopyMemory (tmpBlockList, + RegistryHive->BlockList, + sizeof(PHBIN *)*(RegistryHive->BlockListSize)); ExFreePool(RegistryHive->BlockList); } RegistryHive->BlockList = tmpBlockList; - RegistryHive->BlockList[RegistryHive->BlockListSize++] = tmpBin; + RegistryHive->BlockList[RegistryHive->BlockListSize] = tmpBin; + RegistryHive->BlockListSize++; /* Initialize a free block in this heap : */ tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET); @@ -1939,10 +2870,26 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, if (IsVolatileHive(RegistryHive) && (RegistryHive->BlockListSize % (sizeof(ULONG) * 8) == 0)) { - DPRINT1("Grow hive bitmap - BlockListSize %lu\n", RegistryHive->BlockListSize); + PULONG BitmapBuffer; + ULONG BitmapSize; - /* FIXME */ + DPRINT("Grow hive bitmap\n"); + /* Calculate bitmap size in bytes (always a multiple of 32 bits) */ + BitmapSize = ROUND_UP(RegistryHive->BlockListSize, sizeof(ULONG) * 8) / 8; + DPRINT("RegistryHive->BlockListSize: %lu\n", RegistryHive->BlockListSize); + DPRINT("BitmapSize: %lu Bytes %lu Bits\n", BitmapSize, BitmapSize * 8); + BitmapBuffer = (PULONG)ExAllocatePool(PagedPool, + BitmapSize); + RtlZeroMemory(BitmapBuffer, BitmapSize); + RtlCopyMemory(BitmapBuffer, + RegistryHive->DirtyBitMap.Buffer, + RegistryHive->DirtyBitMap.SizeOfBitMap); + ExFreePool(RegistryHive->BitmapBuffer); + RegistryHive->BitmapBuffer = BitmapBuffer; + RtlInitializeBitMap(&RegistryHive->DirtyBitMap, + RegistryHive->BitmapBuffer, + BitmapSize * 8); } *NewBlock = (PVOID) tmpBlock; @@ -1950,7 +2897,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive, if (NewBlockOffset) *NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; - /* FIXME: set first dword to block_offset of another free bloc */ + /* Mark new bin dirty */ + CmiMarkBinDirty(RegistryHive, + tmpBin->BlockOffset); return STATUS_SUCCESS; } @@ -1965,6 +2914,8 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, PCELL_HEADER NewBlock; NTSTATUS Status; PHBIN pBin; + ULONG i; + PVOID Temp; Status = STATUS_SUCCESS; @@ -1972,7 +2923,7 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, BlockSize = (BlockSize + sizeof(DWORD) + 15) & 0xfffffff0; /* Handle volatile hives first */ - if (IsVolatileHive(RegistryHive)) + if (IsPointerHive(RegistryHive)) { NewBlock = ExAllocatePool(NonPagedPool, BlockSize); @@ -1984,7 +2935,6 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, { RtlZeroMemory(NewBlock, BlockSize); NewBlock->CellSize = BlockSize; - CmiLockBlock(RegistryHive, NewBlock); *Block = NewBlock; if (pBlockOffset) *pBlockOffset = (BLOCK_OFFSET) NewBlock; @@ -1992,26 +2942,27 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, } else { - ULONG i; - /* first search in free blocks */ NewBlock = NULL; for (i = 0; i < RegistryHive->FreeListSize; i++) { if (RegistryHive->FreeList[i]->CellSize >= BlockSize) { - PVOID Temp; - NewBlock = RegistryHive->FreeList[i]; if (pBlockOffset) *pBlockOffset = RegistryHive->FreeListOffset[i]; /* Update time of heap */ Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin); + if (Temp == NULL) + { + DPRINT("CmiGetBlock() failed\n"); + return STATUS_UNSUCCESSFUL; + } if (Temp) { - ZwQuerySystemTime((PTIME) &pBin->DateModified); + NtQuerySystemTime((PTIME) &pBin->DateModified); CmiMarkBlockDirty(RegistryHive, RegistryHive->FreeListOffset[i]); } @@ -2047,8 +2998,12 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, { NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; - CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize); - CmiMarkBlockDirty(RegistryHive, *pBlockOffset + BlockSize); + CmiAddFree(RegistryHive, + NewBlock, + *pBlockOffset + BlockSize, + TRUE); + CmiMarkBlockDirty(RegistryHive, + *pBlockOffset + BlockSize); } else if (NewBlock->CellSize < BlockSize) { @@ -2057,7 +3012,6 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, RtlZeroMemory(*Block, BlockSize); ((PCELL_HEADER) (*Block))->CellSize = -BlockSize; - CmiLockBlock(RegistryHive, *Block); } } @@ -2067,17 +3021,16 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, NTSTATUS CmiDestroyBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block, - BLOCK_OFFSET Offset) + PVOID Block, + BLOCK_OFFSET Offset) { NTSTATUS Status; PHBIN pBin; Status = STATUS_SUCCESS; - if (IsVolatileHive(RegistryHive)) + if (IsPointerHive(RegistryHive)) { - CmiReleaseBlock(RegistryHive, Block); ExFreePool(Block); } else @@ -2091,98 +3044,184 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive, RtlZeroMemory(((PVOID)pFree) + sizeof(ULONG), pFree->CellSize - sizeof(ULONG)); - CmiAddFree(RegistryHive, Block, Offset); - CmiReleaseBlock(RegistryHive, Block); + /* Add block to the list of free blocks */ + CmiAddFree(RegistryHive, Block, Offset, TRUE); /* Update time of heap */ - if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin)) - ZwQuerySystemTime((PTIME) &pBin->DateModified); + if (!IsVolatileHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin)) + NtQuerySystemTime((PTIME) &pBin->DateModified); CmiMarkBlockDirty(RegistryHive, Offset); - - /* FIXME: Set first dword to block_offset of another free block ? */ - /* FIXME: Concatenate with previous and next block if free */ } return Status; } +static BOOLEAN +CmiMergeFree(PREGISTRY_HIVE RegistryHive, + PCELL_HEADER FreeBlock, + BLOCK_OFFSET FreeOffset) +{ + BLOCK_OFFSET BlockOffset; + BLOCK_OFFSET BinOffset; + ULONG BlockSize; + ULONG BinSize; + PHBIN Bin; + ULONG i; + + DPRINT("CmiMergeFree(Block %lx Offset %lx Size %lx) called\n", + FreeBlock, FreeOffset, FreeBlock->CellSize); + + CmiGetBlock(RegistryHive, + FreeOffset, + &Bin); + DPRINT("Bin %p\n", Bin); + if (Bin == NULL) + return(FALSE); + + BinOffset = Bin->BlockOffset; + BinSize = Bin->BlockSize; + DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize); + + for (i = 0; i < RegistryHive->FreeListSize; i++) + { + BlockOffset = RegistryHive->FreeListOffset[i]; + BlockSize = RegistryHive->FreeList[i]->CellSize; + if (BlockOffset > BinOffset && + BlockOffset < BinOffset + BinSize) + { + DPRINT("Free block: Offset %lx Size %lx\n", + BlockOffset, BlockSize); + + if ((i < (RegistryHive->FreeListSize - 1)) && + (BlockOffset + BlockSize == FreeOffset) && + (FreeOffset + FreeBlock->CellSize == RegistryHive->FreeListOffset[i + 1])) + { + DPRINT("Merge current block with previous and next block\n"); + + RegistryHive->FreeList[i]->CellSize += + (FreeBlock->CellSize + RegistryHive->FreeList[i + 1]->CellSize); + + FreeBlock->CellSize = 0; + RegistryHive->FreeList[i + 1]->CellSize = 0; + + + if ((i + 2) < RegistryHive->FreeListSize) + { + RtlMoveMemory(&RegistryHive->FreeList[i + 1], + &RegistryHive->FreeList[i + 2], + sizeof(RegistryHive->FreeList[0]) + * (RegistryHive->FreeListSize - i - 2)); + RtlMoveMemory(&RegistryHive->FreeListOffset[i + 1], + &RegistryHive->FreeListOffset[i + 2], + sizeof(RegistryHive->FreeListOffset[0]) + * (RegistryHive->FreeListSize - i - 2)); + } + RegistryHive->FreeListSize--; + + CmiMarkBlockDirty(RegistryHive, BlockOffset); + + return(TRUE); + } + else if (BlockOffset + BlockSize == FreeOffset) + { + DPRINT("Merge current block with previous block\n"); + + RegistryHive->FreeList[i]->CellSize += FreeBlock->CellSize; + FreeBlock->CellSize = 0; + + CmiMarkBlockDirty(RegistryHive, BlockOffset); + + return(TRUE); + } + else if (FreeOffset + FreeBlock->CellSize == BlockOffset) + { + DPRINT("Merge current block with next block\n"); + + FreeBlock->CellSize += RegistryHive->FreeList[i]->CellSize; + RegistryHive->FreeList[i]->CellSize = 0; + RegistryHive->FreeList[i] = FreeBlock; + RegistryHive->FreeListOffset[i] = FreeOffset; + + CmiMarkBlockDirty(RegistryHive, FreeOffset); + + return(TRUE); + } + } + } + + return(FALSE); +} + + NTSTATUS CmiAddFree(PREGISTRY_HIVE RegistryHive, - PCELL_HEADER FreeBlock, - BLOCK_OFFSET FreeOffset) + PCELL_HEADER FreeBlock, + BLOCK_OFFSET FreeOffset, + BOOLEAN MergeFreeBlocks) { - PCELL_HEADER *tmpList; - BLOCK_OFFSET *tmpListOffset; - LONG minInd; + PCELL_HEADER *tmpList; + BLOCK_OFFSET *tmpListOffset; + LONG minInd; LONG maxInd; LONG medInd; assert(RegistryHive); assert(FreeBlock); - DPRINT("FreeBlock %.08x FreeOffset %.08x\n", - FreeBlock, FreeOffset); -DPRINT("\n"); + DPRINT("FreeBlock %.08lx FreeOffset %.08lx\n", + FreeBlock, FreeOffset); + + /* Merge free blocks */ + if (MergeFreeBlocks == TRUE) + { + if (CmiMergeFree(RegistryHive, FreeBlock, FreeOffset)) + return(STATUS_SUCCESS); + } + if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax) { -DPRINT("\n"); tmpList = ExAllocatePool(PagedPool, sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32)); -DPRINT("\n"); - if (tmpList == NULL) return STATUS_INSUFFICIENT_RESOURCES; -DPRINT("\n"); tmpListOffset = ExAllocatePool(PagedPool, - sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32)); -DPRINT("\n"); + sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax + 32)); if (tmpListOffset == NULL) { ExFreePool(tmpList); return STATUS_INSUFFICIENT_RESOURCES; } -DPRINT("\n"); if (RegistryHive->FreeListMax) { -DPRINT("\n"); RtlMoveMemory(tmpList, RegistryHive->FreeList, sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); -DPRINT("\n"); RtlMoveMemory(tmpListOffset, RegistryHive->FreeListOffset, - sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax)); -DPRINT("\n"); + sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax)); ExFreePool(RegistryHive->FreeList); -DPRINT("\n"); ExFreePool(RegistryHive->FreeListOffset); -DPRINT("\n"); } -DPRINT("\n"); RegistryHive->FreeList = tmpList; RegistryHive->FreeListOffset = tmpListOffset; RegistryHive->FreeListMax += 32; -DPRINT("\n"); } -DPRINT("\n"); /* Add new offset to free list, maintaining list in ascending order */ if ((RegistryHive->FreeListSize == 0) || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset)) { -DPRINT("\n"); /* Add to end of list */ RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock; RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset; } else if (RegistryHive->FreeListOffset[0] > FreeOffset) { -DPRINT("\n"); /* Add to begin of list */ RtlMoveMemory(&RegistryHive->FreeList[1], &RegistryHive->FreeList[0], @@ -2196,7 +3235,6 @@ DPRINT("\n"); } else { -DPRINT("\n"); /* Search where to insert */ minInd = 0; maxInd = RegistryHive->FreeListSize - 1; @@ -2220,7 +3258,6 @@ DPRINT("\n"); RegistryHive->FreeListOffset[maxInd] = FreeOffset; RegistryHive->FreeListSize++; } -DPRINT("\n"); return STATUS_SUCCESS; } @@ -2231,68 +3268,103 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive, BLOCK_OFFSET BlockOffset, PHBIN * ppBin) { + PHBIN pBin; + if (ppBin) *ppBin = NULL; - if ((BlockOffset == 0) || (BlockOffset == (ULONG_PTR) -1)) - return NULL; + if (BlockOffset == (BLOCK_OFFSET)-1) + { + return NULL; + } - if (IsVolatileHive(RegistryHive)) + if (IsPointerHive (RegistryHive)) { - return (PVOID) BlockOffset; + return (PVOID)BlockOffset; } else { - PHBIN pBin; - + if (BlockOffset > RegistryHive->BlockListSize * 4096) + { + DPRINT1("BlockOffset exceeds valid range (%lu > %lu)\n", + BlockOffset, RegistryHive->BlockListSize * 4096); + return NULL; + } pBin = RegistryHive->BlockList[BlockOffset / 4096]; if (ppBin) *ppBin = pBin; - return ((PVOID) ((ULONG_PTR) pBin + (BlockOffset - pBin->BlockOffset))); + return((PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BlockOffset))); } } VOID -CmiLockBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block) +CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, + BLOCK_OFFSET BlockOffset) { - if (IsPermanentHive(RegistryHive)) - { - /* FIXME: Implement */ - } -} + PDATA_CELL Cell; + LONG CellSize; + ULONG BlockNumber; + ULONG BlockCount; + if (IsVolatileHive(RegistryHive)) + return; -VOID -CmiReleaseBlock(PREGISTRY_HIVE RegistryHive, - PVOID Block) -{ - if (IsPermanentHive(RegistryHive)) - { - /* FIXME: Implement */ - } + DPRINT("CmiMarkBlockDirty(Offset 0x%lx)\n", (ULONG)BlockOffset); + + BlockNumber = (ULONG)BlockOffset / 4096; + + Cell = CmiGetBlock(RegistryHive, + BlockOffset, + NULL); + + CellSize = Cell->CellSize; + if (CellSize < 0) + CellSize = -CellSize; + + BlockCount = (ROUND_UP(BlockOffset + CellSize, 4096) - ROUND_DOWN(BlockOffset, 4096)) / 4096; + + DPRINT(" BlockNumber %lu Size %lu (%s) BlockCount %lu\n", + BlockNumber, + CellSize, + (Cell->CellSize < 0) ? "used" : "free", + BlockCount); + + RegistryHive->HiveDirty = TRUE; + RtlSetBits(&RegistryHive->DirtyBitMap, + BlockNumber, + BlockCount); } VOID -CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive, - BLOCK_OFFSET BlockOffset) +CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive, + BLOCK_OFFSET BinOffset) { - ULONG Index; + ULONG BlockNumber; + ULONG BlockCount; + PHBIN Bin; if (IsVolatileHive(RegistryHive)) - return; + return; + + DPRINT("CmiMarkBinDirty(Offset 0x%lx)\n", (ULONG)BinOffset); + + BlockNumber = (ULONG)BinOffset / 4096; + + Bin = RegistryHive->BlockList[BlockNumber]; - Index = (ULONG)BlockOffset / 4096; + BlockCount = Bin->BlockSize / 4096; - DPRINT1("CmiMarkBlockDirty(Offset 0x%lx) Index %lu\n", - (ULONG)BlockOffset, Index); + DPRINT(" BlockNumber %lu Size %lu BlockCount %lu\n", + BlockNumber, + Bin->BlockSize, + BlockCount); RegistryHive->HiveDirty = TRUE; RtlSetBits(&RegistryHive->DirtyBitMap, - Index, - 1); + BlockNumber, + BlockCount); } diff --git a/ntoskrnl/cm/registry.c b/ntoskrnl/cm/registry.c index 8b7769e..e354c1f 100644 --- a/ntoskrnl/cm/registry.c +++ b/ntoskrnl/cm/registry.c @@ -11,9 +11,6 @@ * Created 22/05/98 */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include #include @@ -26,9 +23,8 @@ #include #include "cm.h" -#endif -/* ------------------------------------------------- File Statics */ +/* GLOBALS ******************************************************************/ POBJECT_TYPE CmiKeyType = NULL; PREGISTRY_HIVE CmiVolatileHive = NULL; @@ -42,11 +38,6 @@ volatile BOOLEAN CmiHiveSyncPending = FALSE; KDPC CmiHiveSyncDpc; KTIMER CmiHiveSyncTimer; -static PKEY_OBJECT CmiRootKey = NULL; -static PKEY_OBJECT CmiMachineKey = NULL; -static PKEY_OBJECT CmiUserKey = NULL; -static PKEY_OBJECT CmiHardwareKey = NULL; - static GENERIC_MAPPING CmiKeyMapping = {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS}; @@ -260,8 +251,10 @@ CmInitializeRegistry(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING RootKeyName; + PKEY_OBJECT RootKey; + PKEY_OBJECT MachineKey; + PKEY_OBJECT UserKey; HANDLE RootKeyHandle; - PKEY_OBJECT NewKey; HANDLE KeyHandle; NTSTATUS Status; @@ -280,7 +273,7 @@ CmInitializeRegistry(VOID) CmiKeyType->Close = NULL; CmiKeyType->Delete = CmiObjectDelete; CmiKeyType->Parse = CmiObjectParse; - CmiKeyType->Security = NULL; + CmiKeyType->Security = CmiObjectSecurity; CmiKeyType->QueryName = NULL; CmiKeyType->OkayToClose = NULL; CmiKeyType->Create = CmiObjectCreate; @@ -302,192 +295,79 @@ CmInitializeRegistry(VOID) STANDARD_RIGHTS_REQUIRED, &ObjectAttributes, CmiKeyType, - (PVOID *) &NewKey); + (PVOID *) &RootKey); assert(NT_SUCCESS(Status)); - CmiRootKey = NewKey; Status = ObReferenceObjectByHandle(RootKeyHandle, - STANDARD_RIGHTS_REQUIRED, - CmiKeyType, - KernelMode, - (PVOID *) &CmiRootKey, - NULL); + STANDARD_RIGHTS_REQUIRED, + CmiKeyType, + KernelMode, + (PVOID *)&RootKey, + NULL); assert(NT_SUCCESS(Status)); - CmiRootKey->RegistryHive = CmiVolatileHive; - NewKey->BlockOffset = CmiVolatileHive->HiveHeader->RootKeyCell; - NewKey->KeyCell = CmiGetBlock(CmiVolatileHive, NewKey->BlockOffset, NULL); - CmiRootKey->Flags = 0; - CmiRootKey->NumberOfSubKeys = 0; - CmiRootKey->SubKeys = NULL; - CmiRootKey->SizeOfSubKeys = 0; - CmiRootKey->Name = ExAllocatePool(PagedPool, strlen("Registry")); - CmiRootKey->NameSize = strlen("Registry"); - memcpy(CmiRootKey->Name, "Registry", strlen("Registry")); + RootKey->RegistryHive = CmiVolatileHive; + RootKey->BlockOffset = CmiVolatileHive->HiveHeader->RootKeyCell; + RootKey->KeyCell = CmiGetBlock(CmiVolatileHive, RootKey->BlockOffset, NULL); + RootKey->Flags = 0; + RootKey->NumberOfSubKeys = 0; + RootKey->SubKeys = NULL; + RootKey->SizeOfSubKeys = 0; + RootKey->NameSize = strlen("Registry"); + RootKey->Name = ExAllocatePool(PagedPool, RootKey->NameSize); + RtlCopyMemory(RootKey->Name, "Registry", RootKey->NameSize); KeInitializeSpinLock(&CmiKeyListLock); - /* Create initial predefined symbolic links */ - /* Create '\Registry\Machine' key. */ Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*) &NewKey); + STANDARD_RIGHTS_REQUIRED, + NULL, + CmiKeyType, + (PVOID*)&MachineKey); assert(NT_SUCCESS(Status)); Status = CmiAddSubKey(CmiVolatileHive, - CmiRootKey, - NewKey, - L"Machine", - wcslen(L"Machine") * sizeof(WCHAR), - 0, - NULL, - 0); + RootKey, + MachineKey, + L"Machine", + wcslen(L"Machine") * sizeof(WCHAR), + 0, + NULL, + 0); assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("Machine")); - NewKey->NameSize = strlen("Machine"); - memcpy(NewKey->Name, "Machine", strlen("Machine")); - CmiAddKeyToList(CmiRootKey, NewKey); - CmiMachineKey = NewKey; + MachineKey->RegistryHive = CmiVolatileHive; + MachineKey->Flags = 0; + MachineKey->NumberOfSubKeys = 0; + MachineKey->SubKeys = NULL; + MachineKey->SizeOfSubKeys = MachineKey->KeyCell->NumberOfSubKeys; + MachineKey->NameSize = strlen("Machine"); + MachineKey->Name = ExAllocatePool(PagedPool, MachineKey->NameSize); + RtlCopyMemory(MachineKey->Name, "Machine", MachineKey->NameSize); + CmiAddKeyToList(RootKey, MachineKey); /* Create '\Registry\User' key. */ Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*) &NewKey); - assert(NT_SUCCESS(Status)); - Status = CmiAddSubKey(CmiVolatileHive, - CmiRootKey, - NewKey, - L"User", - wcslen(L"User") * sizeof(WCHAR), - 0, - NULL, - 0); - assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("User")); - NewKey->NameSize = strlen("User"); - memcpy(NewKey->Name, "User", strlen("User")); - CmiAddKeyToList(CmiRootKey, NewKey); - CmiUserKey = NewKey; - - /* Create '\Registry\Machine\HARDWARE' key. */ - Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*)&NewKey); - assert(NT_SUCCESS(Status)); - Status = CmiAddSubKey(CmiVolatileHive, - CmiMachineKey, - NewKey, - L"HARDWARE", - wcslen(L"HARDWARE") * sizeof(WCHAR), - 0, - NULL, - 0); - assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("HARDWARE")); - NewKey->NameSize = strlen("HARDWARE"); - memcpy(NewKey->Name, "HARDWARE", strlen("HARDWARE")); - CmiAddKeyToList(CmiMachineKey, NewKey); - CmiHardwareKey = NewKey; - - /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ - Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*) &NewKey); - assert(NT_SUCCESS(Status)); - Status = CmiAddSubKey(CmiVolatileHive, - CmiHardwareKey, - NewKey, - L"DESCRIPTION", - wcslen(L"DESCRIPTION") * sizeof(WCHAR), - 0, - NULL, - 0); - assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("DESCRIPTION")); - NewKey->NameSize = strlen("DESCRIPTION"); - memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION")); - CmiAddKeyToList(CmiHardwareKey, NewKey); - - /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ - Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*) &NewKey); - assert(NT_SUCCESS(Status)); - Status = CmiAddSubKey(CmiVolatileHive, - CmiHardwareKey, - NewKey, - L"DEVICEMAP", - wcslen(L"DEVICEMAP") * sizeof(WCHAR), - 0, - NULL, - 0); - assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("DEVICEMAP")); - NewKey->NameSize = strlen("DEVICEMAP"); - memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP")); - CmiAddKeyToList(CmiHardwareKey,NewKey); - - /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ - Status = ObCreateObject(&KeyHandle, - STANDARD_RIGHTS_REQUIRED, - NULL, - CmiKeyType, - (PVOID*) &NewKey); + STANDARD_RIGHTS_REQUIRED, + NULL, + CmiKeyType, + (PVOID*)&UserKey); assert(NT_SUCCESS(Status)); Status = CmiAddSubKey(CmiVolatileHive, - CmiHardwareKey, - NewKey, - L"RESOURCEMAP", - wcslen(L"RESOURCEMAP") * sizeof(WCHAR), - 0, - NULL, - 0); + RootKey, + UserKey, + L"User", + wcslen(L"User") * sizeof(WCHAR), + 0, + NULL, + 0); assert(NT_SUCCESS(Status)); - NewKey->RegistryHive = CmiVolatileHive; - NewKey->Flags = 0; - NewKey->NumberOfSubKeys = 0; - NewKey->SubKeys = NULL; - NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen("RESOURCEMAP")); - NewKey->NameSize = strlen("RESOURCEMAP"); - memcpy(NewKey->Name, "RESOURCEMAP", strlen("RESOURCEMAP")); - CmiAddKeyToList(CmiHardwareKey, NewKey); - - /* FIXME: create remaining structure needed for default handles */ - /* FIXME: load volatile registry data from ROSDTECT */ + UserKey->RegistryHive = CmiVolatileHive; + UserKey->Flags = 0; + UserKey->NumberOfSubKeys = 0; + UserKey->SubKeys = NULL; + UserKey->SizeOfSubKeys = UserKey->KeyCell->NumberOfSubKeys; + UserKey->NameSize = strlen("User"); + UserKey->Name = ExAllocatePool(PagedPool, UserKey->NameSize); + RtlCopyMemory(UserKey->Name, "User", UserKey->NameSize); + CmiAddKeyToList(RootKey, UserKey); } @@ -504,12 +384,10 @@ CmInit2(PCHAR CommandLine) /* Create the 'CurrentControlSet' link. */ Status = CmiCreateCurrentControlSetLink(); -#ifndef WIN32_REGDBG if (!NT_SUCCESS(Status)) { KeBugCheck(CONFIG_INITIALIZATION_FAILED); } -#endif /* Set PICE 'Start' value to 1, if PICE debugging is enabled */ PiceStart = 4; @@ -532,7 +410,7 @@ CmInit2(PCHAR CommandLine) } p1 = p2; } -#ifndef WIN32_REGDBG + Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, L"\\Pice", L"Start", @@ -543,7 +421,6 @@ CmInit2(PCHAR CommandLine) { KeBugCheck(CONFIG_INITIALIZATION_FAILED); } -#endif } @@ -603,7 +480,7 @@ CmiCreateCurrentControlSetLink(VOID) DPRINT("Link target '%S'\n", TargetNameBuffer); RtlInitUnicodeStringFromLiteral(&LinkName, - L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"); + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"); InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK, @@ -623,7 +500,7 @@ CmiCreateCurrentControlSetLink(VOID) } RtlInitUnicodeStringFromLiteral(&LinkValue, - L"SymbolicLinkValue"); + L"SymbolicLinkValue"); Status = NtSetValueKey(KeyHandle, &LinkValue, 0, @@ -642,33 +519,53 @@ CmiCreateCurrentControlSetLink(VOID) NTSTATUS -CmiConnectHive(PWSTR FileName, - PWSTR FullName, - PCHAR KeyName, - PKEY_OBJECT Parent, - BOOLEAN CreateNew) +CmiConnectHive(PREGISTRY_HIVE RegistryHive, + PUNICODE_STRING KeyName) { OBJECT_ATTRIBUTES ObjectAttributes; - PREGISTRY_HIVE RegistryHive = NULL; - UNICODE_STRING uKeyName; + UNICODE_STRING ParentKeyName; + PKEY_OBJECT ParentKey; PKEY_OBJECT NewKey; HANDLE KeyHandle; NTSTATUS Status; + PWSTR SubName; - DPRINT("CmiConnectHive(%S, %S, %s, %p, %d) - Called.\n", FileName, FullName, KeyName, Parent, CreateNew); + DPRINT("CmiConnectHive(%p, %wZ) called.\n", + RegistryHive, KeyName); - Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew); - if (!NT_SUCCESS(Status)) + SubName = wcsrchr (KeyName->Buffer, L'\\'); + if (SubName == NULL) { - DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status); - KeBugCheck(0); - return(Status); + return STATUS_UNSUCCESSFUL; } - RtlInitUnicodeString(&uKeyName, FullName); + ParentKeyName.Length = (USHORT)(SubName - KeyName->Buffer) * sizeof(WCHAR); + ParentKeyName.MaximumLength = ParentKeyName.Length + sizeof(WCHAR); + ParentKeyName.Buffer = ExAllocatePool (NonPagedPool, + ParentKeyName.MaximumLength); + RtlCopyMemory (ParentKeyName.Buffer, + KeyName->Buffer, + ParentKeyName.Length); + ParentKeyName.Buffer[ParentKeyName.Length / sizeof(WCHAR)] = 0; + SubName++; + + Status = ObReferenceObjectByName (&ParentKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + STANDARD_RIGHTS_REQUIRED, + CmiKeyType, + KernelMode, + NULL, + (PVOID*)&ParentKey); + RtlFreeUnicodeString (&ParentKeyName); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status); + return Status; + } InitializeObjectAttributes(&ObjectAttributes, - &uKeyName, + KeyName, 0, NULL, NULL); @@ -680,10 +577,9 @@ CmiConnectHive(PWSTR FileName, (PVOID*)&NewKey); if (!NT_SUCCESS(Status)) { - DPRINT1("ObCreateObject() failed (Status %lx)\n", Status); - KeBugCheck(0); - CmiRemoveRegistryHive(RegistryHive); - return(Status); + DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status); + ObDereferenceObject (ParentKey); + return Status; } NewKey->RegistryHive = RegistryHive; @@ -692,32 +588,36 @@ CmiConnectHive(PWSTR FileName, NewKey->Flags = 0; NewKey->NumberOfSubKeys = 0; NewKey->SubKeys = ExAllocatePool(PagedPool, - NewKey->KeyCell->NumberOfSubKeys * sizeof(DWORD)); + NewKey->KeyCell->NumberOfSubKeys * sizeof(ULONG)); if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0)) { DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys); - ZwClose(NewKey); - CmiRemoveRegistryHive(RegistryHive); + NtClose(NewKey); + ObDereferenceObject (ParentKey); return(STATUS_INSUFFICIENT_RESOURCES); } NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys; - NewKey->Name = ExAllocatePool(PagedPool, strlen(KeyName)); + NewKey->NameSize = wcslen (SubName); + NewKey->Name = ExAllocatePool(PagedPool, NewKey->NameSize); - if ((NewKey->Name == NULL) && (strlen(KeyName) != 0)) + if ((NewKey->Name == NULL) && (NewKey->NameSize != 0)) { - DPRINT("strlen(KeyName) %d\n", strlen(KeyName)); + DPRINT("NewKey->NameSize %d\n", NewKey->NameSize); if (NewKey->SubKeys != NULL) ExFreePool(NewKey->SubKeys); - ZwClose(NewKey); - CmiRemoveRegistryHive(RegistryHive); + NtClose(KeyHandle); + ObDereferenceObject (ParentKey); return(STATUS_INSUFFICIENT_RESOURCES); } - NewKey->NameSize = strlen(KeyName); - memcpy(NewKey->Name, KeyName, strlen(KeyName)); - CmiAddKeyToList(Parent, NewKey); + wcstombs (NewKey->Name, + SubName, + NewKey->NameSize); + + CmiAddKeyToList (ParentKey, NewKey); + ObDereferenceObject (ParentKey); VERIFY_KEY_OBJECT(NewKey); @@ -725,53 +625,138 @@ CmiConnectHive(PWSTR FileName, } +static NTSTATUS +CmiInitializeSystemHive (PWSTR FileName, + PUNICODE_STRING KeyName) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING ControlSetKeyName; + UNICODE_STRING ControlSetLinkName; + UNICODE_STRING ControlSetValueName; + HANDLE KeyHandle; + NTSTATUS Status; + PREGISTRY_HIVE RegistryHive; + + Status = CmiCreateRegistryHive (FileName, + &RegistryHive, + TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("CmiCreateRegistryHive() failed (Status %lx)\n", Status); + return Status; + } + + Status = CmiConnectHive (RegistryHive, + KeyName); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status); + CmiRemoveRegistryHive (RegistryHive); + return Status; + } + + /* Create 'ControlSet001' key */ + RtlInitUnicodeStringFromLiteral (&ControlSetKeyName, + L"\\Registry\\Machine\\SYSTEM\\ControlSet001"); + InitializeObjectAttributes (&ObjectAttributes, + &ControlSetKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtCreateKey (&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("NtCreateKey() failed (Status %lx)\n", Status); + return Status; + } + NtClose (KeyHandle); + + /* Link 'CurrentControlSet' to 'ControlSet001' key */ + RtlInitUnicodeStringFromLiteral (&ControlSetLinkName, + L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"); + InitializeObjectAttributes (&ObjectAttributes, + &ControlSetLinkName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK, + NULL, + NULL); + Status = NtCreateKey (&KeyHandle, + KEY_ALL_ACCESS | KEY_CREATE_LINK, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("NtCreateKey() failed (Status %lx)\n", Status); + return Status; + } + + RtlInitUnicodeStringFromLiteral (&ControlSetValueName, + L"SymbolicLinkValue"); + Status = NtSetValueKey (KeyHandle, + &ControlSetValueName, + 0, + REG_LINK, + (PVOID)ControlSetKeyName.Buffer, + ControlSetKeyName.Length); + if (!NT_SUCCESS(Status)) + { + DPRINT1 ("NtSetValueKey() failed (Status %lx)\n", Status); + } + NtClose (KeyHandle); + + return STATUS_SUCCESS; +} + + NTSTATUS CmiInitializeHive(PWSTR FileName, - PWSTR FullName, - PCHAR KeyName, - PKEY_OBJECT Parent, - BOOLEAN CreateNew) + PUNICODE_STRING KeyName, + BOOLEAN CreateNew) { + PREGISTRY_HIVE RegistryHive; NTSTATUS Status; DPRINT("CmiInitializeHive(%s) called\n", KeyName); - /* Try to connect the hive */ - //Status = CmiConnectHive(FileName, FullName, KeyName, Parent, FALSE); - Status = CmiConnectHive(FileName, FullName, KeyName, Parent, CreateNew); + Status = CmiCreateRegistryHive(FileName, + &RegistryHive, + CreateNew); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status); + + /* FIXME: Try to load the backup hive */ + KeBugCheck(0); + return(Status); + } + + /* Connect the hive */ + Status = CmiConnectHive(RegistryHive, + KeyName); if (!NT_SUCCESS(Status)) { -#if 0 -#ifdef WIN32_REGDBG - WCHAR AltFileName[MAX_PATH]; - - CPRINT("WARNING! Registry file %S not found\n", FileName); - //DPRINT("Status %.08x\n", Status); - - wcscpy(AltFileName, FileName); - wcscat(AltFileName, L".alt"); - - DPRINT("Attempting to connect the alternative hive %S\n", AltFileName); - /* Try to connect the alternative hive */ - Status = CmiConnectHive(AltFileName, FullName, KeyName, Parent, TRUE); - - if (!NT_SUCCESS(Status)) { - CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName); - //DPRINT("Status %.08x\n", Status); - } -#endif -#endif + DPRINT1("CmiConnectHive() failed (Status %lx)\n", Status); + CmiRemoveRegistryHive(RegistryHive); + return(Status); } DPRINT("CmiInitializeHive() done\n"); - return(Status); + return(STATUS_SUCCESS); } NTSTATUS -CmiInitHives(BOOLEAN SetUpBoot) +CmiInitHives(BOOLEAN SetupBoot) { PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; OBJECT_ATTRIBUTES ObjectAttributes; @@ -790,59 +775,59 @@ CmiInitHives(BOOLEAN SetUpBoot) DPRINT("CmiInitHives() called\n"); - if (SetUpBoot == TRUE) - { - RtlInitUnicodeStringFromLiteral(&KeyName, - L"\\Registry\\Machine\\HARDWARE"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) + if (SetupBoot == TRUE) { - DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); - return(Status); - } + RtlInitUnicodeStringFromLiteral(&KeyName, + L"\\Registry\\Machine\\HARDWARE"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + return(Status); + } - RtlInitUnicodeStringFromLiteral(&ValueName, - L"InstallPath"); + RtlInitUnicodeStringFromLiteral(&ValueName, + L"InstallPath"); - BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096; - ValueInfo = ExAllocatePool(PagedPool, - BufferSize); - if (ValueInfo == NULL) - { + BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096; + ValueInfo = ExAllocatePool(PagedPool, + BufferSize); + if (ValueInfo == NULL) + { + NtClose(KeyHandle); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + ValueInfo, + BufferSize, + &ResultSize); NtClose(KeyHandle); - return(STATUS_INSUFFICIENT_RESOURCES); - } + if (ValueInfo == NULL) + { + ExFreePool(ValueInfo); + return(Status); + } - Status = NtQueryValueKey(KeyHandle, - &ValueName, - KeyValuePartialInformation, - ValueInfo, - BufferSize, - &ResultSize); - NtClose(KeyHandle); - if (ValueInfo == NULL) - { + RtlCopyMemory(ConfigPath, + ValueInfo->Data, + ValueInfo->DataLength); + ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0; ExFreePool(ValueInfo); - return(Status); } - - RtlCopyMemory(ConfigPath, - ValueInfo->Data, - ValueInfo->DataLength); - ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0; - ExFreePool(ValueInfo); - } else - { - wcscpy(ConfigPath, L"\\SystemRoot"); - } + { + wcscpy(ConfigPath, L"\\SystemRoot"); + } wcscat(ConfigPath, L"\\system32\\config"); DPRINT("ConfigPath: %S\n", ConfigPath); @@ -853,76 +838,82 @@ CmiInitHives(BOOLEAN SetUpBoot) /* FIXME: Save boot log */ - /* FIXME: Rename \Registry\Machine\System */ - - /* Connect the SYSTEM hive */ -// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot); -// assert(NT_SUCCESS(Status)); - - /* FIXME: Synchronize old and new system hive (??) */ + /* Connect the SYSTEM hive only if it has been created */ + if (SetupBoot == TRUE) + { + wcscpy(EndPtr, REG_SYSTEM_FILE_NAME); + DPRINT ("ConfigPath: %S\n", ConfigPath); - /* FIXME: Delete old system hive */ + RtlInitUnicodeString (&KeyName, + REG_SYSTEM_KEY_NAME); + Status = CmiInitializeSystemHive (ConfigPath, + &KeyName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CmiInitializeSystemHive() failed (Status %lx)\n", Status); + return(Status); + } + } /* Connect the SOFTWARE hive */ wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME); - DPRINT1("ConfigPath: %S\n", ConfigPath); + DPRINT ("ConfigPath: %S\n", ConfigPath); + RtlInitUnicodeString (&KeyName, + REG_SOFTWARE_KEY_NAME); Status = CmiInitializeHive(ConfigPath, - REG_SOFTWARE_KEY_NAME, - "Software", - CmiMachineKey, - SetUpBoot); + &KeyName, + SetupBoot); if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); - return(Status); - } + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the SAM hive */ wcscpy(EndPtr, REG_SAM_FILE_NAME); - DPRINT1("ConfigPath: %S\n", ConfigPath); + DPRINT ("ConfigPath: %S\n", ConfigPath); + RtlInitUnicodeString (&KeyName, + REG_SAM_KEY_NAME); Status = CmiInitializeHive(ConfigPath, - REG_SAM_KEY_NAME, - "Sam", - CmiMachineKey, - SetUpBoot); + &KeyName, + SetupBoot); if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); - return(Status); - } + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the SECURITY hive */ wcscpy(EndPtr, REG_SEC_FILE_NAME); - DPRINT1("ConfigPath: %S\n", ConfigPath); + DPRINT ("ConfigPath: %S\n", ConfigPath); + + RtlInitUnicodeString (&KeyName, + REG_SEC_KEY_NAME); Status = CmiInitializeHive(ConfigPath, - REG_SEC_KEY_NAME, - "Security", - CmiMachineKey, - SetUpBoot); + &KeyName, + SetupBoot); if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); - return(Status); - } + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } /* Connect the DEFAULT hive */ wcscpy(EndPtr, REG_USER_FILE_NAME); - DPRINT1("ConfigPath: %S\n", ConfigPath); + DPRINT ("ConfigPath: %S\n", ConfigPath); + RtlInitUnicodeString (&KeyName, + REG_USER_KEY_NAME); Status = CmiInitializeHive(ConfigPath, - REG_USER_KEY_NAME, - ".Default", - CmiUserKey, - SetUpBoot); + &KeyName, + SetupBoot); if (!NT_SUCCESS(Status)) - { - DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); - return(Status); - } - - /* FIXME : initialize standards symbolic links */ + { + DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status); + return(Status); + } // CmiCheckRegistry(TRUE); @@ -958,7 +949,7 @@ CmShutdownRegistry(VOID) { Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList); - if (IsPermanentHive(Hive)) + if (!IsVolatileHive(Hive)) { /* Acquire hive resource exclusively */ ExAcquireResourceExclusiveLite(&Hive->HiveResource, @@ -967,10 +958,6 @@ CmShutdownRegistry(VOID) /* Flush non-volatile hive */ CmiFlushRegistryHive(Hive); - /* Dereference file */ - ObDereferenceObject(Hive->FileObject); - Hive->FileObject = NULL; - /* Release hive resource */ ExReleaseResourceLite(&Hive->HiveResource); } @@ -991,7 +978,7 @@ CmiHiveSyncRoutine(PVOID DeferredContext) PREGISTRY_HIVE Hive; PLIST_ENTRY Entry; - DPRINT1("CmiHiveSyncRoutine() called\n"); + DPRINT("CmiHiveSyncRoutine() called\n"); CmiHiveSyncPending = FALSE; @@ -1003,7 +990,7 @@ CmiHiveSyncRoutine(PVOID DeferredContext) { Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList); - if (IsPermanentHive(Hive)) + if (!IsVolatileHive(Hive)) { /* Acquire hive resource exclusively */ ExAcquireResourceExclusiveLite(&Hive->HiveResource, @@ -1024,6 +1011,8 @@ CmiHiveSyncRoutine(PVOID DeferredContext) DPRINT("DeferredContext %x\n", DeferredContext); ExFreePool(DeferredContext); + + DPRINT("CmiHiveSyncRoutine() done\n"); } diff --git a/ntoskrnl/cm/regobj.c b/ntoskrnl/cm/regobj.c index e4570e4..27944d5 100644 --- a/ntoskrnl/cm/regobj.c +++ b/ntoskrnl/cm/regobj.c @@ -6,9 +6,6 @@ * UPDATE HISTORY: */ -#ifdef WIN32_REGDBG -#include "cm_win32.h" -#else #include #include #include @@ -22,7 +19,6 @@ #include #include "cm.h" -#endif static NTSTATUS @@ -209,16 +205,8 @@ CmiObjectParse(PVOID ParsedObject, NULL, UserMode); } -#ifndef WIN32_REGDBG + DPRINT("CmiObjectParse: %s\n", FoundObject->Name); -#else - { - char buffer[_BUFFER_LEN]; - memset(buffer, 0, _BUFFER_LEN); - strncpy(buffer, FoundObject->Name, min(FoundObject->NameSize, _BUFFER_LEN - 1)); - DPRINT("CmiObjectParse: %s\n", buffer); - } -#endif *Path = EndPtr; @@ -234,7 +222,7 @@ NTSTATUS STDCALL CmiObjectCreate(PVOID ObjectBody, PVOID Parent, PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes) + POBJECT_ATTRIBUTES ObjectAttributes) { PKEY_OBJECT pKey = ObjectBody; @@ -283,16 +271,27 @@ CmiObjectDelete(PVOID DeletedObject) KeyObject->ParentKey, KeyObject); - if (IsPermanentHive(KeyObject->RegistryHive)) - CmiSyncHives(); - } - else - { - CmiReleaseBlock(KeyObject->RegistryHive, KeyObject->KeyCell); + if (!IsVolatileHive(KeyObject->RegistryHive)) + { + CmiSyncHives(); + } } } +NTSTATUS STDCALL +CmiObjectSecurity(PVOID ObjectBody, + SECURITY_OPERATION_CODE OperationCode, + SECURITY_INFORMATION SecurityInformation, + PSECURITY_DESCRIPTOR SecurityDescriptor, + PULONG BufferLength) +{ + DPRINT1("CmiObjectSecurity() called\n"); + + return(STATUS_SUCCESS); +} + + VOID CmiAddKeyToList(PKEY_OBJECT ParentKey, PKEY_OBJECT NewKey) @@ -306,13 +305,13 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey, if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys) { PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool, - (ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD)); + (ParentKey->NumberOfSubKeys + 1) * sizeof(ULONG)); if (ParentKey->NumberOfSubKeys > 0) { - memcpy(tmpSubKeys, - ParentKey->SubKeys, - ParentKey->NumberOfSubKeys * sizeof(DWORD)); + RtlCopyMemory (tmpSubKeys, + ParentKey->SubKeys, + ParentKey->NumberOfSubKeys * sizeof(ULONG)); } if (ParentKey->SubKeys) @@ -380,17 +379,8 @@ CmiScanKeyList(PKEY_OBJECT Parent, WORD NameSize; DWORD Index; -#ifndef WIN32_REGDBG DPRINT("Scanning key list for: %s (Parent: %s)\n", KeyName, Parent->Name); -#else - { - char buffer[_BUFFER_LEN]; - memset(buffer, 0, _BUFFER_LEN); - strncpy(buffer, Parent->Name, min(Parent->NameSize, _BUFFER_LEN - 1)); - DPRINT("Scanning key list for: %s (Parent: %s)\n", KeyName, buffer); - } -#endif NameSize = strlen(KeyName); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); @@ -418,7 +408,7 @@ CmiScanKeyList(PKEY_OBJECT Parent, } } KeReleaseSpinLock(&CmiKeyListLock, OldIrql); - + return NULL; } @@ -471,7 +461,6 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive, DataCell->Data, TargetPath->Length); TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0; - CmiReleaseBlock(RegistryHive, DataCell); } else { diff --git a/ntoskrnl/ex/fmutex.c b/ntoskrnl/ex/fmutex.c index 6c38af9..0c98cbd 100644 --- a/ntoskrnl/ex/fmutex.c +++ b/ntoskrnl/ex/fmutex.c @@ -39,7 +39,7 @@ VOID FASTCALL ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) { assert(FastMutex->Owner != KeGetCurrentThread()); - InterlockedIncrement(&FastMutex->Contention); + InterlockedIncrement((LONG *)&FastMutex->Contention); while (InterlockedExchange(&FastMutex->Count, 0) == 0) { KeWaitForSingleObject(&FastMutex->Event, @@ -48,7 +48,7 @@ ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) FALSE, NULL); } - InterlockedDecrement(&FastMutex->Contention); + InterlockedDecrement((LONG *)&FastMutex->Contention); FastMutex->Owner = KeGetCurrentThread(); } diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c index c9a8c3e..fd2c496 100644 --- a/ntoskrnl/ex/init.c +++ b/ntoskrnl/ex/init.c @@ -47,12 +47,12 @@ ExInit (VOID) BOOLEAN STDCALL -ExIsProcessorFeaturePresent (IN ULONG ProcessorFeature) +ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature) { - if (ProcessorFeature >= 32) - return FALSE; - - return FALSE; + if (ProcessorFeature >= PROCESSOR_FEATURES_MAX) + return(FALSE); + + return(SharedUserData->ProcessorFeatures[ProcessorFeature]); } diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c index 4ea6d53..d0c368a 100644 --- a/ntoskrnl/ex/sysinfo.c +++ b/ntoskrnl/ex/sysinfo.c @@ -7,6 +7,9 @@ * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * Created 22/05/98 + * 20/03/2003: implemented querying SystemProcessInformation, + * no more copying to-from the caller (Aleksey + * Bragin ) */ /* INCLUDES *****************************************************************/ @@ -18,6 +21,7 @@ #include #include #include +#include #include @@ -457,8 +461,98 @@ QSI_DEF(SystemPathInformation) /* Class 5 - Process Information */ QSI_DEF(SystemProcessInformation) { - /* FIXME: scan the process+thread list */ - return (STATUS_NOT_IMPLEMENTED); + ULONG ovlSize=0, nThreads=1; + PEPROCESS pr, syspr; + unsigned char *pCur; + + /* scan the process list */ + // TODO: Add thread information + + PSYSTEM_PROCESSES Spi + = (PSYSTEM_PROCESSES) Buffer; + + *ReqSize = sizeof(SYSTEM_PROCESSES); + + if (Size < sizeof(SYSTEM_PROCESSES)) + { + return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small + } + + syspr = PsGetNextProcess(NULL); + pr = syspr; + pCur = (unsigned char *)Spi; + + do + { + PSYSTEM_PROCESSES SpiCur; + int curSize; + ANSI_STRING imgName; + int inLen=32; // image name len in bytes + + + SpiCur = (PSYSTEM_PROCESSES)pCur; + + nThreads = 1; // FIXME + + // size of the structure for every process + curSize = sizeof(SYSTEM_PROCESSES)-sizeof(SYSTEM_THREADS)+sizeof(SYSTEM_THREADS)*nThreads; + ovlSize += curSize+inLen; + + if (ovlSize > Size) + { + *ReqSize = ovlSize; + + return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small + } + + // fill system information + SpiCur->NextEntryDelta = curSize+inLen; // relative offset to the beginnnig of the next structure + SpiCur->ThreadCount = nThreads; + SpiCur->CreateTime = pr->CreateTime; + //SpiCur->UserTime = 0; // FIXME + //SpiCur->KernelTime = 0; // FIXME + + SpiCur->ProcessName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR); + SpiCur->ProcessName.MaximumLength = inLen; + SpiCur->ProcessName.Buffer = (void*)(pCur+curSize); + + // copy name to the end of the struct + RtlInitAnsiString(&imgName, pr->ImageFileName); + RtlAnsiStringToUnicodeString(&SpiCur->ProcessName, &imgName, FALSE); + + SpiCur->BasePriority = 0; // FIXME + SpiCur->ProcessId = pr->UniqueProcessId; + SpiCur->InheritedFromProcessId = 0; // FIXME + SpiCur->HandleCount = 0; // FIXME + SpiCur->VmCounters.PeakVirtualSize = pr->PeakVirtualSize; + SpiCur->VmCounters.VirtualSize = 0; // FIXME + SpiCur->VmCounters.PageFaultCount = pr->LastFaultCount; + SpiCur->VmCounters.PeakWorkingSetSize = pr->Vm.PeakWorkingSetSize; // Is this right using ->Vm. here ? + SpiCur->VmCounters.WorkingSetSize = pr->Vm.WorkingSetSize; // Is this right using ->Vm. here ? + SpiCur->VmCounters.QuotaPeakPagedPoolUsage = 0; // FIXME + SpiCur->VmCounters.QuotaPagedPoolUsage = 0; // FIXME + SpiCur->VmCounters.QuotaPeakNonPagedPoolUsage = 0; // FIXME + SpiCur->VmCounters.QuotaNonPagedPoolUsage = 0; // FIXME + SpiCur->VmCounters.PagefileUsage = 0; // FIXME + SpiCur->VmCounters.PeakPagefileUsage = pr->PeakPagefileUsage; + // KJK::Hyperion: I don't know what does this mean. VM_COUNTERS + // doesn't seem to contain any equivalent field + //SpiCur->TotalPrivateBytes = pr->NumberOfPrivatePages; //FIXME: bytes != pages + + pr = PsGetNextProcess(pr); + + if ((pr == syspr) || (pr == NULL)) + { + SpiCur->NextEntryDelta = 0; + break; + } + else + pCur = pCur + curSize + inLen; + } while ((pr != syspr) && (pr != NULL)); + + *ReqSize = ovlSize; + + return (STATUS_SUCCESS); } /* Class 6 - Call Count Information */ @@ -1035,10 +1129,10 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, NTSTATUS Status; NTSTATUS FStatus; - if (ExGetPreviousMode() == KernelMode) - { + /*if (ExGetPreviousMode() == KernelMode) + {*/ SystemInformation = UnsafeSystemInformation; - } + /*} else { SystemInformation = ExAllocatePool(NonPagedPool, Length); @@ -1046,7 +1140,7 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, { return(STATUS_NO_MEMORY); } - } + }*/ /* Clear user buffer. */ RtlZeroMemory(SystemInformation, Length); @@ -1065,7 +1159,7 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, FStatus = CallQS [SystemInformationClass].Query(SystemInformation, Length, &ResultLength); - if (ExGetPreviousMode() != KernelMode) + /*if (ExGetPreviousMode() != KernelMode) { Status = MmCopyToCaller(UnsafeSystemInformation, SystemInformation, @@ -1075,15 +1169,15 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, { return(Status); } - } + }*/ if (UnsafeResultLength != NULL) { - if (ExGetPreviousMode() == KernelMode) + /*if (ExGetPreviousMode() == KernelMode) { *UnsafeResultLength = ResultLength; } else - { + {*/ Status = MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG)); @@ -1091,7 +1185,7 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, { return(Status); } - } + /*}*/ } return(FStatus); } diff --git a/ntoskrnl/fs/mcb.c b/ntoskrnl/fs/mcb.c index 184e49b..b109b45 100644 --- a/ntoskrnl/fs/mcb.c +++ b/ntoskrnl/fs/mcb.c @@ -29,17 +29,17 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, return(FALSE); } - -VOID -STDCALL -FsRtlAddMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3 - ) +/* FsRtlAddMcbEntry: Obsolete */ +BOOLEAN STDCALL +FsRtlAddMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + IN LBN Lbn, + IN ULONG SectorCount) { - UNIMPLEMENTED + return FsRtlAddLargeMcbEntry(& Mcb->LargeMcb, + (LONGLONG) Vbn, + (LONGLONG) Lbn, + (LONGLONG) SectorCount); } @@ -55,17 +55,26 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, } -VOID -STDCALL -FsRtlGetNextMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) +BOOLEAN STDCALL +FsRtlGetNextMcbEntry (IN PMCB Mcb, + IN ULONG RunIndex, + OUT PVBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount) { - UNIMPLEMENTED + BOOLEAN rc=FALSE; + LONGLONG llVbn; + LONGLONG llLbn; + LONGLONG llSectorCount; + + // FIXME: how should conversion be done + // FIXME: between 32 and 64 bits? + rc=FsRtlGetNextLargeMcbEntry (& Mcb->LargeMcb, + RunIndex, + & llVbn, + & llLbn, + & llSectorCount); + return(rc); } @@ -74,18 +83,15 @@ FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType) { UNIMPLEMENTED - Mcb->PoolType = PoolType; + Mcb->PoolType = PoolType; } - -VOID -STDCALL -FsRtlInitializeMcb ( - DWORD Unknown0, - DWORD Unknown1 - ) +/* FsRtlInitializeMcb: Obsolete */ +VOID STDCALL +FsRtlInitializeMcb (IN PMCB Mcb, + IN POOL_TYPE PoolType) { - UNIMPLEMENTED + FsRtlInitializeLargeMcb(& Mcb->LargeMcb, PoolType); } @@ -113,47 +119,44 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, } -VOID -STDCALL -FsRtlLookupLastMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) +BOOLEAN STDCALL +FsRtlLookupLastMcbEntry (IN PMCB Mcb, + OUT PVBN Vbn, + OUT PLBN Lbn) { - UNIMPLEMENTED + UNIMPLEMENTED + return(FALSE); } -VOID -STDCALL -FsRtlLookupMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) +BOOLEAN STDCALL +FsRtlLookupMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + OUT PLBN Lbn, + OUT PULONG SectorCount OPTIONAL, + OUT PULONG Index) { - UNIMPLEMENTED + UNIMPLEMENTED + return(FALSE); } ULONG STDCALL FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) { - UNIMPLEMENTED - return(0); + ULONG NumberOfRuns; + ExAcquireFastMutex (Mcb->FastMutex); + NumberOfRuns=Mcb->PairCount; + ExReleaseFastMutex (Mcb->FastMutex); + return(NumberOfRuns); } -VOID -STDCALL -FsRtlNumberOfRunsInMcb ( - DWORD Unknown0 - ) +/* FsRtlNumberOfRunsInMcb: Obsolete */ +ULONG STDCALL +FsRtlNumberOfRunsInMcb (IN PMCB Mcb) { - UNIMPLEMENTED + return FsRtlNumberOfRunsInLargeMcb(& Mcb->LargeMcb); } @@ -166,15 +169,12 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, } -VOID -STDCALL -FsRtlRemoveMcbEntry ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2 - ) +VOID STDCALL +FsRtlRemoveMcbEntry (IN PMCB Mcb, + IN VBN Vbn, + IN ULONG SectorCount) { - UNIMPLEMENTED + UNIMPLEMENTED } @@ -196,14 +196,12 @@ FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, } -VOID -STDCALL -FsRtlTruncateMcb ( - DWORD Unknown0, - DWORD Unknown1 - ) +/* FsRtlTruncateMcb: Obsolete */ +VOID STDCALL +FsRtlTruncateMcb (IN PMCB Mcb, + IN VBN Vbn) { - UNIMPLEMENTED + FsRtlTruncateLargeMcb (& Mcb->LargeMcb, (LONGLONG) Vbn); } @@ -213,14 +211,11 @@ FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb) UNIMPLEMENTED; } - -VOID -STDCALL -FsRtlUninitializeMcb ( - DWORD Unknown0 - ) +/* FsRtlUninitializeMcb: Obsolete */ +VOID STDCALL +FsRtlUninitializeMcb (IN PMCB Mcb) { - UNIMPLEMENTED + FsRtlUninitializeLargeMcb(& Mcb->LargeMcb); } diff --git a/ntoskrnl/fs/util.c b/ntoskrnl/fs/util.c index c4599cc..f4afc89 100644 --- a/ntoskrnl/fs/util.c +++ b/ntoskrnl/fs/util.c @@ -241,7 +241,21 @@ FsRtlGetFileSize ( IN OUT PLARGE_INTEGER FileSize ) { - return STATUS_NOT_IMPLEMENTED; + FILE_STANDARD_INFORMATION Info; + NTSTATUS Status; + ULONG Length; + + Status = IoQueryFileInformation(FileObject, + FileStandardInformation, + sizeof(Info), + &Info, + &Length); + if (NT_SUCCESS(Status)) + { + FileSize->QuadPart = Info.EndOfFile.QuadPart; + } + + return Status; } diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 42532b9..f35f6d4 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -228,8 +228,6 @@ typedef struct _DEVICETREE_TRAVERSE_CONTEXT extern PDEVICE_NODE IopRootDeviceNode; -extern POBJECT_TYPE IoSymbolicLinkType; - VOID PnpInit(VOID); @@ -263,8 +261,6 @@ IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry, VOID IoInitCancelHandling(VOID); VOID -IoInitSymbolicLinkImplementation(VOID); -VOID IoInitFileSystemImplementation(VOID); VOID IoInitVpbImplementation(VOID); diff --git a/ntoskrnl/include/internal/kd.h b/ntoskrnl/include/internal/kd.h index 45567d8..9e5a14d 100644 --- a/ntoskrnl/include/internal/kd.h +++ b/ntoskrnl/include/internal/kd.h @@ -54,7 +54,7 @@ UCHAR KdGetChar(VOID); VOID -KdGdbStubInit(); +KdGdbStubInit(ULONG Phase); VOID KdGdbDebugPrint (LPSTR Message); diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index 102b9c5..7cc8aad 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -36,6 +36,8 @@ struct _KTHREAD; +VOID STDCALL KeRescheduleThread(); + VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip); VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); @@ -58,6 +60,8 @@ VOID KiDeliverNormalApc(VOID); BOOLEAN STDCALL KeRemoveQueueApc (PKAPC Apc); +PLIST_ENTRY STDCALL KeRundownQueue(IN PKQUEUE Queue); + /* INITIALIZATION FUNCTIONS *************************************************/ @@ -86,7 +90,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame, PCONTEXT Context); VOID -KeApplicationProcessorInit(); +KeApplicationProcessorInit(VOID); VOID KePrepareForApplicationProcessorInit(ULONG id); ULONG @@ -96,7 +100,7 @@ KePushAndStackSwitchAndSysRet(ULONG Push, PVOID NewStack); VOID STDCALL KeStackSwitchAndRet(PVOID NewStack); VOID STDCALL -KeBugCheckWithTf(ULONG BugCheckCode, +KeBugCheckWithTf(ULONG BugCheckCode, ULONG BugCheckParameter1, ULONG BugCheckParameter2, ULONG BugCheckParameter3, diff --git a/ntoskrnl/include/internal/ntoskrnl.h b/ntoskrnl/include/internal/ntoskrnl.h index 7481602..0264bcb 100644 --- a/ntoskrnl/include/internal/ntoskrnl.h +++ b/ntoskrnl/include/internal/ntoskrnl.h @@ -45,7 +45,8 @@ VOID PsInit(VOID); VOID CmInitializeRegistry(VOID); VOID CmInit2(PCHAR CommandLine); VOID CmShutdownRegistry(VOID); -VOID CmImportHive(PCHAR ChunkBase, ULONG ChunkSize); +BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize); +BOOLEAN CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize); VOID KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock); VOID RtlpInitNlsTables(VOID); diff --git a/ntoskrnl/include/internal/ob.h b/ntoskrnl/include/internal/ob.h index b8ad6b7..697277c 100644 --- a/ntoskrnl/include/internal/ob.h +++ b/ntoskrnl/include/internal/ob.h @@ -66,6 +66,7 @@ enum extern PDIRECTORY_OBJECT NameSpaceRoot; +extern POBJECT_TYPE ObSymbolicLinkType; POBJECT_HEADER BODY_TO_HEADER(PVOID body); @@ -76,6 +77,8 @@ VOID ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent, PWSTR Name); VOID ObpRemoveEntryDirectory(POBJECT_HEADER Header); +VOID +ObInitSymbolicLinkImplementation(VOID); NTSTATUS ObCreateHandle(struct _EPROCESS* Process, diff --git a/ntoskrnl/include/internal/ps.h b/ntoskrnl/include/internal/ps.h index 26df5e5..be7e94d 100644 --- a/ntoskrnl/include/internal/ps.h +++ b/ntoskrnl/include/internal/ps.h @@ -474,7 +474,7 @@ VOID PsUnfreezeProcessThreads(PEPROCESS Process); PEPROCESS PsGetNextProcess(PEPROCESS OldProcess); VOID PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, - BOOLEAN DispatcherLock, KIRQL WaitIrql); + BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason); VOID PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus); VOID diff --git a/ntoskrnl/include/internal/se.h b/ntoskrnl/include/internal/se.h index 98fb83c..6a401d8 100644 --- a/ntoskrnl/include/internal/se.h +++ b/ntoskrnl/include/internal/se.h @@ -89,11 +89,20 @@ extern PACL SePublicOpenDacl; extern PACL SePublicOpenUnrestrictedDacl; extern PACL SeUnrestrictedDacl; +/* SDs */ +extern PSECURITY_DESCRIPTOR SePublicDefaultSd; +extern PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd; +extern PSECURITY_DESCRIPTOR SePublicOpenSd; +extern PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd; +extern PSECURITY_DESCRIPTOR SeSystemDefaultSd; +extern PSECURITY_DESCRIPTOR SeUnrestrictedSd; + /* Functions */ BOOLEAN SeInit1(VOID); BOOLEAN SeInit2(VOID); +BOOLEAN SeInitSRM(VOID); VOID SepInitLuid(VOID); VOID SepInitPrivileges(VOID); diff --git a/ntoskrnl/io/arcname.c b/ntoskrnl/io/arcname.c index bf5b7ab..2d9d14e 100644 --- a/ntoskrnl/io/arcname.c +++ b/ntoskrnl/io/arcname.c @@ -296,7 +296,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) return(Status); } - sprintf(p, "cdrom(%u)", DeviceNumber); + sprintf(p, "cdrom(%lu)", DeviceNumber); DPRINT("New ARC name: %s\n", ParamBuffer); @@ -313,7 +313,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) q++; strcpy(temp, q); - sprintf(p, "cdrom(%u)", DeviceNumber); + sprintf(p, "cdrom(%lu)", DeviceNumber); strcat(p, temp); } } diff --git a/ntoskrnl/io/buildirp.c b/ntoskrnl/io/buildirp.c index f095690..ff676f9 100644 --- a/ntoskrnl/io/buildirp.c +++ b/ntoskrnl/io/buildirp.c @@ -260,29 +260,27 @@ IoBuildDeviceIoControlRequest(ULONG IoControlCode, case METHOD_IN_DIRECT: DPRINT("Using METHOD_IN_DIRECT!\n"); - /* build input buffer (control buffer) */ - if (InputBuffer && InputBufferLength) + /* build output buffer (control buffer) */ + if (OutputBuffer && OutputBufferLength) { Irp->AssociatedIrp.SystemBuffer = (PVOID) - ExAllocatePoolWithTag(NonPagedPool,InputBufferLength, + ExAllocatePoolWithTag(NonPagedPool,OutputBufferLength, TAG_SYS_BUF); + if (Irp->AssociatedIrp.SystemBuffer == NULL) { IoFreeIrp(Irp); return(NULL); } - - RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, - InputBuffer, - InputBufferLength); + Irp->UserBuffer = OutputBuffer; } - /* build output buffer (data transfer buffer) */ - if (OutputBuffer && OutputBufferLength) + /* build input buffer (data transfer buffer) */ + if (InputBuffer && InputBufferLength) { - Irp->MdlAddress = IoAllocateMdl(OutputBuffer, - OutputBufferLength, + Irp->MdlAddress = IoAllocateMdl(InputBuffer, + InputBufferLength, FALSE, FALSE, Irp); diff --git a/ntoskrnl/io/cleanup.c b/ntoskrnl/io/cleanup.c index c1be188..5fc68f6 100644 --- a/ntoskrnl/io/cleanup.c +++ b/ntoskrnl/io/cleanup.c @@ -99,12 +99,21 @@ VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject, case METHOD_IN_DIRECT: DPRINT ("Using METHOD_IN_DIRECT!\n"); + + /* copy output buffer back and free it */ + if (Irp->AssociatedIrp.SystemBuffer) + { + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + RtlCopyMemory(Irp->UserBuffer, + Irp->AssociatedIrp.SystemBuffer, + IoStack->Parameters.DeviceIoControl. + OutputBufferLength); + } + ExFreePool (Irp->AssociatedIrp.SystemBuffer); + } - /* free input buffer (control buffer) */ - if (Irp->AssociatedIrp.SystemBuffer) - ExFreePool (Irp->AssociatedIrp.SystemBuffer); - - /* free output buffer (data transfer buffer) */ + /* free input buffer (data transfer buffer) */ if (Irp->MdlAddress) IoFreeMdl (Irp->MdlAddress); break; diff --git a/ntoskrnl/io/device.c b/ntoskrnl/io/device.c index a2ebf77..494011c 100644 --- a/ntoskrnl/io/device.c +++ b/ntoskrnl/io/device.c @@ -610,7 +610,6 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject, { PDEVICE_OBJECT CreatedDeviceObject; OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE DeviceHandle; NTSTATUS Status; assert_irql(PASSIVE_LEVEL); @@ -628,7 +627,7 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject, if (DeviceName != NULL) { InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL); - Status = ObCreateObject(&DeviceHandle, + Status = ObCreateObject(NULL, 0, &ObjectAttributes, IoDeviceObjectType, @@ -636,7 +635,7 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject, } else { - Status = ObCreateObject(&DeviceHandle, + Status = ObCreateObject(NULL, 0, NULL, IoDeviceObjectType, diff --git a/ntoskrnl/io/file.c b/ntoskrnl/io/file.c index 99e932b..098356f 100644 --- a/ntoskrnl/io/file.c +++ b/ntoskrnl/io/file.c @@ -236,7 +236,39 @@ NtSetInformationFile(HANDLE FileHandle, } DPRINT("FileObject %x\n", FileObject); - + + //io completion port? + if (FileInformationClass == FileCompletionInformation) + { + PKQUEUE Queue; + + if (Length < sizeof(FILE_COMPLETION_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + Status = ObReferenceObjectByHandle(((PFILE_COMPLETION_INFORMATION)FileInformation)->IoCompletionHandle, + IO_COMPLETION_MODIFY_STATE,//??? + ExIoCompletionType, + UserMode, + (PVOID*)&Queue, + NULL); + if (NT_SUCCESS(Status)) + { + //FIXME: maybe use lookaside list + FileObject->CompletionContext = ExAllocatePool(NonPagedPool, sizeof(IO_COMPLETION_CONTEXT)); + FileObject->CompletionContext->Key = ((PFILE_COMPLETION_INFORMATION)FileInformation)->CompletionKey; + FileObject->CompletionContext->Port = Queue; + + ObDereferenceObject(Queue); + } + } + + ObDereferenceObject(FileObject); + return Status; + } + DeviceObject = FileObject->DeviceObject; Irp = IoAllocateIrp(DeviceObject->StackSize, @@ -308,8 +340,36 @@ NTSTATUS STDCALL NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_BASIC_INFORMATION FileInformation) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + NTSTATUS Status; + + /* Open the file */ + Status = NtOpenFile (&FileHandle, + SYNCHRONIZE | FILE_READ_ATTRIBUTES, + ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + /* Get file attributes */ + Status = NtQueryInformationFile (FileHandle, + &IoStatusBlock, + FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + NtClose (FileHandle); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); + } + + return Status; } @@ -317,8 +377,36 @@ NTSTATUS STDCALL NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + NTSTATUS Status; + + /* Open the file */ + Status = NtOpenFile (&FileHandle, + SYNCHRONIZE | FILE_READ_ATTRIBUTES, + ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + /* Get file attributes */ + Status = NtQueryInformationFile (FileHandle, + &IoStatusBlock, + FileInformation, + sizeof(FILE_NETWORK_OPEN_INFORMATION), + FileNetworkOpenInformation); + NtClose (FileHandle); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status); + } + + return Status; } diff --git a/ntoskrnl/io/fs.c b/ntoskrnl/io/fs.c index 0365f62..f2e0346 100644 --- a/ntoskrnl/io/fs.c +++ b/ntoskrnl/io/fs.c @@ -38,7 +38,7 @@ typedef struct _FS_CHANGE_NOTIFY_ENTRY /* GLOBALS ******************************************************************/ -static KSPIN_LOCK FileSystemListLock; +static ERESOURCE FileSystemListLock; static LIST_ENTRY FileSystemListHead; static KSPIN_LOCK FsChangeNotifyListLock; @@ -159,7 +159,7 @@ VOID IoInitFileSystemImplementation(VOID) { InitializeListHead(&FileSystemListHead); - KeInitializeSpinLock(&FileSystemListLock); + ExInitializeResourceLite(&FileSystemListLock); InitializeListHead(&FsChangeNotifyListHead); KeInitializeSpinLock(&FsChangeNotifyListLock); @@ -169,43 +169,48 @@ IoInitFileSystemImplementation(VOID) VOID IoShutdownRegisteredFileSystems(VOID) { - KIRQL oldlvl; - PLIST_ENTRY current_entry; - FILE_SYSTEM_OBJECT* current; - PIRP Irp; - KEVENT Event; - IO_STATUS_BLOCK IoStatusBlock; - NTSTATUS Status; + PLIST_ENTRY current_entry; + FILE_SYSTEM_OBJECT* current; + PIRP Irp; + KEVENT Event; + IO_STATUS_BLOCK IoStatusBlock; + NTSTATUS Status; - DPRINT("IoShutdownRegisteredFileSystems()\n"); + DPRINT("IoShutdownRegisteredFileSystems()\n"); - KeAcquireSpinLock(&FileSystemListLock,&oldlvl); - KeInitializeEvent(&Event,NotificationEvent,FALSE); + ExAcquireResourceSharedLite(&FileSystemListLock,TRUE); + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); - current_entry = FileSystemListHead.Flink; - while (current_entry!=(&FileSystemListHead)) - { - current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry); - - /* send IRP_MJ_SHUTDOWN */ - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, - current->DeviceObject, - NULL, - 0, - 0, - &Event, - &IoStatusBlock); - - Status = IoCallDriver(current->DeviceObject,Irp); - if (Status==STATUS_PENDING) - { - KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); - } - - current_entry = current_entry->Flink; - } + current_entry = FileSystemListHead.Flink; + while (current_entry!=(&FileSystemListHead)) + { + current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry); + + /* send IRP_MJ_SHUTDOWN */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, + current->DeviceObject, + NULL, + 0, + 0, + &Event, + &IoStatusBlock); + + Status = IoCallDriver(current->DeviceObject,Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + } - KeReleaseSpinLock(&FileSystemListLock,oldlvl); + current_entry = current_entry->Flink; + } + + ExReleaseResourceLite(&FileSystemListLock); } @@ -215,7 +220,7 @@ IopMountFileSystem(PDEVICE_OBJECT DeviceObject, { IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION StackPtr; - PKEVENT Event; + KEVENT Event; PIRP Irp; NTSTATUS Status; @@ -223,23 +228,17 @@ IopMountFileSystem(PDEVICE_OBJECT DeviceObject, DeviceObject,DeviceToMount); assert_irql(PASSIVE_LEVEL); - Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT)); - if (Event == NULL) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - KeInitializeEvent(Event, NotificationEvent, FALSE); + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp==NULL) { - ExFreePool(Event); return(STATUS_INSUFFICIENT_RESOURCES); } Irp->UserIosb = &IoStatusBlock; DPRINT("Irp->UserIosb %x\n", Irp->UserIosb); - Irp->UserEvent = Event; + Irp->UserEvent = &Event; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); @@ -257,12 +256,10 @@ IopMountFileSystem(PDEVICE_OBJECT DeviceObject, Status = IoCallDriver(DeviceObject,Irp); if (Status==STATUS_PENDING) { - KeWaitForSingleObject(Event,Executive,KernelMode,FALSE,NULL); + KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock.Status; } - ExFreePool(Event); - return(Status); } @@ -272,30 +269,24 @@ IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject) { IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION StackPtr; - PKEVENT Event; + KEVENT Event; PIRP Irp; NTSTATUS Status; DPRINT("IopLoadFileSystem(DeviceObject %x)\n", DeviceObject); assert_irql(PASSIVE_LEVEL); - Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT)); - if (Event == NULL) - { - return(STATUS_INSUFFICIENT_RESOURCES); - } - KeInitializeEvent(Event, NotificationEvent, FALSE); + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp==NULL) { - ExFreePool(Event); return(STATUS_INSUFFICIENT_RESOURCES); } Irp->UserIosb = &IoStatusBlock; DPRINT("Irp->UserIosb %x\n", Irp->UserIosb); - Irp->UserEvent = Event; + Irp->UserEvent = &Event; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); @@ -310,12 +301,10 @@ IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject) Status = IoCallDriver(DeviceObject,Irp); if (Status==STATUS_PENDING) { - KeWaitForSingleObject(Event,Executive,KernelMode,FALSE,NULL); + KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock.Status; } - ExFreePool(Event); - return(Status); } @@ -330,11 +319,11 @@ IoMountVolume(IN PDEVICE_OBJECT DeviceObject, * RETURNS: Status */ { - KIRQL oldlvl; PLIST_ENTRY current_entry; FILE_SYSTEM_OBJECT* current; NTSTATUS Status; DEVICE_TYPE MatchingDeviceType; + PDEVICE_OBJECT DevObject; assert_irql(PASSIVE_LEVEL); @@ -366,7 +355,7 @@ IoMountVolume(IN PDEVICE_OBJECT DeviceObject, return(STATUS_UNRECOGNIZED_VOLUME); } - KeAcquireSpinLock(&FileSystemListLock,&oldlvl); + ExAcquireResourceSharedLite(&FileSystemListLock,TRUE); current_entry = FileSystemListHead.Flink; while (current_entry!=(&FileSystemListHead)) { @@ -376,27 +365,26 @@ IoMountVolume(IN PDEVICE_OBJECT DeviceObject, current_entry = current_entry->Flink; continue; } - KeReleaseSpinLock(&FileSystemListLock,oldlvl); Status = IopMountFileSystem(current->DeviceObject, DeviceObject); - KeAcquireSpinLock(&FileSystemListLock,&oldlvl); switch (Status) { case STATUS_FS_DRIVER_REQUIRED: - KeReleaseSpinLock(&FileSystemListLock,oldlvl); - Status = IopLoadFileSystem(current->DeviceObject); + DevObject = current->DeviceObject; + ExReleaseResourceLite(&FileSystemListLock); + Status = IopLoadFileSystem(DevObject); if (!NT_SUCCESS(Status)) { - return(Status); + return(Status); } - KeAcquireSpinLock(&FileSystemListLock,&oldlvl); + ExAcquireResourceSharedLite(&FileSystemListLock,TRUE); current_entry = FileSystemListHead.Flink; continue; case STATUS_SUCCESS: DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags | VPB_MOUNTED; - KeReleaseSpinLock(&FileSystemListLock,oldlvl); + ExReleaseResourceLite(&FileSystemListLock); return(STATUS_SUCCESS); case STATUS_UNRECOGNIZED_VOLUME: @@ -404,7 +392,7 @@ IoMountVolume(IN PDEVICE_OBJECT DeviceObject, current_entry = current_entry->Flink; } } - KeReleaseSpinLock(&FileSystemListLock,oldlvl); + ExReleaseResourceLite(&FileSystemListLock); return(STATUS_UNRECOGNIZED_VOLUME); } @@ -434,7 +422,7 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, { IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION StackPtr; - PKEVENT Event; + KEVENT Event; PIRP Irp; NTSTATUS Status; @@ -454,24 +442,19 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, if (DeviceObject->Vpb->Flags & VPB_MOUNTED) { /* Issue verify request to the FSD */ - Event = ExAllocatePool(NonPagedPool, - sizeof(KEVENT)); - if (Event == NULL) - return(STATUS_INSUFFICIENT_RESOURCES); - KeInitializeEvent(Event, + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); if (Irp==NULL) { - ExFreePool(Event); return(STATUS_INSUFFICIENT_RESOURCES); } Irp->UserIosb = &IoStatusBlock; - Irp->UserEvent = Event; + Irp->UserEvent = &Event; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); StackPtr = IoGetNextIrpStackLocation(Irp); @@ -490,10 +473,9 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, Irp); if (Status==STATUS_PENDING) { - KeWaitForSingleObject(Event,Executive,KernelMode,FALSE,NULL); + KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock.Status; } - ExFreePool(Event); if (NT_SUCCESS(Status)) { @@ -565,9 +547,13 @@ IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject) assert(Fs!=NULL); Fs->DeviceObject = DeviceObject; - ExInterlockedInsertTailList(&FileSystemListHead, - &Fs->Entry, - &FileSystemListLock); + ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE); + + InsertTailList(&FileSystemListHead, + &Fs->Entry); + + ExReleaseResourceLite(&FileSystemListLock); + IopNotifyFileSystemChange(DeviceObject, TRUE); } @@ -576,13 +562,12 @@ IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject) VOID STDCALL IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject) { - KIRQL oldlvl; PLIST_ENTRY current_entry; PFILE_SYSTEM_OBJECT current; DPRINT("IoUnregisterFileSystem(DeviceObject %x)\n",DeviceObject); - KeAcquireSpinLock(&FileSystemListLock,&oldlvl); + ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE); current_entry = FileSystemListHead.Flink; while (current_entry!=(&FileSystemListHead)) { @@ -591,13 +576,13 @@ IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject) { RemoveEntryList(current_entry); ExFreePool(current); - KeReleaseSpinLock(&FileSystemListLock,oldlvl); + ExReleaseResourceLite(&FileSystemListLock); IopNotifyFileSystemChange(DeviceObject, FALSE); return; } current_entry = current_entry->Flink; } - KeReleaseSpinLock(&FileSystemListLock,oldlvl); + ExReleaseResourceLite(&FileSystemListLock); } diff --git a/ntoskrnl/io/iocomp.c b/ntoskrnl/io/iocomp.c index 21b672d..0bb9b96 100644 --- a/ntoskrnl/io/iocomp.c +++ b/ntoskrnl/io/iocomp.c @@ -11,73 +11,303 @@ /* INCLUDES *****************************************************************/ +#include #include +#include +#define NDEBUG #include +#define IOC_TAG TAG('I', 'O', 'C', 'T') + +POBJECT_TYPE ExIoCompletionType; + +NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside; + +static GENERIC_MAPPING ExIoCompletionMapping = +{ + STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE, + STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE, + STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE, + IO_COMPLETION_ALL_ACCESS +}; + /* FUNCTIONS *****************************************************************/ +NTSTATUS +STDCALL +NtpCreateIoCompletion( + PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes + ) +{ + DPRINT("NtpCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) + { + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} + +VOID STDCALL +NtpDeleteIoCompletion(PVOID ObjectBody) +{ + PKQUEUE Queue = ObjectBody; + + DPRINT("NtpDeleteIoCompletion()\n"); + + KeRundownQueue(Queue); +} + + +VOID +NtInitializeIoCompletionImplementation(VOID) +{ + ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + + RtlCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion"); + + ExIoCompletionType->Tag = IOC_TAG; + ExIoCompletionType->MaxObjects = ULONG_MAX; + ExIoCompletionType->MaxHandles = ULONG_MAX; + ExIoCompletionType->TotalObjects = 0; + ExIoCompletionType->TotalHandles = 0; + ExIoCompletionType->PagedPoolCharge = 0; + ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE); + ExIoCompletionType->Mapping = &ExIoCompletionMapping; + ExIoCompletionType->Dump = NULL; + ExIoCompletionType->Open = NULL; + ExIoCompletionType->Close = NULL; + ExIoCompletionType->Delete = NtpDeleteIoCompletion; + ExIoCompletionType->Parse = NULL; + ExIoCompletionType->Security = NULL; + ExIoCompletionType->QueryName = NULL; + ExIoCompletionType->OkayToClose = NULL; + ExIoCompletionType->Create = NtpCreateIoCompletion; + ExIoCompletionType->DuplicationNotify = NULL; + + ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside, + NULL, + NULL, + 0, + sizeof(IO_COMPLETION_PACKET), + IOC_TAG, + 0); +} + + NTSTATUS STDCALL -NtCreateIoCompletion ( - OUT PHANDLE CompletionPort, - IN ACCESS_MASK DesiredAccess, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfConcurrentThreads - ) +NtCreateIoCompletion( + OUT PHANDLE IoCompletionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG NumberOfConcurrentThreads + ) { - UNIMPLEMENTED; + PKQUEUE Queue; + NTSTATUS Status; + + Status = ObCreateObject(IoCompletionHandle, + DesiredAccess, + ObjectAttributes, + ExIoCompletionType, + (PVOID*)&Queue); + + if (NT_SUCCESS(Status)) + { + (void) KeInitializeQueue(Queue, NumberOfConcurrentThreads); + ObDereferenceObject(Queue); + } + + return Status; + /* + + CompletionPort = NULL OR ExistingCompletionPort + + */ + + } +/* +DesiredAccess: +ZERO +IO_COMPLETION_QUERY_STATE Query access +IO_COMPLETION_MODIFY_STATE Modify access +IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL + +ObjectAttributes +OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes +Return Value +STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or +STATUS_OBJECT_NAME_NOT_FOUND. +*/ NTSTATUS STDCALL -NtOpenIoCompletion ( - OUT PHANDLE CompletionPort, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes - ) +NtOpenIoCompletion( + OUT PHANDLE IoCompletionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ) { - return(STATUS_SUCCESS); + NTSTATUS Status; + + Status = ObOpenObjectByName(ObjectAttributes, + ExIoCompletionType, + NULL, + UserMode, + DesiredAccess, + NULL, + IoCompletionHandle); //<- ??? + + return Status; } NTSTATUS STDCALL -NtQueryIoCompletion ( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG NumberOfBytesTransferred - ) +NtQueryIoCompletion( + IN HANDLE IoCompletionHandle, + IN IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, + OUT PVOID IoCompletionInformation, + IN ULONG IoCompletionInformationLength, + OUT PULONG ResultLength OPTIONAL + ) { - UNIMPLEMENTED; + PKQUEUE Queue; + NTSTATUS Status; + + if (IoCompletionInformationClass != IoCompletionBasicInformation) + { + return STATUS_INVALID_INFO_CLASS; + } + if (IoCompletionInformationLength < sizeof(IO_COMPLETION_BASIC_INFORMATION)) + { + return STATUS_INFO_LENGTH_MISMATCH; + } + + Status = ObReferenceObjectByHandle( IoCompletionHandle, + IO_COMPLETION_QUERY_STATE, + ExIoCompletionType, + UserMode, + (PVOID*)&Queue, + NULL); + if (NT_SUCCESS(Status)) + { + ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->SignalState = + Queue->Header.SignalState; + + ObDereferenceObject(Queue); + + if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION); + } + + return Status; } +/* + * Dequeues an I/O completion message from an I/O completion object + */ NTSTATUS STDCALL -NtRemoveIoCompletion ( - IN HANDLE CompletionPort, - OUT PULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PULONG CompletionStatus, - PLARGE_INTEGER WaitTime - ) +NtRemoveIoCompletion( + IN HANDLE IoCompletionHandle, + OUT PULONG CompletionKey, + OUT PULONG CompletionValue, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER Timeout OPTIONAL + ) { - UNIMPLEMENTED; + PKQUEUE Queue; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle( IoCompletionHandle, + IO_COMPLETION_MODIFY_STATE, + ExIoCompletionType, + UserMode, + (PVOID*)&Queue, + NULL); + if (NT_SUCCESS(Status)) + { + PIO_COMPLETION_PACKET Packet; + PLIST_ENTRY ListEntry; + + /* + Try 2 remove packet from queue. Wait (optionaly) if + no packet in queue or max num of threads allready running. + */ + ListEntry = KeRemoveQueue(Queue, UserMode, Timeout ); + + ObDereferenceObject(Queue); + + Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry); + + if (CompletionKey) *CompletionKey = Packet->Key; + if (CompletionValue) *CompletionValue = Packet->Overlapped; + if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus; + + ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet); + } + + return Status; } +/* +ASSOSIERT MED FOB's IoCompletionContext + +typedef struct _IO_COMPLETION_CONTEXT { + PVOID Port; + ULONG Key; +} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT; + +*/ + + +/* + * Queues an I/O completion message to an I/O completion object + */ NTSTATUS STDCALL -NtSetIoCompletion ( - IN HANDLE CompletionPort, - IN ULONG CompletionKey, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG NumberOfBytesToTransfer, - OUT PULONG NumberOfBytesTransferred - ) +NtSetIoCompletion( + IN HANDLE IoCompletionPortHandle, + IN ULONG CompletionKey, + IN ULONG CompletionValue, + IN NTSTATUS CompletionStatus, + IN ULONG CompletionInformation + ) { - UNIMPLEMENTED; + NTSTATUS Status; + PKQUEUE Queue; + + Status = ObReferenceObjectByHandle( IoCompletionPortHandle, + IO_COMPLETION_MODIFY_STATE, + ExIoCompletionType, + UserMode, + (PVOID*)&Queue, + NULL); + if (NT_SUCCESS(Status)) + { + PIO_COMPLETION_PACKET Packet; + + Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside); + + Packet->Key = CompletionKey; + Packet->Overlapped = CompletionValue; + Packet->IoStatus.Status = CompletionStatus; + Packet->IoStatus.Information = CompletionInformation; + + KeInsertQueue(Queue, &Packet->ListEntry); + ObDereferenceObject(Queue); + } + + return Status; } diff --git a/ntoskrnl/io/iomgr.c b/ntoskrnl/io/iomgr.c index 46b2631..2429b90 100644 --- a/ntoskrnl/io/iomgr.c +++ b/ntoskrnl/io/iomgr.c @@ -261,7 +261,6 @@ VOID IoInit (VOID) * Initialize remaining subsubsystem */ IoInitCancelHandling(); - IoInitSymbolicLinkImplementation(); IoInitFileSystemImplementation(); IoInitVpbImplementation(); IoInitShutdownNotification(); diff --git a/ntoskrnl/io/iowork.c b/ntoskrnl/io/iowork.c index 03dbf4c..aff4cf7 100644 --- a/ntoskrnl/io/iowork.c +++ b/ntoskrnl/io/iowork.c @@ -38,8 +38,9 @@ VOID STDCALL STATIC IoWorkItemCallback(PVOID Parameter) { PIO_WORKITEM IoWorkItem = (PIO_WORKITEM)Parameter; + PDEVICE_OBJECT DeviceObject = IoWorkItem->DeviceObject; IoWorkItem->WorkerRoutine(IoWorkItem->DeviceObject, IoWorkItem->Context); - ObDereferenceObject(IoWorkItem->DeviceObject); + ObDereferenceObject(DeviceObject); } VOID STDCALL diff --git a/ntoskrnl/io/lock.c b/ntoskrnl/io/lock.c index 38cdd61..3b14693 100644 --- a/ntoskrnl/io/lock.c +++ b/ntoskrnl/io/lock.c @@ -58,6 +58,7 @@ NtLockFile ( IO_STATUS_BLOCK LocalIoStatusBlock; PIO_STATUS_BLOCK IoStatusBlock; PDEVICE_OBJECT DeviceObject; + ULONG FobFlags; //FIXME: instead of this, use SEH when available? if (!Length || !ByteOffset) { @@ -65,13 +66,9 @@ NtLockFile ( goto fail; } - /* - BUGBUG: ObReferenceObjectByHandle fails if DesiredAccess=0 and mode=UserMode! - It should ONLY fail if we desire an access that conflict with granted access! - */ Status = ObReferenceObjectByHandle( FileHandle, - FILE_READ_DATA,//BUGBUG: have to use something...but shouldn't have to! + 0, IoFileObjectType, ExGetPreviousMode(), (PVOID*)&FileObject, @@ -127,7 +124,6 @@ NtLockFile ( StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->MajorFunction = IRP_MJ_LOCK_CONTROL; StackPtr->MinorFunction = IRP_MN_LOCK; - StackPtr->DeviceObject = DeviceObject; StackPtr->FileObject = FileObject; if (ExclusiveLock) StackPtr->Flags |= SL_EXCLUSIVE_LOCK; @@ -157,15 +153,17 @@ NtLockFile ( TRUE, TRUE ); + //can't touch FileObject after IoCallDriver since it might be freed + FobFlags = FileObject->Flags; Status = IofCallDriver(DeviceObject, Irp); - if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { + if (Status == STATUS_PENDING && (FobFlags & FO_SYNCHRONOUS_IO)) { Status = KeWaitForSingleObject( Event, Executive, ExGetPreviousMode() , - (FileObject->Flags & FO_ALERTABLE_IO) ? TRUE : FALSE, + (FobFlags & FO_ALERTABLE_IO) ? TRUE : FALSE, NULL ); @@ -181,7 +179,7 @@ NtLockFile ( Status = LocalIoStatusBlock.Status; } - if (FileObject->Flags & FO_SYNCHRONOUS_IO) + if (FobFlags & FO_SYNCHRONOUS_IO) *UserIoStatusBlock = LocalIoStatusBlock; return Status; diff --git a/ntoskrnl/io/parttab.c b/ntoskrnl/io/parttab.c index 81290f1..581cc0c 100644 --- a/ntoskrnl/io/parttab.c +++ b/ntoskrnl/io/parttab.c @@ -25,10 +25,10 @@ IoReadPartitionTable(PDEVICE_OBJECT DeviceObject, BOOLEAN ReturnRecognizedPartitions, PDRIVE_LAYOUT_INFORMATION *PartitionBuffer) { - return HalDispatchTable.HalIoReadPartitionTable(DeviceObject, - SectorSize, - ReturnRecognizedPartitions, - PartitionBuffer); + return(HalIoReadPartitionTable(DeviceObject, + SectorSize, + ReturnRecognizedPartitions, + PartitionBuffer)); } @@ -38,10 +38,10 @@ IoSetPartitionInformation(PDEVICE_OBJECT DeviceObject, ULONG PartitionNumber, ULONG PartitionType) { - return HalDispatchTable.HalIoSetPartitionInformation(DeviceObject, - SectorSize, - PartitionNumber, - PartitionType); + return(HalIoSetPartitionInformation(DeviceObject, + SectorSize, + PartitionNumber, + PartitionType)); } @@ -52,11 +52,11 @@ IoWritePartitionTable(PDEVICE_OBJECT DeviceObject, ULONG NumberOfHeads, PDRIVE_LAYOUT_INFORMATION PartitionBuffer) { - return HalDispatchTable.HalIoWritePartitionTable(DeviceObject, - SectorSize, - SectorsPerTrack, - NumberOfHeads, - PartitionBuffer); + return(HalIoWritePartitionTable(DeviceObject, + SectorSize, + SectorsPerTrack, + NumberOfHeads, + PartitionBuffer)); } /* EOF */ diff --git a/ntoskrnl/io/symlink.c b/ntoskrnl/io/symlink.c index 694babc..c373446 100644 --- a/ntoskrnl/io/symlink.c +++ b/ntoskrnl/io/symlink.c @@ -11,63 +11,18 @@ /* INCLUDES *****************************************************************/ -#include #include -#include +#include #define NDEBUG #include -/* GLOBALS ******************************************************************/ - -typedef struct -{ - CSHORT Type; - CSHORT Size; - UNICODE_STRING TargetName; - OBJECT_ATTRIBUTES Target; -} SYMLNK_OBJECT, *PSYMLNK_OBJECT; - -POBJECT_TYPE IoSymbolicLinkType = NULL; - -static GENERIC_MAPPING IopSymbolicLinkMapping = { - STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY, - STANDARD_RIGHTS_WRITE, - STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY, - SYMBOLIC_LINK_ALL_ACCESS}; - -#define TAG_SYMLINK_TTARGET TAG('S', 'Y', 'T', 'T') -#define TAG_SYMLINK_TARGET TAG('S', 'Y', 'M', 'T') - -/* FUNCTIONS *****************************************************************/ - - -/********************************************************************** - * NAME INTERNAL - * IopCreateSymbolicLink - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURNN VALUE - * Status. - * - * REVISIONS - */ -NTSTATUS STDCALL -IopCreateSymbolicLink(PVOID Object, - PVOID Parent, - PWSTR RemainingPath, - POBJECT_ATTRIBUTES ObjectAttributes) -{ - return(STATUS_SUCCESS); -} +/* FUNCTIONS ****************************************************************/ /********************************************************************** - * NAME INTERNAL - * IopParseSymbolicLink + * NAME EXPORTED + * IoCreateSymbolicLink * * DESCRIPTION * @@ -76,104 +31,47 @@ IopCreateSymbolicLink(PVOID Object, * RETURN VALUE * * REVISIONS + * */ NTSTATUS STDCALL -IopParseSymbolicLink(PVOID Object, - PVOID * NextObject, - PUNICODE_STRING FullPath, - PWSTR * RemainingPath, - ULONG Attributes) +IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, + PUNICODE_STRING DeviceName) { - PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object; - UNICODE_STRING TargetPath; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + NTSTATUS Status; - DPRINT("IopParseSymbolicLink (RemainingPath %S)\n", *RemainingPath); - /* - * Stop parsing if the entire path has been parsed and - * the desired object is a symbolic link object. - */ - if (((*RemainingPath == NULL) || (**RemainingPath == 0)) && - (Attributes & OBJ_OPENLINK)) - { - DPRINT("Parsing stopped!\n"); - *NextObject = NULL; - return STATUS_SUCCESS; - } + assert_irql(PASSIVE_LEVEL); - /* build the expanded path */ - TargetPath.MaximumLength = SymlinkObject->TargetName.Length + sizeof(WCHAR); - if (RemainingPath && *RemainingPath) - { - TargetPath.MaximumLength += (wcslen(*RemainingPath) * sizeof(WCHAR)); - } - TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); - TargetPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, - TargetPath.MaximumLength, - TAG_SYMLINK_TTARGET); - wcscpy(TargetPath.Buffer, SymlinkObject->TargetName.Buffer); - if (RemainingPath && *RemainingPath) - { - wcscat(TargetPath.Buffer, *RemainingPath); - } + DPRINT("IoCreateSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n", + SymbolicLinkName, + DeviceName); - /* transfer target path buffer into FullPath */ - RtlFreeUnicodeString(FullPath); - FullPath->Length = TargetPath.Length; - FullPath->MaximumLength = TargetPath.MaximumLength; - FullPath->Buffer = TargetPath.Buffer; + InitializeObjectAttributes(&ObjectAttributes, + SymbolicLinkName, + OBJ_PERMANENT, + NULL, + SePublicDefaultSd); - /* reinitialize RemainingPath for reparsing */ - *RemainingPath = FullPath->Buffer; + Status = NtCreateSymbolicLinkObject(&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + DeviceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateSymbolicLinkObject() failed (Status %lx)\n", Status); + return(Status); + } - *NextObject = NULL; - return STATUS_REPARSE; -} + NtClose(Handle); -/********************************************************************** - * NAME INTERNAL - * IoInitSymbolicLinkImplementation - * - * DESCRIPTION - * - * ARGUMENTS - * None. - * - * RETURNN VALUE - * None. - * - * REVISIONS - */ -VOID IoInitSymbolicLinkImplementation (VOID) -{ - IoSymbolicLinkType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - - IoSymbolicLinkType->Tag = TAG('S', 'Y', 'M', 'T'); - IoSymbolicLinkType->TotalObjects = 0; - IoSymbolicLinkType->TotalHandles = 0; - IoSymbolicLinkType->MaxObjects = ULONG_MAX; - IoSymbolicLinkType->MaxHandles = ULONG_MAX; - IoSymbolicLinkType->PagedPoolCharge = 0; - IoSymbolicLinkType->NonpagedPoolCharge = sizeof (SYMLNK_OBJECT); - IoSymbolicLinkType->Mapping = &IopSymbolicLinkMapping; - IoSymbolicLinkType->Dump = NULL; - IoSymbolicLinkType->Open = NULL; - IoSymbolicLinkType->Close = NULL; - IoSymbolicLinkType->Delete = NULL; - IoSymbolicLinkType->Parse = IopParseSymbolicLink; - IoSymbolicLinkType->Security = NULL; - IoSymbolicLinkType->QueryName = NULL; - IoSymbolicLinkType->OkayToClose = NULL; - IoSymbolicLinkType->Create = IopCreateSymbolicLink; - IoSymbolicLinkType->DuplicationNotify = NULL; - - RtlInitUnicodeStringFromLiteral(&IoSymbolicLinkType->TypeName, - L"SymbolicLink"); + return(STATUS_SUCCESS); } /********************************************************************** * NAME EXPORTED - * NtOpenSymbolicLinkObject + * IoCreateUnprotectedSymbolicLink * * DESCRIPTION * @@ -185,161 +83,57 @@ VOID IoInitSymbolicLinkImplementation (VOID) * */ NTSTATUS STDCALL -NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes) +IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName, + PUNICODE_STRING DeviceName) { - DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n", - ObjectAttributes->ObjectName); + SECURITY_DESCRIPTOR SecurityDescriptor; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + NTSTATUS Status; - return(ObOpenObjectByName(ObjectAttributes, - IoSymbolicLinkType, - NULL, - UserMode, - DesiredAccess, - NULL, - LinkHandle)); -} + assert_irql(PASSIVE_LEVEL); + DPRINT("IoCreateUnprotectedSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n", + SymbolicLinkName, + DeviceName); -/********************************************************************** - * NAME EXPORTED - * NtQuerySymbolicLinkObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, - IN OUT PUNICODE_STRING LinkTarget, - OUT PULONG ReturnedLength OPTIONAL) -{ - PSYMLNK_OBJECT SymlinkObject; - NTSTATUS Status; - - Status = ObReferenceObjectByHandle(LinkHandle, - SYMBOLIC_LINK_QUERY, - IoSymbolicLinkType, - UserMode, - (PVOID *)&SymlinkObject, - NULL); + Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { + DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n", Status); return(Status); } - - RtlCopyUnicodeString(LinkTarget, - SymlinkObject->Target.ObjectName); - if (ReturnedLength != NULL) + + Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, + TRUE, + NULL, + TRUE); + if (!NT_SUCCESS(Status)) { - *ReturnedLength = SymlinkObject->Target.Length; + DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n", Status); + return(Status); } - ObDereferenceObject(SymlinkObject); - - return(STATUS_SUCCESS); -} - - -/********************************************************************** - * NAME EXPORTED - * IoCreateUnprotectedSymbolicLink - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName, - PUNICODE_STRING DeviceName) -{ - return(IoCreateSymbolicLink(SymbolicLinkName, - DeviceName)); -} + InitializeObjectAttributes(&ObjectAttributes, + SymbolicLinkName, + OBJ_PERMANENT, + NULL, + &SecurityDescriptor); -/********************************************************************** - * NAME EXPORTED - * IoCreateSymbolicLink - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName, - PUNICODE_STRING DeviceName) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - PSYMLNK_OBJECT SymbolicLink; - NTSTATUS Status; - - assert_irql(PASSIVE_LEVEL); + Status = NtCreateSymbolicLinkObject(&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes, + DeviceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateSymbolicLinkObject() failed (Status %lx)\n", Status); + return(Status); + } - DPRINT( - "IoCreateSymbolicLink(SymbolicLinkName %S, DeviceName %S)\n", - SymbolicLinkName->Buffer, - DeviceName->Buffer - ); + NtClose(Handle); - InitializeObjectAttributes( - & ObjectAttributes, - SymbolicLinkName, - OBJ_PERMANENT, - NULL, - NULL - ); - Status = ObCreateObject( - NULL, - SYMBOLIC_LINK_ALL_ACCESS, - & ObjectAttributes, - IoSymbolicLinkType, - (PVOID*)&SymbolicLink - ); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - SymbolicLink->TargetName.Length = 0; - SymbolicLink->TargetName.MaximumLength = - ((wcslen(DeviceName->Buffer) + 1) * sizeof(WCHAR)); - SymbolicLink->TargetName.Buffer = - ExAllocatePoolWithTag(NonPagedPool, - SymbolicLink->TargetName.MaximumLength, - TAG_SYMLINK_TARGET); - RtlCopyUnicodeString( - & (SymbolicLink->TargetName), - DeviceName - ); - - DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); - - InitializeObjectAttributes( - & (SymbolicLink->Target), - & (SymbolicLink->TargetName), - 0, - NULL, - NULL - ); - - DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__); - ObDereferenceObject( SymbolicLink ); - return STATUS_SUCCESS; + return(STATUS_SUCCESS); } @@ -386,68 +180,4 @@ IoDeleteSymbolicLink(PUNICODE_STRING SymbolicLinkName) return(Status); } - -/********************************************************************** - * NAME (EXPORTED as Zw) - * NtCreateSymbolicLinkObject - * - * DESCRIPTION - * - * ARGUMENTS - * - * RETURN VALUE - * - * REVISIONS - * - */ -NTSTATUS STDCALL -NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN PUNICODE_STRING DeviceName) -{ - PSYMLNK_OBJECT SymbolicLink; - NTSTATUS Status; - - assert_irql(PASSIVE_LEVEL); - - DPRINT("NtCreateSymbolicLinkObject(SymbolicLinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, DeviceName %S)\n", - SymbolicLinkHandle, - DesiredAccess, - ObjectAttributes, - DeviceName->Buffer); - - Status = ObCreateObject(SymbolicLinkHandle, - DesiredAccess, - ObjectAttributes, - IoSymbolicLinkType, - (PVOID*)&SymbolicLink); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - SymbolicLink->TargetName.Length = 0; - SymbolicLink->TargetName.MaximumLength = - ((wcslen(DeviceName->Buffer) + 1) * sizeof(WCHAR)); - SymbolicLink->TargetName.Buffer = - ExAllocatePoolWithTag(NonPagedPool, - SymbolicLink->TargetName.MaximumLength, - TAG_SYMLINK_TARGET); - RtlCopyUnicodeString(&SymbolicLink->TargetName, - DeviceName); - - DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); - - InitializeObjectAttributes(&SymbolicLink->Target, - &SymbolicLink->TargetName, - 0, - NULL, - NULL); - - DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__); - ObDereferenceObject(SymbolicLink); - return(STATUS_SUCCESS); -} - /* EOF */ diff --git a/ntoskrnl/io/xhaldisp.c b/ntoskrnl/io/xhaldisp.c index 91d00ed..8d0d313 100644 --- a/ntoskrnl/io/xhaldisp.c +++ b/ntoskrnl/io/xhaldisp.c @@ -42,8 +42,11 @@ HAL_PRIVATE_DISPATCH EXPORTED HalPrivateDispatchTable = // HalHandlerForConfigSpace // HalCompleteDeviceControl // HalRegisterBusHandler - // any more?? + // ?? + // ?? + // ?? + // ?? + // ?? }; /* EOF */ - diff --git a/ntoskrnl/io/xhaldrv.c b/ntoskrnl/io/xhaldrv.c index 39973e0..0404f76 100644 --- a/ntoskrnl/io/xhaldrv.c +++ b/ntoskrnl/io/xhaldrv.c @@ -22,31 +22,42 @@ #define AUTO_DRIVE ((ULONG)-1) #define PARTITION_MAGIC 0xaa55 -#define PART_MAGIC_OFFSET 0x01fe -#define PARTITION_OFFSET 0x01be -#define SIGNATURE_OFFSET 0x01b8 + #define PARTITION_TBL_SIZE 4 typedef struct _PARTITION { - unsigned char BootFlags; - unsigned char StartingHead; - unsigned char StartingSector; - unsigned char StartingCylinder; - unsigned char PartitionType; - unsigned char EndingHead; - unsigned char EndingSector; - unsigned char EndingCylinder; - unsigned int StartingBlock; - unsigned int SectorCount; -} PARTITION, *PPARTITION; - -typedef struct _PARTITION_TABLE + unsigned char BootFlags; /* bootable? 0=no, 128=yes */ + unsigned char StartingHead; /* beginning head number */ + unsigned char StartingSector; /* beginning sector number */ + unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */ + unsigned char PartitionType; /* Operating System type indicator code */ + unsigned char EndingHead; /* ending head number */ + unsigned char EndingSector; /* ending sector number */ + unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */ + unsigned int StartingBlock; /* first sector relative to start of disk */ + unsigned int SectorCount; /* number of sectors in partition */ +} PACKED PARTITION, *PPARTITION; + + +typedef struct _PARTITION_SECTOR { - PARTITION Partition[PARTITION_TBL_SIZE]; - unsigned short Magic; -} PARTITION_TABLE, *PPARTITION_TABLE; + UCHAR BootCode[440]; /* 0x000 */ + ULONG Signature; /* 0x1B8 */ + UCHAR Reserved[2]; /* 0x1BC */ + PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */ + USHORT Magic; /* 0x1FE */ +} PACKED PARTITION_SECTOR, *PPARTITION_SECTOR; + + +typedef enum _DISK_MANAGER +{ + NoDiskManager, + OntrackDiskManager, + EZ_Drive +} DISK_MANAGER; + /* FUNCTIONS *****************************************************************/ @@ -159,20 +170,23 @@ xHalQueryDriveLayout(IN PUNICODE_STRING DeviceName, } -VOID FASTCALL -xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, - IN ULONG SectorSize, - IN ULONG MBRTypeIdentifier, - OUT PVOID *Buffer) +static NTSTATUS +xHalpReadSector(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN PLARGE_INTEGER SectorOffset, + OUT PVOID *Buffer) { KEVENT Event; IO_STATUS_BLOCK StatusBlock; - LARGE_INTEGER Offset; - PUCHAR LocalBuffer; + PUCHAR Sector; PIRP Irp; NTSTATUS Status; - DPRINT("xHalExamineMBR()\n"); + DPRINT("xHalReadMBR()\n"); + + assert(DeviceObject); + assert(Buffer); + *Buffer = NULL; if (SectorSize < 512) @@ -180,22 +194,77 @@ xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, if (SectorSize > 4096) SectorSize = 4096; - LocalBuffer = (PUCHAR)ExAllocatePool(PagedPool, - SectorSize); - if (LocalBuffer == NULL) - return; + Sector = (PUCHAR)ExAllocatePool(PagedPool, + SectorSize); + if (Sector == NULL) + return STATUS_NO_MEMORY; KeInitializeEvent(&Event, NotificationEvent, FALSE); - Offset.QuadPart = 0; - + /* Read MBR (Master Boot Record) */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, - LocalBuffer, + Sector, + SectorSize, + SectorOffset, + &Event, + &StatusBlock); + + Status = IoCallDriver(DeviceObject, + Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + Status = StatusBlock.Status; + } + + if (!NT_SUCCESS(Status)) + { + DPRINT("Reading MBR failed (Status 0x%08lx)\n", + Status); + ExFreePool(Sector); + return Status; + } + + *Buffer = (PVOID)Sector; + return Status; +} + + +static NTSTATUS +xHalpWriteSector(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN PLARGE_INTEGER SectorOffset, + OUT PVOID Sector) +{ + KEVENT Event; + IO_STATUS_BLOCK StatusBlock; + PIRP Irp; + NTSTATUS Status; + + DPRINT("xHalWriteMBR()\n"); + + if (SectorSize < 512) + SectorSize = 512; + if (SectorSize > 4096) + SectorSize = 4096; + + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); + + /* Write MBR (Master Boot Record) */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, + DeviceObject, + Sector, SectorSize, - &Offset, + SectorOffset, &Event, &StatusBlock); @@ -213,27 +282,64 @@ xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, if (!NT_SUCCESS(Status)) { - DPRINT("xHalExamineMBR failed (Status = 0x%08lx)\n", + DPRINT("Writing MBR failed (Status 0x%08lx)\n", Status); - ExFreePool(LocalBuffer); + return Status; + } + + return Status; +} + + +VOID FASTCALL +xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject, + IN ULONG SectorSize, + IN ULONG MBRTypeIdentifier, + OUT PVOID *Buffer) +{ + LARGE_INTEGER SectorOffset; + PPARTITION_SECTOR Sector; + PULONG Shift; + NTSTATUS Status; + + DPRINT("xHalExamineMBR()\n"); + + *Buffer = NULL; + + SectorOffset.QuadPart = 0ULL; + Status = xHalpReadSector(DeviceObject, + SectorSize, + &SectorOffset, + (PVOID *)&Sector); + if (!NT_SUCCESS(Status)) + { + DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status); return; } - if (LocalBuffer[0x1FE] != 0x55 || LocalBuffer[0x1FF] != 0xAA) + if (Sector->Magic != PARTITION_MAGIC) { - DPRINT("xHalExamineMBR: invalid MBR signature\n"); - ExFreePool(LocalBuffer); + DPRINT("Invalid MBR magic value\n"); + ExFreePool(Sector); return; } - if (LocalBuffer[0x1C2] != MBRTypeIdentifier) + if (Sector->Partition[0].PartitionType != MBRTypeIdentifier) { - DPRINT("xHalExamineMBR: invalid MBRTypeIdentifier\n"); - ExFreePool(LocalBuffer); + DPRINT("Invalid MBRTypeIdentifier\n"); + ExFreePool(Sector); return; } - *Buffer = (PVOID)LocalBuffer; + if (Sector->Partition[0].PartitionType == 0x54) + { + /* Found 'Ontrack Disk Manager'. Shift all sectors by 63 */ + DPRINT("Found 'Ontrack Disk Manager'!\n"); + Shift = (PULONG)Sector; + *Shift = 63; + } + + *Buffer = (PVOID)Sector; } @@ -589,17 +695,19 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, KEVENT Event; IO_STATUS_BLOCK StatusBlock; ULARGE_INTEGER PartitionOffset; - ULARGE_INTEGER nextPartitionOffset; - ULARGE_INTEGER containerOffset; - PUCHAR SectorBuffer; + ULARGE_INTEGER RealPartitionOffset; + ULARGE_INTEGER nextPartitionOffset; + ULARGE_INTEGER containerOffset; PIRP Irp; NTSTATUS Status; - PPARTITION_TABLE PartitionTable; + PPARTITION_SECTOR PartitionSector; PDRIVE_LAYOUT_INFORMATION LayoutBuffer; ULONG i; ULONG Count = 0; ULONG Number = 1; BOOLEAN ExtendedFound = FALSE; + PVOID MbrBuffer; + DISK_MANAGER DiskManager = NoDiskManager; DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n", DeviceObject, @@ -609,9 +717,33 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, *PartitionBuffer = NULL; - SectorBuffer = (PUCHAR)ExAllocatePool(PagedPool, - SectorSize); - if (SectorBuffer == NULL) + /* Check for 'Ontrack Disk Manager' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x54, + &MbrBuffer); + if (MbrBuffer != NULL) + { + DPRINT("Found 'Ontrack Disk Manager'\n"); + DiskManager = OntrackDiskManager; + ExFreePool(MbrBuffer); + } + + /* Check for 'EZ-Drive' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x55, + &MbrBuffer); + if (MbrBuffer != NULL) + { + DPRINT("Found 'EZ-Drive'\n"); + DiskManager = EZ_Drive; + ExFreePool(MbrBuffer); + } + + PartitionSector = (PPARTITION_SECTOR)ExAllocatePool(PagedPool, + SectorSize); + if (PartitionSector == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } @@ -620,29 +752,40 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, 0x1000); if (LayoutBuffer == NULL) { - ExFreePool(SectorBuffer); + ExFreePool(PartitionSector); return(STATUS_INSUFFICIENT_RESOURCES); } RtlZeroMemory(LayoutBuffer, 0x1000); - PartitionOffset.QuadPart = 0; - containerOffset.QuadPart = 0; + PartitionOffset.QuadPart = (ULONGLONG)0; + containerOffset.QuadPart = (ULONGLONG)0; do { + DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize); + + if (DiskManager == OntrackDiskManager) + { + RealPartitionOffset.QuadPart = PartitionOffset.QuadPart + (ULONGLONG)(63 * SectorSize); + } + else + { + RealPartitionOffset.QuadPart = PartitionOffset.QuadPart; + } + + DPRINT("RealPartitionOffset: %I64u\n", RealPartitionOffset.QuadPart / SectorSize); + KeInitializeEvent(&Event, NotificationEvent, FALSE); - DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize); - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, - SectorBuffer, + PartitionSector, //SectorBuffer, SectorSize, - (PLARGE_INTEGER)&PartitionOffset, + (PLARGE_INTEGER)&RealPartitionOffset, &Event, &StatusBlock); Status = IoCallDriver(DeviceObject, @@ -661,19 +804,17 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, { DPRINT("Failed to read partition table sector (Status = 0x%08lx)\n", Status); - ExFreePool(SectorBuffer); + ExFreePool(PartitionSector); ExFreePool(LayoutBuffer); return(Status); } - PartitionTable = (PPARTITION_TABLE)(SectorBuffer + PARTITION_OFFSET); - /* check the boot sector id */ - DPRINT("Magic %x\n", PartitionTable->Magic); - if (PartitionTable->Magic != PARTITION_MAGIC) + DPRINT("Magic %x\n", PartitionSector->Magic); + if (PartitionSector->Magic != PARTITION_MAGIC) { - DbgPrint("Invalid partition table magic\n"); - ExFreePool(SectorBuffer); + DbgPrint("Invalid partition sector magic\n"); + ExFreePool(PartitionSector); *PartitionBuffer = LayoutBuffer; return(STATUS_SUCCESS); } @@ -683,23 +824,24 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, { DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", i, - PartitionTable->Partition[i].BootFlags, - PartitionTable->Partition[i].PartitionType, - PartitionTable->Partition[i].StartingHead, - PartitionTable->Partition[i].StartingSector & 0x3f, - (((PartitionTable->Partition[i].StartingSector) & 0xc0) << 2) + - PartitionTable->Partition[i].StartingCylinder, - PartitionTable->Partition[i].EndingHead, - PartitionTable->Partition[i].EndingSector, - PartitionTable->Partition[i].EndingCylinder, - PartitionTable->Partition[i].StartingBlock, - PartitionTable->Partition[i].SectorCount); + PartitionSector->Partition[i].BootFlags, + PartitionSector->Partition[i].PartitionType, + PartitionSector->Partition[i].StartingHead, + PartitionSector->Partition[i].StartingSector & 0x3f, + (((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) + + PartitionSector->Partition[i].StartingCylinder, + PartitionSector->Partition[i].EndingHead, + PartitionSector->Partition[i].EndingSector, + PartitionSector->Partition[i].EndingCylinder, + PartitionSector->Partition[i].StartingBlock, + PartitionSector->Partition[i].SectorCount); } #endif - if (ExtendedFound == FALSE); + if (PartitionOffset.QuadPart == 0ULL) { - LayoutBuffer->Signature = *((PULONG)(SectorBuffer + SIGNATURE_OFFSET)); + LayoutBuffer->Signature = PartitionSector->Signature; + DPRINT("Disk signature: %lx\n", LayoutBuffer->Signature); } ExtendedFound = FALSE; @@ -708,17 +850,17 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, { if ((ReturnRecognizedPartitions == FALSE) || ((ReturnRecognizedPartitions == TRUE) && - IsRecognizedPartition(PartitionTable->Partition[i].PartitionType))) + IsRecognizedPartition(PartitionSector->Partition[i].PartitionType))) { /* handle normal partition */ DPRINT("Partition %u: Normal Partition\n", i); Count = LayoutBuffer->PartitionCount; DPRINT("Logical Partition %u\n", Count); - if (PartitionTable->Partition[i].StartingBlock == 0) + if (PartitionSector->Partition[i].StartingBlock == 0) { LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0; } - else if (IsContainerPartition(PartitionTable->Partition[i].PartitionType)) + else if (IsContainerPartition(PartitionSector->Partition[i].PartitionType)) { LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = (ULONGLONG)PartitionOffset.QuadPart; @@ -727,13 +869,13 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, { LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = (ULONGLONG)PartitionOffset.QuadPart + - ((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize); + ((ULONGLONG)PartitionSector->Partition[i].StartingBlock * (ULONGLONG)SectorSize); } LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart = - (ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize; + (ULONGLONG)PartitionSector->Partition[i].SectorCount * (ULONGLONG)SectorSize; LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0; - if (IsRecognizedPartition(PartitionTable->Partition[i].PartitionType)) + if (IsRecognizedPartition(PartitionSector->Partition[i].PartitionType)) { LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number; Number++; @@ -744,11 +886,11 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, } LayoutBuffer->PartitionEntry[Count].PartitionType = - PartitionTable->Partition[i].PartitionType; + PartitionSector->Partition[i].PartitionType; LayoutBuffer->PartitionEntry[Count].BootIndicator = - (PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE; + (PartitionSector->Partition[i].BootFlags & 0x80)?TRUE:FALSE; LayoutBuffer->PartitionEntry[Count].RecognizedPartition = - IsRecognizedPartition (PartitionTable->Partition[i].PartitionType); + IsRecognizedPartition (PartitionSector->Partition[i].PartitionType); LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE; DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n", @@ -762,7 +904,7 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, LayoutBuffer->PartitionCount++; } - if (IsContainerPartition(PartitionTable->Partition[i].PartitionType)) + if (IsContainerPartition(PartitionSector->Partition[i].PartitionType)) { ExtendedFound = TRUE; if ((ULONGLONG) containerOffset.QuadPart == (ULONGLONG) 0) @@ -770,7 +912,7 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, containerOffset = PartitionOffset; } nextPartitionOffset.QuadPart = (ULONGLONG) containerOffset.QuadPart + - (ULONGLONG) PartitionTable->Partition[i].StartingBlock * + (ULONGLONG) PartitionSector->Partition[i].StartingBlock * (ULONGLONG) SectorSize; } } @@ -779,7 +921,7 @@ xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject, while (ExtendedFound == TRUE); *PartitionBuffer = LayoutBuffer; - ExFreePool(SectorBuffer); + ExFreePool(PartitionSector); return(STATUS_SUCCESS); } @@ -802,7 +944,126 @@ xHalIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer) { - return(STATUS_NOT_IMPLEMENTED); + PPARTITION_SECTOR PartitionSector; + LARGE_INTEGER SectorOffset; + NTSTATUS Status; + ULONG i; + + DPRINT("xHalIoWritePartitionTable(%p %lu %lu %p)\n", + DeviceObject, + SectorSize, + SectorsPerTrack, + PartitionBuffer); + + assert(DeviceObject); + assert(PartitionBuffer); + + /* Check for 'Ontrack Disk Manager' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x54, + (PVOID *) &PartitionSector); + if (PartitionSector != NULL) + { + DPRINT1("Ontrack Disk Manager is not supported\n"); + ExFreePool(PartitionSector); + return STATUS_UNSUCCESSFUL; + } + + /* Check for 'EZ-Drive' */ + xHalExamineMBR(DeviceObject, + SectorSize, + 0x55, + (PVOID *) &PartitionSector); + if (PartitionSector != NULL) + { + DPRINT1("EZ-Drive is not supported\n"); + ExFreePool(PartitionSector); + return STATUS_UNSUCCESSFUL; + } + + + for (i = 0; i < PartitionBuffer->PartitionCount; i++) + { + if (IsContainerPartition(PartitionBuffer->PartitionEntry[i].PartitionType)) + { + /* FIXME: Implement */ + DPRINT1("Writing MBRs with extended partitions is not implemented\n"); + return STATUS_UNSUCCESSFUL; + } + } + + + SectorOffset.QuadPart = 0ULL; + Status = xHalpReadSector(DeviceObject, + SectorSize, + &SectorOffset, + (PVOID *) &PartitionSector); + if (!NT_SUCCESS(Status)) + { + DPRINT1("xHalpReadSector() failed (Status %lx)\n", Status); + return Status; + } + + DPRINT1("WARNING: Only 'BootFlags' is implemented\n"); + + + for (i = 0; i < PartitionBuffer->PartitionCount; i++) + { + //= PartitionBuffer->PartitionEntry[i].StartingOffset; + //= PartitionBuffer->PartitionEntry[i].PartitionLength; + //= PartitionBuffer->PartitionEntry[i].HiddenSectors; + //= PartitionBuffer->PartitionEntry[i].PartitionType; + //= PartitionBuffer->PartitionEntry[i].PartitionType; + + if (PartitionBuffer->PartitionEntry[i].BootIndicator) + { + PartitionSector->Partition[i].BootFlags |= 0x80; + } + else + { + PartitionSector->Partition[i].BootFlags &= ~0x80; + } + + //= PartitionBuffer->PartitionEntry[i].RecognizedPartition; + //= PartitionBuffer->PartitionEntry[i].RewritePartition; + } + + + SectorOffset.QuadPart = 0ULL; + Status = xHalpWriteSector(DeviceObject, + SectorSize, + &SectorOffset, + (PVOID) PartitionSector); + if (!NT_SUCCESS(Status)) + { + DPRINT1("xHalpWriteSector() failed (Status %lx)\n", Status); + ExFreePool(PartitionSector); + return Status; + } + +#ifndef NDEBUG + for (i = 0; i < PARTITION_TBL_SIZE; i++) + { + DPRINT1(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", + i, + PartitionSector->Partition[i].BootFlags, + PartitionSector->Partition[i].PartitionType, + PartitionSector->Partition[i].StartingHead, + PartitionSector->Partition[i].StartingSector & 0x3f, + (((PartitionSector->Partition[i].StartingSector) & 0xc0) << 2) + + PartitionSector->Partition[i].StartingCylinder, + PartitionSector->Partition[i].EndingHead, + PartitionSector->Partition[i].EndingSector, + PartitionSector->Partition[i].EndingCylinder, + PartitionSector->Partition[i].StartingBlock, + PartitionSector->Partition[i].SectorCount); + } +#endif + + ExFreePool(PartitionSector); + + return(STATUS_SUCCESS); } /* EOF */ diff --git a/ntoskrnl/kd/gdbstub.c b/ntoskrnl/kd/gdbstub.c index 89c2112..2c8e461 100644 --- a/ntoskrnl/kd/gdbstub.c +++ b/ntoskrnl/kd/gdbstub.c @@ -129,6 +129,8 @@ typedef struct _CPU_REGISTER { DWORD Size; DWORD OffsetInTF; + DWORD OffsetInContext; + BOOLEAN SetInContext; } CPU_REGISTER, *PCPU_REGISTER; #define KTRAP_FRAME_X86 KTRAP_FRAME @@ -137,22 +139,22 @@ typedef struct _CPU_REGISTER static CPU_REGISTER GspRegisters[NUMREGS] = { - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eax) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ecx) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edx) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebx) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esp) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebp) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esi) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edi) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eip) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eflags) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Cs) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ss) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ds) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Es) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Fs) }, - { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Gs) } + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eax), FIELD_OFFSET (CONTEXT, Eax), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ecx), FIELD_OFFSET (CONTEXT, Ecx), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edx), FIELD_OFFSET (CONTEXT, Edx), FALSE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebx), FIELD_OFFSET (CONTEXT, Ebx), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esp), FIELD_OFFSET (CONTEXT, Esp), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ebp), FIELD_OFFSET (CONTEXT, Ebp), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Esi), FIELD_OFFSET (CONTEXT, Esi), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Edi), FIELD_OFFSET (CONTEXT, Edi), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eip), FIELD_OFFSET (CONTEXT, Eip), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eflags), FIELD_OFFSET (CONTEXT, EFlags), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Cs), FIELD_OFFSET (CONTEXT, SegCs), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ss), FIELD_OFFSET (CONTEXT, SegSs), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Ds), FIELD_OFFSET (CONTEXT, SegDs), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Es), FIELD_OFFSET (CONTEXT, SegEs), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Fs), FIELD_OFFSET (CONTEXT, SegFs), TRUE }, + { 4, FIELD_OFFSET (KTRAP_FRAME_X86, Gs), FIELD_OFFSET (CONTEXT, SegGs), TRUE } }; static PCHAR GspThreadStates[THREAD_STATE_MAX] = @@ -349,46 +351,10 @@ GspPutPacketNoWait (PCHAR Buffer) KdPutChar (HexChars[Checksum & 0xf]); } - -VOID -GspDebugError(LPSTR Message) -{ - DbgPrint ("%s\n", Message); -} - -/* Address of a routine to RTE to if we get a memory fault. */ -static VOID (*volatile MemoryFaultRoutine) () = NULL; - /* Indicate to caller of GspMem2Hex or GspHex2Mem that there has been an error. */ static volatile BOOLEAN GspMemoryError = FALSE; - - -/* Currently not used */ -VOID -GspSetMemoryError() -{ - GspMemoryError = TRUE; -} - - -/* These are separate functions so that they are so short and sweet - that the compiler won't save any Registers (if there is a fault - to MemoryFaultRoutine, they won't get restored, so there better - not be any saved). */ -CHAR -GspGetChar (PCHAR Address) -{ - return *Address; -} - - -VOID -GspSetChar (PCHAR Address, - CHAR Value) -{ - *Address = Value; -} +static volatile void *GspAccessLocation = NULL; /* Convert the memory pointed to by Address into hex, placing result in Buffer */ @@ -404,19 +370,25 @@ GspMem2Hex (PCHAR Address, ULONG i; CHAR ch; - if (MayFault) - MemoryFaultRoutine = GspSetMemoryError; + if (NULL == Address && MayFault) + { + GspMemoryError = TRUE; + return Buffer; + } + for (i = 0; i < (ULONG) Count; i++) { - ch = GspGetChar (Address++); + if (MayFault) + GspAccessLocation = Address; + ch = *Address; + GspAccessLocation = NULL; if (MayFault && GspMemoryError) return (Buffer); *Buffer++ = HexChars[(ch >> 4) & 0xf]; *Buffer++ = HexChars[ch & 0xf]; + Address++; } *Buffer = 0; - if (MayFault) - MemoryFaultRoutine = NULL; return (Buffer); } @@ -429,21 +401,51 @@ GspHex2Mem (PCHAR Buffer, ULONG Count, BOOLEAN MayFault) { + PCHAR current; + PCHAR page; + ULONG countinpage; ULONG i; CHAR ch; + ULONG oldprot = 0; - if (MayFault) - MemoryFaultRoutine = GspSetMemoryError; - for (i = 0; i < Count; i++) + current = Address; + while ( current < Address + Count ) { - ch = HexValue (*Buffer++) << 4; - ch = ch + HexValue (*Buffer++); - GspSetChar (Address++, ch); - if (MayFault && GspMemoryError) - return (Buffer); + page = (PCHAR)PAGE_ROUND_DOWN (current); + if (Address + Count <= page + PAGE_SIZE) + { + /* Fits in this page */ + countinpage = Count; + } + else + { + /* Flows into next page, handle only current page in this iteration */ + countinpage = PAGE_SIZE - (Address - page); + } + if (MayFault) + { + oldprot = MmGetPageProtect (NULL, Address); + MmSetPageProtect (NULL, Address, PAGE_EXECUTE_READWRITE); + } + + for (i = 0; i < countinpage && ! GspMemoryError; i++) + { + ch = HexValue (*Buffer++) << 4; + ch = ch + HexValue (*Buffer++); + + GspAccessLocation = Address; + *current = ch; + GspAccessLocation = NULL; + current++; + } + if (MayFault) + { + MmSetPageProtect (NULL, page, oldprot); + if (GspMemoryError) + return (Buffer); + } } - if (MayFault) - MemoryFaultRoutine = NULL; + return (Buffer); } @@ -461,14 +463,12 @@ GspComputeSignal (NTSTATUS ExceptionCode) SigVal = 8; break; /* divide by zero */ case STATUS_SINGLE_STEP: - SigVal = 5; - break; /* debug exception */ + /* debug exception */ case STATUS_BREAKPOINT: SigVal = 5; break; /* breakpoint */ case STATUS_INTEGER_OVERFLOW: - SigVal = 16; - break; /* into instruction (overflow) */ + /* into instruction (overflow) */ case STATUS_ARRAY_BOUNDS_EXCEEDED: SigVal = 16; break; /* bound instruction */ @@ -481,11 +481,12 @@ GspComputeSignal (NTSTATUS ExceptionCode) break; /* coprocessor not available */ #endif case STATUS_STACK_OVERFLOW: - SigVal = 11; - break; /* stack exception */ + /* stack exception */ case STATUS_DATATYPE_MISALIGNMENT: - SigVal = 11; - break; /* page fault */ + /* page fault */ + case STATUS_ACCESS_VIOLATION: + SigVal = 11; /* access violation */ + break; default: SigVal = 7; /* "software generated" */ } @@ -530,55 +531,73 @@ GspLong2Hex (PCHAR *Address, { LONG Save; - Save = (((Value >> 0) & 0xf) << 24) | - (((Value >> 8) & 0xf) << 16) | - (((Value >> 16) & 0xf) << 8) | - (((Value >> 24) & 0xf) << 0); + Save = (((Value >> 0) & 0xff) << 24) | + (((Value >> 8) & 0xff) << 16) | + (((Value >> 16) & 0xff) << 8) | + (((Value >> 24) & 0xff) << 0); *Address = GspMem2Hex ((PCHAR) &Save, *Address, 4, FALSE); } +/* + * Esp is not stored in the trap frame, although there is a member with it's name. + * Instead, it was pointing to the location of the TrapFrame Esp member when the + * exception occured. + */ +static LONG +GspGetEspFromTrapFrame(PKTRAP_FRAME TrapFrame) +{ + return (LONG) &TrapFrame->Esp; +} + + VOID GspGetRegistersFromTrapFrame(PCHAR Address, + PCONTEXT Context, PKTRAP_FRAME TrapFrame) { - PCPU_REGISTER Regs; ULONG Value; PCHAR Buffer; PULONG p; DWORD i; Buffer = Address; - Regs = &GspRegisters[0]; - for (i = 0; i < NUMREGS; i++) + for (i = 0; i < sizeof (GspRegisters) / sizeof (GspRegisters[0]); i++) { if (TrapFrame) { - p = (PULONG) ((ULONG_PTR) TrapFrame + Regs[i].OffsetInTF); - Value = *p; + if (ESP == i) + { + Value = GspGetEspFromTrapFrame (TrapFrame); + } + else + { + p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[i].OffsetInTF); + Value = *p; + } } else if (i == EIP_REGNO) - { + { /* * This thread has not been sheduled yet so assume it * is still in PsBeginThreadWithContextInternal(). */ Value = (ULONG) PsBeginThreadWithContextInternal; - } + } else - { + { Value = 0; } - Buffer = GspMem2Hex ((PCHAR) &Value, Buffer, Regs[i].Size, FALSE); + Buffer = GspMem2Hex ((PCHAR) &Value, Buffer, GspRegisters[i].Size, FALSE); } } VOID GspSetRegistersInTrapFrame(PCHAR Address, + PCONTEXT Context, PKTRAP_FRAME TrapFrame) { - PCPU_REGISTER Regs; ULONG Value; PCHAR Buffer; PULONG p; @@ -588,12 +607,14 @@ GspSetRegistersInTrapFrame(PCHAR Address, return; Buffer = Address; - Regs = &GspRegisters[0]; for (i = 0; i < NUMREGS; i++) { - p = (PULONG) ((ULONG_PTR) TrapFrame + Regs[i].OffsetInTF); + if (GspRegisters[i].SetInContext) + p = (PULONG) ((ULONG_PTR) Context + GspRegisters[i].OffsetInContext); + else + p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[i].OffsetInTF); Value = 0; - Buffer = GspHex2Mem (Buffer, (PCHAR) &Value, Regs[i].Size, FALSE); + Buffer = GspHex2Mem (Buffer, (PCHAR) &Value, GspRegisters[i].Size, FALSE); *p = Value; } } @@ -602,6 +623,7 @@ GspSetRegistersInTrapFrame(PCHAR Address, VOID GspSetSingleRegisterInTrapFrame(PCHAR Address, LONG Number, + PCONTEXT Context, PKTRAP_FRAME TrapFrame) { ULONG Value; @@ -610,7 +632,10 @@ GspSetSingleRegisterInTrapFrame(PCHAR Address, if (!TrapFrame) return; - p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF); + if (GspRegisters[Number].SetInContext) + p = (PULONG) ((ULONG_PTR) Context + GspRegisters[Number].OffsetInContext); + else + p = (PULONG) ((ULONG_PTR) TrapFrame + GspRegisters[Number].OffsetInTF); Value = 0; GspHex2Mem (Address, (PCHAR) &Value, GspRegisters[Number].Size, FALSE); *p = Value; @@ -667,7 +692,10 @@ GspSetThread(PCHAR Request) { GspOutBuffer[0] = 'O'; GspOutBuffer[1] = 'K'; - GspRunThread = ThreadInfo; + + if(GspRunThread) ObDereferenceObject(GspRunThread); + + GspRunThread = ThreadInfo; } else { @@ -679,7 +707,10 @@ GspSetThread(PCHAR Request) { GspOutBuffer[0] = 'O'; GspOutBuffer[1] = 'K'; - GspDbgThread = ThreadInfo; + + if(GspDbgThread) ObDereferenceObject(GspDbgThread); + + GspDbgThread = ThreadInfo; } else { @@ -706,7 +737,14 @@ GspQuery(PCHAR Request) /* Get current thread id */ GspOutBuffer[0] = 'Q'; GspOutBuffer[1] = 'C'; - Value = (ULONG) GspDbgThread->Cid.UniqueThread; + if (NULL != GspDbgThread) + { + Value = (ULONG) GspDbgThread->Cid.UniqueThread; + } + else + { + Value = (ULONG) PsGetCurrentThread()->Cid.UniqueThread; + } GspLong2Hex (&ptr, Value); } else if (strncmp (Command, "fThreadInfo", 11) == 0) @@ -735,7 +773,7 @@ GspQuery(PCHAR Request) } else { - GspOutBuffer[0] = '1'; + GspOutBuffer[0] = 'l'; } } else if (strncmp (Command, "ThreadExtraInfo", 15) == 0) @@ -746,8 +784,11 @@ GspQuery(PCHAR Request) /* Get thread information */ if (GspFindThread (ptr, &ThreadInfo)) { - PCHAR String = GspThreadStates[ThreadInfo->Tcb.State]; - GspMem2Hex (String, &GspOutBuffer[0], strlen (String), FALSE); + PCHAR String = GspThreadStates[ThreadInfo->Tcb.State]; + + ObDereferenceObject(ThreadInfo); + + GspMem2Hex (String, &GspOutBuffer[0], strlen (String), FALSE); } } #if 0 @@ -808,6 +849,8 @@ GspQueryThreadStatus(PCHAR Request) if (GspFindThread (ptr, &ThreadInfo)) { + ObDereferenceObject(ThreadInfo); + GspOutBuffer[0] = 'O'; GspOutBuffer[1] = 'K'; GspOutBuffer[2] = '\0'; @@ -947,248 +990,269 @@ KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord, LONG SigVal; LONG NewPC; PCHAR ptr; + LONG Esp; /* FIXME: Stop on other CPUs too */ /* Disable hardware debugging while we are inside the stub */ __asm__("movl %0,%%db7" : /* no output */ : "r" (0)); - /* reply to host that an exception has occurred */ - SigVal = GspComputeSignal (ExceptionRecord->ExceptionCode); - - ptr = &GspOutBuffer[0]; - - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ - *ptr++ = HexChars[(SigVal >> 4) & 0xf]; - *ptr++ = HexChars[SigVal & 0xf]; - - *ptr++ = HexChars[ESP]; - *ptr++ = ':'; - ptr = GspMem2Hex ((PCHAR) &TrapFrame->Esp, ptr, 4, 0); /* SP */ - *ptr++ = ';'; - - *ptr++ = HexChars[EBP]; - *ptr++ = ':'; - ptr = GspMem2Hex ((PCHAR) &TrapFrame->Ebp, ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = HexChars[PC]; - *ptr++ = ':'; - ptr = GspMem2Hex((PCHAR) &TrapFrame->Eip, ptr, 4, 0); /* PC */ - *ptr++ = ';'; - - *ptr = '\0'; - - GspPutPacket (&GspOutBuffer[0]); - - Stepping = FALSE; - - while (TRUE) + if (STATUS_ACCESS_VIOLATION == (NTSTATUS) ExceptionRecord->ExceptionCode && + NULL != GspAccessLocation && + (ULONG_PTR) GspAccessLocation == + (ULONG_PTR) ExceptionRecord->ExceptionInformation[1]) { - /* Zero the buffer now so we don't have to worry about the terminating zero character */ - memset (GspOutBuffer, 0, sizeof (GspInBuffer)); - ptr = GspGetPacket (); - - switch (*ptr++) - { - case '?': - GspOutBuffer[0] = 'S'; - GspOutBuffer[1] = HexChars[SigVal >> 4]; - GspOutBuffer[2] = HexChars[SigVal % 16]; - GspOutBuffer[3] = 0; - break; - case 'd': - GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU Registers */ - if (GspDbgThread) - GspGetRegistersFromTrapFrame (&GspOutBuffer[0], GspDbgThread->Tcb.TrapFrame); - else - GspGetRegistersFromTrapFrame (&GspOutBuffer[0], TrapFrame); - break; - case 'G': /* set the value of the CPU Registers - return OK */ - if (GspDbgThread) - GspSetRegistersInTrapFrame (ptr, GspDbgThread->Tcb.TrapFrame); - else - GspSetRegistersInTrapFrame (ptr, TrapFrame); - strcpy (GspOutBuffer, "OK"); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - LONG Register; - - if ((GspHex2Long (&ptr, &Register)) && (*ptr++ == '=')) - if ((Register >= 0) && (Register < NUMREGS)) - { - if (GspDbgThread) - GspSetSingleRegisterInTrapFrame (ptr, Register, - GspDbgThread->Tcb.TrapFrame); - else - GspSetSingleRegisterInTrapFrame (ptr, Register, TrapFrame); - strcpy (GspOutBuffer, "OK"); - break; - } - - strcpy (GspOutBuffer, "E01"); - break; - } - - /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - case 'm': - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - if (GspHex2Long (&ptr, &Address)) - if (*(ptr++) == ',') - if (GspHex2Long (&ptr, &Length)) - { - ptr = 0; - GspMemoryError = FALSE; - GspMem2Hex ((PCHAR) Address, GspOutBuffer, Length, 1); - if (GspMemoryError) - { - strcpy (GspOutBuffer, "E03"); - GspDebugError ("memory fault"); - } - } - - if (ptr) - { - strcpy (GspOutBuffer, "E01"); - } - break; - - /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M': - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - if (GspHex2Long (&ptr, &Address)) - if (*(ptr++) == ',') - if (GspHex2Long (&ptr, &Length)) - if (*(ptr++) == ':') - { - GspMemoryError = FALSE; - GspHex2Mem (ptr, (PCHAR) Address, Length, TRUE); - - if (GspMemoryError) - { - strcpy (GspOutBuffer, "E03"); - GspDebugError ("memory fault"); - } - else - { - strcpy (GspOutBuffer, "OK"); - } - - ptr = NULL; - } - if (ptr) - { - strcpy (GspOutBuffer, "E02"); - } - break; - - /* cAA..AA Continue at address AA..AA(optional) */ - /* sAA..AA Step one instruction from AA..AA(optional) */ - case 's': - Stepping = TRUE; - case 'c': - { - ULONG BreakpointNumber; - ULONG dr6; + GspAccessLocation = NULL; + GspMemoryError = TRUE; + TrapFrame->Eip += 2; + ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NONCONTINUABLE; + } + else + { + /* reply to host that an exception has occurred */ + SigVal = GspComputeSignal (ExceptionRecord->ExceptionCode); - /* try to read optional parameter, pc unchanged if no parm */ - if (GspHex2Long (&ptr, &Address)) - Context->Eip = Address; + ptr = &GspOutBuffer[0]; - NewPC = Context->Eip; + *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ + *ptr++ = HexChars[(SigVal >> 4) & 0xf]; + *ptr++ = HexChars[SigVal & 0xf]; - /* clear the trace bit */ - Context->EFlags &= 0xfffffeff; + *ptr++ = HexChars[ESP]; + *ptr++ = ':'; - /* set the trace bit if we're Stepping */ - if (Stepping) - Context->EFlags |= 0x100; + Esp = GspGetEspFromTrapFrame (TrapFrame); /* SP */ + ptr = GspMem2Hex ((PCHAR) &Esp, ptr, 4, 0); + *ptr++ = ';'; - asm volatile ("movl %%db6, %0\n" : "=r" (dr6) : ); - if (!(dr6 & 0x4000)) - { - for (BreakpointNumber = 0; BreakpointNumber < 4; ++BreakpointNumber) - { - if (dr6 & (1 << BreakpointNumber)) - { - if (GspBreakpoints[BreakpointNumber].Type == 0) - { - /* Set restore flag */ - Context->EFlags |= 0x10000; - break; - } - } - } - } - GspCorrectHwBreakpoint(); - asm volatile ("movl %0, %%db6\n" : : "r" (0)); + *ptr++ = HexChars[EBP]; + *ptr++ = ':'; + ptr = GspMem2Hex ((PCHAR) &TrapFrame->Ebp, ptr, 4, 0); /* FP */ + *ptr++ = ';'; - return kdHandleException; - break; - } - case 'k': /* kill the program */ - strcpy (GspOutBuffer, "OK"); - break; - /* kill the program */ - case 'H': /* Set thread */ - GspSetThread (ptr); - break; - case 'q': /* Query */ - GspQuery (ptr); - break; - case 'T': /* Query thread status */ - GspQueryThreadStatus (ptr); - break; - case 'Y': - { - ULONG Number; - ULONG Length; - ULONG Type; - ULONG Address; - - ptr = &GspOutBuffer[1]; - GspHex2Long (&ptr, &Number); - ptr++; - GspHex2Long (&ptr, &Type); - ptr++; - GspHex2Long (&ptr, &Length); - ptr++; - GspHex2Long (&ptr, &Address); - if (GspSetHwBreakpoint (Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0) - { - strcpy (GspOutBuffer, "OK"); - } - else - { - strcpy (GspOutBuffer, "E"); - } - break; - /* Remove hardware breakpoint */ - } - case 'y': - { - ULONG Number; + *ptr++ = HexChars[PC]; + *ptr++ = ':'; + ptr = GspMem2Hex((PCHAR) &TrapFrame->Eip, ptr, 4, 0); /* PC */ + *ptr++ = ';'; - ptr = &GspOutBuffer[1]; - GspHex2Long(&ptr, &Number); - if (GspRemoveHwBreakpoint (Number & 0x3) == 0) - { - strcpy (GspOutBuffer, "OK"); - } - else - { - strcpy (GspOutBuffer, "E"); - } - break; - } - default: - break; - } /* switch */ + *ptr = '\0'; - /* reply to the request */ GspPutPacket (&GspOutBuffer[0]); + + Stepping = FALSE; + + while (TRUE) + { + /* Zero the buffer now so we don't have to worry about the terminating zero character */ + memset (GspOutBuffer, 0, sizeof (GspInBuffer)); + ptr = GspGetPacket (); + + switch (*ptr++) + { + case '?': + GspOutBuffer[0] = 'S'; + GspOutBuffer[1] = HexChars[SigVal >> 4]; + GspOutBuffer[2] = HexChars[SigVal % 16]; + GspOutBuffer[3] = 0; + break; + case 'd': + GspRemoteDebug = !GspRemoteDebug; /* toggle debug flag */ + break; + case 'g': /* return the value of the CPU Registers */ + if (GspDbgThread) + GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, GspDbgThread->Tcb.TrapFrame); + else + GspGetRegistersFromTrapFrame (&GspOutBuffer[0], Context, TrapFrame); + break; + case 'G': /* set the value of the CPU Registers - return OK */ + if (GspDbgThread) +/* GspSetRegistersInTrapFrame (ptr, Context, GspDbgThread->Tcb.TrapFrame);*/ +GspSetRegistersInTrapFrame (ptr, Context, TrapFrame); + else + GspSetRegistersInTrapFrame (ptr, Context, TrapFrame); + strcpy (GspOutBuffer, "OK"); + break; + case 'P': /* set the value of a single CPU register - return OK */ + { + LONG Register; + + if ((GspHex2Long (&ptr, &Register)) && (*ptr++ == '=')) + if ((Register >= 0) && (Register < NUMREGS)) + { + if (GspDbgThread) +/* GspSetSingleRegisterInTrapFrame (ptr, Register, + Context, GspDbgThread->Tcb.TrapFrame);*/ +GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame); + else + GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame); + strcpy (GspOutBuffer, "OK"); + break; + } + + strcpy (GspOutBuffer, "E01"); + break; + } + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm': + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + if (GspHex2Long (&ptr, &Address)) + if (*(ptr++) == ',') + if (GspHex2Long (&ptr, &Length)) + { + ptr = 0; + GspMemoryError = FALSE; + GspMem2Hex ((PCHAR) Address, GspOutBuffer, Length, 1); + if (GspMemoryError) + { + strcpy (GspOutBuffer, "E03"); + DPRINT ("Fault during memory read\n"); + } + } + + if (ptr) + strcpy (GspOutBuffer, "E01"); + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M': + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + if (GspHex2Long (&ptr, &Address)) + if (*(ptr++) == ',') + if (GspHex2Long (&ptr, &Length)) + if (*(ptr++) == ':') + { + GspMemoryError = FALSE; + GspHex2Mem (ptr, (PCHAR) Address, Length, TRUE); + + if (GspMemoryError) + { + strcpy (GspOutBuffer, "E03"); + DPRINT ("Fault during memory write\n"); + } + else + { + strcpy (GspOutBuffer, "OK"); + } + + ptr = NULL; + } + if (ptr) + strcpy (GspOutBuffer, "E02"); + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 's': + Stepping = TRUE; + case 'c': + { + ULONG BreakpointNumber; + ULONG dr6; + + /* try to read optional parameter, pc unchanged if no parm */ + if (GspHex2Long (&ptr, &Address)) + Context->Eip = Address; + + NewPC = Context->Eip; + + /* clear the trace bit */ + Context->EFlags &= 0xfffffeff; + + /* set the trace bit if we're Stepping */ + if (Stepping) + Context->EFlags |= 0x100; + + asm volatile ("movl %%db6, %0\n" : "=r" (dr6) : ); + if (!(dr6 & 0x4000)) + { + for (BreakpointNumber = 0; BreakpointNumber < 4; ++BreakpointNumber) + { + if (dr6 & (1 << BreakpointNumber)) + { + if (GspBreakpoints[BreakpointNumber].Type == 0) + { + /* Set restore flag */ + Context->EFlags |= 0x10000; + break; + } + } + } + } + GspCorrectHwBreakpoint(); + asm volatile ("movl %0, %%db6\n" : : "r" (0)); + + return kdHandleException; + break; + } + + case 'k': /* kill the program */ + strcpy (GspOutBuffer, "OK"); + break; + /* kill the program */ + + case 'H': /* Set thread */ + GspSetThread (ptr); + break; + + case 'q': /* Query */ + GspQuery (ptr); + break; + + case 'T': /* Query thread status */ + GspQueryThreadStatus (ptr); + break; + + case 'Y': + { + LONG Number; + LONG Length; + LONG Type; + LONG Address; + + ptr = &GspOutBuffer[1]; + GspHex2Long (&ptr, &Number); + ptr++; + GspHex2Long (&ptr, &Type); + ptr++; + GspHex2Long (&ptr, &Length); + ptr++; + GspHex2Long (&ptr, &Address); + if (GspSetHwBreakpoint (Number & 0x3, Type & 0x3 , Length & 0x3, Address) == 0) + { + strcpy (GspOutBuffer, "OK"); + } + else + { + strcpy (GspOutBuffer, "E"); + } + break; + } + + /* Remove hardware breakpoint */ + case 'y': + { + LONG Number; + + ptr = &GspOutBuffer[1]; + GspHex2Long(&ptr, &Number); + if (GspRemoveHwBreakpoint (Number & 0x3) == 0) + { + strcpy (GspOutBuffer, "OK"); + } + else + { + strcpy (GspOutBuffer, "E"); + } + break; + } + + default: + break; + } /* switch */ + + /* reply to the request */ + GspPutPacket (&GspOutBuffer[0]); + } } return kdDoNotHandleException; @@ -1253,7 +1317,11 @@ KdGdbStubInit(ULONG Phase) GspInitialized = TRUE; GspRunThread = PsGetCurrentThread(); - GspDbgThread = PsGetCurrentThread(); + + ObReferenceObject(GspRunThread); + +/* GspDbgThread = PsGetCurrentThread(); */ + GspDbgThread = NULL; GspEnumThread = NULL; DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C); diff --git a/ntoskrnl/ke/bug.c b/ntoskrnl/ke/bug.c index 4b3f76c..8bec9da 100644 --- a/ntoskrnl/ke/bug.c +++ b/ntoskrnl/ke/bug.c @@ -56,6 +56,7 @@ BOOLEAN STDCALL KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord) { UNIMPLEMENTED; + return FALSE; } BOOLEAN STDCALL @@ -81,14 +82,59 @@ KeBugCheckWithTf(ULONG BugCheckCode, ULONG BugCheckParameter4, PKTRAP_FRAME Tf) { - KIRQL oldIrql; - KeRaiseIrql(HIGH_LEVEL, &oldIrql); - DbgPrint("Bug detected code: 0x%X\n", BugCheckCode); + PRTL_MESSAGE_RESOURCE_ENTRY Message; + NTSTATUS Status; + + __asm__("cli\n\t"); + DbgPrint("Bug detected (code %x param %x %x %x %x)\n", + BugCheckCode, + BugCheckParameter1, + BugCheckParameter2, + BugCheckParameter3, + BugCheckParameter4); + + Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000, + 11, //RT_MESSAGETABLE, + 0x09, //0x409, + BugCheckCode, + &Message); + if (NT_SUCCESS(Status)) + { + if (Message->Flags == 0) + DbgPrint(" %s\n", Message->Text); + else + DbgPrint(" %S\n", (PWSTR)Message->Text); + } + else + { + DbgPrint(" No message text found!\n\n"); + } + + if (InBugCheck == 1) + { + DbgPrint("Recursive bug check halting now\n"); + for (;;) + { + __asm__ ("hlt\n\t"); + } + } + InBugCheck = 1; KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2); MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4, Tf); - for(;;); + + if (KdDebuggerEnabled) + { + __asm__("sti\n\t"); + DbgBreakPoint(); + __asm__("cli\n\t"); + } + + for (;;) + { + __asm__("hlt\n\t"); + } } VOID STDCALL @@ -158,14 +204,18 @@ KeBugCheckEx(ULONG BugCheckCode, MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4, NULL); - + if (KdDebuggerEnabled) { __asm__("sti\n\t"); DbgBreakPoint(); + __asm__("cli\n\t"); } - for(;;); + for (;;) + { + __asm__("hlt\n\t"); + } } VOID STDCALL diff --git a/ntoskrnl/ke/catch.c b/ntoskrnl/ke/catch.c index 6bdda14..59a44d3 100644 --- a/ntoskrnl/ke/catch.c +++ b/ntoskrnl/ke/catch.c @@ -53,6 +53,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, { EXCEPTION_DISPOSITION Value; CONTEXT TContext; + KD_CONTINUE_TYPE Action = kdContinue; DPRINT("KiDispatchException() called\n"); @@ -77,69 +78,65 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, Context->Eip--; } #endif - if (PreviousMode == UserMode) + + if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) + { + Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); + } +#ifdef KDBG + else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB) { - if (SearchFrames) + Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf); + } +#endif /* KDBG */ + if (Action != kdHandleException) + { + if (PreviousMode == UserMode) { - PULONG Stack; - ULONG CDest; - - /* FIXME: Give the kernel debugger a chance */ - - /* FIXME: Forward exception to user mode debugger */ + if (SearchFrames) + { + PULONG Stack; + ULONG CDest; - /* FIXME: Check user mode stack for enough space */ + /* FIXME: Forward exception to user mode debugger */ + /* FIXME: Check user mode stack for enough space */ - /* - * Let usermode try and handle the exception - */ - Tf->Esp = Tf->Esp - - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)); - Stack = (PULONG)Tf->Esp; - CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4); - /* Return address */ - Stack[0] = 0; - /* Pointer to EXCEPTION_RECORD structure */ - Stack[1] = (ULONG)&Stack[3]; - /* Pointer to CONTEXT structure */ - Stack[2] = (ULONG)&Stack[CDest]; - memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD)); - memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); - - Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher(); - return; - } + /* + * Let usermode try and handle the exception + */ + Tf->Esp = Tf->Esp - + (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)); + Stack = (PULONG)Tf->Esp; + CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4); + /* Return address */ + Stack[0] = 0; + /* Pointer to EXCEPTION_RECORD structure */ + Stack[1] = (ULONG)&Stack[3]; + /* Pointer to CONTEXT structure */ + Stack[2] = (ULONG)&Stack[CDest]; + memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD)); + memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); + + Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher(); + return; + } - /* FIXME: Forward the exception to the debugger */ + /* FIXME: Forward the exception to the debugger */ - /* FIXME: Forward the exception to the process exception port */ + /* FIXME: Forward the exception to the process exception port */ - /* Terminate the offending thread */ - ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); + /* Terminate the offending thread */ + DPRINT1("Unhandled UserMode exception, terminating thread\n"); + ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); - /* If that fails then bugcheck */ - DbgPrint("Could not terminate thread\n"); - KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); - } - else - { - KD_CONTINUE_TYPE Action = kdContinue; - - /* PreviousMode == KernelMode */ - - if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) - { - Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); - } -#ifdef KDBG - else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB) - { - Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf); + /* If that fails then bugcheck */ + DPRINT1("Could not terminate thread\n"); + KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); } -#endif /* KDBG */ - if (Action != kdHandleException) + else { + /* PreviousMode == KernelMode */ Value = RtlpDispatchException (ExceptionRecord, Context); DPRINT("RtlpDispatchException() returned with 0x%X\n", Value); @@ -147,15 +144,16 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, * If RtlpDispatchException() does not handle the exception then * bugcheck */ - if (Value != ExceptionContinueExecution) + if (Value != ExceptionContinueExecution || + 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)) { - KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED); + KeBugCheckWithTf(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf); } } - else - { - KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame); - } + } + else + { + KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame); } } diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c index 40ba941..ccf8d7d 100644 --- a/ntoskrnl/ke/i386/exp.c +++ b/ntoskrnl/ke/i386/exp.c @@ -163,6 +163,7 @@ KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) if (ExceptionNr == 14) { + Er.ExceptionCode = STATUS_ACCESS_VIOLATION; Er.NumberParameters = 2; Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1; Er.ExceptionInformation[1] = (ULONG)Cr2; @@ -180,6 +181,9 @@ KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) Er.NumberParameters = 0; } + Er.ExceptionFlags = (STATUS_SINGLE_STEP == (NTSTATUS) Er.ExceptionCode || STATUS_BREAKPOINT == (NTSTATUS) Er.ExceptionCode ? + 0 : EXCEPTION_NONCONTINUABLE); + KiDispatchException(&Er, 0, Tf, KernelMode, TRUE); return(0); @@ -537,7 +541,6 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) { return(0); } - } /* @@ -586,12 +589,13 @@ static void set_interrupt_gate(unsigned int sel, unsigned int func) KiIdt[sel].b = 0x8e00 + (((int)func)&0xffff0000); } -static void set_trap_gate(unsigned int sel, unsigned int func) +static void set_trap_gate(unsigned int sel, unsigned int func, unsigned int dpl) { - DPRINT("set_trap_gate(sel %d, func %x)\n",sel,func); + DPRINT("set_trap_gate(sel %d, func %x, dpl %d)\n",sel, func, dpl); + assert(dpl <= 3); KiIdt[sel].a = (((int)func)&0xffff) + (KERNEL_CS << 16); - KiIdt[sel].b = 0x8f00 + (((int)func)&0xffff0000); + KiIdt[sel].b = 0x8f00 + (dpl << 13) + (((int)func)&0xffff0000); } static void @@ -614,28 +618,27 @@ KeInitExceptions(VOID) /* * Set up the other gates */ - set_trap_gate(0, (ULONG)KiTrap0); - set_trap_gate(1, (ULONG)KiTrap1); - set_trap_gate(2, (ULONG)KiTrap2); - set_trap_gate(3, (ULONG)KiTrap3); - set_trap_gate(4, (ULONG)KiTrap4); - set_trap_gate(5, (ULONG)KiTrap5); - set_trap_gate(6, (ULONG)KiTrap6); - set_trap_gate(7, (ULONG)KiTrap7); + set_trap_gate(0, (ULONG)KiTrap0, 0); + set_trap_gate(1, (ULONG)KiTrap1, 0); + set_trap_gate(2, (ULONG)KiTrap2, 0); + set_trap_gate(3, (ULONG)KiTrap3, 3); + set_trap_gate(4, (ULONG)KiTrap4, 0); + set_trap_gate(5, (ULONG)KiTrap5, 0); + set_trap_gate(6, (ULONG)KiTrap6, 0); + set_trap_gate(7, (ULONG)KiTrap7, 0); set_task_gate(8, TRAP_TSS_SELECTOR); - set_trap_gate(9, (ULONG)KiTrap9); - set_trap_gate(10, (ULONG)KiTrap10); - set_trap_gate(11, (ULONG)KiTrap11); - set_trap_gate(12, (ULONG)KiTrap12); - set_trap_gate(13, (ULONG)KiTrap13); - set_trap_gate(14, (ULONG)KiTrap14); + set_trap_gate(9, (ULONG)KiTrap9, 0); + set_trap_gate(10, (ULONG)KiTrap10, 0); + set_trap_gate(11, (ULONG)KiTrap11, 0); + set_trap_gate(12, (ULONG)KiTrap12, 0); + set_trap_gate(13, (ULONG)KiTrap13, 0); set_interrupt_gate(14, (ULONG)KiTrap14); - set_trap_gate(15, (ULONG)KiTrap15); - set_trap_gate(16, (ULONG)KiTrap16); + set_trap_gate(15, (ULONG)KiTrap15, 0); + set_trap_gate(16, (ULONG)KiTrap16, 0); for (i=17;i<256;i++) { - set_trap_gate(i,(int)KiTrapUnknown); + set_trap_gate(i,(int)KiTrapUnknown, 0); } set_system_call_gate(0x2d,(int)interrupt_handler2d); diff --git a/ntoskrnl/ke/i386/irq.c b/ntoskrnl/ke/i386/irq.c index fd4dbe6..c098e71 100644 --- a/ntoskrnl/ke/i386/irq.c +++ b/ntoskrnl/ke/i386/irq.c @@ -60,11 +60,13 @@ * FIXME: This does not work if we have more than 24 IRQs (ie. more than one * I/O APIC) */ -#define VECTOR2IRQ(vector) (((vector) - 0x31) / 8) -#define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector)) +#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8) +#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR) +#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector)) -#define IRQ_BASE FIRST_DEVICE_VECTOR -#define NR_IRQS 0x100 - 0x30 + +#define IRQ_BASE 0x30 +#define NR_IRQS 0x100 - IRQ_BASE #define __STR(x) #x #define STR(x) __STR(x) @@ -225,8 +227,8 @@ VOID KeInitInterrupts (VOID) */ for (i=0;iServiceRoutine(isr, isr->ServiceContext)) { current = current->Flink; @@ -335,12 +338,10 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) * ARGUMENTS: * Vector = Interrupt vector * Trapframe = CPU context + * NOTES: Interrupts are disabled at this point. */ { KIRQL old_level; - PKINTERRUPT isr; - PLIST_ENTRY current; - ULONG irq; #ifdef DBG @@ -351,16 +352,22 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) #endif /* DBG */ - DPRINT("I(%d) ", Vector); + DbgPrint("V(0x%.02x)", Vector); /* * Notify the rest of the kernel of the raised irq level */ - HalBeginSystemInterrupt (Vector, + if (!HalBeginSystemInterrupt (Vector, VECTOR2IRQL(Vector), - &old_level); + &old_level)) + { + return; + } - irq = VECTOR2IRQ(Vector); + /* + * Mask the related irq + */ + //HalDisableSystemInterrupt (Vector, 0); /* * Enable interrupts @@ -368,33 +375,11 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) */ __asm__("sti\n\t"); - if (irq == 0) - { - if (KeGetCurrentProcessorNumber() == 0) - { - KiUpdateSystemTime(old_level, Trapframe->Eip); -#ifdef KDBG - KdbProfileInterrupt(Trapframe->Eip); -#endif /* KDBG */ - } - } - else - { - DPRINT("KiInterruptDispatch(Vector %d)\n", Vector); - /* - * Iterate the list until one of the isr tells us its device interrupted - */ - current = isr_table[irq].Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - //DPRINT("current %x isr %x\n",current,isr); - while (current!=(&isr_table[irq]) && - !isr->ServiceRoutine(isr,isr->ServiceContext)) - { - current = current->Flink; - isr = CONTAINING_RECORD(current,KINTERRUPT,Entry); - //DPRINT("current %x isr %x\n",current,isr); - } - } + /* + * Actually call the ISR. + */ + KiInterruptDispatch2(Vector, old_level); + /* * Disable interrupts */ @@ -403,35 +388,13 @@ KiInterruptDispatch (ULONG Vector, PKIRQ_TRAPFRAME Trapframe) /* * Unmask the related irq */ - HalEnableSystemInterrupt (Vector, 0, 0); + //HalEnableSystemInterrupt (Vector, 0, 0); + + //DbgPrint("E(0x%.02x)\n", Vector); /* - * If the processor level will drop below dispatch level on return then - * issue a DPC queue drain interrupt + * End the system interrupt. */ - - __asm__("sti\n\t"); - - if (old_level < DISPATCH_LEVEL) - { - - HalEndSystemInterrupt (DISPATCH_LEVEL, 0); - - if (KeGetCurrentThread() != NULL) - { - // FIXME TODO - What happend to LastEip definition? - //KeGetCurrentThread()->LastEip = Trapframe->Eip; - } - KiDispatchInterrupt(); - if (KeGetCurrentThread() != NULL && - KeGetCurrentThread()->Alerted[1] != 0 && - Trapframe->Cs != KERNEL_CS) - { - HalEndSystemInterrupt (APC_LEVEL, 0); - KiDeliverNormalApc(); - } - } - HalEndSystemInterrupt (old_level, 0); } @@ -602,7 +565,11 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject) DPRINT("%x %x\n",isr_table[Vector].Flink,isr_table[Vector].Blink); if (IsListEmpty(&isr_table[Vector])) { - HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0); +#ifdef MP + HalEnableSystemInterrupt(Vector, 0, 0); +#else + HalEnableSystemInterrupt(Vector + IRQ_BASE, 0, 0); +#endif } InsertTailList(&isr_table[Vector],&InterruptObject->Entry); DPRINT("%x %x\n",InterruptObject->Entry.Flink, @@ -636,7 +603,11 @@ KeDisconnectInterrupt(PKINTERRUPT InterruptObject) RemoveEntryList(&InterruptObject->Entry); if (IsListEmpty(&isr_table[InterruptObject->Vector])) { +#ifdef MP + HalDisableSystemInterrupt(InterruptObject->Vector, 0); +#else HalDisableSystemInterrupt(InterruptObject->Vector + IRQ_BASE, 0); +#endif } KeReleaseSpinLockFromDpcLevel(InterruptObject->IrqLock); KeLowerIrql(oldlvl); diff --git a/ntoskrnl/ke/i386/kernel.c b/ntoskrnl/ke/i386/kernel.c index 2d049ee..2ca1f3f 100644 --- a/ntoskrnl/ke/i386/kernel.c +++ b/ntoskrnl/ke/i386/kernel.c @@ -60,7 +60,7 @@ KeApplicationProcessorInit(VOID) /* * Create a PCR for this processor */ - Offset = InterlockedIncrement(&PcrsAllocated) - 1; + Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1; KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE)); MmCreateVirtualMappingForKernel((PVOID)KPCR, PAGE_READWRITE, diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s index 7a1acd2..a9d3553 100644 --- a/ntoskrnl/ke/i386/trap.s +++ b/ntoskrnl/ke/i386/trap.s @@ -104,6 +104,7 @@ _KiTrapProlog: /* Set the new previous mode based on the saved CS selector */ movl 0x24(%esp), %ebx + andl $0x0000FFFF, %ebx cmpl $KERNEL_CS, %ebx jne .L1 movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi) @@ -170,7 +171,7 @@ _KiTrapProlog: addl $4, %esp /* Get a pointer to the current thread */ - movl %fs:0x124, %esi + movl %fs:KPCR_CURRENT_THREAD, %esi /* Restore the old trap frame pointer */ popl %ebx @@ -318,6 +319,7 @@ _KiTrap14: .globl _KiTrap15 _KiTrap15: + pushl $0 pushl %ebp pushl %ebx pushl %esi @@ -326,6 +328,7 @@ _KiTrap15: .globl _KiTrap16 _KiTrap16: + pushl $0 pushl %ebp pushl %ebx pushl %esi diff --git a/ntoskrnl/ke/i386/usertrap.c b/ntoskrnl/ke/i386/usertrap.c index 19a300b..d8e7214 100644 --- a/ntoskrnl/ke/i386/usertrap.c +++ b/ntoskrnl/ke/i386/usertrap.c @@ -144,6 +144,9 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) } + Er.ExceptionFlags = (STATUS_SINGLE_STEP == (NTSTATUS) Er.ExceptionCode || STATUS_BREAKPOINT == (NTSTATUS) Er.ExceptionCode ? + 0 : EXCEPTION_NONCONTINUABLE); + KiDispatchException(&Er, 0, Tf, UserMode, TRUE); return(0); } diff --git a/ntoskrnl/ke/kthread.c b/ntoskrnl/ke/kthread.c index d0b1ddc..41dd61e 100644 --- a/ntoskrnl/ke/kthread.c +++ b/ntoskrnl/ke/kthread.c @@ -236,3 +236,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) */ } +VOID STDCALL +KeRescheduleThread() +{ + PsDispatchThread(THREAD_STATE_READY); +} diff --git a/ntoskrnl/ke/main.c b/ntoskrnl/ke/main.c index 5de88d2..0b2c079 100644 --- a/ntoskrnl/ke/main.c +++ b/ntoskrnl/ke/main.c @@ -85,43 +85,24 @@ static BOOLEAN RtlpCheckFileNameExtension(PCHAR FileName, PCHAR Extension) { - PCHAR Ext; - - Ext = strrchr(FileName, '.'); - if ((Extension == NULL) || (*Extension == 0)) - { - if (Ext == NULL) - return TRUE; - else - return FALSE; - } - if (*Extension != '.') - Ext++; - - if (_stricmp(Ext, Extension) == 0) - return TRUE; - else - return FALSE; -} + PCHAR Ext; + Ext = strrchr(FileName, '.'); + if (Ext == NULL) + { + if ((Extension == NULL) || (*Extension == 0)) + return TRUE; + else + return FALSE; + } -static BOOLEAN -RtlpIsSystemHive(PCHAR FileName) -{ - PCHAR Name; + if (*Extension != '.') + Ext++; - Name = strrchr(FileName, '\\'); - if (Name == NULL) - { - Name = FileName; - } + if (_stricmp(Ext, Extension) == 0) + return TRUE; else - { - Name = Name + 1; - } - - return((_stricmp(Name, "system.hiv") == 0) || - (_stricmp(Name, "system") == 0)); + return FALSE; } @@ -420,14 +401,14 @@ ExpInitializeExecutive(VOID) if (KeNumberProcessors > 1) { sprintf(str, - "Found %d system processors. [%u MB Memory]\n", + "Found %d system processors. [%lu MB Memory]\n", KeNumberProcessors, (KeLoaderBlock.MemHigher + 1088)/ 1024); } else { sprintf(str, - "Found 1 system processor. [%u MB Memory]\n", + "Found 1 system processor. [%lu MB Memory]\n", (KeLoaderBlock.MemHigher + 1088)/ 1024); } HalDisplayString(str); @@ -499,25 +480,51 @@ ExpInitializeExecutive(VOID) } } - /* Pass 2: load registry chunks passed in */ + /* Pass 2: import system hive registry chunk */ SetupBoot = TRUE; for (i = 1; i < KeLoaderBlock.ModsCount; i++) { start = KeLoaderModules[i].ModStart; length = KeLoaderModules[i].ModEnd - start; - name = (PCHAR)KeLoaderModules[i].String; - if (RtlpCheckFileNameExtension(name, "") || - RtlpCheckFileNameExtension(name, ".hiv")) + + DPRINT("Module: '%s'\n", (PCHAR)KeLoaderModules[i].String); + name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'); + if (name == NULL) + { + name = (PCHAR)KeLoaderModules[i].String; + } + else { - CPRINT("Process registry chunk at %08lx\n", start); - CmImportHive((PCHAR)start, length); + name++; } - if (RtlpIsSystemHive(name)) + + if (!_stricmp (name, "system") || + !_stricmp (name, "system.hiv")) { + CPRINT("Process system hive registry chunk at %08lx\n", start); SetupBoot = FALSE; + CmImportSystemHive((PCHAR)start, length); } } + /* Pass 3: import hardware hive registry chunk */ + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + start = KeLoaderModules[i].ModStart; + length = KeLoaderModules[i].ModEnd - start; + name = (PCHAR)KeLoaderModules[i].String; + if (!_stricmp (name, "hardware") || + !_stricmp (name, "hardware.hiv")) + { + CPRINT("Process hardware hive registry chunk at %08lx\n", start); + CmImportHardwareHive((PCHAR)start, length); + } + } + + /* Create dummy keys if no hardware hive was found */ + CmImportHardwareHive (NULL, 0); + + /* Initialize volatile registry settings */ if (SetupBoot == FALSE) { @@ -533,7 +540,7 @@ ExpInitializeExecutive(VOID) IoCreateDriverList(); - /* Pass 3: process boot loaded drivers */ + /* Pass 4: process boot loaded drivers */ BootDriverCount = 0; for (i=1; i < KeLoaderBlock.ModsCount; i++) { @@ -620,7 +627,6 @@ ExpInitializeExecutive(VOID) { KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); } - /* * Crash the system if the initial process terminates within 5 seconds. */ @@ -728,7 +734,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) } } sprintf(KeLoaderCommandLine, - "multi(0)disk(0)rdisk(%d)partition(%d)%s %s", + "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s", DiskNumber, PartNumber + 1, Temp, options); p = KeLoaderCommandLine; diff --git a/ntoskrnl/ke/queue.c b/ntoskrnl/ke/queue.c index bb6279e..dbc5aa5 100644 --- a/ntoskrnl/ke/queue.c +++ b/ntoskrnl/ke/queue.c @@ -31,6 +31,7 @@ #include #include #include +#include #define NDEBUG #include @@ -46,9 +47,9 @@ KeInitializeQueue(IN PKQUEUE Queue, sizeof(KQUEUE)/sizeof(ULONG), 0); InitializeListHead(&Queue->EntryListHead); - InitializeListHead(&Queue->ThreadListEntry); - Queue->CurrentCount = 0; - Queue->MaximumCount = (Count == 0) ? (ULONG) KeNumberProcessors : Count; + InitializeListHead(&Queue->ThreadListHead); + Queue->RunningThreads = 0; + Queue->MaximumThreads = (Count == 0) ? (ULONG) KeNumberProcessors : Count; } @@ -60,11 +61,46 @@ KeReadStateQueue(IN PKQUEUE Queue) LONG STDCALL +KiInsertQueue( + IN PKQUEUE Queue, + IN PLIST_ENTRY Entry, + BOOLEAN Head + ) +{ + ULONG InitialState; + + DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry); + + KeAcquireDispatcherDatabaseLock(FALSE); + + InitialState = Queue->Header.SignalState; + Queue->Header.SignalState++; + + if (Head) + { + InsertHeadList(&Queue->EntryListHead, Entry); + } + else + { + InsertTailList(&Queue->EntryListHead, Entry); + } + + if (Queue->RunningThreads < Queue->MaximumThreads && InitialState == 0) + { + KeDispatcherObjectWake(&Queue->Header); + } + + KeReleaseDispatcherDatabaseLock(FALSE); + return InitialState; +} + + + +LONG STDCALL KeInsertHeadQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry) { - UNIMPLEMENTED; - return 0; + return KiInsertQueue(Queue,Entry,TRUE); } @@ -72,8 +108,7 @@ LONG STDCALL KeInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry) { - UNIMPLEMENTED; - return 0; + return KiInsertQueue(Queue,Entry,FALSE); } @@ -82,16 +117,88 @@ KeRemoveQueue(IN PKQUEUE Queue, IN KPROCESSOR_MODE WaitMode, IN PLARGE_INTEGER Timeout OPTIONAL) { - UNIMPLEMENTED; - return NULL; + PLIST_ENTRY ListEntry; + NTSTATUS Status; + PKTHREAD Thread = KeGetCurrentThread(); + + KeAcquireDispatcherDatabaseLock(FALSE); + + //assiciate new thread with queue? + if (Thread->Queue != Queue) + { + //remove association from other queue + if (!IsListEmpty(&Thread->QueueListEntry)) + { + RemoveEntryList(&Thread->QueueListEntry); + } + + //associate with this queue + InsertHeadList(&Queue->ThreadListHead, &Thread->QueueListEntry); + Queue->RunningThreads++; + Thread->Queue = Queue; + } + + if (Queue->RunningThreads <= Queue->MaximumThreads && !IsListEmpty(&Queue->EntryListHead)) + { + ListEntry = RemoveHeadList(&Queue->EntryListHead); + Queue->Header.SignalState--; + KeReleaseDispatcherDatabaseLock(FALSE); + return ListEntry; + } + + //need to wait for it... + KeReleaseDispatcherDatabaseLock(FALSE); + + Status = KeWaitForSingleObject(Queue, + WrQueue, + WaitMode, + TRUE,//Alertable, + Timeout); + + if (Status == STATUS_TIMEOUT || Status == STATUS_USER_APC) + { + return (PVOID)Status; + } + else + { + KeAcquireDispatcherDatabaseLock(FALSE); + ListEntry = RemoveHeadList(&Queue->EntryListHead); + KeReleaseDispatcherDatabaseLock(FALSE); + return ListEntry; + } + } PLIST_ENTRY STDCALL KeRundownQueue(IN PKQUEUE Queue) { - UNIMPLEMENTED; - return NULL; + PLIST_ENTRY EnumEntry; + PKTHREAD Thread; + + DPRINT("KeRundownQueue(Queue %x)\n", Queue); + + //FIXME: should we wake thread waiting on a queue? + + KeAcquireDispatcherDatabaseLock(FALSE); + + // Clear Queue and QueueListEntry members of all threads associated with this queue + while (!IsListEmpty(&Queue->ThreadListHead)) + { + EnumEntry = RemoveHeadList(&Queue->ThreadListHead); + InitializeListHead(EnumEntry); + Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry); + Thread->Queue = NULL; + } + + if (!IsListEmpty(&Queue->EntryListHead)) + EnumEntry = Queue->EntryListHead.Flink; + else + EnumEntry = NULL; + + KeReleaseDispatcherDatabaseLock(FALSE); + + return EnumEntry; } /* EOF */ diff --git a/ntoskrnl/ke/spinlock.c b/ntoskrnl/ke/spinlock.c index 2e10122..bbd69d5 100644 --- a/ntoskrnl/ke/spinlock.c +++ b/ntoskrnl/ke/spinlock.c @@ -84,7 +84,7 @@ KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock) KeBugCheck(0); } - while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1) + while ((i = InterlockedExchange((LONG *)&SpinLock->Lock, 1)) == 1) { #ifndef MP DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i); @@ -109,7 +109,7 @@ KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock) DbgPrint("Releasing unacquired spinlock %x\n", SpinLock); KeBugCheck(0); } - (void)InterlockedExchange(&SpinLock->Lock, 0); + (void)InterlockedExchange((LONG *)&SpinLock->Lock, 0); } /* EOF */ diff --git a/ntoskrnl/ke/wait.c b/ntoskrnl/ke/wait.c index df08f49..fb6b191 100644 --- a/ntoskrnl/ke/wait.c +++ b/ntoskrnl/ke/wait.c @@ -11,7 +11,7 @@ */ /* NOTES ******************************************************************** - * + * */ /* INCLUDES ******************************************************************/ @@ -31,7 +31,10 @@ static KSPIN_LOCK DispatcherDatabaseLock; static BOOLEAN WaitSet = FALSE; static KIRQL oldlvl = PASSIVE_LEVEL; -static PKTHREAD Owner = NULL; +static PKTHREAD Owner = NULL; + +#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE) +#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE) /* FUNCTIONS *****************************************************************/ @@ -85,123 +88,113 @@ VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait) } } -static VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr, - PKTHREAD Thread, - PBOOLEAN Abandoned) +static BOOLEAN +KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr, + PKTHREAD Thread) /* * FUNCTION: Perform side effects on object before a wait for a thread is * satisfied */ { - if (Abandoned != NULL) - *Abandoned = FALSE; + BOOLEAN Abandoned = FALSE; switch (hdr->Type) - { + { case InternalSynchronizationEvent: - hdr->SignalState = 0; - break; - + hdr->SignalState = 0; + break; + + case InternalQueueType: case InternalSemaphoreType: - hdr->SignalState--; - break; - + hdr->SignalState--; + break; + case InternalProcessType: - break; - + break; + case InternalThreadType: - break; - + break; + case InternalNotificationEvent: - break; - + break; + case InternalSynchronizationTimer: - hdr->SignalState = FALSE; - break; - + hdr->SignalState = FALSE; + break; + case InternalNotificationTimer: - break; - + break; + case InternalMutexType: - { - PKMUTEX Mutex; - - Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header); - hdr->SignalState--; - assert(hdr->SignalState <= 1); - if (hdr->SignalState == 0) - { - if (Thread == NULL) - { - DPRINT1("Thread == NULL!\n"); - KeBugCheck(0); - } - if (Abandoned != NULL) - *Abandoned = Mutex->Abandoned; - if (Thread != NULL) - InsertTailList(&Thread->MutantListHead, - &Mutex->MutantListEntry); - Mutex->OwnerThread = Thread; - Mutex->Abandoned = FALSE; - } - } - break; - + { + PKMUTEX Mutex; + + Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header); + hdr->SignalState--; + assert(hdr->SignalState <= 1); + if (hdr->SignalState == 0) + { + if (Thread == NULL) + { + DPRINT("Thread == NULL!\n"); + KeBugCheck(0); + } + Abandoned = Mutex->Abandoned; + if (Thread != NULL) + InsertTailList(&Thread->MutantListHead, &Mutex->MutantListEntry); + Mutex->OwnerThread = Thread; + Mutex->Abandoned = FALSE; + } + } + break; + default: - DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", - __FILE__,__LINE__,hdr); - KeBugCheck(0); - } + DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", __FILE__, __LINE__, hdr); + KeBugCheck(0); + } + + return Abandoned; } static BOOLEAN -KiIsObjectSignalled(DISPATCHER_HEADER* hdr, - PKTHREAD Thread, - PBOOLEAN Abandoned) +KiIsObjectSignalled(DISPATCHER_HEADER * hdr, + PKTHREAD Thread) { - if (Abandoned != NULL) - *Abandoned = FALSE; - if (hdr->Type == InternalMutexType) - { - PKMUTEX Mutex; - - Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header); - - assert(hdr->SignalState <= 1); - if ((hdr->SignalState < 1 && Mutex->OwnerThread == Thread) || - hdr->SignalState == 1) - { - KiSideEffectsBeforeWake(hdr, - Thread, - Abandoned); - return(TRUE); - } - else - { - return(FALSE); - } - } + { + PKMUTEX Mutex; + + Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header); + + assert(hdr->SignalState <= 1); + + if ((hdr->SignalState < 1 && Mutex->OwnerThread == Thread) || hdr->SignalState == 1) + { + return (TRUE); + } + else + { + return (FALSE); + } + } + if (hdr->SignalState <= 0) - { - return(FALSE); - } + { + return (FALSE); + } else - { - KiSideEffectsBeforeWake(hdr, - Thread, - Abandoned); - return(TRUE); - } + { + return (TRUE); + } } VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) { PKWAIT_BLOCK WaitBlock; BOOLEAN WasWaiting = FALSE; - + KeAcquireDispatcherDatabaseLock(FALSE); - + WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList; if (WaitBlock != NULL) { @@ -213,165 +206,123 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus) WaitBlock = WaitBlock->NextWaitBlock; } Thread->Tcb.WaitBlockList = NULL; - + if (WasWaiting) { PsUnblockThread(Thread, &WaitStatus); } - + KeReleaseDispatcherDatabaseLock(FALSE); } -static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) +static BOOLEAN +KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr, + BOOLEAN WakeAll) { - PKWAIT_BLOCK current; - PLIST_ENTRY current_entry; - PKWAIT_BLOCK PrevBlock; - NTSTATUS Status; - BOOLEAN Abandoned; - - DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr); - - if (IsListEmpty(&hdr->WaitListHead)) - { - return(FALSE); - } - - while (!IsListEmpty(&hdr->WaitListHead)) - { - current_entry = RemoveHeadList(&hdr->WaitListHead); - current = CONTAINING_RECORD(current_entry, - KWAIT_BLOCK, - WaitListEntry); - DPRINT("Waking %x\n",current->Thread); - if (current->WaitType == WaitAny) - { - DPRINT("WaitAny: Remove all wait blocks.\n"); - for(PrevBlock = current->Thread->WaitBlockList; PrevBlock; - PrevBlock = PrevBlock->NextWaitBlock) - { - if (PrevBlock != current) - RemoveEntryList(&PrevBlock->WaitListEntry); - } - current->Thread->WaitBlockList = 0; - } + PKWAIT_BLOCK Waiter; + PKWAIT_BLOCK WaiterHead; + PLIST_ENTRY EnumEntry; + NTSTATUS Status; + BOOLEAN Abandoned; + BOOLEAN AllSignaled; + BOOLEAN WakedAny = FALSE; + + DPRINT("KeDispatcherObjectWakeOnOrAll(hdr %x)\n", hdr); + DPRINT ("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", + hdr->WaitListHead.Flink, hdr->WaitListHead.Blink); + + if (IsListEmpty(&hdr->WaitListHead)) + { + return (FALSE); + } + + //enum waiters for this dispatcher object + EnumEntry = hdr->WaitListHead.Flink; + while (EnumEntry != &hdr->WaitListHead && (WakeAll || !WakedAny)) + { + WaiterHead = CONTAINING_RECORD(EnumEntry, KWAIT_BLOCK, WaitListEntry); + DPRINT("current_entry %x current %x\n", EnumEntry, WaiterHead); + EnumEntry = EnumEntry->Flink; + assert(WaiterHead->Thread->WaitBlockList != NULL); + + Abandoned = FALSE; + + if (WaiterHead->WaitType == WaitAny) + { + DPRINT("WaitAny: Remove all wait blocks.\n"); + for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock) + { + RemoveEntryList(&Waiter->WaitListEntry); + } + + WaiterHead->Thread->WaitBlockList = NULL; + + /* + * If a WakeAll KiSideEffectsBeforeWake(hdr,.. will be called several times, + * but thats ok since WakeAll objects has no sideeffects. + */ + Abandoned = KiSideEffectsBeforeWake(hdr, WaiterHead->Thread) ? TRUE : Abandoned; + } else - { - DPRINT("WaitAll: Remove the current wait block only.\n"); - - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == current) - { - DPRINT( "WaitAll: Current block is list head.\n" ); - current->Thread->WaitBlockList = current->NextWaitBlock; - } - else - { - DPRINT( "WaitAll: Current block is not list head.\n" ); - while (PrevBlock && PrevBlock->NextWaitBlock != current) - { - PrevBlock = PrevBlock->NextWaitBlock; - } - if (PrevBlock) - { - PrevBlock->NextWaitBlock = current->NextWaitBlock; - } - current->NextWaitBlock = NULL; - /* if the last block is the timeout block then remove this block */ - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == ¤t->Thread->WaitBlock[3] && PrevBlock->NextWaitBlock == NULL) - { - RemoveEntryList(¤t->Thread->WaitBlock[3].WaitListEntry); - current->Thread->WaitBlockList = NULL; - } - } - } - KiSideEffectsBeforeWake(hdr, current->Thread, &Abandoned); - Status = current->WaitKey; - if (Abandoned) - Status += STATUS_ABANDONED_WAIT_0; - if (current->Thread->WaitBlockList == NULL) - { - PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - &Status); - } - } - return(TRUE); -} + { + DPRINT("WaitAll: All WaitAll objects must be signaled.\n"); + + AllSignaled = TRUE; + + //all WaitAll obj. for thread need to be signaled to satisfy a wake + for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock) + { + //no need to check hdr since it has to be signaled + if (Waiter->WaitType == WaitAll && Waiter->Object != hdr) + { + if (!KiIsObjectSignalled(Waiter->Object, Waiter->Thread)) + { + AllSignaled = FALSE; + break; + } + } + } -static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) -{ - PKWAIT_BLOCK current; - PLIST_ENTRY current_entry; - PKWAIT_BLOCK PrevBlock; - NTSTATUS Status; - BOOLEAN Abandoned; - - DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr); - DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", - hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); - if (IsListEmpty(&(hdr->WaitListHead))) - { - return(FALSE); - } - current_entry = RemoveHeadList(&(hdr->WaitListHead)); - current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, - WaitListEntry); - DPRINT("current_entry %x current %x\n",current_entry,current); + if (AllSignaled) + { + for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock) + { + RemoveEntryList(&Waiter->WaitListEntry); - if (current->WaitType == WaitAny) - { - DPRINT("WaitAny: Remove all wait blocks.\n"); - for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) - if( PrevBlock != current ) - RemoveEntryList( &(PrevBlock->WaitListEntry) ); - current->Thread->WaitBlockList = 0; - } - else - { - DPRINT("WaitAll: Remove the current wait block only.\n"); - - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == current) - { - DPRINT( "WaitAll: Current block is list head.\n" ); - current->Thread->WaitBlockList = current->NextWaitBlock; - } - else - { - DPRINT( "WaitAll: Current block is not list head.\n" ); - while ( PrevBlock && PrevBlock->NextWaitBlock != current) - { - PrevBlock = PrevBlock->NextWaitBlock; - } - if (PrevBlock) - { - PrevBlock->NextWaitBlock = current->NextWaitBlock; - } - } - current->NextWaitBlock = NULL; - /* if the last block is the timeout block then remove this block */ - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == ¤t->Thread->WaitBlock[3] && PrevBlock->NextWaitBlock == NULL) - { - RemoveEntryList(¤t->Thread->WaitBlock[3].WaitListEntry); - current->Thread->WaitBlockList = NULL; - } - } + if (Waiter->WaitType == WaitAll) + { + Abandoned = KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread) + ? TRUE : Abandoned; + } - DPRINT("Waking %x\n",current->Thread); - KiSideEffectsBeforeWake(hdr, current->Thread, &Abandoned); - Status = current->WaitKey; - if (Abandoned) - Status += STATUS_ABANDONED_WAIT_0; - if (current->Thread->WaitBlockList == NULL) - { - PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb), - &Status); - } - return(TRUE); + //no WaitAny objects can possibly be signaled since we are here + assert(!(Waiter->WaitType == WaitAny + && KiIsObjectSignalled(Waiter->Object, Waiter->Thread))); + } + + WaiterHead->Thread->WaitBlockList = NULL; + } + } + + if (WaiterHead->Thread->WaitBlockList == NULL) + { + Status = WaiterHead->WaitKey; + if (Abandoned) + { + DPRINT("Abandoned mutex among objects"); + Status += STATUS_ABANDONED_WAIT_0; + } + + WakedAny = TRUE; + DPRINT("Waking %x status = %x\n", WaiterHead->Thread, Status); + PsUnblockThread(CONTAINING_RECORD(WaiterHead->Thread, ETHREAD, Tcb), &Status); + } + } + + return WakedAny; } + BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) /* * FUNCTION: Wake threads waiting on a dispatcher object @@ -388,16 +339,17 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) { case InternalNotificationEvent: return(KeDispatcherObjectWakeAll(hdr)); - + case InternalNotificationTimer: return(KeDispatcherObjectWakeAll(hdr)); - + case InternalSynchronizationEvent: return(KeDispatcherObjectWakeOne(hdr)); case InternalSynchronizationTimer: return(KeDispatcherObjectWakeOne(hdr)); - + + case InternalQueueType: case InternalSemaphoreType: DPRINT("hdr->SignalState %d\n", hdr->SignalState); if(hdr->SignalState>0) @@ -410,13 +362,13 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) return(Ret); } else return FALSE; - + case InternalProcessType: return(KeDispatcherObjectWakeAll(hdr)); case InternalThreadType: return(KeDispatcherObjectWakeAll(hdr)); - + case InternalMutexType: return(KeDispatcherObjectWakeOne(hdr)); } @@ -428,13 +380,13 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) NTSTATUS STDCALL KeWaitForSingleObject(PVOID Object, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout) + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout) /* * FUNCTION: Puts the current thread into a wait state until the - * given dispatcher object is set to signalled + * given dispatcher object is set to signalled * ARGUMENTS: * Object = Object to wait on * WaitReason = Reason for the wait (debugging aid) @@ -446,282 +398,269 @@ KeWaitForSingleObject(PVOID Object, * RETURNS: Status */ { - DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object; + return KeWaitForMultipleObjects(1, + &Object, + WaitAny, + WaitReason, + WaitMode, + Alertable, + Timeout, + NULL); +} + + +inline +PVOID +KiGetWaitableObjectFromObject(PVOID Object) +{ + //special case when waiting on file objects + if ( ((PDISPATCHER_HEADER)Object)->Type == InternalFileType) + { + return &((PFILE_OBJECT)Object)->Event; + } + + return Object; +} + + +NTSTATUS STDCALL +KeWaitForMultipleObjects(ULONG Count, + PVOID Object[], + WAIT_TYPE WaitType, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout, + PKWAIT_BLOCK WaitBlockArray) +{ + DISPATCHER_HEADER *hdr; + PKWAIT_BLOCK blk; PKTHREAD CurrentThread; + ULONG CountSignaled; + ULONG i; NTSTATUS Status; KIRQL WaitIrql; BOOLEAN Abandoned; + DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) " + "PsGetCurrentThread() %x\n", Count, Object, PsGetCurrentThread()); + CurrentThread = KeGetCurrentThread(); WaitIrql = KeGetCurrentIrql(); /* - * Set up the timeout - * FIXME: Check for zero timeout + * Work out where we are going to put the wait blocks */ - if (Timeout != NULL) - { - KeInitializeTimer(&CurrentThread->Timer); - KeSetTimer(&CurrentThread->Timer, *Timeout, NULL); - } - - do - { - KeAcquireDispatcherDatabaseLock(FALSE); - - /* - * If we are going to wait alertably and a user apc is pending - * then return - */ - if (Alertable && KiTestAlert()) - { - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_USER_APC); - } - - /* - * If the object is signalled - */ - if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned)) - { - if (Timeout != NULL) - { - KeCancelTimer(&CurrentThread->Timer); - } - KeReleaseDispatcherDatabaseLock(FALSE); - if (Abandoned == TRUE) - return(STATUS_ABANDONED_WAIT_0); - return(STATUS_WAIT_0); - } - - /* - * Check if we have already timed out - */ - if (Timeout != NULL && - KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread, NULL)) - { - KeCancelTimer(&CurrentThread->Timer); - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_TIMEOUT); - } - - /* - * Set up for a wait - */ - CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0]; - CurrentThread->WaitBlock[0].Object = Object; - CurrentThread->WaitBlock[0].Thread = CurrentThread; - CurrentThread->WaitBlock[0].WaitKey = STATUS_WAIT_0; - CurrentThread->WaitBlock[0].WaitType = WaitAny; - InsertTailList(&hdr->WaitListHead, - &CurrentThread->WaitBlock[0].WaitListEntry); - if (Timeout != NULL) - { - CurrentThread->WaitBlock[0].NextWaitBlock = - &CurrentThread->WaitBlock[3]; - CurrentThread->WaitBlock[3].Object = (PVOID)&CurrentThread->Timer; - CurrentThread->WaitBlock[3].Thread = CurrentThread; - CurrentThread->WaitBlock[3].WaitKey = STATUS_TIMEOUT; - CurrentThread->WaitBlock[3].WaitType = WaitAny; - CurrentThread->WaitBlock[3].NextWaitBlock = NULL; - InsertTailList(&CurrentThread->Timer.Header.WaitListHead, - &CurrentThread->WaitBlock[3].WaitListEntry); - } - else - { - CurrentThread->WaitBlock[0].NextWaitBlock = NULL; - } - PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql); - } while (Status == STATUS_KERNEL_APC); - - if (Timeout != NULL) - { - KeCancelTimer(&CurrentThread->Timer); - } - - DPRINT("Returning from KeWaitForSingleObject()\n"); - return(Status); -} - - -NTSTATUS STDCALL -KeWaitForMultipleObjects(ULONG Count, - PVOID Object[], - WAIT_TYPE WaitType, - KWAIT_REASON WaitReason, - KPROCESSOR_MODE WaitMode, - BOOLEAN Alertable, - PLARGE_INTEGER Timeout, - PKWAIT_BLOCK WaitBlockArray) -{ - DISPATCHER_HEADER* hdr; - PKWAIT_BLOCK blk; - PKTHREAD CurrentThread; - ULONG CountSignaled; - ULONG i; - NTSTATUS Status; - KIRQL WaitIrql; - BOOLEAN Abandoned; - - DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) " - "PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread()); - - CountSignaled = 0; - CurrentThread = KeGetCurrentThread(); - WaitIrql = KeGetCurrentIrql(); - - /* - * Work out where we are going to put the wait blocks - */ - if (WaitBlockArray == NULL) - { + if (WaitBlockArray == NULL) + { if (Count > THREAD_WAIT_OBJECTS) - { - DbgPrint("(%s:%d) Too many objects!\n", - __FILE__,__LINE__); - return(STATUS_UNSUCCESSFUL); - } + { + DPRINT("(%s:%d) Too many objects!\n", __FILE__, __LINE__); + return (STATUS_UNSUCCESSFUL); + } WaitBlockArray = &CurrentThread->WaitBlock[0]; - } - else - { + } + else + { if (Count > EX_MAXIMUM_WAIT_OBJECTS) - { - DbgPrint("(%s:%d) Too many objects!\n", - __FILE__,__LINE__); - return(STATUS_UNSUCCESSFUL); - } - } + { + DPRINT("(%s:%d) Too many objects!\n", __FILE__, __LINE__); + return (STATUS_UNSUCCESSFUL); + } + } - /* - * Set up the timeout if required - */ - if (Timeout != NULL) - { + /* + * Set up the timeout if required + */ + if (Timeout != NULL && Timeout->QuadPart != 0) + { KeInitializeTimer(&CurrentThread->Timer); KeSetTimer(&CurrentThread->Timer, *Timeout, NULL); - } - - do - { + } + + do + { KeAcquireDispatcherDatabaseLock(FALSE); - /* - * If we are going to wait alertably and a user apc is pending - * then return - */ - if (Alertable && KiTestAlert()) - { - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_USER_APC); - } - - /* - * Check if the wait is already satisfied - */ - for (i = 0; i < Count; i++) - { - hdr = (DISPATCHER_HEADER *)Object[i]; - - if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned)) - { - CountSignaled++; - - if (WaitType == WaitAny) - { - if (Timeout != NULL) - { - KeCancelTimer(&CurrentThread->Timer); - } - KeReleaseDispatcherDatabaseLock(FALSE); - DPRINT("One object is already signaled!\n"); - if (Abandoned == TRUE) - return(STATUS_ABANDONED_WAIT_0 + i); - return(STATUS_WAIT_0 + i); - } - } - } - - if ((WaitType == WaitAll) && (CountSignaled == Count)) - { - if (Timeout != NULL) - { - KeCancelTimer(&CurrentThread->Timer); - } - KeReleaseDispatcherDatabaseLock(FALSE); - DPRINT("All objects are already signaled!\n"); - return(STATUS_WAIT_0); - } - - /* - * Check if we have already timed out - */ - if (Timeout != NULL && - KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread, NULL)) - { - KeCancelTimer(&CurrentThread->Timer); - KeReleaseDispatcherDatabaseLock(FALSE); - return(STATUS_TIMEOUT); - } - - /* Append wait block to the KTHREAD wait block list */ - CurrentThread->WaitBlockList = blk = WaitBlockArray; - - /* - * Set up the wait - */ - CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; - for (i = 0; i < Count; i++) - { - hdr = (DISPATCHER_HEADER *)Object[i]; - - blk->Object = Object[i]; - blk->Thread = CurrentThread; - blk->WaitKey = STATUS_WAIT_0 + i; - blk->WaitType = WaitType; - if (i == (Count - 1)) - { - if (Timeout != NULL) - { - blk->NextWaitBlock = &CurrentThread->WaitBlock[3]; - } - else - { - blk->NextWaitBlock = NULL; - } - } - else - { - blk->NextWaitBlock = blk + 1; - } - - InsertTailList(&hdr->WaitListHead, &blk->WaitListEntry); - - blk = blk->NextWaitBlock; - } - if (Timeout != NULL) - { - CurrentThread->WaitBlock[3].Object = (PVOID)&CurrentThread->Timer; - CurrentThread->WaitBlock[3].Thread = CurrentThread; - CurrentThread->WaitBlock[3].WaitKey = STATUS_TIMEOUT; - CurrentThread->WaitBlock[3].WaitType = WaitAny; - CurrentThread->WaitBlock[3].NextWaitBlock = NULL; - InsertTailList(&CurrentThread->Timer.Header.WaitListHead, - &CurrentThread->WaitBlock[3].WaitListEntry); - } - - PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql); - } while(Status == STATUS_KERNEL_APC); - - if (Timeout != NULL) - { + /* + * If we are going to wait alertably and a user apc is pending + * then return + */ + if (Alertable && KiTestAlert()) + { + KeReleaseDispatcherDatabaseLock(FALSE); + return (STATUS_USER_APC); + } + + /* + * Check if the wait is (already) satisfied + */ + CountSignaled = 0; + Abandoned = FALSE; + for (i = 0; i < Count; i++) + { + hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]); + + if (KiIsObjectSignalled(hdr, CurrentThread)) + { + CountSignaled++; + + if (WaitType == WaitAny) + { + Abandoned = KiSideEffectsBeforeWake(hdr, CurrentThread) ? TRUE : Abandoned; + + if (Timeout != NULL && Timeout->QuadPart != 0) + { + KeCancelTimer(&CurrentThread->Timer); + } + + KeReleaseDispatcherDatabaseLock(FALSE); + + DPRINT("One object is (already) signaled!\n"); + if (Abandoned == TRUE) + { + return (STATUS_ABANDONED_WAIT_0 + i); + } + + return (STATUS_WAIT_0 + i); + } + } + } + + Abandoned = FALSE; + if ((WaitType == WaitAll) && (CountSignaled == Count)) + { + for (i = 0; i < Count; i++) + { + hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]); + Abandoned = KiSideEffectsBeforeWake(hdr, CurrentThread) ? TRUE : Abandoned; + } + + if (Timeout != NULL && Timeout->QuadPart != 0) + { + KeCancelTimer(&CurrentThread->Timer); + } + + KeReleaseDispatcherDatabaseLock(FALSE); + DPRINT("All objects are (already) signaled!\n"); + + if (Abandoned == TRUE) + { + return (STATUS_ABANDONED_WAIT_0); + } + + return (STATUS_WAIT_0); + } + + //zero timeout is used for testing if the object(s) can be immediately acquired + if (Timeout != NULL && Timeout->QuadPart == 0) + { + KeReleaseDispatcherDatabaseLock(FALSE); + return STATUS_TIMEOUT; + } + + /* + * Check if we have already timed out + */ + if (Timeout != NULL && KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread)) + { + KiSideEffectsBeforeWake(&CurrentThread->Timer.Header, CurrentThread); + KeCancelTimer(&CurrentThread->Timer); + KeReleaseDispatcherDatabaseLock(FALSE); + return (STATUS_TIMEOUT); + } + + /* Append wait block to the KTHREAD wait block list */ + CurrentThread->WaitBlockList = blk = WaitBlockArray; + + /* + * Set up the wait + */ + CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; + + for (i = 0; i < Count; i++) + { + hdr = (DISPATCHER_HEADER *) KiGetWaitableObjectFromObject(Object[i]); + + blk->Object = KiGetWaitableObjectFromObject(Object[i]); + blk->Thread = CurrentThread; + blk->WaitKey = STATUS_WAIT_0 + i; + blk->WaitType = WaitType; + + if (i == (Count - 1)) + { + if (Timeout != NULL) + { + blk->NextWaitBlock = &CurrentThread->WaitBlock[3]; + } + else + { + blk->NextWaitBlock = NULL; + } + } + else + { + blk->NextWaitBlock = blk + 1; + } + + /* + * add wait block to disp. obj. wait list + * Use FIFO for all waits except for queues which use LIFO + */ + if (WaitReason == WrQueue) + { + InsertHeadList(&hdr->WaitListHead, &blk->WaitListEntry); + } + else + { + InsertTailList(&hdr->WaitListHead, &blk->WaitListEntry); + } + + blk = blk->NextWaitBlock; + } + + if (Timeout != NULL) + { + CurrentThread->WaitBlock[3].Object = (PVOID) & CurrentThread->Timer; + CurrentThread->WaitBlock[3].Thread = CurrentThread; + CurrentThread->WaitBlock[3].WaitKey = STATUS_TIMEOUT; + CurrentThread->WaitBlock[3].WaitType = WaitAny; + CurrentThread->WaitBlock[3].NextWaitBlock = NULL; + + InsertTailList(&CurrentThread->Timer.Header.WaitListHead, + &CurrentThread->WaitBlock[3].WaitListEntry); + } + + //io completion + if (CurrentThread->Queue) + { + CurrentThread->Queue->RunningThreads--; + if (WaitReason != WrQueue && CurrentThread->Queue->RunningThreads < CurrentThread->Queue->MaximumThreads && + !IsListEmpty(&CurrentThread->Queue->EntryListHead)) + { + KeDispatcherObjectWake(&CurrentThread->Queue->Header); + } + } + + PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql, WaitReason); + + //io completion + if (CurrentThread->Queue) + { + CurrentThread->Queue->RunningThreads++; + } + + + } + while (Status == STATUS_KERNEL_APC); + + if (Timeout != NULL) + { KeCancelTimer(&CurrentThread->Timer); - } + } - DPRINT("Returning from KeWaitForMultipleObjects()\n"); - return(Status); + DPRINT("Returning from KeWaitForMultipleObjects()\n"); + return (Status); } VOID KeInitializeDispatcher(VOID) @@ -732,7 +671,7 @@ VOID KeInitializeDispatcher(VOID) NTSTATUS STDCALL NtWaitForMultipleObjects(IN ULONG Count, IN HANDLE Object [], - IN CINT WaitType, + IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER Time) { @@ -740,6 +679,7 @@ NtWaitForMultipleObjects(IN ULONG Count, PVOID ObjectPtrArray[EX_MAXIMUM_WAIT_OBJECTS]; NTSTATUS Status; ULONG i, j; + KPROCESSOR_MODE WaitMode; DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, " "Time %x)\n", Count,Object,Alertable,Time); @@ -747,13 +687,15 @@ NtWaitForMultipleObjects(IN ULONG Count, if (Count > EX_MAXIMUM_WAIT_OBJECTS) return STATUS_UNSUCCESSFUL; + WaitMode = ExGetPreviousMode(); + /* reference all objects */ for (i = 0; i < Count; i++) { Status = ObReferenceObjectByHandle(Object[i], SYNCHRONIZE, NULL, - UserMode, + WaitMode, &ObjectPtrArray[i], NULL); if (Status != STATUS_SUCCESS) @@ -772,7 +714,7 @@ NtWaitForMultipleObjects(IN ULONG Count, ObjectPtrArray, WaitType, UserRequest, - UserMode, + WaitMode, Alertable, Time, WaitBlockArray); @@ -794,29 +736,32 @@ NtWaitForSingleObject(IN HANDLE Object, { PVOID ObjectPtr; NTSTATUS Status; - + KPROCESSOR_MODE WaitMode; + DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n", Object,Alertable,Time); - + + WaitMode = ExGetPreviousMode(); + Status = ObReferenceObjectByHandle(Object, SYNCHRONIZE, NULL, - UserMode, + WaitMode, &ObjectPtr, NULL); if (!NT_SUCCESS(Status)) { return(Status); } - + Status = KeWaitForSingleObject(ObjectPtr, - UserMode, - UserMode, + UserRequest, + WaitMode, Alertable, Time); - + ObDereferenceObject(ObjectPtr); - + return(Status); } @@ -827,17 +772,17 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject, IN BOOLEAN Alertable, IN PLARGE_INTEGER Time) { - KPROCESSOR_MODE ProcessorMode; + KPROCESSOR_MODE WaitMode; DISPATCHER_HEADER* hdr; PVOID SignalObj; PVOID WaitObj; NTSTATUS Status; - ProcessorMode = ExGetPreviousMode(); + WaitMode = ExGetPreviousMode(); Status = ObReferenceObjectByHandle(SignalObject, 0, NULL, - ProcessorMode, + WaitMode, &SignalObj, NULL); if (!NT_SUCCESS(Status)) @@ -848,7 +793,7 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject, Status = ObReferenceObjectByHandle(WaitObject, SYNCHRONIZE, NULL, - ProcessorMode, + WaitMode, &WaitObj, NULL); if (!NT_SUCCESS(Status)) @@ -887,7 +832,7 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject, Status = KeWaitForSingleObject(WaitObj, UserRequest, - ProcessorMode, + WaitMode, Alertable, Time); diff --git a/ntoskrnl/ldr/init.c b/ntoskrnl/ldr/init.c index 80599c7..6e9d3a1 100644 --- a/ntoskrnl/ldr/init.c +++ b/ntoskrnl/ldr/init.c @@ -224,79 +224,156 @@ LdrpCreateProcessEnvironment(HANDLE ProcessHandle, return(STATUS_SUCCESS); } - -static NTSTATUS -LdrpCreateStack(HANDLE ProcessHandle, - PINITIAL_TEB InitialTeb) +/* + FIXME: this sucks. Sucks sucks sucks. This code was duplicated, if you can + believe it, in four different places - excluding this, and twice in the two + DLLs that contained it (kernel32.dll and ntdll.dll). As much as I'd like to + rip the whole RTL out of ntdll.dll and ntoskrnl.exe and into its own static + library, ntoskrnl.exe is built separatedly from the rest of ReactOS, coming + with its own linker scripts and specifications, and, save for changes and fixes + to make it at least compile, I'm not going to touch any of it. If you feel + brave enough, you're welcome [KJK::Hyperion] +*/ +static NTSTATUS LdrpCreateStack +( + HANDLE ProcessHandle, + PUSER_STACK UserStack, + PULONG_PTR StackReserve, + PULONG_PTR StackCommit +) { - ULONG OldPageProtection; - NTSTATUS Status; - - InitialTeb->StackAllocate = NULL; - - /* Allocate the reserved stack space */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb->StackAllocate, - 0, - &InitialTeb->StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Stack allocation failed (Status %x)", Status); - return(Status); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb->StackAllocate, InitialTeb->StackReserve); - - InitialTeb->StackBase = (PVOID)((ULONG)InitialTeb->StackAllocate + InitialTeb->StackReserve); - InitialTeb->StackLimit = (PVOID)((ULONG)InitialTeb->StackBase - InitialTeb->StackCommit); - - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb->StackBase, InitialTeb->StackCommit); - - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb->StackLimit, - 0, - &InitialTeb->StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error comitting stack page!\n"); - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb->StackAllocate, - &InitialTeb->StackReserve, - MEM_RELEASE); - return(Status); - } - - DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", - InitialTeb->StackLimit, - InitialTeb->StackCommit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb->StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error protecting guard page!\n"); - - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb->StackAllocate, - &InitialTeb->StackReserve, - MEM_RELEASE); - return(Status); - } - - return(STATUS_SUCCESS); + PVOID pStackLowest = NULL; + ULONG_PTR nSize = 0; + NTSTATUS nErrCode; + + if(StackReserve == NULL || StackCommit == NULL) + return STATUS_INVALID_PARAMETER; + + /* FIXME: no SEH, no guard pages */ + *StackCommit = *StackReserve; + + UserStack->FixedStackBase = NULL; + UserStack->FixedStackLimit = NULL; + UserStack->ExpandableStackBase = NULL; + UserStack->ExpandableStackLimit = NULL; + UserStack->ExpandableStackBottom = NULL; + + /* FIXME: this code assumes a stack growing downwards */ + /* fixed stack */ + if(*StackCommit == *StackReserve) + { + DPRINT("Fixed stack\n"); + + UserStack->FixedStackLimit = NULL; + + /* allocate the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->FixedStackLimit), + 0, + StackReserve, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + /* store the highest (first) address of the stack */ + UserStack->FixedStackBase = + (PUCHAR)(UserStack->FixedStackLimit) + *StackReserve; + } + /* expandable stack */ + else + { + ULONG_PTR nGuardSize = PAGE_SIZE; + PVOID pGuardBase; + + DPRINT("Expandable stack\n"); + + UserStack->FixedStackLimit = NULL; + UserStack->FixedStackBase = NULL; + UserStack->ExpandableStackBottom = NULL; + + /* reserve the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->ExpandableStackBottom), + 0, + StackReserve, + MEM_RESERVE, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + DPRINT("Reserved %08X bytes\n", *StackReserve); + + /* expandable stack base - the highest address of the stack */ + UserStack->ExpandableStackBase = + (PUCHAR)(UserStack->ExpandableStackBottom) + *StackReserve; + + /* expandable stack limit - the lowest committed address of the stack */ + UserStack->ExpandableStackLimit = + (PUCHAR)(UserStack->ExpandableStackBase) - *StackCommit; + + DPRINT("Stack base %p\n", UserStack->ExpandableStackBase); + DPRINT("Stack limit %p\n", UserStack->ExpandableStackLimit); + + /* commit as much stack as requested */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->ExpandableStackLimit), + 0, + StackCommit, + MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + DPRINT("Stack limit %p\n", UserStack->ExpandableStackLimit); + + pGuardBase = (PUCHAR)(UserStack->ExpandableStackLimit) - PAGE_SIZE; + + DPRINT("Guard base %p\n", UserStack->ExpandableStackBase); + + /* set up the guard page */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &pGuardBase, + 0, + &nGuardSize, + MEM_COMMIT, + PAGE_READWRITE | PAGE_GUARD + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + DPRINT("Guard base %p\n", UserStack->ExpandableStackBase); + } + + return STATUS_SUCCESS; + + /* cleanup in case of failure */ +l_Cleanup: + if(UserStack->FixedStackLimit) + pStackLowest = UserStack->FixedStackLimit; + else if(UserStack->ExpandableStackBottom) + pStackLowest = UserStack->ExpandableStackBottom; + + /* free the stack, if it was allocated */ + if(pStackLowest != NULL) + NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE); + + return nErrCode; } @@ -308,7 +385,11 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, UNICODE_STRING ImagePath; HANDLE SectionHandle; CONTEXT Context; - INITIAL_TEB InitialTeb; + USER_STACK UserStack; + ULONG_PTR nStackReserve = 0; + ULONG_PTR nStackCommit = 0; + PVOID pStackLowest; + PVOID pStackBase; ULONG ResultLength; PVOID ImageBaseAddress; ULONG InitialStack[5]; @@ -373,28 +454,32 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, /* Calculate initial stack sizes */ if (Sii.StackReserve > 0x100000) - InitialTeb.StackReserve = Sii.StackReserve; + nStackReserve = Sii.StackReserve; else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ + nStackReserve = 0x100000; /* 1MByte */ /* FIXME */ #if 0 if (Sii.StackCommit > PAGE_SIZE) - InitialTeb.StackCommit = Sii.StackCommit; + nStackCommit = Sii.StackCommit; else - InitialTeb.StackCommit = PAGE_SIZE; + nStackCommit = PAGE_SIZE; #endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; + nStackCommit = nStackReserve - PAGE_SIZE; - /* add guard page size */ - InitialTeb.StackCommit += PAGE_SIZE; DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n", - InitialTeb.StackReserve, InitialTeb.StackCommit); + nStackReserve, nStackCommit); /* Create the process stack */ - Status = LdrpCreateStack(*ProcessHandle, - &InitialTeb); + Status = LdrpCreateStack + ( + *ProcessHandle, + &UserStack, + &nStackReserve, + &nStackCommit + ); + if (!NT_SUCCESS(Status)) { DPRINT("Failed to write initial stack.\n"); @@ -402,12 +487,31 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, return(Status); } + if(UserStack.FixedStackBase && UserStack.FixedStackLimit) + { + pStackBase = UserStack.FixedStackBase; + pStackLowest = UserStack.FixedStackLimit; + } + else + { + pStackBase = UserStack.ExpandableStackBase; + pStackLowest = UserStack.ExpandableStackBottom; + } + + DPRINT("pStackBase = %p\n", pStackBase); + DPRINT("pStackLowest = %p\n", pStackLowest); /* * Initialize context to point to LdrStartup */ +#if defined(_M_IX86) memset(&Context,0,sizeof(CONTEXT)); - Context.Eip = (ULONG)(ImageBaseAddress + (ULONG)Sii.EntryPoint); + Context.ContextFlags = CONTEXT_FULL; + Context.FloatSave.ControlWord = 0xffff037f; + Context.FloatSave.StatusWord = 0xffff0000; + Context.FloatSave.TagWord = 0xffffffff; + Context.FloatSave.DataSelector = 0xffff0000; + Context.Eip = (ULONG_PTR)(ImageBaseAddress + (ULONG_PTR)Sii.EntryPoint); Context.SegCs = USER_CS; Context.SegDs = USER_DS; Context.SegEs = USER_DS; @@ -415,7 +519,10 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, Context.SegGs = USER_DS; Context.SegSs = USER_DS; Context.EFlags = 0x202; - Context.Esp = (ULONG)InitialTeb.StackBase - 20; + Context.Esp = (ULONG_PTR)pStackBase - 20; +#else +#error Unsupported architecture +#endif /* * Write in the initial stack. @@ -429,11 +536,13 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, &ResultLength); if (!NT_SUCCESS(Status)) { + ULONG_PTR nSize = 0; + DPRINT("Failed to write initial stack.\n"); NtFreeVirtualMemory(*ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, + pStackLowest, + &nSize, MEM_RELEASE); NtClose(*ProcessHandle); return(Status); @@ -447,15 +556,17 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, *ProcessHandle, NULL, &Context, - &InitialTeb, + &UserStack, FALSE); if (!NT_SUCCESS(Status)) { + ULONG_PTR nSize = 0; + DPRINT("NtCreateThread() failed (Status %lx)\n", Status); NtFreeVirtualMemory(*ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, + pStackLowest, + &nSize, MEM_RELEASE); NtClose(*ProcessHandle); diff --git a/ntoskrnl/ldr/loader.c b/ntoskrnl/ldr/loader.c index 1bb0712..031f23c 100644 --- a/ntoskrnl/ldr/loader.c +++ b/ntoskrnl/ldr/loader.c @@ -18,6 +18,7 @@ * JF 26/01/2000 Recoded some parts to retrieve export details correctly * DW 27/06/2000 Removed redundant header files * CSH 11/04/2001 Added automatic loading of module symbols if they exist + * KJK 02/04/2003 Nebbet-ized a couple of type names */ @@ -533,6 +534,7 @@ LdrInitializeBootStartDriver(PVOID ModuleLoadBase, Length = wcslen(Start); wcsncpy(Buffer, Start, Length); + Buffer[Length] = 0; RtlCreateUnicodeString(&DeviceNode->ServiceName, Buffer); Status = IopInitializeDriver(ModuleObject->EntryPoint, @@ -592,7 +594,7 @@ LdrpQueryModuleInformation(PVOID Buffer, PLIST_ENTRY current_entry; PMODULE_OBJECT current; ULONG ModuleCount = 0; - PSYSTEM_MODULE_INFORMATION Smi; + PSYSTEM_MODULES Smi; ANSI_STRING AnsiName; PCHAR p; KIRQL Irql; @@ -607,8 +609,8 @@ LdrpQueryModuleInformation(PVOID Buffer, current_entry = current_entry->Flink; } - *ReqSize = sizeof(SYSTEM_MODULE_INFORMATION)+ - (ModuleCount - 1) * sizeof(SYSTEM_MODULE_ENTRY); + *ReqSize = sizeof(SYSTEM_MODULES)+ + (ModuleCount - 1) * sizeof(SYSTEM_MODULE_INFORMATION); if (Size < *ReqSize) { @@ -619,7 +621,7 @@ LdrpQueryModuleInformation(PVOID Buffer, /* fill the buffer */ memset(Buffer, '=', Size); - Smi = (PSYSTEM_MODULE_INFORMATION)Buffer; + Smi = (PSYSTEM_MODULES)Buffer; Smi->Count = ModuleCount; ModuleCount = 0; @@ -628,15 +630,18 @@ LdrpQueryModuleInformation(PVOID Buffer, { current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry); - Smi->Module[ModuleCount].Unknown2 = 0; /* Always 0 */ - Smi->Module[ModuleCount].BaseAddress = current->Base; - Smi->Module[ModuleCount].Size = current->Length; - Smi->Module[ModuleCount].Flags = 0; /* Flags ??? (GN) */ - Smi->Module[ModuleCount].EntryIndex = ModuleCount; + Smi->Modules[ModuleCount].Reserved[0] = 0; /* Always 0 */ + Smi->Modules[ModuleCount].Reserved[1] = 0; /* Always 0 */ + Smi->Modules[ModuleCount].Base = current->Base; + Smi->Modules[ModuleCount].Size = current->Length; + Smi->Modules[ModuleCount].Flags = 0; /* Flags ??? (GN) */ + Smi->Modules[ModuleCount].Index = ModuleCount; + Smi->Modules[ModuleCount].Unknown = 0; + Smi->Modules[ModuleCount].LoadCount = 0; /* FIXME */ AnsiName.Length = 0; AnsiName.MaximumLength = 256; - AnsiName.Buffer = Smi->Module[ModuleCount].Name; + AnsiName.Buffer = Smi->Modules[ModuleCount].ImageName; RtlUnicodeStringToAnsiString(&AnsiName, ¤t->FullName, FALSE); @@ -644,14 +649,12 @@ LdrpQueryModuleInformation(PVOID Buffer, p = strrchr(AnsiName.Buffer, '\\'); if (p == NULL) { - Smi->Module[ModuleCount].PathLength = 0; - Smi->Module[ModuleCount].NameLength = strlen(AnsiName.Buffer); + Smi->Modules[ModuleCount].ModuleNameOffset = 0; } else { p++; - Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer; - Smi->Module[ModuleCount].NameLength = strlen(p); + Smi->Modules[ModuleCount].ModuleNameOffset = p - AnsiName.Buffer; } ModuleCount++; @@ -1067,15 +1070,22 @@ LdrPEProcessModule(PVOID ModuleLoadBase, LibraryModuleObject = LdrGetModuleObject(&ModuleName); if (LibraryModuleObject == NULL) { - CPRINT("Module '%wZ' not loaded yet\n", &ModuleName); + DPRINT("Module '%wZ' not loaded yet\n", &ModuleName); wcscpy(NameBuffer, L"\\SystemRoot\\system32\\drivers\\"); wcscat(NameBuffer, ModuleName.Buffer); RtlInitUnicodeString(&NameString, NameBuffer); Status = LdrLoadModule(&NameString, &LibraryModuleObject); if (!NT_SUCCESS(Status)) { - CPRINT("Unknown import module: %wZ (Status %lx)\n", &ModuleName, Status); - return(Status); + wcscpy(NameBuffer, L"\\SystemRoot\\system32\\"); + wcscat(NameBuffer, ModuleName.Buffer); + RtlInitUnicodeString(&NameString, NameBuffer); + Status = LdrLoadModule(&NameString, &LibraryModuleObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unknown import module: %wZ (Status %lx)\n", &ModuleName, Status); + return(Status); + } } } /* Get the import address list */ @@ -1384,7 +1394,7 @@ LdrSafePEProcessModule(PVOID ModuleLoadBase, { ULONG Offset; ULONG Type; - PDWORD RelocItem; + PULONG RelocItem; Offset = RelocEntry[Idx].TypeOffset & 0xfff; Type = (RelocEntry[Idx].TypeOffset >> 12) & 0xf; diff --git a/ntoskrnl/lpc/reply.c b/ntoskrnl/lpc/reply.c index 9bae7e0..45af312 100644 --- a/ntoskrnl/lpc/reply.c +++ b/ntoskrnl/lpc/reply.c @@ -65,7 +65,7 @@ EiReplyOrRequestPort (IN PEPORT Port, MessageReply->Message.Cid.UniqueProcess = PsGetCurrentProcessId(); MessageReply->Message.Cid.UniqueThread = PsGetCurrentThreadId(); MessageReply->Message.MessageType = MessageType; - MessageReply->Message.MessageId = InterlockedIncrement(&EiNextLpcMessageId); + MessageReply->Message.MessageId = InterlockedIncrement((LONG *)&EiNextLpcMessageId); KeAcquireSpinLock(&Port->Lock, &oldIrql); EiEnqueueMessagePort(Port, MessageReply); diff --git a/ntoskrnl/mm/anonmem.c b/ntoskrnl/mm/anonmem.c index 282b695..2bcc07a 100644 --- a/ntoskrnl/mm/anonmem.c +++ b/ntoskrnl/mm/anonmem.c @@ -201,7 +201,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, * Write the page to the pagefile */ Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, &PhysicalAddress.u.LowPart); + MmBuildMdlFromPages(Mdl, (ULONG *)&PhysicalAddress.u.LowPart); Status = MmWriteToSwapPage(SwapEntry, Mdl); if (!NT_SUCCESS(Status)) { @@ -877,10 +877,12 @@ MmQueryAnonMem(PMEMORY_AREA MemoryArea, Address, &RegionBase); Info->AllocationBase = RegionBase; Info->AllocationProtect = Region->Protect; /* FIXME */ - Info->RegionSize = Region->Length; + Info->RegionSize = RegionBase + Region->Length - Info->BaseAddress; Info->State = Region->Type; Info->Protect = Region->Protect; Info->Type = MEM_PRIVATE; + + *ResultLength = sizeof(MEMORY_BASIC_INFORMATION); return(STATUS_SUCCESS); } diff --git a/ntoskrnl/mm/balance.c b/ntoskrnl/mm/balance.c index 309948e..753adae 100644 --- a/ntoskrnl/mm/balance.c +++ b/ntoskrnl/mm/balance.c @@ -117,9 +117,9 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page) KeAcquireSpinLock(&AllocationListLock, &oldIrql); if (MmGetReferenceCountPage(Page) == 1) { - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); - InterlockedIncrement(&MiNrAvailablePages); - InterlockedDecrement(&MiPagesRequired); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedIncrement((LONG *)&MiNrAvailablePages); + InterlockedDecrement((LONG *)&MiPagesRequired); if (IsListEmpty(&AllocationListHead)) { KeReleaseSpinLock(&AllocationListLock, oldIrql); @@ -203,13 +203,13 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed our individual target. */ - OldUsed = InterlockedIncrement(&MiMemoryConsumers[Consumer].PagesUsed); + OldUsed = InterlockedIncrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) && WorkerThreadId != PsGetCurrentThreadId()) { if (!CanWait) { - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); return(STATUS_NO_MEMORY); } MiTrimMemoryConsumer(Consumer); @@ -218,22 +218,22 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed global targets. */ - OldAvailable = InterlockedDecrement(&MiNrAvailablePages); + OldAvailable = InterlockedDecrement((LONG *)&MiNrAvailablePages); if (OldAvailable < MiMinimumAvailablePages) { MM_ALLOCATION_REQUEST Request; if (!CanWait) { - InterlockedIncrement(&MiNrAvailablePages); - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedIncrement((LONG *)&MiNrAvailablePages); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); return(STATUS_NO_MEMORY); } /* Insert an allocation request. */ Request.Page.QuadPart = 0LL; KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); - InterlockedIncrement(&MiPagesRequired); + InterlockedIncrement((LONG *)&MiPagesRequired); KeAcquireSpinLock(&AllocationListLock, &oldIrql); if (NrWorkingThreads == 0) diff --git a/ntoskrnl/mm/pageop.c b/ntoskrnl/mm/pageop.c index 7c4b15e..7d43e6f 100644 --- a/ntoskrnl/mm/pageop.c +++ b/ntoskrnl/mm/pageop.c @@ -46,7 +46,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp) KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return; } - InterlockedDecrement(&PageOp->MArea->PageOpCount); + InterlockedDecrement((LONG *)&PageOp->MArea->PageOpCount); PrevPageOp = MmPageOpHashTable[PageOp->Hash]; if (PrevPageOp == PageOp) { @@ -226,7 +226,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, PageOp->MArea = MArea; KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); MmPageOpHashTable[Hash] = PageOp; - InterlockedIncrement(&MArea->PageOpCount); + InterlockedIncrement((LONG *)&MArea->PageOpCount); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return(PageOp); diff --git a/ntoskrnl/mm/section.c b/ntoskrnl/mm/section.c index 3c7dddb..7fa11fe 100644 --- a/ntoskrnl/mm/section.c +++ b/ntoskrnl/mm/section.c @@ -269,7 +269,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section, if (SHARE_COUNT_FROM_SSE(Entry) == 0) { PFILE_OBJECT FileObject; - PREACTOS_COMMON_FCB_HEADER Fcb; + PBCB Bcb; SWAPENTRY SavedSwapEntry; PHYSICAL_ADDRESS Page; @@ -277,13 +277,13 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section, FileObject = Section->FileObject; if (FileObject != NULL) { - Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ && (Offset % PAGE_SIZE) == 0) { NTSTATUS Status; - Status = CcRosUnmapCacheSegment(Fcb->Bcb, Offset, Dirty); + Status = CcRosUnmapCacheSegment(Bcb, Offset, Dirty); if (!NT_SUCCESS(Status)) { KeBugCheck(0); @@ -324,12 +324,12 @@ MiReadPage(PMEMORY_AREA MemoryArea, PCACHE_SEGMENT CacheSeg; PFILE_OBJECT FileObject; NTSTATUS Status; - PREACTOS_COMMON_FCB_HEADER Fcb; + PBCB Bcb; FileObject = MemoryArea->Data.SectionData.Section->FileObject; - Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; - assert(Fcb->Bcb); + assert(Bcb); /* * If the file system is letting us go directly to the cache and the @@ -346,12 +346,12 @@ MiReadPage(PMEMORY_AREA MemoryArea, * filesystems do because it is safe for us to use an offset with a * alignment less than the file system block size. */ - Status = CcRosGetCacheSegment(Fcb->Bcb, - Offset->u.LowPart, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + Status = CcRosGetCacheSegment(Bcb, + Offset->u.LowPart, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) { return(Status); @@ -365,7 +365,7 @@ MiReadPage(PMEMORY_AREA MemoryArea, Status = ReadCacheSegment(CacheSeg); if (!NT_SUCCESS(Status)) { - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE); + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); return Status; } } @@ -377,7 +377,7 @@ MiReadPage(PMEMORY_AREA MemoryArea, (*Page) = Addr; MmReferencePage((*Page)); - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE); } else { @@ -393,12 +393,12 @@ MiReadPage(PMEMORY_AREA MemoryArea, return(Status); } - Status = CcRosGetCacheSegment(Fcb->Bcb, - Offset->u.LowPart, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + Status = CcRosGetCacheSegment(Bcb, + Offset->u.LowPart, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) { return(Status); @@ -412,7 +412,7 @@ MiReadPage(PMEMORY_AREA MemoryArea, Status = ReadCacheSegment(CacheSeg); if (!NT_SUCCESS(Status)) { - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE); + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); return Status; } } @@ -425,13 +425,13 @@ MiReadPage(PMEMORY_AREA MemoryArea, else { memcpy(PageAddr, BaseAddress + Offset->u.LowPart - BaseOffset, OffsetInPage); - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE); - Status = CcRosGetCacheSegment(Fcb->Bcb, - Offset->u.LowPart + OffsetInPage, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); + Status = CcRosGetCacheSegment(Bcb, + Offset->u.LowPart + OffsetInPage, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) { ExUnmapPage(PageAddr); @@ -446,14 +446,14 @@ MiReadPage(PMEMORY_AREA MemoryArea, Status = ReadCacheSegment(CacheSeg); if (!NT_SUCCESS(Status)) { - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE); + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); ExUnmapPage(PageAddr); return Status; } } memcpy(PageAddr + OffsetInPage, BaseAddress, PAGE_SIZE - OffsetInPage); } - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE); + CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); ExUnmapPage(PageAddr); } return(STATUS_SUCCESS); @@ -1571,7 +1571,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, BOOLEAN Private; NTSTATUS Status; PFILE_OBJECT FileObject; - PREACTOS_COMMON_FCB_HEADER Fcb = NULL; + PBCB Bcb = NULL; BOOLEAN DirectMapped; Address = (PVOID)PAGE_ROUND_DOWN(Address); @@ -1583,7 +1583,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, DirectMapped = FALSE; if (FileObject != NULL) { - Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext; + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; /* * If the file system is letting us go directly to the cache and the @@ -1654,7 +1654,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, if (DirectMapped && !Private) { assert(SwapEntry == 0); - CcRosMarkDirtyCacheSegment(Fcb->Bcb, Offset.u.LowPart); + CcRosMarkDirtyCacheSegment(Bcb, Offset.u.LowPart); PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); @@ -1838,12 +1838,12 @@ MmpDeleteSection(PVOID ObjectBody) for (i = 0; i < Section->NrSegments; i++) { - InterlockedDecrement(&Section->Segments[i].ReferenceCount); + InterlockedDecrement((LONG *)&Section->Segments[i].ReferenceCount); } } else { - InterlockedDecrement(&Section->Segments->ReferenceCount); + InterlockedDecrement((LONG *)&Section->Segments->ReferenceCount); } if (Section->FileObject != NULL) { @@ -2684,7 +2684,7 @@ MmCreateImageSection(PHANDLE SectionHandle, */ for (i = 0; i < NrSegments; i++) { - InterlockedIncrement(&SectionSegments[i].ReferenceCount); + InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); } } @@ -2940,7 +2940,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PMEMORY_AREA MArea; ULONG Entry; PFILE_OBJECT FileObject; - PREACTOS_COMMON_FCB_HEADER Fcb; + PBCB Bcb; ULONG Offset; SWAPENTRY SavedSwapEntry; PMM_PAGEOP PageOp; @@ -2978,8 +2978,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, if (PhysAddr.QuadPart == PAGE_FROM_SSE(Entry) && Dirty) { FileObject = MemoryArea->Data.SectionData.Section->FileObject; - Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext; - CcRosMarkDirtyCacheSegment(Fcb->Bcb, Offset); + Bcb = FileObject->SectionObjectPointers->SharedCacheMap; + CcRosMarkDirtyCacheSegment(Bcb, Offset); assert(SwapEntry == 0); } } @@ -3232,6 +3232,7 @@ NtExtendSection(IN HANDLE SectionHandle, IN ULONG NewMaximumSize) { UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } @@ -3373,7 +3374,6 @@ MmMapViewOfSection(IN PVOID SectionObject, Section = (PSECTION_OBJECT)SectionObject; AddressSpace = &Process->AddressSpace; - MmLockAddressSpace(AddressSpace); MmLockSection(SectionObject); if (Section->AllocationAttributes & SEC_IMAGE) @@ -3382,6 +3382,8 @@ MmMapViewOfSection(IN PVOID SectionObject, PVOID ImageBase; ULONG ImageSize; + MmLockAddressSpace(AddressSpace); + ImageBase = *BaseAddress; if (ImageBase == NULL) { @@ -3448,10 +3450,38 @@ MmMapViewOfSection(IN PVOID SectionObject, } } } + *BaseAddress = ImageBase; + + MmUnlockAddressSpace(AddressSpace); + + /* + * Zero-fill the end of initialized data segments which are not completely + * present in the file + */ + for (i = 0; i < Section->NrSegments; i++) + { + if (IMAGE_SECTION_INITIALIZED_DATA == + (Section->Segments[i].Characteristics & + (IMAGE_SECTION_NOLOAD | IMAGE_SECTION_INITIALIZED_DATA)) && + Section->Segments[i].RawLength < Section->Segments[i].Length) + { + /* PsGetCurrentProcess() might not return our process at this moment, + * let's make sure our address space is being used anyway */ + KeAttachProcess(Process); + + RtlZeroMemory((PVOID) (ImageBase + (ULONG_PTR) Section->Segments[i].VirtualAddress) + + Section->Segments[i].RawLength, + Section->Segments[i].Length - Section->Segments[i].RawLength); + + KeDetachProcess(); + } + } } else { + MmLockAddressSpace(AddressSpace); + if (SectionOffset == NULL) { ViewOffset = 0; @@ -3487,16 +3517,16 @@ MmMapViewOfSection(IN PVOID SectionObject, Protect, ViewOffset); MmUnlockSectionSegment(Section->Segments); + MmUnlockAddressSpace(AddressSpace); if (!NT_SUCCESS(Status)) { MmUnlockSection(Section); - MmUnlockAddressSpace(AddressSpace); return(Status); } + } MmUnlockSection(Section); - MmUnlockAddressSpace(AddressSpace); return(STATUS_SUCCESS); } diff --git a/ntoskrnl/mm/virtual.c b/ntoskrnl/mm/virtual.c index ad02cb9..dece177 100644 --- a/ntoskrnl/mm/virtual.c +++ b/ntoskrnl/mm/virtual.c @@ -113,6 +113,7 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle, if (Length != sizeof(MEMORY_BASIC_INFORMATION)) { + MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); return(STATUS_INFO_LENGTH_MISMATCH); } diff --git a/ntoskrnl/nt/nttimer.c b/ntoskrnl/nt/nttimer.c index b2b3010..89d1edc 100644 --- a/ntoskrnl/nt/nttimer.c +++ b/ntoskrnl/nt/nttimer.c @@ -63,6 +63,25 @@ NtpCreateTimer(PVOID ObjectBody, } +VOID STDCALL +NtpDeleteTimer(PVOID ObjectBody) +{ + KIRQL OldIrql; + PNTTIMER Timer = ObjectBody; + + DPRINT("NtpDeleteTimer()\n"); + + OldIrql = KeRaiseIrqlToDpcLevel(); + + KeCancelTimer(&Timer->Timer); + KeRemoveQueueDpc(&Timer->Dpc); + KeRemoveQueueApc(&Timer->Apc); + Timer->Running = FALSE; + + KeLowerIrql(OldIrql); +} + + VOID NtpTimerDpcRoutine(PKDPC Dpc, PVOID DeferredContext, @@ -70,11 +89,11 @@ NtpTimerDpcRoutine(PKDPC Dpc, PVOID SystemArgument2) { PNTTIMER Timer; - + DPRINT("NtpTimerDpcRoutine()\n"); - + Timer = (PNTTIMER)DeferredContext; - + if ( Timer->Running ) { KeInsertQueueApc(&Timer->Apc, @@ -100,9 +119,9 @@ NtpTimerApcKernelRoutine(PKAPC Apc, VOID NtInitializeTimerImplementation(VOID) { ExTimerType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - + RtlCreateUnicodeString(&ExTimerType->TypeName, L"Timer"); - + ExTimerType->Tag = TAG('T', 'I', 'M', 'T'); ExTimerType->MaxObjects = ULONG_MAX; ExTimerType->MaxHandles = ULONG_MAX; @@ -114,7 +133,7 @@ VOID NtInitializeTimerImplementation(VOID) ExTimerType->Dump = NULL; ExTimerType->Open = NULL; ExTimerType->Close = NULL; - ExTimerType->Delete = NULL; + ExTimerType->Delete = NtpDeleteTimer; ExTimerType->Parse = NULL; ExTimerType->Security = NULL; ExTimerType->QueryName = NULL; @@ -142,22 +161,22 @@ NtCancelTimer(IN HANDLE TimerHandle, NULL); if (!NT_SUCCESS(Status)) return Status; - + OldIrql = KeRaiseIrqlToDpcLevel(); - + State = KeCancelTimer(&Timer->Timer); KeRemoveQueueDpc(&Timer->Dpc); KeRemoveQueueApc(&Timer->Apc); Timer->Running = FALSE; - + KeLowerIrql(OldIrql); ObDereferenceObject(Timer); - + if (CurrentState != NULL) { *CurrentState = State; } - + return STATUS_SUCCESS; } @@ -170,7 +189,7 @@ NtCreateTimer(OUT PHANDLE TimerHandle, { PNTTIMER Timer; NTSTATUS Status; - + DPRINT("NtCreateTimer()\n"); Status = ObCreateObject(TimerHandle, DesiredAccess, @@ -179,18 +198,18 @@ NtCreateTimer(OUT PHANDLE TimerHandle, (PVOID*)&Timer); if (!NT_SUCCESS(Status)) return Status; - + KeInitializeTimerEx(&Timer->Timer, TimerType); - + KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)NtpTimerDpcRoutine, (PVOID)Timer); - + Timer->Running = FALSE; - + ObDereferenceObject(Timer); - + return(STATUS_SUCCESS); } @@ -201,7 +220,7 @@ NtOpenTimer(OUT PHANDLE TimerHandle, IN POBJECT_ATTRIBUTES ObjectAttributes) { NTSTATUS Status; - + Status = ObOpenObjectByName(ObjectAttributes, ExTimerType, NULL, @@ -233,7 +252,7 @@ NtQueryTimer(IN HANDLE TimerHandle, NULL); if (!NT_SUCCESS(Status)) { - return(Status); + return(Status); } if (TimerInformationClass != TimerBasicInformation) @@ -246,12 +265,12 @@ NtQueryTimer(IN HANDLE TimerHandle, ObDereferenceObject(Timer); return(STATUS_INFO_LENGTH_MISMATCH); } - + memcpy(&TimerInformation.TimeRemaining, &Timer->Timer.DueTime, sizeof(LARGE_INTEGER)); TimerInformation.SignalState = Timer->Timer.Header.SignalState; ResultLength = sizeof(TIMER_BASIC_INFORMATION); - + Status = MmCopyToCaller(UnsafeTimerInformation, &TimerInformation, sizeof(TIMER_BASIC_INFORMATION)); if (!NT_SUCCESS(Status)) @@ -259,7 +278,7 @@ NtQueryTimer(IN HANDLE TimerHandle, ObDereferenceObject(Timer); return(Status); } - + if (UnsafeResultLength != NULL) { Status = MmCopyToCaller(UnsafeResultLength, &ResultLength, diff --git a/ntoskrnl/ntoskrnl.def b/ntoskrnl/ntoskrnl.def index 06a6c1c..d64b3c1 100644 --- a/ntoskrnl/ntoskrnl.def +++ b/ntoskrnl/ntoskrnl.def @@ -5,10 +5,8 @@ ; ReactOS Operating System ; EXPORTS -CcRosInitializeFileCache@12 -;CcRosRequestCacheSegment@20 -;CcRosReleaseCacheSegment@12 -CcRosReleaseFileCache@8 +CcRosInitializeFileCache@8 +CcRosReleaseFileCache@4 CcCopyRead@24 CcCopyWrite@20 CcFlushCache@16 @@ -414,6 +412,7 @@ KeQuerySystemTime@4 KeQueryTickCount@4 KeQueryTimeIncrement@0 ;KeRaiseUserException +KeRescheduleThread@0 KeReadStateEvent@4 KeReadStateMutant@4 KeReadStateMutex@4 @@ -435,7 +434,7 @@ KeResetEvent@4 KeRundownQueue@4 ;KeSaveFloatingPointState KeServiceDescriptorTable DATA -;KeSetAffinityThread +KeSetAffinityThread@8 KeSetBasePriorityThread@8 ;KeSetDmaIoCoherency KeSetEvent@12 @@ -637,10 +636,8 @@ PsCreateWin32Process@4 PsGetWin32Thread@0 PsGetWin32Process@0 PsEstablishWin32Callouts@24 -PsGetCurrentProcess@0 PsGetCurrentProcessId@0 PsGetCurrentThreadId@0 -PsGetCurrentThread@0 PsGetProcessExitTime@0 PsGetVersion@16 PsImpersonateClient@20 @@ -978,14 +975,14 @@ ZwWaitForSingleObject@12 ZwWriteFile@36 ZwYieldExecution@0 _abnormal_termination -_alldiv -_allmul -_allrem -_allshl -_allshr -_aulldiv -_aullrem -_aullshr +_alldiv@4 +_allmul@4 +_allrem@4 +_allshl@4 +_allshr@4 +_aulldiv@4 +_aullrem@4 +_aullshr@4 _except_handler2 _except_handler3 _global_unwind2 diff --git a/ntoskrnl/ntoskrnl.edf b/ntoskrnl/ntoskrnl.edf index 70f2831..abe6cfa 100644 --- a/ntoskrnl/ntoskrnl.edf +++ b/ntoskrnl/ntoskrnl.edf @@ -5,11 +5,9 @@ ; ReactOS Operating System ; EXPORTS -CcRosInitializeFileCache=CcRosInitializeFileCache@12 +CcRosInitializeFileCache=CcRosInitializeFileCache@8 CcMdlReadComplete=CcMdlReadComplete@8 -;CcRosRequestCacheSegment=CcRosRequestCacheSegment@20 -;CcRosReleaseCacheSegment=CcRosReleaseCacheSegment@12 -CcRosReleaseFileCache=CcRosReleaseFileCache@8 +CcRosReleaseFileCache=CcRosReleaseFileCache@4 CcCopyRead=CcCopyRead@24 CcCopyWrite=CcCopyWrite@20 CcFlushCache=CcFlushCache@16 @@ -413,6 +411,7 @@ KeQuerySystemTime=KeQuerySystemTime@4 KeQueryTickCount=KeQueryTickCount@4 KeQueryTimeIncrement=KeQueryTimeIncrement@0 ;KeRaiseUserException +KeRescheduleThread=KeRescheduleThread@0 KeReadStateEvent=KeReadStateEvent@4 KeReadStateMutant=KeReadStateMutant@4 KeReadStateMutex=KeReadStateMutex@4 @@ -434,7 +433,7 @@ KeResetEvent=KeResetEvent@4 KeRundownQueue=KeRundownQueue@4 ;KeSaveFloatingPointState KeServiceDescriptorTable DATA -;KeSetAffinityThread +KeSetAffinityThread@8 KeSetBasePriorityThread=KeSetBasePriorityThread@8 ;KeSetDmaIoCoherency KeSetEvent=KeSetEvent@12 @@ -636,10 +635,8 @@ PsCreateWin32Process=PsCreateWin32Process@4 PsGetWin32Thread=PsGetWin32Thread@0 PsGetWin32Process=PsGetWin32Process@0 PsEstablishWin32Callouts=PsEstablishWin32Callouts@24 -PsGetCurrentProcess=PsGetCurrentProcess@0 PsGetCurrentProcessId=PsGetCurrentProcessId@0 PsGetCurrentThreadId=PsGetCurrentThreadId@0 -PsGetCurrentThread=PsGetCurrentThread@0 PsGetProcessExitTime=PsGetProcessExitTime@0 PsGetVersion=PsGetVersion@16 PsImpersonateClient=PsImpersonateClient@20 @@ -976,14 +973,14 @@ ZwWaitForSingleObject=ZwWaitForSingleObject@12 ZwWriteFile=ZwWriteFile@36 ZwYieldExecution=ZwYieldExecution@0 _abnormal_termination -_alldiv -_allmul -_allrem -_allshl -_allshr -_aulldiv -_aullrem -_aullshr +_alldiv=_alldiv@4 +_allmul=_allmul@4 +_allrem=_allrem@4 +_allshl=_allshl@4 +_allshr=_allshr@4 +_aulldiv=_aulldiv@4 +_aullrem=_aullrem@4 +_aullshr=_aullshr@4 _except_handler2 _except_handler3 _global_unwind2 diff --git a/ntoskrnl/ob/handle.c b/ntoskrnl/ob/handle.c index c005f74..c7ee41d 100644 --- a/ntoskrnl/ob/handle.c +++ b/ntoskrnl/ob/handle.c @@ -217,40 +217,60 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle, ObDereferenceObject(SourceProcess); return(Status); } - KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql); - SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable, - SourceHandle); - if (SourceHandleRep == NULL) - { - KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); - ObDereferenceObject(SourceProcess); - ObDereferenceObject(TargetProcess); - return(STATUS_INVALID_HANDLE); - } - ObjectBody = SourceHandleRep->ObjectBody; - ObReferenceObjectByPointer(ObjectBody, - 0, - NULL, - UserMode); - - if (Options & DUPLICATE_SAME_ACCESS) + + /* Check for magic handle first */ + if (SourceHandle == NtCurrentThread()) { - DesiredAccess = SourceHandleRep->GrantedAccess; + ObReferenceObjectByHandle(SourceHandle, + PROCESS_DUP_HANDLE, + NULL, + UserMode, + &ObjectBody, + NULL); + + ObCreateHandle(TargetProcess, + ObjectBody, + THREAD_ALL_ACCESS, + InheritHandle, + &TargetHandle); } - - KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); - if (!SourceHandleRep->Inherit) + else { - ObDereferenceObject(TargetProcess); - ObDereferenceObject(SourceProcess); - ObDereferenceObject(ObjectBody); - return STATUS_INVALID_HANDLE; + KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql); + SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable, + SourceHandle); + if (SourceHandleRep == NULL) + { + KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); + ObDereferenceObject(SourceProcess); + ObDereferenceObject(TargetProcess); + return(STATUS_INVALID_HANDLE); + } + ObjectBody = SourceHandleRep->ObjectBody; + ObReferenceObjectByPointer(ObjectBody, + 0, + NULL, + UserMode); + + if (Options & DUPLICATE_SAME_ACCESS) + { + DesiredAccess = SourceHandleRep->GrantedAccess; + } + + KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql); + if (!SourceHandleRep->Inherit) + { + ObDereferenceObject(TargetProcess); + ObDereferenceObject(SourceProcess); + ObDereferenceObject(ObjectBody); + return STATUS_INVALID_HANDLE; + } + ObCreateHandle(TargetProcess, + ObjectBody, + DesiredAccess, + InheritHandle, + &TargetHandle); } - ObCreateHandle(TargetProcess, - ObjectBody, - DesiredAccess, - InheritHandle, - &TargetHandle); if (Options & DUPLICATE_CLOSE_SOURCE) { @@ -687,7 +707,7 @@ ObReferenceObjectByHandle(HANDLE Handle, DPRINT("Reference from %x\n", ((PULONG)&Handle)[-1]); } - if (AccessMode == UserMode) + if (DesiredAccess && AccessMode == UserMode) { RtlMapGenericMask(&DesiredAccess, ObjectHeader->ObjectType->Mapping); diff --git a/ntoskrnl/ob/namespc.c b/ntoskrnl/ob/namespc.c index ecfc3e5..0800e34 100644 --- a/ntoskrnl/ob/namespc.c +++ b/ntoskrnl/ob/namespc.c @@ -411,6 +411,9 @@ ObInit(VOID) ObpCreateTypeObject(ObDirectoryType); ObpCreateTypeObject(ObTypeObjectType); + + /* Create 'symbolic link' object type */ + ObInitSymbolicLinkImplementation(); } diff --git a/ntoskrnl/ob/object.c b/ntoskrnl/ob/object.c index 383a25f..52d9ba0 100644 --- a/ntoskrnl/ob/object.c +++ b/ntoskrnl/ob/object.c @@ -17,7 +17,6 @@ #include #include #include -#include #define NDEBUG #include @@ -170,7 +169,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, RootObject = CurrentObject; Attributes = ObjectAttributes->Attributes; - if (ObjectType == IoSymbolicLinkType) + if (ObjectType == ObSymbolicLinkType) Attributes |= OBJ_OPENLINK; while (TRUE) diff --git a/ntoskrnl/ob/security.c b/ntoskrnl/ob/security.c index cef5182..cf80294 100644 --- a/ntoskrnl/ob/security.c +++ b/ntoskrnl/ob/security.c @@ -45,44 +45,46 @@ ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, NTSTATUS STDCALL -NtQuerySecurityObject(IN HANDLE ObjectHandle, - IN CINT SecurityObjectInformationClass, - OUT PVOID SecurityObjectInformation, +NtQuerySecurityObject(IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Length, - OUT PULONG ReturnLength) + OUT PULONG ResultLength) { - NTSTATUS Status; - PVOID Object; - OBJECT_HANDLE_INFORMATION HandleInfo; - POBJECT_HEADER Header; - - Status = ObReferenceObjectByHandle(ObjectHandle, - 0, - NULL, - KeGetPreviousMode(), - &Object, - &HandleInfo); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Header = BODY_TO_HEADER(Object); - if (Header->ObjectType != NULL && - Header->ObjectType->Security != NULL) - { - Status = Header->ObjectType->Security(Object, - SecurityObjectInformationClass, - SecurityObjectInformation, - &Length); - *ReturnLength = Length; - } - else - { - Status = STATUS_NOT_IMPLEMENTED; - } - ObDereferenceObject(Object); - return(Status); + POBJECT_HEADER Header; + PVOID Object; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(Handle, + 0, + NULL, + KeGetPreviousMode(), + &Object, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Header = BODY_TO_HEADER(Object); + if (Header->ObjectType != NULL && + Header->ObjectType->Security != NULL) + { + Status = Header->ObjectType->Security(Object, + QuerySecurityDescriptor, + SecurityInformation, + SecurityDescriptor, + &Length); + *ResultLength = Length; + } + else + { + Status = STATUS_NOT_IMPLEMENTED; + } + + ObDereferenceObject(Object); + + return(Status); } @@ -91,7 +93,39 @@ NtSetSecurityObject(IN HANDLE Handle, IN SECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; + POBJECT_HEADER Header; + PVOID Object; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(Handle, + 0, + NULL, + KeGetPreviousMode(), + &Object, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Header = BODY_TO_HEADER(Object); + if (Header->ObjectType != NULL && + Header->ObjectType->Security != NULL) + { + Status = Header->ObjectType->Security(Object, + SetSecurityDescriptor, + SecurityInformation, + SecurityDescriptor, + NULL); + } + else + { + Status = STATUS_NOT_IMPLEMENTED; + } + + ObDereferenceObject(Object); + + return(Status); } /* EOF */ diff --git a/ntoskrnl/ob/symlink.c b/ntoskrnl/ob/symlink.c new file mode 100644 index 0000000..83cf74f --- /dev/null +++ b/ntoskrnl/ob/symlink.c @@ -0,0 +1,339 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ob/symlink.c + * PURPOSE: Implements symbolic links + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +typedef struct +{ + CSHORT Type; + CSHORT Size; + UNICODE_STRING TargetName; + OBJECT_ATTRIBUTES Target; +} SYMLNK_OBJECT, *PSYMLNK_OBJECT; + +POBJECT_TYPE ObSymbolicLinkType = NULL; + +static GENERIC_MAPPING ObpSymbolicLinkMapping = { + STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY, + STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY, + SYMBOLIC_LINK_ALL_ACCESS}; + +#define TAG_SYMLINK_TTARGET TAG('S', 'Y', 'T', 'T') +#define TAG_SYMLINK_TARGET TAG('S', 'Y', 'M', 'T') + +/* FUNCTIONS ****************************************************************/ + + +/********************************************************************** + * NAME INTERNAL + * ObpCreateSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURNN VALUE + * Status. + * + * REVISIONS + */ +NTSTATUS STDCALL +ObpCreateSymbolicLink(PVOID Object, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + return(STATUS_SUCCESS); +} + + +/********************************************************************** + * NAME INTERNAL + * ObpDeleteSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURNN VALUE + * Status. + * + * REVISIONS + */ +VOID STDCALL +ObpDeleteSymbolicLink(PVOID ObjectBody) +{ + PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT)ObjectBody; + + RtlFreeUnicodeString(&SymlinkObject->TargetName); +} + + +/********************************************************************** + * NAME INTERNAL + * ObpParseSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + */ +NTSTATUS STDCALL +ObpParseSymbolicLink(PVOID Object, + PVOID * NextObject, + PUNICODE_STRING FullPath, + PWSTR * RemainingPath, + ULONG Attributes) +{ + PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object; + UNICODE_STRING TargetPath; + + DPRINT("ObpParseSymbolicLink (RemainingPath %S)\n", *RemainingPath); + + /* + * Stop parsing if the entire path has been parsed and + * the desired object is a symbolic link object. + */ + if (((*RemainingPath == NULL) || (**RemainingPath == 0)) && + (Attributes & OBJ_OPENLINK)) + { + DPRINT("Parsing stopped!\n"); + *NextObject = NULL; + return(STATUS_SUCCESS); + } + + /* build the expanded path */ + TargetPath.MaximumLength = SymlinkObject->TargetName.Length + sizeof(WCHAR); + if (RemainingPath && *RemainingPath) + { + TargetPath.MaximumLength += (wcslen(*RemainingPath) * sizeof(WCHAR)); + } + TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); + TargetPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, + TargetPath.MaximumLength, + TAG_SYMLINK_TTARGET); + wcscpy(TargetPath.Buffer, SymlinkObject->TargetName.Buffer); + if (RemainingPath && *RemainingPath) + { + wcscat(TargetPath.Buffer, *RemainingPath); + } + + /* transfer target path buffer into FullPath */ + RtlFreeUnicodeString(FullPath); + FullPath->Length = TargetPath.Length; + FullPath->MaximumLength = TargetPath.MaximumLength; + FullPath->Buffer = TargetPath.Buffer; + + /* reinitialize RemainingPath for reparsing */ + *RemainingPath = FullPath->Buffer; + + *NextObject = NULL; + return STATUS_REPARSE; +} + + +/********************************************************************** + * NAME INTERNAL + * ObInitSymbolicLinkImplementation + * + * DESCRIPTION + * + * ARGUMENTS + * None. + * + * RETURNN VALUE + * None. + * + * REVISIONS + */ +VOID ObInitSymbolicLinkImplementation (VOID) +{ + ObSymbolicLinkType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + + ObSymbolicLinkType->Tag = TAG('S', 'Y', 'M', 'T'); + ObSymbolicLinkType->TotalObjects = 0; + ObSymbolicLinkType->TotalHandles = 0; + ObSymbolicLinkType->MaxObjects = ULONG_MAX; + ObSymbolicLinkType->MaxHandles = ULONG_MAX; + ObSymbolicLinkType->PagedPoolCharge = 0; + ObSymbolicLinkType->NonpagedPoolCharge = sizeof(SYMLNK_OBJECT); + ObSymbolicLinkType->Mapping = &ObpSymbolicLinkMapping; + ObSymbolicLinkType->Dump = NULL; + ObSymbolicLinkType->Open = NULL; + ObSymbolicLinkType->Close = NULL; + ObSymbolicLinkType->Delete = ObpDeleteSymbolicLink; + ObSymbolicLinkType->Parse = ObpParseSymbolicLink; + ObSymbolicLinkType->Security = NULL; + ObSymbolicLinkType->QueryName = NULL; + ObSymbolicLinkType->OkayToClose = NULL; + ObSymbolicLinkType->Create = ObpCreateSymbolicLink; + ObSymbolicLinkType->DuplicationNotify = NULL; + + RtlInitUnicodeStringFromLiteral(&ObSymbolicLinkType->TypeName, + L"SymbolicLink"); + + ObpCreateTypeObject(ObSymbolicLinkType); +} + + +/********************************************************************** + * NAME EXPORTED + * NtCreateSymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PUNICODE_STRING DeviceName) +{ + PSYMLNK_OBJECT SymbolicLink; + NTSTATUS Status; + + assert_irql(PASSIVE_LEVEL); + + DPRINT("NtCreateSymbolicLinkObject(SymbolicLinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, DeviceName %wZ)\n", + SymbolicLinkHandle, + DesiredAccess, + ObjectAttributes, + DeviceName); + + Status = ObCreateObject(SymbolicLinkHandle, + DesiredAccess, + ObjectAttributes, + ObSymbolicLinkType, + (PVOID*)&SymbolicLink); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + SymbolicLink->TargetName.Length = 0; + SymbolicLink->TargetName.MaximumLength = + ((wcslen(DeviceName->Buffer) + 1) * sizeof(WCHAR)); + SymbolicLink->TargetName.Buffer = + ExAllocatePoolWithTag(NonPagedPool, + SymbolicLink->TargetName.MaximumLength, + TAG_SYMLINK_TARGET); + RtlCopyUnicodeString(&SymbolicLink->TargetName, + DeviceName); + + DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); + + InitializeObjectAttributes(&SymbolicLink->Target, + &SymbolicLink->TargetName, + 0, + NULL, + NULL); + + DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__); + ObDereferenceObject(SymbolicLink); + + return(STATUS_SUCCESS); +} + + +/********************************************************************** + * NAME EXPORTED + * NtOpenSymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n", + ObjectAttributes->ObjectName); + + return(ObOpenObjectByName(ObjectAttributes, + ObSymbolicLinkType, + NULL, + KeGetPreviousMode(), + DesiredAccess, + NULL, + LinkHandle)); +} + + +/********************************************************************** + * NAME EXPORTED + * NtQuerySymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, + IN OUT PUNICODE_STRING LinkTarget, + OUT PULONG ReturnedLength OPTIONAL) +{ + PSYMLNK_OBJECT SymlinkObject; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(LinkHandle, + SYMBOLIC_LINK_QUERY, + ObSymbolicLinkType, + KeGetPreviousMode(), + (PVOID *)&SymlinkObject, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + RtlCopyUnicodeString(LinkTarget, + SymlinkObject->Target.ObjectName); + if (ReturnedLength != NULL) + { + *ReturnedLength = SymlinkObject->Target.Length; + } + ObDereferenceObject(SymlinkObject); + + return(STATUS_SUCCESS); +} + +/* EOF */ diff --git a/ntoskrnl/ps/create.c b/ntoskrnl/ps/create.c index 72fa987..f46d564 100644 --- a/ntoskrnl/ps/create.c +++ b/ntoskrnl/ps/create.c @@ -269,7 +269,6 @@ PsReferenceImpersonationToken(PETHREAD Thread, VOID PiBeforeBeginThread(CONTEXT c) { - DPRINT("PiBeforeBeginThread(Eip %x)\n", c.Eip); KeLowerIrql(PASSIVE_LEVEL); } @@ -370,7 +369,7 @@ PsInitializeThread(HANDLE ProcessHandle, KeInitializeSpinLock(&Thread->ActiveTimerListLock); InitializeListHead(&Thread->IrpList); Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement( - &PiNextThreadUniqueId); + (LONG *)&PiNextThreadUniqueId); Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; Thread->DeadThread = 0; Thread->Win32Thread = 0; @@ -400,7 +399,7 @@ static NTSTATUS PsCreateTeb(HANDLE ProcessHandle, PTEB *TebPtr, PETHREAD Thread, - PINITIAL_TEB InitialTeb) + PUSER_STACK UserStack) { MEMORY_BASIC_INFORMATION Info; NTSTATUS Status; @@ -448,6 +447,7 @@ PsCreateTeb(HANDLE ProcessHandle, DPRINT ("TebBase %p TebSize %lu\n", TebBase, TebSize); + RtlZeroMemory(&Teb, sizeof(TEB)); /* set all pointers to and from the TEB */ Teb.Tib.Self = TebBase; if (Thread->ThreadsProcess) @@ -456,13 +456,24 @@ PsCreateTeb(HANDLE ProcessHandle, } DPRINT("Teb.Peb %x\n", Teb.Peb); - /* store stack information from InitialTeb */ - if (InitialTeb != NULL) - { - Teb.Tib.StackBase = InitialTeb->StackBase; - Teb.Tib.StackLimit = InitialTeb->StackLimit; - Teb.DeallocationStack = InitialTeb->StackAllocate; - } + /* store stack information from UserStack */ + if(UserStack != NULL) + { + /* fixed-size stack */ + if(UserStack->FixedStackBase && UserStack->FixedStackLimit) + { + Teb.Tib.StackBase = UserStack->FixedStackBase; + Teb.Tib.StackLimit = UserStack->FixedStackLimit; + Teb.DeallocationStack = UserStack->FixedStackLimit; + } + /* expandable stack */ + else + { + Teb.Tib.StackBase = UserStack->ExpandableStackBase; + Teb.Tib.StackLimit = UserStack->ExpandableStackLimit; + Teb.DeallocationStack = UserStack->ExpandableStackBottom; + } + } /* more initialization */ Teb.Cid.UniqueThread = Thread->Cid.UniqueThread; @@ -528,7 +539,7 @@ NtCreateThread(PHANDLE ThreadHandle, HANDLE ProcessHandle, PCLIENT_ID Client, PCONTEXT ThreadContext, - PINITIAL_TEB InitialTeb, + PUSER_STACK UserStack, BOOLEAN CreateSuspended) { PETHREAD Thread; @@ -559,7 +570,7 @@ NtCreateThread(PHANDLE ThreadHandle, Status = PsCreateTeb(ProcessHandle, &TebBase, Thread, - InitialTeb); + UserStack); if (!NT_SUCCESS(Status)) { return(Status); diff --git a/ntoskrnl/ps/process.c b/ntoskrnl/ps/process.c index 7b64e18..127f79f 100644 --- a/ntoskrnl/ps/process.c +++ b/ntoskrnl/ps/process.c @@ -257,7 +257,7 @@ PsInitProcessManagment(VOID) KProcess->DirectoryTableBase = (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory(); PsInitialSystemProcess->UniqueProcessId = - InterlockedIncrement(&PiNextProcessUniqueId); + InterlockedIncrement((LONG *)&PiNextProcessUniqueId); PsInitialSystemProcess->Win32WindowStation = (HANDLE)0; PsInitialSystemProcess->Win32Desktop = (HANDLE)0; @@ -368,7 +368,7 @@ PsGetCurrentProcessId(VOID) * FUNCTION: Returns a pointer to the current process */ PEPROCESS STDCALL -PsGetCurrentProcess(VOID) +IoGetCurrentProcess(VOID) { if (PsGetCurrentThread() == NULL || PsGetCurrentThread()->ThreadsProcess == NULL) @@ -381,12 +381,6 @@ PsGetCurrentProcess(VOID) } } -PEPROCESS STDCALL -IoGetCurrentProcess(VOID) -{ - return(PsGetCurrentProcess()); -} - NTSTATUS STDCALL PsCreateSystemProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, @@ -483,7 +477,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, KProcess->BasePriority = PROCESS_PRIO_NORMAL; MmInitializeAddressSpace(Process, &Process->AddressSpace); - Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId); + Process->UniqueProcessId = InterlockedIncrement((LONG *)&PiNextProcessUniqueId); Process->InheritedFromUniqueProcessId = (HANDLE)ParentProcess->UniqueProcessId; ObCreateHandleTable(ParentProcess, @@ -1220,6 +1214,7 @@ PsLookupProcessByProcessId(IN PVOID ProcessId, if (current->UniqueProcessId == (ULONG)ProcessId) { *Process = current; + ObReferenceObject(current); KeReleaseSpinLock(&PsProcessListLock, oldIrql); return(STATUS_SUCCESS); } diff --git a/ntoskrnl/ps/thread.c b/ntoskrnl/ps/thread.c index c4da6f3..35d772e 100644 --- a/ntoskrnl/ps/thread.c +++ b/ntoskrnl/ps/thread.c @@ -66,12 +66,6 @@ PKTHREAD STDCALL KeGetCurrentThread(VOID) return(KeGetCurrentKPCR()->CurrentThread); } -PETHREAD STDCALL PsGetCurrentThread(VOID) -{ - PKTHREAD CurrentThread = KeGetCurrentKPCR()->CurrentThread; - return(CONTAINING_RECORD(CurrentThread, ETHREAD, Tcb)); -} - HANDLE STDCALL PsGetCurrentThreadId(VOID) { return(PsGetCurrentThread()->Cid.UniqueThread); @@ -286,7 +280,7 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus) VOID PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, - BOOLEAN DispatcherLock, KIRQL WaitIrql) + BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason) { KIRQL oldIrql; PKTHREAD KThread = KeGetCurrentKPCR()->CurrentThread; @@ -324,7 +318,9 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, Thread->Tcb.Alertable = Alertable; Thread->Tcb.WaitMode = WaitMode; Thread->Tcb.WaitIrql = WaitIrql; + Thread->Tcb.WaitReason = WaitReason; PsDispatchThreadNoLock(THREAD_STATE_BLOCKED); + if (Status != NULL) { *Status = Thread->Tcb.WaitStatus; @@ -508,6 +504,18 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) return(OldPriority); } +NTSTATUS STDCALL +KeSetAffinityThread(PKTHREAD Thread, + PVOID AfMask) +/* + * Sets thread's affinity + */ +{ + DPRINT1("KeSetAffinityThread() is a stub returning STATUS_SUCCESS"); + return STATUS_SUCCESS; // FIXME: Use function below + //return ZwSetInformationThread(handle, ThreadAffinityMask,,sizeof(KAFFINITY)); +} + NTSTATUS STDCALL NtAlertResumeThread(IN HANDLE ThreadHandle, @@ -601,8 +609,14 @@ PsLookupProcessThreadByCid(IN PCLIENT_ID Cid, current->Cid.UniqueProcess == Cid->UniqueProcess) { if (Process != NULL) + { *Process = current->ThreadsProcess; + ObReferenceObject(current->ThreadsProcess); + } + *Thread = current; + ObReferenceObject(current); + KeReleaseSpinLock(&PiThreadListLock, oldIrql); return(STATUS_SUCCESS); } @@ -635,6 +649,7 @@ PsLookupThreadByThreadId(IN PVOID ThreadId, if (current->Cid.UniqueThread == (HANDLE)ThreadId) { *Thread = current; + ObReferenceObject(current); KeReleaseSpinLock(&PiThreadListLock, oldIrql); return(STATUS_SUCCESS); } diff --git a/ntoskrnl/ps/tinfo.c b/ntoskrnl/ps/tinfo.c index 63463e2..62675f6 100644 --- a/ntoskrnl/ps/tinfo.c +++ b/ntoskrnl/ps/tinfo.c @@ -13,6 +13,7 @@ #include #include +#include #include @@ -71,7 +72,14 @@ NtSetInformationThread(HANDLE ThreadHandle, } case ThreadBasePriority: - Status = STATUS_NOT_IMPLEMENTED; + if (ThreadInformationLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + Status = MmCopyFromCaller(&(Thread->Tcb.BasePriority), + ThreadInformation, + sizeof(ULONG)); break; case ThreadAffinityMask: diff --git a/ntoskrnl/rtl/i386/exception.c b/ntoskrnl/rtl/i386/exception.c index 6cec442..f145840 100755 --- a/ntoskrnl/rtl/i386/exception.c +++ b/ntoskrnl/rtl/i386/exception.c @@ -321,11 +321,12 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, DPRINT("ERHead is 0x%X\n", ERHead); + pExceptRec = &TempER; + if (ExceptionRecord == NULL) // The normal case { - DPRINT("ExceptionRecord == NULL (normal)\n"); + DPRINT("ExceptionRecord == NULL (normal)\n"); - pExceptRec = &TempER; pExceptRec->ExceptionFlags = 0; pExceptRec->ExceptionCode = STATUS_UNWIND; pExceptRec->ExceptionRecord = NULL; @@ -342,11 +343,11 @@ RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame, DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags); if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING) { - DPRINT(" * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING); + DPRINT(" * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING); } if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND) { - DPRINT(" * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND); + DPRINT(" * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND); } #endif /* NDEBUG */ diff --git a/ntoskrnl/se/acl.c b/ntoskrnl/se/acl.c index bd24958..dd4ca43 100644 --- a/ntoskrnl/se/acl.c +++ b/ntoskrnl/se/acl.c @@ -134,41 +134,45 @@ BOOLEAN STDCALL RtlFirstFreeAce(PACL Acl, PACE* Ace) { - PACE Current; - PVOID AclEnd; - ULONG i; + PACE Current; + PVOID AclEnd; + ULONG i; + + Current = (PACE)(Acl + 1); + *Ace = NULL; + i = 0; + if (Acl->AceCount == 0) + { + *Ace = Current; + return(TRUE); + } - Current = (PACE)(Acl + 1); - *Ace = NULL; - i = 0; - if (Acl->AceCount == 0) - { - *Ace = Current; - return(TRUE); - } - AclEnd = Acl->AclSize + Acl; - do - { - if ((PVOID)Current >= AclEnd) - { - return(FALSE); - } - if (Current->Header.AceType == 4) - { - if (Acl->AclRevision < 3) - { - return(FALSE); - } - } - Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize); - i++; - } while (i < Acl->AceCount); - if ((PVOID)Current >= AclEnd) - { - return(FALSE); - } - *Ace = Current; - return(TRUE); + AclEnd = Acl->AclSize + (PVOID)Acl; + do + { + if ((PVOID)Current >= AclEnd) + { + return(FALSE); + } + + if (Current->Header.AceType == 4) + { + if (Acl->AclRevision < 3) + { + return(FALSE); + } + } + Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize); + i++; + } + while (i < Acl->AceCount); + + if ((PVOID)Current < AclEnd) + { + *Ace = Current; + } + + return(TRUE); } @@ -322,4 +326,27 @@ RtlCreateAcl(PACL Acl, return(STATUS_SUCCESS); } + +BOOLEAN STDCALL +RtlValidAcl(PACL Acl) +{ + PACE Ace; + USHORT Size; + + Size = (Acl->AclSize + 3) & ~3; + + if (Acl->AclRevision != 2 && + Acl->AclRevision != 3) + { + return(FALSE); + } + + if (Size != Acl->AclSize) + { + return(FALSE); + } + + return(RtlFirstFreeAce(Acl, &Ace)); +} + /* EOF */ diff --git a/ntoskrnl/se/sd.c b/ntoskrnl/se/sd.c index 463fba2..86930db 100644 --- a/ntoskrnl/se/sd.c +++ b/ntoskrnl/se/sd.c @@ -16,12 +16,98 @@ #include +/* GLOBALS ******************************************************************/ + +PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL; +PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL; +PSECURITY_DESCRIPTOR SePublicOpenSd = NULL; +PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL; +PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL; +PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL; /* FUNCTIONS ***************************************************************/ BOOLEAN SepInitSDs(VOID) { + /* Create PublicDefaultSd */ + SePublicDefaultSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SePublicDefaultSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SePublicDefaultSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicDefaultSd, + TRUE, + SePublicDefaultDacl, + FALSE); + + /* Create PublicDefaultUnrestrictedSd */ + SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SePublicDefaultUnrestrictedSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, + TRUE, + SePublicDefaultUnrestrictedDacl, + FALSE); + + /* Create PublicOpenSd */ + SePublicOpenSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SePublicOpenSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SePublicOpenSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicOpenSd, + TRUE, + SePublicOpenDacl, + FALSE); + + /* Create PublicOpenUnrestrictedSd */ + SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SePublicOpenUnrestrictedSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, + TRUE, + SePublicOpenUnrestrictedDacl, + FALSE); + + /* Create SystemDefaultSd */ + SeSystemDefaultSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SeSystemDefaultSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SeSystemDefaultSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, + TRUE, + SeSystemDefaultDacl, + FALSE); + + /* Create UnrestrictedSd */ + SeUnrestrictedSd = ExAllocatePool(NonPagedPool, + sizeof(SECURITY_DESCRIPTOR)); + if (SeUnrestrictedSd == NULL) + return(FALSE); + + RtlCreateSecurityDescriptor(SeUnrestrictedSd, + SECURITY_DESCRIPTOR_REVISION); + RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, + TRUE, + SeUnrestrictedDacl, + FALSE); + return(TRUE); } @@ -30,10 +116,10 @@ NTSTATUS STDCALL RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG Revision) { - if (Revision != 1) + if (Revision != SECURITY_DESCRIPTOR_REVISION) return(STATUS_UNSUCCESSFUL); - SecurityDescriptor->Revision = 1; + SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION; SecurityDescriptor->Sbz1 = 0; SecurityDescriptor->Control = 0; SecurityDescriptor->Owner = NULL; @@ -44,59 +130,64 @@ RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, return(STATUS_SUCCESS); } + ULONG STDCALL RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) { - PSID Owner; - PSID Group; - ULONG Length; - PACL Dacl; - PACL Sacl; - - Length = sizeof(SECURITY_DESCRIPTOR); - - if (SecurityDescriptor->Owner != NULL) - { - Owner = SecurityDescriptor->Owner; - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - Owner = (PSID)((ULONG)Owner + - (ULONG)SecurityDescriptor); - } - Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * - sizeof(ULONG) + 3) & 0xfc); - } - if (SecurityDescriptor->Group != NULL) - { - Group = SecurityDescriptor->Group; - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor); - } - Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) * - sizeof(ULONG) + 3) & 0xfc); - } - if (SecurityDescriptor->Control & SE_DACL_PRESENT && - SecurityDescriptor->Dacl != NULL) - { - Dacl = SecurityDescriptor->Dacl; - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor); - } - Length = Length + ((Dacl->AclSize + 3) & 0xfc); - } - if (SecurityDescriptor->Control & SE_SACL_PRESENT && - SecurityDescriptor->Sacl != NULL) - { - Sacl = SecurityDescriptor->Sacl; - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor); - } - Length = Length + ((Sacl->AclSize + 3) & 0xfc); - } - return(Length); + PSID Owner; + PSID Group; + ULONG Length; + PACL Dacl; + PACL Sacl; + + Length = sizeof(SECURITY_DESCRIPTOR); + + if (SecurityDescriptor->Owner != NULL) + { + Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Owner = (PSID)((ULONG)Owner + + (ULONG)SecurityDescriptor); + } + Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * + sizeof(ULONG) + 3) & 0xfc); + } + + if (SecurityDescriptor->Group != NULL) + { + Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor); + } + Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) * + sizeof(ULONG) + 3) & 0xfc); + } + + if (SecurityDescriptor->Control & SE_DACL_PRESENT && + SecurityDescriptor->Dacl != NULL) + { + Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor); + } + Length = Length + ((Dacl->AclSize + 3) & 0xfc); + } + + if (SecurityDescriptor->Control & SE_SACL_PRESENT && + SecurityDescriptor->Sacl != NULL) + { + Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor); + } + Length = Length + ((Sacl->AclSize + 3) & 0xfc); + } + + return(Length); } @@ -106,41 +197,45 @@ RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PACL* Dacl, PBOOLEAN DaclDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (!(SecurityDescriptor->Control & SE_DACL_PRESENT)) - { - *DaclPresent = 0; - return(STATUS_SUCCESS); - } - *DaclPresent = 1; - if (SecurityDescriptor->Dacl == NULL) - { - *Dacl = NULL; - } - else - { - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl + - (PVOID)SecurityDescriptor); - } - else - { - *Dacl = SecurityDescriptor->Dacl; - } - } - if (SecurityDescriptor->Control & SE_DACL_DEFAULTED) - { - *DaclDefaulted = 1; - } - else - { - *DaclDefaulted = 0; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (!(SecurityDescriptor->Control & SE_DACL_PRESENT)) + { + *DaclPresent = FALSE; + return(STATUS_SUCCESS); + } + *DaclPresent = TRUE; + + if (SecurityDescriptor->Dacl == NULL) + { + *Dacl = NULL; + } + else + { + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl + + (PVOID)SecurityDescriptor); + } + else + { + *Dacl = SecurityDescriptor->Dacl; + } + } + + if (SecurityDescriptor->Control & SE_DACL_DEFAULTED) + { + *DaclDefaulted = TRUE; + } + else + { + *DaclDefaulted = FALSE; + } + + return(STATUS_SUCCESS); } @@ -150,34 +245,101 @@ RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PACL Dacl, BOOLEAN DaclDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - return(STATUS_UNSUCCESSFUL); - } - if (!DaclPresent) - { - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT); - return(STATUS_SUCCESS); - } - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT; - SecurityDescriptor->Dacl = Dacl; - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED); - if (DaclDefaulted) - { - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + return(STATUS_UNSUCCESSFUL); + } + + if (!DaclPresent) + { + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT); + return(STATUS_SUCCESS); + } + + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT; + SecurityDescriptor->Dacl = Dacl; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED); + + if (DaclDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED; + } + + return(STATUS_SUCCESS); } BOOLEAN STDCALL RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor) { - UNIMPLEMENTED; + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; + + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(FALSE); + } + + Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor); + } + + if (!RtlValidSid(Owner)) + { + return(FALSE); + } + + Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor); + } + + if (!RtlValidSid(Group)) + { + return(FALSE); + } + + if (SecurityDescriptor->Control & SE_DACL_PRESENT && + SecurityDescriptor->Dacl != NULL) + { + Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor); + } + + if (!RtlValidAcl(Dacl)) + { + return(FALSE); + } + } + + if (SecurityDescriptor->Control & SE_SACL_PRESENT && + SecurityDescriptor->Sacl != NULL) + { + Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor); + } + + if (!RtlValidAcl(Sacl)) + { + return(FALSE); + } + } + + return(TRUE); } @@ -186,21 +348,25 @@ RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID Owner, BOOLEAN OwnerDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - return(STATUS_UNSUCCESSFUL); - } - SecurityDescriptor->Owner = Owner; - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED); - if (OwnerDefaulted) - { - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + return(STATUS_UNSUCCESSFUL); + } + + SecurityDescriptor->Owner = Owner; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED); + + if (OwnerDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED; + } + + return(STATUS_SUCCESS); } @@ -209,12 +375,13 @@ RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID* Owner, PBOOLEAN OwnerDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Owner != NULL) - { + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (SecurityDescriptor->Owner != NULL) + { if (SecurityDescriptor->Control & SE_SELF_RELATIVE) { *Owner = (PSID)((ULONG)SecurityDescriptor->Owner + @@ -224,11 +391,11 @@ RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, { *Owner = SecurityDescriptor->Owner; } - } - else - { + } + else + { *Owner = NULL; - } + } if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED) { *OwnerDefaulted = 1; @@ -246,21 +413,25 @@ RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID Group, BOOLEAN GroupDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - return(STATUS_UNSUCCESSFUL); - } - SecurityDescriptor->Group = Group; - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED); - if (GroupDefaulted) - { - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + return(STATUS_UNSUCCESSFUL); + } + + SecurityDescriptor->Group = Group; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED); + + if (GroupDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED; + } + + return(STATUS_SUCCESS); } @@ -269,35 +440,38 @@ RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID* Group, PBOOLEAN GroupDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Group != NULL) - { - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - *Group = (PSID)((ULONG)SecurityDescriptor->Group + - (PVOID)SecurityDescriptor); - } - else - { - *Group = SecurityDescriptor->Group; - } - } - else - { - *Group = NULL; - } - if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED) - { - *GroupDefaulted = 1; - } - else - { - *GroupDefaulted = 0; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (SecurityDescriptor->Group != NULL) + { + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Group = (PSID)((ULONG)SecurityDescriptor->Group + + (PVOID)SecurityDescriptor); + } + else + { + *Group = SecurityDescriptor->Group; + } + } + else + { + *Group = NULL; + } + + if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED) + { + *GroupDefaulted = TRUE; + } + else + { + *GroupDefaulted = FALSE; + } + + return(STATUS_SUCCESS); } @@ -307,41 +481,45 @@ RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PACL *Sacl, PBOOLEAN SaclDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (!(SecurityDescriptor->Control & SE_SACL_PRESENT)) - { - *SaclPresent = 0; - return(STATUS_SUCCESS); - } - *SaclPresent = 1; - if (SecurityDescriptor->Sacl == NULL) - { - *Sacl = NULL; - } - else - { - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - *Sacl = (PACL)((ULONG)SecurityDescriptor->Sacl + - (PVOID)SecurityDescriptor); - } - else - { - *Sacl = SecurityDescriptor->Sacl; - } - } - if (SecurityDescriptor->Control & SE_SACL_DEFAULTED) - { - *SaclDefaulted = 1; - } - else - { - *SaclDefaulted = 0; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + + if (!(SecurityDescriptor->Control & SE_SACL_PRESENT)) + { + *SaclPresent = FALSE; + return(STATUS_SUCCESS); + } + *SaclPresent = TRUE; + + if (SecurityDescriptor->Sacl == NULL) + { + *Sacl = NULL; + } + else + { + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Sacl = (PACL)((ULONG)SecurityDescriptor->Sacl + + (PVOID)SecurityDescriptor); + } + else + { + *Sacl = SecurityDescriptor->Sacl; + } + } + + if (SecurityDescriptor->Control & SE_SACL_DEFAULTED) + { + *SaclDefaulted = TRUE; + } + else + { + *SaclDefaulted = FALSE; + } + + return(STATUS_SUCCESS); } @@ -351,27 +529,130 @@ RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, PACL Sacl, BOOLEAN SaclDefaulted) { - if (SecurityDescriptor->Revision != 1) - { - return(STATUS_UNSUCCESSFUL); - } - if (SecurityDescriptor->Control & SE_SELF_RELATIVE) - { - return(STATUS_UNSUCCESSFUL); - } - if (!SaclPresent) - { - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT); - return(STATUS_SUCCESS); - } - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT; - SecurityDescriptor->Sacl = Sacl; - SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED); - if (SaclDefaulted) - { - SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED; - } - return(STATUS_SUCCESS); + if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + return(STATUS_UNSUCCESSFUL); + } + + if (!SaclPresent) + { + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT); + return(STATUS_SUCCESS); + } + + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT; + SecurityDescriptor->Sacl = Sacl; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED); + + if (SaclDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED; + } + + return(STATUS_SUCCESS); +} + + +static VOID +RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID* Owner, + PULONG OwnerLength, + PSID* Group, + PULONG GroupLength, + PACL* Dacl, + PULONG DaclLength, + PACL* Sacl, + PULONG SaclLength) +{ + if (SecurityDescriptor->Owner == NULL) + { + *Owner = NULL; + } + else + { + *Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor); + } + } + + if (*Owner != NULL) + { + *OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3; + } + else + { + *OwnerLength = 0; + } + + if ((SecurityDescriptor->Control & SE_DACL_PRESENT) && + SecurityDescriptor->Dacl != NULL) + { + *Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor); + } + } + else + { + *Dacl = NULL; + } + + if (*Dacl != NULL) + { + *DaclLength = ((*Dacl)->AclSize + 3) & ~3; + } + else + { + *DaclLength = 0; + } + + if (SecurityDescriptor->Group != NULL) + { + *Group = NULL; + } + else + { + *Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor); + } + } + + if (*Group != NULL) + { + *GroupLength = (RtlLengthSid(*Group) + 3) & ~3; + } + else + { + *GroupLength = 0; + } + + if ((SecurityDescriptor->Control & SE_SACL_PRESENT) && + SecurityDescriptor->Sacl != NULL) + { + *Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & SE_SELF_RELATIVE) + { + *Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor); + } + } + else + { + *Sacl = NULL; + } + + if (*Sacl != NULL) + { + *SaclLength = ((*Sacl)->AclSize + 3) & ~3; + } } @@ -380,15 +661,84 @@ RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD, PSECURITY_DESCRIPTOR RelSD, PULONG BufferLength) { - if (AbsSD->Control & SE_SELF_RELATIVE) - return(STATUS_BAD_DESCRIPTOR_FORMAT); + PSID Owner; + PSID Group; + PACL Sacl; + PACL Dacl; + ULONG OwnerLength; + ULONG GroupLength; + ULONG SaclLength; + ULONG DaclLength; + ULONG TotalLength; + ULONG Current; -// return(RtlPMakeSelfRelativeSD (AbsSD, RelSD, BufferLength)); + if (AbsSD->Control & SE_SELF_RELATIVE) + { + return(STATUS_BAD_DESCRIPTOR_FORMAT); + } + + RtlpQuerySecurityDescriptor(AbsSD, + &Owner, + &OwnerLength, + &Group, + &GroupLength, + &Dacl, + &DaclLength, + &Sacl, + &SaclLength); + + TotalLength = OwnerLength + GroupLength + SaclLength + + DaclLength + sizeof(SECURITY_DESCRIPTOR); + if (*BufferLength < TotalLength) + { + return(STATUS_BUFFER_TOO_SMALL); + } + + RtlZeroMemory(RelSD, + TotalLength); + memmove(RelSD, + AbsSD, + sizeof(SECURITY_DESCRIPTOR)); + Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR); + + if (SaclLength != 0) + { + memmove((PVOID)Current, + Sacl, + SaclLength); + RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD); + Current += SaclLength; + } + + if (DaclLength != 0) + { + memmove((PVOID)Current, + Dacl, + DaclLength); + RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD); + Current += DaclLength; + } + + if (OwnerLength != 0) + { + memmove((PVOID)Current, + Owner, + OwnerLength); + RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD); + Current += OwnerLength; + } + + if (GroupLength != 0) + { + memmove((PVOID)Current, + Group, + GroupLength); + RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD); + } + + RelSD->Control |= SE_SELF_RELATIVE; - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + return(STATUS_SUCCESS); } - - /* EOF */ diff --git a/ntoskrnl/se/semgr.c b/ntoskrnl/se/semgr.c index 6102752..7788419 100644 --- a/ntoskrnl/se/semgr.c +++ b/ntoskrnl/se/semgr.c @@ -64,6 +64,61 @@ SeInit2(VOID) } +BOOLEAN +SeInitSRM(VOID) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name; + HANDLE DirectoryHandle; + HANDLE EventHandle; + NTSTATUS Status; + + /* Create '\Security' directory */ + RtlInitUnicodeString(&Name, + L"\\Security"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + 0, + NULL); + Status = NtCreateDirectoryObject(&DirectoryHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create 'Security' directory!\n"); + return(FALSE); + } + + /* Create 'LSA_AUTHENTICATION_INITALIZED' event */ + RtlInitUnicodeString(&Name, + L"\\LSA_AUTHENTICATION_INITALIZED"); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_PERMANENT, + DirectoryHandle, + SePublicDefaultSd); + Status = NtCreateEvent(&EventHandle, + EVENT_ALL_ACCESS, + &ObjectAttributes, + FALSE, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create 'Security' directory!\n"); + NtClose(DirectoryHandle); + return(FALSE); + } + + NtClose(EventHandle); + NtClose(DirectoryHandle); + + /* FIXME: Create SRM port and listener thread */ + + return(TRUE); +} + + static BOOLEAN SepInitExports(VOID) { diff --git a/rosbin.txt b/rosbin.txt index a847dc1..910314b 100644 --- a/rosbin.txt +++ b/rosbin.txt @@ -62,6 +62,6 @@ subsys\win32k\win32k.sys system32 ; Contents of disk 4 ;.New Disk -apps\system\shell\shell.exe system32 +apps\system\cmd\cmd.exe system32 ; EOF diff --git a/rules.mak b/rules.mak index 23ab1d6..6996ac7 100644 --- a/rules.mak +++ b/rules.mak @@ -18,8 +18,12 @@ endif ifeq ($(HOST),mingw32-linux) TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) +else +TOPDIR := $(shell cd) endif +TOPDIR := $(TOPDIR)/$(PATH_TO_TOP) + # # Choose various options # @@ -60,6 +64,8 @@ INSTALL_DIR = $(PATH_TO_TOP)/reactos DIST_DIR = $(PATH_TO_TOP)/dist # endif +# Directory to build a bootable CD image in +BOOTCD_DIR=$(TOPDIR)/../bootcd/disk CC = $(PREFIX)gcc CXX = $(PREFIX)g++ @@ -79,6 +85,7 @@ OBJCOPY = $(PREFIX)objcopy TOOLS_PATH = $(PATH_TO_TOP)/tools CP = $(TOOLS_PATH)/rcopy RM = $(TOOLS_PATH)/rdel +RLINE = $(TOOLS_PATH)/rline RMDIR = $(TOOLS_PATH)/rrmdir RMKDIR = $(TOOLS_PATH)/rmkdir RSYM = $(TOOLS_PATH)/rsym @@ -89,11 +96,11 @@ MC = $(TOOLS_PATH)/wmc/wmc # Maybe we can delete these soon ifeq ($(HOST),mingw32-linux) -CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe -march=i386 +CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe -march=i386 -D_M_IX86 endif ifeq ($(HOST),mingw32-windows) -CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe -march=i386 +CFLAGS := $(CFLAGS) -I$(PATH_TO_TOP)/include -pipe -march=i386 -D_M_IX86 endif CXXFLAGS = $(CFLAGS) diff --git a/subsys/csrss/api.h b/subsys/csrss/api.h index c880c22..53d29bf 100644 --- a/subsys/csrss/api.h +++ b/subsys/csrss/api.h @@ -132,6 +132,11 @@ CSR_API(CsrSetShutdownParameters); CSR_API(CsrPeekConsoleInput); CSR_API(CsrReadConsoleOutput); CSR_API(CsrWriteConsoleInput); +CSR_API(CsrGetInputHandle); +CSR_API(CsrGetOutputHandle); +CSR_API(CsrCloseHandle); +CSR_API(CsrVerifyHandle); +CSR_API(CsrDuplicateHandle); /* print.c */ VOID STDCALL DisplayString(LPCWSTR lpwString); @@ -160,6 +165,7 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object ); BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount, PWSTR *ArgumentArray); NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); +NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); VOID STDCALL CsrDrawConsole( PCSRSS_SCREEN_BUFFER Console ); NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib ); diff --git a/subsys/csrss/api/conio.c b/subsys/csrss/api/conio.c index 4ae0b43..0d1e7ba 100644 --- a/subsys/csrss/api/conio.c +++ b/subsys/csrss/api/conio.c @@ -46,6 +46,12 @@ CSR_API(CsrAllocConsole) Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + if( ProcessData->Console ) { Reply->Status = STATUS_INVALID_PARAMETER; @@ -116,6 +122,11 @@ CSR_API(CsrFreeConsole) Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + Reply->Status = STATUS_NOT_IMPLEMENTED; return(STATUS_NOT_IMPLEMENTED); @@ -136,8 +147,8 @@ CSR_API(CsrReadConsole) Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = Reply->Header.MessageSize - sizeof(LPC_MESSAGE); + Buffer = Reply->Data.ReadConsoleReply.Buffer; - Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent; LOCK; Status = CsrGetObject( ProcessData, Request->Data.ReadConsoleRequest.ConsoleHandle, (Object_t **)&Console ); if( !NT_SUCCESS( Status ) ) @@ -152,11 +163,12 @@ CSR_API(CsrReadConsole) UNLOCK; return STATUS_INVALID_HANDLE; } + Reply->Data.ReadConsoleReply.EventHandle = ProcessData->ConsoleEvent; for (; iInputEvents.Flink != &Console->InputEvents; i++ ) { // remove input event from queue - CurrentEntry = RemoveHeadList(&Console->InputEvents); - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + CurrentEntry = RemoveHeadList(&Console->InputEvents); + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); // only pay attention to valid ascii chars, on key down if( Input->InputEvent.EventType == KEY_EVENT && @@ -257,8 +269,8 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR case '\n': Buff->CurrentX = 0; /* slide the viewable screen */ - if( ((PhysicalConsoleSize.Y + Buff->ShowY) % Buff->MaxY) == (Buff->CurrentY + 1) % Buff->MaxY) - if( ++Buff->ShowY == (Buff->MaxY - 1) ) + if (((Buff->CurrentY-Buff->ShowY + Buff->MaxY) % Buff->MaxY) == PhysicalConsoleSize.Y - 1) + if (++Buff->ShowY == Buff->MaxY) Buff->ShowY = 0; if( ++Buff->CurrentY == Buff->MaxY ) { @@ -317,7 +329,7 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR /* clear new line */ ClearLineBuffer (Buff, 0); /* slide the viewable screen */ - if( (Buff->CurrentY - Buff->ShowY) == PhysicalConsoleSize.Y ) + if( (Buff->CurrentY - Buff->ShowY + Buff->MaxY - 1) % Buff->MaxY == PhysicalConsoleSize.Y -1) if( ++Buff->ShowY == Buff->MaxY ) Buff->ShowY = 0; } @@ -344,13 +356,13 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR } #define CsrpRectHeight(Rect) \ - ((Rect.Bottom) - (Rect.Top) + 1) + ((Rect.Top) > (Rect.Bottom) ? 0 : (Rect.Bottom) - (Rect.Top) + 1) #define CsrpRectWidth(Rect) \ - ((Rect.Right) - (Rect.Left) + 1) + ((Rect.Left) > (Rect.Right) ? 0 : (Rect.Right) - (Rect.Left) + 1) #define CsrpIsRectEmpty(Rect) \ - ((Rect.Left >= Rect.Right) || (Rect.Top >= Rect.Bottom)) + ((Rect.Left > Rect.Right) || (Rect.Top > Rect.Bottom)) inline BOOLEAN CsrpIsEqualRect( @@ -368,13 +380,13 @@ inline BOOLEAN CsrpGetIntersection( { if (CsrpIsRectEmpty(Rect1) || (CsrpIsRectEmpty(Rect2)) || - (Rect1.Top >= Rect2.Bottom) || - (Rect1.Left >= Rect2.Right) || - (Rect1.Bottom <= Rect2.Top) || - (Rect1.Right <= Rect2.Left)) + (Rect1.Top > Rect2.Bottom) || + (Rect1.Left > Rect2.Right) || + (Rect1.Bottom < Rect2.Top) || + (Rect1.Right < Rect2.Left)) { /* The rectangles do not intersect */ - CsrpInitRect(*Intersection, 0, 0, 0, 0) + CsrpInitRect(*Intersection, 0, -1, 0, -1) return FALSE; } @@ -396,7 +408,7 @@ inline BOOLEAN CsrpGetUnion( { if (CsrpIsRectEmpty(Rect2)) { - CsrpInitRect(*Union, 0, 0, 0, 0); + CsrpInitRect(*Union, 0, -1, 0, -1); return FALSE; } else @@ -430,7 +442,7 @@ inline BOOLEAN CsrpSubtractRect( if (CsrpIsRectEmpty(Rect1)) { - CsrpInitRect(*Subtraction, 0, 0, 0, 0); + CsrpInitRect(*Subtraction, 0, -1, 0, -1); return FALSE; } *Subtraction = Rect1; @@ -438,7 +450,7 @@ inline BOOLEAN CsrpSubtractRect( { if (CsrpIsEqualRect(tmp, *Subtraction)) { - CsrpInitRect(*Subtraction, 0, 0, 0, 0); + CsrpInitRect(*Subtraction, 0, -1, 0, -1); return FALSE; } if ((tmp.Top == Subtraction->Top) && (tmp.Bottom == Subtraction->Bottom)) @@ -471,18 +483,42 @@ static VOID CsrpCopyRegion( DWORD SrcOffset; DWORD DstOffset; DWORD BytesPerLine; + ULONG i; DstY = DstRegion.Top; BytesPerLine = CsrpRectWidth(DstRegion) * 2; - for (SrcY = SrcRegion.Top; SrcY <= SrcRegion.Bottom; SrcY++) + + SrcY = (SrcRegion.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY; + DstY = (DstRegion.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY; + SrcOffset = (SrcY * ScreenBuffer->MaxX + SrcRegion.Left + ScreenBuffer->ShowX) * 2; + DstOffset = (DstY * ScreenBuffer->MaxX + DstRegion.Left + ScreenBuffer->ShowX) * 2; + + for (i = SrcRegion.Top; i <= SrcRegion.Bottom; i++) { - SrcOffset = (SrcY * ScreenBuffer->MaxX * 2) + (SrcRegion.Left * 2); - DstOffset = (DstY * ScreenBuffer->MaxX * 2) + (DstRegion.Left * 2); RtlCopyMemory( &ScreenBuffer->Buffer[DstOffset], &ScreenBuffer->Buffer[SrcOffset], BytesPerLine); - DstY++; + + if (++DstY == ScreenBuffer->MaxY) + { + DstY = 0; + DstOffset = (DstRegion.Left + ScreenBuffer->ShowX) * 2; + } + else + { + DstOffset += ScreenBuffer->MaxX * 2; + } + + if (++SrcY == ScreenBuffer->MaxY) + { + SrcY = 0; + SrcOffset = (SrcRegion.Left + ScreenBuffer->ShowX) * 2; + } + else + { + SrcOffset += ScreenBuffer->MaxX * 2; + } } } @@ -496,14 +532,28 @@ static VOID CsrpFillRegion( { SHORT X, Y; DWORD Offset; + DWORD Delta; + ULONG i; + + Y = (Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY; + Offset = (Y * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2; + Delta = (ScreenBuffer->MaxX - CsrpRectWidth(Region)) * 2; - for (Y = Region.Top; Y <= Region.Bottom; Y++) + for (i = Region.Top; i <= Region.Bottom; i++) { - Offset = (Y * ScreenBuffer->MaxX + Region.Left) * 2; for (X = Region.Left; X <= Region.Right; X++) { SET_CELL_BUFFER(ScreenBuffer, Offset, CharInfo.Char.AsciiChar, CharInfo.Attributes); } + if (++Y == ScreenBuffer->MaxY) + { + Y = 0; + Offset = (Region.Left + ScreenBuffer->ShowX) * 2; + } + else + { + Offset += Delta; + } } } @@ -551,13 +601,12 @@ static VOID CsrpDrawRegion( /* blast out buffer */ BytesPerLine = CsrpRectWidth(Region) * 2; - SrcOffset = (Region.Top * ScreenBuffer->MaxX + Region.Left) * 2; + SrcOffset = (((Region.Top + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + Region.Left + ScreenBuffer->ShowX) * 2; SrcDelta = ScreenBuffer->MaxX * 2; - for( i = Region.Top - ScreenBuffer->ShowY, y = ScreenBuffer->ShowY; - i <= Region.Bottom - ScreenBuffer->ShowY; i++ ) + for( i = Region.Top, y = ScreenBuffer->ShowY; i <= Region.Bottom; i++ ) { /* Position the cursor correctly */ - Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left - ScreenBuffer->ShowX, i); + Status = CsrpSetConsoleDeviceCursor(ScreenBuffer, Region.Left, i); if( !NT_SUCCESS( Status ) ) { DbgPrint( "CSR: Failed to set console info\n" ); @@ -577,7 +626,7 @@ static VOID CsrpDrawRegion( if( ++y == ScreenBuffer->MaxY ) { y = 0; - SrcOffset = Region.Left * 2; + SrcOffset = (Region.Left + ScreenBuffer->ShowX) * 2; } else { @@ -616,6 +665,8 @@ CSR_API(CsrWriteConsole) { BYTE *Buffer = Request->Data.WriteConsoleRequest.Buffer; PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrWriteConsole\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -738,10 +789,10 @@ VOID STDCALL CsrDrawConsole( PCSRSS_SCREEN_BUFFER Buff ) CsrpInitRect( Region, - Buff->ShowY, - Buff->ShowX, - Buff->ShowY + PhysicalConsoleSize.Y - 1, - Buff->ShowX + PhysicalConsoleSize.X - 1); + 0, + 0, + PhysicalConsoleSize.Y - 1, + PhysicalConsoleSize.X - 1); CsrpDrawRegion(Buff, Region); } @@ -766,16 +817,20 @@ VOID STDCALL CsrDeleteConsole( PCSRSS_CONSOLE Console ) if( Console->Next != Console ) { ActiveConsole = Console->Next; - Console->Prev->Next = Console->Next; - Console->Next->Prev = Console->Prev; } else ActiveConsole = 0; } + if (Console->Next != Console) + { + Console->Prev->Next = Console->Next; + Console->Next->Prev = Console->Prev; + } + if( ActiveConsole ) CsrDrawConsole( ActiveConsole->ActiveBuffer ); - UNLOCK; if( !--Console->ActiveBuffer->Header.ReferenceCount ) CsrDeleteScreenBuffer( Console->ActiveBuffer ); + UNLOCK; NtClose( Console->ActiveEvent ); RtlFreeUnicodeString( &Console->Title ); RtlFreeHeap( CsrssApiHeap, 0, Console ); @@ -904,7 +959,6 @@ VOID Console_Api( DWORD RefreshEvent ) ANSI_STRING Title; void * Buffer; COORD *pos; - unsigned int src, dst; /* alt-tab, swap consoles */ // move SwapConsole to next console, and print its title @@ -919,18 +973,13 @@ VOID Console_Api( DWORD RefreshEvent ) Title.Length = 0; Buffer = RtlAllocateHeap( CsrssApiHeap, 0, - sizeof( COORD ) + Title.MaximumLength ); + sizeof( COORD ) + Title.MaximumLength); pos = (COORD *)Buffer; Title.Buffer = Buffer + sizeof( COORD ); - /* this does not seem to work - RtlUnicodeStringToAnsiString( &Title, &SwapConsole->Title, FALSE ); */ - // temp hack - for( src = 0, dst = 0; src < SwapConsole->Title.Length; src++, dst++ ) - Title.Buffer[dst] = (char)SwapConsole->Title.Buffer[dst]; - + RtlUnicodeStringToAnsiString(&Title, &SwapConsole->Title, FALSE); pos->Y = PhysicalConsoleSize.Y / 2; - pos->X = ( PhysicalConsoleSize.X - Title.MaximumLength ) / 2; + pos->X = ( PhysicalConsoleSize.X - Title.Length ) / 2; // redraw the console to clear off old title CsrDrawConsole( ActiveConsole->ActiveBuffer ); Status = NtDeviceIoControlFile( ConsoleDeviceHandle, @@ -939,10 +988,10 @@ VOID Console_Api( DWORD RefreshEvent ) NULL, &Iosb, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - 0, - 0, Buffer, - sizeof (COORD) + Title.MaximumLength ); + sizeof (COORD) + Title.Length, + NULL, + 0); if( !NT_SUCCESS( Status ) ) { DPRINT1( "Error writing to console\n" ); @@ -1191,11 +1240,14 @@ CSR_API(CsrSetCursor) CSR_API(CsrWriteConsoleOutputChar) { - BYTE *Buffer = Request->Data.WriteConsoleOutputCharRequest.String; + PBYTE String = Request->Data.WriteConsoleOutputCharRequest.String; + PBYTE Buffer; PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y; + DWORD X, Y, Length; NTSTATUS Status; IO_STATUS_BLOCK Iosb; + + DPRINT("CsrWriteConsoleOutputChar\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -1206,12 +1258,26 @@ CSR_API(CsrWriteConsoleOutputChar) UNLOCK; return Reply->Status = STATUS_INVALID_HANDLE; } - X = Buff->CurrentX; - Y = Buff->CurrentY; - Buff->CurrentX = Request->Data.WriteConsoleOutputCharRequest.Coord.X; - Buff->CurrentY = Request->Data.WriteConsoleOutputCharRequest.Coord.Y; - Buffer[Request->Data.WriteConsoleOutputCharRequest.Length] = 0; - CsrpWriteConsole( Buff, Buffer, Request->Data.WriteConsoleOutputCharRequest.Length, FALSE ); + + + X = Request->Data.WriteConsoleOutputCharRequest.Coord.X + Buff->ShowX; + Y = (Request->Data.WriteConsoleOutputCharRequest.Coord.Y + Buff->ShowY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputCharRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + while(Length--) + { + *Buffer = *String++; + Buffer += 2; + if (++X == Buff->MaxX) + { + if (++Y == Buff->MaxY) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; + } + } if( ActiveConsole->ActiveBuffer == Buff ) { Status = NtDeviceIoControlFile( ConsoleDeviceHandle, @@ -1220,17 +1286,15 @@ CSR_API(CsrWriteConsoleOutputChar) NULL, &Iosb, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - 0, - 0, &Request->Data.WriteConsoleOutputCharRequest.Coord, - sizeof (COORD) + Request->Data.WriteConsoleOutputCharRequest.Length ); + sizeof (COORD) + Request->Data.WriteConsoleOutputCharRequest.Length, + NULL, + 0); if( !NT_SUCCESS( Status ) ) DPRINT1( "Failed to write output chars: %x\n", Status ); } - Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = Buff->CurrentX - Buff->ShowX; - Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Buff->CurrentY + Buff->MaxY - Buff->ShowY) % Buff->MaxY; - Buff->CurrentY = Y; - Buff->CurrentX = X; + Reply->Data.WriteConsoleOutputCharReply.EndCoord.X = X - Buff->ShowX; + Reply->Data.WriteConsoleOutputCharReply.EndCoord.Y = (Y + Buff->MaxY - Buff->ShowY) % Buff->MaxY; UNLOCK; return Reply->Status = STATUS_SUCCESS; } @@ -1238,7 +1302,14 @@ CSR_API(CsrWriteConsoleOutputChar) CSR_API(CsrFillOutputChar) { PCSRSS_SCREEN_BUFFER Buff; - DWORD X, Y, i; + DWORD X, Y, Length; + BYTE Char; + OUTPUT_CHARACTER Character; + PBYTE Buffer; + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + + DPRINT("CsrFillOutputChar\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -1251,19 +1322,42 @@ CSR_API(CsrFillOutputChar) return Reply->Status = STATUS_INVALID_HANDLE; } X = Request->Data.FillOutputRequest.Position.X + Buff->ShowX; - Y = Request->Data.FillOutputRequest.Position.Y + Buff->ShowY; - for( i = 0; i < Request->Data.FillOutputRequest.Length; i++ ) + Y = (Request->Data.FillOutputRequest.Position.Y + Buff->ShowY) % Buff->MaxY; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X)]; + Char = Request->Data.FillOutputRequest.Char; + Length = Request->Data.FillOutputRequest.Length; + while (Length--) + { + *Buffer = Char; + Buffer += 2; + if( ++X == Buff->MaxX ) { - Buff->Buffer[ (Y * 2 * Buff->MaxX) + (X * 2) ] = Request->Data.FillOutputRequest.Char; - if( ++X == Buff->MaxX ) - { - if( ++Y == Buff->MaxY ) - Y = 0; - X = 0; - } + if( ++Y == Buff->MaxY ) + { + Y = 0; + Buffer = Buff->Buffer; + } + X = 0; } + } if( Buff == ActiveConsole->ActiveBuffer ) - CsrDrawConsole( Buff ); + { + Character.dwCoord = Request->Data.FillOutputRequest.Position; + Character.cCharacter = Char; + Character.nLength = Request->Data.FillOutputRequest.Length; + Status = NtDeviceIoControlFile( ConsoleDeviceHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER, + &Character, + sizeof(Character), + NULL, + 0); + if (!NT_SUCCESS(Status)) + DPRINT1( "Failed to write output characters to console\n" ); + } UNLOCK; return Reply->Status; } @@ -1305,6 +1399,27 @@ CSR_API(CsrReadInputEvent) Console->WaitingChars--; } RtlFreeHeap( CsrssApiHeap, 0, Input ); + + if (Console->InputEvents.Flink != &Console->InputEvents && + Reply->Data.ReadInputReply.Input.EventType == KEY_EVENT && + Reply->Data.ReadInputReply.Input.Event.KeyEvent.uChar.AsciiChar == '\r') + { + Input = CONTAINING_RECORD(Console->InputEvents.Flink, ConsoleInput, ListEntry); + if (Input->InputEvent.EventType == KEY_EVENT && + Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' && + ((Input->InputEvent.Event.KeyEvent.bKeyDown && Reply->Data.ReadInputReply.Input.Event.KeyEvent.bKeyDown) || + (Input->InputEvent.Event.KeyEvent.bKeyDown==FALSE && Reply->Data.ReadInputReply.Input.Event.KeyEvent.bKeyDown==FALSE))) + { + if(Console->Mode & ENABLE_LINE_INPUT && + Input->InputEvent.Event.KeyEvent.bKeyDown == FALSE && + Input->InputEvent.Event.KeyEvent.uChar.AsciiChar == '\n' ) + Console->WaitingLines--; + Console->WaitingChars--; + RemoveHeadList(&Console->InputEvents); + RtlFreeHeap( CsrssApiHeap, 0, Input ); + } + } + Reply->Data.ReadInputReply.MoreEvents = (Console->InputEvents.Flink != &Console->InputEvents) ? TRUE : FALSE; Status = STATUS_SUCCESS; Console->EarlyReturn = FALSE; // clear early return @@ -1319,11 +1434,13 @@ CSR_API(CsrReadInputEvent) CSR_API(CsrWriteConsoleOutputAttrib) { - int c; PCSRSS_SCREEN_BUFFER Buff; + PUCHAR Buffer, Attribute; NTSTATUS Status; - int X, Y; + int X, Y, Length; IO_STATUS_BLOCK Iosb; + + DPRINT("CsrWriteConsoleOutputAttrib\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -1336,20 +1453,25 @@ CSR_API(CsrWriteConsoleOutputAttrib) UNLOCK; return Status; } - X = Buff->CurrentX; - Y = Buff->CurrentY; - Buff->CurrentX = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX; - Buff->CurrentY = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY; - for( c = 0; c < Request->Data.WriteConsoleOutputAttribRequest.Length; c++ ) + X = Request->Data.WriteConsoleOutputAttribRequest.Coord.X + Buff->ShowX; + Y = (Request->Data.WriteConsoleOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY; + Length = Request->Data.WriteConsoleOutputAttribRequest.Length; + Buffer = &Buff->Buffer[2 * (Y * Buff->MaxX + X) + 1]; + Attribute = Request->Data.WriteConsoleOutputAttribRequest.String; + while (Length--) + { + *Buffer = *Attribute++; + Buffer += 2; + if( ++X == Buff->MaxX ) { - Buff->Buffer[(Buff->CurrentY * Buff->MaxX * 2) + (Buff->CurrentX * 2) + 1] = Request->Data.WriteConsoleOutputAttribRequest.String[c]; - if( ++Buff->CurrentX == Buff->MaxX ) - { - Buff->CurrentX = 0; - if( ++Buff->CurrentY == Buff->MaxY ) - Buff->CurrentY = 0; - } + X = 0; + if( ++Y == Buff->MaxY ) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } } + } if( Buff == ActiveConsole->ActiveBuffer ) { Status = NtDeviceIoControlFile( ConsoleDeviceHandle, @@ -1358,30 +1480,31 @@ CSR_API(CsrWriteConsoleOutputAttrib) NULL, &Iosb, IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE, - 0, - 0, &Request->Data.WriteConsoleOutputAttribRequest.Coord, Request->Data.WriteConsoleOutputAttribRequest.Length + - sizeof (COORD) ); + sizeof (COORD), + NULL, + 0 ); if( !NT_SUCCESS( Status ) ) DPRINT1( "Failed to write output attributes to console\n" ); } Reply->Data.WriteConsoleOutputAttribReply.EndCoord.X = Buff->CurrentX - Buff->ShowX; Reply->Data.WriteConsoleOutputAttribReply.EndCoord.Y = ( Buff->CurrentY + Buff->MaxY - Buff->ShowY ) % Buff->MaxY; - Buff->CurrentX = X; - Buff->CurrentY = Y; UNLOCK; return Reply->Status = STATUS_SUCCESS; } CSR_API(CsrFillOutputAttrib) { - int c; + OUTPUT_ATTRIBUTE Attribute; PCSRSS_SCREEN_BUFFER Buff; + PCHAR Buffer; NTSTATUS Status; - int X, Y; + int X, Y, Length; IO_STATUS_BLOCK Iosb; - OUTPUT_ATTRIBUTE Attr; + UCHAR Attr; + + DPRINT("CsrFillOutputAttrib\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -1394,40 +1517,43 @@ CSR_API(CsrFillOutputAttrib) UNLOCK; return Status; } - X = Buff->CurrentX; - Y = Buff->CurrentY; - Buff->CurrentX = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX; - Buff->CurrentY = Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY; - for( c = 0; c < Request->Data.FillOutputAttribRequest.Length; c++ ) + X = Request->Data.FillOutputAttribRequest.Coord.X + Buff->ShowX; + Y = (Request->Data.FillOutputAttribRequest.Coord.Y + Buff->ShowY) % Buff->MaxY; + Length = Request->Data.FillOutputAttribRequest.Length; + Attr = Request->Data.FillOutputAttribRequest.Attribute; + Buffer = &Buff->Buffer[(Y * Buff->MaxX * 2) + (X * 2) + 1]; + while(Length--) + { + *Buffer = Attr; + Buffer += 2; + if( ++X == Buff->MaxX ) { - Buff->Buffer[(Buff->CurrentY * Buff->MaxX * 2) + (Buff->CurrentX * 2) + 1] = Request->Data.FillOutputAttribRequest.Attribute; - if( ++Buff->CurrentX == Buff->MaxX ) - { - Buff->CurrentX = 0; - if( ++Buff->CurrentY == Buff->MaxY ) - Buff->CurrentY = 0; - } + X = 0; + if( ++Y == Buff->MaxY ) + { + Y = 0; + Buffer = Buff->Buffer + 1; + } } + } if( Buff == ActiveConsole->ActiveBuffer ) - { - Attr.wAttribute = Request->Data.FillOutputAttribRequest.Attribute; - Attr.nLength = Request->Data.FillOutputAttribRequest.Length; - Attr.dwCoord = Request->Data.FillOutputAttribRequest.Coord; - Status = NtDeviceIoControlFile( ConsoleDeviceHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE, - &Attr, - sizeof (Attr), - 0, - 0 ); - if( !NT_SUCCESS( Status ) ) - DPRINT1( "Failed to fill output attribute\n" ); - } - Buff->CurrentX = X; - Buff->CurrentY = Y; + { + Attribute.wAttribute = Attr; + Attribute.nLength = Request->Data.FillOutputAttribRequest.Length; + Attribute.dwCoord = Request->Data.FillOutputAttribRequest.Coord; + Status = NtDeviceIoControlFile( ConsoleDeviceHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE, + &Attribute, + sizeof(OUTPUT_ATTRIBUTE), + NULL, + 0); + if( !NT_SUCCESS( Status ) ) + DPRINT1( "Failed to fill output attributes to console\n" ); + } UNLOCK; return Reply->Status = STATUS_SUCCESS; } @@ -1493,6 +1619,8 @@ CSR_API(CsrSetTextAttrib) CONSOLE_SCREEN_BUFFER_INFO ScrInfo; IO_STATUS_BLOCK Iosb; PCSRSS_SCREEN_BUFFER Buff; + + DPRINT("CsrSetTextAttrib\n"); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - @@ -1588,11 +1716,18 @@ CSR_API(CsrGetConsoleMode) CSR_API(CsrCreateScreenBuffer) { - PCSRSS_SCREEN_BUFFER Buff = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) ); + PCSRSS_SCREEN_BUFFER Buff; NTSTATUS Status; Reply->Header.MessageSize = sizeof( CSRSS_API_REPLY ); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + + Buff = RtlAllocateHeap( CsrssApiHeap, 0, sizeof( CSRSS_SCREEN_BUFFER ) ); if( !Buff ) Reply->Status = STATUS_INSUFFICIENT_RESOURCES; LOCK; @@ -1673,10 +1808,10 @@ CSR_API(CsrGetTitle) Request->Data.GetTitleRequest.ConsoleHandle, (Object_t **) & Console ); - if ( !NT_SUCCESS( Status ) ) - { - Reply->Status = Status; - } + if ( !NT_SUCCESS( Status ) ) + { + Reply->Status = Status; + } else { HANDLE ConsoleHandle = Request->Data.GetTitleRequest.ConsoleHandle; @@ -1689,6 +1824,8 @@ CSR_API(CsrGetTitle) Reply->Data.GetTitleReply.ConsoleHandle = ConsoleHandle; Reply->Data.GetTitleReply.Length = Console->Title.Length; wcscpy (Reply->Data.GetTitleReply.Title, Console->Title.Buffer); + Reply->Header.MessageSize += Console->Title.Length; + Reply->Header.DataSize += Console->Title.Length; Reply->Status = STATUS_SUCCESS; } UNLOCK; @@ -1709,6 +1846,8 @@ CSR_API(CsrWriteConsoleOutput) DWORD Offset; DWORD PSize; + DPRINT("CsrWriteConsoleOutput\n"); + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); LOCK; @@ -1736,8 +1875,8 @@ CSR_API(CsrWriteConsoleOutput) SizeY = RtlMin(BufferSize.Y - BufferCoord.Y, CsrpRectHeight(WriteRegion)); SizeX = RtlMin(BufferSize.X - BufferCoord.X, CsrpRectWidth(WriteRegion)); - WriteRegion.Bottom = WriteRegion.Top + SizeY; - WriteRegion.Right = WriteRegion.Left + SizeX; + WriteRegion.Bottom = WriteRegion.Top + SizeY - 1; + WriteRegion.Right = WriteRegion.Left + SizeX - 1; /* Make sure WriteRegion is inside the screen buffer */ CsrpInitRect(ScreenBuffer, 0, 0, Buff->MaxY - 1, Buff->MaxX - 1); @@ -1751,8 +1890,8 @@ CSR_API(CsrWriteConsoleOutput) for ( i = 0, Y = WriteRegion.Top; Y <= WriteRegion.Bottom; i++, Y++ ) { - CurCharInfo = CharInfo + (i * BufferSize.Y); - Offset = (Y * Buff->MaxX + WriteRegion.Left) * 2; + CurCharInfo = CharInfo + (i + BufferCoord.Y) * BufferSize.X + BufferCoord.X; + Offset = (((Y + Buff->ShowY) % Buff->MaxY) * Buff->MaxX + WriteRegion.Left) * 2; for ( X = WriteRegion.Left; X <= WriteRegion.Right; X++ ) { SET_CELL_BUFFER(Buff, Offset, CurCharInfo->Char.AsciiChar, CurCharInfo->Attributes); @@ -1793,16 +1932,14 @@ CSR_API(CsrFlushInputBuffer) } /* Discard all entries in the input event queue */ - CurrentEntry = Console->InputEvents.Flink; - while (IsListEmpty(&Console->InputEvents)) + while (!IsListEmpty(&Console->InputEvents)) { - NextEntry = CurrentEntry->Flink; - Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - /* Destroy the event */ - Console->WaitingChars--; - RtlFreeHeap( CsrssApiHeap, 0, Input ); - CurrentEntry = NextEntry; + CurrentEntry = RemoveHeadList(&Console->InputEvents); + Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); + /* Destroy the event */ + RtlFreeHeap( CsrssApiHeap, 0, Input ); } + Console->WaitingChars=0; UNLOCK; return (Reply->Status = STATUS_SUCCESS); @@ -1938,7 +2075,7 @@ CSR_API(CsrReadConsoleOutputChar) } Xpos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.X + ScreenBuffer->ShowX; - Ypos = Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY; + Ypos = (Request->Data.ReadConsoleOutputCharRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY; for (i = 0; i < Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; ++i) { @@ -1961,7 +2098,7 @@ CSR_API(CsrReadConsoleOutputChar) Reply->Status = STATUS_SUCCESS; Reply->Data.ReadConsoleOutputCharReply.EndCoord.X = Xpos - ScreenBuffer->ShowX; - Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = Ypos - ScreenBuffer->ShowY; + Reply->Data.ReadConsoleOutputCharReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY; Reply->Header.MessageSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; Reply->Header.DataSize += Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead; @@ -2001,7 +2138,7 @@ CSR_API(CsrReadConsoleOutputAttrib) } Xpos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.X + ScreenBuffer->ShowX; - Ypos = Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + ScreenBuffer->ShowY; + Ypos = (Request->Data.ReadConsoleOutputAttribRequest.ReadCoord.Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY; for (i = 0; i < Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; ++i) { @@ -2024,7 +2161,7 @@ CSR_API(CsrReadConsoleOutputAttrib) Reply->Status = STATUS_SUCCESS; Reply->Data.ReadConsoleOutputAttribReply.EndCoord.X = Xpos - ScreenBuffer->ShowX; - Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = Ypos - ScreenBuffer->ShowY; + Reply->Data.ReadConsoleOutputAttribReply.EndCoord.Y = (Ypos - ScreenBuffer->ShowY + ScreenBuffer->MaxY) % ScreenBuffer->MaxY; Reply->Header.MessageSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; Reply->Header.DataSize += Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead; @@ -2221,7 +2358,7 @@ CSR_API(CsrReadConsoleOutput) { CurCharInfo = CharInfo + (i * BufferSize.Y); - Offset = (Y * ScreenBuffer->MaxX + ReadRegion.Left) * 2; + Offset = (((Y + ScreenBuffer->ShowY) % ScreenBuffer->MaxY) * ScreenBuffer->MaxX + ReadRegion.Left) * 2; for(X = ReadRegion.Left; X < ReadRegion.Right; ++X) { CurCharInfo->Char.AsciiChar = GET_CELL_BUFFER(ScreenBuffer, Offset); diff --git a/subsys/csrss/api/handle.c b/subsys/csrss/api/handle.c index 9a9381f..0b6127c 100644 --- a/subsys/csrss/api/handle.c +++ b/subsys/csrss/api/handle.c @@ -15,15 +15,23 @@ #include "api.h" #include +#define NDEBUG +#include + /* FUNCTIONS *****************************************************************/ NTSTATUS STDCALL CsrGetObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle, Object_t **Object ) { ULONG h = (((ULONG)Handle) >> 2) - 1; - // DbgPrint( "CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData->HandleTableSize ); + DPRINT("CsrGetObject, Object: %x, %x, %x\n", Object, Handle, ProcessData ? ProcessData->HandleTableSize : 0); + + if (ProcessData == NULL) + { + return STATUS_INVALID_PARAMETER; + } if( h >= ProcessData->HandleTableSize ) { - DbgPrint( "CsrGetObject returning invalid handle\n" ); + DPRINT("CsrGetObject returning invalid handle\n"); return STATUS_INVALID_HANDLE; } *Object = ProcessData->HandleTable[h]; @@ -37,6 +45,10 @@ NTSTATUS STDCALL CsrReleaseObject(PCSRSS_PROCESS_DATA ProcessData, { Object_t *Object; ULONG h = (((ULONG)Handle) >> 2) - 1; + if (ProcessData == NULL) + { + return STATUS_INVALID_PARAMETER; + } if( h >= ProcessData->HandleTableSize || ProcessData->HandleTable[h] == 0 ) return STATUS_INVALID_HANDLE; /* dec ref count */ @@ -59,6 +71,11 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl ULONG i; PVOID* NewBlock; + if (ProcessData == NULL) + { + return STATUS_INVALID_PARAMETER; + } + for (i = 0; i < ProcessData->HandleTableSize; i++) { if (ProcessData->HandleTable[i] == NULL) @@ -89,5 +106,20 @@ NTSTATUS STDCALL CsrInsertObject( PCSRSS_PROCESS_DATA ProcessData, PHANDLE Handl return(STATUS_SUCCESS); } +NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Handle ) +{ + ULONG h = (((ULONG)Handle) >> 2) - 1; + + if (ProcessData == NULL) + { + return STATUS_INVALID_PARAMETER; + } + if (h >= ProcessData->HandleTableSize) + { + return STATUS_INVALID_HANDLE; + } + + return ProcessData->HandleTable[h] ? STATUS_SUCCESS : STATUS_INVALID_HANDLE; +} /* EOF */ diff --git a/subsys/csrss/api/process.c b/subsys/csrss/api/process.c index 4e42f94..cd53f24 100644 --- a/subsys/csrss/api/process.c +++ b/subsys/csrss/api/process.c @@ -15,6 +15,9 @@ #include #include "api.h" +#define NDEBUG +#include + BOOL STDCALL W32kCleanupForProcess( INT Process ); #define LOCK RtlEnterCriticalSection(&ProcessDataLock) @@ -52,6 +55,26 @@ PCSRSS_PROCESS_DATA STDCALL CsrGetProcessData(ULONG ProcessId) { pProcessData = pProcessData->next; } + UNLOCK; + return pProcessData; +} + +PCSRSS_PROCESS_DATA STDCALL CsrCreateProcessData(ULONG ProcessId) +{ + ULONG i; + ULONG hash; + PCSRSS_PROCESS_DATA pProcessData; + + hash = ProcessId % (sizeof(ProcessData) / sizeof(*ProcessData)); + + LOCK; + + pProcessData = ProcessData[hash]; + + while (pProcessData && pProcessData->ProcessId != ProcessId) + { + pProcessData = pProcessData->next; + } if (pProcessData == NULL) { pProcessData = RtlAllocateHeap(CsrssApiHeap, @@ -64,6 +87,10 @@ PCSRSS_PROCESS_DATA STDCALL CsrGetProcessData(ULONG ProcessId) ProcessData[hash] = pProcessData; } } + else + { + DPRINT("Process data for pid %d already exist\n", ProcessId); + } UNLOCK; if (pProcessData == NULL) { @@ -148,7 +175,7 @@ CSR_API(CsrCreateProcess) sizeof(LPC_MESSAGE); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); - NewProcessData = CsrGetProcessData(Request->Data.CreateProcessRequest.NewProcessId); + NewProcessData = CsrCreateProcessData(Request->Data.CreateProcessRequest.NewProcessId); if (NewProcessData == NULL) { Reply->Status = STATUS_NO_MEMORY; @@ -234,6 +261,11 @@ CSR_API(CsrTerminateProcess) - sizeof(LPC_MESSAGE); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY); + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + Status = CsrFreeProcessData(ProcessData->ProcessId); Reply->Status = Status; @@ -257,6 +289,11 @@ CSR_API(CsrGetShutdownParameters) Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + Reply->Data.GetShutdownParametersReply.Level = ProcessData->ShutdownLevel; Reply->Data.GetShutdownParametersReply.Flags = ProcessData->ShutdownFlags; @@ -271,6 +308,11 @@ CSR_API(CsrSetShutdownParameters) Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + if (ProcessData == NULL) + { + return(Reply->Status = STATUS_INVALID_PARAMETER); + } + ProcessData->ShutdownLevel = Request->Data.SetShutdownParametersRequest.Level; ProcessData->ShutdownFlags = Request->Data.SetShutdownParametersRequest.Flags; @@ -279,5 +321,123 @@ CSR_API(CsrSetShutdownParameters) return(STATUS_SUCCESS); } +CSR_API(CsrGetInputHandle) +{ + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + if (ProcessData == NULL) + { + Reply->Data.GetInputHandleReply.InputHandle = INVALID_HANDLE_VALUE; + Reply->Status = STATUS_INVALID_PARAMETER; + } + else if (ProcessData->Console) + { + Reply->Status = CsrInsertObject(ProcessData, + &Reply->Data.GetInputHandleReply.InputHandle, + (Object_t *)ProcessData->Console); + } + else + { + Reply->Data.GetInputHandleReply.InputHandle = INVALID_HANDLE_VALUE; + Reply->Status = STATUS_SUCCESS; + } + + return Reply->Status; +} + +CSR_API(CsrGetOutputHandle) +{ + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + if (ProcessData == NULL) + { + Reply->Data.GetOutputHandleReply.OutputHandle = INVALID_HANDLE_VALUE; + Reply->Status = STATUS_INVALID_PARAMETER; + } + else if (ProcessData->Console) + { + RtlEnterCriticalSection( &ActiveConsoleLock ); + Reply->Status = CsrInsertObject(ProcessData, + &Reply->Data.GetOutputHandleReply.OutputHandle, + &(ProcessData->Console->ActiveBuffer->Header)); + RtlLeaveCriticalSection( &ActiveConsoleLock ); + } + else + { + Reply->Data.GetOutputHandleReply.OutputHandle = INVALID_HANDLE_VALUE; + Reply->Status = STATUS_SUCCESS; + } + + return Reply->Status; +} + +CSR_API(CsrCloseHandle) +{ + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + if (ProcessData == NULL) + { + Reply->Status = STATUS_INVALID_PARAMETER; + } + else + { + Reply->Status = CsrReleaseObject(ProcessData, Request->Data.CloseHandleRequest.Handle); + } + return Reply->Status; +} + +CSR_API(CsrVerifyHandle) +{ + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + Reply->Status = CsrVerifyObject(ProcessData, Request->Data.VerifyHandleRequest.Handle); + if (!NT_SUCCESS(Reply->Status)) + { + DPRINT("CsrVerifyObject failed, status=%x\n", Reply->Status); + } + + return Reply->Status; +} + +CSR_API(CsrDuplicateHandle) +{ + Object_t *Object; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + ProcessData = CsrGetProcessData(Request->Data.DuplicateHandleRequest.ProcessId); + Reply->Status = CsrGetObject(ProcessData, Request->Data.DuplicateHandleRequest.Handle, &Object); + if (!NT_SUCCESS(Reply->Status)) + { + DPRINT("CsrGetObject failed, status=%x\n", Reply->Status); + } + else + { + if (Object->Type == CSRSS_CONSOLE_MAGIC) + { + Reply->Status = CsrInsertObject(ProcessData, + &Reply->Data.DuplicateHandleReply.Handle, + (Object_t *)ProcessData->Console); + } + else if (Object->Type == CSRSS_SCREEN_BUFFER_MAGIC) + { + RtlEnterCriticalSection( &ActiveConsoleLock ); + Reply->Status = CsrInsertObject(ProcessData, + &Reply->Data.DuplicateHandleReply.Handle, + &(ProcessData->Console->ActiveBuffer->Header)); + RtlLeaveCriticalSection( &ActiveConsoleLock ); + } + else + { + Reply->Status = STATUS_INVALID_PARAMETER; + } + } + return Reply->Status; +} /* EOF */ diff --git a/subsys/csrss/api/wapi.c b/subsys/csrss/api/wapi.c index 17459e6..db8ed49 100644 --- a/subsys/csrss/api/wapi.c +++ b/subsys/csrss/api/wapi.c @@ -63,6 +63,11 @@ static const CsrFunc CsrFuncs[] = { CsrPeekConsoleInput, CsrReadConsoleOutput, CsrWriteConsoleInput, + CsrGetInputHandle, + CsrGetOutputHandle, + CsrCloseHandle, + CsrVerifyHandle, + CsrDuplicateHandle, 0 }; static void Thread_Api2(HANDLE ServerPort) diff --git a/subsys/smss/init.c b/subsys/smss/init.c index a3cce66..40b59a8 100644 --- a/subsys/smss/init.c +++ b/subsys/smss/init.c @@ -561,7 +561,7 @@ SmLoadSubsystems(VOID) /* Load kernel mode subsystem (aka win32k.sys) */ RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName, - L"\\SystemRoot\\system32\\drivers\\win32k.sys"); + L"\\SystemRoot\\system32\\win32k.sys"); Status = NtSetSystemInformation(SystemLoadAndCallImage, &ImageInfo, diff --git a/subsys/system/cmd/.cvsignore b/subsys/system/cmd/.cvsignore new file mode 100644 index 0000000..b8b4afb --- /dev/null +++ b/subsys/system/cmd/.cvsignore @@ -0,0 +1,16 @@ +*.sys +*.exe +*.dll +*.cpl +*.a +*.o +*.d +*.coff +*.dsp +*.dsw +*.aps +*.ncb +*.opt +*.sym +*.plg +*.bak diff --git a/subsys/system/cmd/alias.c b/subsys/system/cmd/alias.c new file mode 100644 index 0000000..616cf39 --- /dev/null +++ b/subsys/system/cmd/alias.c @@ -0,0 +1,356 @@ +/* + * ALIAS.C - alias administration module. + * + * + * History: + * + * 02/02/1996 (Oliver Mueller) + * started. + * + * 02/03/1996 (Oliver Mueller) + * Added sorting algorithm and case sensitive substitution by using + * partstrupr(). + * + * 27 Jul 1998 John P. Price + * added config.h include + * added ifdef's to disable aliases + * + * 09-Dec-1998 (Eric Kohl ) + * Fixed crash when removing an alias in DeleteAlias(). + * Added help text ("/?"). + * + * 14-Jan-1998 (Eric Kohl ) + * Clean up and Unicode safe! + * + * 24-Jan-1998 (Eric Kohl ) + * Redirection safe! + */ + + +#include "config.h" + +#ifdef FEATURE_ALIASES + +#include +#include +#include +#include +#include + +#include "cmd.h" + + +typedef struct tagALIAS +{ + struct tagALIAS *next; + LPTSTR lpName; + LPTSTR lpSubst; + DWORD dwUsed; +} ALIAS, *LPALIAS; + + +static LPALIAS lpFirst = NULL; +static LPALIAS lpLast = NULL; +static DWORD dwUsed = 0; + + +/* module internal functions */ +/* strlwr only for first word in string */ +static VOID +partstrlwr (LPTSTR str) +{ + LPTSTR c = str; + while (*c && !_istspace (*c) && *c != _T('=')) + { + *c = _totlower (*c); + c++; + } +} + + +static VOID +PrintAlias (VOID) +{ + LPALIAS ptr = lpFirst; + while (ptr) + { + ConOutPrintf (_T("%s=%s\n"), ptr->lpName, ptr->lpSubst); + ptr = ptr->next; + } +} + + +static VOID +DeleteAlias (LPTSTR pszName) +{ + LPALIAS ptr = lpFirst; + LPALIAS prev = NULL; + + while (ptr) + { + if (!_tcsicmp (ptr->lpName, pszName)) + { + if (prev) + prev->next = ptr->next; + else + lpFirst = ptr->next; + free (ptr->lpName); + free (ptr->lpSubst); + free (ptr); + return; + } + prev = ptr; + ptr = ptr->next; + } +} + + +static VOID +AddAlias (LPTSTR name, LPTSTR subst) +{ + LPALIAS ptr = lpFirst; + LPALIAS prev, entry; + LPTSTR s; + + while (ptr) + { + if (!_tcsicmp (ptr->lpName, name)) + { + s = (LPTSTR)malloc ((_tcslen (subst) + 1)*sizeof(TCHAR)); + if (!s) + { + error_out_of_memory (); + return; + } + + free (ptr->lpSubst); + ptr->lpSubst = s; + _tcscpy (ptr->lpSubst, subst); + return; + } + ptr = ptr->next; + } + + ptr = (LPALIAS)malloc (sizeof (ALIAS)); + if (!ptr) + return; + + ptr->next = 0; + + ptr->lpName = (LPTSTR)malloc ((_tcslen (name) + 1)*sizeof(TCHAR)); + if (!ptr->lpName) + { + error_out_of_memory (); + free (ptr); + return; + } + _tcscpy (ptr->lpName, name); + + ptr->lpSubst = (LPTSTR)malloc ((_tcslen (subst) + 1)*sizeof(TCHAR)); + if (!ptr->lpSubst) + { + error_out_of_memory (); + free (ptr->lpName); + free (ptr); + return; + } + _tcscpy (ptr->lpSubst, subst); + + /* it's necessary for recursive substitution */ + partstrlwr (ptr->lpSubst); + + ptr->dwUsed = 0; + + /* Alias table must be sorted! + * Here a little example: + * command line = "ls -c" + * If the entries are + * ls=dir + * ls -c=ls /w + * command line will be expanded to "dir -c" which is not correct. + * If the entries are sortet as + * ls -c=ls /w + * ls=dir + * it will be expanded to "dir /w" which is a valid DOS command. + */ + entry = lpFirst; + prev = 0; + while (entry) + { + if (_tcsicmp (ptr->lpName, entry->lpName) > 0) + { + if (prev) + { + prev->next = ptr; + ptr->next = entry; + } + else + { + ptr->next = entry; + lpFirst = ptr; + } + return; + } + prev = entry; + entry = entry->next; + } + + /* The new entry is the smallest (or the first) and must be + * added to the end of the list. + */ + if (!lpFirst) + lpFirst = ptr; + else + lpLast->next = ptr; + lpLast = ptr; + + return; +} + + +VOID InitializeAlias (VOID) +{ + lpFirst = NULL; + lpLast = NULL; + dwUsed = 0; +} + +VOID DestroyAlias (VOID) +{ + if (lpFirst == NULL) + return; + + while (lpFirst->next != NULL) + { + lpLast = lpFirst; + lpFirst = lpLast->next; + + free (lpLast->lpName); + free (lpLast->lpSubst); + free (lpLast); + } + + free (lpFirst->lpName); + free (lpFirst->lpSubst); + free (lpFirst); + + lpFirst = NULL; + lpLast = NULL; + dwUsed = 0; +} + +/* specified routines */ +VOID ExpandAlias (LPTSTR cmd, INT maxlen) +{ + unsigned n = 0, + m, + i, + len; + short d = 1; + LPALIAS ptr = lpFirst; + + dwUsed++; + if (dwUsed == 0) + { + while (ptr) + ptr->dwUsed = 0; + ptr = lpFirst; + dwUsed = 1; + } + + /* skipping white spaces */ + while (_istspace (cmd[n])) + n++; + + partstrlwr (&cmd[n]); + + if (!_tcsncmp (&cmd[n], _T("NOALIAS"), 7) && + (_istspace (cmd[n + 7]) || cmd[n + 7] == _T('\0'))) + { + memmove (cmd, &cmd[n + 7], (_tcslen (&cmd[n + 7]) + 1) * sizeof (TCHAR)); + return; + } + + /* substitution loop */ + while (d) + { + d = 0; + while (ptr) + { + len = _tcslen (ptr->lpName); + if (!_tcsncmp (&cmd[n], ptr->lpName, len) && + (_istspace (cmd[n + len]) || cmd[n + len] == _T('\0')) && + ptr->dwUsed != dwUsed) + { + m = _tcslen (ptr->lpSubst); + if ((int)(_tcslen (cmd) - len + m - n) > maxlen) + { + ConErrPrintf (_T("Command line too long after alias expansion!\n")); + /* the parser won't cause any problems with an empty line */ + cmd[0] = _T('\0'); + } + else + { + memmove (&cmd[m], &cmd[n + len], (_tcslen(&cmd[n + len]) + 1) * sizeof (TCHAR)); + for (i = 0; i < m; i++) + cmd[i] = ptr->lpSubst[i]; + ptr->dwUsed = dwUsed; + /* whitespaces are removed! */ + n = 0; + d = 1; + } + } + ptr = ptr->next; + } + } +} + + +INT CommandAlias (LPTSTR cmd, LPTSTR param) +{ + LPTSTR ptr; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Sets, removes or shows aliases.\n" + "\n" + "ALIAS [alias=[command]]\n" + "\n" + " alias Name for an alias.\n" + " command Text to be substituted for an alias.\n" + "\n" +// "For example:\n" + "To list all aliases:\n" + " ALIAS\n\n" + "To set a new or replace an existing alias:\n" + " ALIAS da=dir a:\n\n" + "To remove an alias from the alias list:\n" + " ALIAS da=" +// "Type ALIAS without a parameter to display the alias list.\n" + )); + return 0; + } + + if (param[0] == _T('\0')) + { + PrintAlias (); + return 0; + } + + /* error if no '=' found */ + if ((ptr = _tcschr (param, _T('='))) == 0) + return 1; + + /* Split rest into name and substitute */ + *ptr++ = _T('\0'); + + partstrlwr (param); + + if (ptr[0] == _T('\0')) + DeleteAlias (param); + else + AddAlias (param, ptr); + + return 0; +} +#endif diff --git a/subsys/system/cmd/attrib.c b/subsys/system/cmd/attrib.c new file mode 100644 index 0000000..a4435aa --- /dev/null +++ b/subsys/system/cmd/attrib.c @@ -0,0 +1,356 @@ +/* + * ATTRIB.C - attrib internal command. + * + * + * History: + * + * 04-Dec-1998 (Eric Kohl ) + * started + * + * 09-Dec-1998 (Eric Kohl ) + * implementation works, except recursion ("attrib /s"). + * + * 05-Jan-1999 (Eric Kohl ) + * major rewrite. + * fixed recursion ("attrib /s"). + * started directory support ("attrib /s /d"). + * updated help text. + * + * 14-Jan-1999 (Eric Kohl ) + * Unicode ready! + * + * 19-Jan-1999 (Eric Kohl ) + * Redirection ready! + * + * 21-Jan-1999 (Eric Kohl ) + * Added check for invalid filenames. + * + * 23-Jan-1999 (Eric Kohl ) + * Added handling of multiple filenames. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_ATTRIB + +#include +#include +#include +#include + +#include "cmd.h" + + +static VOID +PrintAttribute (LPTSTR pszPath, LPTSTR pszFile, BOOL bRecurse) +{ + WIN32_FIND_DATA findData; + HANDLE hFind; + TCHAR szFullName[MAX_PATH]; + LPTSTR pszFileName; + + /* prepare full file name buffer */ + _tcscpy (szFullName, pszPath); + pszFileName = szFullName + _tcslen (szFullName); + + /* display all subdirectories */ + if (bRecurse) + { + /* append file name */ + _tcscpy (pszFileName, pszFile); + + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } + + do + { + if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + continue; + + if (!_tcscmp (findData.cFileName, _T(".")) || + !_tcscmp (findData.cFileName, _T(".."))) + continue; + + _tcscpy (pszFileName, findData.cFileName); + _tcscat (pszFileName, _T("\\")); + PrintAttribute (szFullName, pszFile, bRecurse); + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); + } + + /* append file name */ + _tcscpy (pszFileName, pszFile); + + /* display current directory */ + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } + + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + _tcscpy (pszFileName, findData.cFileName); + + ConOutPrintf (_T("%c %c%c%c %s\n"), + (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? _T('A') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? _T('S') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? _T('H') : _T(' '), + (findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _T('R') : _T(' '), + szFullName); + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); +} + + +static VOID +ChangeAttribute (LPTSTR pszPath, LPTSTR pszFile, DWORD dwMask, + DWORD dwAttrib, BOOL bRecurse, BOOL bDirectories) +{ + WIN32_FIND_DATA findData; + HANDLE hFind; + DWORD dwAttribute; + TCHAR szFullName[MAX_PATH]; + LPTSTR pszFileName; + + /* prepare full file name buffer */ + _tcscpy (szFullName, pszPath); + pszFileName = szFullName + _tcslen (szFullName); + + /* change all subdirectories */ + if (bRecurse) + { + /* append file name */ + _tcscpy (pszFileName, _T("*.*")); + + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } + + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!_tcscmp (findData.cFileName, _T(".")) || + !_tcscmp (findData.cFileName, _T(".."))) + continue; + + _tcscpy (pszFileName, findData.cFileName); + _tcscat (pszFileName, _T("\\")); + + ChangeAttribute (szFullName, pszFile, dwMask, + dwAttrib, bRecurse, bDirectories); + } + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); + } + + /* append file name */ + _tcscpy (pszFileName, pszFile); + + hFind = FindFirstFile (szFullName, &findData); + if (hFind == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), pszFile); + return; + } + + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + _tcscpy (pszFileName, findData.cFileName); + + dwAttribute = GetFileAttributes (szFullName); + + if (dwAttribute != 0xFFFFFFFF) + { + dwAttribute = (dwAttribute & ~dwMask) | dwAttrib; + SetFileAttributes (szFullName, dwAttribute); + } + } + while (FindNextFile (hFind, &findData)); + FindClose (hFind); +} + + +INT CommandAttrib (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg; + INT argc, i; + TCHAR szPath[MAX_PATH]; + TCHAR szFileName [MAX_PATH]; + BOOL bRecurse = FALSE; + BOOL bDirectories = FALSE; + DWORD dwAttrib = 0; + DWORD dwMask = 0; + + /* initialize strings */ + szPath[0] = _T('\0'); + szFileName[0] = _T('\0'); + + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or changes file attributes.\n\n" + "ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] file ...\n" + " [/S [/D]]\n\n" + " + Sets an attribute\n" + " - Clears an attribute\n" + " R Read-only file attribute\n" + " A Archive file attribute\n" + " S System file attribute\n" + " H Hidden file attribute\n" + " /S Processes matching files in the current directory\n" + " and all subdirectories\n" + " /D Processes direcories as well\n\n" + "Type ATTRIB without a parameter to display the attributes of all files.")); + return 0; + } + + /* build parameter array */ + arg = split (param, &argc, FALSE); + + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/s")) == 0) + bRecurse = TRUE; + else if (_tcsicmp (arg[i], _T("/d")) == 0) + bDirectories = TRUE; + } + + /* create attributes and mask */ + for (i = 0; i < argc; i++) + { + if (*arg[i] == _T('+')) + { + if (_tcslen (arg[i]) != 2) + { + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + + switch ((TCHAR)_totupper (arg[i][1])) + { + case _T('A'): + dwMask |= FILE_ATTRIBUTE_ARCHIVE; + dwAttrib |= FILE_ATTRIBUTE_ARCHIVE; + break; + + case _T('H'): + dwMask |= FILE_ATTRIBUTE_HIDDEN; + dwAttrib |= FILE_ATTRIBUTE_HIDDEN; + break; + + case _T('R'): + dwMask |= FILE_ATTRIBUTE_READONLY; + dwAttrib |= FILE_ATTRIBUTE_READONLY; + break; + + case _T('S'): + dwMask |= FILE_ATTRIBUTE_SYSTEM; + dwAttrib |= FILE_ATTRIBUTE_SYSTEM; + break; + + default: + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + } + else if (*arg[i] == _T('-')) + { + if (_tcslen (arg[i]) != 2) + { + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + + switch ((TCHAR)_totupper (arg[i][1])) + { + case _T('A'): + dwMask |= FILE_ATTRIBUTE_ARCHIVE; + dwAttrib &= ~FILE_ATTRIBUTE_ARCHIVE; + break; + + case _T('H'): + dwMask |= FILE_ATTRIBUTE_HIDDEN; + dwAttrib &= ~FILE_ATTRIBUTE_HIDDEN; + break; + + case _T('R'): + dwMask |= FILE_ATTRIBUTE_READONLY; + dwAttrib &= ~FILE_ATTRIBUTE_READONLY; + break; + + case _T('S'): + dwMask |= FILE_ATTRIBUTE_SYSTEM; + dwAttrib &= ~FILE_ATTRIBUTE_SYSTEM; + break; + + default: + error_invalid_parameter_format (arg[i]); + freep (arg); + return -1; + } + } + } + + if (argc == 0) + { + DWORD len; + + len = GetCurrentDirectory (MAX_PATH, szPath); + if (szPath[len-1] != _T('\\')) + { + szPath[len] = _T('\\'); + szPath[len + 1] = 0; + } + _tcscpy (szFileName, _T("*.*")); + PrintAttribute (szPath, szFileName, bRecurse); + freep (arg); + return 0; + } + + /* get full file name */ + for (i = 0; i < argc; i++) + { + if ((*arg[i] != _T('+')) && (*arg[i] != _T('-')) && (*arg[i] != _T('/'))) + { + LPTSTR p; + GetFullPathName (arg[i], MAX_PATH, szPath, NULL); + p = _tcsrchr (szPath, _T('\\')) + 1; + _tcscpy (szFileName, p); + *p = _T('\0'); + + if (dwMask == 0) + PrintAttribute (szPath, szFileName, bRecurse); + else + ChangeAttribute (szPath, szFileName, dwMask, + dwAttrib, bRecurse, bDirectories); + } + } + + freep (arg); + return 0; +} + +#endif /* INCLUDE_CMD_ATTRIB */ diff --git a/subsys/system/cmd/batch.c b/subsys/system/cmd/batch.c new file mode 100644 index 0000000..db556cf --- /dev/null +++ b/subsys/system/cmd/batch.c @@ -0,0 +1,450 @@ +/* $Id$ + * + * BATCH.C - batch file processor for CMD.EXE. + * + * + * History: + * + * ??/??/?? (Evan Jeffrey) + * started. + * + * 15 Jul 1995 (Tim Norman) + * modes and bugfixes. + * + * 08 Aug 1995 (Matt Rains) + * i have cleaned up the source code. changes now bring this + * source into guidelines for recommended programming practice. + * + * i have added some constants to help making changes easier. + * + * 29 Jan 1996 (Steffan Kaiser) + * made a few cosmetic changes + * + * 05 Feb 1996 (Tim Norman) + * changed to comply with new first/rest calling scheme + * + * 14 Jun 1997 (Steffen Kaiser) + * bug fixes. added error level expansion %?. ctrl-break handling + * + * 16 Jul 1998 (Hans B Pufal) + * Totally reorganised in conjunction with COMMAND.C (cf) to + * implement proper BATCH file nesting and other improvements. + * + * 16 Jul 1998 (John P Price ) + * Seperated commands into individual files. + * + * 19 Jul 1998 (Hans B Pufal) [HBP_001] + * Preserve state of echo flag across batch calls. + * + * 19 Jul 1998 (Hans B Pufal) [HBP_002] + * Implementation of FOR command + * + * 20-Jul-1998 (John P Price ) + * added error checking after malloc calls + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 02-Aug-1998 (Hans B Pufal) [HBP_003] + * Fixed bug in ECHO flag restoration at exit from batch file + * + * 26-Jan-1999 (Eric Kohl ) + * Replaced CRT io functions by Win32 io functions. + * Unicode safe! + * + * 23-Feb-2001 (Carl Nettelblad ) + * Fixes made to get "for" working. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* The stack of current batch contexts. + * NULL when no batch is active + */ +LPBATCH_CONTEXT bc = NULL; + +BOOL bEcho = TRUE; /* The echo flag */ + + + +/* Buffer for reading Batch file lines */ +TCHAR textline[BATCH_BUFFSIZE]; + + +/* + * Returns a pointer to the n'th parameter of the current batch file. + * If no such parameter exists returns pointer to empty string. + * If no batch file is current, returns NULL + * + */ + +LPTSTR FindArg (INT n) +{ + LPTSTR pp; + +#ifdef _DEBUG + DebugPrintf ("FindArg: (%d)\n", n); +#endif + + if (bc == NULL) + return NULL; + + n += bc->shiftlevel; + pp = bc->params; + + /* Step up the strings till we reach the end */ + /* or the one we want */ + while (*pp && n--) + pp += _tcslen (pp) + 1; + + return pp; +} + + +/* + * Batch_params builds a parameter list in newlay allocated memory. + * The parameters consist of null terminated strings with a final + * NULL character signalling the end of the parameters. + * +*/ + +LPTSTR BatchParams (LPTSTR s1, LPTSTR s2) +{ + LPTSTR dp = (LPTSTR)malloc ((_tcslen(s1) + _tcslen(s2) + 3) * sizeof (TCHAR)); + + /* JPP 20-Jul-1998 added error checking */ + if (dp == NULL) + { + error_out_of_memory(); + return NULL; + } + + if (s1 && *s1) + { + s1 = stpcpy (dp, s1); + *s1++ = _T('\0'); + } + else + s1 = dp; + + while (*s2) + { + if (_istspace (*s2) || _tcschr (_T(",;"), *s2)) + { + *s1++ = _T('\0'); + s2++; + while (*s2 && _tcschr (_T(" ,;"), *s2)) + s2++; + continue; + } + + if ((*s2 == _T('"')) || (*s2 == _T('\''))) + { + TCHAR st = *s2; + + do + *s1++ = *s2++; + while (*s2 && (*s2 != st)); + } + + *s1++ = *s2++; + } + + *s1++ = _T('\0'); + *s1 = _T('\0'); + + return dp; +} + + +/* + * If a batch file is current, exits it, freeing the context block and + * chaining back to the previous one. + * + * If no new batch context is found, sets ECHO back ON. + * + * If the parameter is non-null or not empty, it is printed as an exit + * message + */ + +VOID ExitBatch (LPTSTR msg) +{ +#ifdef _DEBUG + DebugPrintf ("ExitBatch: (\'%s\')\n", msg); +#endif + + if (bc != NULL) + { + LPBATCH_CONTEXT t = bc; + + if (bc->hBatchFile) + { + CloseHandle (bc->hBatchFile); + bc->hBatchFile = INVALID_HANDLE_VALUE; + } + + if (bc->params) + free(bc->params); + + if (bc->forproto) + free(bc->forproto); + + if (bc->ffind) + free(bc->ffind); + + /* Preserve echo state across batch calls */ + bEcho = bc->bEcho; + + bc = bc->prev; + free(t); + } + + if (msg && *msg) + ConOutPrintf ("%s\n", msg); +} + + +/* + * Start batch file execution + * + * The firstword parameter is the full filename of the batch file. + * + */ + +BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param) +{ + HANDLE hFile; + + hFile = CreateFile (fullname, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | + FILE_FLAG_SEQUENTIAL_SCAN, NULL); + +#ifdef _DEBUG + DebugPrintf ("Batch: (\'%s\', \'%s\', \'%s\') hFile = %x\n", + fullname, firstword, param, hFile); +#endif + + if (hFile == INVALID_HANDLE_VALUE) + { + ConErrPrintf (_T("Error opening batch file\n")); + return FALSE; + } + + /* Kill any and all FOR contexts */ + while (bc && bc->forvar) + ExitBatch (NULL); + + if (bc == NULL) + { + /* No curent batch file, create a new context */ + LPBATCH_CONTEXT n = (LPBATCH_CONTEXT)malloc (sizeof(BATCH_CONTEXT)); + + if (n == NULL) + { + error_out_of_memory (); + return FALSE; + } + + n->prev = bc; + bc = n; + } + else if (bc->hBatchFile != INVALID_HANDLE_VALUE) + { + /* Then we are transferring to another batch */ + CloseHandle (bc->hBatchFile); + bc->hBatchFile = INVALID_HANDLE_VALUE; + free (bc->params); + } + + bc->hBatchFile = hFile; + bc->bEcho = bEcho; /* Preserve echo across batch calls */ + bc->shiftlevel = 0; + + bc->ffind = NULL; + bc->forvar = _T('\0'); + bc->forproto = NULL; + bc->params = BatchParams (firstword, param); + +#ifdef _DEBUG + DebugPrintf ("Batch: returns TRUE\n"); +#endif + + return TRUE; +} + + +/* + * Read and return the next executable line form the current batch file + * + * If no batch file is current or no further executable lines are found + * return NULL. + * + * Here we also look out for FOR bcontext structures which trigger the + * FOR expansion code. + * + * Set eflag to 0 if line is not to be echoed else 1 + */ + +LPTSTR ReadBatchLine (LPBOOL bLocalEcho) +{ + LPTSTR first; + LPTSTR ip; + + /* No batch */ + if (bc == NULL) + return NULL; + +#ifdef _DEBUG + DebugPrintf ("ReadBatchLine ()\n"); +#endif + + while (1) + { + /* User halt */ + if (CheckCtrlBreak (BREAK_BATCHFILE)) + { + while (bc) + ExitBatch (NULL); + return NULL; + } + + /* No batch */ + if (bc == NULL) + return NULL; + + /* If its a FOR context... */ + if (bc->forvar) + { + LPTSTR sp = bc->forproto; /* pointer to prototype command */ + LPTSTR dp = textline; /* Place to expand protoype */ + LPTSTR fv = FindArg (0); /* Next list element */ + + /* End of list so... */ + if ((fv == NULL) || (*fv == _T('\0'))) + { + /* just exit this context */ + ExitBatch (NULL); + continue; + } + + if (_tcscspn (fv, _T("?*")) == _tcslen (fv)) + { + /* element is wild file */ + bc->shiftlevel++; /* No use it and shift list */ + } + else + { + /* Wild file spec, find first (or next) file name */ + if (bc->ffind) + { + /* First already done so do next */ + + fv = FindNextFile (bc->hFind, bc->ffind) ? bc->ffind->cFileName : NULL; + } + else + { + /* For first find, allocate a find first block */ + if ((bc->ffind = (LPWIN32_FIND_DATA)malloc (sizeof (WIN32_FIND_DATA))) == NULL) + { + error_out_of_memory(); + return NULL; + } + + bc->hFind = FindFirstFile (fv, bc->ffind); + + fv = !(bc->hFind==INVALID_HANDLE_VALUE) ? bc->ffind->cFileName : NULL; + } + + if (fv == NULL) + { + /* Null indicates no more files.. */ + free (bc->ffind); /* free the buffer */ + bc->ffind = NULL; + bc->shiftlevel++; /* On to next list element */ + continue; + } + } + + /* At this point, fv points to parameter string */ + while (*sp) + { + if ((*sp == _T('%')) && (*(sp + 1) == bc->forvar)) + { + /* replace % var */ + dp = stpcpy (dp, fv); + sp += 2; + } + else + { + /* Else just copy */ + *dp++ = *sp++; + } + } + + *dp = _T('\0'); + + *bLocalEcho = bEcho; + + return textline; + } + + if (!FileGetString (bc->hBatchFile, textline, sizeof (textline))) + { +#ifdef _DEBUG + DebugPrintf (_T("ReadBatchLine(): Reached EOF!\n")); +#endif + /* End of file.... */ + ExitBatch (NULL); + + if (bc == NULL) + return NULL; + + continue; + } + +#ifdef _DEBUG + DebugPrintf (_T("ReadBatchLine(): textline: \'%s\'\n"), textline); +#endif + + /* Strip leading spaces and trailing space/control chars */ + for (first = textline; _istspace (*first); first++) + ; + + for (ip = first + _tcslen (first) - 1; _istspace (*ip) || _istcntrl (*ip); ip--) + ; + + *++ip = _T('\0'); + + /* ignore labels and empty lines */ + if (*first == _T(':') || *first == 0) + continue; + + if (*first == _T('@')) + { + /* don't echo this line */ + do + first++; + while (_istspace (*first)); + + *bLocalEcho = 0; + } + else + *bLocalEcho = bEcho; + + break; + } + + return first; +} + +/* EOF */ diff --git a/subsys/system/cmd/batch.h b/subsys/system/cmd/batch.h new file mode 100644 index 0000000..e7e6fb6 --- /dev/null +++ b/subsys/system/cmd/batch.h @@ -0,0 +1,43 @@ +/* + * BATCH.H - A structure to preserve the context of a batch file + * + * + */ + +#ifndef _BATCH_H_INCLUDED_ +#define _BATCH_H_INCLUDED_ + + +typedef struct tagBATCHCONTEXT +{ + struct tagBATCHCONTEXT *prev; + LPWIN32_FIND_DATA ffind; + HANDLE hBatchFile; + LPTSTR forproto; + LPTSTR params; + INT shiftlevel; + BOOL bEcho; /* Preserve echo flag across batch calls */ + HANDLE hFind; /* Preserve find handle when doing a for */ + TCHAR forvar; +} BATCH_CONTEXT, *LPBATCH_CONTEXT; + + +/* The stack of current batch contexts. + * NULL when no batch is active + */ +extern LPBATCH_CONTEXT bc; + +extern BOOL bEcho; /* The echo flag */ + +#define BATCH_BUFFSIZE 2048 + +extern TCHAR textline[BATCH_BUFFSIZE]; /* Buffer for reading Batch file lines */ + + +LPTSTR FindArg (INT); +LPTSTR BatchParams (LPTSTR, LPTSTR); +VOID ExitBatch (LPTSTR); +BOOL Batch (LPTSTR, LPTSTR, LPTSTR); +LPTSTR ReadBatchLine (LPBOOL); + +#endif /* _BATCH_H_INCLUDED_ */ diff --git a/subsys/system/cmd/beep.c b/subsys/system/cmd/beep.c new file mode 100644 index 0000000..bafe06c --- /dev/null +++ b/subsys/system/cmd/beep.c @@ -0,0 +1,57 @@ +/* + * BEEP.C - beep internal command. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Separated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 14-Jan-1999 (Eric Kohl ) + * Added help text ("beep /?"). + * Unicode ready! + * + * 20-Jan-1999 (Eric Kohl ) + * Redirection ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_BEEP + +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +INT cmd_beep (LPTSTR cmd, LPTSTR param) +{ + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts (_T("Beep the speaker.\n\nBEEP")); + return 0; + } + +#if 0 + /* check if run in batch mode */ + if (bc == NULL) + return 1; +#endif +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + + return 0; +} +#endif diff --git a/subsys/system/cmd/bugs.txt b/subsys/system/cmd/bugs.txt new file mode 100644 index 0000000..da1a2d6 --- /dev/null +++ b/subsys/system/cmd/bugs.txt @@ -0,0 +1,15 @@ + **** Please report bugs to ekohl@rz-online.de! **** + +Known bugs in CMD version 0.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +o let set work with or without the '=' sign. People like it that way. + (I don't know, if I should really fix this?) + +o command.com ignores control-c and control-break, which makes it difficult + to quit typing a long file, among other things + +o "alias v = dir" doesn't work because of the spaces. + + + **** Please report bugs to ekohl@rz-online.de! **** diff --git a/subsys/system/cmd/call.c b/subsys/system/cmd/call.c new file mode 100644 index 0000000..9f31327 --- /dev/null +++ b/subsys/system/cmd/call.c @@ -0,0 +1,95 @@ +/* $Id$ + * + * CALL.C - call internal batch command. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Seperated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 04-Aug-1998 (Hans B Pufal) + * added lines to initialize for pointers (HBP004) This fixed the + * lock-up that happened sometimes when calling a batch file from + * another batch file. + * + * 07-Jan-1999 (Eric Kohl ) + * Added help text ("call /?") and cleaned up. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* + * Perform CALL command. + * + * Allocate a new batch context and add it to the current chain. + * Call parsecommandline passing in our param string + * If No batch file was opened then remove our newly allocted + * context block. + */ + +INT cmd_call (LPTSTR cmd, LPTSTR param) +{ + LPBATCH_CONTEXT n = NULL; + +#ifdef _DEBUG + DebugPrintf ("cmd_call: (\'%s\',\'%s\')\n", cmd, param); +#endif + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Calls one batch program from another.\n\n" + "CALL [drive:][path]filename [batch-parameter]\n\n" + " batch-parameter Specifies any command-line information required by the\n" + " batch program.")); + return 0; + } + + n = (LPBATCH_CONTEXT)malloc (sizeof (BATCH_CONTEXT)); + + if (n == NULL) + { + error_out_of_memory (); + return 1; + } + + n->prev = bc; + bc = n; + + bc->hBatchFile = INVALID_HANDLE_VALUE; + bc->params = NULL; + bc->shiftlevel = 0; + bc->forvar = 0; /* HBP004 */ + bc->forproto = NULL; /* HBP004 */ + + ParseCommandLine (param); + + /* Wasn't a batch file so remove conext */ + if (bc->hBatchFile == INVALID_HANDLE_VALUE) + { + bc = bc->prev; + free (n); + } + + return 0; +} + +/* EOF */ diff --git a/subsys/system/cmd/chcp.c b/subsys/system/cmd/chcp.c new file mode 100644 index 0000000..48d541b --- /dev/null +++ b/subsys/system/cmd/chcp.c @@ -0,0 +1,85 @@ +/* + * CHCP.C - chcp internal command. + * + * + * History: + * + * 23-Dec-1998 (Eric Kohl ) + * Started. + * + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_CHCP + +#include +#include +#include +#include + +#include "cmd.h" + + +INT CommandChcp (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg; + INT args; + UINT uOldCodePage; + UINT uNewCodePage; + + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or sets the active code page number.\n\n" + "CHCP [nnn]\n\n" + " nnn Specifies the active code page number.\n\n" + "Type CHCP without a parameter to display the active code page number.")); + return 0; + } + + if (args == 0) + { + /* display active code page number */ + ConOutPrintf ("Active code page: %u\n", GetConsoleCP ()); + return 0; + } + + if (args >= 2) + { + /* too many parameters */ + ConErrPrintf ("Invalid parameter format - %s\n", param); + return 1; + } + + /* get parameters */ + arg = split (param, &args, FALSE); + + /* save old code page */ + uOldCodePage = GetConsoleCP (); + + uNewCodePage = (UINT)_ttoi (arg[0]); + + if (uNewCodePage == 0) + { + ConErrPrintf ("Parameter format incorrect - %s\n", arg[0]); + freep (arg); + return 1; + } + + if (!SetConsoleCP (uNewCodePage)) + { + ConErrPrintf ("Invalid code page\n"); + } + else + { + SetConsoleOutputCP (uNewCodePage); + InitLocale (); + } + + freep (arg); + + return 0; +} + +#endif /* INCLUDE_CMD_CHCP */ diff --git a/subsys/system/cmd/choice.c b/subsys/system/cmd/choice.c new file mode 100644 index 0000000..97f70f2 --- /dev/null +++ b/subsys/system/cmd/choice.c @@ -0,0 +1,331 @@ +/* + * CHOICE.C - internal command. + * + * + * History: + * + * 12 Aug 1999 (Eric Kohl) + * started. + * + * 01 Sep 1999 (Eric Kohl) + * Fixed help text. + * + * 26 Sep 1999 (Paolo Pantaleo) + * Fixed timeout. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_CHOICE + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +#define GC_TIMEOUT -1 +#define GC_NOKEY 0 //an event occurred but it wasn't a key pressed +#define GC_KEYREAD 1 //a key has been read + + +static INT +GetCharacterTimeout (LPTCH ch, DWORD dwMilliseconds) +{ +//-------------------------------------------- +// Get a character from standard input but with a timeout. +// The function will wait a limited amount +// of time, then the function returns GC_TIMEOUT. +// +// dwMilliseconds is the timeout value, that can +// be set to INFINITE, so the function works like +// stdio.h's getchar() + + HANDLE hInput; + DWORD dwRead; + + INPUT_RECORD lpBuffer; + + hInput = GetStdHandle (STD_INPUT_HANDLE); + + //if the timeout experied return GC_TIMEOUT + if (WaitForSingleObject (hInput, dwMilliseconds) == WAIT_TIMEOUT) + return GC_TIMEOUT; + + //otherwise get the event + ReadConsoleInput (hInput, &lpBuffer, 1, &dwRead); + + //if the event is a key pressed + if ((lpBuffer.EventType == KEY_EVENT) && + (lpBuffer.Event.KeyEvent.bKeyDown == TRUE)) + { + //read the key +#ifdef _UNICODE + *ch = lpBuffer.Event.KeyEvent.uChar.UnicodeChar; +#else + *ch = lpBuffer.Event.KeyEvent.uChar.AsciiChar; +#endif + return GC_KEYREAD; + } + + //else return no key + return GC_NOKEY; +} + +static INT +IsKeyInString (LPTSTR lpString, TCHAR cKey, BOOL bCaseSensitive) +{ + LPTCH p = lpString; + INT val = 0; + + while (*p) + { + if (bCaseSensitive) + { + if (*p == cKey) + return val; + } + else + { + if (_totlower (*p) == _totlower (cKey)) + return val; + } + + val++; + p++; + } + + return -1; +} + + +INT +CommandChoice (LPTSTR cmd, LPTSTR param) +{ + LPTSTR lpOptions = "YN"; + LPTSTR lpText = NULL; + BOOL bNoPrompt = FALSE; + BOOL bCaseSensitive = FALSE; + BOOL bTimeout = FALSE; + INT nTimeout = 0; + TCHAR cDefault = _T('\0'); + INPUT_RECORD ir; + LPTSTR p, np; + LPTSTR *arg; + INT argc; + INT i; + INT val; + + INT GCret; + TCHAR Ch; + DWORD amount,clk; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts (_T("Waits for the user to choose one of a set of choices.\n" + "\n" + "CHOICE [/C[:]choices][/N][/S][/T[:]c,nn][text]\n" + "\n" + " /C[:]choices Specifies allowable keys. Default is YN.\n" + " /N Do not display choices and ? at the end of the prompt string.\n" + " /S Treat choice keys as case sensitive.\n" + " /T[:]c,nn Default choice to c after nn seconds.\n" + " text Prompt string to display.\n" + "\n" + "ERRORLEVEL is set to offset of key user presses in choices.")); + return 0; + } + + /* retrieve text */ + p = param; + + while (TRUE) + { + if (*p == _T('\0')) + break; + + if (*p != _T('/')) + { + lpText = p; + break; + } + np = _tcschr (p, _T(' ')); + if (!np) + break; + p = np + 1; + } + + /* build parameter array */ + arg = split (param, &argc, FALSE); + + /* evaluate arguments */ + if (argc > 0) + { + for (i = 0; i < argc; i++) + { + if (_tcsnicmp (arg[i], _T("/c"), 2) == 0) + { + if (arg[i][2] == _T(':')) + lpOptions = &arg[i][3]; + else + lpOptions = &arg[i][2]; + + if (_tcslen (lpOptions) == 0) + { + ConErrPuts (_T("Invalid option. Expected format: /C[:]options")); + freep (arg); + return 1; + } + } + else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0) + { + bNoPrompt = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0) + { + bCaseSensitive = TRUE; + } + else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0) + { + LPTSTR s; + + if (arg[i][2] == _T(':')) + { + cDefault = arg[i][3]; + s = &arg[i][4]; + } + else + { + cDefault = arg[i][2]; + s = &arg[i][3]; + } + + if (*s != _T(',')) + { + ConErrPuts (_T("Invalid option. Expected format: /T[:]c,nn")); + freep (arg); + return 1; + } + + s++; + nTimeout = _ttoi(s); + bTimeout = TRUE; + } + else if (arg[i][0] == _T('/')) + { + ConErrPrintf (_T("Illegal Option: %s"), arg[i]); + freep (arg); + return 1; + } + } + } + + /* print text */ + if (lpText) + ConOutPrintf (_T("%s"), lpText); + + /* print options */ + if (bNoPrompt == FALSE) + { + ConOutPrintf (_T("[%c"), lpOptions[0]); + + for (i = 1; (unsigned)i < _tcslen (lpOptions); i++) + ConOutPrintf (_T(",%c"), lpOptions[i]); + + ConOutPrintf (_T("]?")); + } + + ConInFlush (); + + if(!bTimeout) + { + while (TRUE) + { + ConInKey (&ir); + + val = IsKeyInString (lpOptions, +#ifdef _UNICODE + ir.Event.KeyEvent.uChar.UnicodeChar, +#else + ir.Event.KeyEvent.uChar.AsciiChar, +#endif /* _UNICODE */ + bCaseSensitive); + + if (val >= 0) + { + ConOutPrintf (_T("%c\n"), lpOptions[val]); + + nErrorLevel = val + 1; + + break; + } + + Beep (440, 50); + } + + freep (arg); + return 0; + } + + clk = GetTickCount (); + amount = nTimeout*1000; + +loop: + GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk)); + + switch (GCret) + { + case GC_TIMEOUT: +#ifdef _DEBUG + DebugPrintf (_T("GC_TIMEOUT\n")); + DebugPrintf (_T("elapsed %d msecs\n"), GetTickCount () - clk); +#endif /* _DEBUG */ + break; + + case GC_NOKEY: +#ifdef _DEBUG + DebugPrintf(_T("GC_NOKEY\n")); + DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk); +#endif /* _DEBUG */ + goto loop; + + case GC_KEYREAD: +#ifdef _DEBUG + DebugPrintf(_T("GC_KEYREAD\n")); + DebugPrintf(_T("elapsed %d msecs\n"), GetTickCount () - clk); + DebugPrintf(_T("read %c"), Ch); +#endif /* _DEBUG */ + if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1) + { + Beep (440, 50); + goto loop; + } + cDefault=Ch; + break; + } + +#ifdef _DEBUG + DebugPrintf(_T("exiting wait loop after %d msecs\n"), + GetTickCount () - clk); +#endif /* _DEBUG */ + + val = IsKeyInString (lpOptions, cDefault, bCaseSensitive); + ConOutPrintf (_T("%c\n"), lpOptions[val]); + + nErrorLevel = val + 1; + + freep (arg); + +#ifdef _DEBUG + DebugPrintf (_T("ErrorLevel: %d\n"), nErrorLevel); +#endif /* _DEBUG */ + + return 0; +} +#endif /* INCLUDE_CMD_CHOICE */ + +/* EOF */ diff --git a/subsys/system/cmd/cls.c b/subsys/system/cmd/cls.c new file mode 100644 index 0000000..e6a5991 --- /dev/null +++ b/subsys/system/cmd/cls.c @@ -0,0 +1,65 @@ +/* + * CLS.C - clear screen internal command. + * + * + * History: + * + * 07/27/1998 (John P. Price) + * started. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 04-Dec-1998 (Eric Kohl ) + * Changed to Win32 console app. + * + * 08-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 14-Jan-1998 (Eric Kohl ) + * Unicode ready! + * + * 20-Jan-1998 (Eric Kohl ) + * Redirection ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_CLS + +#include +#include +#include + +#include "cmd.h" + + +INT cmd_cls (LPTSTR cmd, LPTSTR param) +{ + DWORD dwWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Clears the screen.\n\nCLS")); + return 0; + } + + GetConsoleScreenBufferInfo (hOut, &csbi); + + coPos.X = 0; + coPos.Y = 0; + FillConsoleOutputAttribute (hOut, wColor, + (csbi.dwSize.X)*(csbi.dwSize.Y), + coPos, &dwWritten); + FillConsoleOutputCharacter (hOut, _T(' '), + (csbi.dwSize.X)*(csbi.dwSize.Y), + coPos, &dwWritten); + SetConsoleCursorPosition (hOut, coPos); + + bIgnoreEcho = TRUE; + + return 0; +} +#endif diff --git a/subsys/system/cmd/cmd.c b/subsys/system/cmd/cmd.c new file mode 100644 index 0000000..54cf665 --- /dev/null +++ b/subsys/system/cmd/cmd.c @@ -0,0 +1,1190 @@ +/* $Id$ + * + * CMD.C - command-line interface. + * + * + * History: + * + * 17 Jun 1994 (Tim Norman) + * started. + * + * 08 Aug 1995 (Matt Rains) + * I have cleaned up the source code. changes now bring this source + * into guidelines for recommended programming practice. + * + * A added the the standard FreeDOS GNU licence test to the + * initialize() function. + * + * Started to replace puts() with printf(). this will help + * standardize output. please follow my lead. + * + * I have added some constants to help making changes easier. + * + * 15 Dec 1995 (Tim Norman) + * major rewrite of the code to make it more efficient and add + * redirection support (finally!) + * + * 06 Jan 1996 (Tim Norman) + * finished adding redirection support! Changed to use our own + * exec code (MUCH thanks to Svante Frey!!) + * + * 29 Jan 1996 (Tim Norman) + * added support for CHDIR, RMDIR, MKDIR, and ERASE, as per + * suggestion of Steffan Kaiser + * + * changed "file not found" error message to "bad command or + * filename" thanks to Dustin Norman for noticing that confusing + * message! + * + * changed the format to call internal commands (again) so that if + * they want to split their commands, they can do it themselves + * (none of the internal functions so far need that much power, anyway) + * + * 27 Aug 1996 (Tim Norman) + * added in support for Oliver Mueller's ALIAS command + * + * 14 Jun 1997 (Steffan Kaiser) + * added ctrl-break handling and error level + * + * 16 Jun 1998 (Rob Lake) + * Runs command.com if /P is specified in command line. Command.com + * also stays permanent. If /C is in the command line, starts the + * program next in the line. + * + * 21 Jun 1998 (Rob Lake) + * Fixed up /C so that arguments for the program + * + * 08-Jul-1998 (John P. Price) + * Now sets COMSPEC environment variable + * misc clean up and optimization + * added date and time commands + * changed to using spawnl instead of exec. exec does not copy the + * environment to the child process! + * + * 14 Jul 1998 (Hans B Pufal) + * Reorganised source to be more efficient and to more closely + * follow MS-DOS conventions. (eg %..% environment variable + * replacement works form command line as well as batch file. + * + * New organisation also properly support nested batch files. + * + * New command table structure is half way towards providing a + * system in which COMMAND will find out what internal commands + * are loaded + * + * 24 Jul 1998 (Hans B Pufal) [HBP_003] + * Fixed return value when called with /C option + * + * 27 Jul 1998 John P. Price + * added config.h include + * + * 28 Jul 1998 John P. Price + * added showcmds function to show commands and options available + * + * 07-Aug-1998 (John P Price ) + * Fixed carrage return output to better match MSDOS with echo + * on or off. (marked with "JPP 19980708") + * + * 07-Dec-1998 (Eric Kohl ) + * First ReactOS release. + * Extended length of commandline buffers to 512. + * + * 13-Dec-1998 (Eric Kohl ) + * Added COMSPEC environment variable. + * Added "/t" support (color) on cmd command line. + * + * 07-Jan-1999 (Eric Kohl ) + * Added help text ("cmd /?"). + * + * 25-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * Fixed redirections and piping. + * Piping is based on temporary files, but basic support + * for anonymous pipes already exists. + * + * 27-Jan-1999 (Eric Kohl ) + * Replaced spawnl() by CreateProcess(). + * + * 22-Oct-1999 (Eric Kohl ) + * Added break handler. + * + * 15-Dec-1999 (Eric Kohl ) + * Fixed current directory + * + * 28-Dec-1999 (Eric Kohl ) + * Restore window title after program/batch execution + * + * 03-Feb-2001 (Eric Kohl ) + * Workaround because argc[0] is NULL under ReactOS + * + * 23-Feb-2001 (Carl Nettelblad ) + * %envvar% replacement conflicted with for. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +BOOL bExit = FALSE; /* indicates EXIT was typed */ +BOOL bCanExit = TRUE; /* indicates if this shell is exitable */ +BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */ +BOOL bIgnoreEcho = FALSE; /* Ignore 'newline' before 'cls' */ +INT nErrorLevel = 0; /* Errorlevel of last launched external program */ +BOOL bChildProcessRunning = FALSE; +DWORD dwChildProcessId = 0; +OSVERSIONINFO osvi; +HANDLE hIn; +HANDLE hOut; + +#ifdef INCLUDE_CMD_COLOR +WORD wColor; /* current color */ +WORD wDefColor; /* default color */ +#endif + + +/* + * is character a delimeter when used on first word? + * + */ + +static BOOL IsDelimiter (TCHAR c) +{ + return (c == _T('/') || c == _T('=') || c == _T('\0') || _istspace (c)); +} + + +/* + * This command (in first) was not found in the command table + * + * first - first word on command line + * rest - rest of command line + */ + +static VOID +Execute (LPTSTR first, LPTSTR rest) +{ + TCHAR szFullName[MAX_PATH]; +#ifndef __REACTOS__ + TCHAR szWindowTitle[MAX_PATH]; +#endif + DWORD dwExitCode = 0; + +#ifdef _DEBUG + DebugPrintf ("Execute: \'%s\' \'%s\'\n", first, rest); +#endif + + /* check for a drive change */ + if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":")))) + { + BOOL working = TRUE; + if (!SetCurrentDirectory(first)) + /* Guess they changed disc or something, handle that gracefully and get to root */ + { + TCHAR str[4]; + str[0]=first[0]; + str[1]=':'; + str[2]='\\'; + str[3]=0; + working = SetCurrentDirectory(str); + } + + if (!working) ConErrPuts (INVALIDDRIVE); + + return; + } + + /* get the PATH environment variable and parse it */ + /* search the PATH environment variable for the binary */ + if (!SearchForExecutable (first, szFullName)) + { + error_bad_command (); + return; + } + +#ifndef __REACTOS__ + GetConsoleTitle (szWindowTitle, MAX_PATH); +#endif + + /* check if this is a .BAT or .CMD file */ + if (!_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".bat")) || + !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd"))) + { +#ifdef _DEBUG + DebugPrintf ("[BATCH: %s %s]\n", szFullName, rest); +#endif + Batch (szFullName, first, rest); + } + else + { + /* exec the program */ + TCHAR szFullCmdLine [CMDLINE_LENGTH]; + PROCESS_INFORMATION prci; + STARTUPINFO stui; + +#ifdef _DEBUG + DebugPrintf ("[EXEC: %s %s]\n", szFullName, rest); +#endif + /* build command line for CreateProcess() */ + _tcscpy (szFullCmdLine, first); + _tcscat (szFullCmdLine, _T(" ")); + _tcscat (szFullCmdLine, rest); + + /* fill startup info */ + memset (&stui, 0, sizeof (STARTUPINFO)); + stui.cb = sizeof (STARTUPINFO); + stui.dwFlags = STARTF_USESHOWWINDOW; + stui.wShowWindow = SW_SHOWDEFAULT; + + // return console to standard mode + SetConsoleMode (GetStdHandle(STD_INPUT_HANDLE), + ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); + + if (CreateProcess (szFullName, + szFullCmdLine, + NULL, + NULL, + FALSE, + CREATE_NEW_PROCESS_GROUP, + NULL, + NULL, + &stui, + &prci)) + { + /* FIXME: Protect this with critical section */ + bChildProcessRunning = TRUE; + dwChildProcessId = prci.dwProcessId; + + WaitForSingleObject (prci.hProcess, INFINITE); + + /* FIXME: Protect this with critical section */ + bChildProcessRunning = TRUE; + + GetExitCodeProcess (prci.hProcess, &dwExitCode); + nErrorLevel = (INT)dwExitCode; + CloseHandle (prci.hThread); + CloseHandle (prci.hProcess); + } + else + { + ErrorMessage (GetLastError (), + "Error executing CreateProcess()!!\n"); + } + // restore console mode + SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ), + ENABLE_PROCESSED_INPUT ); + } + +#ifndef __REACTOS__ + SetConsoleTitle (szWindowTitle); +#endif +} + + +/* + * look through the internal commands and determine whether or not this + * command is one of them. If it is, call the command. If not, call + * execute to run it as an external program. + * + * line - the command line of the program to run + * + */ + +static VOID +DoCommand (LPTSTR line) +{ + TCHAR com[MAX_PATH]; /* the first word in the command */ + LPTSTR cp = com; + LPTSTR cstart; + LPTSTR rest = line; /* pointer to the rest of the command line */ + INT cl; + LPCOMMAND cmdptr; + +#ifdef _DEBUG + DebugPrintf ("DoCommand: (\'%s\')\n", line); +#endif /* DEBUG */ + + /* Skip over initial white space */ + while (isspace (*rest)) + rest++; + + cstart = rest; + + /* Anything to do ? */ + if (*rest) + { + if (*rest == _T('"')) + { + /* treat quoted words specially */ + + rest++; + + while(*rest != _T('\0') && *rest != _T('"')) + *cp++ = _totlower (*rest++); + } + else + { + while (!IsDelimiter (*rest)) + *cp++ = _totlower (*rest++); + } + + + /* Terminate first word */ + *cp = _T('\0'); + + /* Skip over whitespace to rest of line */ + while (_istspace (*rest)) + rest++; + + /* Scan internal command table */ + for (cmdptr = cmds;; cmdptr++) + { + /* If end of table execute ext cmd */ + if (cmdptr->name == NULL) + { + Execute (com, rest); + break; + } + + if (!_tcscmp (com, cmdptr->name)) + { + cmdptr->func (com, rest); + break; + } + + /* The following code handles the case of commands like CD which + * are recognised even when the command name and parameter are + * not space separated. + * + * e.g dir.. + * cd\freda + */ + + /* Get length of command name */ + cl = _tcslen (cmdptr->name); + + if ((cmdptr->flags & CMD_SPECIAL) && + (!_tcsncmp (cmdptr->name, com, cl)) && + (_tcschr (_T("\\.-"), *(com + cl)))) + { + /* OK its one of the specials...*/ + + /* Terminate first word properly */ + com[cl] = _T('\0'); + + /* Call with new rest */ + cmdptr->func (com, cstart + cl); + break; + } + } + } +} + + +/* + * process the command line and execute the appropriate functions + * full input/output redirection and piping are supported + */ + +VOID ParseCommandLine (LPTSTR cmd) +{ + TCHAR cmdline[CMDLINE_LENGTH]; + LPTSTR s; +#ifdef FEATURE_REDIRECTION + TCHAR in[CMDLINE_LENGTH] = ""; + TCHAR out[CMDLINE_LENGTH] = ""; + TCHAR err[CMDLINE_LENGTH] = ""; + TCHAR szTempPath[MAX_PATH] = _T(".\\"); + TCHAR szFileName[2][MAX_PATH] = {"", ""}; + HANDLE hFile[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + LPTSTR t = NULL; + INT num = 0; + INT nRedirFlags = 0; + + HANDLE hOldConIn; + HANDLE hOldConOut; + HANDLE hOldConErr; +#endif /* FEATURE_REDIRECTION */ + + _tcscpy (cmdline, cmd); + s = &cmdline[0]; + +#ifdef _DEBUG + DebugPrintf ("ParseCommandLine: (\'%s\')\n", s); +#endif /* DEBUG */ + +#ifdef FEATURE_ALIASES + /* expand all aliases */ + ExpandAlias (s, CMDLINE_LENGTH); +#endif /* FEATURE_ALIAS */ + +#ifdef FEATURE_REDIRECTION + /* find the temp path to store temporary files */ + GetTempPath (MAX_PATH, szTempPath); + if (szTempPath[_tcslen (szTempPath) - 1] != _T('\\')) + _tcscat (szTempPath, _T("\\")); + + /* get the redirections from the command line */ + num = GetRedirection (s, in, out, err, &nRedirFlags); + + /* more efficient, but do we really need to do this? */ + for (t = in; _istspace (*t); t++) + ; + _tcscpy (in, t); + + for (t = out; _istspace (*t); t++) + ; + _tcscpy (out, t); + + for (t = err; _istspace (*t); t++) + ; + _tcscpy (err, t); + + /* Set up the initial conditions ... */ + /* preserve STDIN, STDOUT and STDERR handles */ + hOldConIn = GetStdHandle (STD_INPUT_HANDLE); + hOldConOut = GetStdHandle (STD_OUTPUT_HANDLE); + hOldConErr = GetStdHandle (STD_ERROR_HANDLE); + + /* redirect STDIN */ + if (in[0]) + { + HANDLE hFile; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + + hFile = CreateFile (in, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + ConErrPrintf ("Can't redirect input from file %s\n", in); + return; + } + + if (!SetStdHandle (STD_INPUT_HANDLE, hFile)) + { + ConErrPrintf ("Can't redirect input from file %s\n", in); + return; + } +#ifdef _DEBUG + DebugPrintf (_T("Input redirected from: %s\n"), in); +#endif + } + + /* Now do all but the last pipe command */ + *szFileName[0] = '\0'; + hFile[0] = INVALID_HANDLE_VALUE; + + while (num-- > 1) + { + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + + /* Create unique temporary file name */ + GetTempFileName (szTempPath, "CMD", 0, szFileName[1]); + + /* Set current stdout to temporary file */ + hFile[1] = CreateFile (szFileName[1], GENERIC_WRITE, 0, &sa, + TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL); + SetStdHandle (STD_OUTPUT_HANDLE, hFile[1]); + + DoCommand (s); + + /* close stdout file */ + SetStdHandle (STD_OUTPUT_HANDLE, hOldConOut); + if ((hFile[1] != INVALID_HANDLE_VALUE) && (hFile[1] != hOldConOut)) + { + CloseHandle (hFile[1]); + hFile[1] = INVALID_HANDLE_VALUE; + } + + /* close old stdin file */ + SetStdHandle (STD_INPUT_HANDLE, hOldConIn); + if ((hFile[0] != INVALID_HANDLE_VALUE) && (hFile[0] != hOldConIn)) + { + /* delete old stdin file, if it is a real file */ + CloseHandle (hFile[0]); + hFile[0] = INVALID_HANDLE_VALUE; + DeleteFile (szFileName[0]); + *szFileName[0] = _T('\0'); + } + + /* copy stdout file name to stdin file name */ + _tcscpy (szFileName[0], szFileName[1]); + *szFileName[1] = _T('\0'); + + /* open new stdin file */ + hFile[0] = CreateFile (szFileName[0], GENERIC_READ, 0, &sa, + OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL); + SetStdHandle (STD_INPUT_HANDLE, hFile[0]); + + s = s + _tcslen (s) + 1; + } + + /* Now set up the end conditions... */ + /* redirect STDOUT */ + if (out[0]) + { + /* Final output to here */ + HANDLE hFile; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + + hFile = CreateFile (out, GENERIC_WRITE, FILE_SHARE_READ, &sa, + (nRedirFlags & OUTPUT_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + ConErrPrintf ("Can't redirect to file %s\n", out); + return; + } + + if (!SetStdHandle (STD_OUTPUT_HANDLE, hFile)) + { + ConErrPrintf ("Can't redirect to file %s\n", out); + return; + } + + if (nRedirFlags & OUTPUT_APPEND) + { + LONG lHighPos = 0; + + if (GetFileType (hFile) == FILE_TYPE_DISK) + SetFilePointer (hFile, 0, &lHighPos, FILE_END); + } +#ifdef _DEBUG + DebugPrintf (_T("Output redirected to: %s\n"), out); +#endif + } + else if (hOldConOut != INVALID_HANDLE_VALUE) + { + /* Restore original stdout */ + HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE); + SetStdHandle (STD_OUTPUT_HANDLE, hOldConOut); + if (hOldConOut != hOut) + CloseHandle (hOut); + hOldConOut = INVALID_HANDLE_VALUE; + } + + /* redirect STDERR */ + if (err[0]) + { + /* Final output to here */ + HANDLE hFile; + SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + + if (!_tcscmp (err, out)) + { +#ifdef _DEBUG + DebugPrintf (_T("Stdout and stderr will use the same file!!\n")); +#endif + DuplicateHandle (GetCurrentProcess (), + GetStdHandle (STD_OUTPUT_HANDLE), + GetCurrentProcess (), + &hFile, 0, TRUE, DUPLICATE_SAME_ACCESS); + } + else + { + hFile = CreateFile (err, + GENERIC_WRITE, + 0, + &sa, + (nRedirFlags & ERROR_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + ConErrPrintf ("Can't redirect to file %s\n", err); + return; + } + } + if (!SetStdHandle (STD_ERROR_HANDLE, hFile)) + { + ConErrPrintf ("Can't redirect to file %s\n", err); + return; + } + + if (nRedirFlags & ERROR_APPEND) + { + LONG lHighPos = 0; + + if (GetFileType (hFile) == FILE_TYPE_DISK) + SetFilePointer (hFile, 0, &lHighPos, FILE_END); + } +#ifdef _DEBUG + DebugPrintf (_T("Error redirected to: %s\n"), err); +#endif + } + else if (hOldConErr != INVALID_HANDLE_VALUE) + { + /* Restore original stderr */ + HANDLE hErr = GetStdHandle (STD_ERROR_HANDLE); + SetStdHandle (STD_ERROR_HANDLE, hOldConErr); + if (hOldConErr != hErr) + CloseHandle (hErr); + hOldConErr = INVALID_HANDLE_VALUE; + } +#endif + + /* process final command */ + DoCommand (s); + +#ifdef FEATURE_REDIRECTION + /* close old stdin file */ +#if 0 /* buggy implementation */ + SetStdHandle (STD_INPUT_HANDLE, hOldConIn); + if ((hFile[0] != INVALID_HANDLE_VALUE) && + (hFile[0] != hOldConIn)) + { + /* delete old stdin file, if it is a real file */ + CloseHandle (hFile[0]); + hFile[0] = INVALID_HANDLE_VALUE; + DeleteFile (szFileName[0]); + *szFileName[0] = _T('\0'); + } + + /* Restore original STDIN */ + if (hOldConIn != INVALID_HANDLE_VALUE) + { + HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE); + SetStdHandle (STD_INPUT_HANDLE, hOldConIn); + if (hOldConIn != hIn) + CloseHandle (hIn); + hOldConIn = INVALID_HANDLE_VALUE; + } + else + { +#ifdef _DEBUG + DebugPrintf (_T("Can't restore STDIN! Is invalid!!\n"), out); +#endif + } +#endif /* buggy implementation */ + + + if (hOldConIn != INVALID_HANDLE_VALUE) + { + HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE); + SetStdHandle (STD_INPUT_HANDLE, hOldConIn); + if (hIn == INVALID_HANDLE_VALUE) + { +#ifdef _DEBUG + DebugPrintf (_T("Previous STDIN is invalid!!\n")); +#endif + } + else + { + if (GetFileType (hIn) == FILE_TYPE_DISK) + { + if (hFile[0] == hIn) + { + CloseHandle (hFile[0]); + hFile[0] = INVALID_HANDLE_VALUE; + DeleteFile (szFileName[0]); + *szFileName[0] = _T('\0'); + } + else + { +#ifdef _DEBUG + DebugPrintf (_T("hFile[0] and hIn dont match!!!\n")); +#endif + } + } + } + } + + + /* Restore original STDOUT */ + if (hOldConOut != INVALID_HANDLE_VALUE) + { + HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE); + SetStdHandle (STD_OUTPUT_HANDLE, hOldConOut); + if (hOldConOut != hOut) + CloseHandle (hOut); + hOldConOut = INVALID_HANDLE_VALUE; + } + + /* Restore original STDERR */ + if (hOldConErr != INVALID_HANDLE_VALUE) + { + HANDLE hErr = GetStdHandle (STD_ERROR_HANDLE); + SetStdHandle (STD_ERROR_HANDLE, hOldConErr); + if (hOldConErr != hErr) + CloseHandle (hErr); + hOldConErr = INVALID_HANDLE_VALUE; + } +#endif /* FEATURE_REDIRECTION */ +} + + +/* + * do the prompt/input/process loop + * + */ + +static INT +ProcessInput (BOOL bFlag) +{ + TCHAR commandline[CMDLINE_LENGTH]; + TCHAR readline[CMDLINE_LENGTH]; + LPTSTR tp = NULL; + LPTSTR ip; + LPTSTR cp; + BOOL bEchoThisLine; + + do + { + /* if no batch input then... */ + if (!(ip = ReadBatchLine (&bEchoThisLine))) + { + if (bFlag) + return 0; + + ReadCommand (readline, CMDLINE_LENGTH); + ip = readline; + bEchoThisLine = FALSE; + } + + cp = commandline; + while (*ip) + { + if (*ip == _T('%')) + { + switch (*++ip) + { + case _T('%'): + *cp++ = *ip++; + break; + + case _T('0'): + case _T('1'): + case _T('2'): + case _T('3'): + case _T('4'): + case _T('5'): + case _T('6'): + case _T('7'): + case _T('8'): + case _T('9'): + if ((tp = FindArg (*ip - _T('0')))) + { + cp = stpcpy (cp, tp); + ip++; + } + else + *cp++ = _T('%'); + break; + + case _T('?'): + cp += _stprintf (cp, _T("%u"), nErrorLevel); + ip++; + break; + + default: + tp = _tcschr(ip, _T('%')); + if ((tp != NULL) && + (tp <= _tcschr(ip, _T(' ')) - 1)) + { + char evar[512]; + *tp = _T('\0'); + + /* FIXME: This is just a quick hack!! */ + /* Do a proper memory allocation!! */ + if (GetEnvironmentVariable (ip, evar, 512)) + cp = stpcpy (cp, evar); + + ip = tp + 1; + } + else + { + *cp++ = _T('%'); + } + break; + } + continue; + } + + if (_istcntrl (*ip)) + *ip = _T(' '); + *cp++ = *ip++; + } + + *cp = _T('\0'); + + /* strip trailing spaces */ + while ((--cp >= commandline) && _istspace (*cp)); + + *(cp + 1) = _T('\0'); + + /* JPP 19980807 */ + /* Echo batch file line */ + if (bEchoThisLine) + { + PrintPrompt (); + ConOutPuts (commandline); + } + + if (*commandline) + { + ParseCommandLine (commandline); + if (bEcho && !bIgnoreEcho) + ConOutChar ('\n'); + bIgnoreEcho = FALSE; + } + } + while (!bCanExit || !bExit); + + return 0; +} + + +/* + * control-break handler. + */ +BOOL BreakHandler (DWORD dwCtrlType) +{ + if ((dwCtrlType != CTRL_C_EVENT) && + (dwCtrlType != CTRL_BREAK_EVENT)) + return FALSE; + + if (bChildProcessRunning == TRUE) + { + GenerateConsoleCtrlEvent (CTRL_C_EVENT, + dwChildProcessId); + return TRUE; + } + + /* FIXME: Handle batch files */ + + /* FIXME: Print "^C" */ + + + return TRUE; +} + + +VOID AddBreakHandler (VOID) +{ +#ifndef __REACTOS__ + SetConsoleCtrlHandler ((PHANDLER_ROUTINE)&BreakHandler, + TRUE); +#endif +} + + +VOID RemoveBreakHandler (VOID) +{ +#ifndef __REACTOS__ + SetConsoleCtrlHandler (NULL, FALSE); +#endif +} + + +/* + * show commands and options that are available. + * + */ +static VOID +ShowCommands (VOID) +{ + /* print command list */ + ConOutPrintf (_T("\nInternal commands available:\n")); + PrintCommandList (); + + /* print feature list */ + ConOutPuts ("\nFeatures available:"); +#ifdef FEATURE_ALIASES + ConOutPuts (" [aliases]"); +#endif +#ifdef FEATURE_HISTORY + ConOutPuts (" [history]"); +#endif +#ifdef FEATURE_UNIX_FILENAME_COMPLETION + ConOutPuts (" [unix filename completion]"); +#endif +#ifdef FEATURE_DIRECTORY_STACK + ConOutPuts (" [directory stack]"); +#endif +#ifdef FEATURE_REDIRECTION + ConOutPuts (" [redirections and piping]"); +#endif + ConOutChar ('\n'); +} + + +/* + * set up global initializations and process parameters + * + * argc - number of parameters to command.com + * argv - command-line parameters + * + */ +static VOID +Initialize (int argc, char *argv[]) +{ + TCHAR commandline[CMDLINE_LENGTH]; + TCHAR ModuleName[_MAX_PATH + 1]; + INT i; + +#ifdef _DEBUG + INT x; + + DebugPrintf ("[command args:\n"); + for (x = 0; x < argc; x++) + { + DebugPrintf ("%d. %s\n", x, argv[x]); + } + DebugPrintf ("]\n"); +#endif + + /* get version information */ + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx (&osvi); + + InitLocale (); + + /* get default input and output console handles */ + hOut = GetStdHandle (STD_OUTPUT_HANDLE); + hIn = GetStdHandle (STD_INPUT_HANDLE); + + + if (argc >= 2 && !_tcsncmp (argv[1], _T("/?"), 2)) + { + ConOutPuts (_T("Starts a new instance of the ReactOS command line interpreter.\n" + "\n" + "CMD [/[C|K] command][/P][/Q][/T:bf]\n" + "\n" + " /C command Runs the specified command and terminates.\n" + " /K command Runs the specified command and remains.\n" + " /P CMD becomes permanent and runs autoexec.bat\n" + " (cannot be terminated).\n" + " /T:bf Sets the background/foreground color (see COLOR command).")); + ExitProcess (0); + } + SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT); + +#ifdef INCLUDE_CMD_CHDIR + InitLastPath (); +#endif + +#ifdef FATURE_ALIASES + InitializeAlias (); +#endif + + if (argc >= 2) + { + for (i = 1; i < argc; i++) + { + if (!_tcsicmp (argv[i], _T("/p"))) + { + if (!IsValidFileName (_T("\\autoexec.bat"))) + { +#ifdef INCLUDE_CMD_DATE + cmd_date ("", ""); +#endif +#ifdef INCLUDE_CMD_TIME + cmd_time ("", ""); +#endif + } + else + { + ParseCommandLine (_T("\\autoexec.bat")); + } + bCanExit = FALSE; + } + else if (!_tcsicmp (argv[i], _T("/c"))) + { + /* This just runs a program and exits */ + ++i; + if (argv[i]) + { + _tcscpy (commandline, argv[i]); + while (argv[++i]) + { + _tcscat (commandline, " "); + _tcscat (commandline, argv[i]); + } + + ParseCommandLine(commandline); + ExitProcess (ProcessInput (TRUE)); + } + else + { + ExitProcess (0); + } + } + else if (!_tcsicmp (argv[i], _T("/k"))) + { + /* This just runs a program and remains */ + ++i; + if (argv[i]) + { + _tcscpy (commandline, argv[i]); + while (argv[++i]) + { + _tcscat (commandline, " "); + _tcscat (commandline, argv[i]); + } + + ParseCommandLine(commandline); + } + } +#ifdef INCLUDE_CMD_COLOR + else if (!_tcsnicmp (argv[i], _T("/t:"), 3)) + { + /* process /t (color) argument */ + wDefColor = (WORD)strtoul (&argv[i][3], NULL, 16); + wColor = wDefColor; + SetScreenColor (wColor, TRUE); + } +#endif + } + } + + /* run cmdstart.bat */ + if (IsValidFileName (_T("cmdstart.bat"))) + { + ParseCommandLine (_T("cmdstart.bat")); + } + else if (IsValidFileName (_T("\\cmdstart.bat"))) + { + ParseCommandLine (_T("\\cmdstart.bat")); + } +#ifndef __REACTOS__ + else + { + /* try to run cmdstart.bat from install dir */ + LPTSTR p; + + _tcscpy (commandline, argv[0]); + p = _tcsrchr (commandline, _T('\\')) + 1; + _tcscpy (p, _T("cmdstart.bat")); + + if (IsValidFileName (_T("commandline"))) + { + ConErrPrintf ("Running %s...\n", commandline); + ParseCommandLine (commandline); + } + } +#endif + +#ifdef FEATURE_DIR_STACK + /* initialize directory stack */ + InitDirectoryStack (); +#endif + + +#ifdef FEATURE_HISTORY + /*initialize history*/ + InitHistory(); +#endif + + /* Set COMSPEC environment variable */ + if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1)) + { + ModuleName[_MAX_PATH] = _T('\0'); + SetEnvironmentVariable (_T("COMSPEC"), ModuleName); + } + + /* add ctrl break handler */ + AddBreakHandler (); +} + + +static VOID Cleanup (int argc, char *argv[]) +{ + /* run cmdexit.bat */ + if (IsValidFileName (_T("cmdexit.bat"))) + { + ConErrPrintf ("Running cmdexit.bat...\n"); + ParseCommandLine (_T("cmdexit.bat")); + } + else if (IsValidFileName (_T("\\cmdexit.bat"))) + { + ConErrPrintf ("Running \\cmdexit.bat...\n"); + ParseCommandLine (_T("\\cmdexit.bat")); + } +#ifndef __REACTOS__ + else + { + /* try to run cmdexit.bat from install dir */ + TCHAR commandline[CMDLINE_LENGTH]; + LPTSTR p; + + _tcscpy (commandline, argv[0]); + p = _tcsrchr (commandline, _T('\\')) + 1; + _tcscpy (p, _T("cmdexit.bat")); + + if (IsValidFileName (_T("commandline"))) + { + ConErrPrintf ("Running %s...\n", commandline); + ParseCommandLine (commandline); + } + } +#endif + +#ifdef FEATURE_ALIASES + DestroyAlias (); +#endif + +#ifdef FEATURE_DIECTORY_STACK + /* destroy directory stack */ + DestroyDirectoryStack (); +#endif + +#ifdef INCLUDE_CMD_CHDIR + FreeLastPath (); +#endif + +#ifdef FEATURE_HISTORY + CleanHistory(); +#endif + + + /* remove ctrl break handler */ + RemoveBreakHandler (); + SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ), + ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT ); +} + + +/* + * main function + */ +int main (int argc, char *argv[]) +{ + CONSOLE_SCREEN_BUFFER_INFO Info; + INT nExitCode; + + SetFileApisToOEM(); + + AllocConsole(); + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Info) == FALSE) + { + fprintf(stderr, "GetConsoleScreenBufferInfo: Error: %ld\n", GetLastError()); +#ifndef __REACTOS__ + /* On ReactOS GetConsoleScreenBufferInfo returns an error if the stdin + handle is redirected to a pipe or file. This stops windres from working. */ + return(1); +#endif + } + wColor = Info.wAttributes; + wDefColor = wColor; + + /* check switches on command-line */ + Initialize(argc, argv); + + /* call prompt routine */ + nExitCode = ProcessInput(FALSE); + + /* do the cleanup */ + Cleanup(argc, argv); + + return(nExitCode); +} + +/* EOF */ diff --git a/subsys/system/cmd/cmd.h b/subsys/system/cmd/cmd.h new file mode 100644 index 0000000..3378fc5 --- /dev/null +++ b/subsys/system/cmd/cmd.h @@ -0,0 +1,415 @@ +/* $Id$ + * + * CMD.H - header file for the modules in CMD.EXE + * + * + * History: + * + * 7-15-95 Tim Norman + * started + * + * 06/29/98 (Rob Lake) + * Moved error messages in here + * + * 07/12/98 (Rob Lake) + * Moved more error messages here. + * + * 30-Jul-1998 (John P Price ) + * Added compile date to version. + * + * 26-Feb-1999 (Eric Kohl ) + * Introduced a new version string. + * Thanks to Emanuele Aliberti! + */ + +#ifndef _CMD_H_INCLUDED_ +#define _CMD_H_INCLUDED_ + +#include "config.h" + +#include +#include + +#include "cmdver.h" + +#ifdef _MSC_VER +#define SHELLVER "Version " CMD_VER " [" __DATE__ ", msc]" +#else +#ifdef __LCC__ +#define SHELLVER "Version " CMD_VER " [" __DATE__ ", lcc-win32]" +#else +#define SHELLVER "Version " CMD_VER " [" __DATE__ "]" +#endif +#endif + + +#define BREAK_BATCHFILE 1 +#define BREAK_OUTOFBATCH 2 +#define BREAK_INPUT 3 +#define BREAK_IGNORE 4 + +/* define some error messages */ +#define NOENVERR "ERROR: no environment" +#define INVALIDDRIVE "ERROR: invalid drive" +#define INVALIDFUNCTION "ERROR: invalid function" +#define ACCESSDENIED "ERROR: access denied" +#define BADENVIROMENT "ERROR: bad enviroment" +#define BADFORMAT "ERROR: bad format" +#define ERROR_E2BIG "ERROR: Argument list too long" +#define ERROR_EINVAL "ERROR: Invalid argument" + +#define SHELLINFO "ReactOS Command Line Interpreter" + + +#define D_ON "on" +#define D_OFF "off" + + +/* command line buffer length */ +#ifdef __REACTOS__ +#define CMDLINE_LENGTH 512 +#else +#define CMDLINE_LENGTH 8192 +//#define CMDLINE_LENGTH 1024 +#endif + +/* global variables */ +extern HANDLE hOut; +extern HANDLE hIn; +extern WORD wColor; +extern WORD wDefColor; +extern BOOL bCtrlBreak; +extern BOOL bIgnoreEcho; +extern BOOL bExit; +extern INT nErrorLevel; +extern SHORT maxx; +extern SHORT maxy; +extern OSVERSIONINFO osvi; + + + +/* Prototypes for ALIAS.C */ +VOID InitializeAlias (VOID); +VOID DestroyAlias (VOID); +VOID ExpandAlias (LPTSTR, INT); +INT CommandAlias (LPTSTR, LPTSTR); + + +/* Prototypes for ATTRIB.C */ +INT CommandAttrib (LPTSTR, LPTSTR); + + +/* Prototypes for BEEP.C */ +INT cmd_beep (LPTSTR, LPTSTR); + + +/* Prototypes for CALL.C */ +INT cmd_call (LPTSTR, LPTSTR); + + +/* Prototypes for CHCP.C */ +INT CommandChcp (LPTSTR, LPTSTR); + + +/* Prototypes for CHOICE.C */ +INT CommandChoice (LPTSTR, LPTSTR); + + +/* Prototypes for CLS.C */ +INT cmd_cls (LPTSTR, LPTSTR); + + +/* Prototypes for CMD.C */ +VOID ParseCommandLine (LPTSTR); +VOID AddBreakHandler (VOID); +VOID RemoveBreakHandler (VOID); + + +/* Prototypes for CMDINPUT.C */ +VOID ReadCommand (LPTSTR, INT); + + +/* Prototypes for CMDTABLE.C */ +#define CMD_SPECIAL 1 +#define CMD_BATCHONLY 2 +#define CMD_HIDE 4 + +typedef struct tagCOMMAND +{ + LPTSTR name; + INT flags; + INT (*func) (LPTSTR, LPTSTR); +} COMMAND, *LPCOMMAND; + +extern COMMAND cmds[]; /* The internal command table */ + +VOID PrintCommandList (VOID); + + +/* Prototypes for COLOR.C */ +VOID SetScreenColor(WORD wArgColor, BOOL bFill); +INT CommandColor (LPTSTR, LPTSTR); + + +/* Prototypes for CONSOLE.C */ +#ifdef _DEBUG +VOID DebugPrintf (LPTSTR, ...); +#endif /* _DEBUG */ + +VOID ConInDummy (VOID); +VOID ConInDisable (VOID); +VOID ConInEnable (VOID); +VOID ConInFlush (VOID); +VOID ConInKey (PINPUT_RECORD); +VOID ConInString (LPTSTR, DWORD); + +VOID ConOutChar (TCHAR); +VOID ConOutPuts (LPTSTR); +VOID ConOutPrintf (LPTSTR, ...); +VOID ConErrChar (TCHAR); +VOID ConErrPuts (LPTSTR); +VOID ConErrPrintf (LPTSTR, ...); + +SHORT GetCursorX (VOID); +SHORT GetCursorY (VOID); +VOID GetCursorXY (PSHORT, PSHORT); +VOID SetCursorXY (SHORT, SHORT); + +VOID GetScreenSize (PSHORT, PSHORT); +VOID SetCursorType (BOOL, BOOL); + + +/* Prototypes for COPY.C */ +INT cmd_copy (LPTSTR, LPTSTR); + + +/* Prototypes for DATE.C */ +INT cmd_date (LPTSTR, LPTSTR); + + +/* Prototypes for DEL.C */ +INT CommandDelete (LPTSTR, LPTSTR); + + +/* Prototypes for DELAY.C */ +INT CommandDelay (LPTSTR, LPTSTR); + + +/* Prototypes for DIR.C */ +INT CommandDir (LPTSTR, LPTSTR); + + +/* Prototypes for DIRSTACK.C */ +VOID InitDirectoryStack (VOID); +VOID DestroyDirectoryStack (VOID); +INT GetDirectoryStackDepth (VOID); +INT CommandPushd (LPTSTR, LPTSTR); +INT CommandPopd (LPTSTR, LPTSTR); +INT CommandDirs (LPTSTR, LPTSTR); + + +/* Prototypes for ECHO.C */ +INT CommandEcho (LPTSTR, LPTSTR); +INT CommandEchos (LPTSTR, LPTSTR); +INT CommandEchoerr (LPTSTR, LPTSTR); +INT CommandEchoserr (LPTSTR, LPTSTR); + + +/* Prototypes for ERROR.C */ +VOID ErrorMessage (DWORD, LPTSTR, ...); + +VOID error_no_pipe (VOID); +VOID error_bad_command (VOID); +VOID error_invalid_drive (VOID); +VOID error_req_param_missing (VOID); +VOID error_sfile_not_found (LPTSTR); +VOID error_file_not_found (VOID); +VOID error_path_not_found (VOID); +VOID error_too_many_parameters (LPTSTR); +VOID error_invalid_switch (TCHAR); +VOID error_invalid_parameter_format (LPTSTR); +VOID error_out_of_memory (VOID); +VOID error_syntax (LPTSTR); + +VOID msg_pause (VOID); + + +/* Prototypes for FILECOMP.C */ +#ifdef FEATURE_UNIX_FILENAME_COMPLETION +VOID CompleteFilename (LPTSTR, INT); +INT ShowCompletionMatches (LPTSTR, INT); +#endif +#ifdef FEATURE_4NT_FILENAME_COMPLETION +#endif + + +/* Prototypes for FOR.C */ +INT cmd_for (LPTSTR, LPTSTR); + + +/* Prototypes for FREE.C */ +INT CommandFree (LPTSTR, LPTSTR); + + +/* Prototypes for GOTO.C */ +INT cmd_goto (LPTSTR, LPTSTR); + + +/* Prototypes for HISTORY.C */ +#ifdef FEATURE_HISTORY +VOID History (INT, LPTSTR);/*add entries browse history*/ +VOID History_move_to_bottom(VOID);/*F3*/ +VOID InitHistory(VOID); +VOID CleanHistory(VOID); +VOID History_del_current_entry(LPTSTR str);/*CTRL-D*/ +INT CommandHistory (LPTSTR cmd, LPTSTR param); +#endif + + +/* Prototypes for INTERNAL.C */ +VOID InitLastPath (VOID); +VOID FreeLastPath (VOID); +INT cmd_chdir (LPTSTR, LPTSTR); +INT cmd_mkdir (LPTSTR, LPTSTR); +INT cmd_rmdir (LPTSTR, LPTSTR); +INT CommandExit (LPTSTR, LPTSTR); +INT CommandRem (LPTSTR, LPTSTR); +INT CommandShowCommands (LPTSTR, LPTSTR); + + +/* Prototypes for LABEL.C */ +INT cmd_label (LPTSTR, LPTSTR); + + +/* Prototypes for LOCALE.C */ +extern TCHAR cDateSeparator; +extern INT nDateFormat; +extern TCHAR cTimeSeparator; +extern INT nTimeFormat; +extern TCHAR aszDayNames[7][8]; +extern TCHAR cThousandSeparator; +extern TCHAR cDecimalSeparator; +extern INT nNumberGroups; + +VOID InitLocale (VOID); +VOID PrintDate (VOID); +VOID PrintTime (VOID); + + +/* Prototypes for MEMORY.C */ +INT CommandMemory (LPTSTR, LPTSTR); + + +/* Prototypes for MISC.C */ +TCHAR cgetchar (VOID); +BOOL CheckCtrlBreak (INT); +LPTSTR *split (LPTSTR, LPINT, BOOL); +VOID freep (LPTSTR *); +LPTSTR stpcpy (LPTSTR, LPTSTR); +BOOL IsValidPathName (LPCTSTR); +BOOL IsValidFileName (LPCTSTR); +BOOL IsValidDirectory (LPCTSTR); +BOOL FileGetString (HANDLE, LPTSTR, INT); +#ifndef __REACTOS__ +HWND GetConsoleWindow(VOID); +#endif + +#define PROMPT_NO 0 +#define PROMPT_YES 1 +#define PROMPT_ALL 2 +#define PROMPT_BREAK 3 + +INT PagePrompt (VOID); +INT FilePromptYN (LPTSTR, ...); +INT FilePromptYNA (LPTSTR, ...); + + +/* Prototypes for MOVE.C */ +INT cmd_move (LPTSTR, LPTSTR); + + +/* Prototypes for MSGBOX.C */ +INT CommandMsgbox (LPTSTR, LPTSTR); + + +/* Prototypes from PATH.C */ +INT cmd_path (LPTSTR, LPTSTR); + + +/* Prototypes from PROMPT.C */ +VOID PrintPrompt (VOID); +INT cmd_prompt (LPTSTR, LPTSTR); + + +/* Prototypes for REDIR.C */ +#define INPUT_REDIRECTION 1 +#define OUTPUT_REDIRECTION 2 +#define OUTPUT_APPEND 4 +#define ERROR_REDIRECTION 8 +#define ERROR_APPEND 16 +INT GetRedirection (LPTSTR, LPTSTR, LPTSTR, LPTSTR, LPINT); + + +/* Prototypes for REN.C */ +INT cmd_rename (LPTSTR, LPTSTR); + + +/* Prototypes for SCREEN.C */ +INT CommandScreen (LPTSTR, LPTSTR); + + +/* Prototypes for SET.C */ +INT cmd_set (LPTSTR, LPTSTR); + + +/* Prototypes for START.C */ +INT cmd_start (LPTSTR, LPTSTR); + + +/* Prototypes for STRTOCLR.C */ +BOOL StringToColor (LPWORD, LPTSTR *); + + +/* Prototypes for TIME.C */ +INT cmd_time (LPTSTR, LPTSTR); + + +/* Prototypes for TIMER.C */ +INT CommandTimer (LPTSTR cmd, LPTSTR param); + + +/* Prototypes for TITLE.C */ +INT cmd_title (LPTSTR, LPTSTR); + + +/* Prototypes for TYPE.C */ +INT cmd_type (LPTSTR, LPTSTR); + + +/* Prototypes for VER.C */ +VOID ShortVersion (VOID); +INT cmd_ver (LPTSTR, LPTSTR); + + +/* Prototypes for VERIFY.C */ +INT cmd_verify (LPTSTR, LPTSTR); + + +/* Prototypes for VOL.C */ +INT cmd_vol (LPTSTR, LPTSTR); + + +/* Prototypes for WHERE.C */ +BOOL SearchForExecutable (LPCTSTR, LPTSTR); + +/* Prototypes for WINDOW.C */ +INT CommandActivate (LPTSTR, LPTSTR); +INT CommandWindow (LPTSTR, LPTSTR); + + +/* The MSDOS Batch Commands [MS-DOS 5.0 User's Guide and Reference p359] */ +int cmd_if(char *, char *); +int cmd_pause(char *, char *); +int cmd_shift(char *, char *); + +#endif /* _CMD_H_INCLUDED_ */ diff --git a/subsys/system/cmd/cmd.rc b/subsys/system/cmd/cmd.rc new file mode 100644 index 0000000..42ab9ba --- /dev/null +++ b/subsys/system/cmd/cmd.rc @@ -0,0 +1,40 @@ +#include +#include +#include "cmdver.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "ReactOS Command Processor\0" + VALUE "FileVersion", CMD_VER_RC + VALUE "InternalName", "cmd\0" + VALUE "OriginalCopyright", "Copyright (C) 1994-1998 Tim Norman and others\0" + VALUE "LegalCopyright", "Copyright (C) 1998-2001 Eric Kohl and others\0" + VALUE "OriginalFilename", "cmd.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/subsys/system/cmd/cmdinput.c b/subsys/system/cmd/cmdinput.c new file mode 100644 index 0000000..4b5e08d --- /dev/null +++ b/subsys/system/cmd/cmdinput.c @@ -0,0 +1,527 @@ +/* + * CMDINPUT.C - handles command input (tab completion, history, etc.). + * + * + * History: + * + * 01/14/95 (Tim Norman) + * started. + * + * 08/08/95 (Matt Rains) + * i have cleaned up the source code. changes now bring this source + * into guidelines for recommended programming practice. + * i have added some constants to help making changes easier. + * + * 12/12/95 (Tim Norman) + * added findxy() function to get max x/y coordinates to display + * correctly on larger screens + * + * 12/14/95 (Tim Norman) + * fixed the Tab completion code that Matt Rains broke by moving local + * variables to a more global scope and forgetting to initialize them + * when needed + * + * 8/1/96 (Tim Norman) + * fixed a bug in tab completion that caused filenames at the beginning + * of the command-line to have their first letter truncated + * + * 9/1/96 (Tim Norman) + * fixed a silly bug using printf instead of fputs, where typing "%i" + * confused printf :) + * + * 6/14/97 (Steffan Kaiser) + * ctrl-break checking + * + * 6/7/97 (Marc Desrochers) + * recoded everything! now properly adjusts when text font is changed. + * removed findxy(), reposition(), and reprint(), as these functions + * were inefficient. added goxy() function as gotoxy() was buggy when + * the screen font was changed. the printf() problem with %i on the + * command line was fixed by doing printf("%s",str) instead of + * printf(str). Don't ask how I find em just be glad I do :) + * + * 7/12/97 (Tim Norman) + * Note: above changes pre-empted Steffan's ctrl-break checking. + * + * 7/7/97 (Marc Desrochers) + * rewrote a new findxy() because the new dir() used it. This + * findxy() simply returns the values of *maxx *maxy. In the + * future, please use the pointers, they will always be correct + * since they point to BIOS values. + * + * 7/8/97 (Marc Desrochers) + * once again removed findxy(), moved the *maxx, *maxy pointers + * global and included them as externs in command.h. Also added + * insert/overstrike capability + * + * 7/13/97 (Tim Norman) + * added different cursor appearance for insert/overstrike mode + * + * 7/13/97 (Tim Norman) + * changed my code to use _setcursortype until I can figure out why + * my code is crashing on some machines. It doesn't crash on mine :) + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 28-Jul-1998 (John P Price ) + * put ifdef's around filename completion code. + * + * 30-Jul-1998 (John P Price ) + * moved filename completion code to filecomp.c + * made second TAB display list of filename matches + * + * 31-Jul-1998 (John P Price ) + * Fixed bug where if you typed something, then hit HOME, then tried + * to type something else in insert mode, it crashed. + * + * 07-Aug-1998 (John P Price ) + * Fixed carrage return output to better match MSDOS with echo + * on or off.(marked with "JPP 19980708") + * + * 13-Dec-1998 (Eric Kohl ) + * Added insert/overwrite cursor. + * + * 25-Jan-1998 (Eric Kohl ) + * Replaced CRT io functions by Win32 console io functions. + * This can handle - for 4NT filename completion. + * Unicode and redirection safe! + * + * 04-Feb-1999 (Eric Kohl ) + * Fixed input bug. A "line feed" character remained in the keyboard + * input queue when you pressed . This sometimes caused + * some very strange effects. + * Fixed some command line editing annoyances. + */ + +#include "config.h" + +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +SHORT maxx; +SHORT maxy; + +/* + * global command line insert/overwrite flag + */ +static BOOL bInsert = TRUE; + + +static VOID +ClearCommandLine (LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy) +{ + INT count; + + SetCursorXY (orgx, orgy); + for (count = 0; count < (INT)_tcslen (str); count++) + ConOutChar (_T(' ')); + _tcsnset (str, _T('\0'), maxlen); + SetCursorXY (orgx, orgy); +} + + +/* read in a command line */ +VOID ReadCommand (LPTSTR str, INT maxlen) +{ + SHORT orgx; /* origin x/y */ + SHORT orgy; + SHORT curx; /*current x/y cursor position*/ + SHORT cury; + INT count; /*used in some for loops*/ + INT current = 0; /*the position of the cursor in the string (str)*/ + INT charcount = 0;/*chars in the string (str)*/ + INPUT_RECORD ir; + WORD wLastKey = 0; + TCHAR ch; + BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/ + + /* get screen size */ + GetScreenSize (&maxx, &maxy); + + /* JPP 19980807 - if echo off, don't print prompt */ + if (bEcho) + PrintPrompt(); + + GetCursorXY (&orgx, &orgy); + + memset (str, 0, maxlen * sizeof (TCHAR)); + + SetCursorType (bInsert, TRUE); + + do + { + ConInKey (&ir); + + if (ir.Event.KeyEvent.dwControlKeyState & + (RIGHT_ALT_PRESSED|RIGHT_ALT_PRESSED| + RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) ) + { + + switch (ir.Event.KeyEvent.wVirtualKeyCode) + { + +#ifdef FEATURE_HISTORY + + case 'K': + /*add the current command line to the history*/ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + + if (str[0]) + History(0,str); + + ClearCommandLine (str, maxlen, orgx, orgy); + current = charcount = 0; + bContinue=TRUE; + break; + } + + case 'D': + /*delete current history entry*/ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + ClearCommandLine (str, maxlen, orgx, orgy); + History_del_current_entry(str); + current = charcount = _tcslen (str); + ConOutPrintf (_T("%s"), str); + bContinue=TRUE; + break; + } + +#endif/*FEATURE_HISTORY*/ + } + + + + + } + + //if (bContinue) + // continue; + + + + switch (ir.Event.KeyEvent.wVirtualKeyCode) + { + case VK_BACK: + /* - delete character to left of cursor */ + if (current > 0 && charcount > 0) + { + if (current == charcount) + { + /* if at end of line */ + str[current - 1] = _T('\0'); + if (GetCursorX () != 0) + { + ConOutPrintf ("\b \b"); + } + else + { + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + ConOutChar (_T(' ')); + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + } + } + else + { + for (count = current - 1; count < charcount; count++) + str[count] = str[count + 1]; + if (GetCursorX () != 0) + SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); + else + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + GetCursorXY (&curx, &cury); + ConOutPrintf (_T("%s "), &str[current - 1]); + SetCursorXY (curx, cury); + } + charcount--; + current--; + } + break; + + case VK_INSERT: + /* toggle insert/overstrike mode */ + bInsert ^= TRUE; + SetCursorType (bInsert, TRUE); + break; + + case VK_DELETE: + /* delete character under cursor */ + if (current != charcount && charcount > 0) + { + for (count = current; count < charcount; count++) + str[count] = str[count + 1]; + charcount--; + GetCursorXY (&curx, &cury); + ConOutPrintf (_T("%s "), &str[current]); + SetCursorXY (curx, cury); + } + break; + + case VK_HOME: + /* goto beginning of string */ + if (current != 0) + { + SetCursorXY (orgx, orgy); + current = 0; + } + break; + + case VK_END: + /* goto end of string */ + if (current != charcount) + { + SetCursorXY (orgx, orgy); + ConOutPrintf (_T("%s"), str); + current = charcount; + } + break; + + case VK_TAB: +#ifdef FEATURE_UNIX_FILENAME_COMPLETION + /* expand current file name */ + if ((current == charcount) || + (current == charcount - 1 && + str[current] == _T('"'))) /* only works at end of line*/ + { + if (wLastKey != VK_TAB) + { + /* if first TAB, complete filename*/ + CompleteFilename (str, charcount); + charcount = _tcslen (str); + current = charcount; + + if (current > 0 && + str[current-1] == _T('"')) + current--; + + SetCursorXY (orgx, orgy); + ConOutPrintf (_T("%s"), str); + if ((charcount > (USHORT)(maxx - orgx)) && (orgy == maxy + 1)) + orgy--; + + /* set cursor position */ + SetCursorXY ((orgx + current) % maxx, + orgy + (orgx + current) / maxx); + } + else + { + /*if second TAB, list matches*/ + if (ShowCompletionMatches (str, charcount)) + { + PrintPrompt (); + GetCursorXY (&orgx, &orgy); + ConOutPrintf (_T("%s"), str); + + /* set cursor position */ + SetCursorXY ((orgx + current) % maxx, + orgy + (orgx + current) / maxx); + } + + } + } + else + { +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + } +#endif +#ifdef FEATURE_4NT_FILENAME_COMPLETION + /* this is not implemented yet */ + if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + { + /* get previous match */ + + } + else + { + /* get next match */ + + } +#endif + break; + + case VK_RETURN: + /* end input, return to main */ +#ifdef FEATURE_HISTORY + /* add to the history */ + if (str[0]) + History (0, str); +#endif + ConInDummy (); + ConOutChar (_T('\n')); + break; + + case VK_ESCAPE: + /* clear str Make this callable! */ + ClearCommandLine (str, maxlen, orgx, orgy); + current = charcount = 0; + break; + +#ifdef FEATURE_HISTORY + case VK_F3: + History_move_to_bottom(); +#endif + case VK_UP: +#ifdef FEATURE_HISTORY + /* get previous command from buffer */ + ClearCommandLine (str, maxlen, orgx, orgy); + History (-1, str); + current = charcount = _tcslen (str); + ConOutPrintf (_T("%s"), str); +#endif + break; + + case VK_DOWN: +#ifdef FEATURE_HISTORY + /* get next command from buffer */ + ClearCommandLine (str, maxlen, orgx, orgy); + History (1, str); + current = charcount = _tcslen (str); + ConOutPrintf (_T("%s"), str); +#endif + break; + + case VK_LEFT: + /* move cursor left */ + if (current > 0) + { + current--; + if (GetCursorX () == 0) + SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1)); + else + SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ()); + } + else + { +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + } + break; + + case VK_RIGHT: + /* move cursor right */ + if (current != charcount) + { + current++; + if (GetCursorX () == maxx - 1) + SetCursorXY (0, (SHORT)(GetCursorY () + 1)); + else + SetCursorXY ((SHORT)(GetCursorX () + 1), GetCursorY ()); + } + break; + +#if 0 + +#ifdef FEATURE_HISTORY + + + /*!!!WARNING!!!*/ + /*this will only work as long as the two if statement + evaluates the same expression and a break is included + in each if statement. + This can be used for any combination using CTRL. + For other combinations is needed another system*/ + + case 'K': + /*add the current command line to the history*/ + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + + if (str[0]) + History(0,str); + + ClearCommandLine (str, maxlen, orgx, orgy); + current = charcount = 0; + break; + } + + case 'D': + if (ir.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)) + { + ClearCommandLine (str, maxlen, orgx, orgy); + History_del_current_entry(str); + current = charcount = _tcslen (str); + ConOutPrintf (_T("%s"), str); + break; + } + +#endif/*FEATURE_HISTORY*/ +#endif/*0*/ + + default: +#ifdef _UNICODE + ch = ir.Event.KeyEvent.uChar.UnicodeChar; + if ((ch >= 32 && ch <= 255) && (charcount != (maxlen - 2))) +#else + ch = ir.Event.KeyEvent.uChar.AsciiChar; + if (ch >= 32 && (charcount != (maxlen - 2))) +#endif /* _UNICODE */ + { + /* insert character into string... */ + if (bInsert && current != charcount) + { + for (count = charcount; count > current; count--) + str[count] = str[count - 1]; + str[current++] = ch; + if (GetCursorX () == maxx - 1) + { + curx = 0; + cury = GetCursorY () + 1; + } + else + { + GetCursorXY (&curx, &cury); + curx++; + } + ConOutPrintf (_T("%s"), &str[current - 1]); + if ((_tcslen (str) > (USHORT)(maxx - orgx)) && (orgy == maxy + 1)) + cury--; + SetCursorXY (curx, cury); + charcount++; + } + else + { + if (current == charcount) + charcount++; + str[current++] = ch; + ConOutChar (ch); + } + if ((_tcslen (str) > (USHORT)(maxx - orgx)) && (orgy == maxy + 1)) + orgy--; + } +#if 0 + else + { +#ifdef __REACTOS__ + Beep (440, 100); +#else + MessageBeep (-1); +#endif + } +#endif + break; + + } + wLastKey = ir.Event.KeyEvent.wVirtualKeyCode; + } + while (ir.Event.KeyEvent.wVirtualKeyCode != VK_RETURN); + + SetCursorType (bInsert, TRUE); +} diff --git a/subsys/system/cmd/cmdtable.c b/subsys/system/cmd/cmdtable.c new file mode 100644 index 0000000..7087a7d --- /dev/null +++ b/subsys/system/cmd/cmdtable.c @@ -0,0 +1,263 @@ +/* + * CMDTABLE.C - table of internal commands. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * New file to keep the internal command table. I plan on + * getting rid of the table real soon now and replacing it + * with a dynamic mechnism. + * + * 27 Jul 1998 John P. Price + * added config.h include + * + * 21-Jan-1999 (Eric Kohl ) + * Unicode ready! + */ + +#include "config.h" + +#include +#include + +#include "cmd.h" + +/* a list of all the internal commands, associating their command names */ +/* to the functions to process them */ + + +COMMAND cmds[] = +{ + {_T("?"), 0, CommandShowCommands}, + +#ifdef INCLUDE_CMD_ACTIVATE + {_T("activate"), 0, CommandActivate}, +#endif + +#ifdef FEATURE_ALIASES + {_T("alias"), 0, CommandAlias}, +#endif + +#ifdef INCLUDE_CMD_ATTRIB + {_T("attrib"), 0, CommandAttrib}, +#endif + +#ifdef INCLUDE_CMD_BEEP + {_T("beep"), 0, cmd_beep}, +#endif + + {_T("call"), CMD_BATCHONLY, cmd_call}, + +#ifdef INCLUDE_CMD_CHDIR + {_T("cd"), CMD_SPECIAL, cmd_chdir}, + {_T("chdir"), CMD_SPECIAL, cmd_chdir}, +#endif + +#ifdef INCLUDE_CMD_CHCP + {_T("chcp"), 0, CommandChcp}, +#endif + +#ifdef INCLUDE_CMD_CHOICE + {_T("choice"), 0, CommandChoice}, +#endif + +#ifdef INCLUDE_CMD_CLS + {_T("cls"), 0, cmd_cls}, +#endif + +#ifdef INCLUDE_CMD_COLOR + {_T("color"), 0, CommandColor}, +#endif + +#ifdef INCLUDE_CMD_COPY + {_T("copy"), 0, cmd_copy}, +#endif + +#ifdef INCLUDE_CMD_DATE + {_T("date"), 0, cmd_date}, +#endif + +#ifdef INCLUDE_CMD_DEL + {_T("del"), 0, CommandDelete}, + {_T("delete"), 0, CommandDelete}, +#endif + +#ifdef INCLUDE_CMD_DELAY + {_T("delay"), 0, CommandDelay}, +#endif + +#ifdef INCLUDE_CMD_DIR + {_T("dir"), CMD_SPECIAL, CommandDir}, +#endif + +#ifdef FEATURE_DIRECTORY_STACK + {_T("dirs"), 0, CommandDirs}, +#endif + + {_T("echo"), 0, CommandEcho}, + {_T("echo."), CMD_HIDE, CommandEcho}, + {_T("echos"), 0, CommandEchos}, + {_T("echoerr"), 0, CommandEchoerr}, + {_T("echoerr."), CMD_HIDE, CommandEchoerr}, + {_T("echoserr"), 0, CommandEchoserr}, + +#ifdef INCLUDE_CMD_DEL + {_T("erase"), 0, CommandDelete}, +#endif + + {_T("exit"), 0, CommandExit}, + + {_T("for"), 0, cmd_for}, + +#ifdef INCLUDE_CMD_FREE + {_T("free"), 0, CommandFree}, +#endif + + {_T("goto"), CMD_BATCHONLY, cmd_goto}, + +#ifdef FEATURE_HISTORY + {_T("history"), 0, CommandHistory}, +#endif + + {_T("if"), 0, cmd_if}, + +#ifdef INCLUDE_CMD_LABEL + {_T("label"), 0, cmd_label}, +#endif + +#ifdef INCLUDE_CMD_MEMORY + {_T("memory"), 0, CommandMemory}, +#endif + +#ifdef INCLUDE_CMD_MKDIR + {_T("md"), CMD_SPECIAL, cmd_mkdir}, + {_T("mkdir"), CMD_SPECIAL, cmd_mkdir}, +#endif + +#ifdef INCLUDE_CMD_MOVE + {_T("move"), 0, cmd_move}, +#endif + +#ifdef INCLUDE_CMD_MSGBOX + {_T("msgbox"), 0, CommandMsgbox}, +#endif + +#ifdef INCLUDE_CMD_PATH + {_T("path"), 0, cmd_path}, +#endif + +#ifdef INCLUDE_CMD_PAUSE + {_T("pause"), 0, cmd_pause}, +#endif + +#ifdef FEATURE_DIRECTORY_STACK + {_T("popd"), 0, CommandPopd}, +#endif + +#ifdef INCLUDE_CMD_PROMPT + {_T("prompt"), 0, cmd_prompt}, +#endif + +#ifdef FEATURE_DIRECTORY_STACK + {_T("pushd"), 0, CommandPushd}, +#endif + +#ifdef INCLUDE_CMD_RMDIR + {_T("rd"), CMD_SPECIAL, cmd_rmdir}, +#endif + +#ifdef INCLUDE_CMD_REM + {_T("rem"), 0, CommandRem}, +#endif + +#ifdef INCLUDE_CMD_RENAME + {_T("ren"), 0, cmd_rename}, + {_T("rename"), 0, cmd_rename}, +#endif + +#ifdef INCLUDE_CMD_RMDIR + {_T("rmdir"), CMD_SPECIAL, cmd_rmdir}, +#endif + +#ifdef INCLUDE_CMD_SCREEN + {_T("screen"), 0, CommandScreen}, +#endif + +#ifdef INCLUDE_CMD_SET + {_T("set"), 0, cmd_set}, +#endif + + {_T("shift"), CMD_BATCHONLY, cmd_shift}, + +#ifdef INCLUDE_CMD_START + {_T("start"), 0, cmd_start}, +#endif + +#ifdef INCLUDE_CMD_TIME + {_T("time"), 0, cmd_time}, +#endif + +#ifdef INCLUDE_CMD_TIMER + {_T("timer"), 0, CommandTimer}, +#endif + +#ifdef INCLUDE_CMD_TITLE + {_T("title"), 0, cmd_title}, +#endif + +#ifdef INCLUDE_CMD_TYPE + {_T("type"), 0, cmd_type}, +#endif + +#ifdef INCLUDE_CMD_VER + {_T("ver"), 0, cmd_ver}, +#endif + +#ifdef INCLUDE_CMD_VERIFY + {_T("verify"), 0, cmd_verify}, +#endif + +#ifdef INCLUDE_CMD_VOL + {_T("vol"), 0, cmd_vol}, +#endif + +#ifdef INCLUDE_CMD_WINDOW + {_T("window"), 0, CommandWindow}, +#endif + + {NULL, 0, NULL} +}; + + +VOID PrintCommandList (VOID) +{ + LPCOMMAND cmdptr; + INT y; + + y = 0; + cmdptr = cmds; + while (cmdptr->name) + { + if (!(cmdptr->flags & CMD_HIDE)) + { + if (++y == 8) + { + ConOutPuts (cmdptr->name); + y = 0; + } + else + { + ConOutPrintf (_T("%-10s"), cmdptr->name); + } + } + + cmdptr++; + } + + if (y != 0) + ConOutChar ('\n'); +} + +/* EOF */ diff --git a/subsys/system/cmd/cmdver.h b/subsys/system/cmd/cmdver.h new file mode 100644 index 0000000..93ed1b8 --- /dev/null +++ b/subsys/system/cmd/cmdver.h @@ -0,0 +1,2 @@ +#define CMD_VER "0.1.2" +#define CMD_VER_RC CMD_VER"\0" diff --git a/subsys/system/cmd/color.c b/subsys/system/cmd/color.c new file mode 100644 index 0000000..47b34a6 --- /dev/null +++ b/subsys/system/cmd/color.c @@ -0,0 +1,131 @@ +/* $Id$ + * + * COLOR.C - color internal command. + * + * + * History: + * + * 13-Dec-1998 (Eric Kohl ) + * Started. + * + * 19-Jan-1999 (Eric Kohl ) + * Unicode ready! + * + * 20-Jan-1999 (Eric Kohl ) + * Redirection ready! + * + * 14-Oct-1999 (Paolo Pantaleo ) + * 4nt's syntax implemented + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_COLOR +#include +#include +#include +#include + +#include "cmd.h" + +static VOID ColorHelp (VOID) +{ + ConOutPuts (_T( + "Sets the default foreground and background colors.\n" + "\n" + "COLOR [attr [/F]] \n\n" + " attr Specifies color attribute of console output\n" + " /F fill the console with color attribute\n" + "\n" + "There are three ways to specify the colors:" + )); + + ConOutPuts (_T( + "\n" + "1) [bright] name on [bright] name (only the first three letters are required)\n" + "2) decimal on decimal\n" + "3) two hex digits\n" + "\n" + "Colors are:" + )); + + ConOutPuts (_T( + "dec hex name dec hex name\n" + "0 0 Black 8 8 Gray(Bright black)\n" + "1 1 Blue 9 9 Bright Blue\n" + "2 2 Green 10 A Bright Green\n" + "3 3 Cyan 11 B Bright Cyan\n" + "4 4 Red 12 C Bright Red\n" + "5 5 Magenta 13 D Bright Magenta\n" + "6 6 Yellow 14 E Bright Yellow\n" + "7 7 White 15 F Bright White")); +} + + +VOID SetScreenColor (WORD wColor, BOOL bFill) +{ + DWORD dwWritten; + CONSOLE_SCREEN_BUFFER_INFO csbi; + COORD coPos; + + if (bFill == TRUE) + { + GetConsoleScreenBufferInfo (hOut, &csbi); + + coPos.X = 0; + coPos.Y = 0; + FillConsoleOutputAttribute (hOut, + (WORD)(wColor & 0x00FF), + (csbi.dwSize.X)*(csbi.dwSize.Y), + coPos, + &dwWritten); + } + SetConsoleTextAttribute (hOut, (WORD)(wColor & 0x00FF)); +} + + +/* + * color + * + * internal dir command + */ +INT CommandColor (LPTSTR first, LPTSTR rest) +{ + if (_tcsncmp (rest, _T("/?"), 2) == 0) + { + ColorHelp (); + return 0; + } + + if (rest[0] == _T('\0')) + { + /* set default color */ + wColor = wDefColor; + SetScreenColor (wColor, TRUE); + return 0; + } + + if (StringToColor (&wColor, &rest) == FALSE) + { + ConErrPuts("error in color specification"); + return 1; + } + + ConErrPrintf ("Color %x\n", wColor); + + if ((wColor & 0xF) == (wColor &0xF0) >> 4) + { + ConErrPuts (_T("same colors error!")); + return 1; + } + + /* set color */ + SetScreenColor (wColor, + (_tcsstr (rest,"/F") || _tcsstr (rest,"/f"))); + + return 0; +} + +#endif /* INCLUDE_CMD_COLOR */ + +/* EOF */ diff --git a/subsys/system/cmd/config.h b/subsys/system/cmd/config.h new file mode 100644 index 0000000..65f8dac --- /dev/null +++ b/subsys/system/cmd/config.h @@ -0,0 +1,106 @@ +/* + * CONFIG.H - Used to configure what will be compiled into the shell. + * + * + * History: + * + * 27 Jul 1998 - John P. Price + * started. + * + */ + +/* Define only if used under ReactOS */ +#define __REACTOS__ + +#ifndef _CONFIG_H_INCLUDED_ +#define _CONFIG_H_INCLUDED_ + + +#ifndef __REACTOS__ +#define WIN32_LEAN_AND_MEAN +#endif /* __REACTOS__ */ + + +/* Define to enable debugging code */ +//#define _DEBUG + + +/* Define to enable the alias command, and aliases.*/ +#define FEATURE_ALIASES + + +/* Define to enable history */ +#define FEATURE_HISTORY + +/*Define to enable history wrap (4nt's style)*/ +#define WRAP_HISTORY + + +/* Define one of these to enable filename completion */ +#define FEATURE_UNIX_FILENAME_COMPLETION +/* #define FEATURE_4NT_FILENAME_COMPLETION */ + + +/* Define to enable the directory stack */ +#define FEATURE_DIRECTORY_STACK + + +/* Define to activate redirections and piping */ +#define FEATURE_REDIRECTION + + +/* Define one of these to select the used locale. */ +/* (date and time formats etc.) used in DATE, TIME, */ +/* DIR, PROMPT etc. */ +#ifdef __REACTOS__ +#define LOCALE_DEFAULT +#else +#define LOCALE_WINDOWS /* System locale */ +/* #define LOCALE_GERMAN */ /* German locale */ +/* #define LOCALE_DEFAULT */ /* United States locale */ +#endif + +#ifndef __REACTOS__ +#define INCLUDE_CMD_ACTIVATE +#endif +#define INCLUDE_CMD_ATTRIB +#define INCLUDE_CMD_CHCP +#define INCLUDE_CMD_CHDIR +#define INCLUDE_CMD_CHOICE +#define INCLUDE_CMD_CLS +#define INCLUDE_CMD_COLOR +#define INCLUDE_CMD_COPY +#define INCLUDE_CMD_DATE +#define INCLUDE_CMD_DEL +#define INCLUDE_CMD_DELAY +#define INCLUDE_CMD_DIR +#define INCLUDE_CMD_FREE +#define INCLUDE_CMD_LABEL +#define INCLUDE_CMD_MEMORY +#define INCLUDE_CMD_MKDIR +#define INCLUDE_CMD_MOVE +#ifndef __REACTOS__ +#define INCLUDE_CMD_MSGBOX +#endif +#define INCLUDE_CMD_PATH +#define INCLUDE_CMD_PROMPT +#define INCLUDE_CMD_RMDIR +#define INCLUDE_CMD_RENAME +#define INCLUDE_CMD_SCREEN +#define INCLUDE_CMD_SET +#define INCLUDE_CMD_START +#define INCLUDE_CMD_TIME +#define INCLUDE_CMD_TIMER +#define INCLUDE_CMD_TITLE +#define INCLUDE_CMD_TYPE +#define INCLUDE_CMD_VER +#define INCLUDE_CMD_REM +#define INCLUDE_CMD_PAUSE +#define INCLUDE_CMD_BEEP +#define INCLUDE_CMD_VERIFY +#define INCLUDE_CMD_VOL +#ifndef __REACTOS__ +#define INCLUDE_CMD_WINDOW +#endif + +#endif /* _CONFIG_H_INCLUDED_ */ diff --git a/subsys/system/cmd/console.c b/subsys/system/cmd/console.c new file mode 100644 index 0000000..ec73f13 --- /dev/null +++ b/subsys/system/cmd/console.c @@ -0,0 +1,302 @@ +/* $Id$ + * + * CONSOLE.C - console input/output functions. + * + * + * History: + * + * 20-Jan-1999 (Eric Kohl ) + * started + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cmd.h" + + +#define OUTPUT_BUFFER_SIZE 4096 + + +#ifdef _DEBUG +VOID DebugPrintf (LPTSTR szFormat, ...) +{ + TCHAR szOut[OUTPUT_BUFFER_SIZE]; + va_list arg_ptr; + DWORD dwWritten; + + va_start (arg_ptr, szFormat); + _vstprintf (szOut, szFormat, arg_ptr); + va_end (arg_ptr); + + WriteFile (GetStdHandle (STD_ERROR_HANDLE), + szOut, + _tcslen(szOut) * sizeof(TCHAR), + &dwWritten, + NULL); +#if 0 + OutputDebugString (szOut); +#endif +} +#endif /* _DEBUG */ + + +VOID ConInDisable (VOID) +{ + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + DWORD dwMode; + + GetConsoleMode (hInput, &dwMode); + dwMode &= ~ENABLE_PROCESSED_INPUT; + SetConsoleMode (hInput, dwMode); +} + + +VOID ConInEnable (VOID) +{ + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + DWORD dwMode; + + GetConsoleMode (hInput, &dwMode); + dwMode |= ENABLE_PROCESSED_INPUT; + SetConsoleMode (hInput, dwMode); +} + + +VOID ConInDummy (VOID) +{ + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + INPUT_RECORD dummy; + DWORD dwRead; + +#ifdef _DEBUG + if (hInput == INVALID_HANDLE_VALUE) + DebugPrintf ("Invalid input handle!!!\n"); +#endif /* _DEBUG */ + + ReadConsoleInput (hInput, &dummy, 1, &dwRead); +} + +VOID ConInFlush (VOID) +{ + FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); +} + + +VOID ConInKey (PINPUT_RECORD lpBuffer) +{ + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + DWORD dwRead; + +#ifdef _DEBUG + if (hInput == INVALID_HANDLE_VALUE) + DebugPrintf ("Invalid input handle!!!\n"); +#endif /* _DEBUG */ + + do + { + ReadConsoleInput (hInput, lpBuffer, 1, &dwRead); + if ((lpBuffer->EventType == KEY_EVENT) && + (lpBuffer->Event.KeyEvent.bKeyDown == TRUE)) + break; + } + while (TRUE); +} + + + +VOID ConInString (LPTSTR lpInput, DWORD dwLength) +{ + DWORD dwOldMode; + DWORD dwRead; + HANDLE hFile; + + LPTSTR p; + DWORD i; + + ZeroMemory (lpInput, dwLength * sizeof(TCHAR)); + hFile = GetStdHandle (STD_INPUT_HANDLE); + GetConsoleMode (hFile, &dwOldMode); + + SetConsoleMode (hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); + + ReadFile (hFile, lpInput, dwLength, &dwRead, NULL); + + p = lpInput; + for (i = 0; i < dwRead; i++, p++) + { + if (*p == _T('\x0d')) + { + *p = _T('\0'); + break; + } + } + + SetConsoleMode (hFile, dwOldMode); +} + + +VOID ConOutChar (TCHAR c) +{ + DWORD dwWritten; + + WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), + &c, + sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID ConOutPuts (LPTSTR szText) +{ + DWORD dwWritten; + + WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), + szText, + _tcslen(szText) * sizeof(TCHAR), + &dwWritten, + NULL); + WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), + _T("\n"), + sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID ConOutPrintf (LPTSTR szFormat, ...) +{ + TCHAR szOut[OUTPUT_BUFFER_SIZE]; + DWORD dwWritten; + va_list arg_ptr; + + va_start (arg_ptr, szFormat); + _vstprintf (szOut, szFormat, arg_ptr); + va_end (arg_ptr); + + WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), + szOut, + _tcslen(szOut) * sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID ConErrChar (TCHAR c) +{ + DWORD dwWritten; + + WriteFile (GetStdHandle (STD_ERROR_HANDLE), + &c, + sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID ConErrPuts (LPTSTR szText) +{ + DWORD dwWritten; + + WriteFile (GetStdHandle (STD_ERROR_HANDLE), + szText, + _tcslen(szText) * sizeof(TCHAR), + &dwWritten, + NULL); + WriteFile (GetStdHandle (STD_ERROR_HANDLE), + _T ("\n"), + sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID ConErrPrintf (LPTSTR szFormat, ...) +{ + TCHAR szOut[OUTPUT_BUFFER_SIZE]; + DWORD dwWritten; + va_list arg_ptr; + + va_start (arg_ptr, szFormat); + _vstprintf (szOut, szFormat, arg_ptr); + va_end (arg_ptr); + + WriteFile (GetStdHandle (STD_ERROR_HANDLE), + szOut, + _tcslen(szOut) * sizeof(TCHAR), + &dwWritten, + NULL); +} + + +VOID SetCursorXY (SHORT x, SHORT y) +{ + COORD coPos; + + coPos.X = x; + coPos.Y = y; + SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos); +} + + +VOID GetCursorXY (PSHORT x, PSHORT y) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); + + *x = csbi.dwCursorPosition.X; + *y = csbi.dwCursorPosition.Y; +} + + +SHORT GetCursorX (VOID) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); + + return csbi.dwCursorPosition.X; +} + + +SHORT GetCursorY (VOID) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); + + return csbi.dwCursorPosition.Y; +} + + +VOID GetScreenSize (PSHORT maxx, PSHORT maxy) +{ + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); + + if (maxx) + *maxx = csbi.dwSize.X; + if (maxy) + *maxy = csbi.dwSize.Y; +} + + +VOID SetCursorType (BOOL bInsert, BOOL bVisible) +{ + CONSOLE_CURSOR_INFO cci; + + cci.dwSize = bInsert ? 10 : 99; + cci.bVisible = bVisible; + + SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci); +} + +/* EOF */ diff --git a/subsys/system/cmd/copy.c b/subsys/system/cmd/copy.c new file mode 100644 index 0000000..a77f516 --- /dev/null +++ b/subsys/system/cmd/copy.c @@ -0,0 +1,755 @@ +/* $Id$ + * + * COPY.C -- copy internal command. + * + * + * History: + * + * 01-Aug-98 (Rob Lake z63rrl@morgan.ucs.mun.ca) + * started + * + * 13-Aug-1998 (John P. Price) + * fixed memory leak problem in copy function. + * fixed copy function so it would work with wildcards in the source + * + * 13-Dec-1998 (Eric Kohl ) + * Added COPY command to CMD. + * + * 26-Jan-1998 (Eric Kohl ) + * Replaced CRT io functions by Win32 io functions. + * + * 27-Oct-1998 (Eric Kohl ) + * Disabled prompting when used in batch mode. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_COPY + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +#define VERIFY 1 /* VERIFY Switch */ +#define BINARY 2 /* File is to be copied as BINARY */ +#define ASCII 4 /* File is to be copied as ASCII */ +#define PROMPT 8 /* Prompt before overwriting files */ +#define NPROMPT 16 /* Do not prompt before overwriting files */ +#define HELP 32 /* Help was asked for */ +#define SOURCE 128 /* File is a source */ + + +typedef struct tagFILES +{ + struct tagFILES *next; + TCHAR szFile[MAX_PATH]; + DWORD dwFlag; /* BINARY -xor- ASCII */ +} FILES, *LPFILES; + + +static BOOL DoSwitches (LPTSTR, LPDWORD); +static BOOL AddFile (LPFILES, char *, int *, int *, LPDWORD); +static BOOL AddFiles (LPFILES, char *, int *, int *, int *, LPDWORD); +static BOOL GetDestination (LPFILES, LPFILES); +static INT ParseCommand (LPFILES, int, char **, LPDWORD); +static VOID DeleteFileList (LPFILES); +static INT Overwrite (LPTSTR); + + + +static BOOL +IsDirectory (LPTSTR fn) +{ + if (!IsValidFileName (fn)) + return FALSE; + return (GetFileAttributes (fn) & FILE_ATTRIBUTE_DIRECTORY); +} + + +static BOOL +DoSwitches (LPTSTR arg, LPDWORD lpdwFlags) +{ + if (!_tcsicmp (arg, _T("/-Y"))) + { + *lpdwFlags |= PROMPT; + *lpdwFlags &= ~NPROMPT; + return TRUE; + } + else if (_tcslen (arg) > 2) + { + error_too_many_parameters (""); + return FALSE; + } + + switch (_totupper (arg[1])) + { + case _T('V'): + *lpdwFlags |= VERIFY; + break; + + case _T('A'): + *lpdwFlags |= ASCII; + *lpdwFlags &= ~BINARY; + break; + + case _T('B'): + *lpdwFlags |= BINARY; + *lpdwFlags &= ~ASCII; + break; + + case _T('Y'): + *lpdwFlags &= ~PROMPT; + *lpdwFlags |= NPROMPT; + break; + + default: + error_invalid_switch (arg[1]); + return FALSE; + } + return TRUE; +} + + +static BOOL +AddFile (LPFILES f, char *arg, int *source, int *dest, LPDWORD flags) +{ + if (*dest) + { + error_too_many_parameters (""); + return FALSE; + } + if (*source) + { + *dest = 1; + f->dwFlag = 0; + } + else + { + *source = 1; + f->dwFlag = SOURCE; + } + _tcscpy(f->szFile, arg); + f->dwFlag |= *flags & ASCII ? ASCII : BINARY; + if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL) + { + error_out_of_memory (); + return FALSE; + } + f = f->next; + f->dwFlag = 0; + f->next = NULL; + return TRUE; +} + + +static BOOL +AddFiles (LPFILES f, char *arg, int *source, int *dest, + int *count, LPDWORD flags) +{ + char t[128]; + int j; + int k; + + if (*dest) + { + error_too_many_parameters (""); + return FALSE; + } + + j = 0; + k = 0; + + while (arg[j] == _T('+')) + j++; + + while (arg[j] != _T('\0')) + { + t[k] = arg[j++]; + if (t[k] == '+' || arg[j] == _T('\0')) + { + if (!k) + continue; + if (arg[j] == _T('\0') && t[k] != _T('+')) + k++; + t[k] = _T('\0'); + *count += 1; + _tcscpy (f->szFile, t); + *source = 1; + if (*flags & ASCII) + f->dwFlag |= *flags | SOURCE | ASCII; + else + f->dwFlag |= *flags | BINARY | SOURCE; + + if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL) + { + error_out_of_memory (); + return FALSE; + } + f = f->next; + f->next = NULL; + k = 0; + f->dwFlag = 0; + continue; + } + k++; + } + + if (arg[--j] == _T('+')) + *source = 0; + + return 1; +} + + +static BOOL +GetDestination (LPFILES f, LPFILES dest) +{ + LPFILES p = NULL; + LPFILES start = f; + + while (f->next != NULL) + { + p = f; + f = f->next; + } + + f = p; + + if ((f->dwFlag & SOURCE) == 0) + { + free (p->next); + p->next = NULL; + _tcscpy (dest->szFile, f->szFile); + dest->dwFlag = f->dwFlag; + dest->next = NULL; + f = start; + return TRUE; + } + + return FALSE; +} + + +static INT +ParseCommand (LPFILES f, int argc, char **arg, LPDWORD lpdwFlags) +{ + INT i; + INT dest; + INT source; + INT count; + + dest = 0; + source = 0; + count = 0; + + for (i = 0; i < argc; i++) + { + if (arg[i][0] == _T('/')) + { + if (!DoSwitches (arg[i], lpdwFlags)) + return -1; + } + else + { + if (!_tcscmp(arg[i], _T("+"))) + source = 0; + else if (!_tcschr(arg[i], _T('+')) && source) + { + if (!AddFile(f, arg[i], &source, &dest, lpdwFlags)) + return -1; + f = f->next; + count++; + } + else + { + if (!AddFiles(f, arg[i], &source, &dest, &count, lpdwFlags)) + return -1; + while (f->next != NULL) + f = f->next; + } + } + } + +#ifdef _DEBUG + DebugPrintf ("ParseCommand: flags has %s\n", + *lpdwFlags & ASCII ? "ASCII" : "BINARY"); +#endif + return count; +} + + +static VOID +DeleteFileList (LPFILES f) +{ + LPFILES temp; + + while (f != NULL) + { + temp = f; + f = f->next; + free (temp); + } +} + + +static INT +Overwrite (LPTSTR fn) +{ + TCHAR inp[10]; + LPTSTR p; + + ConOutPrintf (_T("Overwrite %s (Yes/No/All)? "), fn); + ConInString (inp, 10); + ConOutPuts (_T("")); + + _tcsupr (inp); + for (p = inp; _istspace (*p); p++) + ; + + if (*p != _T('Y') && *p != _T('A')) + return 0; + if (*p == _T('A')) + return 2; + + return 1; +} + + +#define BUFF_SIZE 16384 /* 16k = max buffer size */ + + +int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags) +{ + FILETIME srctime; + HANDLE hFileSrc; + HANDLE hFileDest; + LPBYTE buffer; + DWORD dwAttrib; + DWORD dwRead; + DWORD dwWritten; + DWORD i; + BOOL bEof = FALSE; + +#ifdef _DEBUG + DebugPrintf ("checking mode\n"); +#endif + + dwAttrib = GetFileAttributes (source); + + hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, 0, NULL); + if (hFileSrc == INVALID_HANDLE_VALUE) + { + ConErrPrintf (_T("Error: Cannot open source - %s!\n"), source); + return 0; + } + +#ifdef _DEBUG + DebugPrintf (_T("getting time\n")); +#endif + + GetFileTime (hFileSrc, &srctime, NULL, NULL); + +#ifdef _DEBUG + DebugPrintf (_T("copy: flags has %s\n"), + *lpdwFlags & ASCII ? "ASCII" : "BINARY"); +#endif + + if (!IsValidFileName (dest)) + { +#ifdef _DEBUG + DebugPrintf (_T("opening/creating\n")); +#endif + hFileDest = + CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + } + else if (!append) + { + if (!_tcscmp (dest, source)) + { + ConErrPrintf (_T("Error: Can't copy onto itself!\n")); + CloseHandle (hFileSrc); + return 0; + } + +#ifdef _DEBUG + DebugPrintf (_T("SetFileAttributes (%s, FILE_ATTRIBUTE_NORMAL);\n"), dest); +#endif + SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL); + +#ifdef _DEBUG + DebugPrintf (_T("DeleteFile (%s);\n"), dest); +#endif + DeleteFile (dest); + + hFileDest = + CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + } + else + { + LONG lFilePosHigh = 0; + + if (!_tcscmp (dest, source)) + { + CloseHandle (hFileSrc); + return 0; + } + +#ifdef _DEBUG + DebugPrintf (_T("opening/appending\n")); +#endif + hFileDest = + CreateFile (dest, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + SetFilePointer (hFileDest, 0, &lFilePosHigh,FILE_END); + } + + if (hFileDest == INVALID_HANDLE_VALUE) + { + CloseHandle (hFileSrc); + error_path_not_found (); + return 0; + } + + buffer = (LPBYTE)malloc (BUFF_SIZE); + if (buffer == NULL) + { + CloseHandle (hFileDest); + CloseHandle (hFileSrc); + error_out_of_memory (); + return 0; + } + + do + { + ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL); + if (*lpdwFlags & ASCII) + { + for (i = 0; i < dwRead; i++) + { + if (((LPTSTR)buffer)[i] == 0x1A) + { + bEof = TRUE; + break; + } + } + dwRead = i; + } + + if (dwRead == 0) + break; + + WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL); + if (dwWritten != dwRead) + { + ConErrPrintf (_T("Error writing destination!\n")); + free (buffer); + CloseHandle (hFileDest); + CloseHandle (hFileSrc); + return 0; + } + } + while (dwRead && !bEof); + +#ifdef _DEBUG + DebugPrintf (_T("setting time\n")); +#endif + SetFileTime (hFileDest, &srctime, NULL, NULL); + + if (*lpdwFlags & ASCII) + { + ((LPTSTR)buffer)[0] = 0x1A; + ((LPTSTR)buffer)[1] = _T('\0'); +#ifdef _DEBUG + DebugPrintf (_T("appending ^Z\n")); +#endif + WriteFile (hFileDest, buffer, sizeof(TCHAR), &dwWritten, NULL); + } + + free (buffer); + CloseHandle (hFileDest); + CloseHandle (hFileSrc); + +#ifdef _DEBUG + DebugPrintf (_T("setting mode\n")); +#endif + SetFileAttributes (dest, dwAttrib); + + return 1; +} + + +static INT +SetupCopy (LPFILES sources, char **p, BOOL bMultiple, + char *drive_d, char *dir_d, char *file_d, + char *ext_d, int *append, LPDWORD lpdwFlags) +{ + WIN32_FIND_DATA find; + + char drive_s[_MAX_DRIVE]; + CHAR dir_s[_MAX_DIR]; + char file_s[_MAX_FNAME]; + char ext_s[_MAX_EXT]; + char from_merge[_MAX_PATH]; + + LPTSTR real_source; + LPTSTR real_dest; + + INT nCopied = 0; + BOOL bAll = FALSE; + BOOL bDone; + HANDLE hFind; + +#ifdef _DEBUG + DebugPrintf (_T("SetupCopy\n")); +#endif + + real_source = (LPTSTR)malloc (MAX_PATH); + real_dest = (LPTSTR)malloc (MAX_PATH); + + if (!real_source || !real_dest) + { + error_out_of_memory (); + DeleteFileList (sources); + free (real_source); + free (real_dest); + freep (p); + return 0; + } + + while (sources->next != NULL) + { + _splitpath (sources->szFile, drive_s, dir_s, file_s, ext_s); + hFind = FindFirstFile (sources->szFile, &find); + if (hFind == INVALID_HANDLE_VALUE) + { + error_file_not_found(); + freep(p); + free(real_source); + free(real_dest); + return 0; + } + + do + { + if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + goto next; + + _makepath(from_merge, drive_d, dir_d, file_d, ext_d); + if (from_merge[_tcslen(from_merge) - 1] == _T('\\')) + from_merge[_tcslen(from_merge) - 1] = 0; + + if (IsDirectory (from_merge)) + { + bMultiple = FALSE; + _tcscat (from_merge, _T("\\")); + _tcscat (from_merge, find.cFileName); + } + else + bMultiple = TRUE; + + _tcscpy (real_dest, from_merge); + _makepath (real_source, drive_s, dir_s, find.cFileName, NULL); + +#ifdef _DEBUG + DebugPrintf (_T("copying %s -> %s (%sappending%s)\n"), + real_source, real_dest, + *append ? "" : "not ", + sources->dwFlag & ASCII ? ", ASCII" : ", BINARY"); +#endif + + if (IsValidFileName (real_dest) && !bAll) + { + /* Don't prompt in a batch file */ + if (bc != NULL) + { + bAll = TRUE; + } + else + { + int over; + + over = Overwrite (real_dest); + if (over == 2) + bAll = TRUE; + else if (over == 0) + goto next; + else if (bMultiple) + bAll = TRUE; + } + } + if (copy (real_source, real_dest, *append, lpdwFlags)) + nCopied++; + next: + bDone = FindNextFile (hFind, &find); + + if (bMultiple) + *append = 1; + } + while (bDone); + + FindClose (hFind); + sources = sources->next; + + } + free (real_source); + free (real_dest); + + return nCopied; +} + + +INT cmd_copy (LPTSTR first, LPTSTR rest) +{ + char **p; + char drive_d[_MAX_DRIVE]; + char dir_d[_MAX_DIR]; + char file_d[_MAX_FNAME]; + char ext_d[_MAX_EXT]; + + int argc; + int append; + int files; + int copied; + + LPFILES sources = NULL; + LPFILES start = NULL; + FILES dest; + BOOL bMultiple; + BOOL bWildcards; + BOOL bDestFound; + DWORD dwFlags = 0; + + if (!_tcsncmp (rest, _T("/?"), 2)) + { + ConOutPuts (_T("Copies one or more files to another location.\n" + "\n" + "COPY [/V][/Y|/-Y][/A|/B] source [/A|/B]\n" + " [+ source [/A|/B] [+ ...]] [destination [/A|/B]]\n" + "\n" + " source Specifies the file or files to be copied.\n" + " /A Indicates an ASCII text file.\n" + " /B Indicates a binary file.\n" + " destination Specifies the directory and/or filename for the new file(s).\n" + " /V Verifies that new files are written correctly.\n" + " /Y Suppresses prompting to confirm you want to overwrite an\n" + " existing destination file.\n" + " /-Y Causes prompting to confirm you want to overwrite an\n" + " existing destination file.\n" + "\n" + "The switch /Y may be present in the COPYCMD environment variable.\n" + "...")); + return 1; + } + + p = split (rest, &argc, FALSE); + + if (argc == 0) + { + error_req_param_missing (); + return 0; + } + + sources = (LPFILES)malloc (sizeof (FILES)); + if (!sources) + { + error_out_of_memory (); + return 0; + } + sources->next = NULL; + sources->dwFlag = 0; + + if ((files = ParseCommand (sources, argc, p, &dwFlags)) == -1) + { + DeleteFileList (sources); + freep (p); + return 0; + } + else if (files == 0) + { + error_req_param_missing(); + DeleteFileList (sources); + freep (p); + return 0; + } + start = sources; + + bDestFound = GetDestination (sources, &dest); + if (bDestFound) + { + _splitpath (dest.szFile, drive_d, dir_d, file_d, ext_d); + if (IsDirectory (dest.szFile)) + { + _tcscat (dir_d, file_d); + _tcscat (dir_d, ext_d); + file_d[0] = _T('\0'); + ext_d[0] = _T('\0'); + } + } + + if (_tcschr (dest.szFile, _T('*')) || _tcschr (dest.szFile, _T('?'))) + bWildcards = TRUE; + else + bWildcards = FALSE; + + if (strchr(rest, '+')) + bMultiple = TRUE; + else + bMultiple = FALSE; + + append = 0; + copied = 0; + + if (bDestFound && !bWildcards) + { + copied = SetupCopy (sources, p, bMultiple, drive_d, dir_d, file_d, ext_d, &append, &dwFlags); + } + else if (bDestFound && bWildcards) + { + ConErrPrintf (_T("Error: Not implemented yet!\n")); + DeleteFileList (sources); + freep (p); + return 0; + } + else if (!bDestFound && !bMultiple) + { + _splitpath (sources->szFile, drive_d, dir_d, file_d, ext_d); + if (IsDirectory (sources->szFile)) + { + _tcscat (dir_d, file_d); + _tcscat (dir_d, ext_d); + file_d[0] = _T('\0'); + ext_d[0] = _T('\0'); + } + copied = SetupCopy (sources, p, FALSE, "", "", file_d, ext_d, &append, &dwFlags); + } + else + { + _splitpath(sources->szFile, drive_d, dir_d, file_d, ext_d); + if (IsDirectory (sources->szFile)) + { + _tcscat (dir_d, file_d); + _tcscat (dir_d, ext_d); + file_d[0] = _T('\0'); + ext_d[0] = _T('\0'); + } + + ConOutPuts (sources->szFile); + append = 1; + copied = SetupCopy (sources->next, p, bMultiple, drive_d, dir_d, file_d, ext_d, &append, &dwFlags) + 1; + } + + DeleteFileList (sources); + freep (p); + ConOutPrintf (_T(" %d file(s) copied\n"), copied); + + return 1; +} +#endif /* INCLUDE_CMD_COPY */ + +/* EOF */ diff --git a/subsys/system/cmd/date.c b/subsys/system/cmd/date.c new file mode 100644 index 0000000..bcee0d6 --- /dev/null +++ b/subsys/system/cmd/date.c @@ -0,0 +1,261 @@ +/* + * DATE.C - date internal command. + * + * + * History: + * + * 08 Jul 1998 (John P. Price) + * started. + * + * 20 Jul 1998 (John P. Price) + * corrected number of days for December from 30 to 31. + * (Thanx to Steffen Kaiser for bug report) + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 29-Jul-1998 (Rob Lake) + * fixed stand-alone mode. + * Added Pacific C compatible dos_getdate functions + * + * 09-Jan-1999 (Eric Kohl ) + * Added locale support + * + * 23-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * + * 04-Feb-1999 (Eric Kohl ) + * Fixed date input bug. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_DATE + +#include +#include +#include +#include + +#include "cmd.h" + + +static WORD awMonths[2][13] = +{ + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + + +static VOID +PrintDateString (VOID) +{ + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + ConOutPrintf (_T("\nEnter new date (mm%cdd%cyyyy): "), + cDateSeparator, cDateSeparator); + break; + + case 1: /* ddmmyy */ + ConOutPrintf (_T("\nEnter new date (dd%cmm%cyyyy): "), + cDateSeparator, cDateSeparator); + break; + + case 2: /* yymmdd */ + ConOutPrintf (_T("\nEnter new date (yyyy%cmm%cdd): "), + cDateSeparator, cDateSeparator); + break; + } +} + + +static BOOL +ReadNumber (LPTSTR *s, LPWORD lpwValue) +{ + if (_istdigit (**s)) + { + while (_istdigit (**s)) + { + *lpwValue = *lpwValue * 10 + **s - _T('0'); + (*s)++; + } + return TRUE; + } + return FALSE; +} + + +static BOOL +ReadSeparator (LPTSTR *s) +{ + if (**s == _T('/') || **s == _T('-') || **s == cDateSeparator) + { + (*s)++; + return TRUE; + } + return FALSE; +} + + +static BOOL +ParseDate (LPTSTR s) +{ + SYSTEMTIME d; + unsigned char leap; + LPTSTR p = s; + + if (!*s) + return TRUE; + + GetLocalTime (&d); + + d.wYear = 0; + d.wDay = 0; + d.wMonth = 0; + + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + break; + + case 1: /* ddmmyy */ + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + break; + + case 2: /* yymmdd */ + if (!ReadNumber (&p, &d.wYear)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wMonth)) + return FALSE; + if (!ReadSeparator (&p)) + return FALSE; + if (!ReadNumber (&p, &d.wDay)) + return FALSE; + break; + } + + /* if only entered two digits: */ + /* assume 2000's if value less than 80 */ + /* assume 1900's if value greater or equal 80 */ + if (d.wYear <= 99) + { + if (d.wYear >= 80) + d.wYear = 1900 + d.wYear; + else + d.wYear = 2000 + d.wYear; + } + + leap = (!(d.wYear % 4) && (d.wYear % 100)) || !(d.wYear % 400); + + if ((d.wMonth >= 1 && d.wMonth <= 12) && + (d.wDay >= 1 && d.wDay <= awMonths[leap][d.wMonth]) && + (d.wYear >= 1980 && d.wYear <= 2099)) + { + SetLocalTime (&d); + return TRUE; + } + + return FALSE; +} + + +INT cmd_date (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg; + INT argc; + INT i; + BOOL bPrompt = TRUE; + INT nDateString = -1; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or sets the date.\n\n" + "DATE [/T][date]\n\n" + " /T display only\n\n" + "Type DATE without parameters to display the current date setting and\n" + "a prompt for a new one. Press ENTER to keep the same date.")); + return 0; + } + + /* build parameter array */ + arg = split (param, &argc, FALSE); + + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/t")) == 0) + bPrompt = FALSE; + if ((*arg[i] != _T('/')) && (nDateString == -1)) + nDateString = i; + } + + if (nDateString == -1) + PrintDate (); + + if (!bPrompt) + { + freep (arg); + return 0; + } + + if (nDateString == -1) + { + while (TRUE) /* forever loop */ + { + TCHAR s[40]; + + PrintDateString (); + ConInString (s, 40); +#ifdef _DEBUG + DebugPrintf ("\'%s\'\n", s); +#endif + while (*s && s[_tcslen (s) - 1] < ' ') + s[_tcslen (s) - 1] = '\0'; + if (ParseDate (s)) + { + freep (arg); + return 0; + } + ConErrPuts ("Invalid date."); + } + } + else + { + if (ParseDate (arg[nDateString])) + { + freep (arg); + return 0; + } + ConErrPuts ("Invalid date."); + } + + freep (arg); + + return 0; +} +#endif + diff --git a/subsys/system/cmd/del.c b/subsys/system/cmd/del.c new file mode 100644 index 0000000..6ef495e --- /dev/null +++ b/subsys/system/cmd/del.c @@ -0,0 +1,348 @@ +/* + * DEL.C - del internal command. + * + * + * History: + * + * 06/29/98 (Rob Lake rlake@cs.mun.ca) + * rewrote del to support wildcards + * added my name to the contributors + * + * 07/13/98 (Rob Lake) + * fixed bug that caused del not to delete file with out + * attribute. moved set, del, ren, and ver to there own files + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 09-Dec-1998 (Eric Kohl ) + * Fixed command line parsing bugs. + * + * 21-Jan-1999 (Eric Kohl ) + * Started major rewrite using a new structure. + * + * 03-Feb-1999 (Eric Kohl ) + * First working version. + * + * 30-Mar-1999 (Eric Kohl ) + * Added quiet ("/Q"), wipe ("/W") and zap ("/Z") option. + * + * 06-Nov-1999 (Eric Kohl ) + * Little fix to keep DEL quiet inside batch files. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_DEL + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +enum +{ + DEL_ATTRIBUTES = 0x001, /* /A : not implemented */ + DEL_ERROR = 0x002, /* /E : not implemented */ + DEL_NOTHING = 0x004, /* /N */ + DEL_PROMPT = 0x008, /* /P : not implemented */ + DEL_QUIET = 0x010, /* /Q */ + DEL_SUBDIR = 0x020, /* /S : not implemented */ + DEL_TOTAL = 0x040, /* /T */ + DEL_WIPE = 0x080, /* /W */ + DEL_EMPTYDIR = 0x100, /* /X : not implemented */ + DEL_YES = 0x200, /* /Y : not implemented */ + DEL_ZAP = 0x400 /* /Z */ +}; + + + +static BOOL +RemoveFile (LPTSTR lpFileName, DWORD dwFlags) +{ + if (dwFlags & DEL_WIPE) + { + + /* FIXME: Wipe the given file */ + + } + + return DeleteFile (lpFileName); +} + + +INT CommandDelete (LPTSTR cmd, LPTSTR param) +{ + TCHAR szFullPath[MAX_PATH]; + LPTSTR pFilePart; + LPTSTR *arg = NULL; + INT args; + INT i; + INT nEvalArgs = 0; /* nunber of evaluated arguments */ + DWORD dwFlags = 0; + DWORD dwFiles = 0; + + HANDLE hFile; + WIN32_FIND_DATA f; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Deletes one or more files.\n" + "\n" + "DEL [/N /P /T /Q /W /Z] file ...\n" + "DELETE [/N /P /T /Q /W /Z] file ...\n" + "ERASE [/N /P /T /Q /W /Z] file ...\n" + "\n" + " file Specifies the file(s) to delete.\n" + "\n" + " /N Nothing.\n" + " /P Prompts for confirmation before deleting each file.\n" + " (Not implemented yet!)\n" + " /T Display total number of deleted files and freed disk space.\n" + " /Q Quiet.\n" + " /W Wipe. Overwrite the file with zeros before deleting it.\n" + " /Z Zap (delete hidden, read-only and system files).\n")); + + return 0; + } + + arg = split (param, &args, FALSE); + + if (args > 0) + { + /* check for options anywhere in command line */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) + { + if (_tcslen (arg[i]) >= 2) + { + switch (_totupper (arg[i][1])) + { + case _T('N'): + dwFlags |= DEL_NOTHING; + break; + + case _T('P'): + dwFlags |= DEL_PROMPT; + break; + + case _T('Q'): + dwFlags |= DEL_QUIET; + break; + + case _T('S'): + dwFlags |= DEL_SUBDIR; + break; + + case _T('T'): + dwFlags |= DEL_TOTAL; + break; + + case _T('W'): + dwFlags |= DEL_WIPE; + break; + + case _T('Z'): + dwFlags |= DEL_ZAP; + break; + } + + } + + nEvalArgs++; + } + } + + /* there are only options on the command line --> error!!! */ + if (args == nEvalArgs) + { + error_req_param_missing (); + freep (arg); + return 1; + } + + /* keep quiet within batch files */ + if (bc != NULL) + dwFlags |= DEL_QUIET; + + /* check for filenames anywhere in command line */ + for (i = 0; i < args; i++) + { + if (!_tcscmp (arg[i], _T("*")) || + !_tcscmp (arg[i], _T("*.*"))) + { + INT res; + + res = FilePromptYN (_T("All files in directory will be deleted!\n" + "Are you sure (Y/N)?")); + if ((res == PROMPT_NO) || + (res == PROMPT_BREAK)) + break; + } + + if (*arg[i] != _T('/')) + { +#ifdef _DEBUG + ConErrPrintf (_T("File: %s\n"), arg[i]); +#endif + + if (_tcschr (arg[i], _T('*')) || _tcschr (arg[i], _T('?'))) + { + /* wildcards in filespec */ +#ifdef _DEBUG + ConErrPrintf (_T("Wildcards!\n\n")); +#endif + + GetFullPathName (arg[i], + MAX_PATH, + szFullPath, + &pFilePart); + +#ifdef _DEBUG + ConErrPrintf (_T("Full path: %s\n"), szFullPath); + ConErrPrintf (_T("File part: %s\n"), pFilePart); +#endif + + hFile = FindFirstFile (szFullPath, &f); + if (hFile == INVALID_HANDLE_VALUE) + { + error_file_not_found (); + freep (arg); + return 0; + } + + do + { + /* ignore "." and ".." */ + if (!_tcscmp (f.cFileName, _T(".")) || + !_tcscmp (f.cFileName, _T(".."))) + continue; + + _tcscpy (pFilePart, f.cFileName); + +#ifdef _DEBUG + ConErrPrintf (_T("Full filename: %s\n"), szFullPath); +#endif + + if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL)) + ConErrPrintf (_T("Deleting: %s\n"), szFullPath); + + /* delete the file */ + if (!(dwFlags & DEL_NOTHING)) + { + if (RemoveFile (szFullPath, dwFlags)) + { + dwFiles++; + } + else + { + if (dwFlags & DEL_ZAP) + { + if (SetFileAttributes (szFullPath, 0)) + { + if (RemoveFile (szFullPath, dwFlags)) + { + dwFiles++; + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + } + } + while (FindNextFile (hFile, &f)); + FindClose (hFile); + } + else + { + /* no wildcards in filespec */ +#ifdef _DEBUG + ConErrPrintf (_T("No Wildcards!\n")); +#endif + GetFullPathName (arg[i], + MAX_PATH, + szFullPath, + &pFilePart); +#ifdef _DEBUG + ConErrPrintf (_T("Full path: %s\n"), szFullPath); +#endif + if (!(dwFlags & DEL_QUIET) && !(dwFlags & DEL_TOTAL)) + ConOutPrintf (_T("Deleting %s\n"), szFullPath); + + if (!(dwFlags & DEL_NOTHING)) + { + if (RemoveFile (szFullPath, dwFlags)) + { + dwFiles++; + } + else + { + if (dwFlags & DEL_ZAP) + { + if (SetFileAttributes (szFullPath, 0)) + { + if (RemoveFile (szFullPath, dwFlags)) + { + dwFiles++; + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + else + { + ErrorMessage (GetLastError(), _T("")); + } + } + } + } + } + } + } + else + { + /* only command given */ + error_req_param_missing (); + freep (arg); + return 1; + } + + freep (arg); + + if (!(dwFlags & DEL_QUIET)) + { + if (dwFiles == 0) + ConOutPrintf (_T(" 0 files deleted\n")); + else + ConOutPrintf (_T(" %lu file%s deleted\n"), + dwFiles, + (dwFiles == 1) ? "" : "s"); + } + + return 0; +} + +#endif diff --git a/subsys/system/cmd/delay.c b/subsys/system/cmd/delay.c new file mode 100644 index 0000000..1c953ab --- /dev/null +++ b/subsys/system/cmd/delay.c @@ -0,0 +1,58 @@ +/* + * DELAY.C - internal command. + * + * clone from 4nt delay command + * + * 30 Aug 1999 + * started - Paolo Pantaleo + * + * + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_DELAY + +#include +#include +#include + +#include "cmd.h" + + +INT CommandDelay (LPTSTR cmd, LPTSTR param) +{ + DWORD val; + DWORD mul=1000; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts(_T( + "pause for n seconds or milliseconds" + "\n" + "DELAY [/m]n\n" + "\n" + " /m specifiy than n are milliseconds\n" + " otherwise n are seconds")); + return 0; + } + + if (*param==0) + { + error_req_param_missing (); + return 1; + } + + if (_tcsnicmp(param,"/m",2) == 0) + { + mul = 1; + param += 2; + } + + val = atoi(param); + Sleep(val*mul); + + return 0; +} + +#endif /* INCLUDE_CMD_DELAY */ diff --git a/subsys/system/cmd/dir.c b/subsys/system/cmd/dir.c new file mode 100644 index 0000000..fc579fb --- /dev/null +++ b/subsys/system/cmd/dir.c @@ -0,0 +1,1223 @@ +/* $Id$ + * + * DIR.C - dir internal command. + * + * + * History: + * + * 01/29/97 (Tim Norman) + * started. + * + * 06/13/97 (Tim Norman) + * Fixed code. + * + * 07/12/97 (Tim Norman) + * Fixed bug that caused the root directory to be unlistable + * + * 07/12/97 (Marc Desrochers) + * Changed to use maxx, maxy instead of findxy() + * + * 06/08/98 (Rob Lake) + * Added compatibility for /w in dir + * + * 06/09/98 (Rob Lake) + * Compatibility for dir/s started + * Tested that program finds directories off root fine + * + * 06/10/98 (Rob Lake) + * do_recurse saves the cwd and also stores it in Root + * build_tree adds the cwd to the beginning of its' entries + * Program runs fine, added print_tree -- works fine.. as EXE, + * program won't work properly as COM. + * + * 06/11/98 (Rob Lake) + * Found problem that caused COM not to work + * + * 06/12/98 (Rob Lake) + * debugged... + * added free mem routine + * + * 06/13/98 (Rob Lake) + * debugged the free mem routine + * debugged whole thing some more + * Notes: + * ReadDir stores Root name and _Read_Dir does the hard work + * PrintDir prints Root and _Print_Dir does the hard work + * KillDir kills Root _after_ _Kill_Dir does the hard work + * Integrated program into DIR.C(this file) and made some same + * changes throughout + * + * 06/14/98 (Rob Lake) + * Cleaned up code a bit, added comments + * + * 06/16/98 (Rob Lake) + * Added error checking to my previously added routines + * + * 06/17/98 (Rob Lake) + * Rewrote recursive functions, again! Most other recursive + * functions are now obsolete -- ReadDir, PrintDir, _Print_Dir, + * KillDir and _Kill_Dir. do_recurse does what PrintDir did + * and _Read_Dir did what it did before along with what _Print_Dir + * did. Makes /s a lot faster! + * Reports 2 more files/dirs that MS-DOS actually reports + * when used in root directory(is this because dir defaults + * to look for read only files?) + * Added support for /b, /a and /l + * Made error message similar to DOS error messages + * Added help screen + * + * 06/20/98 (Rob Lake) + * Added check for /-(switch) to turn off previously defined + * switches. + * Added ability to check for DIRCMD in environment and + * process it + * + * 06/21/98 (Rob Lake) + * Fixed up /B + * Now can dir *.ext/X, no spaces! + * + * 06/29/98 (Rob Lake) + * error message now found in command.h + * + * 07/08/1998 (John P. Price) + * removed extra returns; closer to MSDOS + * fixed wide display so that an extra return is not displayed + * when there is five filenames in the last line. + * + * 07/12/98 (Rob Lake) + * Changed error messages + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * + * 04-Dec-1998 (Eric Kohl ) + * Converted source code to Win32, except recursive dir ("dir /s"). + * + * 10-Dec-1998 (Eric Kohl ) + * Fixed recursive dir ("dir /s"). + * + * 14-Dec-1998 (Eric Kohl ) + * Converted to Win32 directory functions and + * fixed some output bugs. There are still some more ;) + * + * 10-Jan-1999 (Eric Kohl ) + * Added "/N" and "/4" options, "/O" is a dummy. + * Added locale support. + * + * 20-Jan-1999 (Eric Kohl ) + * Redirection safe! + * + * 01-Mar-1999 (Eric Kohl ) + * Replaced all runtime io functions by their Win32 counterparts. + * + * 23-Feb-2001 (Carl Nettelblad ) + * dir /s now works in deeper trees + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_DIR +#include +#include +#include +#include +#include +#include + +#include "cmd.h" + + +typedef BOOL STDCALL +(*PGETFREEDISKSPACEEX)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); + + +/* flag definitions */ +enum +{ + DIR_RECURSE = 0x0001, + DIR_PAGE = 0x0002, + DIR_WIDE = 0x0004, /* Rob Lake */ + DIR_BARE = 0x0008, /* Rob Lake */ + DIR_ALL = 0x0010, /* Rob Lake */ + DIR_LWR = 0x0020, /* Rob Lake */ + DIR_SORT = 0x0040, /* /O sort */ + DIR_NEW = 0x0080, /* /N new style */ + DIR_FOUR = 0x0100 /* /4 four digit year */ +}; + + +/* Globally save the # of dirs, files and bytes, + * probabaly later pass them to functions. Rob Lake */ +static ULONG recurse_dir_cnt; +static ULONG recurse_file_cnt; +static ULARGE_INTEGER recurse_bytes; + + +/* + * help + * + * displays help screen for dir + * Rob Lake + */ +static VOID Help (VOID) +{ + ConOutPuts(_T("Displays a list of files and subdirectories in a directory.\n" + "\n" + "DIR [drive:][path][filename] [/A] [/B] [/L] [/N] [/S] [/P] [/W] [/4]\n" + "\n" + " [drive:][path][filename]\n" + " Specifies drive, directory, and/or files to list.\n" + "\n" + " /A Displays files with HIDDEN SYSTEM attributes\n" + " default is ARCHIVE and READ ONLY\n" + " /B Uses bare format (no heading information or summary).\n" + " /L Uses lowercase.\n" + " /N New long list format where filenames are on the far right.\n" + " /S Displays files in specified directory and all subdirectories\n" + " /P Pauses after each screen full\n" + " /W Prints in wide format\n" + " /4 Display four digit years.\n" + "\n" + "Switches may be present in the DIRCMD environment variable. Use\n" + "of the - (hyphen) can turn off defined swtiches. Ex. /-W would\n" + "turn off printing in wide format.\n" + )); +} + + +/* + * DirReadParam + * + * read the parameters from the command line + */ +static BOOL +DirReadParam (LPTSTR line, LPTSTR *param, LPDWORD lpFlags) +{ + INT slash = 0; + + if (!line) + return TRUE; + + *param = NULL; + + /* scan the command line, processing switches */ + while (*line) + { + /* process switch */ + if (*line == _T('/') || slash) + { + if (!slash) + line++; + slash = 0; + if (*line == _T('-')) + { + line++; + if (_totupper (*line) == _T('S')) + *lpFlags &= ~DIR_RECURSE; + else if (_totupper (*line) == _T('P')) + *lpFlags &= ~DIR_PAGE; + else if (_totupper (*line) == _T('W')) + *lpFlags &= ~DIR_WIDE; + else if (_totupper (*line) == _T('B')) + *lpFlags &= ~DIR_BARE; + else if (_totupper (*line) == _T('A')) + *lpFlags &= ~DIR_ALL; + else if (_totupper (*line) == _T('L')) + *lpFlags &= ~DIR_LWR; + else if (_totupper (*line) == _T('N')) + *lpFlags &= ~DIR_NEW; + else if (_totupper (*line) == _T('O')) + *lpFlags &= ~DIR_SORT; + else if (_totupper (*line) == _T('4')) + *lpFlags &= ~DIR_FOUR; + else + { + error_invalid_switch ((TCHAR)_totupper (*line)); + return FALSE; + } + line++; + continue; + } + else + { + if (_totupper (*line) == _T('S')) + *lpFlags |= DIR_RECURSE; + else if (_totupper (*line) == _T('P')) + *lpFlags |= DIR_PAGE; + else if (_totupper (*line) == _T('W')) + *lpFlags |= DIR_WIDE; + else if (_totupper (*line) == _T('B')) + *lpFlags |= DIR_BARE; + else if (_totupper (*line) == _T('A')) + *lpFlags |= DIR_ALL; + else if (_totupper (*line) == _T('L')) + *lpFlags |= DIR_LWR; + else if (_totupper (*line) == _T('N')) + *lpFlags |= DIR_NEW; + else if (_totupper (*line) == _T('O')) + *lpFlags |= DIR_SORT; + else if (_totupper (*line) == _T('4')) + *lpFlags |= DIR_FOUR; + else if (*line == _T('?')) + { + Help(); + return FALSE; + } + else + { + error_invalid_switch ((TCHAR)_totupper (*line)); + return FALSE; + } + line++; + continue; + } + } + + /* process parameter */ + if (!_istspace (*line)) + { + if (*param) + { + error_too_many_parameters (*param); + return FALSE; + } + + *param = line; + + /* skip to end of line or next whitespace or next / */ + while (*line && !_istspace (*line) && *line != _T('/')) + line++; + + /* if end of line, return */ + if (!*line) + return TRUE; + + /* if parameter, remember to process it later */ + if (*line == _T('/')) + slash = 1; + + *line++ = 0; + continue; + } + + line++; + } + + if (slash) + { + error_invalid_switch ((TCHAR)_totupper (*line)); + return FALSE; + } + + return TRUE; +} + + +/* + * ExtendFilespec + * + * extend the filespec, possibly adding wildcards + */ +static VOID +ExtendFilespec (LPTSTR file) +{ + INT len = 0; + + if (!file) + return; + + /* if no file spec, change to "*.*" */ + if (*file == _T('\0')) + { + _tcscpy (file, _T("*.*")); + return; + } + + /* if starts with . add * in front */ + if (*file == _T('.')) + { + memmove (&file[1], &file[0], (_tcslen (file) + 1) * sizeof(TCHAR)); + file[0] = _T('*'); + } + + /* if no . add .* */ + if (!_tcschr (file, _T('.'))) + { + _tcscat (file, _T(".*")); + return; + } + + /* if last character is '.' add '*' */ + len = _tcslen (file); + if (file[len - 1] == _T('.')) + { + _tcscat (file, _T("*")); + return; + } +} + + +/* + * dir_parse_pathspec + * + * split the pathspec into drive, directory, and filespec + */ +static INT +DirParsePathspec (LPTSTR szPathspec, LPTSTR szPath, LPTSTR szFilespec) +{ + TCHAR szOrigPath[MAX_PATH]; + LPTSTR start; + LPTSTR tmp; + INT i; + BOOL bWildcards = FALSE; + + GetCurrentDirectory (MAX_PATH, szOrigPath); + + /* get the drive and change to it */ + if (szPathspec[1] == _T(':')) + { + TCHAR szRootPath[] = _T("A:"); + + szRootPath[0] = szPathspec[0]; + start = szPathspec + 2; + SetCurrentDirectory (szRootPath); + } + else + { + start = szPathspec; + } + + + /* check for wildcards */ + for (i = 0; szPathspec[i]; i++) + { + if (szPathspec[i] == _T('*') || szPathspec[i] == _T('?')) + bWildcards = TRUE; + } + + /* check if this spec is a directory */ + if (!bWildcards) + { + if (SetCurrentDirectory (szPathspec)) + { + _tcscpy (szFilespec, _T("*.*")); + + if (!GetCurrentDirectory (MAX_PATH, szPath)) + { + szFilespec[0] = _T('\0'); + SetCurrentDirectory (szOrigPath); + error_out_of_memory(); + return 1; + } + + SetCurrentDirectory (szOrigPath); + return 0; + } + } + + /* find the file spec */ + tmp = _tcsrchr (start, _T('\\')); + + /* if no path is specified */ + if (!tmp) + { + _tcscpy (szFilespec, start); + ExtendFilespec (szFilespec); + if (!GetCurrentDirectory (MAX_PATH, szPath)) + { + szFilespec[0] = _T('\0'); + SetCurrentDirectory (szOrigPath); + error_out_of_memory(); + return 1; + } + + SetCurrentDirectory (szOrigPath); + return 0; + } + + /* get the filename */ + _tcscpy (szFilespec, tmp+1); + ExtendFilespec (szFilespec); + + *tmp = _T('\0'); + + /* change to this directory and get its full name */ + if (!SetCurrentDirectory (start)) + { + *tmp = _T('\\'); + szFilespec[0] = _T('\0'); + SetCurrentDirectory (szOrigPath); + error_path_not_found (); + return 1; + } + + if (!GetCurrentDirectory (MAX_PATH, szPath)) + { + *tmp = _T('\\'); + szFilespec[0] = _T('\0'); + SetCurrentDirectory (szOrigPath); + error_out_of_memory (); + return 1; + } + + *tmp = _T('\\'); + + SetCurrentDirectory (szOrigPath); + + return 0; +} + + +/* + * incline + * + * increment our line if paginating, display message at end of screen + */ +static BOOL +IncLine (LPINT pLine, DWORD dwFlags) +{ + if (!(dwFlags & DIR_PAGE)) + return FALSE; + + (*pLine)++; + + if (*pLine >= (int)maxy - 2) + { + *pLine = 0; + return (PagePrompt () == PROMPT_BREAK); + } + + return FALSE; +} + + +/* + * PrintDirectoryHeader + * + * print the header for the dir command + */ +static BOOL +PrintDirectoryHeader (LPTSTR szPath, LPINT pLine, DWORD dwFlags) +{ + TCHAR szRootName[MAX_PATH]; + TCHAR szVolName[80]; + DWORD dwSerialNr; + LPTSTR p; + + if (dwFlags & DIR_BARE) + return(TRUE); + + /* build usable root path */ + if (szPath[1] == _T(':') && szPath[2] == _T('\\')) + { + /* normal path */ + szRootName[0] = szPath[0]; + szRootName[1] = _T(':'); + szRootName[2] = _T('\\'); + szRootName[3] = 0; + } + else if (szPath[0] == _T('\\') && szPath[1] == _T('\\')) + { + /* UNC path */ + p = _tcschr(&szPath[2], _T('\\')); + if (p == NULL) + { + error_invalid_drive(); + return(FALSE); + } + p = _tcschr(p+1, _T('\\')); + if (p == NULL) + { + _tcscpy(szRootName, szPath); + _tcscat(szRootName, _T("\\")); + } + else + { + *p = 0; + _tcscpy(szRootName, szPath); + _tcscat(szRootName, _T("\\")); + *p = _T('\\'); + } + } + else + { + error_invalid_drive(); + return(FALSE); + } + + /* get the media ID of the drive */ + if (!GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, + NULL, NULL, NULL, 0)) + { + error_invalid_drive(); + return(FALSE); + } + + /* print drive info */ + ConOutPrintf(_T(" Volume in drive %c"), szRootName[0]); + + if (szVolName[0] != _T('\0')) + ConOutPrintf(_T(" is %s\n"), szVolName); + else + ConOutPrintf(_T(" has no label\n")); + + if (IncLine(pLine, dwFlags)) + return(FALSE); + + /* print the volume serial number if the return was successful */ + ConOutPrintf(_T(" Volume Serial Number is %04X-%04X\n"), + HIWORD(dwSerialNr), + LOWORD(dwSerialNr)); + if (IncLine(pLine, dwFlags)) + return(FALSE); + + return(TRUE); +} + + +/* + * convert + * + * insert commas into a number + */ +static INT +ConvertULong (ULONG num, LPTSTR des, INT len) +{ + TCHAR temp[32]; + INT c = 0; + INT n = 0; + + if (num == 0) + { + des[0] = _T('0'); + des[1] = _T('\0'); + n = 1; + } + else + { + temp[31] = 0; + while (num > 0) + { + if (((c + 1) % (nNumberGroups + 1)) == 0) + temp[30 - c++] = cThousandSeparator; + temp[30 - c++] = (TCHAR)(num % 10) + _T('0'); + num /= 10; + } + + for (n = 0; n <= c; n++) + des[n] = temp[31 - c + n]; + } + + return n; +} + + +static INT +ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len) +{ + TCHAR temp[32]; + INT c = 0; + INT n = 0; + + if (num.QuadPart == 0) + { + des[0] = _T('0'); + des[1] = _T('\0'); + n = 1; + } + else + { + temp[31] = 0; + while (num.QuadPart > 0) + { + if (((c + 1) % (nNumberGroups + 1)) == 0) + temp[30 - c++] = cThousandSeparator; + temp[30 - c++] = (TCHAR)(num.QuadPart % 10) + _T('0'); + num.QuadPart /= 10; + } + + for (n = 0; n <= c; n++) + des[n] = temp[31 - c + n]; + } + + return n; +} + + +static VOID +PrintFileDateTime (LPSYSTEMTIME dt, DWORD dwFlags) +{ + WORD wYear = (dwFlags & DIR_FOUR) ? dt->wYear : dt->wYear%100; + + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + ConOutPrintf (_T("%.2d%c%.2d%c%d"), + dt->wMonth, cDateSeparator, dt->wDay, cDateSeparator, wYear); + break; + + case 1: /* ddmmyy */ + ConOutPrintf (_T("%.2d%c%.2d%c%d"), + dt->wDay, cDateSeparator, dt->wMonth, cDateSeparator, wYear); + break; + + case 2: /* yymmdd */ + ConOutPrintf (_T("%d%c%.2d%c%.2d"), + wYear, cDateSeparator, dt->wMonth, cDateSeparator, dt->wDay); + break; + } + + switch (nTimeFormat) + { + case 0: /* 12 hour format */ + default: + ConOutPrintf (_T(" %2d%c%.2u%c"), + (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)), + cTimeSeparator, + dt->wMinute, (dt->wHour <= 11 ? 'a' : 'p')); + break; + + case 1: /* 24 hour format */ + ConOutPrintf (_T(" %2d%c%.2u"), + dt->wHour, cTimeSeparator, dt->wMinute); + break; + } +} + + +static VOID +GetUserDiskFreeSpace(LPCTSTR lpRoot, + PULARGE_INTEGER lpFreeSpace) +{ + PGETFREEDISKSPACEEX pGetFreeDiskSpaceEx; + HINSTANCE hInstance; + DWORD dwSecPerCl; + DWORD dwBytPerSec; + DWORD dwFreeCl; + DWORD dwTotCl; + + lpFreeSpace->QuadPart = 0; + + hInstance = LoadLibrary(_T("KERNEL32")); + if (hInstance != NULL) + { +#ifndef UNICODE + pGetFreeDiskSpaceEx = GetProcAddress(hInstance, + "GetDiskFreeSpaceExA"); +#else + pGetFreeDiskSpaceEx = GetProcAddress(hInstance, + "GetDiskFreeSpaceExW"); +#endif + if (pGetFreeDiskSpaceEx != NULL) + { + if (pGetFreeDiskSpaceEx(lpRoot, lpFreeSpace, NULL, NULL) == TRUE) + return; + } + FreeLibrary(hInstance); + } + + GetDiskFreeSpace(lpRoot, + &dwSecPerCl, + &dwBytPerSec, + &dwFreeCl, + &dwTotCl); + + lpFreeSpace->QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl; +} + + +/* + * print_summary: prints dir summary + * Added by Rob Lake 06/17/98 to compact code + * Just copied Tim's Code and patched it a bit + * + */ +static INT +PrintSummary(LPTSTR szPath, + ULONG ulFiles, + ULONG ulDirs, + ULARGE_INTEGER bytes, + LPINT pLine, + DWORD dwFlags) +{ + TCHAR buffer[64]; + ULARGE_INTEGER uliFree; + TCHAR szRoot[] = _T("A:\\"); + + if (dwFlags & DIR_BARE) + return(0); + + /* Print number of files and bytes */ + ConvertULong (ulFiles, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %6s File%c"), + buffer, ulFiles == 1 ? _T(' ') : _T('s')); + + ConvertULargeInteger (bytes, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %15s byte%c\n"), + buffer, bytes.QuadPart == 1 ? _T(' ') : _T('s')); + ConOutPrintf (_T(" %I64u byte%c\n"), + bytes.QuadPart, bytes.QuadPart == 1 ? _T(' ') : _T('s')); + + if (IncLine (pLine, dwFlags)) + return 1; + + /* Print number of dirs and bytes free */ + ConvertULong (ulDirs, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %6s Dir%c"), + buffer, ulDirs == 1 ? _T(' ') : _T('s')); + + if (!(dwFlags & DIR_RECURSE)) + { + szRoot[0] = szPath[0]; + GetUserDiskFreeSpace(szRoot, &uliFree); + ConvertULargeInteger (uliFree, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %15s bytes free\n"), buffer); + } + + if (IncLine (pLine, dwFlags)) + return 1; + + return 0; +} + + +/* + * dir_list + * + * list the files in the directory + */ +static INT +DirList (LPTSTR szPath, LPTSTR szFilespec, LPINT pLine, DWORD dwFlags) +{ + TCHAR szFullPath[MAX_PATH]; + WIN32_FIND_DATA file; + ULARGE_INTEGER bytecount; + FILETIME ft; + SYSTEMTIME dt; + HANDLE hFile; + TCHAR buffer[32]; + ULONG filecount = 0; + ULONG dircount = 0; + INT count; + + bytecount.QuadPart = 0; + + _tcscpy (szFullPath, szPath); + if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\')) + _tcscat (szFullPath, _T("\\")); + _tcscat (szFullPath, szFilespec); + + hFile = FindFirstFile (szFullPath, &file); + if (hFile == INVALID_HANDLE_VALUE) + { + /* Don't want to print anything if scanning recursively + * for a file. RL + */ + if ((dwFlags & DIR_RECURSE) == 0) + { + FindClose (hFile); + error_file_not_found (); + if (IncLine (pLine, dwFlags)) + return 0; + return 1; + } + FindClose (hFile); + return 0; + } + + /* moved down here because if we are recursively searching and + * don't find any files, we don't want just to print + * Directory of C:\SOMEDIR + * with nothing else + * Rob Lake 06/13/98 + */ + if ((dwFlags & DIR_BARE) == 0) + { + ConOutPrintf (_T(" Directory of %s\n"), szPath); + if (IncLine (pLine, dwFlags)) + return 1; + ConOutPrintf (_T("\n")); + if (IncLine (pLine, dwFlags)) + return 1; + } + + /* For counting columns of output */ + count = 0; + + do + { + /* next file, if user doesn't want all files */ + if (!(dwFlags & DIR_ALL) && + ((file.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) || + (file.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))) + continue; + + if (dwFlags & DIR_LWR) + { + _tcslwr (file.cAlternateFileName); + } + + if (dwFlags & DIR_WIDE && (dwFlags & DIR_BARE) == 0) + { + ULARGE_INTEGER uliSize; + + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (file.cAlternateFileName[0] == _T('\0')) + _stprintf (buffer, _T("[%s]"), file.cFileName); + else + _stprintf (buffer, _T("[%s]"), file.cAlternateFileName); + dircount++; + } + else + { + if (file.cAlternateFileName[0] == _T('\0')) + _stprintf (buffer, _T("%s"), file.cFileName); + else + _stprintf (buffer, _T("%s"), file.cAlternateFileName); + filecount++; + } + + ConOutPrintf (_T("%-15s"), buffer); + count++; + if (count == 5) + { + /* output 5 columns */ + ConOutPrintf (_T("\n")); + if (IncLine (pLine, dwFlags)) + return 1; + count = 0; + } + + uliSize.LowPart = file.nFileSizeLow; + uliSize.HighPart = file.nFileSizeHigh; + bytecount.QuadPart += uliSize.QuadPart; + } + else if (dwFlags & DIR_BARE) + { + ULARGE_INTEGER uliSize; + + if (_tcscmp (file.cFileName, _T(".")) == 0 || + _tcscmp (file.cFileName, _T("..")) == 0) + continue; + + if (dwFlags & DIR_RECURSE) + { + TCHAR dir[MAX_PATH]; + + _tcscpy (dir, szPath); + _tcscat (dir, _T("\\")); + if (dwFlags & DIR_LWR) + _tcslwr (dir); + ConOutPrintf (dir); + } + + ConOutPrintf (_T("%-13s\n"), file.cFileName); + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + dircount++; + else + filecount++; + if (IncLine (pLine, dwFlags)) + return 1; + + uliSize.LowPart = file.nFileSizeLow; + uliSize.HighPart = file.nFileSizeHigh; + bytecount.QuadPart += uliSize.QuadPart; + } + else + { + if (dwFlags & DIR_NEW) + { + /* print file date and time */ + if (FileTimeToLocalFileTime (&file.ftLastWriteTime, &ft)) + { + FileTimeToSystemTime (&ft, &dt); + PrintFileDateTime (&dt, dwFlags); + } + + /* print file size */ + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ConOutPrintf (_T(" ")); + dircount++; + } + else + { + ULARGE_INTEGER uliSize; + + uliSize.LowPart = file.nFileSizeLow; + uliSize.HighPart = file.nFileSizeHigh; + + ConvertULargeInteger (uliSize, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %20s"), buffer); + + bytecount.QuadPart += uliSize.QuadPart; + filecount++; + } + + /* print long filename */ + ConOutPrintf (_T(" %s\n"), file.cFileName); + } + else + { + if (file.cFileName[0] == _T('.')) + ConOutPrintf (_T("%-13s "), file.cFileName); + else if (file.cAlternateFileName[0] == _T('\0')) + { + TCHAR szShortName[13]; + LPTSTR ext; + + _tcsncpy (szShortName, file.cFileName, 13); + ext = _tcschr (szShortName, _T('.')); + if (!ext) + ext = _T(""); + else + *ext++ = _T('\0'); + ConOutPrintf (_T("%-8s %-3s "), szShortName, ext); + } + else + { + LPTSTR ext; + + ext = _tcschr (file.cAlternateFileName, _T('.')); + if (!ext) + ext = _T(""); + else + *ext++ = _T('\0'); + ConOutPrintf (_T("%-8s %-3s "), file.cAlternateFileName, ext); + } + + /* print file size */ + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ConOutPrintf ("%-14s", ""); + dircount++; + } + else + { + ULARGE_INTEGER uliSize; + + uliSize.LowPart = file.nFileSizeLow; + uliSize.HighPart = file.nFileSizeHigh; + ConvertULargeInteger (uliSize, buffer, sizeof(buffer)); + ConOutPrintf (_T(" %10s "), buffer); + bytecount.QuadPart += uliSize.QuadPart; + filecount++; + } + + /* print file date and time */ + if (FileTimeToLocalFileTime (&file.ftLastWriteTime, &ft)) + { + FileTimeToSystemTime (&ft, &dt); + PrintFileDateTime (&dt, dwFlags); + } + + /* print long filename */ + ConOutPrintf (" %s\n", file.cFileName); + } + + if (IncLine (pLine, dwFlags)) + return 1; + } + } + while (FindNextFile (hFile, &file)); + FindClose (hFile); + + /* Rob Lake, need to make clean output */ + /* JPP 07/08/1998 added check for count != 0 */ + if ((dwFlags & DIR_WIDE) && (count != 0)) + { + ConOutPrintf (_T("\n")); + if (IncLine (pLine, dwFlags)) + return 1; + } + + if (filecount || dircount) + { + recurse_dir_cnt += dircount; + recurse_file_cnt += filecount; + recurse_bytes.QuadPart += bytecount.QuadPart; + + /* print_summary */ + if (PrintSummary (szPath, filecount, dircount, bytecount, pLine, dwFlags)) + return 1; + } + else + { + error_file_not_found (); + return 1; + } + + return 0; +} + + +/* + * _Read_Dir: Actual function that does recursive listing + */ +static INT +DirRead (LPTSTR szPath, LPTSTR szFilespec, LPINT pLine, DWORD dwFlags) +{ + TCHAR szFullPath[MAX_PATH]; + WIN32_FIND_DATA file; + HANDLE hFile; + + _tcscpy (szFullPath, szPath); + if (szFullPath[_tcslen (szFullPath) - 1] != _T('\\')) + _tcscat (szFullPath, _T("\\")); + _tcscat (szFullPath, szFilespec); + + hFile = FindFirstFile (szFullPath, &file); + if (hFile == INVALID_HANDLE_VALUE) + return 1; + + do + { + /* don't list "." and ".." */ + if (_tcscmp (file.cFileName, _T(".")) == 0 || + _tcscmp (file.cFileName, _T("..")) == 0) + continue; + + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + _tcscpy (szFullPath, szPath); + if (szFullPath[_tcslen (szFullPath) - 1] != _T('\\')) + _tcscat (szFullPath, _T("\\")); + _tcscat (szFullPath, file.cFileName); + + if (DirList (szFullPath, szFilespec, pLine, dwFlags)) + { + FindClose (hFile); + return 1; + } + + if ((dwFlags & DIR_BARE) == 0) + { + ConOutPrintf ("\n"); + if (IncLine (pLine, dwFlags) != 0) + return 1; + ConOutPrintf ("\n"); + if (IncLine (pLine, dwFlags) != 0) + return 1; + } + + if (DirRead (szFullPath, szFilespec, pLine, dwFlags) == 1) + { + FindClose (hFile); + return 1; + } + } + } + while (FindNextFile (hFile, &file)); + + if (!FindClose (hFile)) + return 1; + + return 0; +} + + +/* + * do_recurse: Sets up for recursive directory listing + */ +static INT +DirRecurse (LPTSTR szPath, LPTSTR szSpec, LPINT pLine, DWORD dwFlags) +{ + if (!PrintDirectoryHeader (szPath, pLine, dwFlags)) + return 1; + + if (DirList (szPath, szSpec, pLine, dwFlags)) + return 1; + + if ((dwFlags & DIR_BARE) == 0) + { + ConOutPrintf (_T("\n")); + if (IncLine (pLine, dwFlags)) + return 1; + } + + if (DirRead (szPath, szSpec, pLine, dwFlags)) + return 1; + + if ((dwFlags & DIR_BARE) == 0) + ConOutPrintf (_T("Total files listed:\n")); + + dwFlags &= ~DIR_RECURSE; + + if (PrintSummary (szPath, recurse_file_cnt, + recurse_dir_cnt, recurse_bytes, pLine, dwFlags)) + return 1; + + if ((dwFlags & DIR_BARE) == 0) + { + ConOutPrintf (_T("\n")); + if (IncLine (pLine, dwFlags)) + return 1; + } + + return 0; +} + + +/* + * dir + * + * internal dir command + */ +INT CommandDir (LPTSTR first, LPTSTR rest) +{ + DWORD dwFlags = DIR_NEW | DIR_FOUR; + TCHAR dircmd[256]; + TCHAR szPath[MAX_PATH]; + TCHAR szFilespec[MAX_PATH]; + LPTSTR param; + INT nLine = 0; + + + recurse_dir_cnt = 0L; + recurse_file_cnt = 0L; + recurse_bytes.QuadPart = 0; + + /* read the parameters from the DIRCMD environment variable */ + if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) + { + if (!DirReadParam (dircmd, ¶m, &dwFlags)) + return 1; + } + + /* read the parameters */ + if (!DirReadParam (rest, ¶m, &dwFlags)) + return 1; + + /* default to current directory */ + if (!param) + param = "."; + + /* parse the directory info */ + if (DirParsePathspec (param, szPath, szFilespec)) + return 1; + + if (dwFlags & DIR_RECURSE) + { + if (IncLine (&nLine, dwFlags)) + return 0; + if (DirRecurse (szPath, szFilespec, &nLine, dwFlags)) + return 1; + return 0; + } + + /* print the header */ + if (!PrintDirectoryHeader (szPath, &nLine, dwFlags)) + return 1; + + if (DirList (szPath, szFilespec, &nLine, dwFlags)) + return 1; + + return 0; +} + +#endif + +/* EOF */ diff --git a/subsys/system/cmd/dirstack.c b/subsys/system/cmd/dirstack.c new file mode 100644 index 0000000..a910d32 --- /dev/null +++ b/subsys/system/cmd/dirstack.c @@ -0,0 +1,237 @@ +/* + * DIRSTACK.C - pushd / pop (directory stack) internal commands. + * + * + * History: + * + * 14-Dec-1998 (Eric Kohl ) + * Implemented PUSHD and POPD command. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * + * 20-Jan-1999 (Eric Kohl ) + * Added DIRS command. + */ + +#include "config.h" + +#ifdef FEATURE_DIRECTORY_STACK + +#include +#include +#include +#include + +#include "cmd.h" + + +typedef struct tagDIRENTRY +{ + struct tagDIRENTRY *prev; + struct tagDIRENTRY *next; + LPTSTR pszPath; +} DIRENTRY, *LPDIRENTRY; + + +static INT nStackDepth; +static LPDIRENTRY lpStackTop; +static LPDIRENTRY lpStackBottom; + + +static INT +PushDirectory (LPTSTR pszPath) +{ + LPDIRENTRY lpDir; + + lpDir = (LPDIRENTRY)malloc (sizeof (DIRENTRY)); + if (!lpDir) + { + error_out_of_memory (); + return -1; + } + + lpDir->prev = NULL; + if (lpStackTop == NULL) + { + lpDir->next = NULL; + lpStackBottom = lpDir; + } + else + { + lpDir->next = lpStackTop; + lpStackTop->prev = lpDir; + } + lpStackTop = lpDir; + + lpDir->pszPath = (LPTSTR)malloc ((_tcslen(pszPath)+1)*sizeof(TCHAR)); + if (!lpDir->pszPath) + { + free (lpDir); + error_out_of_memory (); + return -1; + } + + _tcscpy (lpDir->pszPath, pszPath); + + nStackDepth++; + + return 0; +} + + +static VOID +PopDirectory (VOID) +{ + LPDIRENTRY lpDir; + + if (nStackDepth == 0) + return; + + lpDir = lpStackTop; + lpStackTop = lpDir->next; + if (lpStackTop != NULL) + lpStackTop->prev = NULL; + else + lpStackBottom = NULL; + + free (lpDir->pszPath); + free (lpDir); + + nStackDepth--; +} + + +static VOID +GetDirectoryStackTop (LPTSTR pszPath) +{ + if (lpStackTop) + _tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH); + else + *pszPath = _T('\0'); +} + + +/* + * initialize directory stack + */ +VOID InitDirectoryStack (VOID) +{ + nStackDepth = 0; + lpStackTop = NULL; + lpStackBottom = NULL; +} + + +/* + * destroy directory stack + */ +VOID DestroyDirectoryStack (VOID) +{ + while (nStackDepth) + PopDirectory (); +} + + +INT GetDirectoryStackDepth (VOID) +{ + return nStackDepth; +} + + +/* + * pushd command + */ +INT CommandPushd (LPTSTR first, LPTSTR rest) +{ + TCHAR curPath[MAX_PATH]; + TCHAR newPath[MAX_PATH]; + BOOL bChangePath = FALSE; + + if (!_tcsncmp (rest, _T("/?"), 2)) + { + ConOutPuts (_T("Stores the current directory for use by the POPD command, then\n" + "changes to the specified directory.\n\n" + "PUSHD [path | ..]\n\n" + " path Specifies the directory to make the current directory")); + return 0; + } + + if (rest[0] != _T('\0')) + { + GetFullPathName (rest, MAX_PATH, newPath, NULL); + bChangePath = IsValidPathName (newPath); + } + + GetCurrentDirectory (MAX_PATH, curPath); + if (PushDirectory (curPath)) + return 0; + + if (bChangePath) + SetCurrentDirectory (newPath); + + return 0; +} + + +/* + * popd command + */ +INT CommandPopd (LPTSTR first, LPTSTR rest) +{ + TCHAR szPath[MAX_PATH]; + + if (!_tcsncmp(rest, _T("/?"), 2)) + { + ConOutPuts (_T("Changes to the directory stored by the PUSHD command.\n\n" + "POPD")); + return 0; + } + + if (GetDirectoryStackDepth () == 0) + return 0; + + GetDirectoryStackTop (szPath); + PopDirectory (); + + SetCurrentDirectory (szPath); + + return 0; +} + + +/* + * dirs command + */ +INT CommandDirs (LPTSTR first, LPTSTR rest) +{ + LPDIRENTRY lpDir; + + if (!_tcsncmp(rest, _T("/?"), 2)) + { + ConOutPuts (_T("Prints the contents of the directory stack.\n" + "\n" + "DIRS")); + return 0; + } + + + lpDir = lpStackBottom; + + if (lpDir == NULL) + { + ConOutPuts (_T("Directory stack empty")); + return 0; + } + + while (lpDir != NULL) + { + ConOutPuts (lpDir->pszPath); + + lpDir = lpDir->prev; + } + + return 0; +} + +#endif /* FEATURE_DIRECTORY_STACK */ diff --git a/subsys/system/cmd/echo.c b/subsys/system/cmd/echo.c new file mode 100644 index 0000000..7d55b0b --- /dev/null +++ b/subsys/system/cmd/echo.c @@ -0,0 +1,148 @@ +/* $Id$ + * + * ECHO.C - internal echo commands. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * Started. + * + * 16 Jul 1998 (John P Price) + * Separated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * Added config.h include + * + * 08-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 19-Jan-1999 (Eric Kohl ) + * Unicode and redirection ready! + * + * 13-Jul-2000 (Eric Kohl ) + * Implemented 'echo.' and 'echoerr.'. + */ + +#include "config.h" + +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +INT CommandEcho (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("CommandEcho '%s' : '%s'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts ("Displays a message or switches command echoing on or off.\n" + "\n" + " ECHO [ON | OFF]\n" + " ECHO [message]\n" + " ECHO. prints an empty line\n" + "\n" + "Type ECHO without a parameter to display the current ECHO setting."); + return 0; + } + + if (_tcsicmp (cmd, _T("echo.")) == 0) + { + if (param[0] == 0) + ConOutChar (_T('\n')); + else + ConOutPuts (param); + } + else + { + if (_tcsicmp (param, D_OFF) == 0) + bEcho = FALSE; + else if (_tcsicmp (param, D_ON) == 0) + bEcho = TRUE; + else if (*param) + ConOutPuts (param); + else + ConOutPrintf (_T("ECHO is %s\n"), bEcho ? D_ON : D_OFF); + } + + return 0; +} + +INT CommandEchos (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("CommandEchos '%s' : '%s'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts ("Display a messages without trailing carridge return and line feed.\n" + "\n" + " ECHOS message"); + return 0; + } + + if (*param) + ConOutPrintf ("%s", param); + + return 0; +} + + +INT CommandEchoerr (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("CommandEchoerr '%s' : '%s'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts ("Displays a message to the standard error.\n" + "\n" + " ECHOERR message\n" + " ECHOERR. prints an empty line"); + return 0; + } + + if (_tcsicmp (cmd, _T("echoerr.")) == 0) + { + if (param[0] == 0) + ConErrChar (_T('\n')); + else + ConErrPuts (param); + } + else if (*param) + { + ConErrPuts (param); + } + + return 0; +} + +INT CommandEchoserr (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("CommandEchoserr '%s' : '%s'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts ("Prints a messages to standard error output without trailing carridge return and line feed.\n" + "\n" + " ECHOSERR message"); + return 0; + } + + if (*param) + ConOutPrintf (_T("%s"), param); + + return 0; +} + +/* EOF */ diff --git a/subsys/system/cmd/error.c b/subsys/system/cmd/error.c new file mode 100644 index 0000000..d0bf15b --- /dev/null +++ b/subsys/system/cmd/error.c @@ -0,0 +1,175 @@ +/* + * ERROR.C - error reporting functions. + * + * + * History: + * + * 07/12/98 (Rob Lake) + * started + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 24-Jan-1999 (Eric Kohl ) + * Redirection safe! + * + * 02-Feb-1999 (Eric Kohl ) + * Use FormatMessage() for error reports. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" + + +#define INVALID_SWITCH _T("Invalid switch - /%c\n") +#define TOO_MANY_PARAMETERS _T("Too many parameters - %s\n") +#define PATH_NOT_FOUND _T("Path not found\n") +#define FILE_NOT_FOUND _T("File not found\n") +#define REQ_PARAM_MISSING _T("Required parameter missing\n") +#define INVALID_DRIVE _T("Invalid drive specification\n") +#define INVALID_PARAM_FORMAT _T("Invalid parameter format - %s\n") +#define BADCOMMAND _T("Bad command or filename\n") +#define OUT_OF_MEMORY _T("Out of memory error.\n") +#define CANNOTPIPE _T("Error! Cannot pipe! Cannot open temporary file!\n") + +#define D_PAUSEMSG _T("Press any key to continue . . .") + + + +VOID ErrorMessage (DWORD dwErrorCode, LPTSTR szFormat, ...) +{ + TCHAR szMessage[1024]; + LPTSTR szError; + va_list arg_ptr; + + if (dwErrorCode == ERROR_SUCCESS) + return; + + va_start (arg_ptr, szFormat); + _vstprintf (szMessage, szFormat, arg_ptr); + va_end (arg_ptr); + +#ifndef __REACTOS__ + + if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&szError, 0, NULL)) + { + ConErrPrintf (_T("%s %s\n"), szError, szMessage); + LocalFree (szError); + return; + } + else + { + ConErrPrintf (_T("Unknown error! Error code: 0x%lx\n"), dwErrorCode); + return; + } + +#else + + switch (dwErrorCode) + { + case ERROR_FILE_NOT_FOUND: + szError = _T("File not found --"); + break; + + case ERROR_PATH_NOT_FOUND: + szError = _T("Path not found --"); + break; + + default: + ConErrPrintf (_T("Unknown error! Error code: 0x%lx\n"), dwErrorCode); + return; + } + + ConErrPrintf (_T("%s %s\n"), szError, szMessage); +#endif +} + + + +VOID error_invalid_switch (TCHAR ch) +{ + ConErrPrintf (INVALID_SWITCH, ch); +} + + +VOID error_too_many_parameters (LPTSTR s) +{ + ConErrPrintf (TOO_MANY_PARAMETERS, s); +} + + +VOID error_path_not_found (VOID) +{ + ConErrPrintf (PATH_NOT_FOUND); +} + + +VOID error_file_not_found (VOID) +{ + ConErrPrintf (FILE_NOT_FOUND); +} + + +VOID error_sfile_not_found (LPTSTR f) +{ + ConErrPrintf (FILE_NOT_FOUND _T(" - %s\n"), f); +} + + +VOID error_req_param_missing (VOID) +{ + ConErrPrintf (REQ_PARAM_MISSING); +} + + +VOID error_invalid_drive (VOID) +{ + ConErrPrintf (INVALID_DRIVE); +} + + +VOID error_bad_command (VOID) +{ + ConErrPrintf (BADCOMMAND); +} + + +VOID error_no_pipe (VOID) +{ + ConErrPrintf (CANNOTPIPE); +} + + +VOID error_out_of_memory (VOID) +{ + ConErrPrintf (OUT_OF_MEMORY); +} + + +VOID error_invalid_parameter_format (LPTSTR s) +{ + ConErrPrintf (INVALID_PARAM_FORMAT, s); +} + + +VOID error_syntax (LPTSTR s) +{ + if (s) + ConErrPrintf (_T("Syntax error - %s\n"), s); + else + ConErrPrintf (_T("Syntax error.\n")); +} + + +VOID msg_pause (VOID) +{ + ConOutPuts (D_PAUSEMSG); +} diff --git a/subsys/system/cmd/filecomp.c b/subsys/system/cmd/filecomp.c new file mode 100644 index 0000000..abb4fb8 --- /dev/null +++ b/subsys/system/cmd/filecomp.c @@ -0,0 +1,339 @@ +/* + * FILECOMP.C - handles filename completion. + * + * + * Comments: + * + * 30-Jul-1998 (John P Price ) + * moved from command.c file + * made second TAB display list of filename matches + * made filename be lower case if last character typed is lower case + * + * 25-Jan-1999 (Eric Kohl ) + * Cleanup. Unicode safe! + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "cmd.h" + + +#ifdef FEATURE_UNIX_FILENAME_COMPLETION + +VOID CompleteFilename (LPTSTR str, INT charcount) +{ + WIN32_FIND_DATA file; + HANDLE hFile; + INT curplace = 0; + INT start; + INT count; + BOOL found_dot = FALSE; + BOOL perfectmatch = TRUE; + TCHAR path[MAX_PATH]; + TCHAR fname[MAX_PATH]; + TCHAR maxmatch[MAX_PATH] = _T(""); + TCHAR directory[MAX_PATH]; + LPCOMMAND cmds_ptr; + + /* expand current file name */ + count = charcount - 1; + if (count < 0) + count = 0; + + /* find front of word */ + if (str[count] == _T('"')) + { + count--; + while (count > 0 && str[count] != _T('"')) + count--; + } + else + { + while (count > 0 && str[count] != _T(' ')) + count--; + } + + /* if not at beginning, go forward 1 */ + if (str[count] == _T(' ')) + count++; + + start = count; + + if (str[count] == _T('"')) + count++; /* don't increment start */ + + /* extract directory from word */ + _tcscpy (directory, &str[count]); + curplace = _tcslen (directory) - 1; + + if (curplace >= 0 && directory[curplace] == _T('"')) + directory[curplace--] = _T('\0'); + + _tcscpy (path, directory); + + while (curplace >= 0 && directory[curplace] != _T('\\') && + directory[curplace] != _T(':')) + { + directory[curplace] = 0; + curplace--; + } + + /* look for a '.' in the filename */ + for (count = _tcslen (directory); path[count] != _T('\0'); count++) + { + if (path[count] == _T('.')) + { + found_dot = TRUE; + break; + } + } + + if (found_dot) + _tcscat (path, _T("*")); + else + _tcscat (path, _T("*.*")); + + /* current fname */ + curplace = 0; + + hFile = FindFirstFile (path, &file); + if (hFile != INVALID_HANDLE_VALUE) + { + /* find anything */ + do + { + /* ignore "." and ".." */ + if (!_tcscmp (file.cFileName, _T(".")) || + !_tcscmp (file.cFileName, _T(".."))) + continue; + + _tcscpy (fname, file.cFileName); + + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + _tcscat (fname, _T("\\")); + + if (!maxmatch[0] && perfectmatch) + { + _tcscpy(maxmatch, fname); + } + else + { + for (count = 0; maxmatch[count] && fname[count]; count++) + { + if (tolower(maxmatch[count]) != tolower(fname[count])) + { + perfectmatch = FALSE; + maxmatch[count] = 0; + break; + } + } + + if (maxmatch[count] == _T('\0') && + fname[count] != _T('\0')) + perfectmatch = FALSE; + } + } + while (FindNextFile (hFile, &file)); + + FindClose (hFile); + + /* only quote if the filename contains spaces */ + if (_tcschr(directory, _T(' ')) || + _tcschr(maxmatch, _T(' '))) + { + str[start] = _T('\"'); + _tcscpy (&str[start+1], directory); + _tcscat (&str[start], maxmatch); + _tcscat (&str[start], _T("\"") ); + } + else + { + _tcscpy (&str[start], directory); + _tcscat (&str[start], maxmatch); + } + + /* append a space if last word is not a directory */ + if(perfectmatch) + { + curplace = _tcslen(&str[start]); + if(str[start+curplace-1] == _T('"')) + curplace--; + + if(str[start+curplace-1] != _T('\\')) + _tcscat(&str[start], _T(" ")); + } + else + { +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + } + } + else + { + /* no match found - search for internal command */ + for (cmds_ptr = cmds; cmds_ptr->name; cmds_ptr++) + { + if (!_tcsnicmp (&str[start], cmds_ptr->name, + _tcslen (&str[start]))) + { + /* return the mach only if it is unique */ + if (_tcsnicmp (&str[start], (cmds_ptr+1)->name, _tcslen (&str[start]))) + _tcscpy (&str[start], cmds_ptr->name); + break; + } + } + +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + } +} + + +/* + * returns 1 if at least one match, else returns 0 + */ + +BOOL ShowCompletionMatches (LPTSTR str, INT charcount) +{ + WIN32_FIND_DATA file; + HANDLE hFile; + BOOL found_dot = FALSE; + INT curplace = 0; + INT start; + INT count; + TCHAR path[MAX_PATH]; + TCHAR fname[MAX_PATH]; + TCHAR directory[MAX_PATH]; + + /* expand current file name */ + count = charcount - 1; + if (count < 0) + count = 0; + + /* find front of word */ + if (str[count] == _T('"')) + { + count--; + while (count > 0 && str[count] != _T('"')) + count--; + } + else + { + while (count > 0 && str[count] != _T(' ')) + count--; + } + + /* if not at beginning, go forward 1 */ + if (str[count] == _T(' ')) + count++; + + start = count; + + if (str[count] == _T('"')) + count++; /* don't increment start */ + + /* extract directory from word */ + _tcscpy (directory, &str[count]); + curplace = _tcslen (directory) - 1; + + if (curplace >= 0 && directory[curplace] == _T('"')) + directory[curplace--] = _T('\0'); + + _tcscpy (path, directory); + + while (curplace >= 0 && + directory[curplace] != _T('\\') && + directory[curplace] != _T(':')) + { + directory[curplace] = 0; + curplace--; + } + + /* look for a . in the filename */ + for (count = _tcslen (directory); path[count] != _T('\0'); count++) + { + if (path[count] == _T('.')) + { + found_dot = TRUE; + break; + } + } + + if (found_dot) + _tcscat (path, _T("*")); + else + _tcscat (path, _T("*.*")); + + /* current fname */ + curplace = 0; + + hFile = FindFirstFile (path, &file); + if (hFile != INVALID_HANDLE_VALUE) + { + /* find anything */ + ConOutChar (_T('\n')); + count = 0; + do + { + /* ignore . and .. */ + if (!_tcscmp (file.cFileName, _T(".")) || + !_tcscmp (file.cFileName, _T(".."))) + continue; + + if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + _stprintf (fname, _T("[%s]"), file.cFileName); + else + _tcscpy (fname, file.cFileName); + + ConOutPrintf (_T("%-14s"), fname); + if (++count == 5) + { + ConOutChar (_T('\n')); + count = 0; + } + } + while (FindNextFile (hFile, &file)); + + FindClose (hFile); + + if (count) + ConOutChar (_T('\n')); + } + else + { + /* no match found */ +#ifdef __REACTOS__ + Beep (440, 50); +#else + MessageBeep (-1); +#endif + return FALSE; + } + + return TRUE; +} +#endif + +#ifdef FEATURE_4NT_FILENAME_COMPLETION + +//static VOID BuildFilenameMatchList (...) + +// VOID CompleteFilenameNext (LPTSTR, INT) +// VOID CompleteFilenamePrev (LPTSTR, INT) + +// VOID RemoveFilenameMatchList (VOID) + +#endif diff --git a/subsys/system/cmd/files.txt b/subsys/system/cmd/files.txt new file mode 100644 index 0000000..fd3ef16 --- /dev/null +++ b/subsys/system/cmd/files.txt @@ -0,0 +1,61 @@ +Archive Contents +~~~~~~~~~~~~~~~~ +bugs.txt Bug List +files.txt This file list +history.txt History of the shell development +license.txt GNU license - applies to all files named here +readme.txt General shell info +todo.txt What I have to do +wishlist.txt Wish List + +makefile experimental makefile +makefile.lcc makefile for lcc-win + +alias.c Alias code +alias.h Alias header file +attrib.c Implements attrib command +batch.c Batch file interpreter +beep.c Implements beep command +call.c Implements call command +chcp.c Implements chcp command +choice.c Implements choice command +cls.c Implements cls command +cmdinput.c Command-line input functions +cmdtable.c Table of available internal commands +cmd.c Main code for command-line interpreter +cmd.h Command header file +color.c Implements color command +console.c Windows console handling code +copy.c Implements copy command +date.c Implements date command +del.c Implements del command +dir.c Directory listing code +dirstack.c Directory stack code (PUSHD and POPD) +echo.c Implements echo command +error.c Error Message Routines +filecomp.c Filename completion functions +for.c Implements for command +free.c Implements free command +goto.c Implements goto command +history.c Command-line history handling +if.c Implements if command +internal.c Internal commands (DIR, RD, etc) +label.c Implements label command +locale.c Locale handling code +memory.c Implements memory command +misc.c Misc. Functions +msgbox.c Implements msgbox command +move.c Implements move command +path.c Implements path command +pause.c Implements pause command +prompt.c Prompt handling functions +redir.c Redirection and piping parsing functions +ren.c Implements rename command +set.c Implements set command +shift.c Implements shift command +time.c Implements time command +timer.c Implements timer command +type.c Implements type command +ver.c Implements ver command +where.c Code to search path for executables +verify.c Implements verify command diff --git a/subsys/system/cmd/for.c b/subsys/system/cmd/for.c new file mode 100644 index 0000000..d4625be --- /dev/null +++ b/subsys/system/cmd/for.c @@ -0,0 +1,157 @@ +/* + * FOR.C - for internal batch command. + * + * + * History: + * + * 16-Jul-1998 (Hans B Pufal) + * Started. + * + * 16-Jul-1998 (John P Price) + * Seperated commands into individual files. + * + * 19-Jul-1998 (Hans B Pufal) + * Implementation of FOR. + * + * 27-Jul-1998 (John P Price ) + * Added config.h include. + * + * 20-Jan-1999 (Eric Kohl) + * Unicode and redirection safe! + * + * 01-Sep-1999 (Eric Kohl) + * Added help text. + * + * 23-Feb-2001 (Carl Nettelblad ) + * Implemented preservation of echo flag. Some other for related + * code in other files fixed, too. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* + * Perform FOR command. + * + * First check syntax is correct : FOR %v IN ( ) DO + * v must be alphabetic, must not be empty. + * + * If all is correct build a new bcontext structure which preserves + * the necessary information so that readbatchline can expand + * each the command prototype for each list element. + * + * You might look on a FOR as being a called batch file with one line + * per list element. + */ + +INT cmd_for (LPTSTR cmd, LPTSTR param) +{ + LPBATCH_CONTEXT lpNew; + LPTSTR pp; + TCHAR var; + +#ifdef _DEBUG + DebugPrintf ("cmd_for (\'%s\', \'%s\'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Runs a specified command for each file in a set of files\n" + "\n" + "FOR %variable IN (set) DO command [parameters]\n" + "\n" + " %variable Specifies a replaceable parameter.\n" + " (set) Specifies a set of one or more files. Wildcards may be used.\n" + " command Specifies the command to carry out for each file.\n" + " parameters Specifies parameters or switches for the specified command.\n" + "\n" + "To user the FOR comamnd in a batch program, specify %%variable instead of\n" + "%variable.")); + return 0; + } + + /* Check that first element is % then an alpha char followed by space */ + if ((*param != _T('%')) || !_istalpha (*(param + 1)) || !_istspace (*(param + 2))) + { + error_syntax (_T("bad variable specification.")); + return 1; + } + + param++; + var = *param++; /* Save FOR var name */ + + while (_istspace (*param)) + param++; + + /* Check next element is 'IN' */ + if ((_tcsnicmp (param, _T("in"), 2) != 0) || !_istspace (*(param + 2))) + { + error_syntax (_T("'in' missing in for statement.")); + return 1; + } + + param += 2; + while (_istspace (*param)) + param++; + + /* Folowed by a '(', find also matching ')' */ + if ((*param != _T('(')) || (NULL == (pp = _tcsrchr (param, _T(')'))))) + { + error_syntax (_T("no brackets found.")); + return 1; + } + + *pp++ = _T('\0'); + param++; /* param now points at null terminated list */ + + while (_istspace (*pp)) + pp++; + + /* Check DO follows */ + if ((_tcsnicmp (pp, _T("do"), 2) != 0) || !_istspace (*(pp + 2))) + { + error_syntax (_T("'do' missing.")); + return 1; + } + + pp += 2; + while (_istspace (*pp)) + pp++; + + /* Check that command tail is not empty */ + if (*pp == _T('\0')) + { + error_syntax (_T("no command after 'do'.")); + return 1; + } + + /* OK all is correct, build a bcontext.... */ + lpNew = (LPBATCH_CONTEXT)malloc (sizeof (BATCH_CONTEXT)); + + lpNew->prev = bc; + bc = lpNew; + + bc->hBatchFile = INVALID_HANDLE_VALUE; + bc->ffind = NULL; + bc->params = BatchParams (_T(""), param); /* Split out list */ + bc->shiftlevel = 0; + bc->forvar = var; + bc->forproto = _tcsdup (pp); + if (bc->prev) + bc->bEcho = bc->prev->bEcho; + else + bc->bEcho = bEcho; + + return 0; +} + +/* EOF */ diff --git a/subsys/system/cmd/free.c b/subsys/system/cmd/free.c new file mode 100644 index 0000000..934e776 --- /dev/null +++ b/subsys/system/cmd/free.c @@ -0,0 +1,165 @@ +/* + * FREE.C - internal command. + * + * + * History: + * + * 01-Sep-1999 (Eric Kohl) + * Started. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_FREE + +#include +#include +#include +#include +#include + +#include "cmd.h" + + +/* + * convert + * + * insert commas into a number + */ + +static INT +ConvertULargeInteger (ULARGE_INTEGER num, LPTSTR des, INT len) +{ + TCHAR temp[32]; + INT c = 0; + INT n = 0; + + if (num.QuadPart == 0) + { + des[0] = _T('0'); + des[1] = _T('\0'); + n = 1; + } + else + { + temp[31] = 0; + while (num.QuadPart > 0) + { + if (((c + 1) % (nNumberGroups + 1)) == 0) + temp[30 - c++] = cThousandSeparator; + temp[30 - c++] = (TCHAR)(num.QuadPart % 10) + _T('0'); + num.QuadPart /= 10; + } + + for (n = 0; n <= c; n++) + des[n] = temp[31 - c + n]; + } + + return n; +} + + +static VOID +PrintDiskInfo (LPTSTR szDisk) +{ + TCHAR szRootPath[4] = "A:\\"; + TCHAR szDrive[2] = "A"; + TCHAR szVolume[64]; + TCHAR szSerial[10]; + TCHAR szTotal[40]; + TCHAR szUsed[40]; + TCHAR szFree[40]; + DWORD dwSerial; + ULARGE_INTEGER uliSize; + DWORD dwSecPerCl; + DWORD dwBytPerSec; + DWORD dwFreeCl; + DWORD dwTotCl; + + if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':')) + { + ConErrPrintf (_T("Invalid drive %s\n"), szDisk); + return; + } + + szRootPath[0] = szDisk[0]; + szDrive[0] = _totupper (szRootPath[0]); + + if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial, + NULL, NULL, NULL, 0)) + { + ConErrPrintf (_T("Invalid drive %s:\n"), szDrive); + return; + } + + if (szVolume[0] == _T('\0')) + _tcscpy (szVolume, _T("unlabeled")); + + _stprintf (szSerial, + _T("%04X-%04X"), + HIWORD(dwSerial), + LOWORD(dwSerial)); + + if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl, + &dwBytPerSec, &dwFreeCl, &dwTotCl)) + { + ConErrPrintf (_T("Invalid drive %s:\n"), szDrive); + return; + } + + uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwTotCl; + ConvertULargeInteger (uliSize, szTotal, 40); + + uliSize.QuadPart = dwSecPerCl * dwBytPerSec * (dwTotCl - dwFreeCl); + ConvertULargeInteger (uliSize, szUsed, 40); + + uliSize.QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl; + ConvertULargeInteger (uliSize, szFree, 40); + + ConOutPrintf (_T("\n" + " Volume in drive %s is %-11s Serial number is %s\n" + " %16s bytes total disk space\n" + " %16s bytes used\n" + " %16s bytes free\n"), + szDrive, szVolume, szSerial, + szTotal, szUsed, szFree); +} + + +INT CommandFree (LPTSTR cmd, LPTSTR param) +{ + LPTSTR szParam; + TCHAR szDefPath[MAX_PATH]; + INT argc, i; + LPTSTR *arg; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays drive information.\n" + "\n" + "FREE [drive: ...]")); + return 0; + } + + if (!param || *param == _T('\0')) + { + GetCurrentDirectory (MAX_PATH, szDefPath); + szDefPath[2] = _T('\0'); + szParam = szDefPath; + } + else + szParam = param; + + arg = split (szParam, &argc, FALSE); + + for (i = 0; i < argc; i++) + PrintDiskInfo (arg[i]); + + freep (arg); + + return 0; +} + +#endif /* INCLUDE_CMD_FREE */ + +/* EOF */ diff --git a/subsys/system/cmd/goto.c b/subsys/system/cmd/goto.c new file mode 100644 index 0000000..c80a9e4 --- /dev/null +++ b/subsys/system/cmd/goto.c @@ -0,0 +1,109 @@ +/* + * GOTO.C - goto internal batch command. + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Seperated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 28 Jul 1998 (Hans B Pufal) [HBP_003] + * Terminate label on first space character, use only first 8 chars of + * label string + * + * 24-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * + * 27-Jan-1999 (Eric Kohl ) + * Added help text ("/?"). + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* + * Perform GOTO command. + * + * Only valid if batch file current. + * + */ + +INT cmd_goto (LPTSTR cmd, LPTSTR param) +{ + LPTSTR tmp; + LONG lNewPosHigh; + +#ifdef _DEBUG + DebugPrintf ("cmd_goto (\'%s\', \'%s\'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Directs CMD to a labeled line in a batch script.\n" + "\n" + "GOTO label\n" + "\n" + " label Specifies a text string used in a batch script as a label.\n" + "\n" + "You type a label on a line by itself, beginning with a colon.")); + return 0; + } + + /* if not in batch -- error!! */ + if (bc == NULL) + { + return 1; + } + + if (*param == _T('\0')) + { + ExitBatch (_T("No label specified for GOTO\n")); + return 1; + } + + /* terminate label at first space char */ + tmp = param; + while (*tmp && !_istspace (*tmp)) + tmp++; + *tmp = _T('\0'); + + /* set file pointer to the beginning of the batch file */ + lNewPosHigh = 0; + SetFilePointer (bc->hBatchFile, 0, &lNewPosHigh, FILE_BEGIN); + + while (FileGetString (bc->hBatchFile, textline, sizeof(textline))) + { + /* Strip out any trailing spaces or control chars */ + tmp = textline + _tcslen (textline) - 1; + while (_istcntrl (*tmp) || _istspace (*tmp)) + tmp--; + *(tmp + 1) = _T('\0'); + + /* Then leading spaces... */ + tmp = textline; + while (_istspace (*tmp)) + tmp++; + + /* use only 1st 8 chars of label */ + if ((*tmp == _T(':')) && (_tcsncmp (++tmp, param, 8) == 0)) + return 0; + } + + ConErrPrintf (_T("Label '%s' not found\n"), param); + ExitBatch (NULL); + + return 1; +} diff --git a/subsys/system/cmd/history.c b/subsys/system/cmd/history.c new file mode 100644 index 0000000..948ca9d --- /dev/null +++ b/subsys/system/cmd/history.c @@ -0,0 +1,526 @@ +/* + * HISTORY.C - command line history. + * + * + * History: + * + * 14/01/95 (Tim Norman) + * started. + * + * 08/08/95 (Matt Rains) + * i have cleaned up the source code. changes now bring this source + * into guidelines for recommended programming practice. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 25-Jan-1999 (Eric Kohl ) + * Cleanup! + * Unicode and redirection safe! + * + * 25-Jan-1999 (Paolo Pantaleo ) + * Added lots of comments (beginning studying the source) + * Added command.com's F3 support (see cmdinput.c) + * + */ + + + +/* + * HISTORY.C - command line history. Second version + * + * + * History: + * + * 06/12/99 (Paolo Pantaleo ) + * started. + * + */ + + + + + + +#include "config.h" + + +#ifdef FEATURE_HISTORY + +#include +#include +#include +#include +#include + +#include "cmd.h" + + +typedef struct tagHISTORY +{ + struct tagHISTORY *prev; + struct tagHISTORY *next; + LPTSTR string; +} HIST_ENTRY, * LPHIST_ENTRY; + +static INT size, + max_size=100; + + + +static LPHIST_ENTRY Top; +static LPHIST_ENTRY Bottom; + + +static LPHIST_ENTRY curr_ptr=0; + + +VOID InitHistory(VOID); +VOID History_move_to_bottom(VOID); +VOID History (INT dir, LPTSTR commandline); +VOID CleanHistory(VOID); +VOID History_del_current_entry(LPTSTR str); + +/*service functions*/ +static VOID del(LPHIST_ENTRY item); +static VOID add_at_bottom(LPTSTR string); +/*VOID add_before_last(LPTSTR string);*/ +VOID set_size(INT new_size); + + + +INT CommandHistory (LPTSTR cmd, LPTSTR param) +{ + LPTSTR tmp; + INT tmp_int; + LPHIST_ENTRY h_tmp; + TCHAR szBuffer[2048]; + + tmp=_tcschr(param,_T('/')); + + if (tmp) + { + param=tmp; + switch (_totupper(param[1])) + { + case _T('F'):/*delete history*/ + CleanHistory();InitHistory(); + break; + + case _T('R'):/*read history from standard in*/ + //hIn=GetStdHandle (STD_INPUT_HANDLE); + + for(;;) + { + ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR)); + if (*szBuffer!=_T('\0')) + History(0,szBuffer); + else + break; + } + break; + + case _T('A'):/*add an antry*/ + History(0,param+2); + break; + + case _T('S'):/*set history size*/ + if ((tmp_int=_ttoi(param+2))) + set_size(tmp_int); + break; + + default: + return 1; + } + } + else + { + for(h_tmp=Top->prev;h_tmp!=Bottom;h_tmp=h_tmp->prev) + ConErrPuts(h_tmp->string); + } + return 0; +} + +VOID set_size(INT new_size) +{ + + while(new_sizeprev); + + + max_size=new_size; +} + + +VOID InitHistory(VOID) +{ + size=0; + + + Top = malloc(sizeof(HIST_ENTRY)); + Bottom = malloc(sizeof(HIST_ENTRY)); + + + Top->prev = Bottom; + Top->next = NULL; + Top->string = NULL; + + + Bottom->prev = NULL; + Bottom->next = Top; + Bottom->string = NULL; + + curr_ptr=Bottom; +} + + + + +VOID CleanHistory(VOID) +{ + + while (Bottom->next!=Top) + del(Bottom->next); + + free(Top); + free(Bottom); + +} + + +VOID History_del_current_entry(LPTSTR str) +{ + LPHIST_ENTRY tmp; + + if (size==0) + return; + + if(curr_ptr==Bottom) + curr_ptr=Bottom->next; + + if(curr_ptr==Top) + curr_ptr=Top->prev; + + + tmp=curr_ptr; + curr_ptr=curr_ptr->prev; + del(tmp); + History(-1,str); + +} + + +static +VOID del(LPHIST_ENTRY item) +{ + + if( item==NULL || item==Top || item==Bottom ) + { +#ifdef _DEBUG + DebugPrintf("del in " __FILE__ ": retrning\n" + "item is 0x%08x (Bottom is0x%08x)\n", + item, Bottom); + +#endif + return; + } + + + + /*free string's mem*/ + if (item->string) + free(item->string); + + + + + + /*set links in prev and next item*/ + item->next->prev=item->prev; + item->prev->next=item->next; + + free(item); + + size--; + +} + +#if 0 +static +VOID add_before_last(LPTSTR string) +{ + + LPHIST_ENTRY tmp,before,after; + + + /*delete first entry if maximum number of entries is reached*/ + while(size>=max_size) + del(Top->prev); + + while (_istspace(*string)) + string++; + + if (*string==_T('\0')) + return; + + + + /*allocte entry and string*/ + tmp=malloc(sizeof(HIST_ENTRY)); + tmp->string=malloc(_tcslen(string)+1); + _tcscpy(tmp->string,string); + + + /*set links*/ + before=Bottom->next; + after=before->next; + + tmp->prev=before; + tmp->next=after; + + after->prev=tmp; + before->next=tmp; + + + + + + + + /*set new size*/ + size++; + + +} +#endif/*0*/ + +static +VOID add_at_bottom(LPTSTR string) +{ + + + LPHIST_ENTRY tmp; + + + /*delete first entry if maximum number of entries is reached*/ + while(size>=max_size) + del(Top->prev); + + while (_istspace(*string)) + string++; + + if (*string==_T('\0')) + return; + + + /*if new entry is the same than the last do not add it*/ + if(size) + if(_tcscmp(string,Bottom->next->string)==0) + return; + + + /*fill bottom with string, it will become Bottom->next*/ + Bottom->string=malloc(_tcslen(string)+1); + _tcscpy(Bottom->string,string); + + /*save Bottom value*/ + tmp=Bottom; + + + /*create new void Bottom*/ + Bottom=malloc(sizeof(HIST_ENTRY)); + Bottom->next=tmp; + Bottom->prev=NULL; + Bottom->string=NULL; + + tmp->prev=Bottom; + + /*set new size*/ + size++; + +} + + + +VOID History_move_to_bottom(VOID) +{ + curr_ptr=Bottom; + +} + + +VOID History (INT dir, LPTSTR commandline) +{ + + if(dir==0) + { + add_at_bottom(commandline); + curr_ptr=Bottom; + return; + } + + if (size==0) + { + commandline[0]=_T('\0'); + return; + } + + + if(dir<0)/*key up*/ + { + if (curr_ptr->next==Top || curr_ptr==Top) + { +#ifdef WRAP_HISTORY + curr_ptr=Bottom; +#else + curr_ptr=Top; + commandline[0]=_T('\0'); + return; +#endif + } + + + curr_ptr = curr_ptr->next; + if(curr_ptr->string) + _tcscpy(commandline,curr_ptr->string); + + } + + + + + + if(dir>0) + { + + if (curr_ptr->prev==Bottom || curr_ptr==Bottom) + { +#ifdef WRAP_HISTORY + curr_ptr=Top; +#else + curr_ptr=Bottom; + commandline[0]=_T('\0'); + return; +#endif + } + + curr_ptr=curr_ptr->prev; + if(curr_ptr->string) + _tcscpy(commandline,curr_ptr->string); + + } +} + + + + + + +#if 0 + +LPTSTR history = NULL; /*buffer to sotre all the lines*/ +LPTSTR lines[MAXLINES]; /*array of pointers to each line(entry)*/ + /*located in history buffer*/ + +INT curline = 0; /*the last line recalled by user*/ +INT numlines = 0; /*number of entries, included the last*/ + /*empty one*/ + +INT maxpos = 0; /*index of last byte of last entry*/ + + + +VOID History (INT dir, LPTSTR commandline) +{ + + INT count; /*used in for loops*/ + INT length; /*used in the same loops of count*/ + /*both to make room when is full + either history or lines*/ + + /*first time History is called allocate mem*/ + if (!history) + { + history = malloc (history_size * sizeof (TCHAR)); + lines[0] = history; + history[0] = 0; + } + + if (dir > 0) + { + /* next command */ + if (curline < numlines) + { + curline++; + } + + if (curline == numlines) + { + commandline[0] = 0; + } + else + { + _tcscpy (commandline, lines[curline]); + } + } + else if (dir < 0) + { + /* prev command */ + if (curline > 0) + { + curline--; + } + + _tcscpy (commandline, lines[curline]); + } + else + { + /* add to history */ + /* remove oldest string until there's enough room for next one */ + /* strlen (commandline) must be less than history_size! */ + while ((maxpos + (INT)_tcslen (commandline) + 1 > history_size) || (numlines >= MAXLINES)) + { + length = _tcslen (lines[0]) + 1; + + for (count = 0; count < maxpos && count + (lines[1] - lines[0]) < history_size; count++) + { + history[count] = history[count + length]; + } + + maxpos -= length; + + for (count = 0; count <= numlines && count < MAXLINES; count++) + { + lines[count] = lines[count + 1] - length; + } + + numlines--; +#ifdef DEBUG + ConOutPrintf (_T("Reduced size: %ld lines\n"), numlines); + + for (count = 0; count < numlines; count++) + { + ConOutPrintf (_T("%d: %s\n"), count, lines[count]); + } +#endif + } + + /*copy entry in the history bufer*/ + _tcscpy (lines[numlines], commandline); + numlines++; + + /*set last lines[numlines] pointer next the end of last, valid, + just setted entry (the two lines above)*/ + lines[numlines] = lines[numlines - 1] + _tcslen (commandline) + 1; + maxpos += _tcslen (commandline) + 1; + /* last line, empty */ + + curline = numlines; + } + + return; +} + +#endif + +#endif //#if 0 diff --git a/subsys/system/cmd/history.txt b/subsys/system/cmd/history.txt new file mode 100644 index 0000000..a0cac6f --- /dev/null +++ b/subsys/system/cmd/history.txt @@ -0,0 +1,367 @@ +FreeDOS Command Line Interface Development History +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +11/11/94 version 0.01 +~~~~~~~~~~~~~~~~~~~~~ +o initial release. + +01/01/95 version 0.10 +~~~~~~~~~~~~~~~~~~~~~ +o removed some scaffolding. +o modified CD. +o added tab file completion. +o added command line history. + +01/15/95 version 0.20 +~~~~~~~~~~~~~~~~~~~~~ +o formatted all existing source modules. +o added prompt support. +o added drive selection. +o added dir command. +o started this development log. + +08/06/95 prerelease of version 0.30 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o reorganized code into separate source modules. +o added batch processing support (thanks to Evan Jeffrey). +o added exec code (thanks to Steffan Kaiser). +o removed environment handling (thanks again to Steffan Kaiser) + + [ 08/08/95 -- Matt Rains ] +o formatted this development log. +o formatted all existing source modules so that they comply with recommended + programming practice. +o added MD command. +o added RD command. +o added VER command. +o replaced CD command. +o modified DIR command. +o DIR now called regardless of other DIR.??? files. this is done because of + exec() problems. + +12/10/95 version 0.30 +~~~~~~~~~~~~~~~~~~~~~ +o used Borland's spawnve to fix exec problem +o fixed CD again so you don't need a space after it +o couple of spelling fixes + +12/14/95 version 0.31 +~~~~~~~~~~~~~~~~~~~~~ +o modified cmdinput.c to work with non-standard screen sizes (see 28.com) +o fixed a bug in history.c that made it not work when you hit the up arrow + on the first line +o fixed DIR to work a little more like MS-DOS's DIR (see internal.c) +o fixed some code in where.c to make things a bit more efficient and nicer + +01/06/96 version 0.40 (never released) +~~~~~~~~~~~~~~~~~~~~~ +o added redirection and piping support!!! (see redir.c and command.c) +o fixed a stupid pointer problem in where.c that was causing LOTS of + problems in the strangest places... +o added day of the week support to prompt.c (oops, that was already supposed + to be there! :) +o fixed and reorganized the EXEC code!!! Thanks to Svante Frey! +o reorganized command.c and internal.c to handle parsing internal commands + more efficiently and consistently. +o changed the behavior of MD, CD, RD to work without spaces (e.g. CD\DOS) +o small changes here and there to make it work with redirection/piping + (e.g. DIR only pauses if you're not doing redirection) + +01/17/96 version 0.50 +~~~~~~~~~~~~~~~~~~~~~ +Version 0.40 was never released because I was home on Christmas vacation, +and I couldn't upload it. By the time I got back to school, I had the +LOADHIGH patch from Svante Frey, so I decided to jump up to 0.50 without any +release of 0.40... - Tim Norman + +o LOADHIGH/LOADFIX/LH support added!!!! Many thanks go to Svante Frey! +o bug fixed in command parsing that didn't handle / switches correctly... +o removed debugging output from history.c + +07/26/96 version 0.60 +~~~~~~~~~~~~~~~~~~~~~ +Lots of internal changes here... Not much added to the interface. + +o Changed internals to use first,rest parameters instead of arrays of params +o Fixed some bugs +o Some other things I don't remember :) + +07/26/96 version 0.61 +~~~~~~~~~~~~~~~~~~~~~ +Bugfixes + +o Added hook to the PATH command +o Fixed CD.. bug + +08/27/96 version 0.70 +~~~~~~~~~~~~~~~~~~~~~ +Finally added Oliver Mueller's ALIAS command! Also numerous bug fixes. + +o Added ALIAS command +o Removed support for - as a switch in LOADHIGH.C +o Bugfixes in BATCH.C. %0 was returning garbage +o Removed lots of unused variables, reducing # of warnings when compiling +o Other miscellaneous code clean-ups +o Changed WHERE.C to use a little less memory + +06/14/97 version 0.71 +~~~~~~~~~~~~~~~~~~~~~ +Lots of bug fixes, plus some additional features. + +o New DIR command. Now more like MS-DOS's DIR. /p supported, /s coming soon +o bug fix in internal.c - parse_firstarg +o Rewrote parser in batch.c (Steffan Kaiser) +o Ctrl-Break checking in various places (Steffan Kaiser) +o Error level setting/checking (%? in batch files) (Steffan Kaiser) +o bug fix in cmdinput.c ("%i" on command-line caused weird behavior) +o bug fix in where.c (first item in path wasn't searched) + +07/12/97 version 0.72 +~~~~~~~~~~~~~~~~~~~~~ +More bug fixes and code cleanup + +o Rewrote cmdinput.c to be more efficient (Marc Desrochers) +o Added insert/overstrike modes (Marc Desrochers) +o Replaced findxy() with pointers into BIOS (maxx, maxy) (Marc Desrochers) +o Fixed bug that disallowed listing of root directories +o Fixed bug that didn't search the first path (again!) + +07/13/97 version 0.72b +~~~~~~~~~~~~~~~~~~~~~~ +Disabled a feature that caused a crash on some machines. + +o Replaced setcursor calls in cmdinput.c with _setcursortype +o Added dir.c to the distribution (was left out in 0.72) + +07/01/98 version 0.73 (Rob Lake) +~~~~~~~~~~~~~~~~~~~~~~ +o New DIR commands supported: /S, /B, /L, /A and /W. + (/R changed to /S). Also /? added. +o Supports DIRCMD in environment. +o Supports turning off commands with hyphen (ex. /-S + turns off recursive listing) +o Changed error messages for DIR and DEL to more MS-DOS'ish +o Moved error messages from DIR.C and DEL.C to COMMAND.H + (more may go there soon) +o Fixed bug that caused dir *.ext/X not to work (no spaces + between filespec and slash) +o Added wildcard support for DEL command +o Added prompt and help switch for DEL command, /P and /? + respectively. +o Added support for /C when envoking the shell +o Added /P support when Kernel loads shell. This means + the shell now is permanent and runs the autoexec.bat + (/E is not implemented) +o Added my name (Rob Lake) to the developer listing +o Changed version routine to print out copyright notice + with no args, and with appropriate switches, warranty + and redistribution notices and developer listing + +07/08/1998 version 0.74 (John P. Price (linux-guru@gcfl.net)) +~~~~~~~~~~~~~~~~~~~~~~~~ +COMMAND.C/COMMAND.H: +o Now sets COMSPEC environment variable +o misc clean up and optimization +o added date, time and type commands +o changed to using spawnl instead of exec. exec does not copy the + environment to the child process! +DIR.C +o removed extra returns; closer to MSDOS +o fixed wide display so that an extra return is not displayed when + there is five filenames in the last line. +ENVIRON.C +o commented out show_environment function. Not used anymore. +INTERAL.C +o removed call to show_environment in set command. +o moved test for syntax before allocating memory in set command. +o misc clean up and optimization. + +o created DATE.C +o created TIME.C +o created TYPE.C + +07/08/1998 version 0.74b (John P. Price (linux-guru@gcfl.net)) +~~~~~~~~~~~~~~~~~~~~~~~~ +COMMAND.C +o fixed call to spawnl so that it would pass command line arguments + correctly. + +07/12/98 version 0.74c (Rob Lake rlake@cs.mun.ca) +~~~~~~~~~~~~~~~~~~~~~~ +Various Files: +o removed redundant use of error message defines and moved + error printing calls to ERROR.C to reduced program size. + +o created MISC.C +o created ERR_HAND.C/H +o created ERROR.C + +07/13/98 version 0.74d (Rob Lake rlake@cs.mun.ca) +~~~~~~~~~~~~~~~~~~~~~~ +INTERNAL.C +o removed most of the commands and placed them in there own file + -- del, ren, set and ver +o created DEL.C, REN.C SET.C and VER.C +o fixed bug that caused del not to delete files with no attributes +o the critical error handler count number of times called, autofails + at 5 calls + + +16 Jul 1998 (Hans B Pufal ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +batch.c + A new version, implements CALL, ECHO, GOT, IF, PAUSE, SHIFT and + BEEP. There is a stub for FOR but that's all. + +cmdtable.c + New file to keep the internal command table. I plan on getting rid + of the table real soon now and replacing it with a dynamic + mechanism. + +command.c + A new (improved ;) version. Conforms closely to MS-DOS specs. + Cleaned up (and fixed) the redirection handler. + +command.h + Version D with changes. Look for the HBP tag. + +redir.c + Modified file, now supports append redirects. + + +16 Jul 1998 (Rob Lake rlake@cs.mun.ca) +~~~~~~~~~~~~~~~~~~~~~~ +Added TRUENAME command. + + +19 Jul 1998 (Hans B Pufal) ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Preserve state of echo flag across batch calls. +o Implementation of FOR command + + +20 Jul 1998 (John P Price ) +~~~~~~~~~~~~~~~~~~~~~~ +o Fixed bug in DATE.C. +o Fixed bug in LH.ASM. +o Separated commands into individual files. + + +28 Jul 1998 (John P Price ) +~~~~~~~~~~~~~~~~~~~~~~ +o Added CLS command. +o Put ifdef's around all commands and added include file config.h + Now you can define exact what commands you want to include in + command.com. +o Also added ifdefs for optional features: aliases, command history + and filename completion. +o Added display of available internal commands and options at startup. + + +29 Jul 1998 (Rob Lake rlake@cs.mun.ca) +~~~~~~~~~~~~~~~~~~~~~~ +o changed date.c and time.c, and wrote datefunc.c and timefunc.c to + impliment _dos_getdate, _dos_setdate, _dos_gettime and _dos_settime. + This is the first of many steps to make the shell compatible under + Pacific C. + +30-Jul-1998 (John P Price ) +~~~~~~~~~~~~~~~~~~~~~~ +o Changed filename completion so that a second TAB displays a list of + matching filenames! +o made filename be lower case if last character typed is lower case. +o Moved filename completion code to filecomp.c. +o Change ver command to display email address to report bugs, and the + web page address for updates. +o fixed so that it find_which returns NULL if filename is not + executable (does not have .bat, .com, or .exe extension). Before + command would to execute any file with any extension. (opps!) + +30-Jul-1998 (John P Price ) +~~~~~~~~~~~~~~~~~~~~~~ +o Fixed bug where if you typed something, then hit HOME, then tried to + type something else in insert mode, it locked up. +o Changed default insert mode to on. There should be a way to change + this. Maybe options to doskey command. +o Added VERIFY command + +02-Aug-1998 (Hans B Pufal) ) +~~~~~~~~~~~~~~~~~~~~~~ +o batch.c: Fixed bug in ECHO flag restoration at exit from batch file +o command.c: Fixed return value when called with /C option +o Terminate label on first space character, use only first 8 chars of + label string + +04-Aug-1998 (Hans B Pufal) ) +~~~~~~~~~~~~~~~~~~~~~~ +o call.c: added lines to initialize for pointers. This fixed the + lock-up that happened sometimes when calling a batch file from + another batch file. + +07-Aug-1998 (John P Price ) +~~~~~~~~~~~~~~~~~~~~~~ +o Fixed carrage return output to better match MSDOS with echo on or off. + + +07-Dec-1998 ReactOS CMD version 0.0.1 (Eric Kohl ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o First test release. +o Added internal ATTRIB command. + +11-Dec-1998 ReactOS CMD version 0.0.2 (Eric Kohl ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Fixed bug in ALIAS. CMD crashed when you tried to remove an alias. +o Fixed bug in split(). Added freep(). This fixed the DEL command. +o Improved ATTRIB command. +o Added most help texts. +o Fixed recursive DIR ("dir /s"). +o Fixed DATE and TIME command. Now they accept values when used + without parameter. +o Implemented LABEL command. + +05-Jan-1999 ReactOS CMD version 0.0.3 (Eric Kohl ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Added COLOR command and "/t" option. +o Cursor shows insert/overwrite mode. +o COMSPEC environment variable is set upon startup. +o Started COPY command. +o Started MOVE command. +o Added directory stack (PUSHD and POPD commands). +o Added support for file names or paths that contain spaces + (quoted paths / file names). +o Added recursion to ATTRIB command. +o Added locale support for DIR, DATE, TIME and PROMPT. +o Fixed VERIFY. + +10-Feb-1999 ReactOS CMD version 0.0.4 (Eric Kohl ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o "?" lists all available commands. +o Most commands are unicode and redirection aware now. +o Input-, Output- and Error-Redirections works with most commands. +o ATTRIB and DEL can handle multiple filenames now. +o Fixed handling of environment variables. +o Added CHCP command. +o Fixed keyboard input bug. +o Rewrote DEL and MOVE commands. + +28-Dec-1999 ReactOS CMD version 0.1 (Eric Kohl ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Cleaned up DIR command. +o Searching for executables in the right order. +o Fixed some little but nasty bugs. +o Added TITLE command. Thanks to Emanuele Aliberti! +o Added "/Q", "/W" and "/Z" options to DEL command. +o Added CHOICE, TIMER, FREE and MEMORY commands. +o Added MSGBOX command (not available under ReactOS). +o Added and fixed missing help texts. +o Fixed bugs in MD and RD that crashed cmd when no directory was specified. +o Improved history support. +o Improved COLOR command. + +09-Apr-2000 ReactOS CMD version 0.1 (EricKohl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Fixed bug in COPY command. CMD crashed if source file didn't exist. + +13-Jul-2000 ReactOS CMD version 0.1.1 (EricKohl +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +o Implemented 'ECHO.' and 'ECHOERR.' commands. diff --git a/subsys/system/cmd/if.c b/subsys/system/cmd/if.c new file mode 100644 index 0000000..298dcd3 --- /dev/null +++ b/subsys/system/cmd/if.c @@ -0,0 +1,212 @@ +/* + * IF.C - if internal batch command. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Seperated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 07-Jan-1999 (Eric Kohl ) + * Added help text ("if /?") and cleaned up. + * + * 21-Jan-1999 (Eric Kohl ) + * Unicode and redirection ready! + * + * 01-Sep-1999 (Eric Kohl ) + * Fixed help text. + * + * 17-Feb-2001 (ea) + * IF DEFINED variable command + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +#define X_EXEC 1 +#define X_EMPTY 0x80 + +INT cmd_if (LPTSTR cmd, LPTSTR param) +{ + INT x_flag = 0; /* when set cause 'then' clause to be executed */ + LPTSTR pp; + +#ifdef _DEBUG + DebugPrintf ("cmd_if: (\'%s\', \'%s\'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Performs conditional processing in batch programs.\n" + "\n" + " IF [NOT] ERRORLEVEL number command\n" + " IF [NOT] string1==string2 command\n" + " IF [NOT] EXIST filename command\n" + " IF [NOT] DEFINED variable command\n" + "\n" + "NOT Specifies that CMD should carry out the command only if\n" + " the condition is false\n" + "ERRORLEVEL number Specifies a true condition if the last program run returned\n" + " an exit code equal or greater than the number specified.\n" + "command Specifies the command to carry out if the condition is met.\n" + "string1==string2 Specifies a true condition if the specified text strings\n" + " match.\n" + "EXIST filename Specifies a true condition if the specified filename exists.\n" + "DEFINED variable Specifies a true condition if the specified variable is\n" + " defined.")); + return 0; + } + + /* First check if param string begins with word 'not' */ + if (!_tcsnicmp (param, _T("not"), 3) && _istspace (*(param + 3))) + { + x_flag = X_EXEC; /* Remember 'NOT' */ + param += 3; /* Step over 'NOT' */ + while (_istspace (*param)) /* And subsequent spaces */ + param++; + } + + /* Check for 'exist' form */ + if (!_tcsnicmp (param, _T("exist"), 5) && _istspace (*(param + 5))) + { + param += 5; + while (_istspace (*param)) + param++; + + pp = param; + while (*pp && !_istspace (*pp)) + pp++; + + if (*pp) + { + WIN32_FIND_DATA f; + HANDLE hFind; + + *pp++ = _T('\0'); + hFind = FindFirstFile (param, &f); + x_flag ^= (hFind == INVALID_HANDLE_VALUE) ? 0 : X_EXEC; + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose (hFind); + } + } + else + return 0; + } + + /* Check for 'defined' form */ + else if (!_tcsnicmp (param, _T("defined"), 7) && _istspace (*(param + 7))) + { + TCHAR Value [1]; + INT ValueSize = 0; + + param += 7; + /* IF [NOT] DEFINED var COMMAND */ + /* ^ */ + while (_istspace (*param)) + param++; + /* IF [NOT] DEFINED var COMMAND */ + /* ^ */ + pp = param; + while (*pp && !_istspace (*pp)) + pp++; + /* IF [NOT] DEFINED var COMMAND */ + /* ^ */ + if (*pp) + { + *pp++ = _T('\0'); + ValueSize = GetEnvironmentVariable(param, Value, sizeof Value); + x_flag ^= (0 == ValueSize) + ? 0 + : X_EXEC; + x_flag |= X_EMPTY; + } + else + return 0; + } + + /* Check for 'errorlevel' form */ + else if (!_tcsnicmp (param, _T("errorlevel"), 10) && _istspace (*(param + 10))) + { + INT n = 0; + + pp = param + 10; + while (_istspace (*pp)) + pp++; + + while (_istdigit (*pp)) + n = n * 10 + (*pp++ - _T('0')); + + x_flag ^= (nErrorLevel < n) ? 0 : X_EXEC; + + x_flag |= X_EMPTY; /* Syntax error if comd empty */ + } + + /* Check that '==' is present, syntax error if not */ + else if (NULL == (pp = _tcsstr (param, _T("==")))) + { + error_syntax (NULL); + return 1; + } + + else + { + /* Change first '='to space to terminate comparison loop */ + + *pp = _T(' '); /* Need a space to terminate comparison loop */ + pp += 2; /* over '==' */ + while (_istspace (*pp)) /* Skip subsequent spaces */ + pp++; + + _tcscat (pp, _T(" ")); /* Add one space to ensure comparison ends */ + + while (*param == *pp) /* Comparison loop */ + { + if (_istspace (*param)) /* Terminates on space */ + break; + + param++, pp++; + } + + if (x_flag ^= (*param != *pp) ? 0 : X_EXEC) + { + while (*pp && !_istspace (*pp)) /* Find first space, */ + pp++; + + x_flag |= X_EMPTY; + } + } + + if (x_flag & X_EMPTY) + { + while (_istspace (*pp)) /* Then skip spaces */ + pp++; + + if (*pp == _T('\0')) /* If nothing left then syntax err */ + { + error_syntax (NULL); + return 1; + } + } + + if (x_flag & X_EXEC) + { + ParseCommandLine (pp); + } + + return 0; +} diff --git a/subsys/system/cmd/internal.c b/subsys/system/cmd/internal.c new file mode 100644 index 0000000..6f74ab5 --- /dev/null +++ b/subsys/system/cmd/internal.c @@ -0,0 +1,468 @@ +/* + * INTERNAL.C - command.com internal commands. + * + * + * History: + * + * 17/08/94 (Tim Norman) + * started. + * + * 08/08/95 (Matt Rains) + * i have cleaned up the source code. changes now bring this source into + * guidelines for recommended programming practice. + * + * cd() + * started. + * + * dir() + * i have added support for file attributes to the DIR() function. the + * routine adds "d" (directory) and "r" (read only) output. files with the + * system attribute have the filename converted to lowercase. files with + * the hidden attribute are not displayed. + * + * i have added support for directorys. now if the directory attribute is + * detected the file size if replaced with the string "". + * + * ver() + * started. + * + * md() + * started. + * + * rd() + * started. + * + * del() + * started. + * + * does not support wildcard selection. + * + * todo: add delete directory support. + * add recursive directory delete support. + * + * ren() + * started. + * + * does not support wildcard selection. + * + * todo: add rename directory support. + * + * a general structure has been used for the cd, rd and md commands. this + * will be better in the long run. it is too hard to maintain such diverse + * functions when you are involved in a group project like this. + * + * 12/14/95 (Tim Norman) + * fixed DIR so that it will stick \*.* if a directory is specified and + * that it will stick on .* if a file with no extension is specified or + * *.* if it ends in a \ + * + * 1/6/96 (Tim Norman) + * added an isatty call to DIR so it won't prompt for keypresses unless + * stdin and stdout are the console. + * + * changed parameters to be mutually consistent to make calling the + * functions easier + * + * rem() + * started. + * + * doskey() + * started. + * + * 01/22/96 (Oliver Mueller) + * error messages are now handled by perror. + * + * 02/05/96 (Tim Norman) + * converted all functions to accept first/rest parameters + * + * 07/26/96 (Tim Norman) + * changed return values to int instead of void + * + * path() started. + * + * 12/23/96 (Aaron Kaufman) + * rewrote dir() to mimic MS-DOS's dir + * + * 01/28/97 (Tim Norman) + * cleaned up Aaron's DIR code + * + * 06/13/97 (Tim Norman) + * moved DIR code to dir.c + * re-implemented Aaron's DIR code + * + * 06/14/97 (Steffan Kaiser) + * ctrl-break handling + * bug fixes + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 03-Dec-1998 (Eric Kohl ) + * Replaced DOS calls by Win32 calls. + * + * 08-Dec-1998 (Eric Kohl ) + * Added help texts ("/?"). + * + * 18-Dec-1998 (Eric Kohl ) + * Added support for quoted arguments (cd "program files"). + * + * 07-Jan-1999 (Eric Kohl ) + * Clean up. + * + * 26-Jan-1999 (Eric Kohl ) + * Replaced remaining CRT io functions by Win32 io functions. + * Unicode safe! + * + * 30-Jan-1999 (Eric Kohl ) + * Added "cd -" feature. Changes to the previous directory. + * + * 15-Mar-1999 (Eric Kohl ) + * Fixed bug in "cd -" feature. If the previous directory was a root + * directory, it was ignored. + * + * 23-Feb-2001 (Carl Nettelblad ) + * Improved chdir/cd command. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "cmd.h" + + +#ifdef INCLUDE_CMD_CHDIR + +static LPTSTR lpLastPath; + + +VOID InitLastPath (VOID) +{ + lpLastPath = NULL; +} + + +VOID FreeLastPath (VOID) +{ + if (lpLastPath) + free (lpLastPath); +} + +/* + * CD / CHDIR + * + */ +INT cmd_chdir (LPTSTR cmd, LPTSTR param) +{ + LPTSTR dir; /* pointer to the directory to change to */ + LPTSTR lpOldPath; + LPTSTR endofstring; /* pointer to the null character in the directory to change to */ + LPTSTR lastquote; /* pointer to the last quotation mark in the directory to change to */ + + /*Should we better declare a variable containing _tsclen(dir) ? It's used a few times, + but on the other hand paths are generally not very long*/ + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Changes the current directory or displays it's name\n\n" + "CHDIR [drive:][path]\n" + "CHDIR[..|-]\n" + "CD [drive:][path]\n" + "CD[..|-]\n\n" + " .. parent directory\n" + " - previous directory\n\n" + "Type CD drive: to display the current directory on the specified drive.\n" + "Type CD without a parameter to display the current drive and directory.")); + return 0; + } + + /* The whole param string is our parameter these days. The only thing we do is eliminating every quotation mark */ + /* Is it safe to change the characters param is pointing to? I presume it is, as there doesn't seem to be any + post-processing of it after the function call (what would that accomplish?) */ + + dir=param; + endofstring=dir+_tcslen(dir); + + while ((lastquote = _tcsrchr(dir,'\"'))) + { + endofstring--; + memmove(lastquote,lastquote+1,endofstring-lastquote); + *endofstring=_T('\0'); + } + + /* if doing a CD and no parameters given, print out current directory */ + if (!dir || !dir[0]) + { + TCHAR szPath[MAX_PATH]; + + GetCurrentDirectory (MAX_PATH, szPath); + + ConOutPuts (szPath); + + + return 0; + } + + if (dir && _tcslen (dir) == 1 && *dir == _T('-')) + { + if (lpLastPath) + dir = lpLastPath; + else + return 0; + } + else if (dir && _tcslen (dir)==2 && dir[1] == _T(':')) + { + TCHAR szRoot[3] = _T("A:"); + TCHAR szPath[MAX_PATH]; + + szRoot[0] = _totupper (dir[0]); + GetFullPathName (szRoot, MAX_PATH, szPath, NULL); + + /* PathRemoveBackslash */ + if (_tcslen (szPath) > 3) + { + LPTSTR p = _tcsrchr (szPath, _T('\\')); + *p = _T('\0'); + } + + ConOutPuts (szPath); + + + return 0; + } + + /* remove trailing \ if any, but ONLY if dir is not the root dir */ + if (_tcslen (dir) > 3 && dir[_tcslen (dir) - 1] == _T('\\')) + dir[_tcslen(dir) - 1] = _T('\0'); + + + /* store current directory */ + lpOldPath = (LPTSTR)malloc (MAX_PATH * sizeof(TCHAR)); + GetCurrentDirectory (MAX_PATH, lpOldPath); + + if (!SetCurrentDirectory (dir)) + { + ErrorMessage (GetLastError(), _T("CD")); + + /* throw away current directory */ + free (lpOldPath); + lpOldPath = NULL; + + return 1; + } + else + { + GetCurrentDirectory(MAX_PATH, dir); + if (dir[0]!=lpOldPath[0]) + { + SetCurrentDirectory(lpOldPath); + free(lpOldPath); + } + else + { + if (lpLastPath) + free (lpLastPath); + lpLastPath = lpOldPath; + } + } + + + return 0; +} +#endif + + + +#ifdef INCLUDE_CMD_MKDIR +/* + * MD / MKDIR + * + */ +INT cmd_mkdir (LPTSTR cmd, LPTSTR param) +{ + LPTSTR dir; /* pointer to the directory to change to */ + LPTSTR place; /* used to search for the \ when no space is used */ + LPTSTR *p = NULL; + INT argc; + + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Creates a directory.\n\n" + "MKDIR [drive:]path\nMD [drive:]path")); + return 0; + } + + + /* check if there is no space between the command and the path */ + if (param[0] == _T('\0')) + { + /* search for the \ or . so that both short & long names will work */ + for (place = cmd; *place; place++) + if (*place == _T('.') || *place == _T('\\')) + break; + + if (*place) + dir = place; + else + /* signal that there are no parameters */ + dir = NULL; + } + else + { + p = split (param, &argc, FALSE); + if (argc > 1) + { + /*JPP 20-Jul-1998 use standard error message */ + error_too_many_parameters (param); + freep (p); + return 1; + } + else + dir = p[0]; + } + + if (!dir) + { + ConErrPrintf (_T("Required parameter missing\n")); + return 1; + } + + /* remove trailing \ if any, but ONLY if dir is not the root dir */ + if (_tcslen (dir) >= 2 && dir[_tcslen (dir) - 1] == _T('\\')) + dir[_tcslen(dir) - 1] = _T('\0'); + + if (!CreateDirectory (dir, NULL)) + { + ErrorMessage (GetLastError(), _T("MD")); + + freep (p); + return 1; + } + + freep (p); + + return 0; +} +#endif + + +#ifdef INCLUDE_CMD_RMDIR +/* + * RD / RMDIR + * + */ +INT cmd_rmdir (LPTSTR cmd, LPTSTR param) +{ + LPTSTR dir; /* pointer to the directory to change to */ + LPTSTR place; /* used to search for the \ when no space is used */ + + LPTSTR *p = NULL; + INT argc; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Removes a directory.\n\n" + "RMDIR [drive:]path\nRD [drive:]path")); + return 0; + } + + /* check if there is no space between the command and the path */ + if (param[0] == _T('\0')) + { + /* search for the \ or . so that both short & long names will work */ + for (place = cmd; *place; place++) + if (*place == _T('.') || *place == _T('\\')) + break; + + if (*place) + dir = place; + else + /* signal that there are no parameters */ + dir = NULL; + } + else + { + p = split (param, &argc, FALSE); + if (argc > 1) + { + /*JPP 20-Jul-1998 use standard error message */ + error_too_many_parameters (param); + freep (p); + return 1; + } + else + dir = p[0]; + } + + if (!dir) + { + ConErrPrintf (_T("Required parameter missing\n")); + return 1; + } + + /* remove trailing \ if any, but ONLY if dir is not the root dir */ + if (_tcslen (dir) >= 2 && dir[_tcslen (dir) - 1] == _T('\\')) + dir[_tcslen(dir) - 1] = _T('\0'); + + if (!RemoveDirectory (dir)) + { + ErrorMessage (GetLastError(), _T("RD")); + freep (p); + + return 1; + } + + freep (p); + + return 0; +} +#endif + + +/* + * set the exitflag to true + * + */ +INT CommandExit (LPTSTR cmd, LPTSTR param) +{ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Exits the command line interpreter.\n\nEXIT")); + return 0; + } + + bExit = TRUE; + return 0; +} + + +#ifdef INCLUDE_CMD_REM +/* + * does nothing + * + */ +INT CommandRem (LPTSTR cmd, LPTSTR param) +{ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Starts a comment line in a batch file.\n\n" + "REM [Comment]")); + } + + return 0; +} +#endif /* INCLUDE_CMD_REM */ + + +INT CommandShowCommands (LPTSTR cmd, LPTSTR param) +{ + PrintCommandList (); + return 0; +} + +/* EOF */ diff --git a/subsys/system/cmd/label.c b/subsys/system/cmd/label.c new file mode 100644 index 0000000..b7062f0 --- /dev/null +++ b/subsys/system/cmd/label.c @@ -0,0 +1,120 @@ +/* + * LABEL.C - label internal command. + * + * + * History: + * + * 10-Dec-1998 (Eric Kohl ) + * Started. + * + * 11-Dec-1998 (Eric Kohl ) + * Finished. + * + * 19-Jan-1998 (Eric Kohl ) + * Unicode ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_LABEL + +#include +#include +#include +#include + +#include "cmd.h" + + +INT cmd_label (LPTSTR cmd, LPTSTR param) +{ + TCHAR szRootPath[] = _T("A:\\"); + TCHAR szLabel[80]; + TCHAR szOldLabel[80]; + DWORD dwSerialNr; + LPTSTR *arg; + INT args; + + /* set empty label string */ + szLabel[0] = _T('\0'); + + /* print help */ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or changes drive label.\n\n" + "LABEL [drive:][label]")); + return 0; + } + + /* get parameters */ + arg = split (param, &args, FALSE); + + if (args > 2) + { + /* too many parameters */ + error_too_many_parameters (arg[args - 1]); + freep (arg); + return 1; + } + + if (args == 0) + { + /* get label of current drive */ + TCHAR szCurPath[MAX_PATH]; + GetCurrentDirectory (MAX_PATH, szCurPath); + szRootPath[0] = szCurPath[0]; + } + else + { + if ((_tcslen (arg[0]) >= 2) && (arg[0][1] == _T(':'))) + { + szRootPath[0] = toupper (*arg[0]); + if (args == 2) + _tcsncpy (szLabel, arg[1], 12); + } + else + { + TCHAR szCurPath[MAX_PATH]; + GetCurrentDirectory (MAX_PATH, szCurPath); + szRootPath[0] = szCurPath[0]; + _tcsncpy (szLabel, arg[0], 12); + } + } + + /* check root path */ + if (!IsValidPathName (szRootPath)) + { + error_invalid_drive (); + freep (arg); + return 1; + } + + GetVolumeInformation (szRootPath, szOldLabel, 80, &dwSerialNr, + NULL, NULL, NULL, 0); + + /* print drive info */ + ConOutPrintf (_T("Volume in drive %c:"), _totupper (szRootPath[0])); + + if (szOldLabel[0] != _T('\0')) + ConOutPrintf (_T(" is %s\n"), szOldLabel); + else + ConOutPrintf (_T(" has no label\n")); + + /* print the volume serial number */ + ConOutPrintf (_T("Volume Serial Number is %04X-%04X\n"), + HIWORD(dwSerialNr), LOWORD(dwSerialNr)); + + if (szLabel[0] == _T('\0')) + { + ConOutPrintf (_T("Drive label (11 Characters, ENTER if none)? ")); + ConInString (szLabel, 80); + } + + SetVolumeLabel (szRootPath, szLabel); + + freep (arg); + + return 0; +} + +#endif /* INCLUDE_CMD_LABEL */ diff --git a/subsys/system/cmd/license.txt b/subsys/system/cmd/license.txt new file mode 100644 index 0000000..c4fb365 --- /dev/null +++ b/subsys/system/cmd/license.txt @@ -0,0 +1,342 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/subsys/system/cmd/locale.c b/subsys/system/cmd/locale.c new file mode 100644 index 0000000..2751719 --- /dev/null +++ b/subsys/system/cmd/locale.c @@ -0,0 +1,184 @@ +/* + * LOCALE.C - locale handling. + * + * + * History: + * + * 09-Jan-1999 (Eric Kohl ) + * Started. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode safe! + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" + + +TCHAR cDateSeparator; +TCHAR cTimeSeparator; +TCHAR cThousandSeparator; +TCHAR cDecimalSeparator; +INT nDateFormat; +INT nTimeFormat; +TCHAR aszDayNames[7][8]; +INT nNumberGroups; + + +VOID InitLocale (VOID) +{ +#ifdef LOCALE_WINDOWS + TCHAR szBuffer[256]; + INT i; + + /* date settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDATE, szBuffer, 256); + CharToOem (szBuffer, szBuffer); + cDateSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IDATE, szBuffer, 256); + nDateFormat = _ttoi (szBuffer); + + /* time settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szBuffer, 256); + CharToOem (szBuffer, szBuffer); + cTimeSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 256); + nTimeFormat = _ttoi (szBuffer); + + /* number settings */ + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szBuffer, 256); + CharToOem (szBuffer, szBuffer); + cThousandSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szBuffer, 256); + CharToOem (szBuffer, szBuffer); + cDecimalSeparator = szBuffer[0]; + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szBuffer, 256); + nNumberGroups = _ttoi (szBuffer); + + /* days of week */ + for (i = 0; i < 7; i++) + { + GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1 + i, szBuffer, 256); + CharToOem (szBuffer, szBuffer); + _tcscpy (aszDayNames[(i+1)%7], szBuffer); /* little hack */ + } +#endif + +#ifdef LOCALE_GERMAN + LPTSTR names [7] = {_T("So"), _T("Mo"), _T("Di"), _T("Mi"), _T("Do"), _T("Fr"), _T("Sa")}; + INT i; + + /* date settings */ + cDateSeparator = '.'; + nDateFormat = 1; /* ddmmyy */ + + /* time settings */ + cTimeSeparator = ':'; + nTimeFormat = 1; /* 24 hour */ + + /* number settings */ + cThousandSeparator = '.'; + cDecimalSeparator = ','; + nNumberGroups = 3; + + /* days of week */ + for (i = 0; i < 7; i++) + _tcscpy (aszDayNames[i], names[i]); +#endif + +#ifdef LOCALE_DEFAULT + LPTSTR names [7] = {_T("Sun"), _T("Mon"), _T("Tue"), _T("Wed"), _T("Thu"), _T("Fri"), _T("Sat")}; + INT i; + + /* date settings */ + cDateSeparator = '-'; + nDateFormat = 0; /* mmddyy */ + + /* time settings */ + cTimeSeparator = ':'; + nTimeFormat = 0; /* 12 hour */ + + /* number settings */ + cThousandSeparator = ','; + cDecimalSeparator = '.'; + nNumberGroups = 3; + + /* days of week */ + for (i = 0; i < 7; i++) + _tcscpy (aszDayNames[i], names[i]); +#endif +} + + +VOID PrintDate (VOID) +{ +#ifdef __REACTOS__ + SYSTEMTIME st; + + GetLocalTime (&st); + + switch (nDateFormat) + { + case 0: /* mmddyy */ + default: + ConOutPrintf (_T("%s %02d%c%02d%c%04d"), + aszDayNames[st.wDayOfWeek], st.wMonth, cDateSeparator, st.wDay, cDateSeparator, st.wYear); + break; + + case 1: /* ddmmyy */ + ConOutPrintf (_T("%s %02d%c%02d%c%04d"), + aszDayNames[st.wDayOfWeek], st.wDay, cDateSeparator, st.wMonth, cDateSeparator, st.wYear); + break; + + case 2: /* yymmdd */ + ConOutPrintf (_T("%s %04d%c%02d%c%02d"), + aszDayNames[st.wDayOfWeek], st.wYear, cDateSeparator, st.wMonth, cDateSeparator, st.wDay); + break; + } +#else + TCHAR szDate[32]; + + GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, + szDate, sizeof (szDate)); + ConOutPrintf (_T("%s"), szDate); +#endif +} + + +VOID PrintTime (VOID) +{ +#ifdef __REACTOS__ + SYSTEMTIME st; + + GetLocalTime (&st); + + switch (nTimeFormat) + { + case 0: /* 12 hour format */ + default: + ConOutPrintf (_T("Current time is %2d%c%02d%c%02d%c%02d%c\n"), + (st.wHour == 0 ? 12 : (st.wHour <= 12 ? st.wHour : st.wHour - 12)), + cTimeSeparator, st.wMinute, cTimeSeparator, st.wSecond, cDecimalSeparator, + st.wMilliseconds / 10, (st.wHour <= 11 ? 'a' : 'p')); + break; + + case 1: /* 24 hour format */ + ConOutPrintf (_T("Current time is %2d%c%02d%c%02d%c%02d\n"), + st.wHour, cTimeSeparator, st.wMinute, cTimeSeparator, + st.wSecond, cDecimalSeparator, st.wMilliseconds / 10); + break; + } +#else + TCHAR szTime[32]; + + GetTimeFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL, + szTime, sizeof (szTime)); + ConOutPrintf (_T("Current time is: %s\n"), szTime); +#endif +} diff --git a/subsys/system/cmd/makefile b/subsys/system/cmd/makefile new file mode 100644 index 0000000..a705171 --- /dev/null +++ b/subsys/system/cmd/makefile @@ -0,0 +1,37 @@ +# +# ReactOS CMD +# +# Makefile +# + +PATH_TO_TOP = ../../.. +TOOLS_PATH = $(PATH_TO_TOP)/tools + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = cmd + +TARGET_INSTALLDIR = system32 + +WINE_MODE = yes + +WINE_RC = $(TARGET_NAME) + +WINE_INCLUDE = $(PATH_TO_TOP)/include/reactos + +TARGET_OBJECTS = \ + cmd.o attrib.o alias.o batch.o beep.o call.o chcp.o choice.o \ + cls.o cmdinput.o cmdtable.o color.o console.o copy.o date.o del.o \ + delay.o dir.o dirstack.o echo.o error.o filecomp.o for.o free.o \ + goto.o history.o if.o internal.o label.o locale.o memory.o misc.o \ + move.o msgbox.o path.o pause.o prompt.o redir.o ren.o screen.o \ + set.o shift.o start.o strtoclr.o time.o timer.o title.o type.o \ + ver.o verify.o vol.o where.o window.o #cmd.coff + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/subsys/system/cmd/memory.c b/subsys/system/cmd/memory.c new file mode 100644 index 0000000..42d1028 --- /dev/null +++ b/subsys/system/cmd/memory.c @@ -0,0 +1,110 @@ +/* + * MEMORY.C - internal command. + * + * + * History: + * + * 01-Sep-1999 (Eric Kohl) + * Started. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_MEMORY + +#include +#include +#include +#include + +#include "cmd.h" + + +/* + * convert + * + * insert commas into a number + */ +static INT +ConvertDWord (DWORD num, LPTSTR des, INT len, BOOL bSeparator) +{ + TCHAR temp[32]; + INT c = 0; + INT n = 0; + + if (num == 0) + { + des[0] = _T('0'); + des[1] = _T('\0'); + n = 1; + } + else + { + temp[31] = 0; + while (num > 0) + { + if (bSeparator && (((c + 1) % (nNumberGroups + 1)) == 0)) + temp[30 - c++] = cThousandSeparator; + temp[30 - c++] = (TCHAR)(num % 10) + _T('0'); + num /= 10; + } + + for (n = 0; n <= c; n++) + des[n] = temp[31 - c + n]; + } + + return n; +} + + +INT CommandMemory (LPTSTR cmd, LPTSTR param) +{ + MEMORYSTATUS ms; + TCHAR szMemoryLoad[20]; + TCHAR szTotalPhys[20]; + TCHAR szAvailPhys[20]; + TCHAR szTotalPageFile[20]; + TCHAR szAvailPageFile[20]; + TCHAR szTotalVirtual[20]; + TCHAR szAvailVirtual[20]; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays the amount of system memory.\n" + "\n" + "MEMORY")); + return 0; + } + + ms.dwLength = sizeof(MEMORYSTATUS); + + GlobalMemoryStatus (&ms); + + ConvertDWord (ms.dwMemoryLoad, szMemoryLoad, 20, FALSE); + ConvertDWord (ms.dwTotalPhys, szTotalPhys, 20, TRUE); + ConvertDWord (ms.dwAvailPhys, szAvailPhys, 20, TRUE); + ConvertDWord (ms.dwTotalPageFile, szTotalPageFile, 20, TRUE); + ConvertDWord (ms.dwAvailPageFile, szAvailPageFile, 20, TRUE); + ConvertDWord (ms.dwTotalVirtual, szTotalVirtual, 20, TRUE); + ConvertDWord (ms.dwAvailVirtual, szAvailVirtual, 20, TRUE); + + ConOutPrintf (_T("\n" + " %12s%% memory load.\n" + "\n" + " %13s bytes total physical RAM.\n" + " %13s bytes available physical RAM.\n" + "\n" + " %13s bytes total page file.\n" + " %13s bytes available page file.\n" + "\n" + " %13s bytes total virtual memory.\n" + " %13s bytes available virtual memory.\n"), + szMemoryLoad, szTotalPhys, szAvailPhys, szTotalPageFile, + szAvailPageFile, szTotalVirtual, szAvailVirtual); + + return 0; +} + +#endif /* INCLUDE_CMD_MEMORY */ + +/* EOF */ diff --git a/subsys/system/cmd/misc.c b/subsys/system/cmd/misc.c new file mode 100644 index 0000000..8643463 --- /dev/null +++ b/subsys/system/cmd/misc.c @@ -0,0 +1,598 @@ +/* + * MISC.C - misc. functions. + * + * + * History: + * + * 07/12/98 (Rob Lake) + * started + * + * 07/13/98 (Rob Lake) + * moved functions in here + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 18-Dec-1998 (Eric Kohl ) + * Changed split() to accept quoted arguments. + * Removed parse_firstarg(). + * + * 23-Jan-1999 (Eric Kohl ) + * Fixed an ugly bug in split(). In rare cases (last character + * of the string is a space) it ignored the NULL character and + * tried to add the following to the argument list. + * + * 28-Jan-1999 (Eric Kohl ) + * FileGetString() seems to be working now. + * + * 06-Nov-1999 (Eric Kohl ) + * Added PagePrompt() and FilePrompt(). + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "cmd.h" + + +/* + * get a character out-of-band and honor Ctrl-Break characters + */ +TCHAR cgetchar (VOID) +{ + HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE); + INPUT_RECORD irBuffer; + DWORD dwRead; + + do + { + ReadConsoleInput (hInput, &irBuffer, 1, &dwRead); + if ((irBuffer.EventType == KEY_EVENT) && + (irBuffer.Event.KeyEvent.bKeyDown == TRUE)) + { + if ((irBuffer.Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) & + (irBuffer.Event.KeyEvent.wVirtualKeyCode == 'C')) + bCtrlBreak = TRUE; + + break; + } + } + while (TRUE); + +#ifndef _UNICODE + return irBuffer.Event.KeyEvent.uChar.AsciiChar; +#else + return irBuffer.Event.KeyEvent.uChar.UnicodeChar; +#endif /* _UNICODE */ +} + + +/* + * Check if Ctrl-Break was pressed during the last calls + */ + +BOOL CheckCtrlBreak (INT mode) +{ + static BOOL bLeaveAll = FALSE; /* leave all batch files */ + TCHAR c; + + switch (mode) + { + case BREAK_OUTOFBATCH: + bLeaveAll = 0; + return FALSE; + + case BREAK_BATCHFILE: + if (bLeaveAll) + return TRUE; + + if (!bCtrlBreak) + return FALSE; + + /* we need to be sure the string arrives on the screen! */ + do + ConOutPuts (_T("\r\nCtrl-Break pressed. Cancel batch file? (Yes/No/All) ")); + while (!_tcschr ("YNA\3", c = _totupper (cgetchar())) || !c); + + ConOutPuts (_T("\r\n")); + + if (c == _T('N')) + return bCtrlBreak = FALSE; /* ignore */ + + /* leave all batch files */ + bLeaveAll = ((c == _T('A')) || (c == _T('\3'))); + break; + + case BREAK_INPUT: + if (!bCtrlBreak) + return FALSE; + break; + } + + /* state processed */ + bCtrlBreak = FALSE; + return TRUE; +} + +/* add new entry for new argument */ +static BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry) +{ + LPTSTR q; + LPTSTR *oldarg; + + q = malloc ((_tcslen(entry) + 1) * sizeof (TCHAR)); + if (NULL == q) + { + return FALSE; + } + _tcscpy (q, entry); + + oldarg = *arg; + *arg = realloc (oldarg, (*ac + 2) * sizeof (LPTSTR)); + if (NULL == *arg) + { + *arg = oldarg; + return FALSE; + } + + /* save new entry */ + (*arg)[*ac] = q; + (*arg)[++(*ac)] = NULL; + + return TRUE; +} + +static BOOL expand (LPINT ac, LPTSTR **arg, LPCTSTR pattern) +{ + HANDLE hFind; + WIN32_FIND_DATA FindData; + BOOL ok; + LPCTSTR pathend; + LPTSTR dirpart, fullname; + + pathend = _tcsrchr (pattern, _T('\\')); + if (NULL != pathend) + { + dirpart = malloc((pathend - pattern + 2) * sizeof(TCHAR)); + if (NULL == dirpart) + { + return FALSE; + } + memcpy(dirpart, pattern, pathend - pattern + 1); + dirpart[pathend - pattern + 1] = '\0'; + } + else + { + dirpart = NULL; + } + hFind = FindFirstFile (pattern, &FindData); + if (INVALID_HANDLE_VALUE != hFind) + { + do + { + if (NULL != dirpart) + { + fullname = malloc((_tcslen(dirpart) + _tcslen(FindData.cFileName) + 1) * sizeof(TCHAR)); + if (NULL == fullname) + { + ok = FALSE; + } + else + { + _tcscat (_tcscpy (fullname, dirpart), FindData.cFileName); + ok = add_entry(ac, arg, fullname); + free (fullname); + } + } + else + { + ok = add_entry(ac, arg, FindData.cFileName); + } + } while (FindNextFile (hFind, &FindData) && ok); + FindClose (hFind); + } + else + { + ok = add_entry(ac, arg, pattern); + } + + if (NULL != dirpart) + { + free (dirpart); + } + + return ok; +} + +/* + * split - splits a line up into separate arguments, deliminators + * are spaces and slashes ('/'). + */ + +LPTSTR *split (LPTSTR s, LPINT args, BOOL expand_wildcards) +{ + LPTSTR *arg; + LPTSTR start; + LPTSTR q; + INT ac; + INT len; + BOOL bQuoted = FALSE; + + arg = malloc (sizeof (LPTSTR)); + if (!arg) + return NULL; + *arg = NULL; + + ac = 0; + while (*s) + { + /* skip leading spaces */ + while (*s && (_istspace (*s) || _istcntrl (*s))) + ++s; + + /* if quote (") then set bQuoted */ + if (*s == _T('\"')) + { + ++s; + bQuoted = TRUE; + } + + start = s; + + /* the first character can be '/' */ + if (*s == _T('/')) + ++s; + + /* skip to next word delimiter or start of next option */ + if (bQuoted) + { + while (_istprint (*s) && (*s != _T('\"')) && (*s != _T('/'))) + ++s; + } + else + { + while (_istprint (*s) && !_istspace (*s) && (*s != _T('/'))) + ++s; + } + + /* a word was found */ + if (s != start) + { + q = malloc (((len = s - start) + 1) * sizeof (TCHAR)); + if (!q) + { + return NULL; + } + memcpy (q, start, len * sizeof (TCHAR)); + q[len] = _T('\0'); + if (expand_wildcards && _T('/') != *start && + (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?')))) + { + if (! expand(&ac, &arg, q)) + { + free (q); + freep (arg); + return NULL; + } + } + else + { + if (! add_entry(&ac, &arg, q)) + { + free (q); + freep (arg); + return NULL; + } + } + free (q); + } + + /* adjust string pointer if quoted (") */ + if (bQuoted) + { + ++s; + bQuoted = FALSE; + } + } + + *args = ac; + + return arg; +} + + +/* + * freep -- frees memory used for a call to split + * + */ +VOID freep (LPTSTR *p) +{ + LPTSTR *q; + + if (!p) + return; + + q = p; + while (*q) + free(*q++); + + free(p); +} + + +LPTSTR stpcpy (LPTSTR dest, LPTSTR src) +{ + _tcscpy (dest, src); + return (dest + _tcslen (src)); +} + + + +/* + * Checks if a path is valid (accessible) + */ + +BOOL IsValidPathName (LPCTSTR pszPath) +{ + TCHAR szOldPath[MAX_PATH]; + BOOL bResult; + + GetCurrentDirectory (MAX_PATH, szOldPath); + bResult = SetCurrentDirectory (pszPath); + + SetCurrentDirectory (szOldPath); + + return bResult; +} + + +/* + * Checks if a file exists (accessible) + */ + +BOOL IsValidFileName (LPCTSTR pszPath) +{ + return (GetFileAttributes (pszPath) != 0xFFFFFFFF); +} + + +BOOL IsValidDirectory (LPCTSTR pszPath) +{ + return (GetFileAttributes (pszPath) & FILE_ATTRIBUTE_DIRECTORY); +} + + +BOOL FileGetString (HANDLE hFile, LPTSTR lpBuffer, INT nBufferLength) +{ + LPTSTR lpString; + TCHAR ch; + DWORD dwRead; + + lpString = lpBuffer; + + while ((--nBufferLength > 0) && + ReadFile(hFile, &ch, 1, &dwRead, NULL) && dwRead) + { + if (ch == _T('\r')) + { + /* overread '\n' */ + ReadFile (hFile, &ch, 1, &dwRead, NULL); + break; + } + *lpString++ = ch; + } + + if (!dwRead && lpString == lpBuffer) + return FALSE; + + *lpString++ = _T('\0'); + + return TRUE; +} + +#ifndef __REACTOS__ +/* + * GetConsoleWindow - returns the handle to the current console window + */ +HWND GetConsoleWindow (VOID) +{ + TCHAR original[256]; + TCHAR temp[256]; + HWND h=0; + + if(h) + return h; + + GetConsoleTitle (original, sizeof(original)); + + _tcscpy (temp, original); + _tcscat (temp, _T("-xxx ")); + + if (FindWindow (0, temp) == NULL ) + { + SetConsoleTitle (temp); + Sleep (0); + + while(!(h = FindWindow (0, temp))) + ; + + SetConsoleTitle (original); + } + + return h; +} +#endif + + +INT PagePrompt (VOID) +{ + INPUT_RECORD ir; + + ConOutPrintf ("Press a key to continue...\n"); + + RemoveBreakHandler (); + ConInDisable (); + + do + { + ConInKey (&ir); + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + + AddBreakHandler (); + ConInEnable (); + + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + return PROMPT_BREAK; + + return PROMPT_YES; +} + + +INT FilePromptYN (LPTSTR szFormat, ...) +{ + TCHAR szOut[512]; + va_list arg_ptr; +// TCHAR cKey = 0; +// LPTSTR szKeys = _T("yna"); + + TCHAR szIn[10]; + LPTSTR p; + + va_start (arg_ptr, szFormat); + _vstprintf (szOut, szFormat, arg_ptr); + va_end (arg_ptr); + + ConOutPrintf (szFormat); + +/* preliminary fix */ + ConInString (szIn, 10); + ConOutPrintf (_T("\n")); + + _tcsupr (szIn); + for (p = szIn; _istspace (*p); p++) + ; + + if (*p == _T('Y')) + return PROMPT_YES; + else if (*p == _T('N')) + return PROMPT_NO; +#if 0 + else if (*p == _T('\03')) + return PROMPT_BREAK; +#endif + + return PROMPT_NO; + + +/* unfinished sollution */ +#if 0 + RemoveBreakHandler (); + ConInDisable (); + + do + { + ConInKey (&ir); + cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); + if (_tcschr (szKeys, cKey[0]) == NULL) + cKey = 0; + + + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + + AddBreakHandler (); + ConInEnable (); + + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + return PROMPT_BREAK; + + return PROMPT_YES; +#endif +} + + +INT FilePromptYNA (LPTSTR szFormat, ...) +{ + TCHAR szOut[512]; + va_list arg_ptr; +// TCHAR cKey = 0; +// LPTSTR szKeys = _T("yna"); + + TCHAR szIn[10]; + LPTSTR p; + + va_start (arg_ptr, szFormat); + _vstprintf (szOut, szFormat, arg_ptr); + va_end (arg_ptr); + + ConOutPrintf (szFormat); + +/* preliminary fix */ + ConInString (szIn, 10); + ConOutPrintf (_T("\n")); + + _tcsupr (szIn); + for (p = szIn; _istspace (*p); p++) + ; + + if (*p == _T('Y')) + return PROMPT_YES; + else if (*p == _T('N')) + return PROMPT_NO; + if (*p == _T('A')) + return PROMPT_ALL; +#if 0 + else if (*p == _T('\03')) + return PROMPT_BREAK; +#endif + + return PROMPT_NO; + + +/* unfinished sollution */ +#if 0 + RemoveBreakHandler (); + ConInDisable (); + + do + { + ConInKey (&ir); + cKey = _totlower (ir.Event.KeyEvent.uChar.AsciiChar); + if (_tcschr (szKeys, cKey[0]) == NULL) + cKey = 0; + + + } + while ((ir.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_MENU) || + (ir.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL)); + + AddBreakHandler (); + ConInEnable (); + + if ((ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) || + ((ir.Event.KeyEvent.wVirtualKeyCode == 'C') && + (ir.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)))) + return PROMPT_BREAK; + + return PROMPT_YES; +#endif +} + +/* EOF */ diff --git a/subsys/system/cmd/move.c b/subsys/system/cmd/move.c new file mode 100644 index 0000000..fd3744f --- /dev/null +++ b/subsys/system/cmd/move.c @@ -0,0 +1,265 @@ +/* + * MOVE.C - move internal command. + * + * + * History: + * + * 14-Dec-1998 (Eric Kohl ) + * Started. + * + * 18-Jan-1999 (Eric Kohl ) + * Unicode safe! + * Preliminary version!!! + * + * 20-Jan-1999 (Eric Kohl ) + * Redirection safe! + * + * 27-Jan-1999 (Eric Kohl ) + * Added help text ("/?"). + * Added more error checks. + * + * 03-Feb-1999 (Eric Kohl ) + * Added "/N" option. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_MOVE + +#include +#include +#include +#include + +#include "cmd.h" + + +#define OVERWRITE_NO 0 +#define OVERWRITE_YES 1 +#define OVERWRITE_ALL 2 +#define OVERWRITE_CANCEL 3 + + +static INT Overwrite (LPTSTR fn) +{ + TCHAR inp[10]; + LPTSTR p; + + ConOutPrintf (_T("Overwrite %s (Yes/No/All)? "), fn); + ConInString (inp, 10); + + _tcsupr (inp); + for (p=inp; _istspace (*p); p++) + ; + + if (*p != _T('Y') && *p != _T('A')) + return OVERWRITE_NO; + if (*p == _T('A')) + return OVERWRITE_ALL; + + return OVERWRITE_YES; +} + + + +INT cmd_move (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg; + INT argc, i, nFiles; + TCHAR szDestPath[MAX_PATH]; + TCHAR szSrcPath[MAX_PATH]; + BOOL bPrompt = TRUE; + LPTSTR p; + WIN32_FIND_DATA findBuffer; + HANDLE hFile; + LPTSTR pszFile; + BOOL bNothing = FALSE; + + if (!_tcsncmp (param, _T("/?"), 2)) + { +#if 0 + ConOutPuts (_T("Moves files and renames files and directories.\n\n" + "To move one or more files:\n" + "MOVE [/N][/Y|/-Y][drive:][path]filename1[,...] destination\n" + "\n" + "To rename a directory:\n" + "MOVE [/N][/Y|/-Y][drive:][path]dirname1 dirname2\n" + "\n" + " [drive:][path]filename1 Specifies the location and name of the file\n" + " or files you want to move.\n" + " /N Nothing. Don everthing but move files or direcories.\n" + " /Y\n" + " /-Y\n" + "...")); +#else + ConOutPuts (_T("Moves files and renames files and directories.\n\n" + "To move one or more files:\n" + "MOVE [/N][drive:][path]filename1[,...] destination\n" + "\n" + "To rename a directory:\n" + "MOVE [/N][drive:][path]dirname1 dirname2\n" + "\n" + " [drive:][path]filename1 Specifies the location and name of the file\n" + " or files you want to move.\n" + " /N Nothing. Don everthing but move files or direcories.\n" + "\n" + "Current limitations:\n" + " - You can't move a file or directory from one drive to another.\n" + )); +#endif + return 0; + } + + arg = split (param, &argc, FALSE); + nFiles = argc; + + /* read options */ + for (i = 0; i < argc; i++) + { + p = arg[i]; + + if (*p == _T('/')) + { + p++; + if (*p == _T('-')) + { + p++; + if (_totupper (*p) == _T('Y')) + bPrompt = TRUE; + } + else + { + if (_totupper (*p) == _T('Y')) + bPrompt = FALSE; + else if (_totupper (*p) == _T('N')) + bNothing = TRUE; + } + nFiles--; + } + } + + if (nFiles < 2) + { + /* there must be at least two pathspecs */ + error_req_param_missing (); + return 1; + } + + /* get destination */ + GetFullPathName (arg[argc - 1], MAX_PATH, szDestPath, NULL); +#ifdef _DEBUG + DebugPrintf (_T("Destination: %s\n"), szDestPath); +#endif + + /* move it*/ + for (i = 0; i < argc - 1; i++) + { + if (*arg[i] == _T('/')) + continue; + + hFile = FindFirstFile (arg[i], &findBuffer); + if (hFile == INVALID_HANDLE_VALUE) + { + ErrorMessage (GetLastError (), arg[i]); + freep (arg); + return 1; + } + + do + { + GetFullPathName (findBuffer.cFileName, MAX_PATH, szSrcPath, &pszFile); + + if (GetFileAttributes (szSrcPath) & FILE_ATTRIBUTE_DIRECTORY) + { + /* source is directory */ + +#ifdef _DEBUG + DebugPrintf (_T("Move directory \'%s\' to \'%s\'\n"), + szSrcPath, szDestPath); +#endif + if (!bNothing) + { + MoveFile (szSrcPath, szDestPath); + } + } + else + { + /* source is file */ + + if (IsValidFileName (szDestPath)) + { + /* destination exists */ + if (GetFileAttributes (szDestPath) & FILE_ATTRIBUTE_DIRECTORY) + { + /* destination is existing directory */ + + TCHAR szFullDestPath[MAX_PATH]; + + _tcscpy (szFullDestPath, szDestPath); + _tcscat (szFullDestPath, _T("\\")); + _tcscat (szFullDestPath, pszFile); + + ConOutPrintf (_T("%s => %s"), szSrcPath, szFullDestPath); + + if (!bNothing) + { + if (MoveFile (szSrcPath, szFullDestPath)) + ConOutPrintf (_T("[OK]\n")); + else + ConOutPrintf (_T("[Error]\n")); + } + } + else + { + /* destination is existing file */ + INT nOverwrite; + + /* must get the overwrite code */ + if ((nOverwrite = Overwrite (szDestPath))) + { +#if 0 + if (nOverwrite == OVERWRITE_ALL) + *lpFlags |= FLAG_OVERWRITE_ALL; +#endif + ConOutPrintf (_T("%s => %s"), szSrcPath, szDestPath); + + if (!bNothing) + { + if (MoveFile (szSrcPath, szDestPath)) + ConOutPrintf (_T("[OK]\n")); + else + ConOutPrintf (_T("[Error]\n")); + } + } + } + } + else + { + /* destination does not exist */ + TCHAR szFullDestPath[MAX_PATH]; + + GetFullPathName (szDestPath, MAX_PATH, szFullDestPath, NULL); + + ConOutPrintf (_T("%s => %s"), szSrcPath, szFullDestPath); + + if (!bNothing) + { + if (MoveFile (szSrcPath, szFullDestPath)) + ConOutPrintf (_T("[OK]\n")); + else + ConOutPrintf (_T("[Error]\n")); + } + } + } + } + while (FindNextFile (hFile, &findBuffer)); + + FindClose (hFile); + } + + freep (arg); + + return 0; +} + +#endif /* INCLUDE_CMD_MOVE */ diff --git a/subsys/system/cmd/msgbox.c b/subsys/system/cmd/msgbox.c new file mode 100644 index 0000000..284ccd2 --- /dev/null +++ b/subsys/system/cmd/msgbox.c @@ -0,0 +1,174 @@ +/* + * MSGBOX.C - msgbox internal command. + * + * clone from 4nt msgbox command + * + * 25 Aug 1999 + * started - Paolo Pantaleo + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_MSGBOX +#include +#include +#include +#include +#include "cmd.h" +//#include + +//#include + + +#define U_TYPE_INIT 0 + +//undefine it to allow to omit arguments +//that will be replaced by default ones +#define _SYNTAX_CHECK + + +INT CommandMsgbox (LPTSTR cmd, LPTSTR param) +{ + //used to parse command line + LPTSTR tmp; + + //used to find window title (used as messagebox title) + //and to find window handle to pass to MessageBox + HWND hWnd; + TCHAR buff[128]; + + //these are MessabeBox() parameters + LPTSTR title, prompt=""; + UINT uType=U_TYPE_INIT; + + //set default title to window title + GetConsoleTitle(buff,128); + title = buff; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts(_T( + "display a message box and return user responce\n" + "\n" + "MSGBOX type [\"title\"] prompt\n" + "\n" + "type button displayed\n" + " possible values are: OK, OKCANCEL,\n" + " YESNO, YESNOCANCEL\n" + "title title of message box\n" + "prompt text displayed by the message box\n" + "\n" + "\n" + "ERRORLEVEL is set according the button pressed:\n" + "\n" + "YES : 10 | NO : 11\n" + "OK : 10 | CANCEL : 12\n")); + return 0; + } + + //yes here things are quite massed up :) + + //skip spaces + while(_istspace(*param)) + param++; + + //search for type of messagebox (ok, okcancel, ...) + if (_tcsnicmp(param, _T("ok "),3 ) == 0) + { + uType |= MB_ICONEXCLAMATION | MB_OK; + param+=3; + } + else if (_tcsnicmp(param, _T("okcancel "),9 ) == 0) + { + uType |= MB_ICONQUESTION | MB_OKCANCEL; + param+=9; + } + else if (_tcsnicmp(param, _T("yesno "),6 ) == 0) + { + uType |= MB_ICONQUESTION | MB_YESNO; + param+=6; + } + else if (_tcsnicmp(param, _T("yesnocancel "), 12 ) == 0) + { + uType |= MB_ICONQUESTION | MB_YESNOCANCEL; + param+=12; + } + else{ +#ifdef _SYNTAX_CHECK + error_req_param_missing (); + return 1; +#else + uType |= MB_ICONEXCLAMATION | MB_OK; +#endif + } + + + //skip spaces + while(_istspace(*param)) + param++; + +#ifdef _SYNTAX_CHECK + //if reached end of string + //it is an error becuase we do not yet have prompt + if ( *param == 0) + { + error_req_param_missing (); + return 1; + } +#endif + + //search for "title" + tmp = param; + + if(*param == '"') + { + tmp = _tcschr(param+1,'"'); + if (tmp) + { + *tmp = 0; + title = param+1; + tmp++; + param = tmp; + } + } + + //skip spaces + while(_istspace(*param)) + param++; +#ifdef _SYNTAX_CHECK + //get prompt + if ( *param == 0) + { + error_req_param_missing (); + return 1; + } +#endif + + prompt = param; + + hWnd=GetConsoleWindow (); +// DebugPrintf("FindWindow hWnd = %d\n",hWnd); + ConErrPrintf("FindWindow hWnd = %d\n",hWnd); + + switch ( + MessageBox(hWnd,prompt,title,uType) + ) + { + case IDYES: + case IDOK: + nErrorLevel = 10; + break; + + case IDNO: + nErrorLevel = 11; + break; + + case IDCANCEL: + nErrorLevel = 12; + break; + } + + return 0; +} + +#endif /* INCLUDE_CMD_MSGBOX */ diff --git a/subsys/system/cmd/path.c b/subsys/system/cmd/path.c new file mode 100644 index 0000000..39e9309 --- /dev/null +++ b/subsys/system/cmd/path.c @@ -0,0 +1,90 @@ +/* + * PATH.C - path internal command. + * + * + * History: + * + * 17 Jul 1998 (John P Price) + * Separated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 09-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 18-Jan-1999 (Eric Kohl ) + * Unicode ready! + * + * 18-Jan-1999 (Eric Kohl ) + * Redirection safe! + * + * 24-Jan-1999 (Eric Kohl ) + * Fixed Win32 environment handling. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_PATH + +#include +#include +#include +#include + +#include "cmd.h" + + +/* size of environment variable buffer */ +#define ENV_BUFFER_SIZE 1024 + + +INT cmd_path (LPTSTR cmd, LPTSTR param) +{ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or sets a search path for executable files.\n\n" + "PATH [[drive:]path[;...]]\nPATH ;\n\n" + "Type PATH ; to clear all search-path settings and direct the command shell\n" + "to search only in the current directory.\n" + "Type PATH without parameters to display the current path.\n")); + return 0; + } + + /* if param is empty, display the PATH environment variable */ + if (!param || !*param) + { + DWORD dwBuffer; + LPTSTR pszBuffer; + + pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE); + if (dwBuffer == 0) + { + ConErrPrintf ("CMD: Not in environment \"PATH\"\n"); + return 0; + } + else if (dwBuffer > ENV_BUFFER_SIZE) + { + pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE); + } + + ConOutPrintf (_T("PATH=%s\n"), pszBuffer); + free (pszBuffer); + + return 0; + } + + /* skip leading '=' */ + if (*param == _T('=')) + param++; + + /* set PATH environment variable */ + if (!SetEnvironmentVariable (_T("PATH"), param)) + return 1; + + return 0; +} + +#endif diff --git a/subsys/system/cmd/pause.c b/subsys/system/cmd/pause.c new file mode 100644 index 0000000..19e67d5 --- /dev/null +++ b/subsys/system/cmd/pause.c @@ -0,0 +1,66 @@ +/* + * PAUSE.C - pause internal command. + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Seperated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 18-Jan-1999 (Eric Kohl ) + * Unicode ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_PAUSE + +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* + * Perform PAUSE command. + * + * FREEDOS extension : If parameter is specified use that as the pause + * message. + * + * ?? Extend to include functionality of CHOICE if switch chars + * specified. + */ + +INT cmd_pause (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("cmd_pause: \'%s\' : \'%s\'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Stops the execution of a batch file and shows the following message:\n" + "\"Press any key to continue...\" or a user defined message.\n\n" + "PAUSE [message]")); + return 0; + } + + if (*param) + ConOutPrintf (param); + else + msg_pause (); + + cgetchar (); + + return 0; +} + +#endif diff --git a/subsys/system/cmd/prompt.c b/subsys/system/cmd/prompt.c new file mode 100644 index 0000000..0bfe411 --- /dev/null +++ b/subsys/system/cmd/prompt.c @@ -0,0 +1,225 @@ +/* + * PROMPT.C - prompt handling. + * + * + * History: + * + * 14/01/95 (Tim Normal) + * started. + * + * 08/08/95 (Matt Rains) + * i have cleaned up the source code. changes now bring this source + * into guidelines for recommended programming practice. + * + * 01/06/96 (Tim Norman) + * added day of the week printing (oops, forgot about that!) + * + * 08/07/96 (Steffan Kaiser) + * small changes for speed + * + * 20-Jul-1998 (John P Price ) + * removed redundant day strings. Use ones defined in date.c. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 28-Jul-1998 (John P Price ) + * moved cmd_prompt from internal.c to here + * + * 09-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 14-Dec-1998 (Eric Kohl ) + * Added "$+" option. + * + * 09-Jan-1999 (Eric Kohl ) + * Added "$A", "$C" and "$F" option. + * Added locale support. + * Fixed "$V" option. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * + * 24-Jan-1999 (Eric Kohl ) + * Fixed Win32 environment handling. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" + + +/* + * print the command-line prompt + * + */ +VOID PrintPrompt(VOID) +{ + static TCHAR default_pr[] = _T("$P$G"); + TCHAR szPrompt[256]; + LPTSTR pr; + + if (GetEnvironmentVariable (_T("PROMPT"), szPrompt, 256)) + pr = szPrompt; + else + pr = default_pr; + + while (*pr) + { + if (*pr != _T('$')) + { + ConOutChar (*pr); + } + else + { + pr++; + + switch (_totupper (*pr)) + { + case _T('A'): + ConOutChar (_T('&')); + break; + + case _T('B'): + ConOutChar (_T('|')); + break; + + case _T('C'): + ConOutChar (_T('(')); + break; + + case _T('D'): + PrintDate (); + break; + + case _T('E'): + ConOutChar (_T('\x1B')); + break; + + case _T('F'): + ConOutChar (_T(')')); + break; + + case _T('G'): + ConOutChar (_T('>')); + break; + + case _T('H'): + ConOutChar (_T('\x08')); + break; + + case _T('L'): + ConOutChar (_T('<')); + break; + + case _T('N'): + { + TCHAR szPath[MAX_PATH]; + GetCurrentDirectory (MAX_PATH, szPath); + ConOutChar (szPath[0]); + } + break; + + case _T('P'): + { + TCHAR szPath[MAX_PATH]; + GetCurrentDirectory (MAX_PATH, szPath); + ConOutPrintf (_T("%s"), szPath); + } + break; + + case _T('Q'): + ConOutChar (_T('=')); + break; + + case _T('T'): + PrintTime (); + break; + + case _T('V'): + switch (osvi.dwPlatformId) + { + case VER_PLATFORM_WIN32_WINDOWS: + if (osvi.dwMajorVersion == 4 && + osvi.dwMinorVersion == 1) + ConOutPrintf (_T("Windows 98")); + else + ConOutPrintf (_T("Windows 95")); + break; + + case VER_PLATFORM_WIN32_NT: + ConOutPrintf (_T("Windows NT Version %lu.%lu"), + osvi.dwMajorVersion, osvi.dwMinorVersion); + break; + } + break; + + case _T('_'): + ConOutChar (_T('\n')); + break; + + case '$': + ConOutChar (_T('$')); + break; + +#ifdef FEATURE_DIRECTORY_STACK + case '+': + { + INT i; + for (i = 0; i < GetDirectoryStackDepth (); i++) + ConOutChar (_T('+')); + } + break; +#endif + } + } + pr++; + } +} + + +#ifdef INCLUDE_CMD_PROMPT + +INT cmd_prompt (LPTSTR cmd, LPTSTR param) +{ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Changes the command prompt.\n\n" + "PROMPT [text]\n\n" + " text Specifies a new command prompt.\n\n" + "Prompt can be made up of normal characters and the following special codes:\n\n" + " $A & (Ampersand)\n" + " $B | (pipe)\n" + " $C ( (Left parenthesis)\n" + " $D Current date\n" + " $E Escape code (ASCII code 27)\n" + " $F ) (Right parenthesis)\n" + " $G > (greater-than sign)\n" + " $H Backspace (erases previous character)\n" + " $L < (less-than sign)\n" + " $N Current drive\n" + " $P Current drive and path\n" + " $Q = (equal sign)\n" + " $T Current time\n" + " $V OS version number\n" + " $_ Carriage return and linefeed\n" + " $$ $ (dollar sign)")); +#ifdef FEATURE_DIRECTORY_STACK + ConOutPuts (_T(" $+ Displays the current depth of the directory stack")); +#endif + ConOutPuts (_T("\nType PROMPT without parameters to reset the prompt to the default setting.")); + return 0; + } + + /* set PROMPT environment variable */ + if (!SetEnvironmentVariable (_T("PROMPT"), param)) + return 1; + + return 0; +} +#endif diff --git a/subsys/system/cmd/readme.txt b/subsys/system/cmd/readme.txt new file mode 100644 index 0000000..37bf9a9 --- /dev/null +++ b/subsys/system/cmd/readme.txt @@ -0,0 +1,69 @@ +ReactOS command line interpreter CMD version 0.1.1 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ReactOS command line interpreter CMD is derived from FreeCOM, the +FreeDOS command line interpreter. + +We are going for 4NT compatibility but try to stay compatible with +WinNT's CMD.EXE too. + + +Compiling +~~~~~~~~~ +Cmd can be built in two different versions. A full version for use under +Windows 9x or Windows NT and a reduced version for use under ReactOS. + +Note: The full version won't run on ReactOS and the reduced version is not +usable under Win 9x/NT. + +To build the full version, make sure the symbol '__REACTOS__' is NOT defined +in 'rosapps/cmd/config.h' line 13. + +To build the reduced version, make sure the symbol '__REACTOS__' is defined +in 'rosapps/cmd/config.h' line 13. + + +Current Features +~~~~~~~~~~~~~~~~ + - environment handling with prompt and path support. + - directory utilities. + - command-line history with doskey-like features. + - batch file processing. + - input/output redirection and piping. + - alias support. + - filename completion (use TAB) + (this is still incomplete) + + +Credits +~~~~~~~ +FreeDOS developers: + normat@rpi.edu (Tim Norman) + mrains@apanix.apana.org.au (Matt Rains) + ejeffrey@iastate.edu (Evan Jeffrey) + Steffen.Kaiser@Informatik.TU-Chemnitz.DE (Steffen Kaiser) + Svante Frey (sfrey@kuai.se) + Oliver Mueller (ogmueller@t-online.de) + Aaron Kaufman (morgan@remarque.berkeley.edu) + Marc Desrochers (bitzero@hotmail.com) + Rob Lake (rlake@cs.mun.ca) + John P. Price + Hans B Pufal + +ReactOS developers: + Eric Kohl + Emanuele Aliberti + Paolo Pantaleo + + +Bugs +~~~~ +Batch file handling is still untested or buggy. Please report +any bug you find. + +Please report bugs to Eric Kohl . + + +Good luck + + Eric Kohl diff --git a/subsys/system/cmd/redir.c b/subsys/system/cmd/redir.c new file mode 100644 index 0000000..801b818 --- /dev/null +++ b/subsys/system/cmd/redir.c @@ -0,0 +1,216 @@ +/* + * REDIR.C - redirection handling. + * + * + * History: + * + * 12/15/95 (Tim Norman) + * started. + * + * 12 Jul 98 (Hans B Pufal) + * Rewrote to make more efficient and to conform to new command.c + * and batch.c processing. + * + * 27-Jul-1998 (John P Price ) + * Added config.h include + * + * 22-Jan-1999 (Eric Kohl ) + * Unicode safe! + * Added new error redirection "2>" and "2>>". + * + * 26-Jan-1999 (Eric Kohl ) + * Added new error AND output redirection "&>" and "&>>". + */ + +#include "config.h" + +#ifdef FEATURE_REDIRECTION + +#include +#include +#include +#include + +#include "cmd.h" + + +static BOOL +IsRedirection (TCHAR c) +{ + return (c == _T('<')) || (c == _T('>')) || (c == _T('|')); +} + + +/* + * Gets the redirection info from the command line and copies the + * file names into ifn, ofn and efn removing them from the command + * line. + * + * Converts remaining command line into a series of null terminated + * strings defined by the pipe char '|'. Each string corresponds + * to a single executable command. A double null terminates the + * command strings. + * + * Return number of command strings found. + * + */ + +INT GetRedirection (LPTSTR s, LPTSTR ifn, LPTSTR ofn, LPTSTR efn, LPINT lpnFlags) +{ + INT num = 1; + LPTSTR dp = s; + LPTSTR sp = s; + + /* find and remove all the redirections first */ + while (*sp) + { + if ((*sp == _T('"')) || (*sp == _T('\''))) + { + /* No redirects inside quotes */ + TCHAR qc = *sp; + + do + *dp++ = *sp++; + while (*sp && *sp != qc); + + *dp++ = *sp++; + } + else if ((*sp == _T('<')) || (*sp == _T('>')) || + (*sp == _T('2')) || (*sp == _T('&'))) + { + /* MS-DOS ignores multiple redirection symbols and uses the last */ + /* redirection, so we'll emulate that and not check */ + + if (*sp == _T('<')) + { + /* input redirection */ + *lpnFlags |= INPUT_REDIRECTION; + do sp++; + while( _istspace (*sp) ); + + /* copy file name */ + while (*sp && !IsRedirection (*sp) && !_istspace (*sp)) + *ifn++ = *sp++; + *ifn = _T('\0'); + } + else if (*sp == _T('>')) + { + /* output redirection */ + *lpnFlags |= OUTPUT_REDIRECTION; + sp++; + + /* append request ? */ + if (*sp == _T('>')) + { + *lpnFlags |= OUTPUT_APPEND; + sp++; + } + + while (_istspace (*sp)) + sp++; + + /* copy file name */ + while (*sp && !IsRedirection (*sp) && !_istspace (*sp)) + *ofn++ = *sp++; + *ofn = _T('\0'); + } + else if (*sp == _T('2')) + { + /* error redirection */ + sp++; + + if (*sp == _T('>')) + { + *lpnFlags |= ERROR_REDIRECTION; + sp++; + + /* append request ? */ + if (*sp == _T('>')) + { + *lpnFlags |= ERROR_APPEND; + sp++; + } + } + else + { + /* no redirection!! copy the '2' character! */ + sp--; + *dp++ = *sp++; + continue; + } + + while (_istspace (*sp)) + sp++; + + /* copy file name */ + while (*sp && !IsRedirection (*sp) && !_istspace (*sp)) + *efn++ = *sp++; + *efn = _T('\0'); + } + else if (*sp == _T('&')) + { + /* output AND error redirection */ + sp++; + + if (*sp == _T('>')) + { + *lpnFlags |= (ERROR_REDIRECTION | OUTPUT_REDIRECTION); + sp++; + + /* append request ? */ + if (*sp == _T('>')) + { + *lpnFlags |= (ERROR_APPEND | OUTPUT_APPEND); + sp++; + } + } + else + { + /* no redirection!! copy the '&' character! */ + sp--; + *dp++ = *sp++; + continue; + } + + while (_istspace (*sp)) + sp++; + + /* copy file name */ + while (*sp && !IsRedirection (*sp) && !_istspace (*sp)) + *ofn++ = *efn++ = *sp++; + *ofn = *efn = _T('\0'); + } + } + else + *dp++ = *sp++; + } + *dp++ = _T('\0'); + *dp = _T('\0'); + + /* now go for the pipes */ + sp = s; + while (*sp) + { + if ((*sp == _T('"')) || (*sp == _T('\''))) + { + TCHAR qc = *sp; + + do + sp++; + while (*sp && *sp != qc); + + sp++; + } + else if (*sp == _T('|')) + { + *sp++ = _T('\0'); + num++; + } + else + sp++; + } + + return num; +} + +#endif /* FEATURE_REDIRECTION */ diff --git a/subsys/system/cmd/ren.c b/subsys/system/cmd/ren.c new file mode 100644 index 0000000..ef80657 --- /dev/null +++ b/subsys/system/cmd/ren.c @@ -0,0 +1,281 @@ +/* + * REN.C - rename internal command. + * + * + * History: + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 18-Dec-1998 (Eric Kohl + * Added support for quoted long file names with spaces. + * + * 20-Jan-1999 (Eric Kohl + * Unicode and redirection safe! + * + * 17-Oct-2001 (Eric Kohl + * Implemented basic rename code. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_RENAME + +#include +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + +enum +{ + REN_ATTRIBUTES = 0x001, /* /A : not implemented */ + REN_ERROR = 0x002, /* /E */ + REN_NOTHING = 0x004, /* /N */ + REN_PROMPT = 0x008, /* /P : not implemented */ + REN_QUIET = 0x010, /* /Q */ + REN_SUBDIR = 0x020, /* /S */ + REN_TOTAL = 0x040, /* /T */ +}; + + +/* + * file rename internal command. + * + */ +INT cmd_rename (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg = NULL; + INT args = 0; + INT nEvalArgs = 0; /* nunber of evaluated arguments */ + DWORD dwFlags = 0; + DWORD dwFiles = 0; /* number of renamedd files */ + INT i; + LPTSTR srcPattern = NULL; + LPTSTR dstPattern = NULL; + TCHAR dstFile[MAX_PATH]; + BOOL bDstWildcard = FALSE; + + LPTSTR p,q,r; + + HANDLE hFile; + WIN32_FIND_DATA f; + + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutPuts(_T("Renames a file/directory or files/directories.\n" + "\n" + "RENAME [/E /N /P /Q /S /T] old_name ... new_name\n" + "REN [/E /N /P /Q /S /T] old_name ... new_name\n" + "\n" + " /E No eror messages.\n" + " /N Nothing.\n" + " /P Prompts for confirmation before renaming each file.\n" + " (Not implemented yet!)\n" + " /Q Quiet.\n" + " /S Rename subdirectories.\n" + " /T Display total number of renamed files.\n" + "\n" + "Note that you cannot specify a new drive or path for your destination. Use\n" + "the MOVE command for that purpose.")); + return(0); + } + + /* split the argument list */ + arg = split(param, &args, FALSE); + + if (args < 2) + { + if (!(dwFlags & REN_ERROR)) + error_req_param_missing(); + freep(arg); + return(1); + } + + /* read options */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) + { + if (_tcslen(arg[i]) >= 2) + { + switch (_totupper(arg[i][1])) + { + case _T('E'): + dwFlags |= REN_ERROR; + break; + + case _T('N'): + dwFlags |= REN_NOTHING; + break; + + case _T('P'): + dwFlags |= REN_PROMPT; + break; + + case _T('Q'): + dwFlags |= REN_QUIET; + break; + + case _T('S'): + dwFlags |= REN_SUBDIR; + break; + + case _T('T'): + dwFlags |= REN_TOTAL; + break; + } + } + nEvalArgs++; + } + } + + /* keep quiet within batch files */ + if (bc != NULL) + dwFlags |= REN_QUIET; + + /* there are only options on the command line --> error!!! */ + if (args < nEvalArgs + 2) + { + if (!(dwFlags & REN_ERROR)) + error_req_param_missing(); + freep(arg); + return(1); + } + + /* get destination pattern */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/')) + continue; + dstPattern = arg[i]; + } + + if (_tcschr(dstPattern, _T('*')) || _tcschr(dstPattern, _T('?'))) + bDstWildcard = TRUE; + + /* enumerate source patterns */ + for (i = 0; i < args; i++) + { + if (*arg[i] == _T('/') || arg[i] == dstPattern) + continue; + + srcPattern = arg[i]; + +#ifdef _DEBUG + ConErrPrintf(_T("\n\nSourcePattern: %s\n"), srcPattern); + ConErrPrintf(_T("DestinationPattern: %s\n"), dstPattern); +#endif + + hFile = FindFirstFile(srcPattern, &f); + if (hFile == INVALID_HANDLE_VALUE) + { + if (!(dwFlags & REN_ERROR)) + error_file_not_found(); + continue; + } + + do + { + /* ignore "." and ".." */ + if (!_tcscmp (f.cFileName, _T(".")) || + !_tcscmp (f.cFileName, _T(".."))) + continue; + + /* do not rename hidden or system files */ + if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) + continue; + + /* do not rename directories when the destination pattern contains + * wildcards, unless option /S is used */ + if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + && bDstWildcard + && !(dwFlags & REN_SUBDIR)) + continue; + +#ifdef _DEBUG + ConErrPrintf(_T("Found source name: %s\n"), f.cFileName); +#endif + + /* build destination file name */ + p = f.cFileName; + q = dstPattern; + r = dstFile; + while(*q != 0) + { + if (*q == '*') + { + q++; + while (*p != 0 && *p != *q) + { + *r = *p; + p++; + r++; + } + } + else if (*q == '?') + { + q++; + if (*p != 0) + { + *r = *p; + p++; + r++; + } + } + else + { + *r = *q; + if (*p != 0) + p++; + q++; + r++; + } + } + *r = 0; + +#ifdef _DEBUG + ConErrPrintf(_T("DestinationFile: %s\n"), dstFile); +#endif + + if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL)) + ConOutPrintf(_T("%s -> %s\n"), f.cFileName, dstFile); + + /* rename the file */ + if (!(dwFlags & REN_NOTHING)) + { + if (MoveFile(f.cFileName, dstFile)) + { + dwFiles++; + } + else + { + if (!(dwFlags & REN_ERROR)) + ConErrPrintf(_T("MoveFile() failed. Error: %lu\n"), GetLastError()); + } + } + } + while (FindNextFile(hFile, &f)); + FindClose(hFile); + } + + if (!(dwFlags & REN_QUIET)) + { + if (dwFiles == 1) + ConOutPrintf(_T(" %lu file renamed\n"), + dwFiles); + else + ConOutPrintf(_T(" %lu files renamed\n"), + dwFiles); + } + + freep(arg); + + return(0); +} + +#endif + +/* EOF */ diff --git a/subsys/system/cmd/screen.c b/subsys/system/cmd/screen.c new file mode 100644 index 0000000..c27671a --- /dev/null +++ b/subsys/system/cmd/screen.c @@ -0,0 +1,111 @@ +/* + * SCREEN.C - screen internal command. + * + * clone from 4nt msgbox command + * + * 30 Aug 1999 + * started - Paolo Pantaleo + * + * + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_SCREEN + +#include +#include +#include +#include + +#include "cmd.h" + + +INT CommandScreen (LPTSTR cmd, LPTSTR param) +{ + SHORT x,y; + BOOL bSkipText = FALSE; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts(_T( + "move cursor and optionally print text\n" + "\n" + "SCREEN row col [text]\n" + "\n" + " row row to wich move the cursor\n" + " col column to wich move the cursor")); + return 0; + } + + //get row + while(_istspace(*param)) + param++; + + if(!(*param)) + { + error_req_param_missing (); + return 1; + } + + y = atoi(param); + if (y<0 || y>(maxy-1)) + { + ConOutPrintf("invalid value for row"); + return 1; + } + + //get col + if(!(param = _tcschr(param,_T(' ')))) + { + error_req_param_missing (); + return 1; + } + + while(_istspace(*param)) + param++; + + if(!(*param)) + { + error_req_param_missing (); + return 1; + } + + x = atoi(param); + if (x<0 || x>(maxx-1)) + { + ConErrPuts(_T("invalid value for col")); + return 1; + } + + //get text + if(!(param = _tcschr(param,_T(' ')))) + { + bSkipText = TRUE; + } + else + { + while(_istspace(*param)) + param++; + + if(!(*param)) + { + bSkipText = TRUE; + } + } + + bIgnoreEcho = TRUE; + + if(bSkipText) + x=0; + + + SetCursorXY(x,y); + + if(!(bSkipText)) + ConOutPuts(param); + + return 0; +} + +#endif /* INCLUDE_CMD_SCREEN */ diff --git a/subsys/system/cmd/set.c b/subsys/system/cmd/set.c new file mode 100644 index 0000000..a1c9dc7 --- /dev/null +++ b/subsys/system/cmd/set.c @@ -0,0 +1,128 @@ +/* + * SET.C - set internal command. + * + * + * History: + * + * 06/14/97 (Tim Norman) + * changed static var in set() to a malloc'd space to pass to putenv. + * need to find a better way to do this, since it seems it is wasting + * memory when variables are redefined. + * + * 07/08/1998 (John P. Price) + * removed call to show_environment in set command. + * moved test for syntax before allocating memory in set command. + * misc clean up and optimization. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 28-Jul-1998 (John P Price ) + * added set_env function to set env. variable without needing set command + * + * 09-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 24-Jan-1999 (Eric Kohl ) + * Fixed Win32 environment handling. + * Unicode and redirection safe! + * + * 25-Feb-1999 (Eric Kohl ) + * Fixed little bug. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_SET + +#include +#include +#include +#include + +#include "cmd.h" + + +/* initial size of environment variable buffer */ +#define ENV_BUFFER_SIZE 1024 + + +INT cmd_set (LPTSTR cmd, LPTSTR param) +{ + LPTSTR p; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays, sets, or removes environment variables.\n\n" + "SET [variable[=][string]]\n\n" + " variable Specifies the environment-variable name.\n" + " string Specifies a series of characters to assign to the variable.\n\n" + "Type SET without parameters to display the current environment variables.\n")); + return 0; + } + + /* if no parameters, show the environment */ + if (param[0] == _T('\0')) + { + LPTSTR lpEnv; + LPTSTR lpOutput; + INT len; + + lpEnv = (LPTSTR)GetEnvironmentStrings (); + if (lpEnv) + { + lpOutput = lpEnv; + while (*lpOutput) + { + len = _tcslen(lpOutput); + if (len) + { + if (*lpOutput != _T('=')) + ConOutPuts (lpOutput); + lpOutput += (len + 1); + } + } + FreeEnvironmentStrings (lpEnv); + } + + return 0; + } + + p = _tcschr (param, _T('=')); + if (p) + { + /* set or remove environment variable */ + *p = _T('\0'); + p++; + + SetEnvironmentVariable (param, p); + } + else + { + /* display environment variable */ + LPTSTR pszBuffer; + DWORD dwBuffer; + + pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (param, pszBuffer, ENV_BUFFER_SIZE); + if (dwBuffer == 0) + { + ConErrPrintf ("CMD: Not in environment \"%s\"\n", param); + return 0; + } + else if (dwBuffer > ENV_BUFFER_SIZE) + { + pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (param, pszBuffer, dwBuffer * sizeof (TCHAR)); + } + + ConOutPrintf ("%s\n", pszBuffer); + free (pszBuffer); + + return 0; + } + + return 0; +} + +#endif diff --git a/subsys/system/cmd/shift.c b/subsys/system/cmd/shift.c new file mode 100644 index 0000000..87ce454 --- /dev/null +++ b/subsys/system/cmd/shift.c @@ -0,0 +1,70 @@ +/* + * SHIFT.C - shift internal batch command + * + * + * History: + * + * 16 Jul 1998 (Hans B Pufal) + * started. + * + * 16 Jul 1998 (John P Price) + * Separated commands into individual files. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 07-Jan-1999 (Eric Kohl ) + * Added help text ("shift /?") and cleaned up. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + */ + +#include "config.h" + +#include +#include +#include + +#include "cmd.h" +#include "batch.h" + + +/* + * Perform the SHIFT command. + * + * Only valid inside batch files. + * + * FREEDOS extension : optional parameter DOWN to allow shifting + * parameters backwards. + */ + +INT cmd_shift (LPTSTR cmd, LPTSTR param) +{ +#ifdef _DEBUG + DebugPrintf ("cmd_shift: (\'%s\', \'%s\'\n", cmd, param); +#endif + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Changes the position of replaceable parameters in a batch file.\n\n" + "SHIFT [DOWN]")); + return 0; + } + + if (bc == NULL) + { + /* not in batch - error!! */ + return 1; + } + + if (!_tcsicmp (param, _T("down"))) + { + if (bc->shiftlevel) + bc->shiftlevel--; + } + else /* shift up */ + bc->shiftlevel++; + + return 0; +} diff --git a/subsys/system/cmd/start.c b/subsys/system/cmd/start.c new file mode 100644 index 0000000..5b465bb --- /dev/null +++ b/subsys/system/cmd/start.c @@ -0,0 +1,129 @@ +/* + * START.C - start internal command. + * + * + * History: + * + * 24-Jul-1999 (Eric Kohl ) + * Started. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_START +#include +#include +#include +#include +#include + +#include "cmd.h" + + +INT cmd_start (LPTSTR first, LPTSTR rest) +{ + TCHAR szFullName[MAX_PATH]; + BOOL bWait = FALSE; + TCHAR *param; + + if (_tcsncmp (rest, _T("/?"), 2) == 0) + { + ConOutPuts (_T("Starts a command.\n\n" + "START command \n\n" + " command Specifies the command to run.\n\n" + "At the moment all commands are started asynchronously.\n")); + + return 0; + } + + /* check for a drive change */ + if (!_tcscmp (first + 1, _T(":")) && _istalpha (*first)) + { + TCHAR szPath[MAX_PATH]; + + _tcscpy (szPath, _T("A:")); + szPath[0] = _totupper (*first); + SetCurrentDirectory (szPath); + GetCurrentDirectory (MAX_PATH, szPath); + if (szPath[0] != (TCHAR)_totupper (*first)) + ConErrPuts (INVALIDDRIVE); + + return 0; + } + if( !*rest ) + { + // FIXME: use comspec instead + rest = "cmd"; + } + /* get the PATH environment variable and parse it */ + /* search the PATH environment variable for the binary */ + param = strchr( rest, ' ' ); // skip program name to reach parameters + if( param ) + { + *param = 0; + param++; + } + if (!SearchForExecutable (rest, szFullName)) + { + error_bad_command (); + return 1; + } + /* check if this is a .BAT or .CMD file */ + if (!_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".bat")) || + !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd"))) + { +#ifdef _DEBUG + DebugPrintf ("[BATCH: %s %s]\n", szFullName, rest); +#endif + ConErrPuts (_T("No batch support at the moment!")); + } + else + { + /* exec the program */ + TCHAR szFullCmdLine [CMDLINE_LENGTH]; + PROCESS_INFORMATION prci; + STARTUPINFO stui; + +#ifdef _DEBUG + DebugPrintf ("[EXEC: %s %s]\n", szFullName, rest); +#endif + /* build command line for CreateProcess() */ + _tcscpy (szFullCmdLine, first); + if( param ) + { + _tcscat(szFullCmdLine, " " ); + _tcscat (szFullCmdLine, param); + } + + /* fill startup info */ + memset (&stui, 0, sizeof (STARTUPINFO)); + stui.cb = sizeof (STARTUPINFO); + stui.dwFlags = STARTF_USESHOWWINDOW; + stui.wShowWindow = SW_SHOWDEFAULT; + + if (CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE, + CREATE_NEW_CONSOLE, NULL, NULL, &stui, &prci)) + { + if (bWait) + { + DWORD dwExitCode; + WaitForSingleObject (prci.hProcess, INFINITE); + GetExitCodeProcess (prci.hProcess, &dwExitCode); + nErrorLevel = (INT)dwExitCode; + CloseHandle (prci.hThread); + CloseHandle (prci.hProcess); + } + } + else + { + ErrorMessage (GetLastError (), + "Error executing CreateProcess()!!\n"); + } + } + + return 0; +} + +#endif + +/* EOF */ diff --git a/subsys/system/cmd/strtoclr.c b/subsys/system/cmd/strtoclr.c new file mode 100644 index 0000000..f309623 --- /dev/null +++ b/subsys/system/cmd/strtoclr.c @@ -0,0 +1,290 @@ +/* + * STRTOCLR.C - read color (for color command and other) + * + * + * History: + * + * 07-Oct-1999 (Paolo Pantaleo) + * Started. + * + * + */ + +/*only +BOOL StringToColor(LPWORD lpColor, LPTSTR*str) +is to be called +other are internal service functions*/ + + +#include "cmd.h" + +#include +#include + + +#define _B FOREGROUND_BLUE +#define _G FOREGROUND_GREEN +#define _R FOREGROUND_RED +#define _I FOREGROUND_INTENSITY + + +/*return values for chop_blank*/ +#define CP_OK 0 +#define CP_BLANK_NOT_FOUND 1 +#define CP_END_OF_STRING 2 + +#define SC_HEX 0x0100 +#define SC_TXT 0x0200 + + + +typedef struct _CLRTABLE +{ + LPTSTR name; + WORD val; +} CLRTABLE; + + +CLRTABLE clrtable[] = +{ + {"bla" ,0 }, + {"blu" ,_B }, + {"gre" ,_G }, + {"cya" ,_B|_G }, + {"red" ,_R }, + {"mag" ,_B|_R }, + {"yel" ,_R|_G }, + {"whi" ,_R|_G|_B }, + {"gra" ,_I }, + + + {"0" ,0 }, + {"2" ,_G }, + {"3" ,_B|_G }, + {"4" ,_R }, + {"5" ,_B|_R }, + {"6" ,_R|_G }, + {"7" ,_R|_G|_B }, + + {"8" ,_I }, + {"9" ,_I|_B }, + {"10" ,_I|_G }, + {"11" ,_I|_B|_G }, + {"12" ,_I|_R }, + {"13" ,_I|_B|_R }, + {"14" ,_I|_R|_G }, + {"15" ,_I|_R|_G|_B}, + + + /* note that 1 is at the end of list + to avoid to confuse it with 10-15*/ + {"1" ,_B }, + + /*cyan synonimous*/ + {"aqu" ,_B|_G }, + /*magenta synonimous*/ + {"pur" ,_B|_R }, + + + {"" ,0}, +}; + + + +/* +move string pointer to next word (skip all spaces) +on erro retunr nonzero value +*/ +static +INT chop_blank(LPTSTR *arg_str) +{ + + LPTSTR str; + str = _tcschr(*arg_str,_T(' ')); + if(!str) + { + str = _tcschr (*arg_str, _T('\0')); + if(str != NULL) + *arg_str=str; + return CP_BLANK_NOT_FOUND; + } + + + + while(_istspace(*str)) + str++; + + if (*str == _T('\0')) + { + *arg_str=str; + return CP_END_OF_STRING; + } + + *arg_str = str; + + return CP_OK; +} + + + +/* +read a color value in hex (like win nt's cmd syntax) +if an error occurs return -1 +*/ +static +WORD hex_clr(LPTSTR str) +{ + WORD ret= (WORD)-1; + TCHAR ch; + + ch = str[1]; + + if(_istdigit(ch)) + ret = ch-_T('0'); + else + { + ch=_totupper(ch); + + if( ch >= _T('A') && ch <= _T('F') ) + ret = ch-_T('A')+10; + else + return (WORD)-1; + } + + + ch = str[0]; + + if(_istdigit(ch)) + ret |= (ch-_T('0')) << 4; + else + { + ch=_totupper(ch); + + if( ch >= _T('A') && ch <= _T('F') ) + ret |= (ch-_T('A')+10) <<4; + else + return (WORD)-1; + } + + return ret; +} + + +/* +read a color value from a string (like 4nt's syntax) +if an error occurs return -1 +*/ +static +WORD txt_clr(LPTSTR str) +{ + INT i; + + for(i=0;*(clrtable[i].name);i++) + if( _tcsnicmp(str,clrtable[i].name,_tcslen(clrtable[i].name)) == 0) + return clrtable[i].val; + + return (WORD)-1; +} + + + +/*search for x on y*/ +static +WORD str_to_color(LPTSTR* arg_str) +{ + LPTSTR str; + BOOL bBri; + + WORD tmp_clr,ret_clr; + + str = *arg_str; + + + + if(!(*str)) + return (WORD)-1; + + + /*foreground*/ + bBri = FALSE; + + if(_tcsnicmp(str,"bri",3) == 0 ) + { + bBri = TRUE; + + if(chop_blank(&str)) + return (WORD)-1; + } + + if( (tmp_clr = txt_clr(str)) == (WORD)-1 ) + { + return (WORD)-1; + } + + /*skip spaces and "on"*/ + if ( chop_blank(&str) || chop_blank(&str) ) + return (WORD)-1; + + ret_clr = tmp_clr | (bBri << 3); + + /*background*/ + bBri = FALSE; + + if(_tcsnicmp(str,"bri",3) == 0 ) + { + bBri = TRUE; + + if(chop_blank(&str)) + return (WORD)-1; + } + + + if( (tmp_clr = txt_clr(str)) == (WORD)-1 ) + return (WORD)-1; + + chop_blank(&str); + + *arg_str = str; + + return SC_HEX | ret_clr | tmp_clr << 4 | bBri << 7; +} + + + +/****main function****/ +/* +the only parameter is arg_str, a pointer to a string. +the string is modified so it will begin to first word after +color specification +(only the char* is moved, no chars in the string are modfied) + + +it returns the color in the l.o. byte, plus two flags in the +h.o. byte, they are: +SC_HEX win nt's cmd syntax (for exampl a0) +SC_TXT 4nt's syntax ( "bri gre on bla" or "10 on 0") + +if succedes also move the LPTSTR to end of +string that specify color +*/ + + +BOOL StringToColor(LPWORD lpColor, LPTSTR*str) +{ + WORD wRet; + + wRet = str_to_color (str); + if (wRet == (WORD)-1) + { + wRet=hex_clr (*str); + chop_blank (str); + if (wRet == (WORD)-1) + return FALSE; + } + + *lpColor = wRet; + + return TRUE; +} + +/* EOF */ diff --git a/subsys/system/cmd/time.c b/subsys/system/cmd/time.c new file mode 100644 index 0000000..eb2fc08 --- /dev/null +++ b/subsys/system/cmd/time.c @@ -0,0 +1,221 @@ +/* + * TIME.C - time internal command. + * + * + * History: + * + * 07/08/1998 (John P. Price) + * started. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 09-Jan-1999 (Eric Kohl ) + * Added locale support. + * + * 19-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * Added "/t" option. + * + * 04-Feb-1999 (Eric Kohl ) + * Fixed time input bug. + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_TIME + +#include +#include +#include +#include + +#include "cmd.h" + + +static BOOL ParseTime (LPTSTR s) +{ + SYSTEMTIME t; + LPTSTR p = s; + + if (!*s) + return TRUE; + + GetLocalTime (&t); + t.wHour = 0; + t.wMinute = 0; + t.wSecond = 0; + t.wMilliseconds = 0; + + // first get hour + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wHour = t.wHour * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; + + // get time separator + if (*p != cTimeSeparator) + return FALSE; + p++; + + // now get minutes + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wMinute = t.wMinute * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; + + // get time separator + if (*p != cTimeSeparator) + return FALSE; + p++; + + // now get seconds + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { + t.wSecond = t.wSecond * 10 + *p - _T('0'); + p++; + } + } + else + return FALSE; + + // get decimal separator + if (*p == cDecimalSeparator) + { + p++; + + // now get hundreths + if (_istdigit(*p)) + { + while (_istdigit(*p)) + { +// t.wMilliseconds = t.wMilliseconds * 10 + *p - _T('0'); + p++; + } +// t.wMilliseconds *= 10; + } + } + + /* special case: 12 hour format */ + if (nTimeFormat == 0) + { + if (_totupper(*s) == _T('P')) + { + t.wHour += 12; + } + + if ((_totupper(*s) == _T('A')) && (t.wHour == 12)) + { + t.wHour = 0; + } + } + + if (t.wHour > 23 || t.wMinute > 60 || t.wSecond > 60 || t.wMilliseconds > 999) + return FALSE; + + SetLocalTime (&t); + + return TRUE; +} + + +INT cmd_time (LPTSTR cmd, LPTSTR param) +{ + LPTSTR *arg; + INT argc; + INT i; + BOOL bPrompt = TRUE; + INT nTimeString = -1; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays or sets the system time.\n" + "\n" + "TIME [/T][time]\n" + "\n" + " /T display only\n" + "\n" + "Type TIME with no parameters to display the current time setting and a prompt\n" + "for a new one. Press ENTER to keep the same time.")); + return 0; + } + + /* build parameter array */ + arg = split (param, &argc, FALSE); + + /* check for options */ + for (i = 0; i < argc; i++) + { + if (_tcsicmp (arg[i], _T("/t")) == 0) + bPrompt = FALSE; + + if ((*arg[i] != _T('/')) && (nTimeString == -1)) + nTimeString = i; + } + + if (nTimeString == -1) + PrintTime (); + + if (!bPrompt) + { + freep (arg); + return 0; + } + + while (1) + { + if (nTimeString == -1) + { + TCHAR s[40]; + + ConOutPrintf (_T("Enter new time: ")); + + ConInString (s, 40); + +#ifdef _DEBUG + DebugPrintf ("\'%s\'\n", s); +#endif + + while (*s && s[_tcslen (s) - 1] < _T(' ')) + s[_tcslen(s) - 1] = _T('\0'); + + if (ParseTime (s)) + { + freep (arg); + return 0; + } + } + else + { + if (ParseTime (arg[nTimeString])) + { + freep (arg); + return 0; + } + + /* force input the next time around. */ + nTimeString = -1; + } + ConErrPuts (_T("Invalid time.")); + } + + freep (arg); + + return 0; +} + +#endif diff --git a/subsys/system/cmd/timer.c b/subsys/system/cmd/timer.c new file mode 100644 index 0000000..2df9e40 --- /dev/null +++ b/subsys/system/cmd/timer.c @@ -0,0 +1,246 @@ +/* + * TIMER.C - timer internal command. + * + * clone from 4nt timer command + * + * 20 Aug 1999 + * started - Paolo Pantaleo + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_TIMER +#include "cmd.h" + +#include +#include +#include +#include + + +#define NCS_NOT_SPECIFIED -1 +#define NCS_ON 1 +#define NCS_OFF 0 + + + +//print timer status +#define PS ConOutPrintf("Timer %d is %s: ",clk_n,cS?"ON":"OFF"); \ + PrintTime() + +//print timer value +#define PT(format) PrintElapsedTime(GetTickCount()-cT,format) + + +//current timer Time (at wich started to count) +#define cT clksT[clk_n] + +//current timer status +#define cS clksS[clk_n] + + +static VOID +PrintElapsedTime (DWORD time,INT format) +{ + + DWORD h,m,s,ms; + +#ifdef _DEBUG + DebugPrintf("PrintTime(%d,%d)",time,format); +#endif + + switch (format) + { + case 0: + ConOutPrintf("Elapsed %d msecs\n",time); + break; + + case 1: + ms = time % 1000; + time /= 1000; + s = time % 60; + time /=60; + m = time % 60; + h = time / 60; + ConOutPrintf("Elapsed %02d%c%02d%c%02d%c%02d\n", + h,cTimeSeparator, + m,cTimeSeparator, + s,cDecimalSeparator,ms/10); + break; + } +} + + +INT CommandTimer (LPTSTR cmd, LPTSTR param) +{ + // all timers are kept + static DWORD clksT[10]; + + // timers status + // set all the clocks off by default + static BOOL clksS[10]={FALSE,FALSE,FALSE,FALSE, + FALSE,FALSE,FALSE,FALSE,FALSE,FALSE}; + + // TRUE if /S in command line + BOOL bS = FALSE; + + // avoid to set clk_n more than once + BOOL bCanNSet = TRUE; + + INT NewClkStatus = NCS_NOT_SPECIFIED; + + // the clock number specified on the command line + // 1 by default + INT clk_n=1; + + // output format + INT iFormat=1; + + + // command line parsing variables + INT argc; + LPTSTR *p; + + INT i; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPrintf(_T( + "allow the use of ten stopwaches.\n" + "\n" + "TIMER [ON|OFF] [/S] [/n] [/Fn]\n" + "\n" + " ON set stopwach ON\n" + " OFF set stopwach OFF\n" + " /S Split time. Return stopwach split\n" + " time without changing its value\n" + " /n Specifiy the stopwach number.\n" + " Stopwaches avaliable are 0 to 10\n" + " If it is not specified default is 1\n" + " /Fn Format for output\n" + " n can be:\n" + " 0 milliseconds\n" + " 1 hh%cmm%css%cdd\n" + "\n"), + cTimeSeparator,cTimeSeparator,cDecimalSeparator); + + ConOutPrintf(_T( + "if none of ON, OFF or /S is specified the command\n" + "will toggle stopwach state\n" + "\n")); + return 0; + } + + + p = split (param, &argc, FALSE); + + //read options + for (i = 0; i < argc; i++) + { + //set timer on + if (!(_tcsicmp(&p[i][0],"on")) && NewClkStatus == NCS_NOT_SPECIFIED) + { + NewClkStatus = NCS_ON; + continue; + } + + //set timer off + if (!(_tcsicmp(&p[i][0],"off")) && NewClkStatus == NCS_NOT_SPECIFIED) + { + NewClkStatus = NCS_OFF; + continue; + } + + // other options + if (p[i][0] == _T('/')) + { + + // set timer number + if (_istdigit(p[i][1]) && bCanNSet) + { + clk_n = p[i][1] - _T('0'); + bCanNSet = FALSE; + continue; + } + + // set s(plit) option + if (_totupper(p[i][1]) == _T('S')) + { + bS = TRUE; + continue; + } + + // specify format + if(_totupper(p[i][1]) == _T('F')) + { + iFormat = p[i][2] - _T('0'); + continue; + } + } + } + + // do stuff (start/stop/read timer) + if(NewClkStatus == NCS_ON) + { + cT=GetTickCount(); + cS=TRUE; + PS; + freep(p); + return 0; + } + + if(bS) + { + if(cS) + { + PS; + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } + + cT=GetTickCount(); + cS=TRUE; + PS; + freep(p); + return 0; + } + + if(NewClkStatus == NCS_NOT_SPECIFIED) + { + if(cS){ + cS=FALSE; + PS; + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } + + cT=GetTickCount(); + cS=TRUE; + PS; + freep(p); + return 0; + } + + + if(NewClkStatus == NCS_OFF) + { + if(cS) + { + cS=FALSE; + PS; + PrintElapsedTime(GetTickCount()-cT, iFormat); + freep(p); + return 0; + } + PS; + freep(p); + return 0; + } + + freep(p); + return 0; +} + +#endif /* INCLUDE_CMD_TIMER */ diff --git a/subsys/system/cmd/title.c b/subsys/system/cmd/title.c new file mode 100644 index 0000000..a2a1562 --- /dev/null +++ b/subsys/system/cmd/title.c @@ -0,0 +1,42 @@ +/* + * title.c - title internal command. + * + * + * History: + * 1999-02-11 Emanuele Aliberti + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_TITLE + +#include +#include +#include + +#include "cmd.h" + + +INT cmd_title (LPTSTR cmd, LPTSTR param) +{ + /* Do nothing if no args */ + if (*param == _T('\0')) + return 0; + + /* Asking help? */ + if (!_tcsncmp(param, _T("/?"), 2)) + { + ConOutPuts (_T("Sets the window title for the command prompt window.\n" + "\n" + "TITLE [string]\n" + "\n" + " string Specifies the title for the command prompt window.")); + return 0; + } + + return SetConsoleTitle (param); +} + +#endif /* def INCLUDE_CMD_TITLE */ + +/* EOF */ diff --git a/subsys/system/cmd/todo.txt b/subsys/system/cmd/todo.txt new file mode 100644 index 0000000..c125759 --- /dev/null +++ b/subsys/system/cmd/todo.txt @@ -0,0 +1,16 @@ +Things to do +~~~~~~~~~~~~ +Fix bugs :) + +Optimize the code! For size and speed. There are numerous places +where the code is hardly optimal for either. + +Sorting in DIR command ("dir /o..."). + +^S and ^Q to pause/resume displays. + +Improve DEL, COPY and MOVE commands. + +Add wildcard support to REN. + +And many, many more... diff --git a/subsys/system/cmd/type.c b/subsys/system/cmd/type.c new file mode 100644 index 0000000..8ed6a50 --- /dev/null +++ b/subsys/system/cmd/type.c @@ -0,0 +1,111 @@ +/* + * TYPE.C - type internal command. + * + * History: + * + * 07/08/1998 (John P. Price) + * started. + * + * 07/12/98 (Rob Lake) + * Changed error messages + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 07-Jan-1999 (Eric Kohl ) + * Added support for quoted arguments (type "test file.dat"). + * Cleaned up. + * + * 19-Jan-1999 (Eric Kohl ) + * Unicode and redirection ready! + * + * 19-Jan-1999 (Paolo Pantaleo ) + * Added multiple file support (copied from y.c) + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_TYPE + +#include +#include +#include + +#include "cmd.h" + + +INT cmd_type (LPTSTR cmd, LPTSTR param) +{ + TCHAR buff[256]; + HANDLE hFile, hConsoleOut; + DWORD dwRead; + DWORD dwWritten; + BOOL bRet; + INT argc,i; + LPTSTR *argv; + LPTSTR errmsg; + + hConsoleOut=GetStdHandle (STD_OUTPUT_HANDLE); + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays the contents of text files.\n\n" + "TYPE [drive:][path]filename")); + return 0; + } + + if (!*param) + { + error_req_param_missing (); + return 1; + } + + argv = split (param, &argc, TRUE); + + for (i = 0; i < argc; i++) + { + if (_T('/') == argv[i][0]) + { + ConErrPrintf("Invalid option \"%s\"\n", argv[i] + 1); + continue; + } + hFile = CreateFile(argv[i], + GENERIC_READ, + FILE_SHARE_READ,NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL,NULL); + + if(hFile == INVALID_HANDLE_VALUE) + { + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &errmsg, + 0, + NULL); + ConErrPrintf ("%s - %s", argv[i], errmsg); + LocalFree (errmsg); + continue; + } + + do + { + bRet = ReadFile(hFile,buff,sizeof(buff),&dwRead,NULL); + + if (dwRead>0 && bRet) + WriteFile(hConsoleOut,buff,dwRead,&dwWritten,NULL); + + } while(dwRead>0 && bRet); + + CloseHandle(hFile); + } + + freep (argv); + + return 0; +} + +#endif diff --git a/subsys/system/cmd/ver.c b/subsys/system/cmd/ver.c new file mode 100644 index 0000000..333f567 --- /dev/null +++ b/subsys/system/cmd/ver.c @@ -0,0 +1,147 @@ +/* + * VER.C - ver internal command. + * + * + * History: + * + * 06/30/98 (Rob Lake) + * rewrote ver command to accept switches, now ver alone prints + * copyright notice only. + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 30-Jul-1998 (John P Price ) + * added text about where to send bug reports and get updates. + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection safe! + * + * 26-Feb-1999 (Eric Kohl ) + * New version info and some output changes. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "cmd.h" + + + +VOID ShortVersion (VOID) +{ + ConOutPuts (_T("\n" + SHELLINFO "\n" + SHELLVER "\n")); +} + + +#ifdef INCLUDE_CMD_VER + +/* + * display shell version info internal command. + * + * + */ +INT cmd_ver (LPTSTR cmd, LPTSTR param) +{ + INT i; + + if (_tcsstr (param, _T("/?")) != NULL) + { + ConOutPuts (_T("Displays shell version information\n" + "\n" + "VER [/C][/R][/W]\n" + "\n" + " /C Displays credits.\n" + " /R Displays redistribution information.\n" + " /W Displays warranty information.")); + return 0; + } + + ConOutPuts (_T("\n" + SHELLINFO "\n" + SHELLVER "\n" + "\n" + "Copyright (C) 1994-1998 Tim Norman and others.")); + ConOutPuts (_T("Copyright (C) 1998-2001 Eric Kohl and others.")); + + /* Basic copyright notice */ + if (param[0] == _T('\0')) + { + ConOutPuts (_T("\n"SHELLINFO + " comes with ABSOLUTELY NO WARRANTY; for details\n" + "type: `ver /w'. This is free software, and you are welcome to redistribute\n" + "it under certain conditions; type `ver /r' for details. Type `ver /c' for a\n" + "listing of credits.")); + } + else + { + for (i = 0; param[i]; i++) + { + /* skip spaces */ + if (param[i] == _T(' ')) + continue; + + if (param[i] == _T('/')) + { + /* is this a lone '/' ? */ + if (param[i + 1] == 0) + { + error_invalid_switch (_T(' ')); + return 1; + } + continue; + } + + if (_totupper (param[i]) == _T('W')) + { + /* Warranty notice */ + ConOutPuts (_T("\n This program is distributed in the hope that it will be useful,\n" + " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + " GNU General Public License for more details.")); + } + else if (_totupper (param[i]) == _T('R')) + { + /* Redistribution notice */ + ConOutPuts (_T("\n This program is free software; you can redistribute it and/or modify\n" + " it under the terms of the GNU General Public License as published by\n" + " the Free Software Foundation; either version 2 of the License, or\n" + " (at your option) any later version.")); + } + else if (_totupper (param[i]) == _T('C')) + { + /* Developer listing */ + ConOutPuts (_T("\n" + "FreeDOS version written by:\n" + " Tim Norman Matt Rains\n" + " Evan Jeffrey Steffen Kaiser\n" + " Svante Frey Oliver Mueller\n" + " Aaron Kaufman Marc Desrochers\n" + " Rob Lake John P Price\n" + " Hans B Pufal\n" + "\n" + "ReactOS version written by:\n" + " Eric Kohl Emanuele Aliberti\n" + " Paolo Pantaleo Phillip Susi\n")); + } + else + { + error_invalid_switch ((TCHAR)_totupper (param[i])); + return 1; + } + } + } + + ConOutPuts (_T("\n" + "Send bug reports to .\n" + "Updates are available at: http://www.reactos.com")); + return 0; +} + +#endif diff --git a/subsys/system/cmd/verify.c b/subsys/system/cmd/verify.c new file mode 100644 index 0000000..4aeaa94 --- /dev/null +++ b/subsys/system/cmd/verify.c @@ -0,0 +1,57 @@ +/* + * VERIFY.C - verify internal command. + * + * + * History: + * + * 31 Jul 1998 (John P Price) + * started. + * + * 18-Jan-1999 (Eric Kohl ) + * VERIFY is just a dummy under Win32; it only exists + * for compatibility!!! + * + * 20-Jan-1999 (Eric Kohl ) + * Unicode and redirection ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_VERIFY + +#include +#include +#include + +#include "cmd.h" + + +/* global verify flag */ +static BOOL bVerify = FALSE; + + +INT cmd_verify (LPTSTR cmd, LPTSTR param) +{ + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("This command is just a dummy!!\n" + "Sets whether to verify that your files are written correctly to a\n" + "disk.\n\n" + "VERIFY [ON | OFF]\n\n" + "Type VERIFY without a parameter to display the current VERIFY setting.")); + return 0; + } + + if (!*param) + ConOutPrintf (_T("VERIFY is %s.\n"), bVerify ? D_ON : D_OFF); + else if (_tcsicmp (param, D_OFF) == 0) + bVerify = FALSE; + else if (_tcsicmp (param, D_ON) == 0) + bVerify = TRUE; + else + ConOutPuts (_T("Must specify ON or OFF.")); + + return 0; +} + +#endif diff --git a/subsys/system/cmd/vol.c b/subsys/system/cmd/vol.c new file mode 100644 index 0000000..a37bf26 --- /dev/null +++ b/subsys/system/cmd/vol.c @@ -0,0 +1,113 @@ +/* + * VOL.C - vol internal command. + * + * + * History: + * + * 03-Dec-1998 (Eric Kohl ) + * Replaced DOS calls by Win32 calls. + * + * 08-Dec-1998 (Eric Kohl ) + * Added help text ("/?"). + * + * 07-Jan-1999 (Eric Kohl ) + * Cleanup. + * + * 18-Jan-1999 (Eric Kohl ) + * Unicode ready! + * + * 20-Jan-1999 (Eric Kohl ) + * Redirection ready! + */ + +#include "config.h" + +#ifdef INCLUDE_CMD_VOL + +#include +#include +#include + +#include "cmd.h" + + +static INT +PrintVolumeHeader (LPTSTR pszRootPath) +{ + TCHAR szVolName[80]; + DWORD dwSerialNr; + + /* get the volume information of the drive */ + if(!GetVolumeInformation (pszRootPath, + szVolName, + 80, + &dwSerialNr, + NULL, + NULL, + NULL, + 0)) + { + ErrorMessage (GetLastError (), _T("")); + return 1; + } + + /* print drive info */ + ConOutPrintf (_T(" Volume in drive %c:"), pszRootPath[0]); + + if (szVolName[0] != '\0') + ConOutPrintf (_T(" is %s\n"), + szVolName); + else + ConOutPrintf (_T(" has no label\n")); + + /* print the volume serial number */ + ConOutPrintf (_T(" Volume Serial Number is %04X-%04X\n"), + HIWORD(dwSerialNr), + LOWORD(dwSerialNr)); + return 0; +} + + +INT cmd_vol (LPTSTR cmd, LPTSTR param) +{ + TCHAR szRootPath[] = _T("A:\\"); + TCHAR szPath[MAX_PATH]; + + if (!_tcsncmp (param, _T("/?"), 2)) + { + ConOutPuts (_T("Displays the disk volume label and serial number, if they exist.\n\n" + "VOL [drive:]")); + return 0; + } + + if (param[0] == _T('\0')) + { + GetCurrentDirectory (MAX_PATH, szPath); + szRootPath[0] = szPath[0]; + } + else + { + _tcsupr (param); + if (param[1] == _T(':')) + szRootPath[0] = param[0]; + else + { + error_invalid_drive (); + return 1; + } + } + + if (!IsValidPathName (szRootPath)) + { + error_invalid_drive (); + return 1; + } + + /* print the header */ + if (!PrintVolumeHeader (szRootPath)) + return 1; + + return 0; +} + +#endif diff --git a/subsys/system/cmd/where.c b/subsys/system/cmd/where.c new file mode 100644 index 0000000..c9f2cef --- /dev/null +++ b/subsys/system/cmd/where.c @@ -0,0 +1,333 @@ +/* + * WHERE.C - file search functions. + * + * + * History: + * + * 07/15/95 (Tim Norman) + * started. + * + * 08/08/95 (Matt Rains) + * i have cleaned up the source code. changes now bring this source + * into guidelines for recommended programming practice. + * + * 12/12/95 (Steffan Kaiser & Tim Norman) + * added some patches to fix some things and make more efficient + * + * 1/6/96 (Tim Norman) + * fixed a stupid pointer mistake... + * Thanks to everyone who noticed it! + * + * 8/1/96 (Tim Norman) + * fixed a bug when getenv returns NULL + * + * 8/7/96 (Steffan Kaiser and Tim Norman) + * speed improvements and bug fixes + * + * 8/27/96 (Tim Norman) + * changed code to use pointers directly into PATH environment + * variable rather than making our own copy. This saves some memory, + * but requires we write our own function to copy pathnames out of + * the variable. + * + * 12/23/96 (Aaron Kaufman) + * Fixed a bug in get_paths() that did not point to the first PATH + * in the environment variable. + * + * 7/12/97 (Tim Norman) + * Apparently, Aaron's bugfix got lost, so I fixed it again. + * + * 16 July 1998 (John P. Price) + * Added stand alone code. + * + * 17 July 1998 (John P. Price) + * Rewrote find_which to use searchpath function + * + * 24-Jul-1998 (John P Price ) + * fixed bug where didn't check all extensions when path was specified + * + * 27-Jul-1998 (John P Price ) + * added config.h include + * + * 30-Jul-1998 (John P Price ) + * fixed so that it find_which returns NULL if filename is not + * executable (does not have .bat, .com, or .exe extention). + * Before command would to execute any file with any extension (opps!) + * + * 03-Dec-1998 (Eric Kohl ) + * Changed find_which(). + * + * 07-Dec-1998 (Eric Kohl ) + * Added ".CMD" extension. + * Replaced numeric constant by _NR_OF_EXTENSIONS. + * + * 26-Feb-1999 (Eric Kohl ) + * Replaced find_which() by SearchForExecutable(). + * Now files are searched using the right extension order. + * + * 20-Apr-1999 (Eric Kohl ) + * Some minor changes and improvements. + */ + +#include "config.h" + +#include +#include +#include + +#include "cmd.h" + + +/* initial size of environment variable buffer */ +#define ENV_BUFFER_SIZE 1024 + + +static LPTSTR ext[] = {".bat", ".cmd", ".com", ".exe"}; +static INT nExtCount = sizeof(ext) / sizeof(LPTSTR); + + +/* searches for file using path info. */ + +BOOL +SearchForExecutable (LPCTSTR pFileName, LPTSTR pFullName) +{ + TCHAR szPathBuffer[MAX_PATH]; + LPTSTR pszBuffer = NULL; + DWORD dwBuffer, len; + INT n; + LPTSTR p,s,f; + + + /* initialize full name buffer */ + *pFullName = _T('\0'); + +#ifdef _DEBUG + DebugPrintf (_T("SearchForExecutable: \'%s\'\n"), pFileName); +#endif + + if (_tcschr (pFileName, _T('\\')) != NULL) + { + LPTSTR pFilePart; +#ifdef _DEBUG + DebugPrintf (_T("Absolute or relative path is given.\n")); +#endif + + if (GetFullPathName (pFileName, + MAX_PATH, + szPathBuffer, + &pFilePart) ==0) + return FALSE; + + if(pFilePart == 0) + return FALSE; + + + if (_tcschr (pFilePart, _T('.')) != NULL) + { +#ifdef _DEBUG + DebugPrintf (_T("Filename extension!\n")); +#endif + _tcscpy (pFullName, szPathBuffer); + return TRUE; + + } + else + { +#ifdef _DEBUG + DebugPrintf (_T("No filename extension!\n")); +#endif + + p = szPathBuffer + _tcslen (szPathBuffer); + + for (n = 0; n < nExtCount; n++) + { + _tcscpy (p, ext[n]); + +#ifdef _DEBUG + DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer); +#endif + + if (IsValidFileName (szPathBuffer)) + { +#ifdef _DEBUG + DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer); +#endif + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + } + return FALSE; + } + } + + /* load environment varable PATH into buffer */ + pszBuffer = (LPTSTR)malloc (ENV_BUFFER_SIZE * sizeof(TCHAR)); + dwBuffer = GetEnvironmentVariable (_T("PATH"), pszBuffer, ENV_BUFFER_SIZE); + if (dwBuffer > ENV_BUFFER_SIZE) + { + pszBuffer = (LPTSTR)realloc (pszBuffer, dwBuffer * sizeof (TCHAR)); + GetEnvironmentVariable (_T("PATH"), pszBuffer, dwBuffer * sizeof (TCHAR)); + } + + if (!(p = _tcsrchr (pFileName, _T('.'))) || + _tcschr (p + 1, _T('\\'))) + { + /* There is no extension ==> test all the extensions. */ +#ifdef _DEBUG + DebugPrintf (_T("No filename extension!\n")); +#endif + + /* search in current directory */ + len = GetCurrentDirectory (MAX_PATH, szPathBuffer); + if (szPathBuffer[len - 1] != _T('\\')) + { + szPathBuffer[len] = _T('\\'); + szPathBuffer[len + 1] = _T('\0'); + } + _tcscat (szPathBuffer, pFileName); + + p = szPathBuffer + _tcslen (szPathBuffer); + + for (n = 0; n < nExtCount; n++) + { + _tcscpy (p, ext[n]); + +#ifdef _DEBUG + DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer); +#endif + + if (IsValidFileName (szPathBuffer)) + { +#ifdef _DEBUG + DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer); +#endif + free (pszBuffer); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + } + + /* search in PATH */ + s = pszBuffer; + while (s && *s) + { + f = _tcschr (s, _T(';')); + + if (f) + { + _tcsncpy (szPathBuffer, s, (size_t)(f-s)); + szPathBuffer[f-s] = _T('\0'); + s = f + 1; + } + else + { + _tcscpy (szPathBuffer, s); + s = NULL; + } + + len = _tcslen(szPathBuffer); + if (szPathBuffer[len - 1] != _T('\\')) + { + szPathBuffer[len] = _T('\\'); + szPathBuffer[len + 1] = _T('\0'); + } + _tcscat (szPathBuffer, pFileName); + + p = szPathBuffer + _tcslen (szPathBuffer); + + for (n = 0; n < nExtCount; n++) + { + _tcscpy (p, ext[n]); + +#ifdef _DEBUG + DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer); +#endif + + if (IsValidFileName (szPathBuffer)) + { +#ifdef _DEBUG + DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer); +#endif + free (pszBuffer); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + } + } + } + else + { + /* There is an extension and it is in the last path component, */ + /* so don't test all the extensions. */ +#ifdef _DEBUG + DebugPrintf (_T("Filename extension!\n")); +#endif + + /* search in current directory */ + len = GetCurrentDirectory (MAX_PATH, szPathBuffer); + if (szPathBuffer[len - 1] != _T('\\')) + { + szPathBuffer[len] = _T('\\'); + szPathBuffer[len + 1] = _T('\0'); + } + _tcscat (szPathBuffer, pFileName); + +#ifdef _DEBUG + DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer); +#endif + if (IsValidFileName (szPathBuffer)) + { +#ifdef _DEBUG + DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer); +#endif + free (pszBuffer); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + + + /* search in PATH */ + s = pszBuffer; + while (s && *s) + { + f = _tcschr (s, _T(';')); + + if (f) + { + _tcsncpy (szPathBuffer, s, (size_t)(f-s)); + szPathBuffer[f-s] = _T('\0'); + s = f + 1; + } + else + { + _tcscpy (szPathBuffer, s); + s = NULL; + } + + len = _tcslen(szPathBuffer); + if (szPathBuffer[len - 1] != _T('\\')) + { + szPathBuffer[len] = _T('\\'); + szPathBuffer[len + 1] = _T('\0'); + } + _tcscat (szPathBuffer, pFileName); + +#ifdef _DEBUG + DebugPrintf (_T("Testing: \'%s\'\n"), szPathBuffer); +#endif + if (IsValidFileName (szPathBuffer)) + { +#ifdef _DEBUG + DebugPrintf (_T("Found: \'%s\'\n"), szPathBuffer); +#endif + free (pszBuffer); + _tcscpy (pFullName, szPathBuffer); + return TRUE; + } + } + } + + free (pszBuffer); + + return FALSE; +} diff --git a/subsys/system/cmd/window.c b/subsys/system/cmd/window.c new file mode 100644 index 0000000..38211ab --- /dev/null +++ b/subsys/system/cmd/window.c @@ -0,0 +1,247 @@ +/* $Id$ + * + * WINDOW.C - activate & window internal commands. + * + * clone from 4nt activate command + * + * 10 Sep 1999 (Paolo Pantaleo) + * started (window command in WINDOW.c) + * + * 29 Sep 1999 (Paolo Pantaleo) + * activate and window in a single file using mainly the same code + * (nice size optimization :) + */ + + +#include "config.h" + +#if ( defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) ) + +#include "cmd.h" +#include +#include +#include +#include + + +#define A_MIN 0x01 +#define A_MAX 0x02 +#define A_RESTORE 0x04 +#define A_POS 0x08 +#define A_SIZE 0x10 +#define A_CLOSE 0x20 + + +/*service funciton to perform actions on windows + + param is a string to parse for options/actions + hWnd is the handle of window on wich perform actions + +*/ + +static +INT ServiceActivate (LPTSTR param, HWND hWnd) +{ + LPTSTR *p=0,p_tmp; + INT argc=0,i; + INT iAction=0; + LPTSTR title=0; + WINDOWPLACEMENT wp; + RECT pos; + LPTSTR tmp; + + + if(*param) + p=split(param,&argc); + + + for(i = 0; i < argc; i++) + { + p_tmp=p[i]; + if (*p_tmp == _T('/')) + p_tmp++; + + if (_tcsicmp(p_tmp,_T("min"))==0) + { + iAction |= A_MIN; + continue; + } + + if (_tcsicmp(p_tmp,_T("max"))==0) + { + iAction |= A_MAX; + continue; + } + + if (_tcsicmp(p_tmp,_T("restore"))==0) + { + iAction |= A_RESTORE; + continue; + } + + if (_tcsicmp(p_tmp,_T("close"))==0) + { + iAction |= A_CLOSE; + continue; + } + + if (_tcsnicmp(p_tmp,_T("pos"),3)==0) + { + iAction |= A_POS; + tmp = p_tmp+3; + if (*tmp == _T('=')) + tmp++; + + pos.left= _ttoi(tmp); + if(!(tmp=_tcschr(tmp,_T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } + + pos.top = _ttoi (++tmp); + if(!(tmp=_tcschr(tmp,_T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } + + pos.right = _ttoi(++tmp)+pos.left; + if(!(tmp=_tcschr(tmp,_T(',')))) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } + pos.bottom = _ttoi(++tmp) + pos.top; + continue; + } + + if (_tcsnicmp(p_tmp,_T("size"),4)==0) + { + iAction |=A_SIZE; + continue; + } + + /*none of them=window title*/ + if (title) + { + error_invalid_parameter_format(p[i]); + freep(p); + return 1; + } + + if (p_tmp[0] == _T('"')) + { + title = (p_tmp+1); + *_tcschr(p_tmp+1,_T('"'))=0; + continue; + } + title = p_tmp; + } + + if(title) + SetWindowText(hWnd,title); + + wp.length=sizeof(WINDOWPLACEMENT); + GetWindowPlacement(hWnd,&wp); + + if(iAction & A_POS) + wp.rcNormalPosition = pos; + + if(iAction & A_MIN) + wp.showCmd=SW_MINIMIZE; + + if(iAction & A_MAX) + wp.showCmd=SW_SHOWMAXIMIZED; + + /*if no actions are specified default is SW_RESTORE*/ + if( (iAction & A_RESTORE) || (!iAction) ) + wp.showCmd=SW_RESTORE; + + if(iAction & A_CLOSE) + ConErrPrintf(_T("!!!FIXME: CLOSE Not implemented!!!\n")); + + wp.length=sizeof(WINDOWPLACEMENT); + SetWindowPlacement(hWnd,&wp); + + if(p) + freep(p); + + return 0; +} + + + + +INT CommandWindow (LPTSTR cmd, LPTSTR param) +{ + HWND h; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts(_T("change console window aspect\n" + "\n" + "WINDOW [/POS[=]left,top,width,heigth]\n" + " [MIN|MAX|RESTORE] [\"title\"]\n" + "\n" + "/POS specify window placement and dimensions\n" + "MIN minimize the window\n" + "MAX maximize the window\n" + "RESTORE restore the window")); + return 0; + } + + h = GetConsoleWindow(); + Sleep(0); + return ServiceActivate(param,h); +} + + +INT CommandActivate (LPTSTR cmd, LPTSTR param) +{ + LPTSTR str; + HWND h; + + if (_tcsncmp (param, _T("/?"), 2) == 0) + { + ConOutPuts(_T("change console window aspect\n" + "\n" + "ACTIAVTE \"window\" [/POS[=]left,top,width,heigth]\n" + " [MIN|MAX|RESTORE] [\"title\"]\n" + "\n" + "window tile of window on wich perform actions\n" + "/POS specify window placement and dimensions\n" + "MIN minimize the window\n" + "MAX maximize the window\n" + "RESTORE restore the window\n" + "title new title")); + return 0; + } + + if(!(*param)) + return 1; + + str=_tcschr(param,_T(' ')); + + if (str) + { + *str=_T('\0'); + str++; + } + else + str = ""; + + h=FindWindow(NULL, param); + if (!h) + { + ConErrPuts("window not found"); + return 1; + } + + return ServiceActivate(str,h); +} + +#endif /* ( defined(INCLUDE_CMD_WINDOW) || defined(INCLUDE_CMD_ACTIVATE) ) */ diff --git a/subsys/system/cmd/wishlist.txt b/subsys/system/cmd/wishlist.txt new file mode 100644 index 0000000..fe53603 --- /dev/null +++ b/subsys/system/cmd/wishlist.txt @@ -0,0 +1,15 @@ + +Wishlist for ReactOS CMD +~~~~~~~~~~~~~~~~~~~~~~~~ + + - Exclusion wildcards: "del /r *.bak -abcd.bak" + Deletes ALL *.bak files EXCEPT abcd.bak. + + - Progress indikator on long file operations (copy/move). + Percentage at the right side of the filename. + + - [cd test directory] should change to the subdirectory "test directory". + +More ideas? + + Eric Kohl diff --git a/subsys/system/format/format.c b/subsys/system/format/format.c new file mode 100755 index 0000000..6df79a5 --- /dev/null +++ b/subsys/system/format/format.c @@ -0,0 +1,516 @@ +// Copyright (c) 1998 Mark Russinovich +// Systems Internals +// http://www.sysinternals.com +#include +#define NTOS_MODE_USER +#include +#include + +// Globals +BOOL Error = FALSE; + +// switches +BOOL QuickFormat = FALSE; +DWORD ClusterSize = 0; +BOOL CompressDrive = FALSE; +BOOL GotALabel = FALSE; +PWCHAR Label = L""; +PWCHAR Drive = NULL; +PWCHAR Format = L"FAT"; + +WCHAR RootDirectory[MAX_PATH]; +WCHAR LabelString[12]; + +// +// Size array +// +typedef struct { + WCHAR SizeString[16]; + DWORD ClusterSize; +} SIZEDEFINITION, *PSIZEDEFINITION; + +SIZEDEFINITION LegalSizes[] = { + { L"512", 512 }, + { L"1024", 1024 }, + { L"2048", 2048 }, + { L"4096", 4096 }, + { L"8192", 8192 }, + { L"16K", 16384 }, + { L"32K", 32768 }, + { L"64K", 65536 }, + { L"128K", 65536 * 2 }, + { L"256K", 65536 * 4 }, + { L"", 0 }, +}; + + +//---------------------------------------------------------------------- +// +// PrintWin32Error +// +// Takes the win32 error code and prints the text version. +// +//---------------------------------------------------------------------- +void PrintWin32Error( PWCHAR Message, DWORD ErrorCode ) +{ + LPVOID lpMsgBuf; + + FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, ErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (PWCHAR) &lpMsgBuf, 0, NULL ); + printf("%S: %S\n", Message, lpMsgBuf ); + LocalFree( lpMsgBuf ); +} + + +//---------------------------------------------------------------------- +// +// Usage +// +// Tell the user how to use the program +// +//---------------------------------------------------------------------- +VOID Usage( PWCHAR ProgramName ) +{ + printf("Usage: %S drive: [-FS:file-system] [-V:label] [-Q] [-A:size] [-C]\n\n", ProgramName); + printf(" [drive:] Specifies the drive to format.\n"); + printf(" -FS:file-system Specifies the type of file system (e.g. FAT).\n"); + printf(" -V:label Specifies volume label.\n"); + printf(" -Q Performs a quick format.\n"); + printf(" -A:size Overrides the default allocation unit size. Default settings\n"); + printf(" are strongly recommended for general use\n"); + printf(" NTFS supports 512, 1024, 2048, 4096, 8192, 16K, 32K, 64K.\n"); + printf(" FAT supports 8192, 16K, 32K, 64K, 128K, 256K.\n"); + printf(" NTFS compression is not supported for allocation unit sizes\n"); + printf(" above 4096.\n"); + printf(" -C Files created on the new volume will be compressed by\n"); + printf(" default.\n"); + printf("\n"); +} + + +//---------------------------------------------------------------------- +// +// ParseCommandLine +// +// Get the switches. +// +//---------------------------------------------------------------------- +int ParseCommandLine( int argc, WCHAR *argv[] ) +{ + int i, j; + BOOLEAN gotFormat = FALSE; + BOOLEAN gotQuick = FALSE; + BOOLEAN gotSize = FALSE; + BOOLEAN gotLabel = FALSE; + BOOLEAN gotCompressed = FALSE; + + + for( i = 1; i < argc; i++ ) { + + switch( argv[i][0] ) { + + case '-': + case '/': + + if( !wcsnicmp( &argv[i][1], L"FS:", 3 )) { + + if( gotFormat) return -1; + Format = &argv[i][4]; + gotFormat = TRUE; + + + } else if( !wcsnicmp( &argv[i][1], L"A:", 2 )) { + + if( gotSize ) return -1; + j = 0; + while( LegalSizes[j].ClusterSize && + wcsicmp( LegalSizes[j].SizeString, &argv[i][3] )) j++; + + if( !LegalSizes[j].ClusterSize ) return i; + ClusterSize = LegalSizes[j].ClusterSize; + gotSize = TRUE; + + } else if( !wcsnicmp( &argv[i][1], L"V:", 2 )) { + + if( gotLabel ) return -1; + Label = &argv[i][3]; + gotLabel = TRUE; + GotALabel = TRUE; + + } else if( !wcsicmp( &argv[i][1], L"Q" )) { + + if( gotQuick ) return -1; + QuickFormat = TRUE; + gotQuick = TRUE; + + } else if( !wcsicmp( &argv[i][1], L"C" )) { + + if( gotCompressed ) return -1; + CompressDrive = TRUE; + gotCompressed = TRUE; + + } else return i; + break; + + default: + + if( Drive ) return i; + if( argv[i][1] != L':' ) return i; + + Drive = argv[i]; + break; + } + } + return 0; +} + +//---------------------------------------------------------------------- +// +// FormatExCallback +// +// The file system library will call us back with commands that we +// can interpret. If we wanted to halt the chkdsk we could return FALSE. +// +//---------------------------------------------------------------------- +BOOL __stdcall FormatExCallback( CALLBACKCOMMAND Command, DWORD Modifier, PVOID Argument ) +{ + PDWORD percent; + PTEXTOUTPUT output; + PBOOLEAN status; + static createStructures = FALSE; + + // + // We get other types of commands, but we don't have to pay attention to them + // + switch( Command ) { + + case PROGRESS: + percent = (PDWORD) Argument; + printf("%d percent completed.\r", *percent); + break; + + case OUTPUT: + output = (PTEXTOUTPUT) Argument; + fprintf(stdout, "%s", output->Output); + break; + + case DONE: + status = (PBOOLEAN) Argument; + if( *status == FALSE ) { + + printf("FormatEx was unable to complete successfully.\n\n"); + Error = TRUE; + } + break; + } + return TRUE; +} + + +//---------------------------------------------------------------------- +// +// LoadFMIFSEntryPoints +// +// Loads FMIFS.DLL and locates the entry point(s) we are going to use +// +//---------------------------------------------------------------------- +BOOLEAN LoadFMIFSEntryPoints() +{ + LoadLibrary( "fmifs.dll" ); + if( !(void*) GetProcAddress( GetModuleHandle( "fmifs.dll"), "FormatEx" ) ) { + + return FALSE; + } + + if( !((void *) GetProcAddress( GetModuleHandle( "fmifs.dll"), + "EnableVolumeCompression" )) ) { + + return FALSE; + } + return TRUE; +} + +//---------------------------------------------------------------------- +// +// WMain +// +// Engine. Just get command line switches and fire off a format. This +// could also be done in a GUI like Explorer does when you select a +// drive and run a check on it. +// +// We do this in UNICODE because the chkdsk command expects PWCHAR +// arguments. +// +//---------------------------------------------------------------------- +int wmain( int argc, WCHAR *argv[] ) +{ + int badArg; + DWORD media; + DWORD driveType; + WCHAR fileSystem[1024]; + WCHAR volumeName[1024]; + WCHAR input[1024]; + DWORD serialNumber; + DWORD flags, maxComponent; + ULARGE_INTEGER freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes; + + // + // Get function pointers + // + if( !LoadFMIFSEntryPoints()) { + + printf("Could not located FMIFS entry points.\n\n"); + return -1; + } + + // + // Parse command line + // + if( (badArg = ParseCommandLine( argc, argv ))) { + + printf("Unknown argument: %S\n", argv[badArg] ); + + Usage(argv[0]); + return -1; + } + + // + // Get the drive's format + // + if( !Drive ) { + + printf("Required drive parameter is missing.\n\n"); + Usage( argv[0] ); + return -1; + + } else { + + wcscpy( RootDirectory, Drive ); + } + RootDirectory[2] = L'\\'; + RootDirectory[3] = (WCHAR) 0; + + // + // See if the drive is removable or not + // + driveType = GetDriveTypeW( RootDirectory ); + + if( driveType == 0 ) { + PrintWin32Error( L"Could not get drive type", GetLastError()); + return -1; + } + + if( driveType != DRIVE_FIXED ) { + + printf("Insert a new floppy in drive %C:\nand press Enter when ready...", + RootDirectory[0] ); + fgetws( input, sizeof(input)/2, stdin ); + + media = FMIFS_FLOPPY; + + +driveType = DRIVE_FIXED; +media = FMIFS_HARDDISK; + + + } + + // + // Determine the drive's file system format + // + if( !GetVolumeInformationW( RootDirectory, + volumeName, sizeof(volumeName)/2, + &serialNumber, &maxComponent, &flags, + fileSystem, sizeof(fileSystem)/2)) { + + PrintWin32Error( L"Could not query volume", GetLastError()); + return -1; + } + + if( !GetDiskFreeSpaceExW( RootDirectory, + &freeBytesAvailableToCaller, + &totalNumberOfBytes, + &totalNumberOfFreeBytes )) { + + PrintWin32Error( L"Could not query volume size", GetLastError()); + return -1; + } + printf("The type of the file system is %S.\n", fileSystem ); + + // + // Make sure they want to do this + // + if( driveType == DRIVE_FIXED ) { + + if( volumeName[0] ) { + + while(1 ) { + + printf("Enter current volume label for drive %C: ", RootDirectory[0] ); + fgetws( input, sizeof(input)/2, stdin ); + input[ wcslen( input ) - 1] = 0; + + if( !wcsicmp( input, volumeName )) { + + break; + } + printf("An incorrect volume label was entered for this drive.\n"); + } + } + + while( 1 ) { + + printf("\nWARNING, ALL DATA ON NON_REMOVABLE DISK\n"); + printf("DRIVE %C: WILL BE LOST!\n", RootDirectory[0] ); + printf("Proceed with Format (Y/N)? " ); + fgetws( input, sizeof(input)/2, stdin ); + + if( input[0] == L'Y' || input[0] == L'y' ) break; + + if( input[0] == L'N' || input[0] == L'n' ) { + + printf("\n"); + return 0; + } + } + media = FMIFS_HARDDISK; + } + + // + // Tell the user we're doing a long format if appropriate + // + if( !QuickFormat ) { + + if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) { + + printf("Verifying %dM\n", (DWORD) (totalNumberOfBytes.QuadPart/(1024*1024))); + + } else { + + printf("Verifying %.1fM\n", + ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); + } + } else { + + if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) { + + printf("QuickFormatting %dM\n", (DWORD) (totalNumberOfBytes.QuadPart/(1024*1024))); + + } else { + + printf("QuickFormatting %.2fM\n", + ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); + } + printf("Creating file system structures.\n"); + } + + // + // Format away! + // + FormatEx( RootDirectory, media, Format, Label, QuickFormat, + ClusterSize, FormatExCallback ); + if( Error ) return -1; + printf("Format complete.\n"); + + // + // Enable compression if desired + // + if( CompressDrive ) { + + if( !EnableVolumeCompression( RootDirectory, TRUE )) { + + printf("Volume does not support compression.\n"); + } + } + + // + // Get the label if we don't have it + // + if( !GotALabel ) { + + printf("Volume Label (11 characters, Enter for none)? " ); + fgetws( input, sizeof(LabelString)/2, stdin ); + + input[ wcslen(input)-1] = 0; + if( !SetVolumeLabelW( RootDirectory, input )) { + + PrintWin32Error(L"Could not label volume", GetLastError()); + return -1; + } + } + + if( !GetVolumeInformationW( RootDirectory, + volumeName, sizeof(volumeName)/2, + &serialNumber, &maxComponent, &flags, + fileSystem, sizeof(fileSystem)/2)) { + + PrintWin32Error( L"Could not query volume", GetLastError()); + return -1; + } + + // + // Print out some stuff including the formatted size + // + if( !GetDiskFreeSpaceExW( RootDirectory, + &freeBytesAvailableToCaller, + &totalNumberOfBytes, + &totalNumberOfFreeBytes )) { + + PrintWin32Error( L"Could not query volume size", GetLastError()); + return -1; + } + + printf("\n%I64d bytes total disk space.\n", totalNumberOfBytes.QuadPart ); + printf("%I64d bytes available on disk.\n", totalNumberOfFreeBytes.QuadPart ); + + // + // Get the drive's serial number + // + if( !GetVolumeInformationW( RootDirectory, + volumeName, sizeof(volumeName)/2, + &serialNumber, &maxComponent, &flags, + fileSystem, sizeof(fileSystem)/2)) { + + PrintWin32Error( L"Could not query volume", GetLastError()); + return -1; + } + printf("\nVolume Serial Number is %04X-%04X\n", serialNumber >> 16, + serialNumber & 0xFFFF ); + + return 0; +} + +int main(int argc, char* argv[]) +{ + UNICODE_STRING warg; + ANSI_STRING arg; + NTSTATUS status; + PWCHAR *wargv; + int i; + + wargv = (PWCHAR *) RtlAllocateHeap(RtlGetProcessHeap(), 0, argc * sizeof(PWCHAR)); + + for (i = 0; i < argc; i++) + { + RtlInitAnsiString(&arg, argv[i]); + status = RtlAnsiStringToUnicodeString(&warg, &arg, TRUE); + if (!NT_SUCCESS (status)) + { + printf("Not enough free memory.\n"); + return 1; + } + wargv[i] = (PWCHAR) warg.Buffer; + } + + wmain(argc, wargv); + + for (i = 0; i < argc; i++) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, wargv[i]); + } + RtlFreeHeap(RtlGetProcessHeap(), 0, wargv); + + return 0; +} diff --git a/subsys/system/format/makefile b/subsys/system/format/makefile new file mode 100755 index 0000000..fd7599d --- /dev/null +++ b/subsys/system/format/makefile @@ -0,0 +1,20 @@ +# $Id$ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_SDKLIBS = ntdll.a fmifs.a + +TARGET_NAME = format + +TARGET_OBJECTS = \ + $(TARGET_NAME).o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/subsys/system/shell/.cvsignore b/subsys/system/shell/.cvsignore deleted file mode 100644 index 40e130e..0000000 --- a/subsys/system/shell/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -shell.coff -shell.exe -shell.nostrip.exe -*.d -*.o -*.sym diff --git a/subsys/system/shell/makefile b/subsys/system/shell/makefile deleted file mode 100644 index 5723fc4..0000000 --- a/subsys/system/shell/makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $Id$ - -PATH_TO_TOP = ../../.. - -TARGET_TYPE = program - -TARGET_APPTYPE = console - -TARGET_NAME = shell - -TARGET_INSTALLDIR = system32 - -TARGET_SDKLIBS = ntdll.a kernel32.a - -TARGET_OBJECTS = $(TARGET_NAME).o - -include $(PATH_TO_TOP)/rules.mak - -include $(TOOLS_PATH)/helper.mk - -# EOF diff --git a/subsys/system/shell/shell.c b/subsys/system/shell/shell.c deleted file mode 100644 index 26dd9e1..0000000 --- a/subsys/system/shell/shell.c +++ /dev/null @@ -1,504 +0,0 @@ -/* $Id$ - * - * PROJECT : ReactOS Operating System - * DESCRIPTION: ReactOS' Native Shell - * LICENSE : See top level directory - * - */ -#define NTOS_MODE_USER -#include -#include -#include -#include -#include -#include -#include - - -HANDLE InputHandle, OutputHandle; -BOOL bCanExit = TRUE, bCanLinespace = TRUE; - - -void debug_printf(char* fmt, ...) -{ - va_list args; - char buffer[512]; - DWORD nbChar; - - va_start(args,fmt); - _vsnprintf(buffer,512,fmt,args); - va_end(args); - WriteConsoleA(OutputHandle, buffer, strlen(buffer), &nbChar, NULL); -} - -void ExecuteCls(void) -{ - DWORD dwWritten; - CONSOLE_SCREEN_BUFFER_INFO csbi; - COORD coPos; - - GetConsoleScreenBufferInfo (OutputHandle, &csbi); - - coPos.X = 0; - coPos.Y = 0; - FillConsoleOutputAttribute (OutputHandle, csbi.wAttributes, (csbi.dwSize.X)*(csbi.dwSize.Y), coPos, &dwWritten); - FillConsoleOutputCharacter (OutputHandle, _T(' '), (csbi.dwSize.X)*(csbi.dwSize.Y), coPos, &dwWritten); - SetConsoleCursorPosition (OutputHandle, coPos); -} - -void ExecuteVer(void) -{ - debug_printf( - "Reactos Simple Shell\n(compiled on %s, at %s)\n", - __DATE__, - __TIME__ - ); -} - -void ExecuteCd(char* cmdline) -{ - if (!SetCurrentDirectoryA(cmdline)) - { - debug_printf("Invalid directory\n"); - } -} - -void ExecuteMd (char *cmdline) -{ - if (!CreateDirectoryA (cmdline, NULL)) - { - debug_printf("Create Directory failed!\n"); - } -} - -void ExecuteDir(char* cmdline) -{ - HANDLE shandle; - WIN32_FIND_DATA FindData; - int nFile=0, nRep=0; - FILETIME fTime; - SYSTEMTIME sTime; - - shandle = FindFirstFile("*",&FindData); - - if (shandle==INVALID_HANDLE_VALUE) - { - debug_printf("File not found\n"); - return; - } - do - { - debug_printf("%-15.15s",FindData.cAlternateFileName); - if(FindData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) - debug_printf(" "),nRep++; - else - debug_printf(" %10d ",FindData.nFileSizeLow),nFile++; - - FileTimeToLocalFileTime(&FindData.ftLastWriteTime ,&fTime); - FileTimeToSystemTime(&fTime, &sTime); - debug_printf("%02d/%02d/%04d %02d:%02d:%02d " - ,sTime.wMonth,sTime.wDay,sTime.wYear - ,sTime.wHour,sTime.wMinute,sTime.wSecond); - - debug_printf("%s\n",FindData.cFileName); - } while(FindNextFile(shandle,&FindData)); - debug_printf("\n %d files\n %d directories\n",nFile,nRep); - FindClose(shandle); -} - - -void ExecuteReboot(char* cmdline) -{ - NtShutdownSystem (ShutdownReboot); -} - - -void ExecuteShutdown(char* cmdline) -{ - NtShutdownSystem (ShutdownNoReboot); -} - - -void ExecuteType(char* cmdline) -{ - HANDLE FileHandle; - char c; - DWORD Result; - BOOL Success; - - FileHandle = CreateFile(cmdline, - FILE_GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (FileHandle == NULL) - { - debug_printf("Unknown file\n"); - return; - } - do - { - Success = ReadFile(FileHandle, - &c, - 1, - &Result, - NULL); - if (Success) - { - debug_printf("%c",c); - c = 0; - } - } while (Success && Result > 0); - CloseHandle(FileHandle); -} - -int ExecuteProcess(char* name, char* cmdline, BOOL detached) -{ - PROCESS_INFORMATION ProcessInformation; - STARTUPINFO StartupInfo; - BOOL ret; - CHAR fullname[260]; - PCHAR p; - - /* append '.exe' if needed */ - strcpy (fullname, name); - p = strrchr (fullname, '.'); - if ((p == NULL) || - (_stricmp (p, ".exe") != 0)) - { - strcat (fullname, ".exe"); - } - - memset(&StartupInfo, 0, sizeof(StartupInfo)); - StartupInfo.cb = sizeof (STARTUPINFO); - StartupInfo.lpTitle = name; - if( cmdline && *cmdline ) - *(cmdline-1) = ' '; // fix command line so it is the FULL command, including exe name - ret = CreateProcessA(fullname, - name, - NULL, - NULL, - FALSE, - ((TRUE == detached) - ? CREATE_NEW_CONSOLE - : 0 - ), - NULL, - NULL, - & StartupInfo, - & ProcessInformation - ); - if (TRUE == detached) - { - if (ret) - { - debug_printf("\"%s\" detached:\n" - "\thProcess = %08X\n" - "\thThread = %08X\n" - "\tPID = %d\n" - "\tTID = %d\n\n", - fullname, - ProcessInformation.hProcess, - ProcessInformation.hThread, - ProcessInformation.dwProcessId, - ProcessInformation.dwThreadId); - CloseHandle(ProcessInformation.hProcess); - CloseHandle(ProcessInformation.hThread); - } - else - { - debug_printf("Could not detach %s\n", name); - } - } - else - { - if (ret) - { -// debug_printf("ProcessInformation.hThread %x\n", -// ProcessInformation.hThread); - WaitForSingleObject(ProcessInformation.hProcess, INFINITE); - CloseHandle(ProcessInformation.hProcess); -// debug_printf("Thandle %x\n", ProcessInformation.hThread); - CloseHandle(ProcessInformation.hThread); - } - } - return(ret); -} - -void ExecuteStart(char* CommandLine) -{ - char *ImageName = CommandLine; - - for ( ; - ( (*CommandLine) - && (*CommandLine != ' ') - && (*CommandLine != '\t') - ); - CommandLine++ - ); - *CommandLine++ = '\0'; - while ( (*CommandLine) - && ( (*CommandLine == ' ') - || (*CommandLine == '\t') - ) - ); - ExecuteProcess( - ImageName, - CommandLine, - TRUE - ); - return; -} - -void -ExecuteKill(char * lpPid) -{ - HANDLE hProcess; - DWORD dwProcessId; - - dwProcessId = (DWORD) atol(lpPid); - debug_printf("Killing PID %d...\n",dwProcessId); - hProcess = OpenProcess( - PROCESS_TERMINATE, - FALSE, - dwProcessId - ); - if (NULL == hProcess) - { - debug_printf( - "Could not open the process with PID = %d\n", - dwProcessId - ); - return; - } - if (FALSE == TerminateProcess( - hProcess, - 0 - ) - ) { - debug_printf( - "Could not terminate the process with PID = %d\n", - dwProcessId - ); - } - CloseHandle(hProcess); - return; -} - -void ExecuteHelp (void * dummy) -{ - debug_printf ( - "A:\t\t\tCurrent drive is A:\n" - "C:\t\t\tCurrent drive is C:\n" - "cd [directory]\t\tChange current directory\n" - "dir [directory]\t\tList directory\n" - "exit\t\t\tTerminate the shell\n" - "help\t\t\tPrint this help message\n" - "kill [pid]\t\tKill process which PID is pid\n" - "md [directory]\t\tCreate a new directory\n" - "reboot\t\t\tRestart the system\n" - "start [program.exe]\tDetach program.exe\n" - "type [file]\t\tPrint the file on console\n" - "validate\t\tValidate the process' heap\n" - "ver\t\t\tPrint version information\n" - "[program.exe]\t\tStart synchronously program.exe\n" - ); -} - -void ExecuteCommand(char* line) -{ - char* cmd; - char* tail; - - if (isalpha(line[0]) && line[1] == ':' && line[2] == 0) - { - char szPath[MAX_PATH]; - char szVar[5]; - - /* save curent directory in environment variable */ - GetCurrentDirectory (MAX_PATH, szPath); - - strcpy (szVar, "=A:"); - szVar[1] = toupper (szPath[0]); - SetEnvironmentVariable (szVar, szPath); - - /* check for current directory of new drive */ - strcpy (szVar, "=A:"); - szVar[1] = toupper (line[0]); - if (GetEnvironmentVariable (szVar, szPath, MAX_PATH) == 0) - { - /* no environment variable found */ - strcpy (szPath, "A:\\"); - szPath[0] = toupper (line[0]); - } - - /* set new current directory */ - SetCurrentDirectory (szPath); - GetCurrentDirectory (MAX_PATH, szPath); - if (szPath[0] != (char)toupper (line[0])) - debug_printf("Invalid drive\n"); - - return; - } - - tail = line; - while ((*tail)!=' ' && (*tail)!=0) - { - tail++; - } - if ((*tail)==' ') - { - *tail = 0; - tail++; - } - cmd = line; - - - if (cmd==NULL || *cmd == '\0' ) - { - return; - } - if (strcmp(cmd,"cd")==0) - { - ExecuteCd(tail); - return; - } - if (strcmp(cmd,"dir")==0) - { - ExecuteDir(tail); - return; - } - if (strcmp(cmd,"kill")==0) - { - ExecuteKill(tail); - return; - } - if (strcmp(cmd,"md")==0) - { - ExecuteMd(tail); - return; - } - if (strcmp(cmd,"reboot")==0) - { - ExecuteReboot(tail); - return; - } - if (strcmp(cmd,"shutdown")==0) - { - ExecuteShutdown(tail); - return; - } - if (strcmp(cmd,"type")==0) - { - ExecuteType(tail); - return; - } - if (strcmp(cmd,"ver")==0) - { - ExecuteVer(); - return; - } - if (strcmp(cmd,"validate")==0) - { - debug_printf("Validating heap..."); - if (HeapValidate(GetProcessHeap(),0,NULL)) - { - debug_printf("succeeded\n"); - } - else - { - debug_printf("failed\n"); - } - return; - } - if (strcmp(cmd,"start") == 0) - { - ExecuteStart(tail); - return; - } - if ((strcmp(cmd,"help") * strcmp(cmd,"?")) == 0) - { - ExecuteHelp(tail); - return; - } - if (strcmp(cmd,"exit")==0) - { - if (bCanExit == TRUE) - { - ExitProcess(0); - } - return; - } - if (strcmp(cmd,"cls") == 0) - { - ExecuteCls(); - bCanLinespace = FALSE; - return; - } - if (ExecuteProcess(cmd,tail,FALSE)) - { - return; - } - debug_printf("Unknown command '%s'\n", cmd); -} - -void ReadLine(char* line) -{ - DWORD Result; - UCHAR CurrentDir[255]; - - GetCurrentDirectoryA(255,CurrentDir); - debug_printf("%s>", CurrentDir); - if ( !ReadConsoleA(InputHandle, line, 252, &Result, NULL) ) - { - debug_printf("Failed to read from console\n"); - for(;;); - } - // If the \n is in there, so is the \r so null it, otherwise, null the last char - if( line[Result-1] == '\n' ) - line[Result-2] = 0; - else { - line[Result] = 0; - } -} - -void ParseCommandLine (void) -{ - char *pszCommandLine; - - pszCommandLine = GetCommandLineA (); - _strupr (pszCommandLine); - if (strstr (pszCommandLine, "/P") != NULL) - { - debug_printf("Permanent shell\n"); - bCanExit = FALSE; - } -} - -int main(void) -{ - static char line[256]; - - AllocConsole(); - InputHandle = GetStdHandle(STD_INPUT_HANDLE); - OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE); - - ParseCommandLine (); - - for(;;) - { - ReadLine(line); - ExecuteCommand(line); - if(bCanLinespace) - { - printf("\n"); - } else - bCanLinespace = TRUE; - } - - return 0; -} - -/* EOF */ diff --git a/subsys/system/shell/shell.rc b/subsys/system/shell/shell.rc deleted file mode 100644 index 4272d05..0000000 --- a/subsys/system/shell/shell.rc +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -VS_VERSION_INFO VERSIONINFO - FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD - PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", RES_STR_COMPANY_NAME - VALUE "FileDescription", "ReactOS Simple Shell\0" - VALUE "FileVersion", RES_STR_FILE_VERSION - VALUE "InternalName", "shell\0" - VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT - VALUE "OriginalFilename", "shell.exe\0" - VALUE "ProductName", RES_STR_PRODUCT_NAME - VALUE "ProductVersion", RES_STR_PRODUCT_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - diff --git a/subsys/system/usetup/bootsup.c b/subsys/system/usetup/bootsup.c index 77edba3..c9af78c 100644 --- a/subsys/system/usetup/bootsup.c +++ b/subsys/system/usetup/bootsup.c @@ -828,8 +828,8 @@ CHECKPOINT1; 87); /* FAT32 BPB length */ /* Disable the backup boot sector */ - NewBootSector[0x32] = 0xFF; - NewBootSector[0x33] = 0xFF; + NewBootSector[0x32] = 0x00; + NewBootSector[0x33] = 0x00; /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -922,6 +922,165 @@ CHECKPOINT1; NTSTATUS +InstallMBRBootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + UNICODE_STRING Name; + HANDLE FileHandle; + NTSTATUS Status; + PUCHAR OrigBootSector; + PUCHAR NewBootSector; + + /* Allocate buffer for original bootsector */ + OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (OrigBootSector == NULL) + return(STATUS_INSUFFICIENT_RESOURCES); + + /* Read current boot sector into buffer */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + OrigBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(Status); + } + + + /* Allocate buffer for new bootsector */ + NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); + if (NewBootSector == NULL) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read new bootsector from SrcPath */ + RtlInitUnicodeString(&Name, + SrcPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_ALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + /* Copy partition table from old MBR to new */ + memcpy((NewBootSector + 446), (OrigBootSector + 446), 4*16 /* Length of partition table */); + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write new bootsector to RootPath */ + RtlInitUnicodeString(&Name, + RootPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + FILE_WRITE_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return(Status); + } + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + + /* Free the new boot sector */ + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + + return(Status); +} + + +NTSTATUS InstallFat16BootCodeToDisk(PWSTR SrcPath, PWSTR RootPath) { @@ -1199,7 +1358,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath, 87); /* FAT32 BPB length */ /* Get the location of the backup boot sector */ - BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x33]; + BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32]; /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1247,7 +1406,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath, } /* Write backup boot sector */ - if (BackupBootSector != 0xFFFF) + if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) { FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); Status = NtWriteFile(FileHandle, diff --git a/subsys/system/usetup/bootsup.h b/subsys/system/usetup/bootsup.h index 2bf1180..db5a355 100644 --- a/subsys/system/usetup/bootsup.h +++ b/subsys/system/usetup/bootsup.h @@ -54,6 +54,10 @@ InstallFat32BootCodeToFile(PWSTR SrcPath, PWSTR RootPath); NTSTATUS +InstallMBRBootCodeToDisk(PWSTR SrcPath, + PWSTR RootPath); + +NTSTATUS InstallFat16BootCodeToDisk(PWSTR SrcPath, PWSTR RootPath); diff --git a/subsys/system/usetup/console.c b/subsys/system/usetup/console.c index 912f8be..11ff663 100644 --- a/subsys/system/usetup/console.c +++ b/subsys/system/usetup/console.c @@ -346,10 +346,10 @@ WriteConsoleOutputCharacters(LPCSTR lpCharacter, NULL, &IoStatusBlock, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - NULL, - 0, Buffer, - nLength + sizeof(COORD)); + nLength + sizeof(COORD), + NULL, + 0); if (Status == STATUS_PENDING) { NtWaitForSingleObject(StdOutput, @@ -397,10 +397,10 @@ WriteConsoleOutputCharactersW(LPCWSTR lpCharacter, NULL, &IoStatusBlock, IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER, - NULL, - 0, Buffer, - nLength + sizeof(COORD)); + nLength + sizeof(COORD), + NULL, + 0); if (Status == STATUS_PENDING) { NtWaitForSingleObject(StdOutput, @@ -444,10 +444,10 @@ WriteConsoleOutputAttributes(CONST USHORT *lpAttribute, NULL, &IoStatusBlock, IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE, - NULL, - 0, Buffer, - nLength * sizeof(USHORT) + sizeof(COORD)); + nLength * sizeof(USHORT) + sizeof(COORD), + NULL, + 0); if (Status == STATUS_PENDING) { NtWaitForSingleObject(StdOutput, @@ -904,11 +904,17 @@ ClearScreen(VOID) VOID -SetStatusText(PCHAR Text) +SetStatusText(char* fmt, ...) { + char Buffer[128]; + va_list ap; COORD coPos; ULONG Written; + va_start(ap, fmt); + vsprintf(Buffer, fmt, ap); + va_end(ap); + coPos.X = 0; coPos.Y = yScreen - 1; @@ -922,8 +928,8 @@ SetStatusText(PCHAR Text) coPos, &Written); - WriteConsoleOutputCharacters(Text, - strlen(Text), + WriteConsoleOutputCharacters(Buffer, + strlen(Buffer), coPos); } diff --git a/subsys/system/usetup/console.h b/subsys/system/usetup/console.h index daf48e0..99ff5d9 100644 --- a/subsys/system/usetup/console.h +++ b/subsys/system/usetup/console.h @@ -102,7 +102,7 @@ VOID ClearScreen(VOID); VOID -SetStatusText(PCHAR Text); +SetStatusText(char* fmt, ...); VOID SetTextXY(SHORT x, SHORT y, PCHAR Text); diff --git a/subsys/system/usetup/format.c b/subsys/system/usetup/format.c new file mode 100755 index 0000000..2339ed7 --- /dev/null +++ b/subsys/system/usetup/format.c @@ -0,0 +1,57 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/format.c + * PURPOSE: Filesystem format support functions + * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#define NDEBUG +#include +#include + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS +FormatPartition(PUNICODE_STRING DriveRoot) +{ + NTSTATUS Status; + + VfatInitialize(); + + Status = VfatFormat(DriveRoot, + 0, // MediaFlag + NULL, // Label + TRUE, // QuickFormat + 0, // ClusterSize + NULL); // Callback + DPRINT("VfatFormat() status 0x%.08x\n", Status); + + VfatCleanup(); + + return Status; +} + +/* EOF */ diff --git a/subsys/system/usetup/format.h b/subsys/system/usetup/format.h new file mode 100755 index 0000000..193e3d4 --- /dev/null +++ b/subsys/system/usetup/format.h @@ -0,0 +1,35 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/format.h + * PURPOSE: Filesystem format support functions + * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + */ + +#ifndef __FORMAT_H__ +#define __FORMAT_H__ + +NTSTATUS +FormatPartition(PUNICODE_STRING DriveRoot); + +#endif /* __FILESUP_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/infcache.c b/subsys/system/usetup/infcache.c new file mode 100644 index 0000000..8289bd5 --- /dev/null +++ b/subsys/system/usetup/infcache.c @@ -0,0 +1,1559 @@ +/* + * ReactOS kernel + * Copyright (C) 2002,2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/infcache.c + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include "usetup.h" +#include "infcache.h" + + +#define CONTROL_Z '\x1a' +#define MAX_SECTION_NAME_LEN 255 +#define MAX_FIELD_LEN 511 /* larger fields get silently truncated */ +/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */ +#define MAX_STRING_LEN (MAX_INF_STRING_LENGTH+1) + + +typedef struct _INFCACHEFIELD +{ + struct _INFCACHEFIELD *Next; + struct _INFCACHEFIELD *Prev; + + WCHAR Data[1]; +} INFCACHEFIELD, *PINFCACHEFIELD; + + +typedef struct _INFCACHELINE +{ + struct _INFCACHELINE *Next; + struct _INFCACHELINE *Prev; + + LONG FieldCount; + + PWCHAR Key; + + PINFCACHEFIELD FirstField; + PINFCACHEFIELD LastField; + +} INFCACHELINE, *PINFCACHELINE; + + +typedef struct _INFCACHESECTION +{ + struct _INFCACHESECTION *Next; + struct _INFCACHESECTION *Prev; + + PINFCACHELINE FirstLine; + PINFCACHELINE LastLine; + + LONG LineCount; + + WCHAR Name[1]; +} INFCACHESECTION, *PINFCACHESECTION; + + +typedef struct _INFCACHE +{ + PINFCACHESECTION FirstSection; + PINFCACHESECTION LastSection; + + PINFCACHESECTION StringsSection; +} INFCACHE, *PINFCACHE; + + +/* parser definitions */ + +enum parser_state +{ + LINE_START, /* at beginning of a line */ + SECTION_NAME, /* parsing a section name */ + KEY_NAME, /* parsing a key name */ + VALUE_NAME, /* parsing a value name */ + EOL_BACKSLASH, /* backslash at end of line */ + QUOTES, /* inside quotes */ + LEADING_SPACES, /* leading spaces */ + TRAILING_SPACES, /* trailing spaces */ + COMMENT, /* inside a comment */ + NB_PARSER_STATES +}; + +struct parser +{ + const CHAR *start; /* start position of item being parsed */ + const CHAR *end; /* end of buffer */ + PINFCACHE file; /* file being built */ + enum parser_state state; /* current parser state */ + enum parser_state stack[4]; /* state stack */ + int stack_pos; /* current pos in stack */ + + PINFCACHESECTION cur_section; /* pointer to the section being parsed*/ + PINFCACHELINE line; /* current line */ + unsigned int line_pos; /* current line position in file */ + unsigned int error; /* error code */ + unsigned int token_len; /* current token len */ + WCHAR token[MAX_FIELD_LEN+1]; /* current token */ +}; + +typedef const CHAR * (*parser_state_func)( struct parser *parser, const CHAR *pos ); + +/* parser state machine functions */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ); +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ); +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ); +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ); + +static const parser_state_func parser_funcs[NB_PARSER_STATES] = +{ + line_start_state, /* LINE_START */ + section_name_state, /* SECTION_NAME */ + key_name_state, /* KEY_NAME */ + value_name_state, /* VALUE_NAME */ + eol_backslash_state, /* EOL_BACKSLASH */ + quotes_state, /* QUOTES */ + leading_spaces_state, /* LEADING_SPACES */ + trailing_spaces_state, /* TRAILING_SPACES */ + comment_state /* COMMENT */ +}; + + +/* PRIVATE FUNCTIONS ********************************************************/ + +static PINFCACHELINE +InfpCacheFreeLine (PINFCACHELINE Line) +{ + PINFCACHELINE Next; + PINFCACHEFIELD Field; + + if (Line == NULL) + { + return NULL; + } + + Next = Line->Next; + if (Line->Key != NULL) + { + RtlFreeHeap (ProcessHeap, + 0, + Line->Key); + Line->Key = NULL; + } + + /* Remove data fields */ + while (Line->FirstField != NULL) + { + Field = Line->FirstField->Next; + RtlFreeHeap (ProcessHeap, + 0, + Line->FirstField); + Line->FirstField = Field; + } + Line->LastField = NULL; + + RtlFreeHeap (ProcessHeap, + 0, + Line); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFreeSection (PINFCACHESECTION Section) +{ + PINFCACHESECTION Next; + + if (Section == NULL) + { + return NULL; + } + + /* Release all keys */ + Next = Section->Next; + while (Section->FirstLine != NULL) + { + Section->FirstLine = InfpCacheFreeLine (Section->FirstLine); + } + Section->LastLine = NULL; + + RtlFreeHeap (ProcessHeap, + 0, + Section); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFindSection (PINFCACHE Cache, + PWCHAR Name) +{ + PINFCACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL) + { + return NULL; + } + + /* iterate through list of sections */ + Section = Cache->FirstSection; + while (Section != NULL) + { + if (_wcsicmp (Section->Name, Name) == 0) + { + return Section; + } + + /* get the next section*/ + Section = Section->Next; + } + + return NULL; +} + + +static PINFCACHESECTION +InfpCacheAddSection (PINFCACHE Cache, + PWCHAR Name) +{ + PINFCACHESECTION Section = NULL; + ULONG Size; + + if (Cache == NULL || Name == NULL) + { + DPRINT("Invalid parameter\n"); + return NULL; + } + + /* Allocate and initialize the new section */ + Size = sizeof(INFCACHESECTION) + (wcslen (Name) * sizeof(WCHAR)); + Section = (PINFCACHESECTION)RtlAllocateHeap (ProcessHeap, + 0, + Size); + if (Section == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return NULL; + } + RtlZeroMemory (Section, + Size); + + /* Copy section name */ + wcscpy (Section->Name, Name); + + /* Append section */ + if (Cache->FirstSection == NULL) + { + Cache->FirstSection = Section; + Cache->LastSection = Section; + } + else + { + Cache->LastSection->Next = Section; + Section->Prev = Cache->LastSection; + Cache->LastSection = Section; + } + + return Section; +} + + +static PINFCACHELINE +InfpCacheAddLine (PINFCACHESECTION Section) +{ + PINFCACHELINE Line; + + if (Section == NULL) + { + DPRINT("Invalid parameter\n"); + return NULL; + } + + Line = (PINFCACHELINE)RtlAllocateHeap (ProcessHeap, + 0, + sizeof(INFCACHELINE)); + if (Line == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return NULL; + } + RtlZeroMemory(Line, + sizeof(INFCACHELINE)); + + /* Append line */ + if (Section->FirstLine == NULL) + { + Section->FirstLine = Line; + Section->LastLine = Line; + } + else + { + Section->LastLine->Next = Line; + Line->Prev = Section->LastLine; + Section->LastLine = Line; + } + Section->LineCount++; + + return Line; +} + + +static PVOID +InfpAddKeyToLine (PINFCACHELINE Line, + PWCHAR Key) +{ + if (Line == NULL) + return NULL; + + if (Line->Key != NULL) + return NULL; + + Line->Key = (PWCHAR)RtlAllocateHeap (ProcessHeap, + 0, + (wcslen (Key) + 1) * sizeof(WCHAR)); + if (Line->Key == NULL) + return NULL; + + wcscpy (Line->Key, Key); + + return (PVOID)Line->Key; +} + + +static PVOID +InfpAddFieldToLine (PINFCACHELINE Line, + PWCHAR Data) +{ + PINFCACHEFIELD Field; + ULONG Size; + + Size = sizeof(INFCACHEFIELD) + (wcslen(Data) * sizeof(WCHAR)); + Field = (PINFCACHEFIELD)RtlAllocateHeap (ProcessHeap, + 0, + Size); + if (Field == NULL) + { + return NULL; + } + RtlZeroMemory (Field, + Size); + wcscpy (Field->Data, Data); + + /* Append key */ + if (Line->FirstField == NULL) + { + Line->FirstField = Field; + Line->LastField = Field; + } + else + { + Line->LastField->Next = Field; + Field->Prev = Line->LastField; + Line->LastField = Field; + } + Line->FieldCount++; + + return (PVOID)Field; +} + + +static PINFCACHELINE +InfpCacheFindKeyLine (PINFCACHESECTION Section, + PWCHAR Key) +{ + PINFCACHELINE Line; + + Line = Section->FirstLine; + while (Line != NULL) + { + if (Line->Key != NULL && _wcsicmp (Line->Key, Key) == 0) + { + return Line; + } + + Line = Line->Next; + } + + return NULL; +} + + +/* push the current state on the parser stack */ +inline static void push_state( struct parser *parser, enum parser_state state ) +{ +// assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) ); + parser->stack[parser->stack_pos++] = state; +} + + +/* pop the current state */ +inline static void pop_state( struct parser *parser ) +{ +// assert( parser->stack_pos ); + parser->state = parser->stack[--parser->stack_pos]; +} + + +/* set the parser state and return the previous one */ +inline static enum parser_state set_state( struct parser *parser, enum parser_state state ) +{ + enum parser_state ret = parser->state; + parser->state = state; + return ret; +} + + +/* check if the pointer points to an end of file */ +inline static int is_eof( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || *ptr == CONTROL_Z); +} + + +/* check if the pointer points to an end of line */ +inline static int is_eol( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\r' /*'\n'*/); +} + + +/* push data from current token start up to pos into the current token */ +static int push_token( struct parser *parser, const CHAR *pos ) +{ + int len = pos - parser->start; + const CHAR *src = parser->start; + WCHAR *dst = parser->token + parser->token_len; + + if (len > MAX_FIELD_LEN - parser->token_len) + len = MAX_FIELD_LEN - parser->token_len; + + parser->token_len += len; + for ( ; len > 0; len--, dst++, src++) + *dst = *src ? (WCHAR)*src : L' '; + *dst = 0; + parser->start = pos; + + return 0; +} + + + +/* add a section with the current token as name */ +static PVOID add_section_from_token( struct parser *parser ) +{ + PINFCACHESECTION Section; + + if (parser->token_len > MAX_SECTION_NAME_LEN) + { + parser->error = STATUS_SECTION_NAME_TOO_LONG; + return NULL; + } + + Section = InfpCacheFindSection (parser->file, + parser->token); + if (Section == NULL) + { + /* need to create a new one */ + Section= InfpCacheAddSection (parser->file, + parser->token); + if (Section == NULL) + { + parser->error = STATUS_NOT_ENOUGH_MEMORY; + return NULL; + } + } + + parser->token_len = 0; + parser->cur_section = Section; + + return (PVOID)Section; +} + + +/* add a field containing the current token to the current line */ +static struct field *add_field_from_token( struct parser *parser, int is_key ) +{ + PVOID field; + WCHAR *text; + + if (!parser->line) /* need to start a new line */ + { + if (parser->cur_section == NULL) /* got a line before the first section */ + { + parser->error = STATUS_WRONG_INF_STYLE; + return NULL; + } + + parser->line = InfpCacheAddLine (parser->cur_section); + if (parser->line == NULL) + goto error; + } + else + { +// assert(!is_key); + } + + if (is_key) + { + field = InfpAddKeyToLine(parser->line, parser->token); + } + else + { + field = InfpAddFieldToLine(parser->line, parser->token); + } + + if (field != NULL) + { + parser->token_len = 0; + return field; + } + +error: + parser->error = STATUS_NOT_ENOUGH_MEMORY; + return NULL; +} + + +/* close the current line and prepare for parsing a new one */ +static void close_current_line( struct parser *parser ) +{ + parser->line = NULL; +} + + + +/* handler for parser LINE_START state */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { +// case '\n': + case '\r': + p++; + parser->line_pos++; + close_current_line( parser ); + break; + case ';': + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case '[': + parser->start = p + 1; + set_state( parser, SECTION_NAME ); + return p + 1; + default: + if (!isspace(*p)) + { + parser->start = p; + set_state( parser, KEY_NAME ); + return p; + } + break; + } + } + close_current_line( parser ); + return NULL; +} + + +/* handler for parser SECTION_NAME state */ +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ']') + { + push_token( parser, p ); + if (add_section_from_token( parser ) == NULL) + return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); /* ignore everything else on the line */ + return p + 1; + } + } + parser->error = STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */ + return NULL; +} + + +/* handler for parser KEY_NAME state */ +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ',') break; + switch(*p) + { + + case '=': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 1 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, KEY_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, KEY_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, KEY_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + set_state( parser, VALUE_NAME ); + return p; +} + + +/* handler for parser VALUE_NAME state */ +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + switch(*p) + { + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case ',': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, VALUE_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, VALUE_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + set_state( parser, LINE_START ); + return p; +} + + +/* handler for parser EOL_BACKSLASH state */ +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { +// case '\n': + case '\r': + parser->line_pos++; +// parser->start = p + 1; + parser->start = p + 2; + set_state( parser, LEADING_SPACES ); +// return p + 1; + return p + 2; + case '\\': + continue; + case ';': + push_state( parser, EOL_BACKSLASH ); + set_state( parser, COMMENT ); + return p + 1; + default: + if (isspace(*p)) + continue; + push_token( parser, p ); + pop_state( parser ); + return p; + } + } + parser->start = p; + pop_state( parser ); + + return p; +} + + +/* handler for parser QUOTES state */ +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '"') + { + if (p+1 < parser->end && p[1] == '"') /* double quotes */ + { + push_token( parser, p + 1 ); + parser->start = token_end = p + 2; + p++; + } + else /* end of quotes */ + { + push_token( parser, p ); + parser->start = p + 1; + pop_state( parser ); + return p + 1; + } + } + } + push_token( parser, p ); + pop_state( parser ); + return p; +} + + +/* handler for parser LEADING_SPACES state */ +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\\') + { + parser->start = p; + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + parser->start = p; + pop_state( parser ); + return p; +} + + +/* handler for parser TRAILING_SPACES state */ +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\\') + { + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + pop_state( parser ); + return p; +} + + +/* handler for parser COMMENT state */ +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p = pos; + + while (!is_eol( parser, p )) + p++; + pop_state( parser ); + return p; +} + + +/* parse a complete buffer */ +static NTSTATUS +InfpParseBuffer (PINFCACHE file, + const CHAR *buffer, + const CHAR *end, + PULONG error_line) +{ + struct parser parser; + const CHAR *pos = buffer; + + parser.start = buffer; + parser.end = end; + parser.file = file; + parser.line = NULL; + parser.state = LINE_START; + parser.stack_pos = 0; + parser.cur_section = NULL; + parser.line_pos = 1; + parser.error = 0; + parser.token_len = 0; + + /* parser main loop */ + while (pos) + pos = (parser_funcs[parser.state])(&parser, pos); + + if (parser.error) + { + if (error_line) + *error_line = parser.line_pos; + return parser.error; + } + + /* find the [strings] section */ + file->StringsSection = InfpCacheFindSection (file, + L"Strings"); + + return STATUS_SUCCESS; +} + + + +/* PUBLIC FUNCTIONS *********************************************************/ + +NTSTATUS +InfOpenFile(PHINF InfHandle, + PUNICODE_STRING FileName, + PULONG ErrorLine) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + FILE_STANDARD_INFORMATION FileInfo; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + NTSTATUS Status; + PCHAR FileBuffer; + ULONG FileLength; + LARGE_INTEGER FileOffset; + PINFCACHE Cache; + + + *InfHandle = NULL; + *ErrorLine = (ULONG)-1; + + /* Open the inf file */ + InitializeObjectAttributes(&ObjectAttributes, + FileName, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_NON_DIRECTORY_FILE); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenFile() failed (Status %lx)\n", Status); + return(Status); + } + + DPRINT("NtOpenFile() successful\n"); + + /* Query file size */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + if (Status == STATUS_PENDING) + { + DPRINT("NtQueryInformationFile() returns STATUS_PENDING\n"); + + } + else if (!NT_SUCCESS(Status)) + { + DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return(Status); + } + + FileLength = FileInfo.EndOfFile.u.LowPart; + + DPRINT("File size: %lu\n", FileLength); + + /* Allocate file buffer */ + FileBuffer = RtlAllocateHeap(ProcessHeap, + 0, + FileLength + 1); + if (FileBuffer == NULL) + { + DPRINT1("RtlAllocateHeap() failed\n"); + NtClose(FileHandle); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Read file */ + FileOffset.QuadPart = 0ULL; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FileBuffer, + FileLength, + &FileOffset, + NULL); + + if (Status == STATUS_PENDING) + { + DPRINT("NtReadFile() returns STATUS_PENDING\n"); + + Status = IoStatusBlock.Status; + } + + /* Append string terminator */ + FileBuffer[FileLength] = 0; + + NtClose(FileHandle); + + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReadFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, + 0, + FileBuffer); + return(Status); + } + + /* Allocate infcache header */ + Cache = (PINFCACHE)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(INFCACHE)); + if (Cache == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + RtlFreeHeap(ProcessHeap, + 0, + FileBuffer); + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Initialize inicache header */ + RtlZeroMemory(Cache, + sizeof(INFCACHE)); + + /* Parse the inf buffer */ + Status = InfpParseBuffer (Cache, + FileBuffer, + FileBuffer + FileLength, + ErrorLine); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, + 0, + Cache); + Cache = NULL; + } + + /* Free file buffer */ + RtlFreeHeap(ProcessHeap, + 0, + FileBuffer); + + *InfHandle = (HINF)Cache; + + return(Status); +} + + +VOID +InfCloseFile(HINF InfHandle) +{ + PINFCACHE Cache; + + Cache = (PINFCACHE)InfHandle; + + if (Cache == NULL) + { + return; + } + + while (Cache->FirstSection != NULL) + { + Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection); + } + Cache->LastSection = NULL; + + RtlFreeHeap(ProcessHeap, + 0, + Cache); +} + + +BOOLEAN +InfFindFirstLine (HINF InfHandle, + PCWSTR Section, + PCWSTR Key, + PINFCONTEXT Context) +{ + PINFCACHE Cache; + PINFCACHESECTION CacheSection; + PINFCACHELINE CacheLine; + + if (InfHandle == NULL || Section == NULL || Context == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + Cache = (PINFCACHE)InfHandle; + + /* Iterate through list of sections */ + CacheSection = Cache->FirstSection; + while (Section != NULL) + { + DPRINT("Comparing '%S' and '%S'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (_wcsicmp(CacheSection->Name, Section) == 0) + { + if (Key != NULL) + { + CacheLine = InfpCacheFindKeyLine (CacheSection, (PWCHAR)Key); + } + else + { + CacheLine = CacheSection->FirstLine; + } + + if (CacheLine == NULL) + return FALSE; + + Context->Inf = (PVOID)Cache; + Context->Section = (PVOID)CacheSection; + Context->Line = (PVOID)CacheLine; + + return TRUE; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + + DPRINT("Section not found\n"); + + return FALSE; +} + + +BOOLEAN +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL) + return FALSE; + + if (ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + if (CacheLine->Next == NULL) + return FALSE; + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)(CacheLine->Next); + + return TRUE; +} + + +BOOLEAN +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCWSTR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL) + return FALSE; + + CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && _wcsicmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +BOOLEAN +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCWSTR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && _wcsicmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +LONG +InfGetLineCount(HINF InfHandle, + PCWSTR Section) +{ + PINFCACHE Cache; + PINFCACHESECTION CacheSection; + + if (InfHandle == NULL || Section == NULL) + { + DPRINT("Invalid parameter\n"); + return -1; + } + + Cache = (PINFCACHE)InfHandle; + + /* Iterate through list of sections */ + CacheSection = Cache->FirstSection; + while (Section != NULL) + { + DPRINT("Comparing '%S' and '%S'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (_wcsicmp(CacheSection->Name, Section) == 0) + { + return CacheSection->LineCount; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + + DPRINT("Section not found\n"); + + return -1; +} + + +/* InfGetLineText */ + + +LONG +InfGetFieldCount(PINFCONTEXT Context) +{ + if (Context == NULL || Context->Line == NULL) + return 0; + + return ((PINFCACHELINE)Context->Line)->FieldCount; +} + + +BOOLEAN +InfGetBinaryField (PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + ULONG Size; + PUCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Size = CacheLine->FieldCount - FieldIndex + 1; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + /* Copy binary data */ + Ptr = ReturnBuffer; + while (CacheField != NULL) + { + *Ptr = (UCHAR)wcstoul (CacheField->Data, NULL, 16); + + Ptr++; + CacheField = CacheField->Next; + } + } + + return TRUE; +} + + +BOOLEAN +InfGetIntField (PINFCONTEXT Context, + ULONG FieldIndex, + PLONG IntegerValue) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + PWCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || IntegerValue == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + *IntegerValue = wcstol (Ptr, NULL, 0); + + return TRUE; +} + + +BOOLEAN +InfGetMultiSzField (PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + PINFCACHEFIELD FieldPtr; + ULONG Index; + ULONG Size; + PWCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + /* Calculate the required buffer size */ + FieldPtr = CacheField; + Size = 0; + while (FieldPtr != NULL) + { + Size += (wcslen (FieldPtr->Data) + 1); + FieldPtr = FieldPtr->Next; + } + Size++; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + /* Copy multi-sz string */ + Ptr = ReturnBuffer; + FieldPtr = CacheField; + while (FieldPtr != NULL) + { + Size = wcslen (FieldPtr->Data) + 1; + + wcscpy (Ptr, FieldPtr->Data); + + Ptr = Ptr + Size; + FieldPtr = FieldPtr->Next; + } + *Ptr = 0; + } + + return TRUE; +} + + +BOOLEAN +InfGetStringField (PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + PWCHAR Ptr; + ULONG Size; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + Size = wcslen (Ptr) + 1; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + wcscpy (ReturnBuffer, Ptr); + } + + return TRUE; +} + + + + +BOOLEAN +InfGetData (PINFCONTEXT Context, + PWCHAR *Key, + PWCHAR *Data) +{ + PINFCACHELINE CacheKey; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheKey = (PINFCACHELINE)Context->Line; + if (Key != NULL) + *Key = CacheKey->Key; + + if (Data != NULL) + { + if (CacheKey->FirstField == NULL) + { + *Data = NULL; + } + else + { + *Data = CacheKey->FirstField->Data; + } + } + + return TRUE; +} + + +BOOLEAN +InfGetDataField (PINFCONTEXT Context, + ULONG FieldIndex, + PWCHAR *Data) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + *Data = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + *Data = CacheField->Data; + } + + return TRUE; +} + + +/* EOF */ diff --git a/subsys/system/usetup/infcache.h b/subsys/system/usetup/infcache.h new file mode 100644 index 0000000..8b35488 --- /dev/null +++ b/subsys/system/usetup/infcache.h @@ -0,0 +1,130 @@ +/* + * ReactOS kernel + * Copyright (C) 2002, 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/infcache.h + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +#ifndef __INFCACHE_H__ +#define __INFCACHE_H__ + + +#define STATUS_BAD_SECTION_NAME_LINE (0xC0700001) +#define STATUS_SECTION_NAME_TOO_LONG (0xC0700002) +#define STATUS_WRONG_INF_STYLE (0xC0700003) +#define STATUS_NOT_ENOUGH_MEMORY (0xC0700004) + +#define MAX_INF_STRING_LENGTH 512 + +typedef PVOID HINF, *PHINF; + +typedef struct _INFCONTEXT +{ + PVOID Inf; +// PVOID CurrentInf; + PVOID Section; + PVOID Line; +} INFCONTEXT, *PINFCONTEXT; + + +/* FUNCTIONS ****************************************************************/ + +NTSTATUS +InfOpenFile (PHINF InfHandle, + PUNICODE_STRING FileName, + PULONG ErrorLine); + +VOID +InfCloseFile (HINF InfHandle); + + +BOOLEAN +InfFindFirstLine (HINF InfHandle, + PCWSTR Section, + PCWSTR Key, + PINFCONTEXT Context); + +BOOLEAN +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut); + +BOOLEAN +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCWSTR Key, + PINFCONTEXT ContextOut); + +BOOLEAN +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCWSTR Key, + PINFCONTEXT ContextOut); + + +LONG +InfGetLineCount (HINF InfHandle, + PCWSTR Section); + +LONG +InfGetFieldCount (PINFCONTEXT Context); + + +BOOLEAN +InfGetBinaryField (PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +BOOLEAN +InfGetIntField (PINFCONTEXT Context, + ULONG FieldIndex, + PLONG IntegerValue); + +BOOLEAN +InfGetMultiSzField (PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +BOOLEAN +InfGetStringField (PINFCONTEXT Context, + ULONG FieldIndex, + PWSTR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + + + +BOOLEAN +InfGetData (PINFCONTEXT Context, + PWCHAR *Key, + PWCHAR *Data); + +BOOLEAN +InfGetDataField (PINFCONTEXT Context, + ULONG FieldIndex, + PWCHAR *Data); + +#endif /* __INFCACHE_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/makefile b/subsys/system/usetup/makefile index 78491d0..39774b0 100644 --- a/subsys/system/usetup/makefile +++ b/subsys/system/usetup/makefile @@ -2,18 +2,25 @@ PATH_TO_TOP = ../../.. +TARGET_BOOTSTRAP = yes + +TARGET_BOOTSTRAP_NAME = smss.exe + TARGET_TYPE = program TARGET_APPTYPE = native TARGET_NAME = usetup +TARGET_SDKLIBS = vfatlib.a ntdll.a + TARGET_INSTALLDIR = system32 TARGET_CFLAGS = -D__NTAPP__ TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o console.o drivesup.o filequeue.o \ - filesup.o inicache.o partlist.o progress.o + filesup.o format.o infcache.o inicache.o partlist.o progress.o \ + registry.o include $(PATH_TO_TOP)/rules.mak diff --git a/subsys/system/usetup/partlist.c b/subsys/system/usetup/partlist.c index 6181363..121a628 100644 --- a/subsys/system/usetup/partlist.c +++ b/subsys/system/usetup/partlist.c @@ -22,6 +22,7 @@ * FILE: subsys/system/usetup/partlist.c * PURPOSE: Partition list functions * PROGRAMMER: Eric Kohl + * Casper S. Hornstrup (chorns@users.sourceforge.net) */ #include @@ -47,7 +48,11 @@ AddPartitionList(ULONG DiskNumber, PPARTENTRY PartEntry; ULONG i; ULONG EntryCount; - + BOOLEAN LastEntryWasUnused; + ULONGLONG LastStartingOffset; + ULONGLONG LastPartitionSize; + ULONGLONG LastUnusedPartitionSize; + ULONG LastUnusedEntry; /* * FIXME: @@ -62,14 +67,6 @@ AddPartitionList(ULONG DiskNumber, } else { - -#if 0 - for (i = 0; i < LayoutBuffer->PartitionCount; i++) - { - - } -#endif - EntryCount = LayoutBuffer->PartitionCount; } @@ -88,12 +85,21 @@ AddPartitionList(ULONG DiskNumber, PartEntry = &DiskEntry->PartArray[0]; PartEntry->Unpartitioned = TRUE; - PartEntry->PartSize = 0; /* ?? */ - - PartEntry->Used = TRUE; + // Start partition at head 1, cylinder 0 + PartEntry->StartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector; + PartEntry->PartSize = DiskEntry->DiskSize - PartEntry->StartingOffset; + PartEntry->Used = FALSE; + PartEntry->HidePartEntry = FALSE; + PartEntry->PartNumber = 1; } else { + LastEntryWasUnused = FALSE; + // Start partition at head 1, cylinder 0 + LastStartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector; + LastPartitionSize = 0; + LastUnusedEntry = -1; + LastUnusedPartitionSize = 0; for (i = 0; i < LayoutBuffer->PartitionCount; i++) { PartEntry = &DiskEntry->PartArray[i]; @@ -101,6 +107,18 @@ AddPartitionList(ULONG DiskNumber, if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) && (!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType))) { + LastUnusedPartitionSize = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart + - (LastStartingOffset + LastPartitionSize); + if (LastUnusedEntry != -1) + { + DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize; + DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize; + DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */ + } + LastStartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart; + LastPartitionSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; + + PartEntry->StartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart; PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart; PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber, PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType; @@ -112,12 +130,37 @@ AddPartitionList(ULONG DiskNumber, PartEntry->Unpartitioned = FALSE; PartEntry->Used = TRUE; + PartEntry->HidePartEntry = FALSE; + LastEntryWasUnused = FALSE; + LastUnusedEntry = -1; } else { + if (LastEntryWasUnused) + { + /* Group unused entries into one unpartitioned disk space area */ + PartEntry->HidePartEntry = TRUE; + PartEntry->PartSize = 0; + } + else + { + LastUnusedEntry = i; + } + + PartEntry->Unpartitioned = TRUE; + PartEntry->Used = FALSE; + LastEntryWasUnused = TRUE; } } + LastUnusedPartitionSize = DiskEntry->DiskSize + - (LastStartingOffset + LastPartitionSize); + if (LastUnusedEntry != -1) + { + DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize; + DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize; + DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */ + } } } @@ -156,10 +199,7 @@ GetDriverName(PDISKENTRY DiskEntry) PPARTLIST -CreatePartitionList(SHORT Left, - SHORT Top, - SHORT Right, - SHORT Bottom) +CreatePartitionListNoGUI() { PPARTLIST List; OBJECT_ATTRIBUTES ObjectAttributes; @@ -179,10 +219,10 @@ CreatePartitionList(SHORT Left, if (List == NULL) return(NULL); - List->Left = Left; - List->Top = Top; - List->Right = Right; - List->Bottom = Bottom; + List->Left = 0; + List->Top = 0; + List->Right = 0; + List->Bottom = 0; List->Line = 0; @@ -259,6 +299,16 @@ CreatePartitionList(SHORT Left, sizeof(SCSI_ADDRESS)); + List->DiskArray[DiskNumber].Cylinders = DiskGeometry.Cylinders.QuadPart; + List->DiskArray[DiskNumber].TracksPerCylinder = DiskGeometry.TracksPerCylinder; + List->DiskArray[DiskNumber].SectorsPerTrack = DiskGeometry.SectorsPerTrack; + List->DiskArray[DiskNumber].BytesPerSector = DiskGeometry.BytesPerSector; + + DPRINT("Cylinders %d\n", List->DiskArray[DiskNumber].Cylinders); + DPRINT("TracksPerCylinder %d\n", List->DiskArray[DiskNumber].TracksPerCylinder); + DPRINT("SectorsPerTrack %d\n", List->DiskArray[DiskNumber].SectorsPerTrack); + DPRINT("BytesPerSector %d\n", List->DiskArray[DiskNumber].BytesPerSector); + List->DiskArray[DiskNumber].DiskSize = DiskGeometry.Cylinders.QuadPart * (ULONGLONG)DiskGeometry.TracksPerCylinder * @@ -314,12 +364,191 @@ CreatePartitionList(SHORT Left, List->CurrentDisk = 0; List->CurrentPartition = 0; + return(List); +} + +PPARTLIST +CreatePartitionList(SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom) +{ + PPARTLIST List; + + List = CreatePartitionListNoGUI(); + if (List == NULL) + return(NULL); + + List->Left = Left; + List->Top = Top; + List->Right = Right; + List->Bottom = Bottom; + DrawPartitionList(List); return(List); } +PPARTENTRY +GetPartitionInformation(PPARTLIST List, + ULONG DiskNumber, + ULONG PartitionNumber, + PULONG PartEntryNumber) +{ + PPARTENTRY PartEntry; + ULONG i; + + if (List->DiskArray == NULL) + { + return(FALSE); + } + + if (DiskNumber >= List->DiskCount) + { + return(FALSE); + } + + if (PartitionNumber >= List->DiskArray[DiskNumber].PartCount) + { + return(FALSE); + } + + if (List->DiskArray[DiskNumber].FixedDisk != TRUE) + { + return(FALSE); + } + + for (i = 0; i < List->DiskArray[DiskNumber].PartCount; i++) + { + PartEntry = &List->DiskArray[DiskNumber].PartArray[i]; + if (PartEntry->PartNumber == PartitionNumber) + { + *PartEntryNumber = i; + return PartEntry; + } + } + return NULL; +} + +BOOLEAN +MarkPartitionActive(ULONG DiskNumber, + ULONG PartitionNumber, + PPARTDATA ActivePartition) +{ + PPARTLIST List; + PPARTENTRY PartEntry; + ULONG PartEntryNumber; + OBJECT_ATTRIBUTES ObjectAttributes; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + + List = CreatePartitionListNoGUI(); + if (List == NULL) + { + return(FALSE); + } + + PartEntry = GetPartitionInformation(List, + DiskNumber, + PartitionNumber, + &PartEntryNumber); + if (List == NULL) + { + DestroyPartitionList(List); + return(FALSE); + } + + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskNumber); + RtlInitUnicodeString(&Name, Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + 0x10001, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + 8192); + if (!NT_SUCCESS(Status)) + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + + + LayoutBuffer->PartitionEntry[PartEntryNumber].BootIndicator = TRUE; + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + LayoutBuffer, + 8192, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + } + else + { + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + DestroyPartitionList(List); + return FALSE; + } + + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + + PartEntry->Active = TRUE; + if (!GetActiveBootPartition(List, ActivePartition)) + { + DestroyPartitionList(List); + DPRINT("GetActiveBootPartition() failed\n"); + return FALSE; + } + + DestroyPartitionList(List); + + return TRUE; +} + + VOID DestroyPartitionList(PPARTLIST List) { @@ -478,7 +707,7 @@ PrintPartitionData(PPARTLIST List, if (PartEntry->Unpartitioned == TRUE) { sprintf(LineBuffer, - " Unpartitioned space %I64u %s", + " Unpartitioned space %I64u %s", PartSize, Unit); } @@ -640,12 +869,12 @@ PrintDiskData(PPARTLIST List, /* Print partition lines*/ for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++) { - if (DiskEntry->PartArray[PartIndex].Used == TRUE) - { - PrintPartitionData(List, - DiskIndex, - PartIndex); - } + if (!DiskEntry->PartArray[PartIndex].HidePartEntry) + { + PrintPartitionData(List, + DiskIndex, + PartIndex); + } } /* Print separator line */ @@ -754,12 +983,12 @@ ScrollDownPartitionList(PPARTLIST List) /* check for next usable entry on current disk */ for (i = List->CurrentPartition + 1; i < List->DiskArray[List->CurrentDisk].PartCount; i++) { - if (List->DiskArray[List->CurrentDisk].PartArray[i].Used == TRUE) - { - List->CurrentPartition = i; - DrawPartitionList(List); - return; - } + if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry) + { + List->CurrentPartition = i; + DrawPartitionList(List); + return; + } } /* check for first usable entry on next disk */ @@ -767,13 +996,13 @@ ScrollDownPartitionList(PPARTLIST List) { for (i = 0; i < List->DiskArray[j].PartCount; i++) { - if (List->DiskArray[j].PartArray[i].Used == TRUE) - { + if (!List->DiskArray[j].PartArray[i].HidePartEntry) + { List->CurrentDisk = j; List->CurrentPartition = i; DrawPartitionList(List); return; - } + } } } } @@ -792,7 +1021,7 @@ ScrollUpPartitionList(PPARTLIST List) /* check for previous usable entry on current disk */ for (i = List->CurrentPartition - 1; i != (ULONG)-1; i--) { - if (List->DiskArray[List->CurrentDisk].PartArray[i].Used == TRUE) + if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry) { List->CurrentPartition = i; DrawPartitionList(List); @@ -805,7 +1034,7 @@ ScrollUpPartitionList(PPARTLIST List) { for (i = List->DiskArray[j].PartCount - 1; i != (ULONG)-1; i--) { - if (List->DiskArray[j].PartArray[i].Used == TRUE) + if (!List->DiskArray[j].PartArray[i].HidePartEntry) { List->CurrentDisk = j; List->CurrentPartition = i; @@ -838,7 +1067,9 @@ GetSelectedPartition(PPARTLIST List, PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; if (PartEntry->Used == FALSE) - return(FALSE); + { + return(FALSE); + } /* Copy disk-specific data */ Data->DiskSize = DiskEntry->DiskSize; @@ -866,11 +1097,12 @@ GetSelectedPartition(PPARTLIST List, } /* Copy partition-specific data */ + Data->CreatePartition = FALSE; + Data->NewPartSize = 0; Data->PartSize = PartEntry->PartSize; Data->PartNumber = PartEntry->PartNumber; Data->PartType = PartEntry->PartType; Data->DriveLetter = PartEntry->DriveLetter; - return(TRUE); } @@ -886,10 +1118,12 @@ GetActiveBootPartition(PPARTLIST List, if (List->CurrentDisk >= List->DiskCount) return(FALSE); - DiskEntry = &List->DiskArray[0]; + DiskEntry = &List->DiskArray[List->CurrentDisk]; if (DiskEntry->FixedDisk == FALSE) + { return(FALSE); + } for (i = 0; i < DiskEntry->PartCount; i++) { @@ -898,7 +1132,9 @@ GetActiveBootPartition(PPARTLIST List, PartEntry = &DiskEntry->PartArray[i]; if (PartEntry->Used == FALSE) + { return(FALSE); + } /* Copy disk-specific data */ Data->DiskSize = DiskEntry->DiskSize; @@ -939,4 +1175,221 @@ GetActiveBootPartition(PPARTLIST List, } +BOOL +CreateSelectedPartition(PPARTLIST List, + ULONG PartType, + ULONGLONG NewPartSize) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + ULONG PartEntryNumber; + OBJECT_ATTRIBUTES ObjectAttributes; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + LARGE_INTEGER li; + + DiskEntry = &List->DiskArray[List->CurrentDisk]; + PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; + PartEntry->PartType = PartType; + PartEntryNumber = List->CurrentPartition; + + DPRINT("NewPartSize %d (%d MB)\n", NewPartSize, NewPartSize / (1024 * 1024)); + DPRINT("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset); + DPRINT("PartEntry->PartSize %d\n", PartEntry->PartSize); + DPRINT("PartEntry->PartNumber %d\n", PartEntry->PartNumber); + DPRINT("PartEntry->PartType 0x%x\n", PartEntry->PartType); + DPRINT("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName); + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskEntry->DiskNumber); + RtlInitUnicodeString(&Name, Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + 0x10001, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + 8192); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + + li.QuadPart = PartEntry->StartingOffset; + LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li; + li.QuadPart = NewPartSize; + LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li; + LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0; /* FIXME: ? */ + LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = PartType; + LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = TRUE; + LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE; + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + LayoutBuffer, + 8192, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + } + else + { + DPRINT("NtOpenFile failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + + return TRUE; +} + + +BOOL +DeleteSelectedPartition(PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + ULONG PartEntryNumber; + OBJECT_ATTRIBUTES ObjectAttributes; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + LARGE_INTEGER li; + + DiskEntry = &List->DiskArray[List->CurrentDisk]; + PartEntry = &DiskEntry->PartArray[List->CurrentPartition]; + PartEntry->PartType = PARTITION_ENTRY_UNUSED; + PartEntryNumber = List->CurrentPartition; + + DPRINT1("DeleteSelectedPartition(PartEntryNumber = %d)\n", PartEntryNumber); + DPRINT1("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset); + DPRINT1("PartEntry->PartSize %d\n", PartEntry->PartSize); + DPRINT1("PartEntry->PartNumber %d\n", PartEntry->PartNumber); + DPRINT1("PartEntry->PartType 0x%x\n", PartEntry->PartType); + DPRINT1("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName); + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskEntry->DiskNumber); + RtlInitUnicodeString(&Name, Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + 0x10001, + &ObjectAttributes, + &Iosb, + 1, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192); + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + 8192); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + + li.QuadPart = 0; + LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li; + li.QuadPart = 0; + LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li; + LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0; + LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = 0; + LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = FALSE; + LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE; + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + LayoutBuffer, + 8192, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + } + else + { + DPRINT("NtOpenFile failed() 0x%.08x\n", Status); + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + return FALSE; + } + + NtClose(FileHandle); + RtlFreeHeap(ProcessHeap, 0, LayoutBuffer); + + return TRUE; +} + /* EOF */ diff --git a/subsys/system/usetup/partlist.h b/subsys/system/usetup/partlist.h index ce79d5b..851a96c 100644 --- a/subsys/system/usetup/partlist.h +++ b/subsys/system/usetup/partlist.h @@ -35,7 +35,9 @@ typedef struct _PARTDATA USHORT Bus; USHORT Id; + BOOLEAN CreatePartition; ULONGLONG PartSize; + ULONGLONG NewPartSize; ULONG PartNumber; ULONG PartType; @@ -47,6 +49,7 @@ typedef struct _PARTDATA typedef struct _PARTENTRY { + ULONGLONG StartingOffset; ULONGLONG PartSize; ULONG PartNumber; ULONG PartType; @@ -59,11 +62,17 @@ typedef struct _PARTENTRY BOOL Unpartitioned; BOOL Used; + + BOOLEAN HidePartEntry; } PARTENTRY, *PPARTENTRY; typedef struct _DISKENTRY { ULONGLONG DiskSize; + ULONGLONG Cylinders; + ULONGLONG TracksPerCylinder; + ULONGLONG SectorsPerTrack; + ULONGLONG BytesPerSector; ULONG DiskNumber; USHORT Port; USHORT Bus; @@ -107,6 +116,11 @@ CreatePartitionList(SHORT Left, SHORT Right, SHORT Bottom); +BOOLEAN +MarkPartitionActive(ULONG DiskNumber, + ULONG PartitionNumber, + PPARTDATA ActivePartition); + VOID DestroyPartitionList(PPARTLIST List); @@ -127,6 +141,14 @@ BOOL GetActiveBootPartition(PPARTLIST List, PPARTDATA Data); +BOOL +CreateSelectedPartition(PPARTLIST List, + ULONG PartType, + ULONGLONG NewPartSize); + +BOOL +DeleteSelectedPartition(PPARTLIST List); + #endif /* __PARTLIST_H__ */ -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/subsys/system/usetup/progress.h b/subsys/system/usetup/progress.h index 45d1ed2..428bea9 100644 --- a/subsys/system/usetup/progress.h +++ b/subsys/system/usetup/progress.h @@ -64,4 +64,4 @@ ProgressNextStep(PPROGRESS Bar); #endif /* __PROGRESS_H__ */ -/* EOF */ \ No newline at end of file +/* EOF */ diff --git a/subsys/system/usetup/registry.c b/subsys/system/usetup/registry.c new file mode 100644 index 0000000..7041cc7 --- /dev/null +++ b/subsys/system/usetup/registry.c @@ -0,0 +1,652 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/registry.c + * PURPOSE: Registry creation functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include "usetup.h" +#include "registry.h" +#include "infcache.h" + + + +#define FLG_ADDREG_BINVALUETYPE 0x00000001 +#define FLG_ADDREG_NOCLOBBER 0x00000002 +#define FLG_ADDREG_DELVAL 0x00000004 +#define FLG_ADDREG_APPEND 0x00000008 +#define FLG_ADDREG_KEYONLY 0x00000010 +#define FLG_ADDREG_OVERWRITEONLY 0x00000020 +#define FLG_ADDREG_TYPE_SZ 0x00000000 +#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000 +#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000 +#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) + + +/* FUNCTIONS ****************************************************************/ + +static BOOLEAN +GetRootKey (PWCHAR Name) +{ + if (!_wcsicmp (Name, L"HKCR")) + { + wcscpy (Name, L"\\Registry\\Machine\\SOFTWARE\\Classes\\"); + return TRUE; + } + + if (!_wcsicmp (Name, L"HKCU")) + { + wcscpy (Name, L"\\Registry\\User\\.DEFAULT\\"); + return TRUE; + } + + if (!_wcsicmp (Name, L"HKLM")) + { + wcscpy (Name, L"\\Registry\\Machine\\"); + return TRUE; + } + + if (!_wcsicmp (Name, L"HKU")) + { + wcscpy (Name, L"\\Registry\\User\\"); + return TRUE; + } + +#if 0 + if (!_wcsicmp (Name, L"HKR")) + return FALSE; +#endif + + return FALSE; +} + + +/*********************************************************************** + * append_multi_sz_value + * + * Append a multisz string to a multisz registry value. + */ +#if 0 +static void +append_multi_sz_value (HANDLE hkey, + const WCHAR *value, + const WCHAR *strings, + DWORD str_size ) +{ + DWORD size, type, total; + WCHAR *buffer, *p; + + if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; + if (type != REG_MULTI_SZ) return; + + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return; + if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; + + /* compare each string against all the existing ones */ + total = size; + while (*strings) + { + int len = strlenW(strings) + 1; + + for (p = buffer; *p; p += strlenW(p) + 1) + if (!strcmpiW( p, strings )) break; + + if (!*p) /* not found, need to append it */ + { + memcpy( p, strings, len * sizeof(WCHAR) ); + p[len] = 0; + total += len; + } + strings += len; + } + if (total != size) + { + TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) ); + RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total ); + } + done: + HeapFree( GetProcessHeap(), 0, buffer ); +} +#endif + +/*********************************************************************** + * delete_multi_sz_value + * + * Remove a string from a multisz registry value. + */ +#if 0 +static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string ) +{ + DWORD size, type; + WCHAR *buffer, *src, *dst; + + if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; + if (type != REG_MULTI_SZ) return; + /* allocate double the size, one for value before and one for after */ + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return; + if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; + src = buffer; + dst = buffer + size; + while (*src) + { + int len = strlenW(src) + 1; + if (strcmpiW( src, string )) + { + memcpy( dst, src, len * sizeof(WCHAR) ); + dst += len; + } + src += len; + } + *dst++ = 0; + if (dst != buffer + 2*size) /* did we remove something? */ + { + TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) ); + RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, + (BYTE *)(buffer + size), dst - (buffer + size) ); + } + done: + HeapFree( GetProcessHeap(), 0, buffer ); +} +#endif + +/*********************************************************************** + * do_reg_operation + * + * Perform an add/delete registry operation depending on the flags. + */ +static BOOLEAN +do_reg_operation(HANDLE KeyHandle, + PUNICODE_STRING ValueName, + PINFCONTEXT Context, + ULONG Flags) +{ + WCHAR EmptyStr = (WCHAR)0; + ULONG Type; + ULONG Size; + NTSTATUS Status; + + if (Flags & FLG_ADDREG_DELVAL) /* deletion */ + { +#if 0 + if (ValueName) + { + RegDeleteValueW( hkey, value ); + } + else + { + RegDeleteKeyW( hkey, NULL ); + } +#endif + return TRUE; + } + + if (Flags & FLG_ADDREG_KEYONLY) + return TRUE; + +#if 0 + if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) + { + BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL ); + if (exists && (flags & FLG_ADDREG_NOCLOBBER)) + return TRUE; + if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) + return TRUE; + } +#endif + + switch (Flags & FLG_ADDREG_TYPE_MASK) + { + case FLG_ADDREG_TYPE_SZ: + Type = REG_SZ; + break; + + case FLG_ADDREG_TYPE_MULTI_SZ: + Type = REG_MULTI_SZ; + break; + + case FLG_ADDREG_TYPE_EXPAND_SZ: + Type = REG_EXPAND_SZ; + break; + + case FLG_ADDREG_TYPE_BINARY: + Type = REG_BINARY; + break; + + case FLG_ADDREG_TYPE_DWORD: + Type = REG_DWORD; + break; + + case FLG_ADDREG_TYPE_NONE: + Type = REG_NONE; + break; + + default: + Type = Flags >> 16; + break; + } + + if (!(Flags & FLG_ADDREG_BINVALUETYPE) || + (Type == REG_DWORD && InfGetFieldCount (Context) == 5)) + { + PWCHAR Str = NULL; + + if (Type == REG_MULTI_SZ) + { + if (!InfGetMultiSzField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Str = RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); + if (Str == NULL) + return FALSE; + + InfGetMultiSzField (Context, 5, Str, Size, NULL); + } + + if (Flags & FLG_ADDREG_APPEND) + { + if (Str == NULL) + return TRUE; + +// append_multi_sz_value( hkey, value, str, size ); + + RtlFreeHeap (ProcessHeap, 0, Str); + return TRUE; + } + /* else fall through to normal string handling */ + } + else + { + if (!InfGetStringField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Str = RtlAllocateHeap (ProcessHeap, 0, Size * sizeof(WCHAR)); + if (Str == NULL) + return FALSE; + + InfGetStringField (Context, 5, Str, Size, NULL); + } + } + + if (Type == REG_DWORD) + { + ULONG dw = Str ? wcstol (Str, NULL, 0) : 0; + + DPRINT("setting dword %wZ to %lx\n", ValueName, dw); + + NtSetValueKey (KeyHandle, + ValueName, + 0, + Type, + (PVOID)&dw, + sizeof(ULONG)); + } + else + { + DPRINT("setting value %wZ to %S\n", ValueName, Str); + + if (Str) + { + NtSetValueKey (KeyHandle, + ValueName, + 0, + Type, + (PVOID)Str, + Size * sizeof(WCHAR)); + } + else + { + NtSetValueKey (KeyHandle, + ValueName, + 0, + Type, + (PVOID)&EmptyStr, + sizeof(WCHAR)); + } + } + RtlFreeHeap (ProcessHeap, 0, Str); + } + else /* get the binary data */ + { + PUCHAR Data = NULL; + + if (!InfGetBinaryField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Data = RtlAllocateHeap (ProcessHeap, 0, Size); + if (Data == NULL) + return FALSE; + + DPRINT("setting binary data %wZ len %lu\n", ValueName, Size); + InfGetBinaryField (Context, 5, Data, Size, NULL); + } + + NtSetValueKey (KeyHandle, + ValueName, + 0, + Type, + (PVOID)Data, + Size); + + RtlFreeHeap (ProcessHeap, 0, Data); + } + + return TRUE; +} + + +NTSTATUS +CreateNestedKey (PHANDLE KeyHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + OBJECT_ATTRIBUTES LocalObjectAttributes; + UNICODE_STRING LocalKeyName; + ULONG Disposition; + NTSTATUS Status; + ULONG FullNameLength; + ULONG Length; + PWCHAR Ptr; + HANDLE LocalKeyHandle; + + Status = NtCreateKey (KeyHandle, + KEY_ALL_ACCESS, + ObjectAttributes, + 0, + NULL, + 0, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status); + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + return Status; + + /* Copy object attributes */ + RtlCopyMemory (&LocalObjectAttributes, + ObjectAttributes, + sizeof(OBJECT_ATTRIBUTES)); + RtlCreateUnicodeString (&LocalKeyName, + ObjectAttributes->ObjectName->Buffer); + LocalObjectAttributes.ObjectName = &LocalKeyName; + FullNameLength = LocalKeyName.Length / sizeof(WCHAR); + + /* Remove the last part of the key name and try to create the key again. */ + while (Status == STATUS_OBJECT_NAME_NOT_FOUND) + { + Ptr = wcsrchr (LocalKeyName.Buffer, '\\'); + if (Ptr == NULL || Ptr == LocalKeyName.Buffer) + { + Status = STATUS_UNSUCCESSFUL; + break; + } + *Ptr = (WCHAR)0; + LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR); + + Status = NtCreateKey (&LocalKeyHandle, + KEY_ALL_ACCESS, + &LocalObjectAttributes, + 0, + NULL, + 0, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + } + + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString (&LocalKeyName); + return Status; + } + + /* Add removed parts of the key name and create them too. */ + Length = wcslen (LocalKeyName.Buffer); + while (TRUE) + { + if (Length == FullNameLength) + { + Status == STATUS_SUCCESS; + *KeyHandle = LocalKeyHandle; + break; + } + NtClose (LocalKeyHandle); + + LocalKeyName.Buffer[Length] = L'\\'; + Length = wcslen (LocalKeyName.Buffer); + LocalKeyName.Length = Length * sizeof(WCHAR); + + Status = NtCreateKey (&LocalKeyHandle, + KEY_ALL_ACCESS, + &LocalObjectAttributes, + 0, + NULL, + 0, + &Disposition); + DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status); + if (!NT_SUCCESS(Status)) + break; + } + + RtlFreeUnicodeString (&LocalKeyName); + + return Status; +} + + +/*********************************************************************** + * registry_callback + * + * Called once for each AddReg and DelReg entry in a given section. + */ +static BOOLEAN +registry_callback (HINF hInf, PCWSTR Section, BOOLEAN Delete) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + WCHAR Buffer[MAX_INF_STRING_LENGTH]; + UNICODE_STRING Name; + UNICODE_STRING Value; + PUNICODE_STRING ValuePtr; + NTSTATUS Status; + ULONG Flags; + ULONG Length; + + INFCONTEXT Context; + HANDLE KeyHandle; + BOOLEAN Ok; + + + Ok = InfFindFirstLine (hInf, Section, NULL, &Context); + + for (;Ok; Ok = InfFindNextLine (&Context, &Context)) + { + /* get root */ + if (!InfGetStringField (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL)) + continue; + if (!GetRootKey (Buffer)) + continue; + + /* get key */ + Length = wcslen (Buffer); + if (!InfGetStringField (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL)) + *Buffer = 0; + + DPRINT("KeyName: <%S>\n", Buffer); + + /* get flags */ + if (!InfGetIntField (&Context, 4, (PLONG)&Flags)) + Flags = 0; + + DPRINT("Flags: %lx\n", Flags); + + RtlInitUnicodeString (&Name, + Buffer); + + InitializeObjectAttributes (&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) + { + Status = NtOpenKey (&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtOpenKey(%wZ) failed (Status %lx)\n", &Name, Status); + continue; /* ignore if it doesn't exist */ + } + } + else + { + Status = CreateNestedKey (&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("CreateNestedKey(%wZ) failed (Status %lx)\n", &Name, Status); + continue; + } + } + + /* get value name */ + if (InfGetStringField (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL)) + { + RtlInitUnicodeString (&Value, + Buffer); + ValuePtr = &Value; + } + else + { + ValuePtr = NULL; + } + + /* and now do it */ + if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags)) + { + NtClose (KeyHandle); + return FALSE; + } + + NtClose (KeyHandle); + } + + return TRUE; +} + + +BOOLEAN +ImportRegistryFile(PWSTR Filename, + PWSTR Section, + BOOLEAN Delete) +{ + WCHAR FileNameBuffer[MAX_PATH]; + UNICODE_STRING FileName; + HINF hInf; + NTSTATUS Status; + ULONG ErrorLine; + + /* Load inf file from install media. */ + wcscpy(FileNameBuffer, SourceRootPath.Buffer); + wcscat(FileNameBuffer, L"\\install\\"); + wcscat(FileNameBuffer, Filename); + + RtlInitUnicodeString(&FileName, + FileNameBuffer); + + Status = InfOpenFile(&hInf, + &FileName, + &ErrorLine); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InfOpenFile() failed (Status %lx)\n", Status); + return FALSE; + } + + if (!registry_callback (hInf, L"AddReg", FALSE)) + { + DPRINT1("registry_callback() failed\n"); + } + + InfCloseFile (hInf); + + return TRUE; +} + + +BOOLEAN +SetInstallPathValue(PUNICODE_STRING InstallPath) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE KeyHandle; + NTSTATUS Status; + + /* Create the 'secret' InstallPath key */ + RtlInitUnicodeStringFromLiteral (&KeyName, + L"\\Registry\\Machine\\HARDWARE"); + InitializeObjectAttributes (&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey (&KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); + return FALSE; + } + + RtlInitUnicodeStringFromLiteral (&ValueName, + L"InstallPath"); + Status = NtSetValueKey (KeyHandle, + &ValueName, + 0, + REG_SZ, + (PVOID)InstallPath->Buffer, + InstallPath->Length); + NtClose(KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); + return FALSE; + } + + return TRUE; +} + +/* EOF */ diff --git a/subsys/system/usetup/registry.h b/subsys/system/usetup/registry.h new file mode 100644 index 0000000..0ac2832 --- /dev/null +++ b/subsys/system/usetup/registry.h @@ -0,0 +1,40 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/registry.h + * PURPOSE: Registry creation functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __REGISTRY_H__ +#define __REGISTRY_H__ + +BOOLEAN +ImportRegistryFile(PWSTR Filename, + PWSTR Section, + BOOLEAN Delete); + +BOOLEAN +SetInstallPathValue(PUNICODE_STRING InstallPath); + +#endif /* __REGISTRY_H__ */ + +/* EOF */ diff --git a/subsys/system/usetup/usetup.c b/subsys/system/usetup/usetup.c index 20d1883..96620cf 100644 --- a/subsys/system/usetup/usetup.c +++ b/subsys/system/usetup/usetup.c @@ -22,6 +22,7 @@ * FILE: subsys/system/usetup/usetup.c * PURPOSE: Text-mode setup * PROGRAMMER: Eric Kohl + * Casper S. Hornstrup (chorns@users.sourceforge.net) */ #include @@ -34,30 +35,39 @@ #include "console.h" #include "partlist.h" #include "inicache.h" +#include "infcache.h" #include "filequeue.h" #include "progress.h" #include "bootsup.h" +#include "registry.h" +#include "format.h" +#define NDEBUG +#include -#define START_PAGE 0 -#define INTRO_PAGE 1 -#define INSTALL_INTRO_PAGE 2 - -#define SELECT_PARTITION_PAGE 4 -#define SELECT_FILE_SYSTEM_PAGE 5 -#define CHECK_FILE_SYSTEM_PAGE 6 -#define PREPARE_COPY_PAGE 7 -#define INSTALL_DIRECTORY_PAGE 8 -#define FILE_COPY_PAGE 9 -#define REGISTRY_PAGE 10 -#define BOOT_LOADER_PAGE 11 - -#define REPAIR_INTRO_PAGE 20 - -#define SUCCESS_PAGE 100 -#define QUIT_PAGE 101 -#define REBOOT_PAGE 102 - +typedef enum _PAGE_NUMBER +{ + START_PAGE, + INTRO_PAGE, + INSTALL_INTRO_PAGE, + + SELECT_PARTITION_PAGE, + CREATE_PARTITION_PAGE, + SELECT_FILE_SYSTEM_PAGE, + FORMAT_PARTITION_PAGE, + CHECK_FILE_SYSTEM_PAGE, + PREPARE_COPY_PAGE, + INSTALL_DIRECTORY_PAGE, + FILE_COPY_PAGE, + REGISTRY_PAGE, + BOOT_LOADER_PAGE, + + REPAIR_INTRO_PAGE, + + SUCCESS_PAGE, + QUIT_PAGE, + REBOOT_PAGE, /* virtual page */ +} PAGE_NUMBER, *PPAGE_NUMBER; typedef struct _COPYCONTEXT { @@ -70,26 +80,31 @@ typedef struct _COPYCONTEXT /* GLOBALS ******************************************************************/ HANDLE ProcessHeap; +UNICODE_STRING SourceRootPath; -BOOLEAN PartDataValid; -PARTDATA PartData; +/* LOCALS *******************************************************************/ -BOOLEAN ActivePartitionValid; -PARTDATA ActivePartition; +static BOOLEAN PartDataValid; +static PARTDATA PartData; -UNICODE_STRING SourcePath; -UNICODE_STRING SourceRootPath; +static BOOLEAN ActivePartitionValid; +static PARTDATA ActivePartition; -UNICODE_STRING InstallPath; -UNICODE_STRING DestinationPath; -UNICODE_STRING DestinationArcPath; -UNICODE_STRING DestinationRootPath; +static UNICODE_STRING SourcePath; -UNICODE_STRING SystemRootPath; /* Path to the active partition */ +static UNICODE_STRING InstallPath; +static UNICODE_STRING DestinationPath; +static UNICODE_STRING DestinationArcPath; +static UNICODE_STRING DestinationRootPath; -PINICACHE IniCache; +static UNICODE_STRING SystemRootPath; /* Path to the active partition */ -HSPFILEQ SetupFileQueue = NULL; +static HINF SetupInf; + +static HSPFILEQ SetupFileQueue = NULL; + +static PPARTLIST CurrentPartitionList = NULL; +static PFILE_SYSTEM_LIST CurrentFileSystemList; /* FUNCTIONS ****************************************************************/ @@ -139,36 +154,36 @@ PopupError(PCHAR Text, Lines = 0; pnext = Text; while (TRUE) - { - p = strchr(pnext, '\n'); - if (p == NULL) { - Length = strlen(pnext); - LastLine = TRUE; - } - else - { - Length = (ULONG)(p - pnext); - LastLine = FALSE; - } + p = strchr(pnext, '\n'); + if (p == NULL) + { + Length = strlen(pnext); + LastLine = TRUE; + } + else + { + Length = (ULONG)(p - pnext); + LastLine = FALSE; + } - Lines++; - if (Length > MaxLength) - MaxLength = Length; + Lines++; + if (Length > MaxLength) + MaxLength = Length; - if (LastLine == TRUE) - break; + if (LastLine == TRUE) + break; - pnext = p + 1; - } + pnext = p + 1; + } /* Check length of status line */ if (Status != NULL) - { - Length = strlen(Status); - if (Length > MaxLength) - MaxLength = Length; - } + { + Length = strlen(Status); + if (Length > MaxLength) + MaxLength = Length; + } GetScreenSize(&xScreen, &yScreen); @@ -184,12 +199,12 @@ PopupError(PCHAR Text, /* Set screen attributes */ coPos.X = xLeft; for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++) - { - FillConsoleOutputAttribute(0x74, - Width, - coPos, - &Written); - } + { + FillConsoleOutputAttribute(0x74, + Width, + coPos, + &Written); + } /* draw upper left corner */ coPos.X = xLeft; @@ -217,25 +232,25 @@ PopupError(PCHAR Text, /* Draw right edge, inner space and left edge */ for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++) - { - coPos.X = xLeft; - FillConsoleOutputCharacter(0xB3, // '|', - 1, - coPos, - &Written); - - coPos.X = xLeft + 1; - FillConsoleOutputCharacter(' ', - Width - 2, - coPos, - &Written); - - coPos.X = xLeft + Width - 1; - FillConsoleOutputCharacter(0xB3, // '|', - 1, - coPos, - &Written); - } + { + coPos.X = xLeft; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + + coPos.X = xLeft + 1; + FillConsoleOutputCharacter(' ', + Width - 2, + coPos, + &Written); + + coPos.X = xLeft + Width - 1; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + } /* draw lower left corner */ coPos.X = xLeft; @@ -265,62 +280,62 @@ PopupError(PCHAR Text, coPos.Y = yTop + 1; pnext = Text; while (TRUE) - { - p = strchr(pnext, '\n'); - if (p == NULL) - { - Length = strlen(pnext); - LastLine = TRUE; - } - else { - Length = (ULONG)(p - pnext); - LastLine = FALSE; - } + p = strchr(pnext, '\n'); + if (p == NULL) + { + Length = strlen(pnext); + LastLine = TRUE; + } + else + { + Length = (ULONG)(p - pnext); + LastLine = FALSE; + } - if (Length != 0) - { - coPos.X = xLeft + 2; - WriteConsoleOutputCharacters(pnext, - Length, - coPos); - } + if (Length != 0) + { + coPos.X = xLeft + 2; + WriteConsoleOutputCharacters(pnext, + Length, + coPos); + } - if (LastLine == TRUE) - break; + if (LastLine == TRUE) + break; - coPos.Y++; - pnext = p + 1; - } + coPos.Y++; + pnext = p + 1; + } /* Print separator line and status text */ if (Status != NULL) - { - coPos.Y = yTop + Height - 3; - coPos.X = xLeft; - FillConsoleOutputCharacter(0xC3, // '+', - 1, - coPos, - &Written); - - coPos.X = xLeft + 1; - FillConsoleOutputCharacter(0xC4, // '-', - Width - 2, - coPos, - &Written); - - coPos.X = xLeft + Width - 1; - FillConsoleOutputCharacter(0xB4, // '+', - 1, - coPos, - &Written); - - coPos.Y++; - coPos.X = xLeft + 2; - WriteConsoleOutputCharacters(Status, - min(strlen(Status), Width - 4), - coPos); - } + { + coPos.Y = yTop + Height - 3; + coPos.X = xLeft; + FillConsoleOutputCharacter(0xC3, // '+', + 1, + coPos, + &Written); + + coPos.X = xLeft + 1; + FillConsoleOutputCharacter(0xC4, // '-', + Width - 2, + coPos, + &Written); + + coPos.X = xLeft + Width - 1; + FillConsoleOutputCharacter(0xB4, // '+', + 1, + coPos, + &Written); + + coPos.Y++; + coPos.X = xLeft + 2; + WriteConsoleOutputCharacters(Status, + min(strlen(Status), Width - 4), + coPos); + } } @@ -370,15 +385,16 @@ ConfirmQuit(PINPUT_RECORD Ir) * RETURNS * Number of the next page. */ -static ULONG +static PAGE_NUMBER StartPage(PINPUT_RECORD Ir) { NTSTATUS Status; WCHAR FileNameBuffer[MAX_PATH]; UNICODE_STRING FileName; - PINICACHESECTION Section; + INFCONTEXT Context; PWCHAR Value; + ULONG ErrorLine; SetStatusText(" Please wait..."); @@ -402,10 +418,9 @@ StartPage(PINPUT_RECORD Ir) RtlInitUnicodeString(&FileName, FileNameBuffer); - IniCache = NULL; - Status = IniCacheLoad(&IniCache, - &FileName, - TRUE); + Status = InfOpenFile(&SetupInf, + &FileName, + &ErrorLine); if (!NT_SUCCESS(Status)) { PopupError("Setup failed to load the file TXTSETUP.SIF.\n", @@ -423,9 +438,7 @@ StartPage(PINPUT_RECORD Ir) } /* Open 'Version' section */ - Section = IniCacheGetSection(IniCache, - L"Version"); - if (Section == NULL) + if (!InfFindFirstLine (SetupInf, L"Version", L"Signature", &Context)) { PopupError("Setup found a corrupt TXTSETUP.SIF.\n", "ENTER = Reboot computer"); @@ -443,10 +456,7 @@ StartPage(PINPUT_RECORD Ir) /* Get pointer 'Signature' key */ - Status = IniCacheGetKey(Section, - L"Signature", - &Value); - if (!NT_SUCCESS(Status)) + if (!InfGetData (&Context, NULL, &Value)) { PopupError("Setup found a corrupt TXTSETUP.SIF.\n", "ENTER = Reboot computer"); @@ -484,7 +494,7 @@ StartPage(PINPUT_RECORD Ir) -static ULONG +static PAGE_NUMBER RepairIntroPage(PINPUT_RECORD Ir) { SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet"); @@ -523,7 +533,7 @@ RepairIntroPage(PINPUT_RECORD Ir) * TRUE: setup/repair completed successfully * FALSE: setup/repair terminated by user */ -static ULONG +static PAGE_NUMBER IntroPage(PINPUT_RECORD Ir) { SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup"); @@ -573,7 +583,7 @@ IntroPage(PINPUT_RECORD Ir) } -static ULONG +static PAGE_NUMBER InstallIntroPage(PINPUT_RECORD Ir) { SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet"); @@ -615,7 +625,44 @@ InstallIntroPage(PINPUT_RECORD Ir) } -static ULONG +/* + * Confirm delete partition + * RETURNS + * TRUE: Delete currently selected partition. + * FALSE: Don't delete currently selected partition. + */ +static BOOL +ConfirmDeletePartition(PINPUT_RECORD Ir) +{ + BOOL Result = FALSE; + + PopupError("Are you sure you want to delete this partition?\n" + "\n" + " * Press ENTER to delete the partition.\n" + " * Press ESC to NOT delete the partition.", + "ESC = Cancel ENTER = Delete partition"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */ + { + Result = FALSE; + break; + } + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ + { + Result = TRUE; + break; + } + } + + return(Result); +} + + +static PAGE_NUMBER SelectPartitionPage(PINPUT_RECORD Ir) { WCHAR PathBuffer[MAX_PATH]; @@ -645,6 +692,12 @@ SelectPartitionPage(PINPUT_RECORD Ir) return(QUIT_PAGE); } + if (CurrentPartitionList != NULL) + { + DestroyPartitionList(CurrentPartitionList); + } + CurrentPartitionList = PartList; + SetStatusText(" ENTER = Continue F3 = Quit"); while(TRUE) @@ -671,46 +724,497 @@ SelectPartitionPage(PINPUT_RECORD Ir) { ScrollUpPartitionList(PartList); } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { PartDataValid = GetSelectedPartition(PartList, &PartData); - ActivePartitionValid = GetActiveBootPartition(PartList, - &ActivePartition); - DestroyPartitionList(PartList); + if (PartDataValid) + { + ActivePartitionValid = GetActiveBootPartition(PartList, + &ActivePartition); + + RtlFreeUnicodeString(&DestinationRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + RtlCreateUnicodeString(&DestinationRootPath, + PathBuffer); + + RtlFreeUnicodeString(&SystemRootPath); + + if (ActivePartitionValid) + { + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + ActivePartition.DiskNumber, + ActivePartition.PartNumber); + } + else + { + /* We mark the selected partition as bootable */ + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + } + RtlCreateUnicodeString(&SystemRootPath, + PathBuffer); + + return(SELECT_FILE_SYSTEM_PAGE); + } + else + { + /* FIXME: show an error dialog */ + return(SELECT_PARTITION_PAGE); + } + } + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */ + { +#ifdef ENABLE_FORMAT + /* Don't destroy the parition list here */; + return(CREATE_PARTITION_PAGE); +#endif + } + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */ + { +#ifdef ENABLE_FORMAT + if (ConfirmDeletePartition(Ir) == TRUE) + { + (BOOLEAN) DeleteSelectedPartition(CurrentPartitionList); + } + return(SELECT_PARTITION_PAGE); +#endif + } - RtlFreeUnicodeString(&DestinationRootPath); - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - PartData.DiskNumber, - PartData.PartNumber); - RtlCreateUnicodeString(&DestinationRootPath, - PathBuffer); + /* FIXME: Update status text */ - RtlFreeUnicodeString(&SystemRootPath); - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - ActivePartition.DiskNumber, - ActivePartition.PartNumber); - RtlCreateUnicodeString(&SystemRootPath, - PathBuffer); + } - return(SELECT_FILE_SYSTEM_PAGE); - } + return(SELECT_PARTITION_PAGE); +} - /* FIXME: Update status text */ +static VOID +DrawInputField(ULONG FieldLength, + SHORT Left, + SHORT Top, + PCHAR FieldContent) +{ + CHAR buf[100]; + COORD coPos; + + coPos.X = Left; + coPos.Y = Top; + memset(buf, '_', sizeof(buf)); + buf[FieldLength - strlen(FieldContent)] = 0; + strcat(buf, FieldContent); + WriteConsoleOutputCharacters(buf, + strlen(buf), + coPos); +} + +#define PARTITION_SIZE_INPUT_FIELD_LENGTH 6 + +static VOID +ShowPartitionSizeInputBox(ULONG MaxSize, + PCHAR InputBuffer, + PBOOLEAN Quit, + PBOOLEAN Cancel) +{ + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; + INPUT_RECORD Ir; + COORD coPos; + ULONG Written; + SHORT i; + CHAR buf[100]; + ULONG index; + CHAR ch; + SHORT iLeft; + SHORT iTop; + SHORT xScreen; + SHORT yScreen; + + if (Quit != NULL) + *Quit = FALSE; + if (Cancel != NULL) + *Cancel = FALSE; + + GetScreenSize(&xScreen, &yScreen); + Left = 12; + Top = 11; + Right = xScreen - 12; + Bottom = 15; + + /* draw upper left corner */ + coPos.X = Left; + coPos.Y = Top; + FillConsoleOutputCharacter(0xDA, // '+', + 1, + coPos, + &Written); + + /* draw upper edge */ + coPos.X = Left + 1; + coPos.Y = Top; + FillConsoleOutputCharacter(0xC4, // '-', + Right - Left - 1, + coPos, + &Written); + + /* draw upper right corner */ + coPos.X = Right; + coPos.Y = Top; + FillConsoleOutputCharacter(0xBF, // '+', + 1, + coPos, + &Written); + + /* draw left and right edge */ + for (i = Top + 1; i < Bottom; i++) + { + coPos.X = Left; + coPos.Y = i; + FillConsoleOutputCharacter(0xB3, // '|', + 1, + coPos, + &Written); + + coPos.X = Right; + FillConsoleOutputCharacter(0xB3, //'|', + 1, + coPos, + &Written); + } + + /* draw lower left corner */ + coPos.X = Left; + coPos.Y = Bottom; + FillConsoleOutputCharacter(0xC0, // '+', + 1, + coPos, + &Written); + + /* draw lower edge */ + coPos.X = Left + 1; + coPos.Y = Bottom; + FillConsoleOutputCharacter(0xC4, // '-', + Right - Left - 1, + coPos, + &Written); + + /* draw lower right corner */ + coPos.X = Right; + coPos.Y = Bottom; + FillConsoleOutputCharacter(0xD9, // '+', + 1, + coPos, + &Written); + /* Print message */ + coPos.X = Left + 2; + coPos.Y = Top + 2; + strcpy(buf, "Size of new partition:"); + iLeft = coPos.X + strlen(buf) + 1; + iTop = coPos.Y; + WriteConsoleOutputCharacters(buf, + strlen(buf), + coPos); + + sprintf(buf, "MB (max. %d MB)", MaxSize / (1024 * 1024)); + coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1; + coPos.Y = iTop; + WriteConsoleOutputCharacters(buf, + strlen(buf), + coPos); + + buf[0] = 0; + index = 0; + DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf); + + while(TRUE) + { + ConInKey(&Ir); + if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + { + if (Quit != NULL) + *Quit = TRUE; + buf[0] = 0; + break; + } + else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ + { + break; + } + else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */ + { + if (Cancel != NULL) + *Cancel = FALSE; + buf[0] = 0; + break; + } + else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) && (index > 0)) /* BACKSPACE */ + { + index--; + buf[index] = 0; + DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf); + } + else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00) + && (index < PARTITION_SIZE_INPUT_FIELD_LENGTH)) + { + ch = Ir.Event.KeyEvent.uChar.AsciiChar; + if ((ch >= '0') && (ch <= '9')) + { + buf[index] = ch; + index++; + buf[index] = 0; + DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf); + } + } } + strcpy(InputBuffer, buf); +} + - DestroyPartitionList(PartList); +static PAGE_NUMBER +CreatePartitionPage(PINPUT_RECORD Ir) +{ + BOOLEAN Valid; + WCHAR PathBuffer[MAX_PATH]; + PPARTLIST PartList; + PPARTENTRY PartEntry; + SHORT xScreen; + SHORT yScreen; + BOOLEAN Quit; + BOOLEAN Cancel; + CHAR InputBuffer[50]; + ULONG MaxSize; + ULONGLONG PartSize; + + SetTextXY(6, 8, "You have chosen to create a new partition in the unused disk space."); + SetTextXY(6, 9, "Please enter the size of the new partition in megabytes."); + + SetStatusText(" Please wait..."); + + GetScreenSize(&xScreen, &yScreen); + + PartList = CurrentPartitionList; + + SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit"); + + PartEntry = &PartList->DiskArray[PartList->CurrentDisk].PartArray[PartList->CurrentPartition]; + while (TRUE) + { + MaxSize = PartEntry->PartSize; + ShowPartitionSizeInputBox(MaxSize, InputBuffer, &Quit, &Cancel); + if (Quit == TRUE) + { + if (ConfirmQuit(Ir) == TRUE) + { + DestroyPartitionList(PartList); + return(QUIT_PAGE); + } + } + else if (Cancel == TRUE) + { + break; + } + else + { + PartSize = atoi(InputBuffer); + if (PartSize < 1) + { + // Too small + continue; + } + /* Convert to bytes */ + PartSize *= 1024 * 1024; + + if (PartSize > PartEntry->PartSize) + { + // Too large + continue; + } + + assert(PartEntry->Unpartitioned == TRUE); + PartEntry->PartType = PARTITION_ENTRY_UNUSED; + PartEntry->Used = TRUE; + + PartDataValid = GetSelectedPartition(PartList, + &PartData); + if (PartDataValid) + { + PartData.CreatePartition = TRUE; + PartData.NewPartSize = PartSize; + + ActivePartitionValid = GetActiveBootPartition(PartList, + &ActivePartition); + + RtlFreeUnicodeString(&DestinationRootPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + RtlCreateUnicodeString(&DestinationRootPath, + PathBuffer); + + RtlFreeUnicodeString(&SystemRootPath); + + if (ActivePartitionValid) + { + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + ActivePartition.DiskNumber, + ActivePartition.PartNumber); + } + else + { + /* We mark the selected partition as bootable */ + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition%lu", + PartData.DiskNumber, + PartData.PartNumber); + } + RtlCreateUnicodeString(&SystemRootPath, + PathBuffer); + + return(SELECT_FILE_SYSTEM_PAGE); + } + else + { + /* FIXME: show an error dialog */ + return(SELECT_PARTITION_PAGE); + } + } + } return(SELECT_PARTITION_PAGE); } -static ULONG +static PFILE_SYSTEM_LIST +CreateFileSystemList(SHORT Left, + SHORT Top, + BOOLEAN ForceFormat, + FILE_SYSTEM ForceFileSystem) +{ + PFILE_SYSTEM_LIST List; + + List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST)); + if (List == NULL) + return(NULL); + + List->Left = Left; + List->Top = Top; + +#ifdef ENABLE_FORMAT + List->FileSystemCount = 1; +#else + List->FileSystemCount = 0; +#endif + if (ForceFormat) + { + List->CurrentFileSystem = ForceFileSystem; + } + else + { + List->FileSystemCount++; + List->CurrentFileSystem = FsKeep; + } + return(List); +} + + +static VOID +DestroyFileSystemList(PFILE_SYSTEM_LIST List) +{ + RtlFreeHeap(ProcessHeap, 0, List); +} + + +static VOID +DrawFileSystemList(PFILE_SYSTEM_LIST List) +{ + COORD coPos; + ULONG Written; + ULONG index; + + index = 0; + +#ifdef ENABLE_FORMAT + coPos.X = List->Left; + coPos.Y = List->Top + index; + FillConsoleOutputAttribute(0x17, + 50, + coPos, + &Written); + FillConsoleOutputCharacter(' ', + 50, + coPos, + &Written); + + if (List->CurrentFileSystem == FsFat) + { + SetInvertedTextXY(List->Left, List->Top + index, " Format partition as FAT file system "); + } + else + { + SetTextXY(List->Left, List->Top + index, " Format partition as FAT file system "); + } + index++; +#endif + + coPos.X = List->Left; + coPos.Y = List->Top + index; + FillConsoleOutputAttribute(0x17, + 50, + coPos, + &Written); + FillConsoleOutputCharacter(' ', + 50, + coPos, + &Written); + + if (List->CurrentFileSystem == FsKeep) + { + SetInvertedTextXY(List->Left, List->Top + index, " Keep current file system (no changes) "); + } + else + { + SetTextXY(List->Left, List->Top + index, " Keep current file system (no changes) "); + } +} + + +static VOID +ScrollDownFileSystemList(PFILE_SYSTEM_LIST List) +{ + if ((ULONG) List->CurrentFileSystem < List->FileSystemCount - 1) + { + (ULONG) List->CurrentFileSystem++; + DrawFileSystemList(List); + } +} + + +static VOID +ScrollUpFileSystemList(PFILE_SYSTEM_LIST List) +{ + if ((ULONG) List->CurrentFileSystem > 0) + { + (ULONG) List->CurrentFileSystem--; + DrawFileSystemList(List); + } +} + + +static PAGE_NUMBER SelectFileSystemPage(PINPUT_RECORD Ir) { + PFILE_SYSTEM_LIST FileSystemList; ULONGLONG DiskSize; ULONGLONG PartSize; PCHAR DiskUnit; @@ -764,6 +1268,10 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { PartType = "NTFS"; /* FIXME: Not quite correct! */ } + else if (PartData.PartType == PARTITION_ENTRY_UNUSED) + { + PartType = "Unused"; + } else { PartType = "Unknown"; @@ -771,7 +1279,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) SetTextXY(6, 8, "Setup will install ReactOS on"); - PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s on", + PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of", PartData.PartNumber, PartSize, PartUnit, @@ -793,9 +1301,16 @@ SelectFileSystemPage(PINPUT_RECORD Ir) SetTextXY(8, 21, "\xfa Press ENTER to format the partition."); SetTextXY(8, 23, "\xfa Press ESC to select another partition."); - /* FIXME: use a real list later */ - SetInvertedTextXY(6, 26, " Keep current file system (no changes) "); + FileSystemList = CreateFileSystemList(6, 26, FALSE, FsKeep); + if (FileSystemList == NULL) + { + /* FIXME: show an error dialog */ + return(QUIT_PAGE); + } + + CurrentFileSystemList = FileSystemList; + DrawFileSystemList(FileSystemList); SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit"); @@ -813,17 +1328,111 @@ SelectFileSystemPage(PINPUT_RECORD Ir) else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */ { + DestroyFileSystemList(FileSystemList); return(SELECT_PARTITION_PAGE); } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */ + { + ScrollDownFileSystemList(FileSystemList); + } + else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */ + { + ScrollUpFileSystemList(FileSystemList); + } + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ { - return(CHECK_FILE_SYSTEM_PAGE); + if (FileSystemList->CurrentFileSystem == FsKeep) + { + return(CHECK_FILE_SYSTEM_PAGE); + } + else + { + return(FORMAT_PARTITION_PAGE); + } } } - - return(SELECT_FILE_SYSTEM_PAGE); } +static ULONG +FormatPartitionPage(PINPUT_RECORD Ir) +{ + NTSTATUS Status; + ULONG PartType; + BOOLEAN Valid; + + SetTextXY(6, 8, "Format partition"); + + SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue."); + + SetStatusText(" ENTER = Continue F3 = Quit"); + + while(TRUE) + { + ConInKey(Ir); + + if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + { + if (ConfirmQuit(Ir) == TRUE) + { + return(QUIT_PAGE); + } + break; + } + else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */ + { + SetStatusText(" Please wait ..."); + + switch (CurrentFileSystemList->CurrentFileSystem) + { +#ifdef ENABLE_FORMAT + case FsFat: + PartType = PARTITION_FAT32_XINT13; + break; +#endif + case FsKeep: + break; + default: + return QUIT_PAGE; + } + + if (PartData.CreatePartition) + { + Valid = CreateSelectedPartition(CurrentPartitionList, PartType, PartData.NewPartSize); + if (!Valid) + { + DPRINT("CreateSelectedPartition() failed\n"); + /* FIXME: show an error dialog */ + return(QUIT_PAGE); + } + } + + switch (CurrentFileSystemList->CurrentFileSystem) + { +#ifdef ENABLE_FORMAT + case FsFat: + Status = FormatPartition(&DestinationRootPath); + if (!NT_SUCCESS(Status)) + { + DPRINT1("FormatPartition() failed with status 0x%.08x\n", Status); + /* FIXME: show an error dialog */ + return(QUIT_PAGE); + } + break; +#endif + case FsKeep: + break; + default: + return QUIT_PAGE; + } + return(INSTALL_DIRECTORY_PAGE); + } + } + + return(INSTALL_DIRECTORY_PAGE); +} static ULONG CheckFileSystemPage(PINPUT_RECORD Ir) @@ -858,20 +1467,18 @@ CheckFileSystemPage(PINPUT_RECORD Ir) } -static ULONG +static PAGE_NUMBER InstallDirectoryPage(PINPUT_RECORD Ir) { - PINICACHESECTION Section; WCHAR PathBuffer[MAX_PATH]; WCHAR InstallDir[51]; PWCHAR DefaultPath; + INFCONTEXT Context; ULONG Length; NTSTATUS Status; - /* Open 'SetupData' section */ - Section = IniCacheGetSection(IniCache, - L"SetupData"); - if (Section == NULL) + /* Search for 'DefaultPath' in the 'SetupData' section */ + if (!InfFindFirstLine (SetupInf, L"SetupData", L"DefaultPath", &Context)) { PopupError("Setup failed to find the 'SetupData' section\n" "in TXTSETUP.SIF.\n", @@ -888,17 +1495,14 @@ InstallDirectoryPage(PINPUT_RECORD Ir) } } - /* Read the 'DefaultPath' key */ - Status = IniCacheGetKey(Section, - L"DefaultPath", - &DefaultPath); - if (!NT_SUCCESS(Status)) + /* Read the 'DefaultPath' data */ + if (InfGetData (&Context, NULL, &DefaultPath)) { - wcscpy(InstallDir, L"\\reactos"); + wcscpy(InstallDir, DefaultPath); } else { - wcscpy(InstallDir, DefaultPath); + wcscpy(InstallDir, L"\\ReactOS"); } Length = wcslen(InstallDir); @@ -982,13 +1586,12 @@ InstallDirectoryPage(PINPUT_RECORD Ir) } -static ULONG +static PAGE_NUMBER PrepareCopyPage(PINPUT_RECORD Ir) { WCHAR PathBuffer[MAX_PATH]; - PINICACHESECTION DirSection; - PINICACHESECTION FilesSection; - PINICACHEITERATOR Iterator; + INFCONTEXT FilesContext; + INFCONTEXT DirContext; PWCHAR KeyName; PWCHAR KeyValue; ULONG Length; @@ -1008,7 +1611,6 @@ PrepareCopyPage(PINPUT_RECORD Ir) // SetStatusText(" Please wait..."); - /* * Build the file copy list */ @@ -1016,112 +1618,86 @@ PrepareCopyPage(PINPUT_RECORD Ir) // SetInvertedTextXY(8, 12, "Build file copy list"); - /* Open 'Directories' section */ - DirSection = IniCacheGetSection(IniCache, - L"Directories"); - if (DirSection == NULL) - { - PopupError("Setup failed to find the 'Directories' section\n" - "in TXTSETUP.SIF.\n", - "ENTER = Reboot computer"); - - while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } - } - } - /* Open 'SourceFiles' section */ - FilesSection = IniCacheGetSection(IniCache, - L"SourceFiles"); - if (FilesSection == NULL) - { - PopupError("Setup failed to find the 'SourceFiles' section\n" - "in TXTSETUP.SIF.\n", - "ENTER = Reboot computer"); + /* Search for the 'SourceFiles' section */ + if (!InfFindFirstLine (SetupInf, L"SourceFiles", NULL, &FilesContext)) + { + PopupError("Setup failed to find the 'SourceFiles' section\n" + "in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - return(QUIT_PAGE); + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } - } - } + } /* Create the file queue */ SetupFileQueue = SetupOpenFileQueue(); if (SetupFileQueue == NULL) - { - PopupError("Setup failed to open the copy file queue.\n", - "ENTER = Reboot computer"); + { + PopupError("Setup failed to open the copy file queue.\n", + "ENTER = Reboot computer"); while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - return(QUIT_PAGE); + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } - } - } + } /* * Enumerate the files in the 'SourceFiles' section * and add them to the file queue. */ - Iterator = IniCacheFindFirstValue(FilesSection, - &FileKeyName, - &FileKeyValue); - if (Iterator != NULL) - { - do + do { + if (!InfGetData (&FilesContext, &FileKeyName, &FileKeyValue)) + break; + DPRINT1("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue); /* Lookup target directory */ - Status = IniCacheGetKey(DirSection, - FileKeyValue, - &DirKeyValue); - if (!NT_SUCCESS(Status)) - { - /* FIXME: Handle error! */ - DPRINT1("IniCacheGetKey() failed (Status 0x%lX)\n", Status); - } + if (!InfFindFirstLine (SetupInf, L"Directories", FileKeyValue, &DirContext)) + { + /* FIXME: Handle error! */ + DPRINT1("InfFindFirstLine() failed\n"); + break; + } - if (SetupQueueCopy(SetupFileQueue, - SourceRootPath.Buffer, - L"\\install", - FileKeyName, - DirKeyValue, - NULL) == FALSE) - { - /* FIXME: Handle error! */ - DPRINT1("SetupQueueCopy() failed\n"); - } - } - while (IniCacheFindNextValue(Iterator, &FileKeyName, &FileKeyValue)); + if (!InfGetData (&DirContext, NULL, &DirKeyValue)) + { + /* FIXME: Handle error! */ + DPRINT1("InfGetData() failed\n"); + break; + } - IniCacheFindClose(Iterator); - } + if (!SetupQueueCopy(SetupFileQueue, + SourceRootPath.Buffer, + L"\\install", + FileKeyName, + DirKeyValue, + NULL)) + { + /* FIXME: Handle error! */ + DPRINT1("SetupQueueCopy() failed\n"); + } + } + while (InfFindNextLine(&FilesContext, &FilesContext)); - /* Report that the file queue has been built */ -// SetTextXY(8, 12, "Build file copy list"); -// SetHighlightedTextXY(50, 12, "Done"); - /* create directories */ + /* Create directories */ SetStatusText(" Creating directories..."); -// SetInvertedTextXY(8, 14, "Create directories"); - /* * FIXME: @@ -1134,110 +1710,94 @@ PrepareCopyPage(PINPUT_RECORD Ir) /* Remove trailing backslash */ Length = wcslen(PathBuffer); if ((Length > 0) && (PathBuffer[Length - 1] == '\\')) - PathBuffer[Length - 1] = 0; + { + PathBuffer[Length - 1] = 0; + } /* Create the install directory */ Status = CreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); - - PopupError("Setup could not create the install directory.", - "ENTER = Reboot computer"); - - while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } - } - } - - - /* Enumerate the directory values and create the subdirectories */ - Iterator = IniCacheFindFirstValue(DirSection, - &KeyName, - &KeyValue); - if (Iterator != NULL) - { - do { - if (KeyValue[0] == L'\\' && KeyValue[1] != 0) - { - DPRINT("Absolute Path: '%S'\n", KeyValue); - - wcscpy(PathBuffer, DestinationRootPath.Buffer); - wcscat(PathBuffer, KeyValue); - - DPRINT("FullPath: '%S'\n", PathBuffer); - } - else if (KeyValue[0] != L'\\') - { - DPRINT("RelativePath: '%S'\n", KeyValue); - wcscpy(PathBuffer, DestinationPath.Buffer); - wcscat(PathBuffer, L"\\"); - wcscat(PathBuffer, KeyValue); - - DPRINT("FullPath: '%S'\n", PathBuffer); - - Status = CreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + PopupError("Setup could not create the install directory.", + "ENTER = Reboot computer"); - PopupError("Setup could not create install directories.", - "ENTER = Reboot computer"); + while(TRUE) + { + ConInKey(Ir); - while(TRUE) + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - IniCacheFindClose(Iterator); - return(QUIT_PAGE); - } + return(QUIT_PAGE); } - } - } + } } - while (IniCacheFindNextValue(Iterator, &KeyName, &KeyValue)); - - IniCacheFindClose(Iterator); - } - return(FILE_COPY_PAGE); - -#if 0 - SetTextXY(8, 14, "Create directories"); - SetHighlightedTextXY(50, 14, "Done"); + /* Search for the 'Directories' section */ + if (!InfFindFirstLine(SetupInf, L"Directories", NULL, &DirContext)) + { + PopupError("Setup failed to find the 'Directories' section\n" + "in TXTSETUP.SIF.\n", + "ENTER = Reboot computer"); + while(TRUE) + { + ConInKey(Ir); - SetStatusText(" ENTER = Continue F3 = Quit"); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - while(TRUE) + /* Enumerate the directory values and create the subdirectories */ + do { - ConInKey(Ir); + if (!InfGetData (&DirContext, NULL, &KeyValue)) + break; - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + if (KeyValue[0] == L'\\' && KeyValue[1] != 0) { - if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); - break; + DPRINT("Absolute Path: '%S'\n", KeyValue); + + wcscpy(PathBuffer, DestinationRootPath.Buffer); + wcscat(PathBuffer, KeyValue); + + DPRINT("FullPath: '%S'\n", PathBuffer); } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + else if (KeyValue[0] != L'\\') { - return(FILE_COPY_PAGE); + DPRINT("RelativePath: '%S'\n", KeyValue); + wcscpy(PathBuffer, DestinationPath.Buffer); + wcscat(PathBuffer, L"\\"); + wcscat(PathBuffer, KeyValue); + + DPRINT("FullPath: '%S'\n", PathBuffer); + + Status = CreateDirectory(PathBuffer); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) + { + DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + PopupError("Setup could not create install directories.", + "ENTER = Reboot computer"); + + while (TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } } } + while (InfFindNextLine (&DirContext, &DirContext)); - return(PREPARE_COPY_PAGE); -#endif + return(FILE_COPY_PAGE); } @@ -1252,34 +1812,33 @@ FileCopyCallback(PVOID Context, CopyContext = (PCOPYCONTEXT)Context; switch (Notification) - { - case SPFILENOTIFY_STARTSUBQUEUE: - CopyContext->TotalOperations = (ULONG)Param2; - ProgressSetStepCount(CopyContext->ProgressBar, - CopyContext->TotalOperations); - break; - - case SPFILENOTIFY_STARTCOPY: - /* Display copy message */ - PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1); - - PrintTextXYN(6, 18, 60, "File %lu of %lu", - CopyContext->CompletedOperations + 1, - CopyContext->TotalOperations); - break; - - - case SPFILENOTIFY_ENDCOPY: - CopyContext->CompletedOperations++; - ProgressNextStep(CopyContext->ProgressBar); - break; - } + { + case SPFILENOTIFY_STARTSUBQUEUE: + CopyContext->TotalOperations = (ULONG)Param2; + ProgressSetStepCount(CopyContext->ProgressBar, + CopyContext->TotalOperations); + break; + + case SPFILENOTIFY_STARTCOPY: + /* Display copy message */ + PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1); + + PrintTextXYN(6, 18, 60, "File %lu of %lu", + CopyContext->CompletedOperations + 1, + CopyContext->TotalOperations); + break; + + case SPFILENOTIFY_ENDCOPY: + CopyContext->CompletedOperations++; + ProgressNextStep(CopyContext->ProgressBar); + break; + } return(0); } -static ULONG +static PAGE_NUMBER FileCopyPage(PINPUT_RECORD Ir) { COPYCONTEXT CopyContext; @@ -1310,165 +1869,131 @@ FileCopyPage(PINPUT_RECORD Ir) DestroyProgressBar(CopyContext.ProgressBar); return(REGISTRY_PAGE); - -#if 0 - SetStatusText(" ENTER = Continue F3 = Quit"); - - while(TRUE) - { - ConInKey(Ir); - - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ - { - if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); - break; - } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(REGISTRY_PAGE); - } - } - - return(FILE_COPY_PAGE); -#endif } - -static ULONG +static PAGE_NUMBER RegistryPage(PINPUT_RECORD Ir) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - UNICODE_STRING ValueName; - HANDLE KeyHandle; + INFCONTEXT InfContext; NTSTATUS Status; - SetTextXY(6, 8, "Setup initializes system settings"); - + PWSTR Action; + PWSTR File; + PWSTR Section; + BOOLEAN Delete; -// SetTextXY(6, 12, "Create registry hives"); -// SetTextXY(6, 14, "Update registry hives"); - - -// SetStatusText(" Please wait..."); + SetTextXY(6, 8, "Setup is updating the system configuration"); SetStatusText(" Creating registry hives..."); - /* Create the 'secret' InstallPath key */ - RtlInitUnicodeStringFromLiteral(&KeyName, - L"\\Registry\\Machine\\HARDWARE"); - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = NtOpenKey(&KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenKey() failed (Status %lx)\n", Status); - PopupError("Setup failed to open the HARDWARE registry key.", - "ENTER = Reboot computer"); + if (!SetInstallPathValue(&DestinationPath)) + { + DPRINT("SetInstallPathValue() failed\n"); + PopupError("Setup failed to set the initialize the registry.", + "ENTER = Reboot computer"); while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - return(QUIT_PAGE); - } - } - } + ConInKey(Ir); - RtlInitUnicodeStringFromLiteral(&ValueName, - L"InstallPath"); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - Status = NtSetValueKey(KeyHandle, - &ValueName, - 0, - REG_SZ, - (PVOID)DestinationPath.Buffer, - DestinationPath.Length); - NtClose(KeyHandle); + /* Create the default hives */ + Status = NtInitializeRegistry(TRUE); if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); - PopupError("Setup failed to set the \'InstallPath\' registry value.", - "ENTER = Reboot computer"); + { + DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status); + PopupError("Setup failed to create the registry hives.", + "ENTER = Reboot computer"); while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - return(QUIT_PAGE); + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } - } - } + } - /* Create the standard hives */ - Status = NtInitializeRegistry(TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status); - PopupError("Setup failed to initialize the registry.", - "ENTER = Reboot computer"); + /* Update registry */ + SetStatusText(" Updating registry hives..."); - while(TRUE) - { - ConInKey(Ir); + if (!InfFindFirstLine(SetupInf, L"HiveInfs.Install", NULL, &InfContext)) + { + DPRINT1("InfFindFirstLine() failed\n"); + PopupError("Setup failed to find the registry data files.", + "ENTER = Reboot computer"); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + while(TRUE) { - return(QUIT_PAGE); - } - } - } + ConInKey(Ir); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } - /* Update registry */ - SetStatusText(" Updating registry hives..."); + do + { + InfGetDataField (&InfContext, 0, &Action); + InfGetDataField (&InfContext, 1, &File); + InfGetDataField (&InfContext, 2, &Section); - /* FIXME: Create key '\Registry\Machine\System\Setup' */ + DPRINT1("Action: %S File: %S Section %S\n", Action, File, Section); - /* FIXME: Create value 'SystemSetupInProgress' */ + if (!_wcsicmp (Action, L"AddReg")) + { + Delete = FALSE; + } + else if (!_wcsicmp (Action, L"DelReg")) + { + Delete = TRUE; + } + else + { + continue; + } + SetStatusText(" Importing %S...", File); - return(BOOT_LOADER_PAGE); + if (!ImportRegistryFile(File, Section, Delete)) + { + DPRINT1("Importing %S failed\n", File); -#if 0 - SetStatusText(" ENTER = Continue F3 = Quit"); + PopupError("Setup failed to import a hive file.", + "ENTER = Reboot computer"); - while(TRUE) - { - ConInKey(Ir); + while(TRUE) + { + ConInKey(Ir); - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ - { - if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); - break; - } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(BOOT_LOADER_PAGE); + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } } - } + while (InfFindNextLine (&InfContext, &InfContext)); - return(REGISTRY_PAGE); -#endif + SetStatusText(" Done..."); + + return(BOOT_LOADER_PAGE); } -static ULONG +static PAGE_NUMBER BootLoaderPage(PINPUT_RECORD Ir) { WCHAR SrcPath[MAX_PATH]; @@ -1476,99 +2001,144 @@ BootLoaderPage(PINPUT_RECORD Ir) PINICACHE IniCache; PINICACHESECTION IniSection; NTSTATUS Status; + BOOLEAN InstallMBR = FALSE; SetTextXY(6, 8, "Installing the boot loader"); SetStatusText(" Please wait..."); if (ActivePartitionValid == FALSE) - { - DPRINT1("Error: no active partition found\n"); - PopupError("Setup could not find an active partiton\n", - "ENTER = Reboot computer"); - - while(TRUE) { - ConInKey(Ir); + /* Mark the chosen partition as active since there is no active + partition now */ + + if (!MarkPartitionActive(PartData.DiskNumber, + PartData.PartNumber, &ActivePartition)) + { + PopupError("Setup could not mark the system partiton active\n", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } + InstallMBR = TRUE; + } - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } + if (InstallMBR) + { + WCHAR PathBuffer[MAX_PATH]; + UNICODE_STRING SystemRootMBRPath; + + RtlFreeUnicodeString(&SystemRootMBRPath); + swprintf(PathBuffer, + L"\\Device\\Harddisk%lu\\Partition0", + PartData.DiskNumber); + RtlCreateUnicodeString(&SystemRootMBRPath, + PathBuffer); + + /* Install MBR bootcode */ + wcscpy(SrcPath, SourceRootPath.Buffer); + wcscat(SrcPath, L"\\loader\\dosmbr.bin"); + + DPRINT1("Install MBR bootcode: %S ==> %S\n", SrcPath, SystemRootMBRPath.Buffer); + Status = InstallMBRBootCodeToDisk(SrcPath, + SystemRootMBRPath.Buffer); + if (!NT_SUCCESS(Status)) + { + DPRINT1("InstallMBRBootCodeToDisk() failed (Status %lx)\n", Status); + PopupError("Setup failed to install the MBR bootcode.", + "ENTER = Reboot computer"); + + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } + } } - } if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED) - { - DPRINT1("Error: active partition invalid (unused)\n"); - PopupError("The active partition is unused (invalid).\n", - "ENTER = Reboot computer"); - - while(TRUE) { - ConInKey(Ir); + DPRINT1("Error: active partition invalid (unused)\n"); + PopupError("The active partition is unused (invalid).\n", + "ENTER = Reboot computer"); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } } - } if (ActivePartition.PartType == 0x0A) - { - /* OS/2 boot manager partition */ - DPRINT1("Found OS/2 boot manager partition\n"); - PopupError("Setup found an OS/2 boot manager partiton.\n" - "The OS/2 boot manager is not supported yet!", - "ENTER = Reboot computer"); - - while(TRUE) { - ConInKey(Ir); + /* OS/2 boot manager partition */ + DPRINT1("Found OS/2 boot manager partition\n"); + PopupError("Setup found an OS/2 boot manager partiton.\n" + "The OS/2 boot manager is not supported yet!", + "ENTER = Reboot computer"); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } } - } else if (ActivePartition.PartType == 0x83) - { - /* Linux ext2 partition */ - DPRINT1("Found Linux ext2 partition\n"); - PopupError("Setup found a Linux ext2 partiton.\n" - "Linux ext2 partitions are not supported yet!", - "ENTER = Reboot computer"); - - while(TRUE) { - ConInKey(Ir); + /* Linux ext2 partition */ + DPRINT1("Found Linux ext2 partition\n"); + PopupError("Setup found a Linux ext2 partiton.\n" + "Linux ext2 partitions are not supported yet!", + "ENTER = Reboot computer"); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } + while(TRUE) + { + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } } - } else if (ActivePartition.PartType == PARTITION_IFS) - { + { /* NTFS partition */ - DPRINT1("Found NTFS partition\n"); - PopupError("Setup found an NTFS partiton.\n" - "NTFS partitions are not supported yet!", - "ENTER = Reboot computer"); + DPRINT1("Found NTFS partition\n"); + PopupError("Setup found an NTFS partiton.\n" + "NTFS partitions are not supported yet!", + "ENTER = Reboot computer"); - while(TRUE) - { - ConInKey(Ir); + while(TRUE) + { + ConInKey(Ir); - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } + } } - } else if ((ActivePartition.PartType == PARTITION_FAT_12) || (ActivePartition.PartType == PARTITION_FAT_16) || (ActivePartition.PartType == PARTITION_HUGE) || @@ -2075,53 +2645,30 @@ BootLoaderPage(PINPUT_RECORD Ir) } } else - { - /* Unknown partition */ - DPRINT1("Unknown partition found\n"); - PopupError("Setup found an unknown partiton type.\n" - "This partition type is not supported!", - "ENTER = Reboot computer"); - - while(TRUE) - { - ConInKey(Ir); - - if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ - { - return(QUIT_PAGE); - } - } - } - - return(SUCCESS_PAGE); - -#if 0 - SetStatusText(" ENTER = Continue F3 = Quit"); - - while(TRUE) { - ConInKey(Ir); + /* Unknown partition */ + DPRINT1("Unknown partition found\n"); + PopupError("Setup found an unknown partiton type.\n" + "This partition type is not supported!", + "ENTER = Reboot computer"); - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ - { - if (ConfirmQuit(Ir) == TRUE) - return(QUIT_PAGE); - break; - } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + while(TRUE) { - return(SUCCESS_PAGE); + ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return(QUIT_PAGE); + } } } - return(BOOT_LOADER_PAGE); -#endif + return(SUCCESS_PAGE); } -static ULONG +static PAGE_NUMBER QuitPage(PINPUT_RECORD Ir) { SetTextXY(10, 6, "ReactOS is not completely installed"); @@ -2145,7 +2692,7 @@ QuitPage(PINPUT_RECORD Ir) } -static ULONG +static PAGE_NUMBER SuccessPage(PINPUT_RECORD Ir) { SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully."); @@ -2174,7 +2721,7 @@ NtProcessStartup(PPEB Peb) { NTSTATUS Status; INPUT_RECORD Ir; - ULONG Page; + PAGE_NUMBER Page; RtlNormalizeProcessParams(Peb->ProcessParameters); @@ -2240,10 +2787,18 @@ NtProcessStartup(PPEB Peb) Page = SelectPartitionPage(&Ir); break; + case CREATE_PARTITION_PAGE: + Page = CreatePartitionPage(&Ir); + break; + case SELECT_FILE_SYSTEM_PAGE: Page = SelectFileSystemPage(&Ir); break; + case FORMAT_PARTITION_PAGE: + Page = FormatPartitionPage(&Ir); + break; + case CHECK_FILE_SYSTEM_PAGE: Page = CheckFileSystemPage(&Ir); break; diff --git a/subsys/system/usetup/usetup.h b/subsys/system/usetup/usetup.h index b4fc855..2fab152 100644 --- a/subsys/system/usetup/usetup.h +++ b/subsys/system/usetup/usetup.h @@ -27,6 +27,8 @@ #ifndef __USETUP_H__ #define __USETUP_H__ +// Define to allow creating a new partition and format it +//#define ENABLE_FORMAT #define DPRINT1(args...) do { DbgPrint("(%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0); #define CHECKPOINT1 do { DbgPrint("%s:%d\n",__FILE__,__LINE__); } while(0); @@ -34,9 +36,28 @@ #define DPRINT(args...) #define CHECKPOINT +typedef enum +{ +#ifdef ENABLE_FORMAT + FsFat = 0, + FsKeep = 1 +#else + FsKeep = 0 +#endif +} FILE_SYSTEM; + +typedef struct _FILE_SYSTEM_LIST +{ + SHORT Left; + SHORT Top; + FILE_SYSTEM CurrentFileSystem; + ULONG FileSystemCount; +} FILE_SYSTEM_LIST, *PFILE_SYSTEM_LIST; extern HANDLE ProcessHeap; +extern UNICODE_STRING SourceRootPath; + #endif /* __USETUP_H__*/ diff --git a/subsys/system/winlogon/makefile b/subsys/system/winlogon/makefile index 031b6c4..ea9b972 100644 --- a/subsys/system/winlogon/makefile +++ b/subsys/system/winlogon/makefile @@ -12,7 +12,7 @@ TARGET_INSTALLDIR = system32 TARGET_SDKLIBS = ntdll.a kernel32.a user32.a -TARGET_OBJECTS = $(TARGET_NAME).o +TARGET_OBJECTS = $(TARGET_NAME).o setup.o include $(PATH_TO_TOP)/rules.mak diff --git a/subsys/system/winlogon/setup.c b/subsys/system/winlogon/setup.c new file mode 100644 index 0000000..62434c6 --- /dev/null +++ b/subsys/system/winlogon/setup.c @@ -0,0 +1,195 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS winlogon + * FILE: subsys/system/winlogon/setup.h + * PURPOSE: Setup support functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include +#include + +#include "setup.h" + +#define NDEBUG +#include + + +/* FUNCTIONS ****************************************************************/ + +DWORD +GetSetupType(VOID) +{ + DWORD dwError; + HANDLE hKey; + DWORD dwType; + DWORD dwSize; + DWORD dwSetupType; + + dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SYSTEM\\Setup", //TEXT("SYSTEM\\Setup"), + 0, + KEY_QUERY_VALUE, + &hKey); + if (dwError != ERROR_SUCCESS) + { + return 0; + } + + dwSize = sizeof(DWORD); + dwError = RegQueryValueEx (hKey, + "SetupType", //TEXT("SetupType"), + NULL, + &dwType, + (LPBYTE)&dwSetupType, + &dwSize); + RegCloseKey (hKey); + if (dwError != ERROR_SUCCESS || dwType != REG_DWORD) + { + return 0; + } + + return dwSetupType; +} + + +BOOL +SetSetupType (DWORD dwSetupType) +{ + DWORD dwError; + HANDLE hKey; + + dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "SYSTEM\\Setup", //TEXT("SYSTEM\\Setup"), + 0, + KEY_QUERY_VALUE, + &hKey); + if (dwError != ERROR_SUCCESS) + { + return FALSE; + } + + dwError = RegSetValueEx (hKey, + "SetupType", //TEXT("SetupType"), + 0, + REG_DWORD, + (LPBYTE)&dwSetupType, + sizeof(DWORD)); + RegCloseKey (hKey); + if (dwError != ERROR_SUCCESS) + { + return FALSE; + } + + return TRUE; +} + + +BOOL +RunSetup (VOID) +{ + PROCESS_INFORMATION ProcessInformation; + STARTUPINFO StartupInfo; + CHAR CommandLine[MAX_PATH]; + BOOLEAN Result; + DWORD dwError; + HANDLE hKey; + DWORD dwType; + DWORD dwSize; + DWORD dwExitCode; + + DPRINT ("RunSetup() called\n"); + + dwError = RegOpenKeyEx (HKEY_LOCAL_MACHINE, + "SYSTEM\\Setup", + 0, + KEY_QUERY_VALUE, + &hKey); + if (dwError != ERROR_SUCCESS) + { + return FALSE; + } + + dwSize = MAX_PATH; + dwError = RegQueryValueEx (hKey, + "CmdLine", + NULL, + &dwType, + (LPBYTE)CommandLine, + &dwSize); + RegCloseKey (hKey); + if (dwError != ERROR_SUCCESS || dwType != REG_SZ) + { + return FALSE; + } + + DPRINT ("Winlogon: Should run '%s' now.\n", CommandLine); + + StartupInfo.cb = sizeof(StartupInfo); + StartupInfo.lpReserved = NULL; + StartupInfo.lpDesktop = NULL; + StartupInfo.lpTitle = NULL; + StartupInfo.dwFlags = 0; + StartupInfo.cbReserved2 = 0; + StartupInfo.lpReserved2 = 0; + + DPRINT ("Winlogon: Creating new setup process\n"); + + Result = CreateProcess (NULL, + CommandLine, + NULL, + NULL, + FALSE, + DETACHED_PROCESS, + NULL, + NULL, + &StartupInfo, + &ProcessInformation); + if (!Result) + { + DPRINT ("Winlogon: Failed to run setup process\n"); + return FALSE; + } + + /* Wait for process termination */ + WaitForSingleObject (ProcessInformation.hProcess, INFINITE); + + GetExitCodeProcess (ProcessInformation.hProcess, &dwExitCode); + + CloseHandle (ProcessInformation.hThread); + CloseHandle (ProcessInformation.hProcess); + + if (dwExitCode == 0) + { + SetSetupType (0); + } + + DPRINT ("Winlogon: RunSetup() done.\n"); + + return TRUE; +} + + +/* EOF */ diff --git a/subsys/system/winlogon/setup.h b/subsys/system/winlogon/setup.h new file mode 100644 index 0000000..5089d11 --- /dev/null +++ b/subsys/system/winlogon/setup.h @@ -0,0 +1,36 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS winlogon + * FILE: subsys/system/winlogon/setup.h + * PURPOSE: Setup support functions + * PROGRAMMER: Eric Kohl + */ + +#ifndef __SETUP_H__ +#define __SETUP_H__ + +DWORD GetSetupType (VOID); +BOOL SetSetupType (DWORD dwSetupType); +BOOL RunSetup (VOID); + +#endif /* __SETUP_H__ */ + +/* EOF */ diff --git a/subsys/system/winlogon/winlogon.c b/subsys/system/winlogon/winlogon.c index 2b3da97..3ab16dc 100644 --- a/subsys/system/winlogon/winlogon.c +++ b/subsys/system/winlogon/winlogon.c @@ -15,10 +15,11 @@ #include #include #include - #include -#define DBG +#include "setup.h" + +#define NDEBUG #include /* GLOBALS ******************************************************************/ @@ -243,7 +244,7 @@ static PCHAR GetShell(PCHAR CommandLine) if (! GotCommandLine) { GetSystemDirectory(CommandLine, MAX_PATH - 10); - strcat(CommandLine, "\\shell.exe"); + strcat(CommandLine, "\\cmd.exe"); } return CommandLine; @@ -381,15 +382,30 @@ WinMain(HINSTANCE hInstance, { DbgPrint("WL: Cannot switch to Winlogon desktop (0x%X)\n", GetLastError()); } - + AllocConsole(); SetConsoleTitle( "Winlogon" ); + + /* Check for pending setup */ + if (GetSetupType () != 0) + { + DPRINT ("Winlogon: CheckForSetup() in setup mode\n"); + + /* Run setup and reboot when done */ + RunSetup (); + +// NtShutdownSystem (ShutdownReboot); + NtShutdownSystem (ShutdownNoReboot); + ExitProcess (0); + return 0; + } + /* start system processes (services.exe & lsass.exe) */ if (StartProcess("StartServices")) { if (!StartServices()) { - DbgPrint("WL: Failed to Start Services (0x%X)\n", GetLastError()); + DbgPrint("WL: Failed to start Services (0x%X)\n", GetLastError()); } } #if 0 @@ -397,7 +413,7 @@ WinMain(HINSTANCE hInstance, { if (!StartLsass()) { - DbgPrint("WL: Failed to Start Security System (0x%X)\n", GetLastError()); + DbgPrint("WL: Failed to start LSASS (0x%X)\n", GetLastError()); } } #endif @@ -408,7 +424,7 @@ WinMain(HINSTANCE hInstance, Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); if (!NT_SUCCESS(Status)) { - DbgPrint("WL: Failed to connect to lsass\n"); + DbgPrint("WL: Failed to connect to LSASS\n"); return(1); } #endif @@ -420,50 +436,49 @@ WinMain(HINSTANCE hInstance, */ /* Main loop */ - for (;;) - { #if 0 - /* Display login prompt */ - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - LoginPrompt, - strlen(LoginPrompt), // wcslen(LoginPrompt), - &Result, - NULL); - i = 0; - do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &LoginName[i], - 1, - &Result, - NULL); - i++; - } while (LoginName[i - 1] != '\n'); - LoginName[i - 1] = 0; + /* Display login prompt */ + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), + LoginPrompt, + strlen(LoginPrompt), // wcslen(LoginPrompt), + &Result, + NULL); + i = 0; + do + { + ReadConsole(GetStdHandle(STD_INPUT_HANDLE), + &LoginName[i], + 1, + &Result, + NULL); + i++; + } while (LoginName[i - 1] != '\n'); + LoginName[i - 1] = 0; - /* Display password prompt */ - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), - PasswordPrompt, - strlen(PasswordPrompt), // wcslen(PasswordPrompt), - &Result, - NULL); - i = 0; - do - { - ReadConsole(GetStdHandle(STD_INPUT_HANDLE), - &Password[i], - 1, - &Result, - NULL); - i++; - } while (Password[i - 1] != '\n'); - Password[i - 1] =0; + /* Display password prompt */ + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), + PasswordPrompt, + strlen(PasswordPrompt), // wcslen(PasswordPrompt), + &Result, + NULL); + i = 0; + do + { + ReadConsole(GetStdHandle(STD_INPUT_HANDLE), + &Password[i], + 1, + &Result, + NULL); + i++; + } while (Password[i - 1] != '\n'); + Password[i - 1] =0; #endif - if (! DoLoginUser(LoginName, Password)) - { - break; - } + + if (! DoLoginUser(LoginName, Password)) + { } + + NtShutdownSystem(ShutdownNoReboot); ExitProcess(0); diff --git a/subsys/win32k/dib/dib.c b/subsys/win32k/dib/dib.c new file mode 100644 index 0000000..fd06bae --- /dev/null +++ b/subsys/win32k/dib/dib.c @@ -0,0 +1,5 @@ +/* Static data */ + +unsigned char notmask[2] = { 0x0f, 0xf0 }; +unsigned char altnotmask[2] = { 0xf0, 0x0f }; +unsigned char mask1Bpp[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; diff --git a/subsys/win32k/dib/dib.h b/subsys/win32k/dib/dib.h index 4d00fed..bcc3b60 100644 --- a/subsys/win32k/dib/dib.h +++ b/subsys/win32k/dib/dib.h @@ -1,35 +1,57 @@ -static unsigned char notmask[2] = { 0x0f, 0xf0 }; -static unsigned char altnotmask[2] = { 0xf0, 0x0f }; -static unsigned char mask1Bpp[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +extern unsigned char notmask[2]; +extern unsigned char altnotmask[2]; +extern unsigned char mask1Bpp[8]; -typedef VOID (*PFN_DIB_PutPixel)(PSURFOBJ, LONG, LONG, ULONG); -typedef ULONG (*PFN_DIB_GetPixel)(PSURFOBJ, LONG, LONG); -typedef VOID (*PFN_DIB_HLine) (PSURFOBJ, LONG, LONG, LONG, ULONG); -typedef VOID (*PFN_DIB_VLine) (PSURFOBJ, LONG, LONG, LONG, ULONG); +VOID DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_1BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); -PFN_DIB_PutPixel DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); -PFN_DIB_GetPixel DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); -PFN_DIB_HLine DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); -PFN_DIB_VLine DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); -BOOLEAN DIB_To_1BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation); +VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_4BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); -PFN_DIB_PutPixel DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); -PFN_DIB_GetPixel DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); -PFN_DIB_HLine DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); -PFN_DIB_VLine DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); -BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation); +VOID DIB_8BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_8BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_8BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_8BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_8BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); -PFN_DIB_PutPixel DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); -PFN_DIB_GetPixel DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); -PFN_DIB_HLine DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); -PFN_DIB_VLine DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); -BOOLEAN DIB_To_24BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation); +VOID DIB_16BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_16BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_16BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_16BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); + +VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_24BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); + +VOID DIB_32BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c); +ULONG DIB_32BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y); +VOID DIB_32BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c); +VOID DIB_32BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c); +BOOLEAN DIB_32BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation); diff --git a/subsys/win32k/dib/dib16bpp.c b/subsys/win32k/dib/dib16bpp.c new file mode 100644 index 0000000..da63042 --- /dev/null +++ b/subsys/win32k/dib/dib16bpp.c @@ -0,0 +1,201 @@ +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include "../eng/objects.h" +#include "dib.h" + +VOID DIB_16BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PWORD addr = (PWORD)byteaddr + x; + + *addr = (WORD)c; +} + +ULONG DIB_16BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PWORD addr = (PWORD)byteaddr + x; + + return (ULONG)(*addr); +} + +VOID DIB_16BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PWORD addr = (PWORD)byteaddr + x1; + LONG cx = x1; + + while(cx < x2) { + *addr = (WORD)c; + ++addr; + ++cx; + } +} + +VOID DIB_16BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta; + PWORD addr = (PWORD)byteaddr + x; + LONG lDelta = SurfObj->lDelta; + + byteaddr = (PBYTE)addr; + while(y1++ < y2) { + *addr = (WORD)c; + + byteaddr += lDelta; + addr = (PWORD)byteaddr; + } +} + +BOOLEAN DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) +{ + LONG i, j, sx, sy, xColor, f1; + PBYTE SourceBits, DestBits, SourceLine, DestLine; + PBYTE SourceBits_4BPP, SourceLine_4BPP; + DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left; + + switch(SourceGDI->BitsPerPixel) + { + case 1: + sx = SourcePoint->x; + sy = SourcePoint->y; + + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) + { + DIB_16BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0)); + } else { + DIB_16BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1)); + } + sx++; + } + sy++; + } + break; + + case 4: + SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1); + + for (j=DestRect->top; jbottom; j++) + { + SourceLine_4BPP = SourceBits_4BPP; + sx = SourcePoint->x; + f1 = sx & 1; + + for (i=DestRect->left; iright; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, + (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1)))); + DIB_16BPP_PutPixel(DestSurf, i, j, xColor); + if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; } + sx++; + } + + SourceBits_4BPP += SourceSurf->lDelta; + } + break; + + case 8: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(ColorTranslation, *SourceBits); + SourceBits += 1; + DestBits += 2; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 16: + if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL)) + { + SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; + for (j = DestRect->top; j < DestRect->bottom; j++) + { + RtlCopyMemory(DestBits, SourceBits, 2 * (DestRect->right - DestRect->left)); + SourceBits += SourceSurf->lDelta; + DestBits += DestSurf->lDelta; + } + } + else + { + /* FIXME */ + DPRINT1("DIB_16BPP_Bitblt: Unhandled ColorTranslation for 16 -> 16 copy"); + return FALSE; + } + break; + + case 24: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = (*(SourceBits + 2) << 0x10) + + (*(SourceBits + 1) << 0x08) + + (*(SourceBits)); + *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 3; + DestBits += 2; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 32: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(ColorTranslation, *((PDWORD) SourceBits)); + SourceBits += 4; + DestBits += 2; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + default: + DbgPrint("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); + return FALSE; + } + + return TRUE; +} diff --git a/subsys/win32k/dib/dib1bpp.c b/subsys/win32k/dib/dib1bpp.c index a3af45a..d56140f 100644 --- a/subsys/win32k/dib/dib1bpp.c +++ b/subsys/win32k/dib/dib1bpp.c @@ -8,52 +8,49 @@ #include "../eng/objects.h" #include "dib.h" -PFN_DIB_PutPixel DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +VOID DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) { - unsigned char *vp; - unsigned char mask; - PBYTE addr = SurfObj->pvBits; + PBYTE addr = SurfObj->pvScan0; addr += y * SurfObj->lDelta + (x >> 3); if(c == 0) { - *addr = (*addr ^ mask1Bpp[mod(x, 8)]); + *addr = (*addr ^ mask1Bpp[x % 8]); } else { - *addr = (*addr | mask1Bpp[mod(x, 8)]); + *addr = (*addr | mask1Bpp[x % 8]); } } -PFN_DIB_GetPixel DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +ULONG DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) { - PBYTE addr = SurfObj->pvBits + y * SurfObj->lDelta + (x >> 3); + PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x >> 3); - if(*addr & mask1Bpp[mod(x, 8)]) return (PFN_DIB_GetPixel)(1); - return (PFN_DIB_GetPixel)(0); + return (*addr & mask1Bpp[x % 8] ? 1 : 0); } -PFN_DIB_HLine DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +VOID DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { - while(x1 <= x2) { + while(x1 < x2) { DIB_1BPP_PutPixel(SurfObj, x1, y, c); x1++; } } -PFN_DIB_VLine DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +VOID DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { - while(y1 <= y2) { + while(y1 < y2) { DIB_1BPP_PutPixel(SurfObj, x, y1, c); y1++; } } -BOOLEAN DIB_To_1BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation) +BOOLEAN DIB_1BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) { LONG i, j, sx, sy = SourcePoint->y; @@ -95,6 +92,42 @@ BOOLEAN DIB_To_1BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, } break; + case 8: + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(XLATEOBJ_iXlate(ColorTranslation, DIB_8BPP_GetPixel(SourceSurf, sx, sy)) == 0) + { + DIB_1BPP_PutPixel(DestSurf, i, j, 0); + } else { + DIB_1BPP_PutPixel(DestSurf, i, j, 1); + } + sx++; + } + sy++; + } + break; + + case 16: + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(XLATEOBJ_iXlate(ColorTranslation, DIB_16BPP_GetPixel(SourceSurf, sx, sy)) == 0) + { + DIB_1BPP_PutPixel(DestSurf, i, j, 0); + } else { + DIB_1BPP_PutPixel(DestSurf, i, j, 1); + } + sx++; + } + sy++; + } + break; + case 24: for (j=DestRect->top; jbottom; j++) { @@ -113,6 +146,24 @@ BOOLEAN DIB_To_1BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, } break; + case 32: + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(XLATEOBJ_iXlate(ColorTranslation, DIB_32BPP_GetPixel(SourceSurf, sx, sy)) == 0) + { + DIB_1BPP_PutPixel(DestSurf, i, j, 0); + } else { + DIB_1BPP_PutPixel(DestSurf, i, j, 1); + } + sx++; + } + sy++; + } + break; + default: DbgPrint("DIB_1BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); return FALSE; diff --git a/subsys/win32k/dib/dib24bpp.c b/subsys/win32k/dib/dib24bpp.c index 1e27752..e24df91 100644 --- a/subsys/win32k/dib/dib24bpp.c +++ b/subsys/win32k/dib/dib24bpp.c @@ -8,43 +8,43 @@ #include "../eng/objects.h" #include "dib.h" -PFN_DIB_PutPixel DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +VOID DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) { - PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta; + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x; *(PULONG)(addr) = c; } -PFN_DIB_GetPixel DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +ULONG DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) { - PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta; + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x; - return (PFN_DIB_GetPixel)(*(PULONG)(addr)); + return *(PULONG)(addr) & 0x00ffffff; } -PFN_DIB_HLine DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +VOID DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { - PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta; + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x1; LONG cx = x1; - while(cx <= x2) { + while(cx < x2) { *(PULONG)(addr) = c; ++addr; ++cx; } } -PFN_DIB_VLine DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +VOID DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { - PBYTE byteaddr = SurfObj->pvBits + y1 * SurfObj->lDelta; + PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta; PRGBTRIPLE addr = (PRGBTRIPLE)byteaddr + x; LONG lDelta = SurfObj->lDelta; byteaddr = (PBYTE)addr; - while(y1++ <= y2) { + while(y1++ < y2) { *(PULONG)(addr) = c; byteaddr += lDelta; @@ -52,50 +52,17 @@ PFN_DIB_VLine DIB_24BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG } } -VOID DIB_24BPP_BltTo_24BPP(PSURFOBJ dstpsd, LONG dstx, LONG dsty, LONG w, LONG h, - PSURFOBJ srcpsd, LONG srcx, LONG srcy) -{ - PRGBTRIPLE dst; - PRGBTRIPLE src; - PBYTE bytedst; - PBYTE bytesrc; - int i; - int dlDelta = dstpsd->lDelta; - int slDelta = srcpsd->lDelta; - - bytedst = (char *)dstpsd->pvBits + dsty * dlDelta; - bytesrc = (char *)srcpsd->pvBits + srcy * slDelta; - dst = (PRGBTRIPLE)bytedst + dstx; - src = (PRGBTRIPLE)bytesrc + srcx; - - while(--h >= 0) { - PRGBTRIPLE d = dst; - PRGBTRIPLE s = src; - LONG dx = dstx; - LONG sx = srcx; - for(i=0; ipvBits + (DestRect->top * DestSurf->lDelta) + DestRect->left * 3; + DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left * 3; switch(SourceGDI->BitsPerPixel) { @@ -121,7 +88,7 @@ BOOLEAN DIB_To_24BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, break; case 4: - SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1); for (j=DestRect->top; jbottom; j++) { @@ -146,6 +113,93 @@ BOOLEAN DIB_To_24BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, } break; + case 8: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, *SourceBits); + *DestBits = xColor & 0xff; + *(PWORD)(DestBits + 1) = xColor >> 8; + SourceBits += 1; + DestBits += 3; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 16: + SourceBits_16BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; + + for (j=DestRect->top; jbottom; j++) + { + SourceLine_16BPP = SourceBits_16BPP; + DestLine = DestBits; + + for (i=DestRect->left; iright; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, *SourceLine_16BPP); + *DestLine++ = xColor & 0xff; + *(PWORD)DestLine = xColor >> 8; + DestLine += 2; + SourceLine_16BPP++; + } + + SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + SourceSurf->lDelta); + DestBits += DestSurf->lDelta; + } + break; + + case 24: + if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL)) + { + SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x; + for (j = DestRect->top; j < DestRect->bottom; j++) + { + RtlCopyMemory(DestBits, SourceBits, 3 * (DestRect->right - DestRect->left)); + SourceBits += SourceSurf->lDelta; + DestBits += DestSurf->lDelta; + } + } + else + { + /* FIXME */ + DPRINT1("DIB_24BPP_Bitblt: Unhandled ColorTranslation for 16 -> 16 copy"); + return FALSE; + } + break; + + case 32: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, *((PDWORD) SourceBits)); + *DestBits = xColor & 0xff; + *(PWORD)(DestBits + 1) = xColor >> 8; + SourceBits += 4; + DestBits += 3; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + default: DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); return FALSE; diff --git a/subsys/win32k/dib/dib32bpp.c b/subsys/win32k/dib/dib32bpp.c new file mode 100644 index 0000000..38a479a --- /dev/null +++ b/subsys/win32k/dib/dib32bpp.c @@ -0,0 +1,203 @@ +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include "../eng/objects.h" +#include "dib.h" + +VOID DIB_32BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PDWORD addr = (PDWORD)byteaddr + x; + + *addr = c; +} + +ULONG DIB_32BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PDWORD addr = (PDWORD)byteaddr + x; + + return (ULONG)(*addr); +} + +VOID DIB_32BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PDWORD addr = (PDWORD)byteaddr + x1; + LONG cx = x1; + + while(cx < x2) { + *addr = (DWORD)c; + ++addr; + ++cx; + } +} + +VOID DIB_32BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta; + PDWORD addr = (PDWORD)byteaddr + x; + LONG lDelta = SurfObj->lDelta / sizeof(DWORD); + + byteaddr = (PBYTE)addr; + while(y1++ < y2) { + *addr = (DWORD)c; + + addr += lDelta; + } +} + +BOOLEAN DIB_32BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) +{ + ULONG i, j, sx, sy, xColor, f1; + PBYTE SourceBits, DestBits, SourceLine, DestLine; + PBYTE SourceBits_4BPP, SourceLine_4BPP; + + DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 4 * DestRect->left; + + switch(SourceGDI->BitsPerPixel) + { + case 1: + sx = SourcePoint->x; + sy = SourcePoint->y; + + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) + { + DIB_32BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0)); + } else { + DIB_32BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1)); + } + sx++; + } + sy++; + } + break; + + case 4: + SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1); + + for (j=DestRect->top; jbottom; j++) + { + SourceLine_4BPP = SourceBits_4BPP; + sx = SourcePoint->x; + f1 = sx & 1; + + for (i=DestRect->left; iright; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, + (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1)))); + DIB_32BPP_PutPixel(DestSurf, i, j, xColor); + if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; } + sx++; + } + + SourceBits_4BPP += SourceSurf->lDelta; + } + break; + + case 8: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *SourceBits; + *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 1; + DestBits += 4; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 16: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *((PWORD) SourceBits); + *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 2; + DestBits += 4; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 24: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = (*(SourceBits + 2) << 0x10) + + (*(SourceBits + 1) << 0x08) + + (*(SourceBits)); + *((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 3; + DestBits += 4; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 32: + if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL)) + { + SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; + for (j = DestRect->top; j < DestRect->bottom; j++) + { + RtlCopyMemory(DestBits, SourceBits, 4 * (DestRect->right - DestRect->left)); + SourceBits += SourceSurf->lDelta; + DestBits += DestSurf->lDelta; + } + } + else + { + /* FIXME */ + DPRINT1("DIB_32BPP_Bitblt: Unhandled ColorTranslation for 32 -> 32 copy"); + return FALSE; + } + break; + + default: + DbgPrint("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); + return FALSE; + } + + return TRUE; +} diff --git a/subsys/win32k/dib/dib4bpp.c b/subsys/win32k/dib/dib4bpp.c index 856ea0d..e8231bb 100644 --- a/subsys/win32k/dib/dib4bpp.c +++ b/subsys/win32k/dib/dib4bpp.c @@ -8,29 +8,27 @@ #include "../eng/objects.h" #include "dib.h" -PFN_DIB_PutPixel DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +VOID DIB_4BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) { - unsigned char *vp; - unsigned char mask; - PBYTE addr = SurfObj->pvBits; + PBYTE addr = SurfObj->pvScan0; addr += (x>>1) + y * SurfObj->lDelta; *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); } -PFN_DIB_GetPixel DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +ULONG DIB_4BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) { - PBYTE addr = SurfObj->pvBits; + PBYTE addr = SurfObj->pvScan0; - return (PFN_DIB_GetPixel)((addr[(x>>1) + y * SurfObj->lDelta] >> ((1-(x&1))<<2) ) & 0x0f); + return (addr[(x>>1) + y * SurfObj->lDelta] >> ((1-(x&1))<<2) ) & 0x0f; } -PFN_DIB_HLine DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +VOID DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { - PBYTE addr = SurfObj->pvBits + (x1>>1) + y * SurfObj->lDelta; + PBYTE addr = SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta; LONG cx = x1; - while(cx <= x2) { + while(cx < x2) { *addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2)); if((++x1 & 1) == 0) ++addr; @@ -38,30 +36,29 @@ PFN_DIB_HLine DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c } } -PFN_DIB_VLine DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +VOID DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { - PBYTE addr = SurfObj->pvBits; + PBYTE addr = SurfObj->pvScan0; int lDelta = SurfObj->lDelta; addr += (x>>1) + y1 * lDelta; - while(y1++ <= y2) { + while(y1++ < y2) { *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); addr += lDelta; } } -BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation) +BOOLEAN DIB_4BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) { LONG i, j, sx, sy, f1, f2, xColor; PBYTE SourceBits_24BPP, SourceLine_24BPP; - PBYTE DestBits, DestLine, SourceBits_4BPP, SourceBits_8BPP, SourceLine_4BPP, SourceLine_8BPP; - PWORD SourceBits_16BPP, SourceLine_16BPP; - PDWORD SourceBits_32BPP, SourceLine_32BPP; + PBYTE DestBits, DestLine, SourceBits_8BPP, SourceLine_8BPP; + PBYTE SourceBits, SourceLine; - DestBits = DestSurf->pvBits + (DestRect->left>>1) + DestRect->top * DestSurf->lDelta; + DestBits = DestSurf->pvScan0 + (DestRect->left>>1) + DestRect->top * DestSurf->lDelta; switch(SourceGDI->BitsPerPixel) { @@ -103,23 +100,20 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, break; case 8: - SourceBits_8BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + SourceBits_8BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; for (j=DestRect->top; jbottom; j++) { SourceLine_8BPP = SourceBits_8BPP; DestLine = DestBits; - sx = SourcePoint->x; - f1 = sx & 1; f2 = DestRect->left & 1; for (i=DestRect->left; iright; i++) { *DestLine = (*DestLine & notmask[i&1]) | - ((XLATEOBJ_iXlate(ColorTranslation, *SourceLine_8BPP)) << ((4 * (1-(sx & 1))))); + ((XLATEOBJ_iXlate(ColorTranslation, *SourceLine_8BPP)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; } SourceLine_8BPP++; - sx++; } SourceBits_8BPP += SourceSurf->lDelta; @@ -127,15 +121,37 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, } break; + case 16: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + f2 = DestRect->left & 1; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *((PWORD) SourceBits); + *DestBits = (*DestBits & notmask[i&1]) | + ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); + if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; } + SourceBits += 2; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + case 24: - SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3; + SourceBits_24BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3; for (j=DestRect->top; jbottom; j++) { SourceLine_24BPP = SourceBits_24BPP; DestLine = DestBits; - sx = SourcePoint->x; - f1 = sx & 1; f2 = DestRect->left & 1; for (i=DestRect->left; iright; i++) @@ -144,10 +160,9 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, (*(SourceLine_24BPP + 1) << 0x08) + (*(SourceLine_24BPP)); *DestLine = (*DestLine & notmask[i&1]) | - ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(sx & 1))))); + ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; } SourceLine_24BPP+=3; - sx++; } SourceBits_24BPP += SourceSurf->lDelta; @@ -155,6 +170,30 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf, } break; + case 32: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + f2 = DestRect->left & 1; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *((PDWORD) SourceBits); + *DestBits = (*DestBits & notmask[i&1]) | + ((XLATEOBJ_iXlate(ColorTranslation, xColor)) << ((4 * (1-(i & 1))))); + if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; } + SourceBits += 4; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + default: DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); return FALSE; diff --git a/subsys/win32k/dib/dib8bpp.c b/subsys/win32k/dib/dib8bpp.c new file mode 100644 index 0000000..84bd38c --- /dev/null +++ b/subsys/win32k/dib/dib8bpp.c @@ -0,0 +1,201 @@ +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include "../eng/objects.h" +#include "dib.h" + +VOID DIB_8BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x; + + *byteaddr = c; +} + +ULONG DIB_8BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta + x; + + return (ULONG)(*byteaddr); +} + +VOID DIB_8BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta; + PBYTE addr = byteaddr + x1; + LONG cx = x1; + + while(cx < x2) { + *addr = c; + ++addr; + ++cx; + } +} + +VOID DIB_8BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +{ + PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta; + PBYTE addr = byteaddr + x; + LONG lDelta = SurfObj->lDelta; + + byteaddr = addr; + while(y1++ < y2) { + *addr = c; + + addr += lDelta; + } +} + +BOOLEAN DIB_8BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) +{ + ULONG i, j, sx, sy, xColor, f1; + PBYTE SourceBits, DestBits, SourceLine, DestLine; + PBYTE SourceBits_4BPP, SourceLine_4BPP; + + DestBits = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left; + + switch(SourceGDI->BitsPerPixel) + { + case 1: + sx = SourcePoint->x; + sy = SourcePoint->y; + + for (j=DestRect->top; jbottom; j++) + { + sx = SourcePoint->x; + for (i=DestRect->left; iright; i++) + { + if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0) + { + DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0)); + } else { + DIB_8BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1)); + } + sx++; + } + sy++; + } + break; + + case 4: + SourceBits_4BPP = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + (SourcePoint->x >> 1); + + for (j=DestRect->top; jbottom; j++) + { + SourceLine_4BPP = SourceBits_4BPP; + sx = SourcePoint->x; + f1 = sx & 1; + + for (i=DestRect->left; iright; i++) + { + xColor = XLATEOBJ_iXlate(ColorTranslation, + (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1)))); + DIB_8BPP_PutPixel(DestSurf, i, j, xColor); + if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; } + sx++; + } + + SourceBits_4BPP += SourceSurf->lDelta; + } + break; + + case 8: + if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL)) + { + SourceBits = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x; + for (j = DestRect->top; j < DestRect->bottom; j++) + { + RtlCopyMemory(DestBits, SourceBits, DestRect->right - DestRect->left); + SourceBits += SourceSurf->lDelta; + DestBits += DestSurf->lDelta; + } + } + else + { + /* FIXME */ + DPRINT1("DIB_8BPP_Bitblt: Unhandled ColorTranslation for 32 -> 32 copy"); + return FALSE; + } + break; + + case 16: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *((PWORD) SourceBits); + *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 2; + DestBits += 1; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 24: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = (*(SourceBits + 2) << 0x10) + + (*(SourceBits + 1) << 0x08) + + (*(SourceBits)); + *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 3; + DestBits += 1; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + case 32: + SourceLine = SourceSurf->pvScan0 + (SourcePoint->y * SourceSurf->lDelta) + 4 * SourcePoint->x; + DestLine = DestBits; + + for (j = DestRect->top; j < DestRect->bottom; j++) + { + SourceBits = SourceLine; + DestBits = DestLine; + + for (i = DestRect->left; i < DestRect->right; i++) + { + xColor = *((PDWORD) SourceBits); + *DestBits = XLATEOBJ_iXlate(ColorTranslation, xColor); + SourceBits += 4; + DestBits += 1; + } + + SourceLine += SourceSurf->lDelta; + DestLine += DestSurf->lDelta; + } + break; + + default: + DbgPrint("DIB_8BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); + return FALSE; + } + + return TRUE; +} diff --git a/subsys/win32k/eng/bitblt.c b/subsys/win32k/eng/bitblt.c index c582ebf..53f8046 100644 --- a/subsys/win32k/eng/bitblt.c +++ b/subsys/win32k/eng/bitblt.c @@ -14,11 +14,17 @@ #include "brush.h" #include "clip.h" #include "objects.h" +#include "../dib/dib.h" +#include "misc.h" #include #include #include #include #include +#include + +#define NDEBUG +#include BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2) { @@ -40,119 +46,166 @@ BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2) return(FALSE); } +static BOOL STDCALL +BltMask(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, + RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush, + POINTL* BrushPoint) +{ + LONG i, j, dx, dy, c8; + BYTE *tMask, *lMask; + static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + + dx = DestRect->right - DestRect->left; + dy = DestRect->bottom - DestRect->top; + + if (Mask != NULL) + { + tMask = Mask->pvBits; + for (j = 0; j < dy; j++) + { + lMask = tMask; + c8 = 0; + for (i = 0; i < dx; i++) + { + if (0 != (*lMask & maskbit[c8])) + { + DestGDI->DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor); + } + c8++; + if (8 == c8) + { + lMask++; + c8=0; + } + } + tMask += Mask->lDelta; + } + return TRUE; + } + else + { + return FALSE; + } +} + +static BOOL STDCALL +BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, + RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush, + POINTL* BrushPoint) +{ + // These functions are assigned if we're working with a DIB + // The assigned functions depend on the bitsPerPixel of the DIB + LONG y; + ULONG LineWidth; + + LineWidth = DestRect->right - DestRect->left; + for (y = DestRect->top; y < DestRect->bottom; y++) + { + DestGDI->DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor); + } + + return TRUE; +} + INT abs(INT nm); BOOL STDCALL -EngBitBlt(SURFOBJ *Dest, - SURFOBJ *Source, +EngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, SURFOBJ *Mask, CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint, - POINTL *MaskRect, + POINTL *MaskOrigin, BRUSHOBJ *Brush, POINTL *BrushOrigin, ROP4 rop4) { - BOOLEAN ret; - BYTE clippingType; - RECTL rclTmp; - POINTL ptlTmp; - RECT_ENUM RectEnum; - BOOL EnumMore; - PSURFGDI DestGDI, SourceGDI; - HSURF hTemp; - PSURFOBJ TempSurf = NULL; - BOOLEAN canCopyBits; - POINTL TempPoint; - RECTL TempRect; - SIZEL TempSize; - - if(Source != NULL) SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source); - if(Dest != NULL) DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest); - - if (Source != NULL) + BOOLEAN ret; + BYTE clippingType; + RECTL rclTmp; + POINTL ptlTmp; + RECT_ENUM RectEnum; + BOOL EnumMore; + PSURFGDI OutputGDI, InputGDI; + POINTL InputPoint; + RECTL InputRect; + RECTL OutputRect; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeaveSource; + INTENG_ENTER_LEAVE EnterLeaveDest; + PSURFOBJ InputObj; + PSURFOBJ OutputObj; + + /* Check for degenerate case: if height or width of DestRect is 0 pixels there's + nothing to do */ + if (DestRect->right == DestRect->left || DestRect->bottom == DestRect->top) { - MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y, - (SourcePoint->x + abs(DestRect->right - DestRect->left)), - (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + return TRUE; } - MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - // If we don't have to do anything special, we can punt to DrvCopyBits - // if it exists - if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) && - (BrushOrigin == NULL) && (rop4 == 0) ) - { - canCopyBits = TRUE; - } else - canCopyBits = FALSE; - - // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF: - // * The destination bitmap is not managed by the GDI OR - if(Dest->iType != STYPE_BITMAP) - { - // Destination surface is device managed - if (DestGDI->BitBlt!=NULL) + if (NULL != SourcePoint) { - if (Source!=NULL) - { - // Get the source into a format compatible surface - TempPoint.x = 0; - TempPoint.y = 0; - TempRect.top = 0; - TempRect.left = 0; - TempRect.bottom = DestRect->bottom - DestRect->top; - TempRect.right = DestRect->right - DestRect->left; - TempSize.cx = TempRect.right; - TempSize.cy = TempRect.bottom; - - hTemp = EngCreateBitmap(TempSize, - DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)), - Dest->iBitmapFormat, 0, NULL); - TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp); - - // FIXME: Skip creating a TempSurf if we have the same BPP and palette - EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0); - } - - ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion, - NULL, DestRect, &TempPoint, - MaskRect, Brush, BrushOrigin, rop4); - - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); - - return ret; + InputRect.left = SourcePoint->x; + InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left); + InputRect.top = SourcePoint->y; + InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top); + } + else + { + InputRect.left = 0; + InputRect.right = DestRect->right - DestRect->left; + InputRect.top = 0; + InputRect.bottom = DestRect->bottom - DestRect->top; } - } - /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to - * paint a brush pattern on the destination. */ - if(!Source) - { - DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n"); + if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj)) + { return FALSE; - } + } - // * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device - if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL) - { - if (SourceGDI->BitBlt!=NULL) + if (NULL != SourcePoint) + { + InputPoint.x = SourcePoint->x + Translate.x; + InputPoint.y = SourcePoint->y + Translate.y; + } + else + { + InputPoint.x = 0; + InputPoint.y = 0; + } + + if (NULL != InputObj) { - // Request the device driver to return the bitmap in a format compatible with the device - ret = SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion, - NULL, DestRect, SourcePoint, - MaskRect, Brush, BrushOrigin, rop4); + InputGDI = (PSURFGDI) AccessInternalObjectFromUserObject(InputObj); + } - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + OutputRect = *DestRect; - return ret; + if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj)) + { + IntEngLeave(&EnterLeaveSource); + return FALSE; + } + + OutputRect.left = DestRect->left + Translate.x; + OutputRect.right = DestRect->right + Translate.x; + OutputRect.top = DestRect->top + Translate.y; + OutputRect.bottom = DestRect->bottom + Translate.y; - // Convert the surface from the driver into the required destination surface + + if (NULL != OutputObj) + { + OutputGDI = (PSURFGDI)AccessInternalObjectFromUserObject(OutputObj); } + + /* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to + * paint a brush pattern on the destination. */ + if (NULL == InputObj && 0xaacc != rop4 && PATCOPY != rop4) + { + DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n"); + return FALSE; } // Determine clipping type @@ -163,27 +216,41 @@ EngBitBlt(SURFOBJ *Dest, clippingType = ClipRegion->iDComplexity; } + if (0xaacc == rop4) + { + ret = BltMask(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); + return ret; + } else if (PATCOPY == rop4) { + ret = BltPatCopy(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); + return ret; + } + + // We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE] switch(clippingType) { case DC_TRIVIAL: - CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation); + OutputGDI->DIB_BitBlt(OutputObj, InputObj, OutputGDI, InputGDI, &OutputRect, &InputPoint, ColorTranslation); - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); case DC_RECT: // Clip the blt to the clip rectangle - EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds); + EngIntersectRect(&rclTmp, &OutputRect, &ClipRegion->rclBounds); - ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; - ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; + ptlTmp.x = InputPoint.x + rclTmp.left - OutputRect.left; + ptlTmp.y = InputPoint.y + rclTmp.top - OutputRect.top; - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); @@ -200,10 +267,10 @@ EngBitBlt(SURFOBJ *Dest, RECTL* prcl = &RectEnum.arcl[0]; do { - EngIntersectRect(prcl, prcl, DestRect); + EngIntersectRect(prcl, prcl, &OutputRect); - ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left; - ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top; + ptlTmp.x = InputPoint.x + prcl->left - OutputRect.left; + ptlTmp.y = InputPoint.y + prcl->top - OutputRect.top; prcl++; @@ -212,14 +279,65 @@ EngBitBlt(SURFOBJ *Dest, } while(EnumMore); - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); } - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(FALSE); } + +BOOL STDCALL +IntEngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, + SURFOBJ *Mask, + CLIPOBJ *ClipRegion, + XLATEOBJ *ColorTranslation, + RECTL *DestRect, + POINTL *SourcePoint, + POINTL *MaskOrigin, + BRUSHOBJ *Brush, + POINTL *BrushOrigin, + ROP4 rop4) +{ + BOOLEAN ret; + SURFGDI *DestGDI; + SURFGDI *SourceGDI; + + if (NULL != SourceObj) + { + SourceGDI = (PSURFGDI) AccessInternalObjectFromUserObject(SourceObj); + MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourcePoint->x, SourcePoint->y, + (SourcePoint->x + abs(DestRect->right - DestRect->left)), + (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + } + + /* No success yet */ + ret = FALSE; + DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj); + MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top, + DestRect->right, DestRect->bottom); + + /* Call the driver's DrvBitBlt if available */ + if (NULL != DestGDI->BitBlt) { + ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, + DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4); + } + + if (! ret) { + ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, + DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4); + } + + MouseSafetyOnDrawEnd(DestObj, DestGDI); + if (NULL != SourceObj) + { + MouseSafetyOnDrawEnd(SourceObj, SourceGDI); + } + + return ret; +} diff --git a/subsys/win32k/eng/clip.c b/subsys/win32k/eng/clip.c index 244b3bd..18a2953 100644 --- a/subsys/win32k/eng/clip.c +++ b/subsys/win32k/eng/clip.c @@ -14,6 +14,7 @@ #include "clip.h" #include +#define NDEBUG #include VOID IntEngDeleteClipRegion(CLIPOBJ *ClipObj) @@ -120,16 +121,15 @@ CLIPOBJ_bEnum(IN PCLIPOBJ ClipObj, PENUMRECTS pERects = (PENUMRECTS)EnumRects; //calculate how many rectangles we should copy - nCopy = MIN( ClipGDI->EnumMax-ClipGDI->EnumPos, - MIN( ClipGDI->EnumRects.c, (ObjSize-sizeof(ULONG))/sizeof(RECTL))); + nCopy = MIN( ClipGDI->EnumMax - ClipGDI->EnumPos, + MIN( ClipGDI->EnumRects.c - ClipGDI->EnumPos, + (ObjSize - sizeof(ULONG)) / sizeof(RECTL))); - RtlCopyMemory( &(pERects->arcl), &(ClipGDI->EnumRects.arcl), nCopy*sizeof(RECTL) ); + RtlCopyMemory( pERects->arcl, ClipGDI->EnumRects.arcl + ClipGDI->EnumPos, + nCopy * sizeof(RECTL) ); pERects->c = nCopy; ClipGDI->EnumPos+=nCopy; - if(ClipGDI->EnumPos > ClipGDI->EnumRects.c) - return FALSE; - else - return TRUE; + return ClipGDI->EnumPos < ClipGDI->EnumRects.c; } diff --git a/subsys/win32k/eng/copybits.c b/subsys/win32k/eng/copybits.c index d3f4528..740faed 100644 --- a/subsys/win32k/eng/copybits.c +++ b/subsys/win32k/eng/copybits.c @@ -16,46 +16,6 @@ #include #include -BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFGDI *DestGDI, SURFGDI *SourceGDI, - PRECTL DestRect, POINTL *SourcePoint, - LONG Delta, XLATEOBJ *ColorTranslation) -{ - LONG DestWidth, DestHeight, CurrentDestLine, CurrentSourceLine, CurrentDestCol, CurrentSourceCol, i, TranslationPixel; - - PFN_DIB_GetPixel Source_DIB_GetPixel; - PFN_DIB_PutPixel Dest_DIB_PutPixel; - - DestWidth = DestRect->right - DestRect->left; - DestHeight = DestRect->bottom - DestRect->top; - CurrentSourceCol = SourcePoint->x; - CurrentSourceLine = SourcePoint->y; - - // Assign GetPixel DIB function according to bytes per pixel - switch(DestGDI->BitsPerPixel) - { - case 1: - return DIB_To_1BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI, - DestRect, SourcePoint, Delta, ColorTranslation); - break; - - case 4: - return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI, - DestRect, SourcePoint, Delta, ColorTranslation); - break; - - case 24: - return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI, - DestRect, SourcePoint, Delta, ColorTranslation); - break; - - default: - return FALSE; - } - - return TRUE; -} - BOOL STDCALL EngCopyBits(SURFOBJ *Dest, SURFOBJ *Source, @@ -146,7 +106,7 @@ EngCopyBits(SURFOBJ *Dest, switch(clippingType) { case DC_TRIVIAL: - CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation); + DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, ColorTranslation); MouseSafetyOnDrawEnd(Source, SourceGDI); MouseSafetyOnDrawEnd(Dest, DestGDI); @@ -160,7 +120,7 @@ EngCopyBits(SURFOBJ *Dest, ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; - CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, Source->lDelta, ColorTranslation); + DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI, &rclTmp, &ptlTmp, ColorTranslation); MouseSafetyOnDrawEnd(Source, SourceGDI); MouseSafetyOnDrawEnd(Dest, DestGDI); @@ -185,8 +145,8 @@ EngCopyBits(SURFOBJ *Dest, ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left; ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top; - if(!CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, - prcl, &ptlTmp, Source->lDelta, ColorTranslation)) return FALSE; + if(!DestGDI->DIB_BitBlt(Dest, Source, DestGDI, SourceGDI, + prcl, &ptlTmp, ColorTranslation)) return FALSE; prcl++; diff --git a/subsys/win32k/eng/device.c b/subsys/win32k/eng/device.c index 39a5358..cb2e1bc 100644 --- a/subsys/win32k/eng/device.c +++ b/subsys/win32k/eng/device.c @@ -9,6 +9,7 @@ */ #include +#include #define NDEBUG #include @@ -32,16 +33,21 @@ EngDeviceIoControl(HANDLE hDevice, KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + /* Switch to process context in which hDevice is valid */ + KeAttachProcess(W32kDeviceProcess); + Status = ObReferenceObjectByHandle(hDevice, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID *)&FileObject, NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + KeDetachProcess(); + + if (!NT_SUCCESS(Status)) + { + return(Status); + } Irp = IoBuildDeviceIoControlRequest(dwIoControlCode, FileObject->DeviceObject, diff --git a/subsys/win32k/eng/handle.c b/subsys/win32k/eng/handle.c index dd0700b..6571648 100644 --- a/subsys/win32k/eng/handle.c +++ b/subsys/win32k/eng/handle.c @@ -14,6 +14,7 @@ #define NDEBUG #include +static int LastHandle = MAX_GDI_HANDLES; ULONG CreateGDIHandle(ULONG InternalSize, ULONG UserSize) { @@ -31,15 +32,17 @@ ULONG CreateGDIHandle(ULONG InternalSize, ULONG UserSize) pObj->InternalSize = InternalSize; pObj->UserSize = UserSize; - for( i=1; i < MAX_GDI_HANDLES; i++ ){ + for( i = (MAX_GDI_HANDLES - 1 <= LastHandle ? 1 : LastHandle + 1); i != LastHandle; + i = (MAX_GDI_HANDLES - 1 <= i ? 1 : i + 1) ){ if( GDIHandles[ i ].pEngObj == NULL ){ pObj->hObj = i; GDIHandles[ i ].pEngObj = pObj; DPRINT("CreateGDIHandle: obj: %x, handle: %d, usersize: %d\n", pObj, i, UserSize ); + LastHandle = i; return i; } } - DPRINT("CreateGDIHandle: Out of available handles!!!\n"); + DPRINT1("CreateGDIHandle: Out of available handles!!!\n"); EngFreeMem( pObj ); return 0; } @@ -47,7 +50,7 @@ ULONG CreateGDIHandle(ULONG InternalSize, ULONG UserSize) VOID FreeGDIHandle(ULONG Handle) { if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT("FreeGDIHandle: invalid handle!!!!\n"); + DPRINT1("FreeGDIHandle: invalid handle!!!!\n"); return; } DPRINT("FreeGDIHandle: handle: %d\n", Handle); @@ -60,7 +63,7 @@ PVOID AccessInternalObject(ULONG Handle) PENGOBJ pEngObj; if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT("AccessInternalObject: invalid handle: %d!!!!\n", Handle); + DPRINT1("AccessInternalObject: invalid handle: %d!!!!\n", Handle); return NULL; } @@ -73,7 +76,7 @@ PVOID AccessUserObject(ULONG Handle) PENGOBJ pEngObj; if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT("AccessUserObject: invalid handle: %d!!!!\n", Handle); + DPRINT1("AccessUserObject: invalid handle: %d!!!!\n", Handle); return NULL; } @@ -93,7 +96,7 @@ ULONG AccessHandleFromUserObject(PVOID UserObject) Handle = pEngObj->hObj; if( Handle == 0 || Handle >= MAX_GDI_HANDLES ){ - DPRINT("AccessHandleFromUserObject: inv handle: %d, obj: %x!!!!\n", Handle, pEngObj); + DPRINT1("AccessHandleFromUserObject: inv handle: %d, obj: %x!!!!\n", Handle, pEngObj); return INVALID_HANDLE; } return Handle; @@ -109,6 +112,6 @@ VOID InitEngHandleTable( void ) { ULONG i; for( i=1; i < MAX_GDI_HANDLES; i++ ){ - GDIHandles[ i ].pEngObj == NULL; + GDIHandles[ i ].pEngObj = NULL; } } diff --git a/subsys/win32k/eng/lineto.c b/subsys/win32k/eng/lineto.c index ce09b70..a4d2f09 100644 --- a/subsys/win32k/eng/lineto.c +++ b/subsys/win32k/eng/lineto.c @@ -1,13 +1,16 @@ #include +#include +#include #include "objects.h" #include "../dib/dib.h" +#include "misc.h" #include #include #include BOOL STDCALL -EngLineTo(SURFOBJ *Surface, +EngLineTo(SURFOBJ *DestObj, CLIPOBJ *Clip, BRUSHOBJ *Brush, LONG x1, @@ -17,125 +20,194 @@ EngLineTo(SURFOBJ *Surface, RECTL *RectBounds, MIX mix) { - BOOLEAN ret; - SURFGDI *SurfGDI; - LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy; - - // These functions are assigned if we're working with a DIB - // The assigned functions depend on the bitsPerPixel of the DIB - PFN_DIB_PutPixel DIB_PutPixel; - PFN_DIB_HLine DIB_HLine; - PFN_DIB_VLine DIB_VLine; - - SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface); - - MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2); - - if(Surface->iType!=STYPE_BITMAP) - { - // Call the driver's DrvLineTo - ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); - MouseSafetyOnDrawEnd(Surface, SurfGDI); - return ret; - } - - // Assign DIB functions according to bytes per pixel - switch(BitsPerFormat(Surface->iBitmapFormat)) - { - case 1: - DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel; - DIB_HLine = (PFN_DIB_HLine)DIB_1BPP_HLine; - DIB_VLine = (PFN_DIB_VLine)DIB_1BPP_VLine; - break; - - case 4: - DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel; - DIB_HLine = (PFN_DIB_HLine)DIB_4BPP_HLine; - DIB_VLine = (PFN_DIB_VLine)DIB_4BPP_VLine; - break; + LONG x, y, deltax, deltay, i, xchange, ychange, error, hx, vy; + ULONG Pixel = Brush->iSolidColor; + SURFOBJ *OutputObj; + SURFGDI *OutputGDI; + RECTL DestRect; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeave; + + DestRect.left = x1; + if (x1 != x2) + { + DestRect.right = x2; + } + else + { + DestRect.right = x2 + 1; + } + DestRect.top = y1; + if (y1 != y2) + { + DestRect.bottom = y2; + } + else + { + DestRect.bottom = y2 + 1; + } - case 24: - DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel; - DIB_HLine = (PFN_DIB_HLine)DIB_24BPP_HLine; - DIB_VLine = (PFN_DIB_VLine)DIB_24BPP_VLine; - break; + if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj)) + { + return FALSE; + } - default: - DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat, - BitsPerFormat(Surface->iBitmapFormat)); + x1 += Translate.x; + x2 += Translate.x; + y1 += Translate.y; + y2 += Translate.y; - MouseSafetyOnDrawEnd(Surface, SurfGDI); - return FALSE; - } + OutputGDI = AccessInternalObjectFromUserObject(OutputObj); // FIXME: Implement clipping - x=x1; - y=y1; - deltax=x2-x1; - deltay=y2-y1; + x = x1; + y = y1; + deltax = x2 - x1; + deltay = y2 - y1; - if(deltax<0) - { - xchange=-1; - deltax=-deltax; + if (deltax < 0) + { + xchange = -1; + deltax = - deltax; hx = x2; - } else - { - xchange=1; + x--; + } + else + { + xchange = 1; hx = x1; - } + } - if(deltay<0) - { - ychange=-1; - deltay=-deltay; + if (deltay < 0) + { + ychange = -1; + deltay = - deltay; vy = y2; - } else - { - ychange=1; + y--; + } + else + { + ychange = 1; vy = y1; - } - - if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; } - if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; } - - error=0; - i=0; + } - if(deltaxDIB_HLine(OutputObj, hx, hx + deltax, y1, Pixel); + } + else if (x1 == x2) + { + OutputGDI->DIB_VLine(OutputObj, x1, vy, vy + deltay, Pixel); + } + else { - DIB_PutPixel(Surface, x, y, Brush->iSolidColor); - y=y+ychange; - error=error+deltax; + error = 0; - if(error>deltay) + if (deltax < deltay) { - x=x+xchange; - error=error-deltay; + for (i = 0; i < deltay; i++) + { + OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel); + y = y + ychange; + error = error + deltax; + + if (deltay <= error) + { + x = x + xchange; + error = error - deltay; + } + } } - i=i+1; - } - } else - { - length=deltax+1; - while(iiSolidColor); - x=x+xchange; - error=error+deltay; - if(error>deltax) + else { - y=y+ychange; - error=error-deltax; + for (i = 0; i < deltax; i++) + { + OutputGDI->DIB_PutPixel(OutputObj, x, y, Pixel); + x = x + xchange; + error = error + deltay; + if (deltax <= error) + { + y = y + ychange; + error = error - deltax; + } + } } - i=i+1; } + + return IntEngLeave(&EnterLeave); +} + +BOOL STDCALL +IntEngLineTo(SURFOBJ *DestSurf, + CLIPOBJ *Clip, + BRUSHOBJ *Brush, + LONG x1, + LONG y1, + LONG x2, + LONG y2, + RECTL *RectBounds, + MIX mix) +{ + BOOLEAN ret; + SURFGDI *SurfGDI; + + /* No success yet */ + ret = FALSE; + SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf); + + MouseSafetyOnDrawStart(DestSurf, SurfGDI, x1, y1, x2, y2); + + if (NULL != SurfGDI->LineTo) { + /* Call the driver's DrvLineTo */ + ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); + } + +#if 0 + if (! ret && NULL != SurfGDI->StrokePath) { + /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */ + } +#endif + + if (! ret) { + ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); } - MouseSafetyOnDrawEnd(Surface, SurfGDI); + MouseSafetyOnDrawEnd(DestSurf, SurfGDI); + + return ret; +} + +BOOL STDCALL +IntEngPolyline(SURFOBJ *DestSurf, + CLIPOBJ *Clip, + BRUSHOBJ *Brush, + CONST LPPOINT pt, + LONG dCount, + MIX mix) +{ + LONG i; + RECTL rect; + BOOL ret = FALSE; + + //Draw the Polyline with a call to IntEngLineTo for each segment. + for (i=1; i +#include +#include +#include +#include "misc.h" +#include "objects.h" + +BOOL STDCALL +IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, + SURFOBJ *DestObj, + RECTL *DestRect, + BOOL ReadOnly, + POINTL *Translate, + SURFOBJ **OutputObj) +{ + LONG Exchange; + SIZEL BitmapSize; + POINTL SrcPoint; + LONG Width; + + /* Normalize */ + if (DestRect->right < DestRect->left) + { + Exchange = DestRect->left; + DestRect->left = DestRect->right; + DestRect->right = Exchange; + } + if (DestRect->bottom < DestRect->top) + { + Exchange = DestRect->top; + DestRect->top = DestRect->bottom; + DestRect->bottom = Exchange; + } + + if (NULL != DestObj && STYPE_BITMAP != DestObj->iType && + (NULL == DestObj->pvScan0 || 0 == DestObj->lDelta)) + { + EnterLeave->DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj); + /* Driver needs to support DrvCopyBits, else we can't do anything */ + if (NULL == EnterLeave->DestGDI->CopyBits) + { + return FALSE; + } + + /* Allocate a temporary bitmap */ + BitmapSize.cx = DestRect->right - DestRect->left; + BitmapSize.cy = DestRect->bottom - DestRect->top; + Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(DestObj->iBitmapFormat)); + EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width, + DestObj->iBitmapFormat, + BMF_NOZEROINIT, NULL); + *OutputObj = (SURFOBJ *) AccessUserObject((ULONG) EnterLeave->OutputBitmap); + + EnterLeave->DestRect.left = 0; + EnterLeave->DestRect.top = 0; + EnterLeave->DestRect.right = BitmapSize.cx; + EnterLeave->DestRect.bottom = BitmapSize.cy; + SrcPoint.x = DestRect->left; + SrcPoint.y = DestRect->top; + EnterLeave->TrivialClipObj = EngCreateClip(); + EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL; + if (! EnterLeave->DestGDI->CopyBits(*OutputObj, DestObj, + EnterLeave->TrivialClipObj, NULL, + &EnterLeave->DestRect, &SrcPoint)) + { + EngDeleteClip(EnterLeave->TrivialClipObj); + EngFreeMem((*OutputObj)->pvBits); + EngDeleteSurface(EnterLeave->OutputBitmap); + return FALSE; + } + EnterLeave->DestRect.left = DestRect->left; + EnterLeave->DestRect.top = DestRect->top; + EnterLeave->DestRect.right = DestRect->right; + EnterLeave->DestRect.bottom = DestRect->bottom; + Translate->x = - DestRect->left; + Translate->y = - DestRect->top; + } + else + { + Translate->x = 0; + Translate->y = 0; + *OutputObj = DestObj; + } + + EnterLeave->DestObj = DestObj; + EnterLeave->OutputObj = *OutputObj; + EnterLeave->ReadOnly = ReadOnly; + + return TRUE; +} + +BOOL STDCALL +IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave) +{ + POINTL SrcPoint; + BOOL Result; + + if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj) + { + if (! EnterLeave->ReadOnly) + { + SrcPoint.x = 0; + SrcPoint.y = 0; + Result = EnterLeave->DestGDI->CopyBits(EnterLeave->DestObj, + EnterLeave->OutputObj, + EnterLeave->TrivialClipObj, NULL, + &EnterLeave->DestRect, &SrcPoint); + } + EngFreeMem(EnterLeave->OutputObj->pvBits); + EngDeleteSurface(EnterLeave->OutputBitmap); + EngDeleteClip(EnterLeave->TrivialClipObj); + } + else + { + Result = TRUE; + } + + return Result; +} \ No newline at end of file diff --git a/subsys/win32k/eng/misc.h b/subsys/win32k/eng/misc.h new file mode 100644 index 0000000..9177784 --- /dev/null +++ b/subsys/win32k/eng/misc.h @@ -0,0 +1,28 @@ +#ifndef __ENG_MISC_H +#define __ENG_MISC_H + +#ifndef __ENG_OBJECTS_H +#include "objects.h" +#endif + +typedef struct INTENG_ENTER_LEAVE_TAG + { + /* Contents is private to EngEnter/EngLeave */ + SURFOBJ *DestObj; + SURFGDI *DestGDI; + SURFOBJ *OutputObj; + HBITMAP OutputBitmap; + CLIPOBJ *TrivialClipObj; + RECTL DestRect; + BOOL ReadOnly; + } INTENG_ENTER_LEAVE, *PINTENG_ENTER_LEAVE; + +extern BOOL STDCALL IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, + SURFOBJ *DestObj, + RECTL *DestRect, + BOOL ReadOnly, + POINTL *Translate, + SURFOBJ **OutputObj); +extern BOOL STDCALL IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave); + +#endif diff --git a/subsys/win32k/eng/mouse.c b/subsys/win32k/eng/mouse.c index 44136f6..ca740f1 100644 --- a/subsys/win32k/eng/mouse.c +++ b/subsys/win32k/eng/mouse.c @@ -29,10 +29,15 @@ #include #include +#include #include -#include "../../drivers/input/include/mouse.h" #include "objects.h" #include "include/msgqueue.h" +#include "include/object.h" +#include "include/winsta.h" + +#define NDEBUG +#include /* GLOBALS *******************************************************************/ @@ -41,9 +46,61 @@ static BOOLEAN SafetySwitch2 = FALSE; static BOOLEAN MouseEnabled = FALSE; static LONG mouse_x, mouse_y; static UINT mouse_width = 0, mouse_height = 0; +static ULONG PointerStatus; static UCHAR DefaultCursor[256] = { + 0x3F, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, + 0x07, 0xFF, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xFF, + 0x01, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x18, 0x7F, 0xFF, 0xFF, + 0x38, 0x7F, 0xFF, 0xFF, + 0x7C, 0x3F, 0xFF, 0xFF, + 0xFC, 0x3F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFF, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x7F, 0x00, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x76, 0x00, 0x00, 0x00, + 0x76, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -56,58 +113,7 @@ static UCHAR DefaultCursor[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xC0, 0x00, 0x00, - 0x00, 0xC0, 0x00, 0x00, - 0x01, 0x80, 0x00, 0x00, - 0x01, 0x80, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - 0x43, 0x00, 0x00, 0x00, - 0x66, 0x00, 0x00, 0x00, - 0x76, 0x00, 0x00, 0x00, - 0x7E, 0x00, 0x00, 0x00, - 0x7F, 0xC0, 0x00, 0x00, - 0x7F, 0x80, 0x00, 0x00, - 0x7F, 0x00, 0x00, 0x00, - 0x7E, 0x00, 0x00, 0x00, - 0x7C, 0x00, 0x00, 0x00, - 0x78, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x3F, 0xFF, 0xFF, - 0xFE, 0x1F, 0xFF, 0xFF, - 0xFE, 0x1F, 0xFF, 0xFF, - 0xFC, 0x3F, 0xFF, 0xFF, - 0x7C, 0x3F, 0xFF, 0xFF, - 0x38, 0x7F, 0xFF, 0xFF, - 0x18, 0x7F, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x00, 0x0F, 0xFF, 0xFF, - 0x00, 0x1F, 0xFF, 0xFF, - 0x00, 0x3F, 0xFF, 0xFF, - 0x00, 0x7F, 0xFF, 0xFF, - 0x00, 0xFF, 0xFF, 0xFF, - 0x01, 0xFF, 0xFF, 0xFF, - 0x03, 0xFF, 0xFF, 0xFF, - 0x07, 0xFF, 0xFF, 0xFF, - 0x0F, 0xFF, 0xFF, 0xFF, - 0x1F, 0xFF, 0xFF, 0xFF, - 0x3F, 0xFF, 0xFF, 0xFF}; + 0x00, 0x00, 0x00, 0x00}; /* FUNCTIONS *****************************************************************/ @@ -122,6 +128,10 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, RECTL MouseRect; LONG tmp; + + /* Mouse is not allowed to move if GDI is busy drawing */ + SafetySwitch2 = TRUE; + if (SurfObj == NULL) { return(FALSE); @@ -132,6 +142,12 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, return(FALSE); } + if (SPS_ACCEPT_NOEXCLUDE == PointerStatus) + { + /* Hardware cursor, no need to remove it */ + return(FALSE); + } + if (HazardX1 > HazardX2) { tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; @@ -144,13 +160,10 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, if (((mouse_x + mouse_width) >= HazardX1) && (mouse_x <= HazardX2) && ((mouse_y + mouse_height) >= HazardY1) && (mouse_y <= HazardY2)) { - SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect); SafetySwitch = TRUE; + SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect); } - /* Mouse is not allowed to move if GDI is busy drawing */ - SafetySwitch2 = TRUE; - return(TRUE); } @@ -164,11 +177,20 @@ MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI) if (SurfObj == NULL) { + SafetySwitch2 = FALSE; return(FALSE); } if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE) { + SafetySwitch2 = FALSE; + return(FALSE); + } + + if (SPS_ACCEPT_NOEXCLUDE == PointerStatus) + { + /* Hardware cursor, it wasn't removed so need to restore it */ + SafetySwitch2 = FALSE; return(FALSE); } @@ -197,81 +219,94 @@ MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount) PSURFGDI SurfGDI; RECTL MouseRect; MSG Msg; - ULONG j; LARGE_INTEGER LargeTickCount; ULONG TickCount; static ULONG ButtonsDown = 0; - const UINT MouseButtonDownMessage[3] = - {WM_RBUTTONDOWN, WM_MBUTTONDOWN, WM_LBUTTONDOWN}; - const UINT MouseButtonUpMessage[3] = - {WM_RBUTTONUP, WM_MBUTTONUP, WM_LBUTTONUP}; - const ULONG MouseButtonFlag[3] = {MK_RBUTTON, MK_MBUTTON, MK_LBUTTON}; KeQueryTickCount(&LargeTickCount); TickCount = LargeTickCount.u.LowPart; if (hDC == 0) - { - return; - } + { + return; + } dc = DC_HandleToPtr(hDC); - SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); - SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); + SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface); + SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface); DC_ReleasePtr( hDC ); /* Compile the total mouse movement change and dispatch button events. */ for (i = 0; i < InputCount; i++) + { + mouse_cx += Data[i].LastX; + mouse_cy += Data[i].LastY; + + Msg.wParam = ButtonsDown; + Msg.lParam = MAKELPARAM(mouse_x + mouse_cx, mouse_y + mouse_cy); + Msg.message = WM_MOUSEMOVE; + Msg.time = TickCount; + Msg.pt.x = mouse_x + mouse_cx; + Msg.pt.y = mouse_y + mouse_cy; + if ((0 != Data[i].LastX) || (0 != Data[i].LastY)) { - mouse_cx += Data[i].LastX; - mouse_cy += Data[i].LastY; - - Msg.wParam = ButtonsDown; - Msg.lParam = MAKELPARAM(mouse_x + mouse_cx, mouse_y + mouse_cy); - Msg.message = WM_MOUSEMOVE; - Msg.time = TickCount; - Msg.pt.x = mouse_x + mouse_cx; - Msg.pt.y = mouse_y + mouse_cy; MsqInsertSystemMessage(&Msg); + } - for (j = 0; j < 3; j++) - { - ULONG Flag = MouseButtonFlag[j]; - if (Data[i].ButtonData & (1 << j) && !(ButtonsDown & Flag)) - { - ButtonsDown |= Flag; - - Msg.wParam = ButtonsDown; - Msg.message = MouseButtonDownMessage[j]; - MsqInsertSystemMessage(&Msg); - } - if (!(Data[i].ButtonData & (1 << j)) && (ButtonsDown & Flag)) - { - ButtonsDown &= ~Flag; - - Msg.wParam = ButtonsDown; - Msg.message = MouseButtonUpMessage[j]; - MsqInsertSystemMessage(&Msg); - } - } + if (Data[i].ButtonFlags != 0) + { + if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_DOWN) > 0) + { + Msg.wParam = MK_LBUTTON; + Msg.message = WM_LBUTTONDOWN; + } + if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN) > 0) + { + Msg.wParam = MK_MBUTTON; + Msg.message = WM_MBUTTONDOWN; + } + if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN) > 0) + { + Msg.wParam = MK_RBUTTON; + Msg.message = WM_RBUTTONDOWN; + } + + if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_UP) > 0) + { + Msg.wParam = MK_LBUTTON; + Msg.message = WM_LBUTTONUP; + } + if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_UP) > 0) + { + Msg.wParam = MK_MBUTTON; + Msg.message = WM_MBUTTONUP; + } + if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_UP) > 0) + { + Msg.wParam = MK_RBUTTON; + Msg.message = WM_RBUTTONUP; + } + + MsqInsertSystemMessage(&Msg); } + } /* If the mouse moved then move the pointer. */ - if (mouse_cx != 0 || mouse_cy != 0) + if ((mouse_cx != 0 || mouse_cy != 0) && MouseEnabled) + { + mouse_x += mouse_cx; + mouse_y += mouse_cy; + + mouse_x = max(mouse_x, 0); + mouse_y = max(mouse_y, 0); + mouse_x = min(mouse_x, 620); + mouse_y = min(mouse_y, 460); + + if (SafetySwitch == FALSE && SafetySwitch2 == FALSE) { - mouse_x += mouse_cx; - mouse_y += mouse_cy; - - mouse_x = max(mouse_x, 0); - mouse_y = max(mouse_y, 0); - mouse_x = min(mouse_x, 620); - mouse_y = min(mouse_y, 460); - - if (SafetySwitch == FALSE && SafetySwitch2 == FALSE) - { - SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); - } + SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); } + } } VOID @@ -285,30 +320,41 @@ EnableMouse(HDC hDisplayDC) SIZEL MouseSize; RECTL MouseRect; - dc = DC_HandleToPtr(hDisplayDC); - if( dc ){ - SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); - SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); - DC_ReleasePtr( hDisplayDC ); - - /* Create the default mouse cursor. */ - mouse_width = 32; - mouse_height = 32; - MouseSize.cx = 32; - MouseSize.cy = 64; - hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, 0, DefaultCursor); - MouseSurf = (PSURFOBJ)AccessUserObject(hMouseSurf); - - /* Tell the display driver to set the pointer shape. */ - SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 320, 240, - &MouseRect, 0); - - mouse_x = 320; - mouse_y = 240; - MouseEnabled = TRUE; + if( hDisplayDC ) + { + dc = DC_HandleToPtr(hDisplayDC); + SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface); + SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface); + DC_ReleasePtr( hDisplayDC ); + + /* Create the default mouse cursor. */ + mouse_width = 32; + mouse_height = 32; + MouseSize.cx = 32; + MouseSize.cy = 64; + hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, BMF_TOPDOWN, DefaultCursor); + MouseSurf = (PSURFOBJ)AccessUserObject((ULONG) hMouseSurf); + + /* Tell the display driver to set the pointer shape. */ +#if 0 + mouse_x = SurfObj->sizlBitmap.cx / 2; + mouse_y = SurfObj->sizlBitmap.cy / 2; +#else + mouse_x = 320; + mouse_y = 240; +#endif + PointerStatus = SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, + 0, 0, mouse_x, mouse_y, &MouseRect, + SPS_CHANGE); + + MouseEnabled = (SPS_ACCEPT_EXCLUDE == PointerStatus || + SPS_ACCEPT_NOEXCLUDE == PointerStatus); + + EngDeleteSurface(hMouseSurf); } - else{ - MouseEnabled = FALSE; + else + { + MouseEnabled = FALSE; } } diff --git a/subsys/win32k/eng/objects.h b/subsys/win32k/eng/objects.h index 23bb15c..bf4149e 100644 --- a/subsys/win32k/eng/objects.h +++ b/subsys/win32k/eng/objects.h @@ -69,7 +69,7 @@ typedef struct _FONTGDI { LPCWSTR Filename; FT_Face face; - TEXTMETRIC TextMetric; + TEXTMETRICW TextMetric; } FONTGDI, *PFONTGDI; typedef struct _PALGDI { @@ -131,19 +131,32 @@ typedef VOID STDCALL (*PFN_Synchronize)(DHPDEV, PRECTL); typedef VOID STDCALL (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL); -typedef VOID STDCALL (*PFN_SetPointerShape)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PXLATEOBJ, +typedef ULONG STDCALL (*PFN_SetPointerShape)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PXLATEOBJ, LONG, LONG, LONG, LONG, PRECTL, ULONG); typedef HBITMAP STDCALL (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG); typedef BOOL STDCALL (*PFN_SetPalette)(DHPDEV, PALOBJ*, ULONG, ULONG, ULONG); +/* Forward declare (circular reference) */ +typedef struct _SURFGDI *PSURFGDI; + +typedef VOID (*PFN_DIB_PutPixel)(PSURFOBJ, LONG, LONG, ULONG); +typedef ULONG (*PFN_DIB_GetPixel)(PSURFOBJ, LONG, LONG); +typedef VOID (*PFN_DIB_HLine) (PSURFOBJ, LONG, LONG, LONG, ULONG); +typedef VOID (*PFN_DIB_VLine) (PSURFOBJ, LONG, LONG, LONG, ULONG); +typedef BOOLEAN (*PFN_DIB_BitBlt) (PSURFOBJ DestSurf, PSURFOBJ SourceSurf, + PSURFGDI DestGDI, PSURFGDI SourceGDI, + PRECTL DestRect, PPOINTL SourcePoint, + XLATEOBJ *ColorTranslation); + typedef struct _SURFGDI { ENGOBJ Header; SURFOBJ SurfObj; INT BitsPerPixel; + /* Driver functions */ PFN_BitBlt BitBlt; PFN_TransparentBlt TransparentBlt; PFN_StretchBlt StretchBlt; @@ -160,7 +173,13 @@ typedef struct _SURFGDI { PFN_SetPalette SetPalette; PFN_MovePointer MovePointer; PFN_SetPointerShape SetPointerShape; -} SURFGDI, *PSURFGDI; + + /* DIB functions */ + PFN_DIB_PutPixel DIB_PutPixel; + PFN_DIB_HLine DIB_HLine; + PFN_DIB_VLine DIB_VLine; + PFN_DIB_BitBlt DIB_BitBlt; +} SURFGDI; typedef struct _XFORMGDI { ENGOBJ Header; @@ -174,6 +193,14 @@ typedef struct _XLATEGDI { HPALETTE SourcePal; ULONG *translationTable; + + ULONG RedMask; + ULONG GreenMask; + ULONG BlueMask; + INT RedShift; + INT GreenShift; + INT BlueShift; + BOOL UseShiftAndMask; } XLATEGDI; // List of GDI objects diff --git a/subsys/win32k/eng/paint.c b/subsys/win32k/eng/paint.c index a500969..3f4f79c 100644 --- a/subsys/win32k/eng/paint.c +++ b/subsys/win32k/eng/paint.c @@ -25,56 +25,17 @@ BOOL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor) { - // These functions are assigned if we're working with a DIB - // The assigned functions depend on the bitsPerPixel of the DIB - PFN_DIB_PutPixel DIB_PutPixel; - PFN_DIB_HLine DIB_HLine; - PFN_DIB_VLine DIB_VLine; LONG y; - ULONG x, LineWidth, leftOfBitmap; + ULONG LineWidth; SURFGDI *SurfaceGDI; SurfaceGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface); MouseSafetyOnDrawStart(Surface, SurfaceGDI, pRect->left, pRect->top, pRect->right, pRect->bottom); -/* - if(Surface->iType!=STYPE_BITMAP) - { - // Call the driver's DrvLineTo - ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); - MouseSafetyOnDrawEnd(Surface, SurfGDI); - return ret; - } -*/ - // Assign DIB functions according to bytes per pixel - DPRINT("BPF: %d\n", BitsPerFormat(Surface->iBitmapFormat)); - switch(BitsPerFormat(Surface->iBitmapFormat)) - { - case 4: - DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel; - DIB_HLine = (PFN_DIB_HLine)DIB_4BPP_HLine; - DIB_VLine = (PFN_DIB_VLine)DIB_4BPP_VLine; - break; - - case 24: - DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel; - DIB_HLine = (PFN_DIB_HLine)DIB_24BPP_HLine; - DIB_VLine = (PFN_DIB_VLine)DIB_24BPP_VLine; - break; - - default: - DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat, - BitsPerFormat(Surface->iBitmapFormat)); - - MouseSafetyOnDrawEnd(Surface, SurfaceGDI); - return FALSE; - } - LineWidth = pRect->right - pRect->left; DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom); for (y = pRect->top; y < pRect->bottom; y++) { - //EngLineTo(Surface, SurfaceGDI, Dimensions->left, y, LineWidth, iColor); - DIB_HLine(Surface, pRect->left, pRect->right, y, iColor); + SurfaceGDI->DIB_HLine(Surface, pRect->left, pRect->right, y, iColor); } MouseSafetyOnDrawEnd(Surface, SurfaceGDI); @@ -86,6 +47,7 @@ BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, { RECT_ENUM RectEnum; BOOL EnumMore; + ULONG i; DPRINT("ClipRegion->iMode:%d, ClipRegion->iDComplexity: %d\n Color: %d", ClipRegion->iMode, ClipRegion->iDComplexity, iColor); switch(ClipRegion->iMode) { @@ -106,7 +68,9 @@ BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, do { EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum); - FillSolid(Surface, &RectEnum.arcl[0], iColor); + for (i = 0; i < RectEnum.c; i++) { + FillSolid(Surface, RectEnum.arcl + i, iColor); + } } while (EnumMore); } diff --git a/subsys/win32k/eng/palette.c b/subsys/win32k/eng/palette.c index 327cbe3..7411167 100644 --- a/subsys/win32k/eng/palette.c +++ b/subsys/win32k/eng/palette.c @@ -12,13 +12,13 @@ #include #include "handle.h" -//#define NDEBUG +#define NDEBUG #include HPALETTE STDCALL EngCreatePalette(ULONG Mode, ULONG NumColors, - PULONG *Colors, // FIXME: This was implemented with ULONG *Colors!! + ULONG *Colors, ULONG Red, ULONG Green, ULONG Blue) @@ -30,7 +30,7 @@ EngCreatePalette(ULONG Mode, if( !ValidEngHandle( NewPalette ) ) return 0; - PalGDI = (PALGDI*) AccessInternalObject( NewPalette ); + PalGDI = (PALGDI*) AccessInternalObject( (ULONG) NewPalette ); ASSERT( PalGDI ); PalGDI->Mode = Mode; @@ -68,7 +68,7 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Colors, ULONG *PaletteEntry) { - ULONG i, entry; + ULONG i; PALGDI *PalGDI; PalGDI = (PALGDI*)AccessInternalObjectFromUserObject(PalObj); diff --git a/subsys/win32k/eng/surface.c b/subsys/win32k/eng/surface.c index 3ec0967..dfa33be 100644 --- a/subsys/win32k/eng/surface.c +++ b/subsys/win32k/eng/surface.c @@ -18,8 +18,9 @@ #include #include #include "handle.h" +#include "../dib/dib.h" -//#define NDEBUG +#define NDEBUG #include INT BitsPerFormat(ULONG Format) @@ -60,13 +61,94 @@ ULONG BitmapFormat(WORD Bits, DWORD Compression) } } -VOID InitializeHooks(SURFGDI *SurfGDI) +static VOID Dummy_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) +{ + return; +} + +static VOID Dummy_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) +{ + return; +} + +static VOID Dummy_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) +{ + return; +} + +static BOOLEAN Dummy_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFGDI *DestGDI, SURFGDI *SourceGDI, + PRECTL DestRect, POINTL *SourcePoint, + XLATEOBJ *ColorTranslation) +{ + return FALSE; +} + +VOID InitializeFuncs(SURFGDI *SurfGDI, ULONG BitmapFormat) { SurfGDI->BitBlt = NULL; SurfGDI->CopyBits = NULL; SurfGDI->CreateDeviceBitmap = NULL; SurfGDI->SetPalette = NULL; SurfGDI->TransparentBlt = NULL; + + switch(BitmapFormat) + { + case BMF_1BPP: + SurfGDI->DIB_PutPixel = DIB_1BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_1BPP_HLine; + SurfGDI->DIB_VLine = DIB_1BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_1BPP_BitBlt; + break; + + case BMF_4BPP: + SurfGDI->DIB_PutPixel = DIB_4BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_4BPP_HLine; + SurfGDI->DIB_VLine = DIB_4BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_4BPP_BitBlt; + break; + + case BMF_8BPP: + SurfGDI->DIB_PutPixel = DIB_8BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_8BPP_HLine; + SurfGDI->DIB_VLine = DIB_8BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_8BPP_BitBlt; + break; + + case BMF_16BPP: + SurfGDI->DIB_PutPixel = DIB_16BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_16BPP_HLine; + SurfGDI->DIB_VLine = DIB_16BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_16BPP_BitBlt; + break; + + case BMF_24BPP: + SurfGDI->DIB_PutPixel = DIB_24BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_24BPP_HLine; + SurfGDI->DIB_VLine = DIB_24BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_24BPP_BitBlt; + break; + + case BMF_32BPP: + SurfGDI->DIB_PutPixel = DIB_32BPP_PutPixel; + SurfGDI->DIB_HLine = DIB_32BPP_HLine; + SurfGDI->DIB_VLine = DIB_32BPP_VLine; + SurfGDI->DIB_BitBlt = DIB_32BPP_BitBlt; + break; + + case BMF_4RLE: + case BMF_8RLE: + /* Not supported yet, fall through to unrecognized case */ + default: + DPRINT1("InitializeFuncs: unsupported DIB format %d\n", + BitmapFormat); + + SurfGDI->DIB_PutPixel = Dummy_PutPixel; + SurfGDI->DIB_HLine = Dummy_HLine; + SurfGDI->DIB_VLine = Dummy_VLine; + SurfGDI->DIB_BitBlt = Dummy_BitBlt; + break; + } } HBITMAP STDCALL @@ -100,13 +182,11 @@ EngCreateBitmap(IN SIZEL Size, if( !ValidEngHandle( NewBitmap ) ) return 0; - SurfObj = (SURFOBJ*) AccessUserObject( NewBitmap ); - SurfGDI = (SURFGDI*) AccessInternalObject( NewBitmap ); + SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewBitmap ); + SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewBitmap ); ASSERT( SurfObj ); ASSERT( SurfGDI ); - InitializeHooks(SurfGDI); - SurfGDI->BitsPerPixel = BitsPerFormat(Format); SurfObj->lDelta = Width; SurfObj->cjBits = SurfObj->lDelta * Size.cy; @@ -134,6 +214,10 @@ EngCreateBitmap(IN SIZEL Size, SurfObj->sizlBitmap = Size; SurfObj->iBitmapFormat = Format; SurfObj->iType = STYPE_BITMAP; + SurfObj->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT); + SurfObj->pvScan0 = SurfObj->pvBits; + + InitializeFuncs(SurfGDI, Format); // Use flags to determine bitmap type -- TOP_DOWN or whatever @@ -153,13 +237,11 @@ EngCreateDeviceSurface(IN DHSURF dhsurf, if( !ValidEngHandle( NewSurface ) ) return 0; - SurfObj = (SURFOBJ*) AccessUserObject( NewSurface ); - SurfGDI = (SURFGDI*) AccessInternalObject( NewSurface ); + SurfObj = (SURFOBJ*) AccessUserObject( (ULONG) NewSurface ); + SurfGDI = (SURFGDI*) AccessInternalObject( (ULONG) NewSurface ); ASSERT( SurfObj ); ASSERT( SurfGDI ); - InitializeHooks(SurfGDI); - SurfGDI->BitsPerPixel = BitsPerFormat(Format); SurfObj->dhsurf = dhsurf; SurfObj->hsurf = dhsurf; // FIXME: Is this correct?? @@ -168,6 +250,8 @@ EngCreateDeviceSurface(IN DHSURF dhsurf, SurfObj->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)); SurfObj->iType = STYPE_DEVICE; + InitializeFuncs(SurfGDI, Format); + return NewSurface; } @@ -243,3 +327,9 @@ EngLockSurface(IN HSURF Surface) // FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c) return (SURFOBJ*)AccessUserObject((ULONG)Surface); } + +VOID STDCALL +EngUnlockSurface(IN SURFOBJ *Surface) +{ + // FIXME: Call GDI_UnlockObject +} diff --git a/subsys/win32k/eng/transblt.c b/subsys/win32k/eng/transblt.c index 9af39f6..ff0c1ce 100644 --- a/subsys/win32k/eng/transblt.c +++ b/subsys/win32k/eng/transblt.c @@ -82,6 +82,12 @@ EngTransparentBlt(PSURFOBJ Dest, MouseSafetyOnDrawEnd(Source, SourceGDI); MouseSafetyOnDrawEnd(Dest, DestGDI); + if(EngDeleteSurface(hTemp) == FALSE) + { + DbgPrint("Win32k: Failed to delete surface: %d\n", hTemp); + return FALSE; + } + return ret; } diff --git a/subsys/win32k/eng/xlate.c b/subsys/win32k/eng/xlate.c index da83776..00a4f63 100644 --- a/subsys/win32k/eng/xlate.c +++ b/subsys/win32k/eng/xlate.c @@ -17,7 +17,7 @@ #include #include "handle.h" -//#define NDEBUG +#define NDEBUG #include ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0; @@ -32,17 +32,43 @@ ULONG BGRtoULONG(BYTE Blue, BYTE Green, BYTE Red) return ((Blue & 0xff) << 16) | ((Green & 0xff) << 8) | (Red & 0xff); } +static ULONG ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color) +{ + ULONG TranslatedColor; + + TranslatedColor = 0; + if (XlateGDI->RedShift < 0) + { + TranslatedColor = (Color >> -(XlateGDI->RedShift)) & XlateGDI->RedMask; + } else + TranslatedColor = (Color << XlateGDI->RedShift) & XlateGDI->RedMask; + if (XlateGDI->GreenShift < 0) + { + TranslatedColor |= (Color >> -(XlateGDI->GreenShift)) & XlateGDI->GreenMask; + } else + TranslatedColor |= (Color << XlateGDI->GreenShift) & XlateGDI->GreenMask; + if (XlateGDI->BlueShift < 0) + { + TranslatedColor |= (Color >> -(XlateGDI->BlueShift)) & XlateGDI->BlueMask; + } else + TranslatedColor |= (Color << XlateGDI->BlueShift) & XlateGDI->BlueMask; + + return TranslatedColor; +} + // FIXME: If the caller knows that the destinations are indexed and not RGB // then we should cache more than one value. Same with the source. // Takes indexed palette and a -ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, +ULONG ClosestColorMatch(XLATEGDI *XlateGDI, ULONG SourceColor, ULONG *DestColors, ULONG NumColors) { PVIDEO_CLUTDATA cSourceColor; PVIDEO_CLUTDATA cDestColors; LONG idx = 0, i, rt; + ULONG SourceRGB; + ULONG SourceRed, SourceGreen, SourceBlue; ULONG cxRed, cxGreen, cxBlue, BestMatch = 16777215; // Simple cache -- only one value because we don't want to waste time @@ -53,16 +79,33 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, return CCMLastColorMatch; } - cSourceColor = (PVIDEO_CLUTDATA)&SourceColor; + if (PAL_BITFIELDS == XlateGDI->XlateObj.iSrcType) + { + /* FIXME: must use bitfields */ + SourceRGB = ShiftAndMask(XlateGDI, SourceColor); + cSourceColor = (PVIDEO_CLUTDATA) &SourceRGB; +/* + SourceRed = (SourceColor >> 7) & 0xff; + SourceGreen = (SourceColor >> 2) & 0xff; + SourceBlue = (SourceColor << 3) & 0xff; +*/ + } + else + { + cSourceColor = (PVIDEO_CLUTDATA)&SourceColor; + } + SourceRed = cSourceColor->Red; + SourceGreen = cSourceColor->Green; + SourceBlue = cSourceColor->Blue; for (i=0; iRed - cDestColors->Red); + cxRed = (SourceRed - cDestColors->Red); cxRed *= cxRed; //compute cxRed squared - cxGreen = (cSourceColor->Green - cDestColors->Green); + cxGreen = (SourceGreen - cDestColors->Green); cxGreen *= cxGreen; - cxBlue = (cSourceColor->Blue - cDestColors->Blue); + cxBlue = (SourceBlue - cDestColors->Blue); cxBlue *= cxBlue; rt = /* sqrt */ (cxRed + cxGreen + cxBlue); @@ -80,19 +123,60 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, return idx; } -VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable, +VOID IndexedToIndexedTranslationTable(XLATEGDI *XlateGDI, ULONG *TranslationTable, PALGDI *PalDest, PALGDI *PalSource) { ULONG i; for(i=0; iNumColors; i++) { - TranslationTable[i] = ClosestColorMatch(PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors); + TranslationTable[i] = ClosestColorMatch(XlateGDI, PalSource->IndexedColors[i], PalDest->IndexedColors, PalDest->NumColors); } } -XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, - HPALETTE PaletteDest, HPALETTE PaletteSource) +static VOID BitMasksFromPal(USHORT PalType, PPALGDI Palette, + PULONG RedMask, PULONG BlueMask, PULONG GreenMask) +{ + switch(PalType) + { + case PAL_RGB: + *RedMask = RGB(255, 0, 0); + *GreenMask = RGB(0, 255, 0); + *BlueMask = RGB(0, 0, 255); + break; + case PAL_BGR: + *RedMask = RGB(0, 0, 255); + *GreenMask = RGB(0, 255, 0); + *BlueMask = RGB(255, 0, 0); + break; + case PAL_BITFIELDS: + *RedMask = Palette->RedMask; + *BlueMask = Palette->BlueMask; + *GreenMask = Palette->GreenMask; + break; + } +} + +/* + * Calculate the number of bits Mask must be shift to the left to get a + * 1 in the most significant bit position + */ +static INT CalculateShift(ULONG Mask) +{ + INT Shift = 0; + ULONG LeftmostBit = 1 << (8 * sizeof(ULONG) - 1); + + while (0 == (Mask & LeftmostBit) && Shift < 8 * sizeof(ULONG)) + { + Mask = Mask << 1; + Shift++; + } + + return Shift; +} + +XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, + HPALETTE PaletteDest, HPALETTE PaletteSource) { // FIXME: Add support for BGR conversions @@ -101,20 +185,27 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, XLATEGDI *XlateGDI; PALGDI *SourcePalGDI, *DestPalGDI; ULONG IndexedColors; + ULONG SourceRedMask, SourceGreenMask, SourceBlueMask; + ULONG DestRedMask, DestGreenMask, DestBlueMask; + UINT i; NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ )); if( !ValidEngHandle( NewXlate ) ) return NULL; - XlateObj = (XLATEOBJ*) AccessUserObject( NewXlate ); - XlateGDI = (XLATEGDI*) AccessInternalObject( NewXlate ); + XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate ); + XlateGDI = (XLATEGDI*) AccessInternalObject( (ULONG) NewXlate ); ASSERT( XlateObj ); ASSERT( XlateGDI ); - if(SourcePalType == PAL_INDEXED) + if (NULL != PaletteSource) + { SourcePalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteSource); - if(DestPalType == PAL_INDEXED) + } + if (NULL != PaletteDest) + { DestPalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteDest); + } XlateObj->iSrcType = SourcePalType; XlateObj->iDstType = DestPalType; @@ -125,6 +216,23 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, XlateObj->flXlate = 0; + XlateGDI->UseShiftAndMask = FALSE; + + /* Compute bit fiddeling constants unless both palettes are indexed, then we don't need them */ + if (PAL_INDEXED != SourcePalType || PAL_INDEXED != DestPalType) + { + BitMasksFromPal(PAL_INDEXED == SourcePalType ? PAL_RGB : SourcePalType, + SourcePalGDI, &SourceRedMask, &SourceBlueMask, &SourceGreenMask); + BitMasksFromPal(PAL_INDEXED == DestPalType ? PAL_RGB : DestPalType, + DestPalGDI, &DestRedMask, &DestBlueMask, &DestGreenMask); + XlateGDI->RedShift = CalculateShift(SourceRedMask) - CalculateShift(DestRedMask); + XlateGDI->RedMask = DestRedMask; + XlateGDI->GreenShift = CalculateShift(SourceGreenMask) - CalculateShift(DestGreenMask); + XlateGDI->GreenMask = DestGreenMask; + XlateGDI->BlueShift = CalculateShift(SourceBlueMask) - CalculateShift(DestBlueMask); + XlateGDI->BlueMask = DestBlueMask; + } + // If source and destination palettes are the same or if they're RGB/BGR if( (PaletteDest == PaletteSource) || ((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) || @@ -134,6 +242,20 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, return XlateObj; } + /* If source and destination are bitfield based (RGB and BGR are just special bitfields) */ + if ((PAL_RGB == DestPalType || PAL_BGR == DestPalType || PAL_BITFIELDS == DestPalType) && + (PAL_RGB == SourcePalType || PAL_BGR == SourcePalType || PAL_BITFIELDS == SourcePalType)) + { + if (SourceRedMask == DestRedMask && + SourceBlueMask == DestBlueMask && + SourceGreenMask == DestGreenMask) + { + XlateObj->flXlate |= XO_TRIVIAL; + } + XlateGDI->UseShiftAndMask = TRUE; + return XlateObj; + } + // Prepare the translation table if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) ) { @@ -158,9 +280,9 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, if(XlateObj->iDstType == PAL_INDEXED) { // Converting from indexed to indexed - IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI); + IndexedToIndexedTranslationTable(XlateGDI, XlateGDI->translationTable, DestPalGDI, SourcePalGDI); } else - if(XlateObj->iDstType == PAL_RGB) + if (PAL_RGB == XlateObj->iDstType || PAL_BITFIELDS == XlateObj->iDstType ) { // FIXME: Is this necessary? I think the driver has to call this // function anyways if pulXlate is NULL and Source is PAL_INDEXED @@ -170,6 +292,13 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType, XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE, SourcePalGDI->NumColors, XlateGDI->translationTable); + if (PAL_BITFIELDS == XlateObj->iDstType) + { + for (i = 0; i < SourcePalGDI->NumColors; i++) + { + XlateGDI->translationTable[i] = ShiftAndMask(XlateGDI, XlateGDI->translationTable[i]); + } + } } XlateObj->pulXlate = XlateGDI->translationTable; @@ -232,7 +361,11 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj, { return Color; } else - if(XlateObj->iSrcType == PAL_RGB) + if(XlateGDI->UseShiftAndMask) + { + return ShiftAndMask(XlateGDI, Color); + } else + if(PAL_RGB == XlateObj->iSrcType || PAL_BITFIELDS == XlateObj->iSrcType) { // FIXME: should we cache colors used often? // FIXME: won't work if destination isn't indexed @@ -240,8 +373,8 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj, // Extract the destination palette PalGDI = (PALGDI*)AccessInternalObject((ULONG)XlateGDI->DestPal); - // Return closest match for the given RGB color - return ClosestColorMatch(Color, PalGDI->IndexedColors, PalGDI->NumColors); + // Return closest match for the given color + return ClosestColorMatch(XlateGDI, Color, PalGDI->IndexedColors, PalGDI->NumColors); } else if(XlateObj->iSrcType == PAL_INDEXED) { diff --git a/subsys/win32k/freetype/.cvsignore b/subsys/win32k/freetype/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/CHANGES b/subsys/win32k/freetype/CHANGES deleted file mode 100644 index d9d5816..0000000 --- a/subsys/win32k/freetype/CHANGES +++ /dev/null @@ -1,904 +0,0 @@ -LATEST CHANGES - - - deactivated the trueType bytecode interpreter by default - - - deactivated the "src/type1" font driver. Now "src/type1z" is - used by default.. - - - updates to the build system. We now compile the library correctly - under Unix system through "configure" which is automatically called - on the first "make" invocation. - - - added the auto-hinting module !!. Fixing some bugs here and there.. - - - found some bugs in the composite loader (seac) of the Type1-based - font drivers.. - - - renamed the directory "freetype2/config" to "freetype2/builds" and - updated all relevant files.. - - - found a memory leak in the "type1" driver - - - incorporated Tom's patches to support flex operators correctly - in OpenType/CFF fonts.. Now all I need is to support pure CFF - and CEF fonts to be done with this driver.. :-) - - - added the Windows FNT/FON driver in "src/winfonts". For now, - it always "simulates" a Unicode charmap, so it shouldn't be - considered completed right now.. - - It's there to be more a proof of concept than anything else - anyway. The driver is a single C source file, that compiles - to 3 Kb of code.. - - I'm still working on the PCF/BDF drivers.. but I'm too lazy - to finish them now.. - - - - CHANGES TO THE HIGH-LEVEL API - - o FT_Get_Kerning has a new parameter that allows you to select - the coordinates of the kerning vector ( font units, scaled, - scaled + grid-fitted ). - - o the outline functions are now in and not - part of anymore - - o now contains declarations for - FT_New_Library, FT_Done_Library, FT_Add_Default_Modules - - o the so-called convenience functions have moved from "ftoutln.c" - to "ftglyph.c", and are thus available with this optional component - of the library. They are declared in now.. - - o anti-aliased rendering is now the default for FT_Render_Glyph - (i.e. corresponds to render_mode == 0 == ft_render_mode_normal). - To generate a monochrome bitmap, use ft_render_mode_mono, or the - FT_LOAD_MONOCHROME flag in FT_Load_Glyph/FT_Load_Char. - - FT_LOAD_ANTI_ALIAS is still defined, but values to 0. - - o now include , - solving a few headaches :-) - - o the type FT_GlyphSlotRec has now a "library" field. - - - - - CHANGES TO THE "ftglyph.h" API - - This API has been severely modified in order to make it simpler, - clearer, and more efficient. It certainly now looks like a real - "glyph factory" object, and allows client applications to manage - (i.e. transform, bbox and render) glyph images without ever knowing - their original format. - - - added support for CID-keyed fonts to the CFF driver. - maybe support for pure CFF + CEF fonts should come in ?? - - - - cleaned up source code in order to avoid two functions with the - same name. Also changed the names of the files in "type1z" from - "t1XXXX" to "z1XXXX" in order to avoid any conflicts. - - "make multi" now works well :-) - - Also removed the use of "cidafm" for now, even if the source files - are still there. This functionality will certainly go into a specific - module.. - - - - - ADDED SUPPORT FOR THE AUTO-HINTER - - It works :-) I have a demo program which simply is a copy of "ftview" - that does a FT_Add_Module( library, &autohinter_module_class ) after - library initialisation, and Type 1 & OpenType/CFF fonts are now hinted. - - CID fonts are not hinted, as they include no charmap and the auto-hinter - doesn't include "generic" global metrics computations yet.. - - Now, I need to release this thing to the FreeType 2 source.. - - - - - - - CHANGES TO THE RENDERER MODULES - - the monochrome and smooth renderers are now in two distinct directories, - namely "src/raster1" and "src/smooth". Note that the old "src/renderer" - is now gone.. - - I ditched the 5-gray-levels renderers. Basically, it involved a simple - #define toggle in 'src/raster1/ftraster.c' - - FT_Render_Glyph, FT_Outline_Render & FT_Outline_Get_Bitmap now select - the best renderer available, depending on render mode. If the current - renderer for a given glyph image format isn't capable of supporting - the render mode, another one will be found in the library's list. - - This means that client applications do not need to switch or set the - renderers themselves (as in the latest change), they'll get what they - want automatically... At last.. - - Changed the demo programs accordingly.. - - - - - MAJOR INTERNAL REDESIGN: - - A lot of internal modifications have been performed lately on the - source in order to provide the following enhancements: - - - more generic module support: - - The FT_Module type is now defined to represent a handle to a given - module. The file contains the FT_Module_Class - definition, as well as the module-loading public API - - The FT_Driver type is still defined, and still represents a pointer - to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module, - FT_Get_Driver by FT_Get_Module, etc.. - - - - support for generic glyph image types: - - The FT_Renderer type is a pointer to a module used to perform various - operations on glyph image. - - Each renderer is capable of handling images in a single format - (e.g. ft_glyph_format_outline). Its functions are used to: - - - transform an glyph image - - render a glyph image into a bitmap - - return the control box (dimensions) of a given glyph image - - - The scan converters "ftraster.c" and "ftgrays.c" have been moved - to the new directory "src/renderer", and are used to provide two - default renderer modules. - - One corresponds to the "standard" scan-converter, the other to the - "smooth" one. - - The current renderer can be set through the new function - FT_Set_Renderer. - - The old raster-related function FT_Set_Raster, FT_Get_Raster and - FT_Set_Raster_Mode have now disappeared, in favor of the new: - - FT_Get_Renderer - FT_Set_Renderer - - see the file for more details.. - - These changes were necessary to properly support different scalable - formats in the future, like bi-color glyphs, etc.. - - - - glyph loader object: - - A new internal object, called a 'glyph loader' has been introduced - in the base layer. It is used by all scalable format font drivers - to load glyphs and composites. - - This object has been created to reduce the code size of each driver, - as each one of them basically re-implemented its functionality. - - See and the FT_GlyphLoader type for - more information.. - - - - - FT_GlyphSlot had new fields: - - In order to support extended features (see below), the FT_GlyphSlot - structure has a few new fields: - - linearHoriAdvance: this field gives the linearly scaled (i.e. - scaled but unhinted) advance width for the glyph, - expressed as a 16.16 fixed pixel value. This - is useful to perform WYSIWYG text. - - linearVertAdvance: this field gives the linearly scaled advance - height for the glyph (relevant in vertical glyph - layouts only). This is useful to perform - WYSIWYG text. - - Note that the two above field replace the removed "metrics2" field - in the glyph slot. - - advance: this field is a vector that gives the transformed - advance for the glyph. By default, it corresponds - to the advance width, unless FT_LOAD_VERTICAL_LAYOUT - was specified when calling FT_Load_Glyph or FT_Load_Char - - bitmap_left: this field gives the distance in integer pixels from - the current pen position to the left-most pixel of - a glyph image WHEN IT IS A BITMAP. It is only valid - when the "format" field is set to - "ft_glyph_format_bitmap", for example, after calling - the new function FT_Render_Glyph. - - bitmap_top: this field gives the distance in integer pixels from - the current pen position (located on the baseline) to - the top-most pixel of the glyph image WHEN IT IS A - BITMAP. Positive values correspond to upwards Y. - - loader: this is a new private field for the glyph slot. Client - applications should not touch it.. - - - - support for transforms and direct rendering in FT_Load_Glyph: - - Most of the functionality found in has been - moved to the core library. Hence, the following: - - - a transform can be specified for a face through FT_Set_Transform. - this transform is applied by FT_Load_Glyph to scalable glyph images - (i.e. NOT TO BITMAPS) before the function returns, unless the - bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags.. - - - - once a glyph image has been loaded, it can be directly converted to - a bitmap by using the new FT_Render_Glyph function. Note that this - function takes the glyph image from the glyph slot, and converts - it to a bitmap whose properties are returned in "face.glyph.bitmap", - "face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original - native image might be lost after the conversion. - - - - when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph - and FT_Load_Char functions will call FT_Render_Glyph automatically - when needed. - - - - - - reformated all modules source code in order to get rid of the basic - data types redifinitions (i.e. "TT_Int" instead of "FT_Int", "T1_Fixed" - instead of "FT_Fixed"). Hence the format-specific prefixes like "TT_", - "T1_", "T2_" and "CID_" are only used for relevant structures.. - -============================================================================ -OLD CHANGES FOR BETA 7 - - - bug-fixed the OpenType/CFF parser. It now loads and displays my two - fonts nicely, but I'm pretty certain that more testing is needed :-) - - - fixed the crummy Type 1 hinter, it now handles accented characters - correctly (well, the accent is not always well placed, but that's - another problem..) - - - added the CID-keyed Type 1 driver in "src/cid". Works pretty well for - only 13 Kb of code ;-) Doesn't read AFM files though, nor the really - useful CMAP files.. - - - fixed two bugs in the smooth renderer (src/base/ftgrays.c). Thanks to - Boris Letocha for spotting them and providing a fix.. - - - fixed potential "divide by zero" bugs in ftcalc.c.. my god.. - - - added source code for the OpenType/CFF driver (still incomplete though..) - - - modified the SFNT driver slightly to perform more robust header - checks in TT_Load_SFNT_Header. This prevents certain font files - (e.g. some Type 1 Multiple Masters) from being incorrectly "recognized" - as TrueType font files.. - - - moved a lot of stuff from the TrueType driver to the SFNT module, - this allows greater code re-use between font drivers (e.g. TrueType, - OpenType, Compact-TrueType, etc..) - - - added a tiny segment cache to the SFNT Charmap 4 decoder, in order - to minimally speed it up.. - - - added support for Multiple Master fonts in "type1z". There is also - a new file named which defines functions to - manage them from client applications. - - The new file "src/base/ftmm.c" is also optional to the engine.. - - - various formatting changes (e.g. EXPORT_DEF -> FT_EXPORT_DEF) + - small bug fixes in FT_Load_Glyph, the "type1" driver, etc.. - - - a minor fix to the Type 1 driver to let them apply the font matrix - correctly (used for many oblique fonts..) - - - some fixes for 64-bit systems (mainly changing some FT_TRACE calls - to use %p instead of %lx).. Thanks to Karl Robillard - - - fixed some bugs in the sbit loader (src/base/sfnt/ttsbit.c) + added - a new flag, FT_LOAD_CROP_BITMAP to query that bitmaps be cropped when - loaded from a file (maybe I should move the bitmap cropper to the - base layer ??). - - - changed the default number of gray levels of the smooth renderer to - 256 (instead of the previous 128). Of course, the human eye can't - see any difference ;-) - - - removed TT_MAX_SUBGLYPHS, there is no static limit on the number of - subglyphs in a TrueType font now.. - -============================================================================= -OLD CHANGES 16 May 2000 - - - tagged "BETA-6" in the CVS tree. This one is a serious release candidate - even though it doesn't incorporate the auto-hinter yet.. - - - various obsolete files were removed, and copyright header updated - - - finally updated the standard raster to fix the monochrome rendering bug - + re-enable support for 5-gray levels anti-aliasing (suck, suck..) - - - created new header files, and modified sources accordingly: - - - simple FreeType types, without the API - - definition of memory-management macros - - - added the "DSIG" (OpenType Digital Signature) tag to - - - light update/cleaning of the build system + changes to the sources in - order to get rid of _all_ compiler warnings with three compilers, i.e: - - gcc with "-ansi -pedantic -Wall -W", Visual C++ with "/W3 /WX" - and LCC - - IMPORTANT NOTE FOR WIN32-LCC USERS: - | - | It seems the C pre-processor that comes with LCC is broken, it - | doesn't recognize the ANSI standard directives # and ## correctly - | when one of the argument is a macro. Also, something like: - | - | #define F(x) print##x - | - | F(("hello")) - | - | will get incorrectly translated to: - | - | print "hello") - | - | by its pre-processor. For this reason, you simply cannot build - | FreeType 2 in debug mode with this compiler.. - - - - yet another massive grunt work. I've changed the definition of the - EXPORT_DEF, EXPORT_FUNC, BASE_DEF & BASE_FUNC macros. These now take - an argument, which is the function's return value type. - - This is necessary to compile FreeType as a DLL on Windows and OS/2. - Depending on the compiler used, a compiler-specific keyword like __export - or __system must be placed before (VisualC++) or after (BorlandC++) - the type.. - - Of course, this needed a lot of changes throughout the source code - to make it compile again... All cleaned up now, apparently.. - - Note also that there is a new EXPORT_VAR macro defined to allow the - _declaration_ of an exportable public (constant) variable. This is the - case of the raster interfaces (see ftraster.h and ftgrays.h), as well - as each module's interface (see sfdriver.h, psdriver.h, etc..) - - - new feature: it is now possible to pass extra parameters to font - drivers when creating a new face object. For now, this - capability is unused. It could however prove to be useful - in a near future.. - - the FT_Open_Args structure was changes, as well as the internal - driver interface (the specific "init_face" module function has now - a different signature). - - - updated the tutorial (not finished though). - - updated the top-level BUILD document - - - fixed a potential memory leak that could occur when loading embedded - bitmaps. - - - added the declaration of FT_New_Memory_Face in , as - it was missing from the public header (the implementation was already - in "ftobjs.c"). - - - the file has been seriously updated in order to - allow the automatic generation of error message tables. See the comments - within it for more information. - - - major directory hierarchy re-organisation. This was done for two things: - - * first, to ease the "manual" compilation of the library by requiring - at lot less include paths :-) - - * second, to allow external programs to effectively access internal - data fields. For example, this can be extremely useful if someone - wants to write a font producer or a font manager on top of FreeType. - - Basically, you should now use the 'freetype/' prefix for header inclusion, - as in: - - #include - #include - - Some new include sub-directories are available: - - a. the "freetype/config" directory, contains two files used to - configure the build of the library. Client applications should - not need to look at these normally, but they can if they want. - - #include - #include - - b. the "freetype/internal" directory, contains header files that - describes library internals. These are the header files that were - previously found in the "src/base" and "src/shared" directories. - - - As usual, the build system and the demos have been updated to reflect - the change.. - - Here's a layout of the new directory hierarchy: - - TOP - include/ - freetype/ - freetype.h - ... - config/ - ftoption.h - ftconfig.h - ftmodule.h - - internal/ - ftobjs.h - ftstream.h - ftcalc.h - ... - - src/ - base/ - ... - - sfnt/ - psnames/ - truetype/ - type1/ - type1z/ - - - Compiling a module is now much easier, for example, the following should - work when in the TOP directory on an ANSI build: - - gcc -c -I./include -I./src/base src/base/ftbase.c - gcc -c -I./include -I./src/sfnt src/sfnt/sfnt.c - etc.. - - (of course, using -Iconfig/ if you provide system-specific - configuration files). - - - - updated the structure of FT_Outline_Funcs in order to allow - direct coordinate scaling within the outline decomposition routine - (this is important for virtual "on" points with TrueType outlines) - + updates to the rasters to support this.. - - - updated the OS/2 table loading code in "src/sfnt/ttload.c" in order - to support version 2 of the table (see OpenType 1.2 spec) - - - created "include/tttables.h" and "include/t1tables.h" to allow - client applications to access some of the SFNT and T1 tables of a - face with a procedural interface (see FT_Get_Sfnt_Table()) - + updates to internal source files to reflect the change.. - - - some cleanups in the source code to get rid of warnings when compiling - with the "-Wall -W -ansi -pedantic" options in gcc. - - - debugged and moved the smooth renderer to "src/base/ftgrays.c" and - its header to "include/ftgrays.h" - - - updated TT_MAX_SUBGLYPHS to 96 as some CJK fonts have composites with - up to 80 sub-glyphs !! Thanks to Werner - -================================================================================ -OLD CHANGES - 14-apr-2000 - - - fixed a bug in the TrueType glyph loader that prevented the correct - loading of some CJK glyphs in mingli.ttf - - - improved the standard Type 1 hinter in "src/type1" - - - fixed two bugs in the experimental Type 1 driver in "src/type1z" - to handle the new XFree86 4.0 fonts (and a few other ones..) - - - the smooth renderer is now complete and supports sub-banding - to render large glyphs at high speed. However, it is still located - in "demos/src/ftgrays.c" and should move to the library itself - in the next beta.. NOTE: The smooth renderer doesn't compile in - stand-alone mode anymore, but this should be fixed RSN.. - - - introduced convenience functions to more easily deal with glyph - images, see "include/ftglyph.h" for more details, as well as the - new demo program named "demos/src/ftstring.c" that demonstrates - its use - - - implemented FT_LOAD_NO_RECURSE in both the TrueType and Type 1 - drivers (this is required by the auto-hinter to improve its results). - - - changed the raster interface, in order to allow client applications - to provide their own span-drawing callbacks. However, only the - smooth renderer supports this. See "FT_Raster_Params" in the - file "include/ftimage.h" - - - fixed a small bug in FT_MulFix that caused incorrect transform - computation !! - - - Note: The tutorial is out-of-date, grumpf.. :-( - -================================================================================ -OLD CHANGES - 12-mar-2000 - - - changed the layout of configuration files : now, all ANSI configuration - files are located in "freetype2/config". System-specific over-rides - can be placed in "freetype2/config/". - - - moved all configuration macros to "config/ftoption.h" - - - improvements in the Type 1 driver with AFM support - - - changed the fields in the FT_Outline structure : the old "flags" - array is re-named "tags", while all ancient flags are encoded into - a single unsigned int named "flags". - - - introduced new flags in FT_Outline.flags (see ft_outline_.... enums in - "ftimage.h"). - - - changed outline functions to "FT_Outline_" syntax - - - added a smooth anti-alias renderer to the demonstration programs - - added Mac graphics driver (thanks Just) - - - FT_Open_Face changed in order to received a pointer to a FT_Open_Args - descriptor.. - - - various cleanups, a few more API functions implemented (see FT_Attach_File) - - - updated some docs - -================================================================================ -OLD CHANGES - 22-feb-2000 - - - introduced the "psnames" module. It is used to: - - o convert a Postscript glyph name into the equivalent Unicode - character code (used by the Type 1 driver(s) to synthetize - on the fly a Unicode charmap). - - o provide an interface to retrieve the Postscript names of - the Macintosh, Adobe Standard & Adobe Expert character codes. - (the Macintosh names are used by the SFNT-module postscript - names support routines, while the other two tables are used - by the Type 1 driver(s)). - - - introduced the "type1z" alternate Type 1 driver. This is a (still - experimental) driver for the Type 1 format that will ultimately - replace the one in "src/type1". It uses pattern matching to load - data from the font, instead of a finite state analyzer. It works - much better than the "old" driver with "broken" fonts. It is also - much smaller (under 15 Kb). - - - the Type 1 drivers (both in "src/type1" and "src/type1z") are - nearly complete. They both provide automatic Unicode charmap - synthesis through the "psnames" module. No re-encoding vector - is needed. (note that they still leak memory due to some code - missing, and I'm getting lazy). - - Trivial AFM support has been added to read kerning information - but wasn't exactly tested as it should ;-) - - - The TrueType glyph loader has been seriously rewritten (see the - file "src/truetype/ttgload.c". It is now much, much simpler as - well as easier to read, maintain and understand :-) Preliminary - versions introduced a memory leak that has been reported by Jack - Davis, and is now fixed.. - - - introduced the new "ft_glyph_format_plotter", used to represent - stroked outlines like Windows "Vector" fonts, and certain Type 1 - fonts like "Hershey". The corresponding raster will be written - soon. - - - FT_New_Memory_Face is gone. Likewise, FT_Open_Face has a new - interface that uses a structure to describe the input stream, - the driver (if required), etc.. - -TODO - - Write FT_Get_Glyph_Bitmap and FT_Load_Glyph_Bitmap - - - Add a function like FT_Load_Character( face, char_code, load_flags ) - that would really embbed a call to FT_Get_Char_Index then FT_Load_Glyph - to ease developer's work. - - - Update the tutorial !! - - consider adding support for Multiple Master fonts in the Type 1 - drivers. - - - Test the AFM routines of the Type 1 drivers to check that kerning - information is returned correctly. - - - write a decent auto-gridding component !! We need this to release - FreeType 2.0 gold ! - - ------ less urgent needs : ---------- - - add a CFF/Type2 driver - - add a BDF driver - - add a FNT/PCF/HBF driver - - add a Speedo driver from the X11 sources - - -============================================================================== -OLDER CHANGES - 27-jan-2000 - - - updated the "sfnt" module interface to allow several SFNT-based - drivers to co-exist peacefully - - - updated the "T1_Face" type to better separate Postscript font content - from the rest of the FT_Face structure. Might be used later by the - CFF/Type2 driver.. - - - added an experimental replacement Type 1 driver featuring advanced - (and speedy) pattern matching to retrieve the data from postscript - fonts. - - - very minor changes in the implementation of FT_Set_Char_Size and - FT_Set_Pixel_Sizes (they now implement default to ligthen the - font driver's code). - - -============================================================================= -OLD MESSAGE - -This file summarizes the changes that occured since the last "beta" of FreeType 2. -Because the list is important, it has been divided into separate sections: - -Table Of Contents: - - I High-Level Interface (easier !) - II Directory Structure - III Glyph Image Formats - IV Build System - V Portability - VI Font Drivers - ------------------------------------------------------------------------------------------ -High-Level Interface : - - The high-level API has been considerably simplified. Here is how : - - - resource objects have disappeared. this means that face objects can - now be created with a single function call (see FT_New_Face and - FT_Open_Face) - - - when calling either FT_New_Face & FT_Open_Face, a size object and a - glyph slot object are automatically created for the face, and can be - accessed through "face->glyph" and "face->size" if one really needs to. - In most cases, there's no need to call FT_New_Size or FT_New_Glyph. - - - similarly, FT_Load_Glyph now only takes a "face" argument (instead of - a glyph slot and a size). Also, it's "result" parameter is gone, as - the glyph image type is returned in the field "face->glyph.format" - - - the list of available charmaps is directly accessible through - "face->charmaps", counting "face->num_charmaps" elements. Each - charmap has an 'encoding' field which specifies which known encoding - it deals with. Valid values are, for example : - - ft_encoding_unicode (for ASCII, Latin-1 and Unicode) - ft_encoding_apple_roman - ft_encoding_sjis - ft_encoding_adobe_standard - ft_encoding_adobe_expert - - other values may be added in the future. Each charmap still holds its - "platform_id" and "encoding_id" values in case the encoding is too - exotic for the current library - - ------------------------------------------------------------------------------------------ -Directory Structure: - - Should seem obvious to most of you: - - freetype/ - config/ -- configuration sub-makefiles - ansi/ - unix/ -- platform-specific configuration files - win32/ - os2/ - msdos/ - - include/ -- public header files, those to be included directly - by client apps - - src/ -- sources of the library - base/ -- the base layer - sfnt/ -- the sfnt "driver" (see the drivers section below) - truetype/ -- the truetype driver - type1/ -- the type1 driver - shared/ -- some header files shared between drivers - - demos/ -- demos/tools - - docs/ -- documentation (a bit empty for now) - ------------------------------------------------------------------------------------------ -Glyph Image Formats : - - Drivers are now able to register new glyph image formats within the library. - For now, the base layer supports of course bitmaps and vector outlines, but - one could imagine something different like colored bitmaps, bi-color - vectors or wathever else (Metafonts anyone ??). - - See the file `include/ftimage.h'. Note also that the type FT_Raster_Map is - gone, and is now replaced by FT_Bitmap, which should encompass all known - bitmap types. - - Each new image format must provide at least one "raster", i.e. a module - capable of transforming the glyph image into a bitmap. It's also possible - to change the default raster used for a given glyph image format. - - The default outline scan-converter now uses 128 levels of grays by default, - which tends to smooth many things. Note that the demo programs have been - updated significantly in order to display these.. - - ------------------------------------------------------------------------------------------ -Build system : - - You still need GNU Make to build the library. The build system has been - very seriously re-vamped in order to provide things like : - - - automatic host platform detection (reverting to 'config/ansi' - if it is not detected, with pseudo-standard compilation flags) - - - the ability to compile from the Makefiles with very different and - exotic compilers. Note that linking the library can be difficult for - some platforms. - - For example, the file `config/win32/lcclib.bat' is invoked by the - build system to create the ".lib" file with LCC-Win32 because its - librarian has too many flaws to be invoked directly from the Makefile. - - Here's how it works : - - - the first time you type `make', the build system runs a series of - sub-makefiles in order to detect your host platform. It then dumps - what it found, and creates a file called `config.mk' in the current - directory. This is a sub-Makefile used to define many important Make - variables used to build the library. - - - the second time, the build system detects the `config.mk' then use it - to build the library. All object files go into 'obj' by default, as - well as the library file, but this can easily be changed. - - Note that you can run "make setup" to force another host platform detection - even if a `config.mk' is present in the current directory. Another solution - is simply to delete the file, then re-run make. - - Finally, the default compiler for all platforms is gcc (for now, this will - hopefully changed in the future). You can however specify a different - compiler by specifying it after the 'setup' target as in : - - gnumake setup lcc on Win32 to use the LCC compiler - gnumake setup visualc on Win32 to use Visual C++ - - See the file `config//detect.mk' for a list of supported compilers - for your platforms. - - It should be relatively easy to write new detection rules files and - config.mk.. - - Finally, to build the demo programs, go to `demos' and launch GNU Make, - it will use the `config.mk' in the top directory to build the test - programs.. - ------------------------------------------------------------------------------------------ -Portability : - - In the previous beta, a single FT_System object was used to encompass - all low-level operations like thread synchronisation, memory management - and i/o access. This has been greatly simplified : - - - thread synchronisation has been dropped, for the simple reason that - the library is already re-entrant, and that if you really need two - threads accessing the same FT_Library, you should really synchronize - access to it yourself with a simple mutex. - - - memory management is performed through a very simple object called - "FT_Memory", which really is a table containing a table of pointers - to functions like malloc, realloc and free as well as some user data - (closure). - - - resources have disappeared (they created more problems than they - solved), and i/o management have been simplified greatly as a - result. Streams are defined through FT_Stream objects, which can - be either memory-based or disk-based. - - Note that each face has its own stream, which is closed only when - the face object is destroyed. Hence, a function like TT_Flush_Face - in 1.x cannot be directly supported. However, if you really need - something like this, you can easily tailor your own streams to achieve - the same feature at a lower level (and use FT_Open_Face instead of - FT_New_Face to create the face). - - See the file "include/ftsystem.h" for more details, as well as the - implementations found in "config/unix" and "config/ansi". - - ------------------------------------------------------------------------------------------ -Font Drivers : - - - The Font Driver interface has been modified in order to support - extensions & versioning. - - - The list of the font drivers that are statically linked to the - library at compile time is managed through a new configuration file - called `config//ftmodule.h'. - - This file is autogenerated when invoking `make modules'. This target - will parse all sub-directories of 'src', looking for a "module.mk" - rules file, used to describe the driver to the build system. - - Hence, one should call `make modules' each time a font driver is added - or removed from the `src' directory. - - - Finally, this version provides a "pseudo-driver" in `src/sfnt'. This - driver doesn't support font files directly, but provides services used - by all TrueType-like font drivers. Hence, its code is shared between - the TrueType & OpenType font formats, and possibly more formats to - come if we're lucky.. - ------------------------------------------------------------------------------------------ -Extensions support : - - The extensions support is inspired by the one found in 1.x. - - Now, each font driver has its own "extension registry", which lists - which extensions are available for the font faces managed by the driver. - - Extension ids are now strings, rather than 4-byte tags, as this is - usually more readable.. - - Each extension has: - - some data, associated to each face object - - an interface (table of function pointers) - - An extension that is format-specific should simply register itself - to the correct font driver. Here is some example code: - - // Registering an extensions - // - FT_Error FT_Init_XXXX_Extension( FT_Library library ) - { - FT_DriverInterface* tt_driver; - - driver = FT_Get_Driver( library, "truetype" ); - if (!driver) return FT_Err_Unimplemented_Feature; - - return FT_Register_Extension( driver, &extension_class ); - } - - - // Implementing the extensions - // - FT_Error FT_Proceed_Extension_XXX( FT_Face face ) - { - FT_XXX_Extension ext; - FT_XXX_Extension_Interface ext_interface; - - ext = FT_Get_Extension( face, "extensionid", &ext_interface ); - if (!ext) return error; - - return ext_interface->do_it(ext); - } - diff --git a/subsys/win32k/freetype/builds/.cvsignore b/subsys/win32k/freetype/builds/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/builds/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/builds/ansi/ansi.mk b/subsys/win32k/freetype/builds/ansi/ansi.mk deleted file mode 100644 index d326f83..0000000 --- a/subsys/win32k/freetype/builds/ansi/ansi.mk +++ /dev/null @@ -1,134 +0,0 @@ -# -# FreeType 2 configuration rules for a `normal' ANSI compiler -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := rm -f -SEP := / -HOSTSEP := $(SEP) -BUILD := $(TOP)/builds/ansi -PLATFORM := ansi - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f $TOP/Makefile setup [options] -# make -f $TOP/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_std - distclean_freetype: distclean_freetype_std - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $@ - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/detect.mk b/subsys/win32k/freetype/builds/detect.mk deleted file mode 100644 index d34904a..0000000 --- a/subsys/win32k/freetype/builds/detect.mk +++ /dev/null @@ -1,130 +0,0 @@ -# -# FreeType 2 host platform detection rules -# - - -# Copyright 1996-2000 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 sub-Makefile is in charge of detecting the current platform. It sets -# the following variables: -# -# BUILD The configuration and system-specific directory. Usually -# `freetype/builds/$(PLATFORM)' but can be different for -# custom builds of the library. -# -# The following variables must be defined in system specific `detect.mk' -# files: -# -# PLATFORM The detected platform. This will default to `ansi' if -# auto-detection fails. -# CONFIG_FILE The configuration sub-makefile to use. This usually depends -# on the compiler defined in the `CC' environment variable. -# DELETE The shell command used to remove a given file. -# COPY The shell command used to copy one file. -# SEP The platform-specific directory separator. -# CC The compiler to use. -# -# You need to set the following variable(s) before calling it: -# -# TOP The top-most directory in the FreeType library source -# hierarchy. If not defined, it will default to `.'. - -# If TOP is not defined, default it to `.' -# -ifndef TOP - TOP := . -endif - -# Set auto-detection default to `ansi' resp. UNIX-like operating systems. -# Note that we delay the evaluation of $(BUILD_CONFIG_), $(BUILD), and -# $(CONFIG_RULES). -# -PLATFORM := ansi -DELETE := $(RM) -COPY := cp -SEP := / - -BUILD_CONFIG_ = $(TOP)$(SEP)builds$(SEP) -BUILD = $(BUILD_CONFIG_)$(PLATFORM) -CONFIG_RULES = $(BUILD)$(SEP)$(CONFIG_FILE) - -# We define the BACKSLASH variable to hold a single back-slash character. -# This is needed because a line like -# -# SEP := \ -# -# does not work with GNU Make (the backslash is interpreted as a line -# continuation). While a line like -# -# SEP := \\ -# -# really defines $(SEP) as `\' on Unix, and `\\' on Dos and Windows! -# -BACKSLASH := $(strip \ ) - -# Now, include all detection rule files found in the `builds/' -# directories. Note that the calling order of the various `detect.mk' files -# isn't predictable. -# -include $(wildcard $(BUILD_CONFIG_)*/detect.mk) - -# In case no detection rule file was successful, use the default. -# -ifndef CONFIG_FILE - CONFIG_FILE := ansi.mk - setup: std_setup -endif - -# The following targets are equivalent, with the exception that they use -# a slightly different syntax for the `echo' command. -# -# std_setup: defined for most (i.e. Unix-like) platforms -# dos_setup: defined for Dos-ish platforms like Dos, Windows & OS/2 -# -.PHONY: std_setup dos_setup - -std_setup: - @echo "" - @echo "FreeType build system -- automatic system detection" - @echo "" - @echo "The following settings are used:" - @echo "" - @echo " platform $(PLATFORM)" - @echo " compiler $(CC)" - @echo " configuration directory $(BUILD)" - @echo " configuration rules $(CONFIG_RULES)" - @echo "" - @echo "If this does not correspond to your system or settings please remove the file" - @echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help." - @echo "" - @echo "Otherwise, simply type \`make' again to build the library." - @echo "" - @$(COPY) $(CONFIG_RULES) $(CONFIG_MK) - -dos_setup: - @echo ÿ - @echo FreeType build system -- automatic system detection - @echo ÿ - @echo The following settings are used: - @echo ÿ - @echo ÿÿplatformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(PLATFORM) - @echo ÿÿcompilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$(CC) - @echo ÿÿconfiguration directoryÿÿÿÿÿÿ$(BUILD) - @echo ÿÿconfiguration rulesÿÿÿÿÿÿÿÿÿÿ$(CONFIG_RULES) - @echo ÿ - @echo If this does not correspond to your system or settings please remove the file - @echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help. - @echo ÿ - @echo Otherwise, simply type 'make' again to build the library. - @echo ÿ - @$(COPY) $(subst /,\,$(CONFIG_RULES) $(CONFIG_MK)) > nul - -# EOF diff --git a/subsys/win32k/freetype/builds/dos/detect.mk b/subsys/win32k/freetype/builds/dos/detect.mk deleted file mode 100644 index f8c1706..0000000 --- a/subsys/win32k/freetype/builds/dos/detect.mk +++ /dev/null @@ -1,87 +0,0 @@ -# -# FreeType 2 configuration file to detect a DOS host platform. -# - - -# Copyright 1996-2000 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. - - -# We test for the COMSPEC environment variable, then run the `ver' -# command-line program to see if its output contains the word `Dos'. -# -# If this is true, we are running a Dos-ish platform (or an emulation). -# -ifeq ($(PLATFORM),ansi) - - ifdef COMSPEC - - is_dos := $(findstring Dos,$(shell ver)) - - # We try to recognize a Dos session under OS/2. The `ver' command - # returns `Operating System/2 ...' there, so `is_dos' should be empty. - # - # To recognize a Dos session under OS/2, we check COMSPEC for the - # substring `MDOS\COMMAND' - # - ifeq ($(is_dos),) - is_dos := $(findstring MDOS\COMMAND,$(COMSPEC)) - endif - - ifneq ($(is_dos),) - - PLATFORM := dos - DELETE := del - COPY := copy - - # Use DJGPP (i.e. gcc) by default. - # - CONFIG_FILE := dos-gcc.mk - SEP := / - ifndef CC - CC := gcc - endif - - # additionally, we provide hooks for various other compilers - # - ifneq ($(findstring turboc,$(MAKECMDGOALS)),) # Turbo C - CONFIG_FILE := dos-tcc.mk - SEP := $(BACKSLASH) - CC := tcc - .PHONY: turboc - endif - - ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++ - CONFIG_FILE := dos-wat.mk - SEP := $(BACKSLASH) - CC := wcc386 - .PHONY: watcom - endif - - ifneq ($(findstring borlandc16,$(MAKECMDGOALS)),) # Borland C/C++ 16-bit - CONFIG_FILE := dos-bcc.mk - SEP := $(BACKSLASH) - CC := bcc - .PHONY: borlandc16 - endif - - ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C/C++ 32-bit - CONFIG_FILE := dos-bcc.mk - SEP := $(BACKSLASH) - CC := bcc32 - .PHONY: borlandc - endif - - setup: dos_setup - - endif # test Dos - endif # test COMSPEC -endif # test PLATFORM - -# EOF diff --git a/subsys/win32k/freetype/builds/dos/dos-gcc.mk b/subsys/win32k/freetype/builds/dos/dos-gcc.mk deleted file mode 100644 index b9f55a2..0000000 --- a/subsys/win32k/freetype/builds/dos/dos-gcc.mk +++ /dev/null @@ -1,134 +0,0 @@ -# -# FreeType 2 configuration rules for the DJGPP compiler -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := rm -f -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/dos -PLATFORM := dos - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g -O6 -Wall -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := -ansi -pedantic - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like: - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $@ - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/freetype.mk b/subsys/win32k/freetype/builds/freetype.mk deleted file mode 100644 index 172678f..0000000 --- a/subsys/win32k/freetype/builds/freetype.mk +++ /dev/null @@ -1,279 +0,0 @@ -# -# FreeType 2 library sub-Makefile -# - - -# Copyright 1996-2000 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. - - -# DO NOT INVOKE THIS MAKEFILE DIRECTLY! IT IS MEANT TO BE INCLUDED BY -# OTHER MAKEFILES. - - -# The following variables (set by other Makefile components, in the -# environment, or on the command line) are used: -# -# BUILD The architecture dependent directory, -# e.g. `$(TOP)/builds/unix'. -# -# OBJ_DIR The directory in which object files are created. -# -# LIB_DIR The directory in which the library is created. -# -# INCLUDES A list of directories to be included additionally. -# Usually empty. -# -# CFLAGS Compilation flags. This overrides the default settings -# in the platform-specific configuration files. -# -# FTSYS_SRC If set, its value is used as the name of a replacement -# file for `src/base/ftsystem.c'. -# -# FTDEBUG_SRC If set, its value is used as the name of a replacement -# file for `src/base/ftdebug.c'. [For a normal build, this -# file does nothing.] -# -# FT_MODULE_LIST The file which contains the list of modules for the -# current build. Usually, this is automatically created by -# `modules.mk'. -# -# BASE_OBJ_S -# BASE_OBJ_M A list of base objects (for single object and multiple -# object builds, respectively). Set up in -# `src/base/rules.mk'. -# -# BASE_EXT_OBJ A list of base extension objects. Set up in -# `src/base/rules.mk'. -# -# DRV_OBJ_S -# DRV_OBJ_M A list of driver objects (for single object and multiple -# object builds, respectively). Set up cumulatively in -# `src//rules.mk'. -# -# CLEAN -# DISTCLEAN The sub-makefiles can append additional stuff to these two -# variables which is to be removed for the `clean' resp. -# `distclean' target. -# -# TOP, SEP, -# LIBRARY, CC, -# A, I, O, T Check `config.mk' for details. - - -# The targets `objects' and `library' are defined at the end of this -# Makefile after all other rules have been included. -# -.PHONY: single objects library - -# default target -- build single objects and library -# -single: objects library - -# `multi' target -- build multiple objects and library -# -multi: objects library - - -# The FreeType source directory, usually `./src'. -# -SRC := $(TOP)$(SEP)src - - -# The directory where the base layer components are placed, usually -# `./src/base'. -# -BASE_DIR := $(SRC)$(SEP)base - - -# A few short-cuts in order to avoid typing $(SEP) all the time for the -# directory separator. -# -# For example: $(SRC_) equals to `./src/' where `.' is $(TOP). -# -# -SRC_ := $(SRC)$(SEP) -BASE_ := $(BASE_DIR)$(SEP) -OBJ_ := $(OBJ_DIR)$(SEP) -LIB_ := $(LIB_DIR)$(SEP) -PUBLIC_ := $(TOP)$(SEP)include$(SEP)freetype$(SEP) -INTERNAL_ := $(PUBLIC_)internal$(SEP) -CONFIG_ := $(PUBLIC_)config$(SEP) - - -# The final name of the library file. -# -FT_LIBRARY := $(LIB_)$(LIBRARY).$A - - -# include paths -# -# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed -# in front of the include list. Porters are then able to -# put their own version of some of the FreeType components -# in the `freetype/builds/' directory, as these -# files will override the default sources. -# -INCLUDES := $(BUILD) $(TOP)$(SEP)include $(SRC) - -INCLUDE_FLAGS = $(INCLUDES:%=$I%) - - -# C flags used for the compilation of an object file. This must include at -# least the paths for the `base' and `builds/' directories; -# debug/optimization/warning flags + ansi compliance if needed. -# -FT_CFLAGS = $(CFLAGS) $(INCLUDE_FLAGS) -FT_CC = $(CC) $(FT_CFLAGS) -FT_COMPILE = $(CC) $(ANSIFLAGS) $(FT_CFLAGS) - - -# Include the `modules' rules file. -# -include $(TOP)/builds/modules.mk - - -# Initialize the list of objects. -# -OBJECTS_LIST := - - -# Define $(PUBLIC_H) as the list of all public header files located in -# `$(TOP)/include/freetype'. $(BASE_H) and $(CONFIG_H) are defined -# similarly. -# -# This is used to simplify the dependency rules -- if one of these files -# changes, the whole library is recompiled. -# -PUBLIC_H := $(wildcard $(PUBLIC_)*.h) -BASE_H := $(wildcard $(INTERNAL_)*.h) -CONFIG_H := $(wildcard $(CONFIG_)*.h) - -FREETYPE_H := $(PUBLIC_H) $(BASE_H) $(CONFIG_H) - - -# ftsystem component -# -ifndef FTSYS_SRC - FTSYS_SRC = $(BASE_)ftsystem.c -endif - -FTSYS_OBJ = $(OBJ_)ftsystem.$O - -OBJECTS_LIST += $(FTSYS_OBJ) - -$(FTSYS_OBJ): $(FTSYS_SRC) $(FREETYPE_H) - $(FT_COMPILE) $T$@ $< - - -# ftdebug component -# -ifndef FTDEBUG_SRC - FTDEBUG_SRC = $(BASE_)ftdebug.c -endif - -FTDEBUG_OBJ = $(OBJ_)ftdebug.$O - -OBJECTS_LIST += $(FTDEBUG_OBJ) - -$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(FREETYPE_H) - $(FT_COMPILE) $T$@ $< - - -# Include all rule files from FreeType components. -# -include $(wildcard $(SRC)/*/rules.mk) - - -# ftinit component -# -# The C source `ftinit.c' contains the FreeType initialization routines. -# It is able to automatically register one or more drivers when the API -# function FT_Init_FreeType() is called. -# -# The set of initial drivers is determined by the driver Makefiles -# includes above. Each driver Makefile updates the FTINIT_xxx lists -# which contain additional include paths and macros used to compile the -# single `ftinit.c' source. -# -FTINIT_SRC := $(BASE_)ftinit.c -FTINIT_OBJ := $(OBJ_)ftinit.$O - -OBJECTS_LIST += $(FTINIT_OBJ) - -$(FTINIT_OBJ): $(FTINIT_SRC) $(FREETYPE_H) $(FT_MODULE_LIST) - $(FT_COMPILE) $T$@ $< - - -# All FreeType library objects -# -# By default, we include the base layer extensions. These could be -# omitted on builds which do not want them. -# -OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) -OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) - - -# The target `multi' on the Make command line indicates that we want to -# compile each source file independently. -# -# Otherwise, each module/driver is compiled in a single object file through -# source file inclusion (see `src/base/ftbase.c' or -# `src/truetype/truetype.c' for examples). -# -BASE_OBJECTS := $(OBJECTS_LIST) - -ifneq ($(findstring multi,$(MAKECMDGOALS)),) - OBJECTS_LIST += $(OBJ_M) -else - OBJECTS_LIST += $(OBJ_S) -endif - -objects: $(OBJECTS_LIST) - -library: $(FT_LIBRARY) - -.c.$O: - $(FT_COMPILE) $T$@ $< - - -# Standard cleaning and distclean rules. These are not accepted -# on all systems though. -# -clean_freetype_std: - -$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S) $(CLEAN) - -distclean_freetype_std: clean_freetype_std - -$(DELETE) $(FT_LIBRARY) - -$(DELETE) *.orig *~ core *.core $(DISTCLEAN) - -# The Dos command shell does not support very long list of arguments, so -# we are stuck with wildcards. -# -clean_freetype_dos: - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(OBJ_))*.$O $(CLEAN) 2> nul - -distclean_freetype_dos: clean_freetype_dos - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_LIBRARY)) $(DISTCLEAN) 2> nul - -# Remove configuration file (used for distclean). -# -remove_config_mk: - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(CONFIG_MK)) - - -# The `config.mk' file must define `clean_freetype' and -# `distclean_freetype'. Implementations may use to relay these to either -# the `std' or `dos' versions from above, or simply provide their own -# implementation. -# -clean: clean_freetype -distclean: distclean_freetype remove_config_mk - -# EOF diff --git a/subsys/win32k/freetype/builds/mac/ftlib.prj b/subsys/win32k/freetype/builds/mac/ftlib.prj deleted file mode 100644 index d624c2502ff104ae5014f36690ca32123c42def5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 603 zcmd_mI}QO+6vpv$$9TWrG$^SQ647f^LZu@zrXZ3VH*A1bY(irb5~U4@MX2?@F`req z#r^+gZgq~M^;$#%BC08}S0aa&h<(SujZ{e8~>w@uH`AiYCF^a%~q7c@d&(J1{yWAq!1`&Qn2g07)Sx{IdhA)2PAXolXP mS^9|P=rfw9Z)kyjphfzHmV8^@d}X?hR_Gq;?FGjg - -DISCLAIMER: this subdirectory is *not* being maintained by the -FreeType team, but by Just van Rossum. It's being released under -the same terms as FreeType (see LICENSE.TXT). diff --git a/subsys/win32k/freetype/builds/modules.mk b/subsys/win32k/freetype/builds/modules.mk deleted file mode 100644 index 110ee81..0000000 --- a/subsys/win32k/freetype/builds/modules.mk +++ /dev/null @@ -1,75 +0,0 @@ -# -# FreeType 2 modules sub-Makefile -# - -# Copyright 1996-2000 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. - - -# DO NOT INVOKE THIS MAKEFILE DIRECTLY! IT IS MEANT TO BE INCLUDED BY -# OTHER MAKEFILES. - - -# This file is in charge of handling the generation of the modules list -# file. - -.PHONY: make_module_list clean_module_list remake_module_list - -# MODULE_LIST, as its name suggests, indicates where the modules list -# resides. For now, it is in `include/freetype/config/ftmodule.h'. -# -ifndef FT_MODULE_LIST - FT_MODULE_LIST := $(TOP)$(SEP)include$(SEP)freetype$(SEP)config$(SEP)ftmodule.h -endif - -# To build the modules list, we invoke the `make_module_list' target. -# -# This rule is commented out by default since FreeType comes already with -# a ftmodule.h file. -# -#$(FT_MODULE_LIST): make_module_list - -# Before the modules list file can be generated, we must remove the file in -# order to `clean' the list. -# -clean_module_list: - @-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_MODULE_LIST)) - @-echo Regenerating the modules list in $(FT_MODULE_LIST)... - -make_module_list: clean_module_list - @echo done. - - -# Trailing spaces are protected with a `#' sign to avoid accidental -# removing. -# -ifneq ($(findstring $(PLATFORM),dos win32 win16 os2),) - OPEN_MODULE := @echo # - CLOSE_MODULE := >> $(subst $(SEP),$(HOSTSEP),$(FT_MODULE_LIST)) -else - OPEN_MODULE := @echo " - CLOSE_MODULE := " >> $(FT_MODULE_LIST) -endif - -# $(OPEN_DRIVER) & $(CLOSE_DRIVER) are used to specify a given font driver -# in the `module.mk' rules file. -# -OPEN_DRIVER := $(OPEN_MODULE)FT_USE_MODULE( -CLOSE_DRIVER := )$(CLOSE_MODULE) - -ECHO_DRIVER := @echo "* module: # -ECHO_DRIVER_DESC := ( -ECHO_DRIVER_DONE := )" - -# Each `module.mk' in the `src' sub-dirs is used to add one rule to the -# target `make_module_list'. -# -include $(wildcard $(TOP)/src/*/module.mk) - -# EOF diff --git a/subsys/win32k/freetype/builds/os2/detect.mk b/subsys/win32k/freetype/builds/os2/detect.mk deleted file mode 100644 index ed0f124..0000000 --- a/subsys/win32k/freetype/builds/os2/detect.mk +++ /dev/null @@ -1,62 +0,0 @@ -# -# FreeType 2 configuration file to detect an OS/2 host platform. -# - - -# Copyright 1996-2000 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. - - -ifeq ($(PLATFORM),ansi) - - ifdef OS2_SHELL - - PLATFORM := os2 - COPY := copy - DELETE := del - - CONFIG_FILE := os2-gcc.mk # gcc-emx by default - SEP := / - - # additionally, we provide hooks for various other compilers - # - ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++ - CONFIG_FILE := os2-icc.mk - SEP := $(BACKSLASH) - CC := icc - .PHONY: visualage - endif - - ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++ - CONFIG_FILE := os2-wat.mk - SEP := $(BACKSLASH) - CC := wcc386 - .PHONY: watcom - endif - - ifneq ($(findstring borlandc,$(MAKECMDGOALS)),) # Borland C++ 32-bit - CONFIG_FILE := os2-bcc.mk - SEP := $(BACKSLASH) - CC := bcc32 - .PHONY: borlandc - endif - - ifneq ($(findstring devel,$(MAKECMDGOALS)),) # development target - CONFIG_FILE := os2-dev.mk - CC := gcc - SEP := / - devel: setup - endif - - setup: dos_setup - - endif # test OS2_SHELL -endif # test PLATFORM - -#EOF diff --git a/subsys/win32k/freetype/builds/os2/os2-dev.mk b/subsys/win32k/freetype/builds/os2/os2-dev.mk deleted file mode 100644 index 93939d2..0000000 --- a/subsys/win32k/freetype/builds/os2/os2-dev.mk +++ /dev/null @@ -1,137 +0,0 @@ -# -# FreeType 2 configuration rules for OS/2 + gcc -# -# Development version without optimizations. -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/os2 -PLATFORM := os2 -CC := gcc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g -O0 -Wall -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := -ansi -pedantic - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_LIBRARY)) 2> nul - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/os2/os2-gcc.mk b/subsys/win32k/freetype/builds/os2/os2-gcc.mk deleted file mode 100644 index 14992e6..0000000 --- a/subsys/win32k/freetype/builds/os2/os2-gcc.mk +++ /dev/null @@ -1,135 +0,0 @@ -# -# FreeType 2 configuration rules for OS/2 + gcc -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/os2 -PLATFORM := os2 -CC := gcc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g -O6 -Wall -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := -ansi -pedantic - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_LIBRARY)) 2> nul - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/unix/aclocal.m4 b/subsys/win32k/freetype/builds/unix/aclocal.m4 deleted file mode 100644 index 47abe43..0000000 --- a/subsys/win32k/freetype/builds/unix/aclocal.m4 +++ /dev/null @@ -1,430 +0,0 @@ -## 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 $lt_target \ -|| 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 - -case "$target" in -NONE) lt_target="$host" ;; -*) lt_target="$target" ;; -esac - -# 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 "$lt_target" 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_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_CHECK_LIBM - check for math library -AC_DEFUN(AC_CHECK_LIBM, -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case "$lt_target" 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/subsys/win32k/freetype/builds/unix/config.guess b/subsys/win32k/freetype/builds/unix/config.guess deleted file mode 100644 index 4994964..0000000 --- a/subsys/win32k/freetype/builds/unix/config.guess +++ /dev/null @@ -1,1273 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 -# Free Software Foundation, Inc. - -version='2000-06-13' - -# 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 . -# Please send patches to . -# -# 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). -# - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of this system. - -Operation modes: - -h, --help print this help, then exit - -V, --version print version number, then exit" - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case "$1" in - --version | --vers* | -V ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - exec >&2 - echo "$me: invalid option $1" - echo "$help" - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -# 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 - *:NetBSD:*:*) - # Netbsd (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-cbm ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - *) machine=${UNAME_MACHINE}-unknown ;; - esac - # The Operating System including object format. - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - 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 - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 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: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 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - 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*: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*:OpenBSD:*:*) - echo m68k-unknown-openbsd${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 ;; - 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 -#include /* for printf() prototype */ - 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 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${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 BSD 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 - - #define _HPUX_SOURCE - #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 - (CCOPTS= $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} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - 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 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/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:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`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 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - *:Linux:*:*) - - # 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 - *ia64) - echo "${UNAME_MACHINE}-unknown-linux" - exit 0 - ;; - i?86linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 - ;; - elf_i?86) - echo "${UNAME_MACHINE}-pc-linux" - 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 - ;; - elf32arm*) - echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" - exit 0 - ;; - armelf_linux*) - echo "${UNAME_MACHINE}-unknown-linux-gnu" - exit 0 - ;; - m68klinux) - echo "${UNAME_MACHINE}-unknown-linux-gnuaout" - exit 0 - ;; - elf32ppc | elf32ppclinux) - # 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 - ;; - shelf_linux) - echo "${UNAME_MACHINE}-unknown-linux-gnu" - exit 0 - ;; - esac - - if test "${UNAME_MACHINE}" = "alpha" ; then - cat <$dummy.s - .data - \$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main - main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - LIBC="" - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 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 < /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __MIPSEB__ - printf ("%s-unknown-linux-gnu\n", argv[1]); -#endif -#ifdef __MIPSEL__ - printf ("%sel-unknown-linux-gnu\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 - elif test "${UNAME_MACHINE}" = "s390"; then - echo s390-ibm-linux && exit 0 - 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 -#include /* for printf() prototype */ - 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.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i?86:*:5:7*) - # Fixed at (any) Pentium or better - UNAME_MACHINE=i586 - if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then - echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} - fi - 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 ;; - i?86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # 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 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - if test "${UNAME_MACHINE}" = "x86pc"; then - UNAME_MACHINE=pc - fi - echo `uname -p`-${UNAME_MACHINE}-nto-qnx - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-W:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${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 - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess version = $version - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "version='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/subsys/win32k/freetype/builds/unix/config.sub b/subsys/win32k/freetype/builds/unix/config.sub deleted file mode 100644 index 6e5f1a8..0000000 --- a/subsys/win32k/freetype/builds/unix/config.sub +++ /dev/null @@ -1,1319 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 -# Free Software Foundation, Inc. - -version='2000-06-20' - -# 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. - -# Please send patches to . -# -# 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. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -V, --version print version number, then exit" - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case "$1" in - --version | --vers* | -V ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - exec >&2 - echo "$me: invalid option $1" - echo "$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -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 - nto-qnx* | 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 | -axis) - 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 - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -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 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ - | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ - | 580 | i960 | h8300 \ - | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ - | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ - | hppa64 \ - | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ - | alphaev6[78] \ - | we32k | ns16k | clipper | i370 | sh | sh[34] \ - | powerpc | powerpcle \ - | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ - | mips64orion | mips64orionel | mipstx39 | mipstx39el \ - | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ - | mips64vr5000 | miprs64vr5000el | mcore \ - | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ - | thumb | d10v | fr30 | avr) - basic_machine=$basic_machine-unknown - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) - ;; - - # 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[234567]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. - # FIXME: clean up the formatting here. - vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | 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-* \ - | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ - | hppa2.0n-* | hppa64-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ - | alphaev6[78]-* \ - | 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-* | mcore-* \ - | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ - | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ - | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ - | bs2000-* | tic54x-* | c54x-*) - ;; - # 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 - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - 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 - ;; -# 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[0-9]* | *MiNT | *MiNT[0-9]*) - 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 - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - msdos) - basic_machine=i386-unknown - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - 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 - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - 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 | athlon) - 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-* | athlon-*) - 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 - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=t3e-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - 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 - ;; - sh3 | sh4) - base_machine=sh-unknown - ;; - 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* | -darwin* | -opened* \ - | -openstep* | -oskit*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i[34567]86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -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|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -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 - ;; - -nsk) - os=-nsk - ;; - # 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*-rebel) - 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* | -opened*) - 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 -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "version='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/subsys/win32k/freetype/builds/unix/configure b/subsys/win32k/freetype/builds/unix/configure deleted file mode 100644 index 78e572b..0000000 --- a/subsys/win32k/freetype/builds/unix/configure +++ /dev/null @@ -1,2514 +0,0 @@ -#! /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-shared[=PKGS] build shared libraries [default=yes]" -ac_help="$ac_help - --enable-static[=PKGS] build static 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)" - -# 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=ftconfig.in - -# 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 - - - - - -version_info='6:0:0' - - -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:588: 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:609: 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:627: 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:653: 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:683: 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:734: 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:766: 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 777 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:782: \"$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:808: 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:813: 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:841: 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:873: 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:894: \"$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:911: \"$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:928: \"$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" - XX_ANSIFLAGS="-pedantic -ansi" -else - case "$host" in - *-dec-osf*) - XX_CFLAGS="-std1 -O2 -g3" - XX_ANSIFLAGS= - ;; - *) - XX_CFLAGS= - XX_ANSIFLAGS= - ;; - 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:974: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RMF'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RMF"; then - ac_cv_prog_RMF="$RMF" # 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_RMF="rm -f" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -RMF="$ac_cv_prog_RMF" -if test -n "$RMF"; then - echo "$ac_t""$RMF" 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:1003: 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: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' - - -echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1095: 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:1108: \"$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:1175: \"$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 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:1202: 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:1212: \"$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:1240: 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:1294: \"$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:1315: 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:1334: \"$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:1354: 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:1373: \"$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:1398: 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:1408: \"$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:1437: 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:1465: \"$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:1490: 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:1638: \"$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 - FTSYS_SRC='$(BASE_)ftsystem.c' -else - FTSYS_SRC='$(BUILD)/ftsystem.c' -fi - - -for ac_func in memcpy memmove -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1670: 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:1698: \"$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 - - -# 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-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=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 - -# 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:1795: 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 - -# 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:1834: 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:1858: checking for GNU ld" >&5 -else - echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1861: 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:1896: 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:1912: 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:1948: 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 - - -case "$target" in -NONE) lt_target="$host" ;; -*) lt_target="$target" ;; -esac - -# 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 "$lt_target" in -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 1997 "configure"' > conftest.$ac_ext - if { (eval echo configure:1998: \"$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:2019: 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 $lt_target \ -|| { 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 - - -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 "unix.mk:unix.in ftconfig.h:ftconfig.in" | 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%@version_info@%$version_info%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%@XX_ANSIFLAGS@%$XX_ANSIFLAGS%g -s%@RMF@%$RMF%g -s%@RMDIR@%$RMDIR%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@FTSYS_SRC@%$FTSYS_SRC%g -s%@RANLIB@%$RANLIB%g -s%@LN_S@%$LN_S%g -s%@LIBTOOL@%$LIBTOOL%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 - -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/subsys/win32k/freetype/builds/unix/configure.in b/subsys/win32k/freetype/builds/unix/configure.in deleted file mode 100644 index cfaf1b7..0000000 --- a/subsys/win32k/freetype/builds/unix/configure.in +++ /dev/null @@ -1,74 +0,0 @@ -dnl This file is part of the FreeType project. -dnl -dnl Process this file with autoconf to produce a configure script. -dnl - -AC_INIT(ftconfig.in) - -dnl Configuration file -- stay in 8.3 limit -AC_CONFIG_HEADER(ftconfig.h:ftconfig.in) - -version_info='6:0:0' -AC_SUBST(version_info) - -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" - XX_ANSIFLAGS="-pedantic -ansi" -else - case "$host" in - *-dec-osf*) - XX_CFLAGS="-std1 -O2 -g3" - XX_ANSIFLAGS= - ;; - *) - XX_CFLAGS= - XX_ANSIFLAGS= - ;; - esac -fi -AC_SUBST(XX_CFLAGS) -AC_SUBST(XX_ANSIFLAGS) - -AC_CHECK_PROG(RMF, rm, rm -f) -AC_CHECK_PROG(RMDIR, rmdir, rmdir) -AC_PROG_INSTALL - -dnl checks for header files -AC_HEADER_STDC -AC_CHECK_HEADERS(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 - FTSYS_SRC='$(BASE_)ftsystem.c' -else - FTSYS_SRC='$(BUILD)/ftsystem.c' -fi -AC_SUBST(FTSYS_SRC) - -AC_CHECK_FUNCS(memcpy memmove) - -AM_PROG_LIBTOOL - -dnl create the Unix-specific sub-Makefile `builds/unix/unix.mk' that will be -dnl used by the build system -dnl -AC_OUTPUT(unix.mk:unix.in) - - -dnl end of configure.in diff --git a/subsys/win32k/freetype/builds/unix/detect.mk b/subsys/win32k/freetype/builds/unix/detect.mk deleted file mode 100644 index dec1baa..0000000 --- a/subsys/win32k/freetype/builds/unix/detect.mk +++ /dev/null @@ -1,59 +0,0 @@ -# -# FreeType 2 configuration file to detect a UNIX host platform. -# - - -# Copyright 1996-2000 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. - - -ifeq ($(PLATFORM),ansi) - - has_init := $(strip $(wildcard /sbin/init)) - ifneq ($(has_init),) - - PLATFORM := unix - COPY := cp - DELETE := rm -f - - # If a Unix platform is detected, the configure script is called and - # `unix.mk' is created. - # - # Arguments to `configure' should be in the CFG variable. Example: - # - # make CFG="--prefix=/usr --disable-static" - # - # If you need to set CFLAGS or LDFLAGS, do it here also. - # - # Feel free to add support for other platform specific compilers in this - # directory (e.g. solaris.mk + changes here to detect the platform). - # - CONFIG_FILE := unix.mk - setup: unix.mk - unix: setup - - # If `devel' is the requested target, use `-g -O0' as the default value - # for CFLAGS if CFLAGS isn't set. - # - ifneq ($(findstring devel,$(MAKECMDGOALS)),) - ifndef CFLAGS - USE_CFLAGS := CFLAGS="-g -O0" - endif - devel: setup - endif - - setup: std_setup - - unix.mk: builds/unix/unix.in - cd builds/unix; $(USE_CFLAGS) ./configure $(CFG) - - endif # test Unix -endif # test PLATFORM - -# EOF diff --git a/subsys/win32k/freetype/builds/unix/ftconfig.in b/subsys/win32k/freetype/builds/unix/ftconfig.in deleted file mode 100644 index a24b679..0000000 --- a/subsys/win32k/freetype/builds/unix/ftconfig.in +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftconfig.in */ -/* */ -/* UNIX-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2000 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 header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `freetype/builds/', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ - /* */ - /*************************************************************************/ - - -#ifndef FTCONFIG_H -#define FTCONFIG_H - - - /* Include the header file containing all developer build options */ -#include - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - -#define HAVE_UNISTD_H 0 -#define HAVE_FCNTL_H 0 - -#define SIZEOF_INT 2 -#define SIZEOF_LONG 2 - - -#define FT_SIZEOF_INT SIZEOF_INT -#define FT_SIZEOF_LONG SIZEOF_LONG - - - /* Preferred alignment of data */ -#define FT_ALIGNMENT 8 - - - /* UNUSED is a macro used to indicate that a given parameter is not used */ - /* -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* IntN types */ - /* */ - /* Used to guarantee the size of some specific integers. */ - /* */ - typedef signed short FT_Int16; - typedef unsigned short FT_UInt16; - -#if FT_SIZEOF_INT == 4 - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == 4 - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - -#if FT_SIZEOF_LONG == 8 - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long - -#else - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ - /* `ftoption.h'. */ - /* */ - /* Note that this will produce many -ansi warnings during library */ - /* compilation, and that in many cases, the generated code will be */ - /* neither smaller nor faster! */ - /* */ -#ifdef FTCALC_USE_LONG_LONG - -#define FT_LONG64 -#define FT_INT64 long long - -#endif /* FTCALC_USE_LONG_LONG */ -#endif /* FT_SIZEOF_LONG == 8 */ - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT -#define LOCAL_DEF static -#define LOCAL_FUNC static -#else -#define LOCAL_DEF extern -#define LOCAL_FUNC /* nothing */ -#endif - -#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT -#define BASE_DEF( x ) static x -#define BASE_FUNC( x ) static x -#else -#define BASE_DEF( x ) extern x -#define BASE_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_DEF -#define FT_EXPORT_DEF( x ) extern x -#endif - -#ifndef FT_EXPORT_FUNC -#define FT_EXPORT_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* FTCONFIG_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/builds/unix/ftsystem.c b/subsys/win32k/freetype/builds/unix/ftsystem.c deleted file mode 100644 index 9ecd95c..0000000 --- a/subsys/win32k/freetype/builds/unix/ftsystem.c +++ /dev/null @@ -1,306 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* Unix-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2000 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 -#include - - - /* memory-mapping includes and definitions */ -#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 -#include -#include - - - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* ft_alloc */ - /* */ - /* */ - /* The memory allocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* size :: The requested size in bytes. */ - /* */ - /* */ - /* block :: The address of newly allocated block. */ - /* */ - static - void* ft_alloc( FT_Memory memory, - long size ) - { - FT_UNUSED( memory ); - - return malloc( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_realloc */ - /* */ - /* */ - /* The memory reallocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* */ - /* The address of the reallocated memory block. */ - /* */ - static - void* ft_realloc( FT_Memory memory, - long cur_size, - long new_size, - void* block ) - { - FT_UNUSED( memory ); - FT_UNUSED( cur_size ); - - return realloc( block, new_size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_free */ - /* */ - /* */ - /* The memory release function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ - static - void ft_free( FT_Memory memory, - void* block ) - { - FT_UNUSED( memory ); - - free( block ); - } - - - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_io - - /* We use the macro STREAM_FILE for convenience to extract the */ - /* system-specific stream handle from a given FreeType stream object */ -#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) - - - /*************************************************************************/ - /* */ - /* */ - /* ft_close_stream */ - /* */ - /* */ - /* The function to close a stream. */ - /* */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - static - void ft_close_stream( FT_Stream stream ) - { - munmap ( stream->descriptor.pointer, stream->size ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Stream */ - /* */ - /* */ - /* Creates a new stream object. */ - /* */ - /* */ - /* filepathname :: The name of the stream (usually a file) to be */ - /* opened. */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Stream( const char* filepathname, - FT_Stream stream ) - { - int file; - struct stat stat_buf; - - - if ( !stream ) - return FT_Err_Invalid_Stream_Handle; - - /* open the file */ - file = open( filepathname, O_RDONLY ); - if ( file < 0 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); - return FT_Err_Cannot_Open_Resource; - } - - if ( fstat( file, &stat_buf ) < 0 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not `fstat' file `%s'\n", filepathname )); - goto Fail_Map; - } - - stream->size = stat_buf.st_size; - stream->pos = 0; - stream->base = mmap( NULL, - stream->size, - PROT_READ, - MAP_FILE | MAP_PRIVATE, - file, - 0 ); - - if ( (long)stream->base == -1 ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not `mmap' file `%s'\n", filepathname )); - goto Fail_Map; - } - - close( file ); - - stream->descriptor.pointer = stream->base; - stream->pathname.pointer = (char*)filepathname; - - stream->close = ft_close_stream; - stream->read = 0; - - FT_TRACE1(( "FT_New_Stream:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", - filepathname, stream->size )); - - return FT_Err_Ok; - - Fail_Map: - close( file ); - - stream->base = NULL; - stream->size = 0; - stream->pos = 0; - - return FT_Err_Cannot_Open_Stream; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory */ - /* */ - /* */ - /* Creates a new memory object. */ - /* */ - /* */ - /* A pointer to the new memory object. 0 in case of error. */ - /* */ - FT_EXPORT_FUNC( FT_Memory ) FT_New_Memory( void ) - { - FT_Memory memory; - - - memory = (FT_Memory)malloc( sizeof ( *memory ) ); - if ( memory ) - { - memory->user = 0; - memory->alloc = ft_alloc; - memory->realloc = ft_realloc; - memory->free = ft_free; - } - - return memory; - } - - -/* END */ diff --git a/subsys/win32k/freetype/builds/unix/install-sh b/subsys/win32k/freetype/builds/unix/install-sh deleted file mode 100644 index ebc6691..0000000 --- a/subsys/win32k/freetype/builds/unix/install-sh +++ /dev/null @@ -1,250 +0,0 @@ -#! /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/subsys/win32k/freetype/builds/unix/ltconfig b/subsys/win32k/freetype/builds/unix/ltconfig deleted file mode 100644 index a01334f..0000000 --- a/subsys/win32k/freetype/builds/unix/ltconfig +++ /dev/null @@ -1,3078 +0,0 @@ -#! /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 "X${CDPATH+set}" = Xset; 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.4 -TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)" -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $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 "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi -if test "X${LANG+set}" = Xset; 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 "X${COLLECT_NAMES+set}" != Xset; 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 echo __ELF__ | $CC -E - | grep __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* | sysv5*) - 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= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - 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*) - 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=: - ;; - - osf4* | osf5*) # As osf3* with the addition of the -msym flag - if test "$with_gcc" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${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 -msym -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' - ;; - - sysv5*) - 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= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - 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 -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - unixware7*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - 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:1636: \"$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:1639: 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:1691: \"$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 - 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 $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" - export_dynamic_flag_spec=-rdynamic - # 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 - shlibpath_var=LD_LIBRARY_PATH - case "$host_os" in - freebsd2* | freebsd3.[01]* | freebsdelf3.[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 - ;; - 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:2212: 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:2252: 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. */ -#ifdef __cplusplus -extern "C" -#endif -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:2282: \"$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:2299: 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:2339: 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. */ -#ifdef __cplusplus -extern "C" -#endif -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:2369: \"$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:2387: 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:2452: 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 >/dev/null 2>conftest.out" -{ (eval echo $progname:2462: \"$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:2490: 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:2544: \"$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:2563: 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:2617: \"$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. -# 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. - -# 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 "X\${CDPATH+set}" = Xset; 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 "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # Append the ltmain.sh script. - sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - - 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/subsys/win32k/freetype/builds/unix/ltmain.sh b/subsys/win32k/freetype/builds/unix/ltmain.sh deleted file mode 100644 index ab65054..0000000 --- a/subsys/win32k/freetype/builds/unix/ltmain.sh +++ /dev/null @@ -1,4012 +0,0 @@ -# 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 $srcfile $pic_flag -DPIC" - 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 - - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` - libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - # Now arrange that obj and lo_libobj become the same file - $show "(cd $xdir && $LN_S $baseobj $libobj)" - if $run eval '(cd $xdir && $LN_S $baseobj $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" - 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) in case we are running --disable-static - for obj in $libobjs; do - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - if test ! -f $xdir/$oldobj; then - $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" - $run eval '(cd $xdir && ${LN_S} $baseobj $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 - xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$libobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - $show "(cd $xdir && $LN_S $oldobj $baseobj)" - $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || 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*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $CC -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' - 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 in case 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 - xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$oldobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` - obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - $show "(cd $xdir && ${LN_S} $obj $baseobj)" - $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || 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 - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # 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. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $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/subsys/win32k/freetype/builds/unix/mkinstalldirs b/subsys/win32k/freetype/builds/unix/mkinstalldirs deleted file mode 100644 index d0fd194..0000000 --- a/subsys/win32k/freetype/builds/unix/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id$ - -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/subsys/win32k/freetype/builds/unix/unix.in b/subsys/win32k/freetype/builds/unix/unix.in deleted file mode 100644 index 9aeea24..0000000 --- a/subsys/win32k/freetype/builds/unix/unix.in +++ /dev/null @@ -1,216 +0,0 @@ -# -# FreeType 2 configuration rules templates for Unix + configure -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := @RMF@ -DELDIR := @RMDIR@ -SEP := / -HOSTSEP := $(SEP) -BUILD := $(TOP)/builds/unix -PLATFORM := unix -CC := @CC@ - -INSTALL := @INSTALL@ -INSTALL_DATA := @INSTALL_DATA@ -MKINSTALLDIRS := $(BUILD)/mkinstalldirs - -LIBTOOL := $(BUILD)/libtool - - -# don't use `:=' here since the path stuff will be included after this file -# -FTSYS_SRC = @FTSYS_SRC@ - -DISTCLEAN += $(BUILD)/config.cache \ - $(BUILD)/config.log \ - $(BUILD)/config.status \ - $(BUILD)/unix.mk \ - $(BUILD)/ftconfig.h \ - $(LIBTOOL) - - -# Standard installation variables. -# -prefix := @prefix@ -exec_prefix := @exec_prefix@ -libdir := @libdir@ -bindir := @bindir@ -includedir := @includedir@ - -version_info := @version_info@ - - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f $TOP/Makefile setup [options] -# make -f $TOP/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := lo -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := la -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -CFLAGS := -c @XX_CFLAGS@ @CFLAGS@ - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := @XX_ANSIFLAGS@ - -# C compiler to use -- we use libtool! -# -# -CCraw := $(CC) -CC := $(LIBTOOL) --mode=compile $(CCraw) - -# Linker flags. -# -LDFLAGS := @LDFLAGS@ - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - - # The cleanup targets. - # - clean_freetype: clean_freetype_unix - distclean_freetype: distclean_freetype_unix - - - # Unix installation and deinstallation targets. - install: $(FT_LIBRARY) - $(MKINSTALLDIRS) $(libdir) \ - $(includedir)/freetype/config \ - $(includedir)/freetype/internal - $(LIBTOOL) --mode=install $(INSTALL) $(FT_LIBRARY) $(libdir) - -for P in $(PUBLIC_H) ; do \ - $(INSTALL_DATA) $$P $(includedir)/freetype ; \ - done - -for P in $(BASE_H) ; do \ - $(INSTALL_DATA) $$P $(includedir)/freetype/internal ; \ - done - -for P in $(CONFIG_H) ; do \ - $(INSTALL_DATA) $$P $(includedir)/freetype/config ; \ - done - - uninstall: - -$(LIBTOOL) --mode=uninstall $(RM) $(libdir)/$(LIBRARY).$A - -$(DELETE) $(includedir)/freetype/config/* - -$(DELDIR) $(includedir)/freetype/config - -$(DELETE) $(includedir)/freetype/internal/* - -$(DELDIR) $(includedir)/freetype/internal - -$(DELETE) $(includedir)/freetype/* - -$(DELDIR) $(includedir)/freetype - - - # Unix cleaning and distclean rules. - # - clean_freetype_unix: - -$(DELETE) $(BASE_OBJECTS) $(OBJ_M) $(OBJ_S) - -$(DELETE) $(subst $O,$(SO),$(BASE_OBJECTS) $(OBJ_M) $(OBJ_S)) \ - $(CLEAN) - - distclean_freetype_unix: clean_freetype_unix - -$(DELETE) $(FT_LIBRARY) - -$(DELETE) $(OBJ_DIR)/.libs/* - -$(DELDIR) $(OBJ_DIR)/.libs - -$(DELETE) *.orig *~ core *.core $(DISTCLEAN) - - - # Librarian to use to build the library - # - FT_LIBRARIAN := $(LIBTOOL) --mode=link $(CCraw) - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - $(FT_LIBRARIAN) -o $@ $(OBJECTS_LIST) \ - -rpath $(libdir) -version-info $(version_info) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/detect.mk b/subsys/win32k/freetype/builds/win32/detect.mk deleted file mode 100644 index c2bf8cc..0000000 --- a/subsys/win32k/freetype/builds/win32/detect.mk +++ /dev/null @@ -1,90 +0,0 @@ -# -# FreeType 2 configuration file to detect a Win32 host platform. -# - - -# Copyright 1996-2000 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. - - -ifeq ($(PLATFORM),ansi) - - # Detecting Windows NT is easy, as the OS variable must be defined and - # contains `Windows_NT'. Untested with Windows 2K, but I guess it should - # work... - # - ifeq ($(OS),Windows_NT) - is_windows := 1 - - # We test for the COMSPEC environment variable, then run the `ver' - # command-line program to see if its output contains the word `Windows'. - # - # If this is true, we are running a win32 platform (or an emulation). - # - else - ifdef COMSPEC - is_windows := $(findstring Windows,$(strip $(shell ver))) - endif - endif # test NT - - ifdef is_windows - - PLATFORM := win32 - DELETE := del - COPY := copy - - CONFIG_FILE := w32-gcc.mk # gcc Makefile by default - SEP := / - ifeq ($(firstword $(CC)),cc) - CC := gcc - endif - - # additionally, we provide hooks for various other compilers - # - ifneq ($(findstring visualc,$(MAKECMDGOALS)),) # Visual C/C++ - CONFIG_FILE := w32-vcc.mk - SEP := $(BACKSLASH) - CC := cl - visualc: setup - endif - - ifneq ($(findstring watcom,$(MAKECMDGOALS)),) # Watcom C/C++ - CONFIG_FILE := w32-wat.mk - SEP := $(BACKSLASH) - CC := wcc386 - watcom: setup - endif - - ifneq ($(findstring visualage,$(MAKECMDGOALS)),) # Visual Age C++ - CONFIG_FILE := w32-icc.mk - SEP := $(BACKSLASH) - CC := icc - visualage: setup - endif - - ifneq ($(findstring lcc,$(MAKECMDGOALS)),) # LCC-Win32 - CONFIG_FILE := w32-lcc.mk - SEP := $(BACKSLASH) - CC := lcc - lcc: setup - endif - - ifneq ($(findstring devel,$(MAKECMDGOALS)),) # development target - CONFIG_FILE := w32-dev.mk - CC := gcc - SEP := / - devel: setup - endif - - setup: dos_setup - - endif # test is_windows -endif # test PLATFORM - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/w32-dev.mk b/subsys/win32k/freetype/builds/win32/w32-dev.mk deleted file mode 100644 index 8eea55a..0000000 --- a/subsys/win32k/freetype/builds/win32/w32-dev.mk +++ /dev/null @@ -1,140 +0,0 @@ -# -# FreeType 2 Configuration rules for Win32 + GCC -# -# Development version without optimizations. -# - - -# Copyright 1996-2000 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 version requires that GNU Make is invoked from the Windows -# Shell (_not_ Cygwin BASH)! -# - -ifndef TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/win32 -PLATFORM := win32 -CC := gcc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g -O0 -Wall -W -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := -ansi -pedantic - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_LIBRARY)) 2> nul - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/w32-gcc.mk b/subsys/win32k/freetype/builds/win32/w32-gcc.mk deleted file mode 100644 index 3501a79..0000000 --- a/subsys/win32k/freetype/builds/win32/w32-gcc.mk +++ /dev/null @@ -1,138 +0,0 @@ -# -# FreeType 2 Configuration rules for Win32 + GCC -# - - -# Copyright 1996-2000 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 version requires that GNU Make is invoked from the Windows -# Shell (_not_ Cygwin BASH)! -# - -ifndef TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/win32 -PLATFORM := win32 -CC := gcc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := o -SO := o - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := a -SA := a - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := libfreetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -l - - -# Target flag. -# -T := -o # Don't remove this comment line! We need the space after `-o'. - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g -O6 -Wall -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := -ansi -pedantic - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # Librarian to use to build the static library - # - FT_LIBRARIAN := $(AR) -r - - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - -$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_LIBRARY)) 2> nul - $(FT_LIBRARIAN) $@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/w32-icc.mk b/subsys/win32k/freetype/builds/win32/w32-icc.mk deleted file mode 100644 index 504579e..0000000 --- a/subsys/win32k/freetype/builds/win32/w32-icc.mk +++ /dev/null @@ -1,122 +0,0 @@ -# -# FreeType 2 Configuration rules for Win32 + IBM Visual Age C++ -# - - -# Copyright 1996-2000 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. -# - -DELETE := del -SEP := $(strip \ ) -HOSTSEP := $(strip \ ) -BUILD := $(TOP)$(SEP)config$(SEP)win32 -PLATFORM := win32 -CC := icc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := obj -SO := obj - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := lib -SA := lib - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := freetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := /I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := /D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := /Fl - - -# Target flag. -# -T := /Fo - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -ifndef CFLAGS - CFLAGS := /Q- /Gd+ /O2 /G5 /W3 /C -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSI_FLAGS := /Sa - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - lib /nologo /out:$@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/w32-lcc.mk b/subsys/win32k/freetype/builds/win32/w32-lcc.mk deleted file mode 100644 index 476de14..0000000 --- a/subsys/win32k/freetype/builds/win32/w32-lcc.mk +++ /dev/null @@ -1,130 +0,0 @@ -# -# FreeType 2 Configuration rules for Win32 + LCC -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/win32 -PLATFORM := win32 -CC := lcc - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := obj -SO := obj - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := lib -SA := lib - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := freetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := -I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := -D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := -Fl - - -# Target flag. -# -T := -Fo - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := -c -g2 -O -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - lcclib /out:$(subst $(SEP),\\,$@) \ - $(subst $(SEP),\\,$(OBJECTS_LIST)) - -endif - -# EOF diff --git a/subsys/win32k/freetype/builds/win32/w32-vcc.mk b/subsys/win32k/freetype/builds/win32/w32-vcc.mk deleted file mode 100644 index 955f44a..0000000 --- a/subsys/win32k/freetype/builds/win32/w32-vcc.mk +++ /dev/null @@ -1,129 +0,0 @@ -# -# FreeType 2 Configuration rules for Win32 + Visual C/C++ -# - - -# Copyright 1996-2000 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 TOP - TOP := . -endif - -DELETE := del -SEP := / -HOSTSEP := $(strip \ ) -BUILD := $(TOP)/builds/win32 -PLATFORM := win32 -CC := cl - -# The directory where all object files are placed. -# -# Note that this is not $(TOP)/obj! -# This lets you build the library in your own directory with something like -# -# set TOP=.../path/to/freetype2/top/dir... -# mkdir obj -# make -f %TOP%/Makefile setup [options] -# make -f %TOP%/Makefile -# -OBJ_DIR := obj - - -# The directory where all library files are placed. -# -# By default, this is the same as $(OBJ_DIR), however, this can be changed -# to suit particular needs. -# -LIB_DIR := $(OBJ_DIR) - - -# The object file extension (for standard and static libraries). This can be -# .o, .tco, .obj, etc., depending on the platform. -# -O := obj -SO := obj - -# The library file extension (for standard and static libraries). This can -# be .a, .lib, etc., depending on the platform. -# -A := lib -SA := lib - - -# The name of the final library file. Note that the DOS-specific Makefile -# uses a shorter (8.3) name. -# -LIBRARY := freetype - - -# Path inclusion flag. Some compilers use a different flag than `-I' to -# specify an additional include path. Examples are `/i=' or `-J'. -# -I := /I - - -# C flag used to define a macro before the compilation of a given source -# object. Usually is `-D' like in `-DDEBUG'. -# -D := /D - - -# The link flag used to specify a given library file on link. Note that -# this is only used to compile the demo programs, not the library itself. -# -L := /Fl - - -# Target flag. -# -T := /Fo - - -# C flags -# -# These should concern: debug output, optimization & warnings. -# -# Use the ANSIFLAGS variable to define the compiler flags used to enfore -# ANSI compliance. -# -ifndef CFLAGS - CFLAGS := /nologo /c /Ox /G5 /W3 /WX -endif - -# ANSIFLAGS: Put there the flags used to make your compiler ANSI-compliant. -# -ANSIFLAGS := /Za - - -ifdef BUILD_FREETYPE - - # Now include the main sub-makefile. It contains all the rules used to - # build the library with the previous variables defined. - # - include $(TOP)/builds/freetype.mk - - # The cleanup targets. - # - clean_freetype: clean_freetype_dos - distclean_freetype: distclean_freetype_dos - - # This final rule is used to link all object files into a single library. - # It is part of the system-specific sub-Makefile because not all - # librarians accept a simple syntax like - # - # librarian library_file {list of object files} - # - $(FT_LIBRARY): $(OBJECTS_LIST) - lib /nologo /out:$@ $(OBJECTS_LIST) - -endif - -# EOF diff --git a/subsys/win32k/freetype/ctype.c b/subsys/win32k/freetype/ctype.c deleted file mode 100644 index 42689b4..0000000 --- a/subsys/win32k/freetype/ctype.c +++ /dev/null @@ -1,706 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/rtl/ctype.c - * PURPOSE: Character type and conversion functions - * PROGRAMMERS: ??? - * Eric Kohl - * HISTORY: ???: Created - * 10/01/2000: Added missing functions and changed - * all functions to use ctype table - */ - -#undef __MSVCRT__ -#include -#include - -#undef _pctype - -#define upalpha ('A' - 'a') - - -unsigned short _ctype[] = { - 0, /* , 0xFFFF */ - _CONTROL, /* CTRL+@, 0x00 */ - _CONTROL, /* CTRL+A, 0x01 */ - _CONTROL, /* CTRL+B, 0x02 */ - _CONTROL, /* CTRL+C, 0x03 */ - _CONTROL, /* CTRL+D, 0x04 */ - _CONTROL, /* CTRL+E, 0x05 */ - _CONTROL, /* CTRL+F, 0x06 */ - _CONTROL, /* CTRL+G, 0x07 */ - _CONTROL, /* CTRL+H, 0x08 */ - _CONTROL | _SPACE, /* CTRL+I, 0x09 */ - _CONTROL | _SPACE, /* CTRL+J, 0x0a */ - _CONTROL | _SPACE, /* CTRL+K, 0x0b */ - _CONTROL | _SPACE, /* CTRL+L, 0x0c */ - _CONTROL | _SPACE, /* CTRL+M, 0x0d */ - _CONTROL, /* CTRL+N, 0x0e */ - _CONTROL, /* CTRL+O, 0x0f */ - _CONTROL, /* CTRL+P, 0x10 */ - _CONTROL, /* CTRL+Q, 0x11 */ - _CONTROL, /* CTRL+R, 0x12 */ - _CONTROL, /* CTRL+S, 0x13 */ - _CONTROL, /* CTRL+T, 0x14 */ - _CONTROL, /* CTRL+U, 0x15 */ - _CONTROL, /* CTRL+V, 0x16 */ - _CONTROL, /* CTRL+W, 0x17 */ - _CONTROL, /* CTRL+X, 0x18 */ - _CONTROL, /* CTRL+Y, 0x19 */ - _CONTROL, /* CTRL+Z, 0x1a */ - _CONTROL, /* CTRL+[, 0x1b */ - _CONTROL, /* CTRL+\, 0x1c */ - _CONTROL, /* CTRL+], 0x1d */ - _CONTROL, /* CTRL+^, 0x1e */ - _CONTROL, /* CTRL+_, 0x1f */ - _SPACE | _BLANK, /* ` ', 0x20 */ - _PUNCT, /* `!', 0x21 */ - _PUNCT, /* 0x22 */ - _PUNCT, /* `#', 0x23 */ - _PUNCT, /* `$', 0x24 */ - _PUNCT, /* `%', 0x25 */ - _PUNCT, /* `&', 0x26 */ - _PUNCT, /* 0x27 */ - _PUNCT, /* `(', 0x28 */ - _PUNCT, /* `)', 0x29 */ - _PUNCT, /* `*', 0x2a */ - _PUNCT, /* `+', 0x2b */ - _PUNCT, /* `,', 0x2c */ - _PUNCT, /* `-', 0x2d */ - _PUNCT, /* `.', 0x2e */ - _PUNCT, /* `/', 0x2f */ - _DIGIT | _HEX, /* `0', 0x30 */ - _DIGIT | _HEX, /* `1', 0x31 */ - _DIGIT | _HEX, /* `2', 0x32 */ - _DIGIT | _HEX, /* `3', 0x33 */ - _DIGIT | _HEX, /* `4', 0x34 */ - _DIGIT | _HEX, /* `5', 0x35 */ - _DIGIT | _HEX, /* `6', 0x36 */ - _DIGIT | _HEX, /* `7', 0x37 */ - _DIGIT | _HEX, /* `8', 0x38 */ - _DIGIT | _HEX, /* `9', 0x39 */ - _PUNCT, /* `:', 0x3a */ - _PUNCT, /* `;', 0x3b */ - _PUNCT, /* `<', 0x3c */ - _PUNCT, /* `=', 0x3d */ - _PUNCT, /* `>', 0x3e */ - _PUNCT, /* `?', 0x3f */ - _PUNCT, /* `@', 0x40 */ - _UPPER | _HEX, /* `A', 0x41 */ - _UPPER | _HEX, /* `B', 0x42 */ - _UPPER | _HEX, /* `C', 0x43 */ - _UPPER | _HEX, /* `D', 0x44 */ - _UPPER | _HEX, /* `E', 0x45 */ - _UPPER | _HEX, /* `F', 0x46 */ - _UPPER, /* `G', 0x47 */ - _UPPER, /* `H', 0x48 */ - _UPPER, /* `I', 0x49 */ - _UPPER, /* `J', 0x4a */ - _UPPER, /* `K', 0x4b */ - _UPPER, /* `L', 0x4c */ - _UPPER, /* `M', 0x4d */ - _UPPER, /* `N', 0x4e */ - _UPPER, /* `O', 0x4f */ - _UPPER, /* `P', 0x50 */ - _UPPER, /* `Q', 0x51 */ - _UPPER, /* `R', 0x52 */ - _UPPER, /* `S', 0x53 */ - _UPPER, /* `T', 0x54 */ - _UPPER, /* `U', 0x55 */ - _UPPER, /* `V', 0x56 */ - _UPPER, /* `W', 0x57 */ - _UPPER, /* `X', 0x58 */ - _UPPER, /* `Y', 0x59 */ - _UPPER, /* `Z', 0x5a */ - _PUNCT, /* `[', 0x5b */ - _PUNCT, /* 0x5c */ - _PUNCT, /* `]', 0x5d */ - _PUNCT, /* `^', 0x5e */ - _PUNCT, /* `_', 0x5f */ - _PUNCT, /* 0x60 */ - _LOWER | _HEX, /* `a', 0x61 */ - _LOWER | _HEX, /* `b', 0x62 */ - _LOWER | _HEX, /* `c', 0x63 */ - _LOWER | _HEX, /* `d', 0x64 */ - _LOWER | _HEX, /* `e', 0x65 */ - _LOWER | _HEX, /* `f', 0x66 */ - _LOWER, /* `g', 0x67 */ - _LOWER, /* `h', 0x68 */ - _LOWER, /* `i', 0x69 */ - _LOWER, /* `j', 0x6a */ - _LOWER, /* `k', 0x6b */ - _LOWER, /* `l', 0x6c */ - _LOWER, /* `m', 0x6d */ - _LOWER, /* `n', 0x6e */ - _LOWER, /* `o', 0x6f */ - _LOWER, /* `p', 0x70 */ - _LOWER, /* `q', 0x71 */ - _LOWER, /* `r', 0x72 */ - _LOWER, /* `s', 0x73 */ - _LOWER, /* `t', 0x74 */ - _LOWER, /* `u', 0x75 */ - _LOWER, /* `v', 0x76 */ - _LOWER, /* `w', 0x77 */ - _LOWER, /* `x', 0x78 */ - _LOWER, /* `y', 0x79 */ - _LOWER, /* `z', 0x7a */ - _PUNCT, /* `{', 0x7b */ - _PUNCT, /* `|', 0x7c */ - _PUNCT, /* `}', 0x7d */ - _PUNCT, /* `~', 0x7e */ - _CONTROL, /* 0x7f */ - 0, /* 0x80 */ - 0, /* 0x81 */ - 0, /* 0x82 */ - 0, /* 0x83 */ - 0, /* 0x84 */ - 0, /* 0x85 */ - 0, /* 0x86 */ - 0, /* 0x87 */ - 0, /* 0x88 */ - 0, /* 0x89 */ - 0, /* 0x8a */ - 0, /* 0x8b */ - 0, /* 0x8c */ - 0, /* 0x8d */ - 0, /* 0x8e */ - 0, /* 0x8f */ - 0, /* 0x90 */ - 0, /* 0x91 */ - 0, /* 0x92 */ - 0, /* 0x93 */ - 0, /* 0x94 */ - 0, /* 0x95 */ - 0, /* 0x96 */ - 0, /* 0x97 */ - 0, /* 0x98 */ - 0, /* 0x99 */ - 0, /* 0x9a */ - 0, /* 0x9b */ - 0, /* 0x9c */ - 0, /* 0x9d */ - 0, /* 0x9e */ - 0, /* 0x9f */ - 0, /* 0xa0 */ - 0, /* 0xa1 */ - 0, /* 0xa2 */ - 0, /* 0xa3 */ - 0, /* 0xa4 */ - 0, /* 0xa5 */ - 0, /* 0xa6 */ - 0, /* 0xa7 */ - 0, /* 0xa8 */ - 0, /* 0xa9 */ - 0, /* 0xaa */ - 0, /* 0xab */ - 0, /* 0xac */ - 0, /* 0xad */ - 0, /* 0xae */ - 0, /* 0xaf */ - 0, /* 0xb0 */ - 0, /* 0xb1 */ - 0, /* 0xb2 */ - 0, /* 0xb3 */ - 0, /* 0xb4 */ - 0, /* 0xb5 */ - 0, /* 0xb6 */ - 0, /* 0xb7 */ - 0, /* 0xb8 */ - 0, /* 0xb9 */ - 0, /* 0xba */ - 0, /* 0xbb */ - 0, /* 0xbc */ - 0, /* 0xbd */ - 0, /* 0xbe */ - 0, /* 0xbf */ - 0, /* 0xc0 */ - 0, /* 0xc1 */ - 0, /* 0xc2 */ - 0, /* 0xc3 */ - 0, /* 0xc4 */ - 0, /* 0xc5 */ - 0, /* 0xc6 */ - 0, /* 0xc7 */ - 0, /* 0xc8 */ - 0, /* 0xc9 */ - 0, /* 0xca */ - 0, /* 0xcb */ - 0, /* 0xcc */ - 0, /* 0xcd */ - 0, /* 0xce */ - 0, /* 0xcf */ - 0, /* 0xd0 */ - 0, /* 0xd1 */ - 0, /* 0xd2 */ - 0, /* 0xd3 */ - 0, /* 0xd4 */ - 0, /* 0xd5 */ - 0, /* 0xd6 */ - 0, /* 0xd7 */ - 0, /* 0xd8 */ - 0, /* 0xd9 */ - 0, /* 0xda */ - 0, /* 0xdb */ - 0, /* 0xdc */ - 0, /* 0xdd */ - 0, /* 0xde */ - 0, /* 0xdf */ - 0, /* 0xe0 */ - 0, /* 0xe1 */ - 0, /* 0xe2 */ - 0, /* 0xe3 */ - 0, /* 0xe4 */ - 0, /* 0xe5 */ - 0, /* 0xe6 */ - 0, /* 0xe7 */ - 0, /* 0xe8 */ - 0, /* 0xe9 */ - 0, /* 0xea */ - 0, /* 0xeb */ - 0, /* 0xec */ - 0, /* 0xed */ - 0, /* 0xee */ - 0, /* 0xef */ - 0, /* 0xf0 */ - 0, /* 0xf1 */ - 0, /* 0xf2 */ - 0, /* 0xf3 */ - 0, /* 0xf4 */ - 0, /* 0xf5 */ - 0, /* 0xf6 */ - 0, /* 0xf7 */ - 0, /* 0xf8 */ - 0, /* 0xf9 */ - 0, /* 0xfa */ - 0, /* 0xfb */ - 0, /* 0xfc */ - 0, /* 0xfd */ - 0, /* 0xfe */ - 0 /* 0xff */ -}; - -unsigned short *_pctype = _ctype + 1; -unsigned short *_pwctype = _ctype + 1; - -int _isctype (int c, int ctypeFlags) -{ - return (_pctype[(unsigned char)(c & 0xFF)] & ctypeFlags); -} - -int iswctype(wint_t wc, wctype_t wctypeFlags) -{ - return (_pwctype[(unsigned char)(wc & 0xFF)] & wctypeFlags); -} - -int isalpha(int c) -{ - return(_isctype(c, _ALPHA)); -} - -int isalnum(int c) -{ - return(_isctype(c, _ALPHA | _DIGIT)); -} - -int __isascii(int c) -{ - return ((unsigned char)c <= 0x7f); -} - -int iscntrl(int c) -{ - return(_isctype(c, _CONTROL)); -} - -int __iscsym(int c) -{ - return(isalnum(c)||(c == '_')); -} - -int __iscsymf(int c) -{ - return(isalpha(c)||(c == '_')); -} - - -int isdigit(int c) -{ - return(_isctype(c, _DIGIT)); -} - -/* -int isgraph(int c) -{ - return (_isctype (c, _PUNCT | _ALPHA | _DIGIT)); -} -*/ - -int islower(int c) -{ - return (_isctype (c, _LOWER)); -} - -int isprint(int c) -{ - return (_isctype (c, _BLANK | _PUNCT | _ALPHA | _DIGIT)); -} - -/* -int ispunct(int c) -{ - return (_isctype (c, _PUNCT)); -} -*/ - -int isspace(int c) -{ - return (_isctype (c, _SPACE)); -} - -int isupper(int c) -{ - return (_isctype (c, _UPPER)); -} - -int isxdigit(int c) -{ - return (_isctype (c, _HEX)); -} - -/* -int iswalpha(wint_t c) -{ - return (iswctype (c, _ALPHA)); -} -*/ - -int iswdigit(wint_t c) -{ - return (iswctype (c, _DIGIT)); -} - -int iswlower(wint_t c) -{ - return (iswctype (c, _LOWER)); -} - -int iswxdigit(wint_t c) -{ - return (iswctype (c, _HEX)); -} - - -/* -int __toascii(int c) -{ - return((unsigned)(c) & 0x7f); -} - -int _tolower(int c) -{ - if (_isctype (c, _UPPER)) - return (c - upalpha); - return(c); -} - -int _toupper(int c) -{ - if (_isctype (c, _LOWER)) - return (c + upalpha); - return(c); -} -*/ - -int tolower(int c) -{ - if (_isctype (c, _UPPER)) - return (c - upalpha); - return(c); -} - -int toupper(int c) -{ - if (_isctype (c, _LOWER)) - return (c + upalpha); - return(c); -} - -wchar_t towlower(wchar_t c) -{ - if (iswctype (c, _UPPER)) - return (c - upalpha); - return(c); -} - -wchar_t towupper(wchar_t c) -{ - if (iswctype (c, _LOWER)) - return (c + upalpha); - return(c); -} - -/* EOF */ - -int strcmp(const char *s1, const char *s2) -{ - while (*s1 == *s2) - { - if (*s1 == 0) - return 0; - s1++; - s2++; - } - - return *(unsigned const char *)s1 - *(unsigned const char *)(s2); -} - -int strncmp(const char *s1, const char *s2, size_t n) -{ - if (n == 0) - return 0; - do - { - if (*s1 != *s2++) - return *(unsigned const char *)s1 - *(unsigned const char *)--s2; - if (*s1++ == 0) - break; - } - while (--n != 0); - - return 0; -} - -char *strncpy(char *dst, const char *src, size_t n) -{ - if (n != 0) - { - char *d = dst; - const char *s = src; - - do - { - if ((*d++ = *s++) == 0) - { - while (--n != 0) - *d++ = 0; - break; - } - } - while (--n != 0); - } - - return dst; -} - -void * memmove(void *dest,const void *src,size_t count) -{ - char *char_dest = (char *)dest; - char *char_src = (char *)src; - - if ((char_dest <= char_src) || (char_dest >= (char_src+count))) - { - /* non-overlapping buffers */ - while(count > 0) - { - *char_dest = *char_src; - char_dest++; - char_src++; - count--; - } - } - else - { - /* overlaping buffers */ - char_dest = (char *)dest + count - 1; - char_src = (char *)src + count - 1; - - while(count > 0) - { - *char_dest = *char_src; - char_dest--; - char_src--; - count--; - } - } - - return dest; -} - -/* FIXME: these types should be from the default includes */ - -typedef int (* _pfunccmp_t) (char *, char *); - -#define min(a,b) ((a)<(b)?(a):(b)) - -/* - * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". - */ -#define swapcode(TYPE, parmi, parmj, n) { \ - long i = (n) / sizeof (TYPE); \ - register TYPE *pi = (TYPE *) (parmi); \ - register TYPE *pj = (TYPE *) (parmj); \ - do { \ - register TYPE t = *pi; \ - *pi++ = *pj; \ - *pj++ = t; \ - } while (--i > 0); \ -} - -#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ - es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; - -static inline void -swapfunc ( - char * a, - char * b, - int n, - int swaptype - ) -{ - if(swaptype <= 1) - swapcode(long, a, b, n) - else - swapcode(char, a, b, n) -} - -#define swap(a, b) \ - if (swaptype == 0) { \ - long t = *(long *)(a); \ - *(long *)(a) = *(long *)(b); \ - *(long *)(b) = t; \ - } else \ - swapfunc(a, b, es, swaptype) - -#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) - -static inline char * -med3 ( - char * a, - char * b, - char * c, - _pfunccmp_t cmp - ) -{ - return cmp(a, b) < 0 ? - (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) - :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); -} - - -/* EXPORTED */ -void -qsort ( - void * a, - size_t n, - size_t es, - _pfunccmp_t cmp - ) -{ - char *pa, *pb, *pc, *pd, *pl, *pm, *pn; - int d, r, swaptype, swap_cnt; - -loop: SWAPINIT(a, es); - swap_cnt = 0; - if (n < 7) - { - for ( pm = (char *) a + es; - pm < (char *) a + n * es; - pm += es - ) - { - for ( pl = pm; - pl > (char *) a && cmp(pl - es, pl) > 0; - pl -= es - ) - { - swap(pl, pl - es); - } - } - return; - } - pm = (char *) a + (n / 2) * es; - if (n > 7) - { - pl = (char *) a; - pn = (char *) a + (n - 1) * es; - if (n > 40) - { - d = (n / 8) * es; - pl = med3(pl, pl + d, pl + 2 * d, cmp); - pm = med3(pm - d, pm, pm + d, cmp); - pn = med3(pn - 2 * d, pn - d, pn, cmp); - } - pm = med3(pl, pm, pn, cmp); - } - swap(a, pm); - pa = pb = (char *) a + es; - - pc = pd = (char *) a + (n - 1) * es; - for (;;) - { - while (pb <= pc && (r = cmp(pb, a)) <= 0) - { - if (r == 0) - { - swap_cnt = 1; - swap(pa, pb); - pa += es; - } - pb += es; - } - while (pb <= pc && (r = cmp(pc, a)) >= 0) - { - if (r == 0) - { - swap_cnt = 1; - swap(pc, pd); - pd -= es; - } - pc -= es; - } - if (pb > pc) - { - break; - } - swap(pb, pc); - swap_cnt = 1; - pb += es; - pc -= es; - } - if (swap_cnt == 0) /* Switch to insertion sort */ - { - for ( pm = (char *) a + es; - pm < (char *) a + n * es; - pm += es - ) - { - for ( pl = pm; - pl > (char *) a && cmp(pl - es, pl) > 0; - pl -= es - ) - { - swap(pl, pl - es); - } - } - return; - } - - pn = (char *) a + n * es; - r = min(pa - (char *)a, pb - pa); - vecswap(a, pb - r, r); - r = min(pd - pc, pn - pd - es); - vecswap(pb, pn - r, r); - if ((r = pb - pa) > es) - { - qsort(a, r / es, es, cmp); - } - if ((r = pd - pc) > es) - { - /* Iterate rather than recurse to save stack space */ - a = pn - r; - n = r / es; - goto loop; - } -/* qsort(pn - r, r / es, es, cmp);*/ -} diff --git a/subsys/win32k/freetype/docs/build b/subsys/win32k/freetype/docs/build deleted file mode 100644 index 93c7463..0000000 --- a/subsys/win32k/freetype/docs/build +++ /dev/null @@ -1,264 +0,0 @@ -FreeType 2 compilation how-to - - -Introduction: - -Welcome to this new beta of the FreeType 2 library. You'll find in this -document instructions on how to compile the library on your favorite -platform. - - *** UNIX USERS : Even though the FT2 build system doesn't - ************** : use the Autoconf/Automake tools, these will - ************** : be introduced in the Unix-specific parts of - ************** : the build in our final release.. - - -I. QUICK COMMAND-LINE GUIDE: ----------------------------- - - Install GNU Make, then try the following on Unix or any system with gcc: - - make // this will setup the build - make // this will build the library - - On Win32+Visual C++: - - make setup visualc // setup the build for VisualC++ on Win32 - make // build the library - - Then, go to the "demos" directory and type - - make - - To compile the demo programs.. - - If this doesn't work, read the following.. - - - -II. COMMAND-LINE COMPILATION: ------------------------------ - - Note that if you do not want to compile FreeType 2 from a command line - shell, please skip to section III below (DETAILED COMPILATION) - - FreeType 2 includes a powerful and flexible build system that allows you - to easily compile it on a great variety of platforms from the command - line. To do so, just follow these simple instructions: - - a/ Install GNU Make: - - Because GNU Make is the only Make tool supported to compile FreeType 2, - you should install it on your machine. - - Because the FT2 build system relies on many important features of GNU - Make, trying to build the library with any other Make tool will *fail*. - - - b/ Invoke "make": - - Go to the root FT2 directory, then simply invoke GNU Make from the - command line, this will launch the FreeType 2 Host Platform detection - routines. A summary will be displayed, for example, on Win32: - - ======================================================================== - FreeType build system -- automatic system detection - - The following settings are used: - - platform win32 - compiler gcc - configuration directory ./builds/win32 - configuration rules ./builds/win32/w32-gcc.mk - - If this does not correspond to your system or settings please remove - the file 'config.mk' from this directory then read the INSTALL file - for help. - - Otherwise, simply type 'make' again to build the library. - ========================================================================= - - If the detected settings correspond to your platform and compiler, - skip to step e/. Note that if your platform is completely alien to - the build system, the detected platform will be "ansi". - - - c/ Configure the build system for a different compiler: - - If the build system correctly detected your platform, but you want to - use a different compiler than the one specified in the summary (for - most platforms, gcc is the defaut compiler), simply invoke GNU Make - like : - - make setup - - For example: - - to use Visual C++ on Win32, type: "make setup visualc" - to use LCC-Win32 on Win32, type: "make setup lcc" - - The name to use is platform-dependent. The list of available - compilers for your system is available in the file - "builds//detect.mk" (note that we hope to make the list - displayed at user demand in the final release).. - - If you're satisfying by the new configuration summary, skip to step e/ - - - d/ Configure the build system for an unknown platform/compiler: - - What the auto-detection/setup phase of the build system does is simply - copy a file to the current directory under the name "config.mk". - - For example, on OS/2+gcc, it would simply copy "builds/os2/os2-gcc.mk" - to "./config.mk" - - If for some reason your platform isn't correctly detected, simply copy - manually the configuration sub-makefile to "./config.mk" and go to - step e/. - - Note that this file is a sub-Makefile used to specify Make variables - used to invoke the compiler and linker during the build, you can easily - create your own version from one of the existing configuration files, - then copy it to the current directory under the name "./config.mk". - - - e/ Build the library: - - The auto-detection/setup phase should have copied a file in the current - directory, called "./config.mk". This file contains definitions of various - Make variables used to invoke the compiler and linker during the build. - - To launch the build, simply invoke GNU Make again: the top Makefile will - detect the configuration file and run the build with it.. - - - f/ Build the demonstration programs: - - Once the library is compiled, go to "demos", then invoke GNU Make. - - Note that the demonstration programs include a tiny graphics sub-system - that includes "drivers" to display Windows on Win32, X11 and OS/2. The - build system should automatically detect which driver to use based on - the current platform. - - UNIX USERS TAKE NOTE: XXXXXX - - When building the demos, the build system tries to detect your X11 path - by looking for the patterns "X11R5/bin", "X11R6/bin" or "X11/bin" in - your current path. If no X11 path is found, the demo programs will not - be able to display graphics and will fail. Change your current path - if you encounter this problem. - - Note that the release version will use Autoconf to detect everything - on Unix, so this will not be necessary !! - - -II. DETAILED COMPILATION PROCEDURE: ------------------------------------ - - If you don't want to compile FreeType 2 from the command-line (for example - from a graphical IDE on a Mac or Windows), you'll need to understand how the - FreeType files are organized. - - FreeType 2 has a very module design, and it is made of several components. - Each component must be compiled as a stand-alone object file, even when it - is really made of several C source files. For example, the "base layer" - component is made of the following C files: - - src/ - base/ - ftcalc.c - computations - ftobjs.c - object management - ftstream.c - stream input - ftlist.c - simple list management - ftoutln.c - simple outline processing - ftextend.c - extensions support - - However, you can create a single object file by compiling the file - "src/base/ftbase.c", whose content is basically: - - #include - #include - #include - #include - #include - #include - - Similarly, each component has a single "englobing" C file to compile it - as a stand-alone object, i.e. : - - src/base/ftbase.c - the base layer, high-level interface - src/sfnt/sfnt.c - the "sfnt" module - src/psnames/psnames.c - the Postscript Names module - src/truetype/truetype.c - the TrueType font driver - src/type1/type1.c - the Type 1 font driver - - - To compile one component, do the following: - - - add the top-level "include" directory to your compilation include path - - - add the "src" directory to your compilation include path. - - - compile the component "source" file (see list below), you don't need - to be in the component's directory.. - - For example, the following line can be used to compile the truetype driver - on Unix: - - cd freetype2/ - cc -c -Iinclude -Isrc src/truetype/truetype.c - - Alternatively: - - cd freetype2/src/truetype - cc -c -I../../include -I.. truetype.c - - The complete list of files to compile for a feature-complete build of - FreeType 2 is: - - src/base/ftsystem.c - system-specific memory and i/o support - src/base/ftinit.c - initialisation layer - src/base/ftdebug.c - debugging component (empty in release build) - src/base/ftbase.c - the "base layer" component - src/base/ftglyph.c - optional convenience functions - src/raster1/raster1.c - the monochrome bitmap renderer - src/smooth/smooth.c - the anti-aliased bitmap renderer - src/sfnt/sfnt.c - the "sfnt" module - src/psnames/psnames.c - the "psnames" module - src/truetype/truetype.c - the TrueType font driver - src/type1/type1.c - the Type 1 font driver (incl. Multiple Masters) - src/cid/type1cid.c - the Type 1 CID-keyed font driver - src/cff/cff.c - the OpenType/CFF/CEF font driver - src/winfonts/winfnt.c - the Windows FNT/FON font driver - - All font drivers are optional. the "sfnt" and "psnames" modules are - mandatory for certain drivers. - - -III. Support for flat-directory compilation: ----------------------------------------- - - It is now possible to put all FreeType 2 source files into a single - directory, with the exception of the "include" hierarchy. - - Note that you'll still need to only compile the 'wrapper' sources described - above. Define the "FT_FLAT_COMPILE" macro when compiling. Here's an - example: - - 1/ Copy all files in current directory: - - cp freetype2/src/base/*.[hc] . - cp freetype2/src/raster1/*.[hc] . - cp freetype2/src/smooth/*.[hc] . - etc... - - 2/ Compile sources: - - cc -c -DFT_FLAT_COMPILE -Ifreetype/include ftsystem.c - cc -c -DFT_FLAT_COMPILE -Ifreetype/include ftinit.c - cc -c -DFT_FLAT_COMPILE -Ifreetype/include ftdebug.c - cc -c -DFT_FLAT_COMPILE -Ifreetype/include ftbase.c - etc... - diff --git a/subsys/win32k/freetype/docs/design/build-system.html b/subsys/win32k/freetype/docs/design/build-system.html deleted file mode 100644 index b548b45..0000000 --- a/subsys/win32k/freetype/docs/design/build-system.html +++ /dev/null @@ -1,910 +0,0 @@ - - - - - - - FreeType 2 Internals - I/O Frames - - - - - - -
-

FreeType 2.0 Build System

- -
-

-© 2000 David Turner (david@freetype.org)
-© 2000 The FreeType Development Team -(devel@freetype.org) -

- -
- -


- -

Table of Content

- -
-

Introduction

-

I. Features & Background

- -

II. Overview of the build process

- -

III. Build setup details

-

IV. Library compilation details

- - -
- -
-

Introduction:

- -

This document describes the new build system that was introduced - with FreeType 2.

- -


-
-

I. Features and Background:

- -

The FreeType 2 build system is a set of Makefiles and sub-Makefiles that - are used to build the library on a very large variety of systems easily. - One of its main features are the following:

- -
-

1. Convenience, not Requirement

-
    -

    Even though the build system is rather sophisticated, it simply is a - convenience that was written simply to allow the compilation of the - FreeType 2 library on as many platforms as possible, as easily as - possible. However, it is not a requirement and the library can be - compiled manually or in a graphical IDE without using it, with minimal - efforts

    - -

    (for more information on this topic, see the BUILD - document that comes with your release of FreeType, in its Detailed - Compilation Guide section).

    -
- -
-

2. Compiler and platform independence

-
    -

    The FreeType 2 build system can be used with any compiler, on any platform. - It is independent of object file suffix, executable file suffix, directory - separator convention (i.e. "/" or "\"), and compiler flags for path - inclusion, macro definition, output naming, ansi compliance, etc..

    - -

    Supporting a new compiler is trivial and only requires writing a minimal - configuration sub-makefile that contains several Makefile variables - definitions that are later used by the rest of the build system. This is - described in details later in the document.

    -
- -
-

3. Uses GNU Make

-
    -

    The build system works exclusively with GNU Make. Reason - is that it is the only make utility that has all the features required to - implement the build system as described below. Moreover, it is already - ported to hundreds of various distinct platforms and is widely and - freely available.

    - -

    It also uses the native command line shell. You thus - don't need a Unix-like shell on your platform. - For example, FreeType 2 already compiles on Unix, Dos, Windows - and OS/2 right "out of the box" (assuming you have GNU Make - installed).

    - -

    Finally, note that the build system is specifically designed - for gnu make and will fail with any other make tool. We have - no plans to support a different tools, as you'll rapidly - understand by reading this document or looking at the sub-makefiles - themselves.

    -
- -
-

4. Automatic host platform detection

-
    -

    When you launch the build system for the first time, by simply invoking - GNU make in the top-level directory, it automatically tries to detect - your current platform in order to choose the best configuration - sub-makefile available. It then displays what it found. If everything - is ok, you can then launch compilation of the library, by invoking make - a second time.

    - -

    The following platforms are currently automatically detected:

    -
      -
    • Dos (plain-dos, windows in Dos mode, or Dos session under OS/2) -
    • Windows 95, 98 + Windows NT (a.k.a win32) -
    • OS/2 -
    • Unix (uses Autoconf/Automake) -
    - -

    Note that adding support for a new platform requires writing a minimal - number of very small files, and simply putting them in a new sub-directory - of freetype2/config.

    -
- -
-

5. User-selectable builds

-
    -

    The platform auto-detection rules try to setup the build for a default - compiler (gcc for most platforms), with default build options - for the library (which normally is - "all features enable, no debugging"), as well as the default - list of modules (which is "all modules in freetype2/src")

    - -

    There are cases where it is important to specify a different compiler, - different build options or simply a different module list. The FreeType 2 - build system is designed in such a way that all of this is easily possible - from the command line, without having to touch a single file. - The latter is crucial when dealing with projects that need specific - builds of the library without modifying a single file from the FreeType - distribution.

    - -

    The exact mechanism and implementation to do this is described later in - this document. It allows, for example, to compile FreeType with any of - the following compilers on Win32: gcc, Visual C++, Win32-LCC.

    -
- -
-

6. Robustness

-
- - -

7. Simple Module Management

-
    -

    FreeType 2 has a very modular design, and is made of a core - base layer that provides its high-level API as well as - generic services used by one or more modules. - - Most modules are used to support a specific font format (like TrueType - or Type 1), and they are called font drivers. However, some of - them do not support font files directly, but rather provide helper - services to the font drivers.

    - -

    FreeType 2 is designed so that adding modules at run-time is possible - and easy. Similarly, we expect many more modules to come in the near - future and wanted a build system that makes such additions to the - source package itself dead easy. - - Indeed, all source code (base + modules) is located in the - freetype2/src directory hierarchy. And the build system is - capable of re-generating automatically the list of known modules - from the contents of this directory. Hence, adding a new font driver - to the FreeType sources simply requires to:

    - -
      -
    • Add a new sub-directory to freetype2/src -

    • Re-launch the build system

      -
    - -

    There is thus no need to edit a source file

    -
- -


- -

II. Overview of the build process(es):

- -

Before describing in details how the build system works, it is essential - to give a few examples of how it's used. This section presents - what's the build process is to the typical developer:

- -

Compiling the library is normally done in two steps: the first one - configures the build according to the current platform and possible - additional parameters, while the second simply compiles the library with - the information gathered in the configuration step.

- -
-

1. Build Setup

- -
-

a. Default build setup

-
    -

    To configure the build, simply invoke gnu make from the top-level FreeType - directory. This will launch a series of rules that will detect your current - host platform, and choose a configuration file for you. It will then display - what it found. For example, here's the output of typing the command "make" - on a win32 platform (assuming this calls GNU make):

    - -
    
    -    C:\FreeType> make
    -
    -    FreeType build system -- automatic system detection
    -
    -    The following settings are used:
    -
    -      platform                     win32
    -      compiler                     gcc
    -      configuration directory      ./config/win32
    -      configuration rules          ./config/win32/w32-gcc.mk
    -
    -    If this does not correspond to your system or settings please remove the file
    -    'config.mk' from this directory then read the INSTALL file for help.
    -
    -    Otherwise, simply type 'make' again to build the library.
    -
    -    C:\FreeType>
    -
    - -

    Note that this step copies the selected configuration file (here - ./config/win32/w32-gcc.mk) to the current directory, under - the name config.mk. This file contains data that is used - to drive the library compilation of the second step. It correspond to - the platform and compiler selected by the auto-detection phase.

    - -

    Note that you can re-generate the config.mk file anytime - by invoking make setup whenever you need it, even when the file is - already present in the current directory.

    - -

    Finally, if your platform is not correctly detected, the build system will - display and use configuration information for the virtual "ansi" platform. -

    -
-
-

b. Selecting another build configuration

-
    -

    You may not be really satisfied by the configuration file selected by the - auto-detection routines. Typically, you might be using a compiler that is - not the default one for your platform. It is however possible to re-launch - the build setup phase with an additional argument, used to specify a - different compiler/config file. For example, you can type the following - commands on Win32 systems:

    - -

    -

    make setup

    -
    -

    re-run the platform detection phase, and select the default compiler for it. - On Win32, this is gcc.

    -
    -

    make setup visualc

    -
    -

    re-run the platform detection phase, and select a config file that - corresponds to the Visual C++ compiler

    -
    -

    make setup lcc

    -
    -

    re-run the platform detection phase, and select a config file that - corresponds to the Win32-LCC compiler

    -
    -

    - -

    Note that a specific configuration is selected with a command that - looks like : make setup compiler, - where the compiler keywords depends on the platform. - Moreover, each one of them corresponds to a specific configuration - sub-makefile that is copied as config.mk in the current - directory.

    -
- - -
-

2. Library compilation

- -

Once you're satisfied with the version of config.mk that - has been copied to your current directory, you can simply re-invoke - gnu make with no arguments. The top-level Makefile will - automatically detect the config sub-makefile in the current directory, - and use it to drive the library compilation. The latter can be seen - as a series of different steps decribed here:

- -
    -
  • Compiling the ftsystem component

      - It encapsulates all low-level operations (memory management + - i/o access) for the library. Its default version, located in - ./src/base/ftsystem.c uses the ANSI C library but - system-specific implementations are also available to - improve performance (e.g. memory-mapped files on Unix). -

    - -
  • Compiling the base layer and optional components

      - They provide the library's high-level API as well as various useful - routines for client applications. Many features of the base layer can - be activated or not depending on a configuration file named - ftoption.h -

    - -
  • Compiling the modules

      - Each module is used to support a specific font format (it is then - called a font driver), or to provide helper services to - the drivers (e.g. the auto-hinter). They are all located in - sub-directories of ./src, like ./src/truetype, - ./src/type1. -

    - -
  • Compiling the ftinit component

      - This one is in charge of implementing FT_Init_FreeType, - the library initialisation routine. It also selects what modules - are activated when a new library instance is created. -

    -
-


- -

II. Details of the build setup.

- -

When the top-level Makefile is invoked, it looks for a - file named config.mk in the current directory. - If this file is found, it is used directly to build the library - (skip to Section III for details then).

- -

Otherwise, the file ./config/detect.mk is included - by the top-level Makefile and parsed. Its purpose is to drive the - platform-detection phase, by:

- -
    -
  • Defining the PLATFORM variable, which indicates - what the currently detected platform is. It is initially - set to the default value "ansi". -

    - -
  • Searching for a detect.mk file in all - subdirectories of ./config. - Each such file is included and parsed. Each of these files must - try to detect if the host platform is a system it knows - about. If so, it changes the value of the PLATFORM variable - accordingly.

    - -
  • Copying the selected configuration submakefile to the current directory - under the name config.mk.

    -
-

This is illustrated by the following graphics :

-

- -

- -

Each system-specific detect.mk works as follows:

-
    -
  • It checks that the value of PLATFORM is currently set - to ansi, which indicates that no platform was detected - for now. If this isn't true, it doesn't do anything

    - -
  • Otherwise, it runs a series of test to see wether it is on a - system it knows about. Here are a few examples of tests:

    - -

    - Unix - -

    checks for a file named /sbin/init, and runs, when it found - it, a 'configure' script to generate the relevant config sub-makefile

    -
    - Dos - -

    checks for the COMSPEC environment variable, then tries to - run the "ver" command on the current shell to check that there - is a "Dos" substring in its output; if not, it tries to find the - substring "MDOS\COMMAND" in COMSPEC, which indicates - a Dos session under OS/2.

    -
    - Win32 - -

    if the environment variable OS is defined and has the value - Windows_NT, or if COMSPEC is defined and the - "ver" returns a string that contains Windows in it, - we're on a Win32 system.

    -
    -

    - -
  • It sets the value of PLATFORM to a new value corresponding - to its platform.

    - -
  • It then tries to select a configuration - sub-makefile, depending on the current platform and any optional - make target (like "visualc" or "devel", etc..). Note that it can - even generate the file, as on Unix through Autoconf/Automake.

    - -
  • It copies the selected configuration sub-makefile to the current - directory, under the name config.mk -

- -

If one wants to support a new platform in the build system, it simply needs - to provide:

- -
    -
  • A new subdirectory, in ./config, with a file named - detect.mk in it, containing relevant checks for the system. - -
  • One or more configuration sub-makefiles that will get copied to - config.mk at build setup time. You can use the one in - ./config/ansi/config.mk as a template. -
- -

Similary, supporting a new compiler on an existing system simply means:

-
    -
  • Writing a new config sub-makefile that contains definitions used to - specify the compiler and flags for the build. - -
  • Change your ./config/system/detect.mk to recognize - a new optional build target that will copy your new config sub-makefile - instead of the default one. -
- - -


-

III. Details of the library compilation.

- -

When the top-level Makefile is invoked, it looks for a file named - config.mk in the current directory. If one is found, it - defines the BUILD_FREETYPE variable, then includes and parses it. - The structure of this file is the following: -

- -
    -
  • First, it defines a series of Make variables that describe - the host environment, like the compiler, compilation flags, - object file suffix, the directory where all object files are - placed, etc..

    - -
  • If BUILD_FREETYPE is defined, it includes the file - ./config/freetype.mk, which is in charge of - defining all the rules used to build the library object files. - (The test is useful to use the config.mk file to - compile other projects that rely on FreeType 2, like its - demonstration programs).

    - -
  • Finally, it defines the rule(s) used to link FreeType 2 object files - into a library file (e.g. libfreetype.a, freetype.lib, - freetype.dll, ...). Unfortunately, the command line interface of link tools is - a lot less standardized than those of compilers, which - explains why this rule must be defined in the system-specific - config.mk.

    -
- -

The following is an explanation of what ./config/freetype.mk - does to build the library objects: -

- -

a. Include paths

-
    -

    To avoid namespace pollution, the freetype directory prefix - is used to include all public header files of the library. This means - that a client application will typically use lines like:

    - -
    
    -    #include <freetype/freetype.h>
    -    #include <freetype/ftglyph.h>
    -
    - -

    to include one the FreeType 2 public header files. freetype.mk - uses a variable named INCLUDES to hold the inclusion - paths list, and thus starts by adding ./include to it. However, - nothing prevents - -

    freetype.mk uses a variable named INCLUDES - to hold directory inclusion-path to be used when compiling the library. - It always add ./include to this variable, which means - -

- -

b. Configuration header files:

-
    -

    Three header files used to configure the compilation of the - FreeType 2 library. Their default versions are all located in the - directory ./include/freetype/config/, even though - project specific versions can be provided on a given build, as - described later:

    - -
      -

      #include <freetype/config/ftoption.h>

        - This file contains a set of configuration macro definitions that - can be toggled to activate or deactivate certain features of the - library. By changing one of these definitions, it is possible to - compile only the features that are needed for a specific - project. Note that by default, all options are enabled. -

        - You might need to provide an alternative version of ftoption.h - for one of your own projects. -

      - -

      #include <freetype/config/ftconfig.h>

        - This file includes ftoption.h but also contains some automatic - macro definitions used to indicate some important system-specific - features (e.g: word size in bytes, DLL export prefix macros, etc..). -

        - You shouldn't normally need to change or provide an alternative - version of this file. -

      - - -

      #include <freetype/config/ftmodule.h>

        - This file is very special, as it is normally machine-generated, and - used by the ftinit component that is described below. To - understand it, one must reminds that FreeType 2 has an extremely - modular design and that it's possible to change, at run-time, - the modules it's using. The ftmodule.h file simply contains - the list of modules that are registered with each new instance of - the library. -

        - Note that the file can be re-generated automatically by invoking - make setup from the top-level directory. The re-generated - list contains all the modules that were found in subdirectories of - ./src. -

      -
    - -

    Note that we strongly advise you to avoid modifying the config files - within the FreeType 2 source directory hierarchy. Rather, it's possible - to specify alternative versions through the help of a build-specific - include path that is include before ./include in the inclusion - path.

    - -

    For example, imagine that your platform, named foo, needs a - specific version of ftoption.h -

- -

a. Compiling the ftsystem component:

-
    -

    FreeType 2 encapsulates all low-level operations (i.e. memory management - and i/o access) within a single component called ftsystem. - Its default implementation uses the ANSI C Library and is located - in ./src/base/ftsystem.c.

    - -

    However, some alternate, system-specific, implementations of - ftsystem are provided with the library in order to support more - efficient and advanced features. As an example, the file - ./config/unix/ftsystem.c is an implementation that - uses memory-mapped files rather than the slow ANSI fopen, - fread and fseek, boosting performance significantly.

    - -

    The build system is thus capable of managing alternate implementations - of ftsystem

    -
- -

b. Compiling the base layer and optional components:

-
    -

    The high-level API of the library is provided by a component called the - base layer, whose source is located in ./src/base. This - directory also contains one or more components that are optional, i.e. - that are not required by the library but provide valuable routines to - client applications.

    - -

    The features of the base library and other components are selected through - a single configuration file named - ./include/freetype/config/ftoption.h. It contains a list - of commented configuration macro definitions, that can be toggled to - activate or de-activate a certain feature or component at build time.

    - -

    For example, the code in ./src/base/ftdebug.c will be compiled - only if one of these two macros are defined in ftoption.h: - FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE

    -
- -

c. Compiling the modules:

-
    -

    Once the base layer is completed, the build system starts to compile each - additional module independently. These are simply defined as all source - code located in a sub-directory of ./src that contains a file - named rules., for example: - src/sfnt, src/truetype, src/type1, ...

    - -

    The rules. file simply contains directives used by the - build system to compile the corresponding module into a single object - file.

    -
- -

d. Compiling the ftinit component:

-
    -

    The file ./src/base/ftinit.c is special because it is used - to implement the library initialisation function FT_Init_FreeType. -

    -
- -

Typically, you will end up with all object files, as well as the - corresponding library file, residing in the freetype2/obj - directory.

- - -

1. Purpose of the configuration sub-makefile

- -

2. Managing module dependencies

- -

3.

- -


- -

IV. Managing the modules list

- -


- The build system features some important points, which are all detailed - in the following sections:

-

    -
  • Automatic host platform detection
    - The first time the top Makefile is invoked, it will - run a series of rules to detect your platform. It will then - create a system-specific configuration sub-Makefile in the - current directory, called config.mk. You can now - invoke the top Makefile a second time to compile the - library directly. -

    - The configuration sub-makefile can be regenerated any time - by invoking "make setup", which will re-run the - detection rules even if a config.mk is already present. -

    - - -

  • User-selectable builds
    -

    - - - -

  • Automatic detection of font drivers
    - FreeType is made of a "base" layer that invokes several - separately-compiled modules. Each module is a given - font driver, in charge of supporting a given font format. -

    - The list of font drivers is located in the file - "freetype2/config/system/ftmodule.h", however - it can be regenerated on-demand. Adding a new module to the - FreeType source tree is thus as easy as:

    -

      -
    • create a new directory in "freetype2/src" and - put the new driver's source code and sub-makefiles there. -

      - -

    • invoke the top Makefile with target - "modules" (as in "make modules"), - as this will automatically regenerate the list of - available drivers by detecting the new directory and - its content. -
    -

    -

- - -


- -

II. Host Platform Detection

-
    - When the top-level Makefile is invoked, it looks for a - file named config.mk in the current directory. If this - file is found, it is used to build the library - (see Section III). -

    - Otherwise, the file freetype2/config/detect.mk is included - and parsed. Its purpose is to:

    -

      -
    • Define the PLATFORM variable, which indicates - what is the currently detected platform. It is initially - set to the default value "ansi". -

      - -

    • It searches for a detect.mk file in all - subdirectories of freetype2/config. Each such - file is included and parsed. Each of these files must - try to detect if the host platform is a system it knows - about. If so, it changes the value of the PLATFORM - accordingly. -
    -

    - This is illustrated by the following graphics :

    -

    - -
    -

    - Note that each system-specific detect.mk is in charge - of copying a valid configuration makefile to the current directory - (i.e. the one where make was invoked), depending on the - current targets. For example, the Win32 detect.mk will - be able to detect a "visualc" or "lcc" target, - as described in section I. Similarly, the OS/2 detect.mk - can detect targets like "borlandc", "watcom" - or "visualage", etc.. -

- -


- -

III. Building the library

-
    - When the top-level Makefile is invoked and that it finds - a config.mk file in the current directory, it defines - the variable BUILD_FREETYPE, then includes and parses the - configuration sub-makefile. -

    - The latter defines a number of important variables that describe - the compilation process to the build system. Among other things:

    -

      -
    • the extension to be used for object files and library files - (i.e. .o and .a on Unix, .obj - and .lib on Dos-Windows-OS/2, etc..). -

      - -

    • the directory where all object files will be stored - (usually freetype2/obj), as well as the one - containing the library file (usually the same as for - objects). -

      - -

    • the command line compiler, and its compilation flags for - indicating a new include path (usually "-I"), - a new macro declaration (usually "-D") or - the target object file (usually "-o ") -
    -

    - Once these variable are defined, config.mk test for the - definition of the BUILD_FREETYPE variable. If it exists, - the makefile then includes "freetype2/config/freetype.mk" - which contains the rules required to compile the library. -

    - Note that freetype.mk also scans the subdirectories of - "freetype2/src" for a file called "rules.mk". - Each rules.mk contains, as it names suggests, the rules - required to compile a given font driver or module. -

    - Once all this parsing is done, the library can be compiled. Usually, - each font driver is compiled as a standalone object file (e.g. - sfnt.o, truetype.o and type1.o). -

    - This process can be illustrated by the following graphics:

    -

    - -
    -

    -

- -


- -

IIV. Managing the list of modules

-
    - The makefile freetype.mk only determines how to compile - each one of the modules that are located in the sub-directories of - freetype2/src. -

    - However, when the function FT_Init_FreeType is invoked at - the start of an application, it must create a new FT_Library - object, and registers all known font drivers to it by - repeatly calling FT_Add_Driver. -

    - The list of known drivers is located in the file - "freetype2/config/system/ftmodule.h", and is used - exclusively by the internal function FT_Default_Drivers. The - list in ftmodule.h must be re-generated each time you add - or remove a module from freetype2/src. -

    - This is normally performed by invoking the top-level Makefile - with the modules target, as in:

    -

      - make modules -
    -

    - This will trigger a special rule that will re-generate - ftmodule.h. To do so, the Makefile will parse all module - directories for a file called "module.mk". Each - module.mk is a tiny sub-Makefile used to add a single - module to the driver list. -

    - This is illustrated by the following graphics:

    -

    - -
    -

    - Note that the new list of modules is displayed in a very human-friendly - way after a "make modules". Here's an example with the current - source tree (on 11 Jan 2000):

    -

      -Regenerating the font drivers list in ./config/unix/ftmodule.h
      -* driver:  sfnt      ( pseudo-driver for TrueType & OpenType formats )
      -* driver:  truetype  ( Windows/Mac font files with extension *.ttf or *.ttc )
      -* driver:  type1     ( Postscript font files with extension *.pfa or *.pfb )
      --- done --
      -    
    - -
- -


- -

V. Building the demonstration programs

-
    - Several demonstration programs are located in the - "freetype2/demos" directory hierarchy. This directory also - includes a tiny graphics sub-system that is able to blit glyphs to - a great variety of surfaces, as well as display these in various - graphics libraries or windowed environments. -

    - This section describes how the demonstration programs are compiled, - using the configuration freetype2/config.mk and their own - freetype2/demos/Makefile. -

    - To compile the demonstration programs, after the library, - simply go to freetype2/demos then invoke GNU make with no - arguments. -

    - The top-level Makefile will detect the config.mk in the - upper directory and include it. Because it doesn't define - the BUILD_FREETYPE variable, this will not force the - inclusion of freetype2/config/freetype.mk as described in - the previous section. -

    - the Makefile will then include the makefile called - "freetype2/demos/graph/rules.mk". The graphics rules.mk - defines the rules required to compile the graphics sub-system. -

    - Because the graphics syb-system is also designed modularly, it is able - to use any number of "modules" to display surfaces on the screen. - The graphics modules are located in the subdirectories of - freetype2/demos/config. Each such directory contains a file - named rules.mk which is in charge of:

    -

      -
    • detecting wether the corresponding graphics library is - available at the time of compilation. -

      -

    • if it is, alter the compilation rules to include the graphics - module in the build of the graph library. -
    -

    - When the graph library is built in demos/obj, the - demonstration programs executables are generated by the top-level - Makefile. -

    - This is illustrated by the following graphics:

    -

    - -
    -
- -


-
- - - diff --git a/subsys/win32k/freetype/docs/design/demo-programs.png b/subsys/win32k/freetype/docs/design/demo-programs.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/demo-programs.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/drivers-list.png b/subsys/win32k/freetype/docs/design/drivers-list.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/drivers-list.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/index.html b/subsys/win32k/freetype/docs/design/index.html deleted file mode 100644 index 50f7f29..0000000 --- a/subsys/win32k/freetype/docs/design/index.html +++ /dev/null @@ -1,791 +0,0 @@ - - - - - - - FreeType 2 Internals - - - - - -
-

-FreeType 2.0 Internals

- -
-

-Version 1.2

- -
-

-© 1999-2000 David Turner (david@freetype.org)
-© 1999-2000 The FreeType Development Team (devel@freetype.org)

- -


-


-
  -

Introduction:

- -

This document describes in great deatils the internals of FreeType 2. - It is a must read for porters and developers alike. Its purpose is to - - present the -

This document describes in great details the internals of the -FreeType 2.0 library. It is a must read for porters and developers alike. -Its purpose is to present the engine's objects, their roles and interactions. -It is assumed that the FreeType Glyph Conventions document -has been read. -

We advise porters to also read the FreeType Porting Guide -after this document. Would-be hackers and maintainers are of course encouraged -to read the FreeType Coding Conventions document too. The -development of a new driver is described in more details in the FreeType -Driver HowTo document.

- -


-


-

-I. Overview :

- -
-

-1. Features (and what's new) :

- -
FreeType 2.0 has a number of important new features that were -not found in the 1.x releases : -
  -
font-format independent API -
FreeType 2.0 is able to support any kind of font format, be it fixed -or scalable, through the use of pluggable "font drivers". These drivers -can be added or replaced at run time, while applications use a new font -format-independent API. -

advanced stream caching -
2.0 is able to control the number of concurrently opened streams when -using fonts. It is thus possible to open dozens or hundreds of font faces -without running out of system resources. -

real reentrancy support -
It is now possible to use FreeType as a shared library with no static -data in a multi-threaded environment. The synchronization model has also -been simplified in order to make font driver writing easier. Of course, -you can build FreeType with no thread support to get a smaller library. -

support for cubic beziers and 17-levels anti-aliasing -
The FreeType scan-line converter (a.k.a. raster) now supports cubic -bezier arcs seamlessly. It also provides a new anti-aliasing mode which -uses a palette of 17 levels of grays. -
 

-It also features the following : -
performance improvements : -
The FreeType raster has been optimized, and the generation of anti-aliased -pixmaps is now 60% faster than in the 1.x release. Moreover, the TrueType -bytecode interpreter has been profiled and greatly optimised. -

easier portability -
Porting and configuring FreeType is now much easier. A single file -must be provided for system-specific operations (like memory, i/o, thread -management), and a single configuration header is used to select the build -you need. -
 

-
- -

-2. Architecture :

- -
The engine is now split in several parts, which are : -

-a. The base layer :

- -
This part contains all the font-format independent features -of the engine which are : -
    -
  • -computations/scaling
  • - -
  • -list processing
  • - -
  • -outline processing
  • - -
  • -scan-line converter
  • - -
  • -stream manager
  • - -
  • -base object classes
  • - -
  • -debugging & traces
  • - -
  • -high-level API functions
  • - -
  • -low-level system object (memory, i/o, threads)
  • -
-
- -

-b. The font drivers :

- -
Each font format is managed with the use of a single font driver -object. The base layer is able to manage several drivers, and these can -be easily added, removed or upgraded at runtime. Each driver has the following -features and functions : -
    -
  • -auto-check font format when opening a font resource (i.e. file)
  • - -
  • -access, load and/or extract all tables and data from the font file
  • - -
  • -grid-fit/hint the glyph outlines (in the case of scalable formats like -TrueType or Type1)
  • - -
  • -provide extensions to access font format-specific data and tables from -the font file
  • -
-Note that FreeType 2.0 is a font service. Its purpose is to provide a unified -API for all kinds of fonts and extract individual glyph images and metrics. -However, it does not render text itself, as this operation is left to the -developer, or to higher-level libraries built on top of FreeType. Here -are a few features that are thus not implemented : -
1) Text string rendering -
2) Glyph bitmap/outline caching for improved performance -
3) Synthetic fonts (i.e. italicising, emboldening, underlining) -
4) Contextual glyph substitution and other advanced layout processes
-Note that features 1 through 3 should be provided by the SemTex library, -which may soon become part of the standard FreeType distribution.
-
-
- -


-


-

-II. Design :

- -
-

-1. Objects :

- -
They are several kinds of objects in FreeType, which can be -described as follows : -
Base objects -
These objects do not relate directly to font data, but to the way it -is organised and managed. It is the basic core and provides functions that -are heavily used by each font driver. Examples are the resource objects, -used to describe font files, the system object used to manage low-level -system operations, or the raster object, used to convert vector outlines -into bitmaps or anti-aliased pixmaps. Most of the base objects are not -directly visible for client applications of FreeType. -

Font objects -
The font objects directly model the data as it is found in font files. -The root classes implemented in the base layer like FT_Face, FT_Size, -FT_GlyphSlot, -must be derived in each font driver.

-Objects are defined in the files "base/freetype.h" and "base/ftobjs.h". -The former contains all the public object definitions usable by client -applications. The latter contains private definitions used by the rest -of the base layer and each font driver.
- -

-2. List management

- -
The "base/ftlist.c" component a very simple doubly-linked -list facility which is used by the rest of the engine to create and process -lists, including iteration and finalisation. The definition of the list -node and functions are placed in the "base/freetype.h" to let -client applications access listed objects as they like. -

The base list type is FT_List, which links nodes of type FT_ListNode -together. -
 

- -

-3. Limited encapsulation

- -
Unlike what happened in the 1.x releases, the FT_Face, -FT_Size, -FT_GlyphSlot and FT_CharMap types are no longer blind -pointers to opaque types. Rather, the corresponding structures are now -public (and defined in "base/freetype.h", see FT_FaceRec, -FT_SizeRec, -etc..) in order to let client applications read directly the various object -attributes they're interested in. -

This breaks encapsulation of implementation, famed by OOP, but was chosen -because: -
  -

    -
  • -it simplifies a lot the work of client applications and libraries which -don't need to perform a function call everytime they want to read one important -object attribute (nor does it force them to cache these attributes in their -own structures).
  • -
- -
    -
  • -It reduces greatly the API, as many FT_Get_XXX functions are avoided.
  • -
- -
    -
  • -Higher-level libraries are able to  access data directly. When it -is used frequently, they don't need to cache it in their own structures.
  • -
- -
    -
  • -It is possible to tightly link FreeType objects with higher-level ones, -in a clearer and more efficient way. This is very important when one wants -to write a C++ wrapper or a text rendering library on top of FreeType (actually, -both projects were performed in an earlier version of FreeType 2.0 which -featured classic encapsulation through get/set methods. The resulting code -was ugly and slow. Moving to a limited encapsulation approach simplified -so many things that the compiled code size was reduced by a factor of two -!).
  • -
- -
    -
  • -Finally, the API and font object structures were designed after the creation -of two scalable font drivers and one bitmap font driver. They are now very -stable and the public (visible) attributes are not going to change.
  • -
-
-
- -


-


-

-III. Base objects :

- -
This section describes the FreeType base object classes : -
  -

-1. System objects :

- -
The system class is in charge of managing all low-level and -system-specific operations. This means simply memory management, i/o access -and thread synchronisation. It is implemented by the "ftsys.c" -component, whose source must be located in the configuration directory -when building FreeType. (e.g. "lib/arch/ansi/ftsys.c" for an ANSI -build, "lib/arch/unix/ftsys.c" for a Unix one, etc..). -

Porting FreeType 2.0 really means providing a new implementation of -ftsys -(along with a few configuration file changes). Note however that its interface -is common to all ports, and located in "base/ftsys.h".

- -

-2. Resources and Streams:

- -
The concepts of files as storages, and files as streams has -been separated for FreeType 2.0. The "resource" concept was -introduced while the "stream" one has been redefined. Here -is how they work together : -
    -
  • -a "resource" is an object which models a file, seen as a storage. -There are several classes of resources, which differ usually in two ways -: the way their data is accessed by applications, and the way they're named -within the system.
  • -
- -
    For example, when parsing files with the ANSI C library, data has to -be read (through fseek/fread) into intermediate buffers before it can be -decoded. This scheme is highly portable, but rather inefficient; when using -it, we'll describe the file as a disk-based resource. -

    As most modern operating systems now provide memory-mapped files, which -allow direct access while improving performance and reducing memory usage. -Because data can be read directly in memory, we'll speak of a memory-based -resource in this case. For embedded systems (like printers, PDAs, etc..), -ROM-fonts fit into this category as well. -

    Regarding naming, most systems use a string to name files in their storage -hierarchy. Though a typical pathname is an ASCII string ('c:\windows\fonts\times.ttf' -on Windows, '/home/fonts/times.ttf' on Unix), some OSes use different -schemes, varying from Unicode character strings to file i-node numbers. -These details are platform-specific and must be hidden to the rest of the -library in resource objects. -

    A resource encapsulates the lowest details regarding a file, though -it should have NO STATE. Note that the nature or type of a resource (i.e. -disk or memory based) is important to the "stream" component only. The -rest of the library and font drivers work transparently from their implementation. -

    Note also that it is perfectly possible to mix resources of distinct -natures in a single build

- -
    -
  • -a "stream" is an object which is used to extract bytes from a resource. -Only resource objects can create streams, through its Open_Stream() -method. A stream has state, which typically consist of a file "cursor", -some intermediate buffers, a "current frame" and, of course, methods used -to extract the data from streams, resolving endianess and alignement issues.
  • -
-Data can be extracted from streams through direct reads, or through the -use of frames. A frame models a run of contiguous bytes starting -from the current stream position, and of liberal size. -

Methods exist to extract successive integers of any sizes, while resolving -endianess and alignement issues. Rather than a long rethorical explanation, -here's how frames are typically used : -

{ -
  Â… -
  FT_Error  error; -

  error = FT_Access_Frame( stream, 14 ); -
  if (error) goto Fail; -

  val1 = FT_Get_Short(stream); -
  val2 = FT_Get_Long(stream); -
  val3 = FT_Get_Long(stream); -
  val4 = FT_Get_Long(stream); -

  FT_Forget_Frame(stream); -
  Â… -
}

-This code does the following : -
-
    -
  1. - first, it "loads" the next 14 bytes from the current cursor position -into the stream's frame, using the FT_Access_Frame API. An error -is returned if, for example, less than 14 bytes are left in the stream -when the call occurs..
  2. -
- -
    -
  1. - it extract four integers (one 16-bit short, three 32-bit longs) from -the frame using FT_Get_Short and FT_Get_Long. These function -increment the frame's cursor finally, it "releases" the stream's frame.
  2. -
- -
    -
  1. - Each stream has its own frame which can be accessed independently, -however, nested frame accesses are not allowed. Note also that the bytes -are effectively read from the stream on the call to FT_Access_Frame. -Any subsequent read will occur after these 14 bytes, even if less are extracted -through FT_Get_xxxx functions.
  2. -
-
-The implementation of the resource class is located in the system component -(i.e. "arch/<system>/ftsys.c") and can thus be tailored -for a specific port of the engine. -

A resource can be created through the FT_New_Resource API; -however this function only accepts an 8-bit pathname to name the target -font file, which may be inappropriate for systems using a different naming -scheme (e.g. UTF-16 pathname, i-node number, etc..). It's up to the porter -then to provide its own resource creation function (like. FT_New_UTF16_Resource, -for example) in its version of "ftsys.c". -

Note that FT_New_Resource will fail and return an error code -if the font file cannot be found, or when its font format isn't recognized -by one of the drivers installed in the library. The list or resources created -for a given library instance is thus the list of "installed font files". -
 

- -

-3. Stream Manager :

- -
As said before, resources do not bear states, while streams -do. Stream creation is also a very lengthy process, depending on the target -operating system (e.g. "fopen" is usually very slow). -

Because a typical font driver will want to use a new stream on each -access to individual glyphs, being able to cache the most recently used -streams is a requirement in order to avoid considerable performance penalties. -

Stream caching is thus implemented in the "ftstream" component. -It maintains a simple LRU list of the least recently used streams. Each -stream in the cache is still opened and available for immediate processing. -When a resource is destroyed, the stream cache is parsed to remove all -related cached streams. -

Stream caching can also be disabled with a configuration macro when -using only ROM based resources (where stream opening is really quick). -It is implemented through a Stream Manager object (see ftstream.c). -
 

- -

-4. Raster :

- -
The raster is the component is charge of generating bitmaps -and anti-aliased pixmaps from vectorial outline definitions. It is also -sometimes called the scan-line converter. It has been completely rewritten -for FreeType 2.0 in order to support third-order bezier arcs, 17-levels -anti-aliasing (through 4x4 sub-sampling), improved performance, as well -as stand-alone compilation (in order to include it in other graphics package -without requiring the rest of the FreeType engine). -

Because it was designed for easy re-use and embedded systems, the raster -is a rtaher 'unusual' piece of code, because it doesn't perform a single -memory allocation, nor contain any static or global variable. Rather, it -is up to client applications to allocate a raster object in their own heap -or memory space. -

Each raster object also needs a rather large block of memory called -its render pool. The pool is used during rendering (and only during it) -in order to perform the scan-line conversion. Because it accesses and manages -data directly within the pool, the raster yelds impressive performance -as well as bounded memory consumption. It can also automatically decompose -large requests into smaller individual sub-tasks. -

Finally, it never creates bitmaps or pixmaps, but simply renders into -them (providing clipping too). These must be described to the raster with -the help of a FT_Raster_Map structure (a very simple bitmap/pixmap -descriptor). -

Note that when rendering anti-aliased pixmaps, the raster doesn't use -an intermediate bitmap buffer, as filtering is part of the scan-line conversion -process. -
 

- -

-5. Library objects :

- -
A library object models a single instance of the FreeType engine. -This is useful when FreeType is compiled as a shared object (DLL), as it -can then be used by several applications, each with its own resources and -objects. -

The FT_Library type is an opaque handle to a library object. -Such an object is created through a call  to FT_Init_FreeType. -Once you don't need it anymore, one can destroy a library object through -FT_Done_FreeType. -

Note that in reentrant builds, several threads can access a single library -object concurrently. Such a build can be chosen by switching one configuration -macro in the file 'arch/<system>/ftconfig.h'

- -

-6. Driver objects :

- -
A driver object models an instance of a given font driver, -i.e. an element of FreeType code in charge of handling a given font format, -like TrueType, Type1, FNT, PCF, etc.. -

Each library object contains a given set of driver objects when it is -created through FT_Init_FreeType, this set being determined at compile -time (see the file 'base/ftapi.c'). However, removing or adding drivers -is possible at run-time, in order to make upgrades easy.

- -

-7. Diagram

- -
This diagram show the object relationships for the sole base -layer. The library object is the root of the object graph : -
-

- -

It can be read as follows : -
  -

    -
  • -Each library object has one system, one raster and one stream manager objects. -These objects can only belong to one given library.
  • -
- -
    -
  • -Each library contains one list of 0 or more resources, as well as one list -of 0 or more driver objects.
  • -
- -
    -
  • -Each stream manager holds a bounded list ("0..n" where 'n' is the stream -cache's size) of stream objects. Each stream is related to one given resource -object. Each resource may be related to zero or one stream.
  • -
- -
    -
  • -Each resource is related to one driver object. A driver is related to 0 -or more resources.
  • -
-
-
- -


-


-

-IV. Font objects :

- -
Font objects are used to directly map the information found -in font files into several categories : -
  -

-1. Face objects :

- -
Face objects are used to model individual font faces. They -encapsulate data which isn't related to a specific character size, or a -specific glyph or glyph set. Usually, this means : -
    -
  • -the font face's family and style names (e.g. "Palatino" + "Regular")
  • - -
  • -some flags indicating which kind of font this is (scalable or fixed ? fixed-width -or proportional ? horizontal or vertical ? etcÂ…)
  • - -
  • -the number of glyphs, charmaps and eventually fixed character sizes (for -bitmap formats) found in the font face.
  • - -
  • -for scalable formats, some important metrics like the ascender, descender, -global font bounding box, maximum advance width, etc.. expressed in notional -font/grid units (as well as the number of units on the EM grid).
  • -
-A face is created from a resource object, with the FT_New_Face -API. Each driver contains a list of opened face objects for the resources -it manages. When a driver is removed or destroyed, all its child faces -are discarded automatically with it.
- -

-2. Size objects :

- -
Size objects are used to model a given character dimension -for a given device resolution (which really means a given character pixel -dimensions). -

Each size object is created from a parent face object. The object can -be reset to new dimensions at any time. Each face object holds a list of -all its child sizes, these are destroyed automatically when the face object -is discarded. -

The metrics contains metrics, expressed in pixels, for the ascender, -descender, maximum advance width, etc.. -
 

- -

-3. Glyph Slot objects :

- -
A glyph slot is a container where one can load individual glyphs, -be they in vector of bitmap format. Each slot also contains metrics for -the glyph it contains. -

Each face object contains one or more glyph slot object : the first -glyph slot is created automatically with its parent face, and it is possible -to add new glyph slots (this is rarely used outside of debugging purposes). -
 

- -

-4. CharMap objects :

- -
A charmap object is a sort of dictionary whose task is to translate -character codes in a given character encoding (like ShiftJIS, Unicode, -ANSI, etc..) into glyph indexes in a given font face. -

A face object contains one or more charmap objects. All charmap objects -are created when the parent face is created, though they're not directly -visible to client applications (rather, they can be enumerated through -FT_Get_First_CharMap and FT_Get_Next_CharMap, or more simply picked adequately -with FT_Find_CharMap for a set of given encodings). -
 

- -

-5. Diagram

- -
The following diagram illustrates the relationships between -font objects : -
-

- -

Which can be read as : -
  -

    -
  • -each resource may have zero or more child face objects "opened" for it. -The number of faces is bounded by the number of font faces within the font -resource.
  • -
- -
    -
  • -each driver holds a list of all the faces opened for the resources it manages. -When the driver is removed, its child faces are discarded automatically.
  • -
- -
    -
  • -each face object has one single parent resource, and one single driver.
  • -
- -
    -
  • -each face has one or more charmaps, and one or more glyph slots
  • -
- -
    -
  • -each face holds a list of zero or more child size objects
  • -
- -
    -
  • -each charmap, glyph slot and size is related to one given parent face. -These objects are destroyed automatically when the parent face is discarded.
  • -
-
-
- -


-


-

-V. Driver Interface :

- -
A font driver is added to a given library object through the -FT_Add_Driver -API. This function receives a structure known as a FT_DriverInterface, -which describes the driver's basic properties. -

The FT_DriverInterface contains a set of function pointers -used for the base FreeType functionalities. However, each driver can also -provide a font-format-specific extended interface to allow client applications -to use more advanced features. -
  -

-1. Common Interface

- -
The structure of FT_DriverInterface is rather simple, -and defined in "base/ftdriver.h". It must be well known by any -developer who wants to write a new driver for the engine. We advise reading -the FreeType Driver HowTo as well as the source code of existing -drivers. Source comments.
- -

-2. Driver-specific extensions

- -
The field of the FT_DriverInterface structure is a -typeless pointer to a format-specific interface. This extended interface -is usually a structure containing function pointers as well as other kind -of information related to the driver. -

It is assumed that client applications that wish to use the driver-specific -extensions are able to #include the relevant header files to understand -the format-specific interface structure.

-
- -
-

-VI. Configuration:

- -
This section relates to the configuration of the FreeType library. -By configuration, we mean selection of build options as well as the choice -of font drivers to be used for each new library object. -
  -

-1. Configuration files :

- -
A single file is used to configure the FreeType base engine. -As it is considered system-specific, it is located in the architecture -directories of the library, under the name "arch/<system>/ftconfig.h". -Note that the same directory should also contain a platform-specific implementation -of "ftsys.c". -

The configuration files is a simple C header which is included by the -engine's sources during compilation. It is not included in "freetype.h", -and hence doesn't need to be copied when installing the FreeType headers -on your system. -

It is made of a series of #define or #undef statements, which are used -to select or turn off a specific option. Each option is documented with -heavy comments, and some of them are explained below.

- -

-2. Building and Makefiles :

- -
FreeType 2.0 is more complex than its 1.x release. In order -to facilitate maintenance, as well as ease considerably the writing of -new font drivers, only GNU Make is supported with FreeType 2.0. -However, it is possible to use any compiler, as well as any object or library -prefix (.o, .obj, .a, .lib etc..) with them. -

To build FreeType 2.0, one has to be in the library directory, then -invoke its platform-specific makefile. For a Unix system, this would be -: -

-
% cd freetype2/lib -
% make -f arch/unix/Makefile -

where 'make' is really GNU Make !

-
-The system-specific Makefile located in 'arch/<system>' -is a tiny file used to define several variables. It then includes the file -freetype2/lib/Makefile.lib, -which contains all the gory details about library compilation. The system-specific -Makefile can be very easily modified to accomodate a new compiler/platform -(see the comments within one of these files). -

Each font driver is located in a directory like "freetype2/lib/drivers/<formatdir>". -For example, the TrueType driver is located in "drivers/truetype". -Each driver directory must contain a Makefile which will be included -by Makefile.lib. The former is used to define and build driver -object files. -
  -


-

-

-
- -

-3. Make options :

- -
The base layer, as well as each font driver, are made up of -several C sources. Traditionally, one compiles each source (i.e. '.c' -file) into an object ('.o' or '.obj') file, and all of -them are grouped into a library file (i.e. '.a' or '.lib'). -

By default, FreeType takes a slightly different approach when it comes -to compiling each part of the engine. Usually, a single tiny source is -compiled, which includes all other component sources. This results in a -single object files, with the benefits or reduced code size, usually better -compilation as well as a drastic reduction of the number of symbols exported -by the library. Of course, it is made possible through the use of specific -declaration macros in the FreeType source (see the definition of LOCAL_DEF -and LOCAL_FUNC in ftconfig.h for details). -

For a concrete example, see the source code in "base/ftbase.c" -which generates the whole base layer in a single object file. The same -build process is applied to font drivers, in order to generate one single -object file per given font format (e.g. truetype.o, type1.o, -etc..). -

Compiling the library and drivers in "normal" mode is possible, through -the use of the 'multi' target (which really means « multiple -objects »). For example, calling : -

% make -f arch/ansi/Makefile multi
-Will build the FreeType library by compiling each source file to an individual -object, then linking them together. You'll notice that the library is significantly -bigger in this case. Creating a shared dll from a 'multi' build is certainly -a very poor idea, as this will export a huge quantity of symbols that aren't -useful to any client application.
- -

-4. Adding a driver at compile time

- -
A driver can be included very easily in the build process by -including its Makefile in Makefile.lib. For example, -the TrueType driver is simply included with the following lines (see Makefile.lib): -
# TrueType driver rules -
# -
include $(DRIVERS_DIR)/truetype/Makefile
- -


Where DRIVERS_DIR really is "freetype2/lib/drivers", -though this can be redefined. You can, of course specify a different path -if you want to place your driver sources in another location. -

Note that this only adds the driver's object files to the generated -library file. A few more steps are needed to make your FT_Library -objects use the driver. They consist in modifying the file "base/ftinit.c", -whose sole purpose is to define the set of driver objects that are to be -created with each new library object. -
 

- -

-5. Adding a driver at run time

- -
New driver objects can be added at run-time through the FT_Add_Driver -API. This function takes a handle to an existing library object, as well -as a pointer to a given driver interface. This interface is used to create -a new driver object and register it within the library. -

Similarly, a single driver can be removed from a library anytime through -FT_Remove_Driver. -This will automatically discard the resources and face objects managed -by the driver.

- -

-6. Custom library objects :

- -
Finally, it is possible to build custom library objects. You -need to pass a handle to a valid FT_System object to the FT_Build_Library -API. The function will return a handle to the new fresh library object. -Note that the library has no registered drivers after the call, developers -have to add them by hand with FT_Add_Driver. -

It is thus possible to create two distinct library objects with distinct -FT_System -implementations in the same session, which can be useful for debugging -purpose.

- -
 
- - - diff --git a/subsys/win32k/freetype/docs/design/io-frames.html b/subsys/win32k/freetype/docs/design/io-frames.html deleted file mode 100644 index a5c6de7..0000000 --- a/subsys/win32k/freetype/docs/design/io-frames.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - FreeType 2 Internals - I/O Frames - - - - -

- FreeType 2.0 I/O Frames -

- -

- © 2000 David Turner - (david@freetype.org)
- © 2000 The FreeType Development Team - (www.freetype.org) -

- -
- - -
- -
- -

- Introduction -

- -

This document explains the concept of I/O frames as used in the - FreeType 2 source code. It also enumerates the various functions and - macros that can be used to read them.

- -

It is targeted to FreeType hackers, or more simply to developers who - would like a better understanding of the library's source code.

- -
- -

- I. What frames are -

- -

Simply speaking, a frame is an array of bytes in a font file that is - `preloaded' into memory in order to be rapidly parsed. Frames are useful - to ensure that every `load' is checked against end-of-file overruns, and - provides nice functions to extract data in a variety of distinct - formats.

- -

But an example is certainly more meaningful than anything else. The - following code

- - -
-    error = read_short( stream, &str.value1 );
-    if ( error ) goto ...
-
-    error = read_ulong( stream, &str.value2 );
-    if ( error ) goto ...
-
-    error = read_ulong( stream, &str.value3 );
-    if ( error ) goto ...
-
- -

can easily be replaced with

- - -
-    error = FT_Access_Frame( stream, 2 + 4 + 4 );
-    if ( error ) goto ...
-
-    str.value1 = FT_Get_Short( stream );
-    str.value2 = FT_Get_ULong( stream );
-    str.value3 = FT_Get_ULong( stream );
-
-    FT_Forget_Frame( stream );
-
- -

Here, the call to FT_Access_Frame() will

- -
    -
  • -

    Ensure that there are at least 2+4+4=10 bytes left in the - stream.

    -
  • -
  • -

    `Preload' (for disk-based streams) 10 bytes from the current - stream position.

    -
  • -
  • -

    Set the frame `cursor' to the first byte in the frame.

    -
  • -
- -

Each FT_Get_Short() or FT_Get_ULong() call - will read a big-endian integer from the stream (2 bytes for - FT_Get_Short(), 4 bytes for FT_Get_ULong) - and advance the frame cursor accordingly.

- -

FT_Forget_Frame() `releases' the frame from memory.

- -

There are several advantages to using frames:

- -
    -
  • -

    Single-check when loading tables.

    -
  • -
  • -

    Making code clearer by providing simple parsing functions - while keeping code safe from file over-runs and invalid - offsets.

    -
  • -
- -
- -

- II. Accessing and reading a frame with macros -

- -

By convention in the FreeType source code, macros are able to use two - implicit variables named error and stream. This is - useful because these two variables are extremely often used in the - library, and doing this only reduces our typing requirements and make the - source code much clearer.

- -

Note that error must be a local variable of type - FT_Error, while stream must be a local variable or - argument of type FT_Stream.

- -

The macro used to access a frame is ACCESS_Frame(_size_), it will - translate to

- - -
-    ( error = FT_Access_Frame( stream, _size_ ) )
-        != FT_Err_Ok
-
- -

Similarly, the macro FORGET_Frame() translates to

- - -
-    FT_Forget_Frame( stream )
-
- -

Extracting integers can be performed with the GET_xxx() - macros, like

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Macro name - - Translation - - Description -
- GET_Byte() - - FT_Get_Byte(stream) - -

Reads an 8-bit unsigned byte.

-
- GET_Char() - - (FT_Char)
- FT_Get_Byte(stream)
-
-

Reads an 8-bit signed byte.

-
- GET_Short() - - FT_Get_Short(stream) - - Reads a 16-bit signed big-endian integer. -
- GET_UShort() - - (FT_UShort)
- FT_Get_Short(stream)
-
- Reads a 16-bit unsigned big-endian integer. -
- GET_Offset() - - FT_Get_Offset(stream) - - Reads a 24-bit signed big-endian integer. -
- GET_UOffset() - - (FT_UOffset)
- FT_Get_Offset(stream)
-
- Reads a 24-bit unsigned big-endian integer. -
- GET_Long() - - FT_Get_Long(stream) - - Reads a 32-bit signed big-endian integer. -
- GET_ULong() - - (FT_ULong)
- FT_Get_Long(stream)
-
- Reads a 32-bit unsigned big-endian integer. -
- -

(Note that an Offset is an integer stored with 3 bytes on - the file.)

- -

All this means that the following code

- - -
-    error = FT_Access_Frame( stream, 2 + 4 + 4 );
-    if ( error ) goto ...
-
-    str.value1 = FT_Get_Short( stream );
-    str.value2 = FT_Get_ULong( stream );
-    str.value3 = FT_Get_ULong( stream );
-
-    FT_Forget_Frame( stream );
-
- -

can be simplified with macros:

- - -
-    if ( ACCESS_Frame( 2 +4 + 4 ) ) goto ...
-
-    str.value1 = GET_Short();
-    str.value2 = GET_ULong();
-    str.value3 = GET_ULong();
-
-    FORGET_Frame();
-
- -

Which is clearer. Notice that error and stream - must be defined locally though for this code to work!

- -
- -

- III. Alternatives -

- -

It is sometimes useful to read small integers from a font file without - using a frame. Some functions have been introduced in FreeType 2 to - do just that, and they are of the form FT_Read_xxxx.

- -

For example, FT_Read_Short(stream, - &error) reads and returns a 2-byte big-endian integer from a - stream, and places an error code in the error - variable.

- -

Thus, reading a single big-endian integer is shorter than using a frame - for it.

- -

Note that there are also macros READ_xxx() which translate to

- - -
-    FT_Read_xxx( stream, &error ), error != FT_Err_Ok
-
- -

and can be used as in

- - -
-    if ( READ_UShort( variable1 ) ||
-         READ_ULong ( variable2 ) )
-      goto Fail;
-
- -

if error and stream are already defined - locally.

- -
-
- - - diff --git a/subsys/win32k/freetype/docs/design/library-compilation.png b/subsys/win32k/freetype/docs/design/library-compilation.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/library-compilation.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/logo1.png b/subsys/win32k/freetype/docs/design/logo1.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/logo1.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/objects_diagram.png b/subsys/win32k/freetype/docs/design/objects_diagram.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/objects_diagram.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/objects_diagram2.png b/subsys/win32k/freetype/docs/design/objects_diagram2.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/objects_diagram2.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/platform-detection.png b/subsys/win32k/freetype/docs/design/platform-detection.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/design/platform-detection.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/design/system-interface.html b/subsys/win32k/freetype/docs/design/system-interface.html deleted file mode 100644 index c505bbe..0000000 --- a/subsys/win32k/freetype/docs/design/system-interface.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - - FreeType 2 Internals - - - - - -
-

-FreeType 2.0 System Interface

- -
-

-© 2000 David Turner (david@freetype.org)
-© 2000 The FreeType Development Team (devel@freetype.org)

- -


-


-
  -

Introduction:

-
    - This document explains how the FreeType 2 library performs the low-level and - system-specific operations of memory management and i/o access. It is targetted - to FreeType hackers, porters and "advanced" developers who want special - features like providing their own memory manager or streams. -

    - Note that the only system-specific part of the library is a file - named "ftsystem.c", normally located in the directory - "freetype2/config/<system>" where <system> designates - your platform (e.g. "config/ansi/ftsystem.c" or - "config/unix/ftsystem.c"). -

    -

- -

-


-

- -

I. Memory Management

-
    - Memory allocation and releases are performed through a FT_Memory object in - FreeType. A FT_Memory is nothing more than a table of functions plus - an arbitrary user data field. It is defined in the file - "freetype2/include/ftsystem.h" and has the following structure: -

    -

      - typedef struct
      - { -
        - -
        void* user // a user-defined pointer. This is zero by default -
        void* (*alloc)( FT_System, int) // a function used to allocate a new block -
        void* (*realloc)( FT_System, int, int, void* ) // a function used to reallocate a given block -
        void (*free)( FT_System, void*) // a function used to release a given block -
        -
      - } FT_MemoryRec, *FT_Memory;
      -
    -

    - You'll notice that:

    -

      -
    • The FT_Memory type is really a pointer to a FT_MemoryRec. - This is a normal convention for the FreeType code. -
    • The realloc takes two integer arguments. The first one is the - current block size, the second one its new size. -
    -

    - - All current implementations of "ftsystem.c" provide a very simple - implementation of the FT_Memory interface by calling directly the - standard C alloc, realloc and free. -

    - The FreeType source code never invokes directly the function pointers. Rather, - it calls FT_Alloc, FT_Realloc and FT_Free functions - which are defined in "freetype2/src/base/ftobjs.c". These will not be - discussed here. -

    - If you want to use your own memory allocator rather than the one provided - by your build of FreeType, follow these simple steps:

    -

      -
    1. Create your own FT_Memory object, with pointers that map to - your own memory management routines (beware function signatures though). -

      -

    2. Call FT_Build_Library(memory,&library). This will create a new - FT_Library object that uses your own FT_Memory exclusively. - Note however that this library has no font drivers loaded in !! -

      -

    3. Load the default font drivers into the new library, either by - calling FT_Default_Drivers(library), or by adding them manually - through repeated calls to FT_Add_Driver(library,&driver_interface) -

      -

    - This will replace the FT_Init_FreeType(&library) call that an application - must do to initialise one library instance. -

    - Notice that you don't need to recompile FreeType 2 to use your own memory - manager !!. -

    -

- -

-


-

- -

II. Streams

-
    -

    1. Basic Stream Structure

    -

    - A stream models the array of bytes found in a font file. FreeType 2 separates - streams into two families :

    -

      -
    • memory-based streams:
      - when the stream's content is entirely found in memory. This is the - case for ROM font files, or memory-mapped files. -

      -

    • disk-based streams:
      - when the stream isn't directly accessible in memory. This is the - case for local or remote files. -

      -

    -

    - Note that a stream's nature only determines how FreeType accesses its content, not - the way it is effectively stored. For example, in the case of a compressed font file, - one implementation may choose to uncompress the font in memory, then provide a memory - based stream to access it. Another one might chose a disk based stream to perform - on-the-fly decompression of the font data. Similarly, the font file can be stored - on a local disk, or obtained from a network. This will be completely transparent to - FreeType. -

    - The stream structure is: -

    -

      - typedef struct
      - {
      -
        -
        char* base for memory-based streams, the address - of its first byte. - -
        ulong size the stream's size in bytes. - -
        ulong pos the current stream position in the file - -
        descriptor a union field used to hold either an - integer file descriptor or pointer. - This field is not used by FreeType - itself, but is left to implementations - of "ftsystem" -
        pathname a union field that can hold either an - integer or pointer. It is not used by - FreeType itself, but is left to - implementations. These can put the - file pathname's during debugging for - example. - -
        read a pointer to a function used to seek the - stream and/or read a run of bytes from it. - -
        close a pointer to a function called when the - stream is closed. - -
        memory a FT_Memory object, which is used - to allocate frames for disk-based streams. - This field is set and used by FreeType. - -
        cursor a pointer in memory used when accessing - frames. This is set and used by FreeType. - -
        limit a pointer in memory used when accessing - frames. This is set and used by FreeType. -
      - } FT_StreamRec, *FT_Stream -
    -

    - - The following important things must be noticed here:

    -

      -
    • The FT_Stream type is really a pointer to a FT_StreamRec. - This is a normal convention for the FreeType source. -

      - -

    • When the read field is non NULL, the stream is considered to be - disk-based. Otherwise, the stream is memory-based, and the base - field must be set by "ftsystem.c" when the stream is - created. -

      - -

    • The base field must be set to 0 when a disk-based stream is created. - However, this field will later be set and used by the FreeType library when - accessing frames of bytes within the font file (of course, this doesn't - happen with memory-based streams). -
    - -

    2. Stream lifecyles

    -

    - Each FT_Face needs its own stream to access font data. The most common - way to create a new FT_Stream object is to call the function - FT_New_Face. This function takes a file pathname argument that - is used to create a new stream object. -

    - This is possible because each implementation of "ftsystem.c" provides - a function called FT_New_Stream which takes a file pathname and a - FT_Stream pointer as an argument. The function simply opens the file - and initialises the stream structure accordingly. It is called by FT_New_Face - to create the face's stream object. -

    - A stream is only closed when the face is destroyed through FT_Done_Face. - Its close field function will then be called. Note that the function should - never destroy the FT_Stream. -

    - - -

    3. Using your own streams

    -

    - There are cases where it is interesting to provide your own stream to create - a new face object, rather than rely on the default implementation. For example, - a filepathname, which is a C string, might not be useful on a system where files - are named with a UTF-16 string or via an i-node number of memory address (for ROM files). -

    - For this purpose, the FT_Open_Face is defined. It simply takes a - FT_Stream pointer as its second argument, instead of a file pathname (the - stream must be allocated and initialised by you, so be careful). -

    - Actually, the only thing that FT_New_Face does is create a new stream - through FT_New_Stream, then call FT_Open_Face to create the - face with it. -

    - Note also that you can use the function FT_New_Memory_Face to create - a new font face for a memory-based font file, whose address and size can be passed - as arguments. The function automatically creates the corresponding memory-based - stream and use it to create the face. -

    - -

- - -

-


-

- -

III. Thread synchronisation

-
    - The FreeType library uses no static data. It can be used concurrently by two - thread as long as each one uses its own FT_Library instance. Otherwise, - one can very simply synchronize access to a single library instance by using a - mutex to protect each call to one of FreeType's API functions. -

    -

- - diff --git a/subsys/win32k/freetype/docs/docmaker.py b/subsys/win32k/freetype/docs/docmaker.py deleted file mode 100644 index 5a6ea0e..0000000 --- a/subsys/win32k/freetype/docs/docmaker.py +++ /dev/null @@ -1,516 +0,0 @@ -#!/usr/bin/env python -# -# DocMaker is a very simple program used to generate HTML documentation -# from the source files of the FreeType packages. -# - -import fileinput, sys, string - -# This function is used to parse a source file, and extract comment blocks -# from it. The following comment block formats are recognized : -# -# /************************** -# * -# * FORMAT1 -# * -# * -# * -# * -# *************************/ -# -# /**************************/ -# /* */ -# /* FORMAT2 */ -# /* */ -# /* */ -# /* */ -# /* */ -# -# /**************************/ -# /* */ -# /* FORMAT3 */ -# /* */ -# /* */ -# /* */ -# /* */ -# /**************************/ -# -# Each block is modeled as a simple list of text strings -# The function returns a list of blocks, i.e. a list of strings lists -# - -def make_block_list(): - """parse a file and extract comments blocks from it""" - - list = [] - block = [] - format = 0 - - for line in fileinput.input(): - - line = string.strip(line) - l = len(line) - - if format == 0: - if l > 3 and line[0:3] == '/**': - i = 3 - while (i < l) and (line[i] == '*'): - i = i+1 - - if i == l: - # this is '/**' followed by any number of '*', the - # beginning of a Format 1 block - # - block = []; - format = 1; - - elif (i == l-1) and (line[i] == '/'): - # this is '/**' followed by any number of '*', followed - # by a '/', i.e. the beginning of a Format 2 or 3 block - # - block = []; - format = 2; - - ############################################################## - # - # FORMAT 1 - # - elif format == 1: - - # if the line doesn't begin with a "*", something went - # wrong, and we must exit, and forget the current block.. - if (l == 0) or (line[0] != '*'): - block = [] - format = 0 - - # otherwise, we test for an end of block, which is an - # arbitrary number of '*', followed by '/' - else: - i = 1 - while (i < l) and (line[i] == '*'): - i = i+1 - - # test for the end of the block - if (i < l) and (line[i] == '/'): - if block != []: list.append( block ) - format = 0 - block = [] - - else: - block.append( line[1:] ) - - ############################################################## - # - # FORMAT 2 - # - elif format == 2: - - # if the line doesn't begin with '/*' and end with '*/', - # this is the end of the format 2 format.. - if (l < 4 ) or (line[:2] != '/*') or (line[-2:] != '*/'): - if block != []: list.append(block) - block = [] - format = 0 - continue - - # remove the start and end comment delimiters, then right-strip - # the line - line = string.rstrip(line[2:-2]) - - # check for end of a format2 block, i.e. a run of '*' - if string.count(line,'*') == l-4: - if block != []: list.append(block) - block = [] - format = 0 - else: - # otherwise, add the line to the current block - block.append(line) - - return list - - -# This function is only used for debugging -# -def dump_block_list( list ): - """dump a comment block list""" - for block in list: - print "----------------------------------------" - for line in block: - print line - print "---------the end-----------------------" - - - - - -###################################################################################### -# -# -# The DocParagraph is used to store either simple text paragraph or -# source code lines -# -# -# If the paragraph contains source code (use code=1 when initializing the -# object), self.lines is a list of source code strings -# -# Otherwise, self.lines is simply a list of words for the paragraph -# -class DocParagraph: - - def __init__(self,code=0,margin=0): - self.lines = [] - self.code = code - self.margin = margin - - def add(self,line): - - if self.code==0: - # get rid of unwanted spaces in the paragraph - self.lines.extend( string.split(line) ) - - else: - # remove margin whitespace - if string.strip( line[:self.margin] ) == "": line = line[self.margin:] - self.lines.append(line) - - - def dump(self): - - max_width = 50 - - if self.code == 0: - cursor = 0 - line = "" - - for word in self.lines: - - if cursor+len(word)+1 > max_width: - print line - cursor = 0 - line = "" - - line = line + word + " " - cursor = cursor + len(word) + 1 - - if cursor > 0: - print line - - else: - for line in self.lines: - print "--" + line - - print "" - - -###################################################################################### -# -# -# The DocContent class is used to store the content of a given marker -# Each DocContent can have its own text, plus a list of fields. Each field -# has its own text too -# -# Hence, the following lines : -# -# """ -# Some arbitraty text: -# -# fieldone :: some arbitraty text for this field, -# note that the text stretches to several lines -# -# fieldtwo :: some other text -# -# """ -# -# will be stored as (each text is a list of string: -# -# self.fields = [ "", "fieldone", "fieldtwo" ] -# self.texts = [ -# [ "some arbitraty text for this field," , -# "note that the text stretches to several lines" ], -# -# [ "some other text" ] -# ] -# -# -class DocContent: - - def __init__(self, paragraph_lines=[]): - - self.fields = [] - self.texts = [] - - code_mode = 0 - code_margin = 0 - - field = "" - text = [] - paragraph = None - - for aline in paragraph_lines: - - if code_mode == 0: - line = string.lstrip(aline) - l = len(line) - margin = len(aline) - l - - # if the line is empty, this is the end of the current - # paragraph - if line == "": - if paragraph: - text.append(paragraph) - paragraph = None - continue - - # test for the beginning of a code block, i.e.'{' is the first - # and only character on the line.. - # - if line == '{': - code_mode = 1 - code_margin = margin - if paragraph: - text.append(paragraph) - paragraph = DocParagraph( 1, margin ) - continue - - words = string.split(line) - - # test for a field delimiter on the start of the line, i.e. - # the oken `::' - # - if len(words) >= 2 and words[1] == "::": - if paragraph: - text.append(paragraph) - paragraph = None - - self.fields.append(field) - self.texts.append(text) - - field = words[0] - text = [] - words = words[2:] - - if len(words) > 0: - line = string.join(words) - if not paragraph: - paragraph = DocParagraph() - paragraph.add( line ) - - else: - line = aline - - # the code block ends with a line that has a single '}' on it - if line == " "*code_margin+'}': - text.append(paragraph) - paragraph = None - code_mode = 0 - code_margin = 0 - - # otherwise, add the line to the current paragraph - else: - paragraph.add(line) - - if paragraph: - text.append(paragraph) - - self.fields.append( field ) - self.texts.append( text ) - - - - def dump(self): - for i in range(len(self.fields)): - field = self.fields[i] - if field: print "" - - for paras in self.texts[i]: - paras.dump() - - if field: print " " - - def dump_html(self): - n = len(self.fields) - for i in range(n): - field = self.fields[i] - if field==[]: - print "

" - for paras in self.texts[i]: - print "

" - paras.dump() - print "

" - else: - if i==1: - print "" - if n > 1: - print "
" - else: - print "
" - - print ""+field+"" - - for paras in self.texts[i]: - print "

" - paras.dump() - print "

" - - print "
" - - -###################################################################################### -# -# -# The DocBlock class is used to store a given comment block. It contains -# a list of markers, as well as a list of contents for each marker. -# -# -class DocBlock: - - def __init__(self, block_line_list=[]): - self.markers = [] - self.contents = [] - - marker = "" - content = [] - alphanum = string.letters + string.digits + "_" - - for line in block_line_list: - line2 = string.lstrip(line) - l = len(line2) - margin = len(line) - l - - if l > 3 and line2[0] == '<': - i = 1 - while i < l and line2[i] in alphanum: i = i+1 - if i < l and line2[i] == '>': - if marker or content: - self.add( marker, content ) - marker = line2[1:i] - content = [] - line2 = string.lstrip(line2[i+1:]) - l = len(line2) - line = " "*margin + line2 - - content.append(line) - - if marker or content: - self.add( marker, content ) - - - def add( self, marker, lines ): - - # remove the first and last empty lines from the content list - l = len(lines) - if l > 0: - i = 0 - while l > 0 and string.strip(lines[l-1]) == "": l = l-1 - while i < l and string.strip(lines[i]) == "": i = i+1 - lines = lines[i:l] - l = len(lines) - - # add a new marker only if its marker and its content list aren't empty - if l > 0 and marker: - self.markers.append(marker) - self.contents.append(lines) - - def dump( self ): - for i in range( len(self.markers) ): - print "["+self.markers[i]+"]" - for line in self.contents[i]: - print "-- "+line - - def doc_contents(self): - contents = [] - for item in self.contents: - contents.append( DocContent(item) ) - return contents - - -def dump_doc_blocks( block_list ): - for block in block_list: - docblock = DocBlock(block) - docblock.dump() - print "<<------------------->>" - - -# -# -# -def dump_single_content( block_list ): - - block = block_list[0] - docblock = DocBlock(block) - - print "" - for i in range(len(docblock.markers)): - marker = docblock.markers[i] - contents = docblock.contents[i] - - print "" - doccontent = DocContent( contents ) - - doccontent.dump() - - print "" - - print "" - -def dump_doc_contents( block_list ): - - for block in block_list: - docblock = DocBlock(block) - print "" - - for i in range(len(docblock.markers)): - print "" - content = DocContent( docblock.contents[i] ) - content.dump() - print "" - print "" - -def dump_html_1( block_list ): - - print "" - types = [ 'Type', 'Struct', 'FuncType', 'Function', 'Constant', 'Enumeration' ] - for block in block_list: - docblock = DocBlock(block) - print "
" - for i in range(len(docblock.markers)): - marker = docblock.markers[i] - content = docblock.contents[i] - dcontent = DocContent( content ) - - if marker=="Description": - print "

    " - dcontent.dump() - print "

" - - elif marker in types: - print "

"+content[0]+"

" - else: - print "

"+marker+"

" - print "

    " - dcontent.dump_html() - print "

" - - print "" - - print "
" - - -def main(argv): - """main program loop""" - print "extracting comment blocks from sources .." - list = make_block_list() - -# dump_block_list( list ) - -# dump_doc_blocks( list ) - -# print "dumping block contents .." -# dump_doc_contents(list) - - dump_html_1(list) - -# dump_single_content(list) - -# If called from the command line -if __name__=='__main__': main(sys.argv) diff --git a/subsys/win32k/freetype/docs/freetype2.html b/subsys/win32k/freetype/docs/freetype2.html deleted file mode 100644 index 3cc94c9..0000000 --- a/subsys/win32k/freetype/docs/freetype2.html +++ /dev/null @@ -1,352 +0,0 @@ - - -FreeType 2 Introduction - - - - - - - -http://www.freetype.org

- -

- - The FreeType Project -

An Introduction to FreeType 2

-
- -
-

- -DOCUMENT INDEX:
-

- - -


- -
-

What is FreeType 2 ?

-
- -

The FreeType project is a team of volunteers who develop free, portable -and high-quality software solutions for digital typography. We specifically -target embedded systems and focus on bringing small, efficient and -ubiquitous products.

- -

the FreeType 2 library is our new software font engine. It has been - designed to provide the following important features:

- -
    -
  • - A universal and simple API to manage font files:
    -

      -

      The FreeType 2 API is simple and easy to use. It supports both - bitmapped and scalable fonts and is well-suited to manage font - files of all formats. Unlike other font libraries, FreeType 2 - returns and manages outline font data (images & metrics).

      -
    -

  • - -
  • - Support for several font formats through loadable modules:
    -

      -

      FreeType 2 uses "font drivers". Each driver is a loadable - module used to support one specific font format. Each driver can also - provide specific extensions used to access format-specific features of - the font.

      -
    -

  • - - -
  • - High-quality anti-aliasing:
    -

      -

      FreeType 2 produces etremely smooth outlines at small sizes, with its new - anti-aliasing renderer, which produces bitmaps with 256-levels of gray. - It uses a new algorithm that has been specifically designed to render - small complex shapes (like glyphs) at high speed. Indeed, it's even - faster than the monochrome renderer for small character sizes (under - 20 pixels) !! -

      -
    - - -
  • High portability & performance:
    -
      -

      The FreeType 2 source code is written in ANSI C and runs on any - platform with a compliant compiler. Client applications can - provide their own memory manager or input stream to the library - (which means that font files can come from any place: disk, - memory, compressed file, network, etc..). -

      -
    - -
- -

Note that the beta of FreeType 2 is available now. For more - info, check our Download page or see the source - and its diffs through our CVS Web interface. -

- - -
- -
-

Features

-
- -

Supported font formats

- -

FreeType 2 readily supports the following font formats:

- -
    -
  • TrueType files (.ttf) and collections (.ttc)
  • -
  • Type 1 font files both in ASCII (.pfa) or binary (.pfb) format
  • -
  • Type 1 Multiple Master fonts. The FreeType 2 API also provides - routines to manage design instances easily
  • -
  • Type 1 CID-keyed fonts
  • -
  • OpenType/CFF (.otf) fonts
  • -
  • CFF/Type 2 fonts
  • -
  • Adobe CEF fonts (.cef), used to embed fonts in SVG documents - with the Adobe SVG viewer plugin.
  • -
  • Windows FNT/FON bitmap fonts
  • -
- -

Note that Apple's TrueType GX fonts are supported as normal TTFs, - (the advanced tables are ignored).

- -

Besides, it's possible to add support for new font formats by providing - a specific font driver module. Modules can be added either at - build time (when recompiling the library), or at run-time; - this allows, for example, applications to register their own - font driver to support program-specific formats.

- - -

Patent-free automatic hinter

- -

TrueType fonts are normally renderered (hinted) with the help of a - specific bytecode where the behaviour of a few opcodes is patented by - Apple. We're currently in contact with Apple to discuss the importance - of such patents and their use in open source projects like FreeType. -

- -

In the meantime, we have developped our own alternative technology that - is capable of automatically hinting scalable glyph images. It is - now part of the FreeType 2 source tree as the "autohint" module, - and is used to hint glyphs when the bytecode interpreter is disabled - (through a configuration macro when building the engine). Note that - the auto-hinter is also used to handle glyphs in other formats like - CFF and Type 1.

- -

The auto-hinter provides pretty good results (in some cases, it even - significantly improves the output of poorly hinted fonts) but we'll - continue to improve it with each new release of FreeType to achieve - the highest possible quality.

- - -

Modular design:

- -

The design of FreeType 2 is extremely modular as most features are - supported through optional modules. This means it's easily possible to - only compile the features you need. As each module is between - 10 and 20 Kb in size, it's possible to build a bare-bones - font engine that supports anti-aliasing in about 30 Kb !!

- -

Configuration is performed by modifications of only two header - files (one to select global features, another one to select modules) - and don't need tweaking of source code. Note that it is however - possible to provide your own implementation of certain components.

- -

For example, when building on Unix, the engine will automatically - use memory-mapped files when available on the target platform, - thus significantly increasing font file i/o.

- - -

Due to its very flexible design, it is possible to add, remove and - upgrade modules at run-time.

- - - -

Advanced glyph management

- -

The API comes with a standard extension used to extract individual - glyph images from font files. These images can be bitmaps, scalable - bezier outlines or even anything else. (e.g. bi-color or metafont - glyphs, as long as they're supported by a module).

- -

Each scalable glyph image can be transformed, measured and - rendered into a monochrome or anti-aliased bitmaps easily - through a uniform interface. - - This allows client applications to easily cache glyphs or - perform text rendering effects with minimal difficulty - (look at the FreeType 2 Tutorial to see how to render - rotated text with very few lines of code). -

- - - -

Advanced font access

- -

The FreeType 2 API is useful to retrieve advanced information from - various fonts:

- -
    -
  • vertical metrics are available whenever found in the font file
  • - -
  • kerning distances are available when found in the font file. It - is also possible to "attach" a given additional file to a given - font face. This is useful to load kerning distances from an - .afm file into a Type 1 face for example.
  • - -
  • provides ASCII glyph names whenever available in the font - (TrueType, OpenType, Type1, etc..)
  • - -
  • provides access to important tables for SFNT-based font formats - (i.e. TrueType, OpenType, CEF, etc..), like the name table, - font header, maximum profile, etc...
  • - -
  • automatic synthesis of Unicode-based character maps for - those fonts or formats that do not provide one. This is - extremely useful with Type 1 fonts which are normally - limited to a stupid 256-characters encoding.
  • -
- - -

Simple & clean API

- -

The FreeType 2 high-level API is simple and straightforward, as it - has been specifically designed to make the most commmon font operations - easy

- -

As a comparison, the number of function calls needed to perform a - the tasks of font face creation/opening and glyph loading/rendering - has been reduced by a factor of 4 !!

- -

The API is also independent of any font-format specific issue, though - it provides standard extensions to access format-specific tables and - information. More extensions can also be easily added through new - modules

- - -

Robust & Portable code

- -

Because it is written in industry-standard ANSI C, FreeType 2 compiles - on all platforms with a compliant compiler. Because the default build - only relies on the C library, it is free of any system-specific - dependencies, even if it is possible to "enhance" certain components - by providing a specific implementation.

- -

The code doesn't use global or static variables. Client applications - can provide their own memory manager. Font files can be read from - a disk file, memory, or through a client-provided input stream. This - allows to support compressed font files, remote fonts, fonts embedded - in other streams (e.g. Type42 fonts), etc..

- -

An advanced i/o sub-system is used to optimise file access, as well - as reduce memory usage of the library when the file is memory-based - ( ROM, RAM, memory-mapped ).

- - -

Open Source & Vendor Independence

- -

Finally, FreeType 2 is released under its own BSD-like open source - license, one of the less restricting licenses available, and this - means that:

- -
    -
  • - It can be included in all kinds of products, be they proprietary - or not. -

  • - -
  • - As any module can be added or replaced anytime, any third party - vendor has the ability to provide its own set of modules (under - its own license) in order to support proprietary font formats or - more advanced features (e.g. a new auto-hinter, or a new - anti-aliasing renderer for LCDs or TV screens). -

  • -
- -

One could even imagine an application using the FreeType 2 API with - a "wrapper" module used to access system-specific fonts (like through - the Windows GDI). This would mean native font support with more portable - application code (as simply changing the wrapper module would be required - to port the application to another system).

- -
- -
-

Requirements

-
- -

FreeType 2 is written in ANSI C and should compile with no problems - on a great variety of platforms. We have taken care of removing all - compilation warnings from major compliant compilers. Detailed compilation - instructions are provided in the software archive.

- -

This version of the library has been succesfully compiled and run - under the following systems: Dos, OS/2, Windows, Macintosh, Unix - (including the 64-bits DEC Unix, a.k.a. "True64"). You should not - encounter major problems compiling it on any other kind of platform. - In all cases, contact us if you do.

- -

Note that a small set of demonstration programs is also separately - available. They include a tiny graphics sub-system that is used to - display and show-off the library's capabilities on the following - platforms: X11, MacOS, OS/2 & Windows.

- -

Please visit our - Download section to access the software archives.

- - - -
- -
-

Patents issues

-
- -

The FreeType 2 source code includes a TrueType bytecode interpreter that - is covered by the Apple patents. However, this piece of code is never - compiled by default in this release (unlike in previous betas) making - a default build of the library entirely patent-free !!

- -

Note that in order to compile the interpreter, one needs to define - the configuration macro TT_CONFIG_OPTION_BYTECODE_INTERPRETER configuration - macro in the file "ftoption.h". More details are available in - the software archive. Note that the use of the interpreter is normally - protected by US, UK and French patents. In the event you'd absolutely - need it, you may have to contact - Apple legal department for licensing conditions, depending on your - location and the places you distribute/sell your products.

- -

Please do not ask us any detailed information regarding licensing, as - we're still discussing with Apple this issue, we're unable to inform - the public of what's currently going on..

- -
- -


-

-Back to FreeType homepage

- -

- - diff --git a/subsys/win32k/freetype/docs/ft2faq.html b/subsys/win32k/freetype/docs/ft2faq.html deleted file mode 100644 index 6b9cc9b..0000000 --- a/subsys/win32k/freetype/docs/ft2faq.html +++ /dev/null @@ -1,502 +0,0 @@ - - -FreeType 2 FAQ - - - - - - - -http://www.freetype.org

- -

- - The FreeType Project -

The FreeType 2 FAQ

-
- -
-

- -DOCUMENT INDEX:
-

- - -


- -
-

General questions & answers

-
- - -

I.1. I though the FreeType project was dead. Is this true?

-
    -

    Well, not exactly :-) It's true that the TrueType patents issues - have been less than a graceful event to handle but it didn't not - really killed the project per se, as Apple hasn't made an official - statement yet regarding the use of the patented "technology" in - open source projects (or other products).

    - -

    We have thus continued updating FreeType 1.x, and started developping - FreeType 2 with the idea of providing this time a completely patent - free font engine. However, we largely preferred not to broadly - communicate about it until we've got a satisfying implementation - to show.

    -
- - -
-

I.2. Why did it take so long to release FreeType 2?

-
- - -

I.3. Is FreeType 2 a Unix-only project?

-
- - -

I.4. When will X11/XFree support anti-aliased text?

-
    -

    This question isn't exactly related to FreeType as we have no direct - connection to the XFree people, but we've been asked so frequently - about it that it deserves a prominent place in this FAQ :-)

    - -

    FreeType has been capable of anti-aliasing since version 1.0. The - reason why XFree doesn't support it is directly related to the - limitations of the design and specification of X11. More specifically:

    - -
      -
    • - X11 assumes that all glyph images are monochrome bitmaps, - hence the X font library and server are unable to send anything - else to the X server. -

    • - -
    • - Even if the X font library/server was able to generate anti-aliased - bitmaps (and this has been already done through extensions), the X - rendering model doesn't allow translucent composition of "gray" pixmaps - onto an arbitrary drawable. -

    • -
    - -

    As both the font and rendering models of X11 are limited, it's basically - impossible to draw anti-aliased glyphs without performing huge - hacks within the server.

    - -

    Note that Keith Packard, from XFree fame, has recently started working - on a new rendering model for X11 in order to support new features - (mainly transparency and anti-aliased fonts). This will be provided - through protocol extensions. The question of knowing wether legacy X - applications will be able to display anti-aliased text is still very - uncertain. -

    -
- -
-

I.5. Is FreeType 2 backwards compatible with FreeType 1.x?

-
    -

    Not directly, though we had the project to provide an optional binary - compatibility layer on top of it in order to easily re-link applications - with the new version. However, this idea has been dropped as it is - possible to install and use the two versions independtly on any - system (read: no namespace conflicts).

    - -

    The FreeType 2 API is a lot simpler than the one in 1.x while being - much more powerful. We thus encourage you to adapt your source code - to it as this should not involve much work.

    - -
- -
-

I.6. Can I use FreeType 2 to edit fonts or create new ones?

-
    -

    The answer is a definitive NO, because the library was specifically - designed to read font files with small code size and very - low memory usage.

    - -

    We thus do not plan to support editing or creation in the font - engine in any way, as this would imply a complete rewrite. This - doesn't mean that we won't introduce a font editing/creation library - in the future, as this really depends on how many people are asking - for it (or how much they would be willing to pay for it), as well as - the time of the FreeType developers.

    - -

    Do not expect anything in this direction until we officially announce - something though. There are other axis of development for this project - (like text-layout capabilities, glyph caching, etc..) that may be more - important to us at the moment..

    -
- -
- -
-

Compilation & Configuration

-
- - -

II.1. How do I compile the FreeType 2 library?

-
    -

    The library can be compiled in various ways, and a detailed documentation - is available in the file "freetype2/docs/BUILD". However, we'll - summarize the process to a few cases:

    - -

    a. by using the command-line 2 build system

    - -

    The engine comes with a sophisticated build system that is used - to configure and compile a build of the library. You'll need - GNU Make installed on your platform (NOTE: It will not - work with other Make tools).

    - -

    Basically, you'll need to invoke make a first time in the - top-level FreeType 2 directory in order to setup the build. This will - detect your current platform and choose a configuration sub-makefile to - drive the build. A specific compiler can be selected on some platforms - by providing an additional target. For example, on Win32:

    - -
      -
    • make visualc will select the Visual C++ compiler
    • -
    • make lcc will select the Win32-lcc compiler
    • -
    - -

    Note that on Unix, the first time make is called, a configure script - located in "freetype2/builds/unix" will be run in order to - automatically detect the platform & compiler.

    - -

    A summary will be displayed showing the detected platform and compiler - selected. You'll then be able to start the build by invoking make - a second time. In case of problem, consult the BUILD document.

    - - -

    b. by direct compilation

    - -

    You can also directly compile the library from the command line by - using these simple rules:

    - -
      -
    • - You should place the directories "freetype2/include" and - "freetype2/src" in your include path in order to compile - any component of the library. You can also add the system-specific - build directory (i.e. "builds/system/") in the - case where an alternate implementation of some of the components - is available there (e.g. the memory-mapped i/o implementation - on some Unix systems). -

    • - -
    • - The components of the library are located in sub-directories of - "src", for example: "src/base", - "src/truetype", etc.. -

    • - -
    • - Each component is normally compiled through a single C file that - "wraps" other sources in the component's directory. For example, - your should compile the TrueType font driver by compiling the - file "src/truetype/truetype.c". The list of C files to - compile for a feature-complete build of the library is given in - the BUILD document. -

    • -
    - -

    c. in a graphical IDE

    -
      -

      Well, the process is vastly similar to the one described in b., - except that you need to set the include paths, source code paths, - etc.. in dialog boxes before running the compilation. -

      -
    - -
- -
-

II.2. How do I configure my build of the library?

-
    -

    Each build of the library is configured through two header files - located in "include/freetype/config":

    - -
      -
    • ftoption.h
      - This file contains various configuration macros whose definition - can be toggled on a per-build basis. Each macro is heavily - commented in this file's comment, and we invite you to refer - to it directly.

    • - -
    • ftmodule.h
      - This file contains the list of all the modules that are initially - registered (added) when the function FT_Init_FreeType - is called. See the next answer to know how to change it and - why it may be important.

    • -
    - -

    Alternatively, some specific implementations of some FT2 components - can be provided in a "builds/system/" directory - (e.g. the Unix-specific ftsystem.c that uses memory-mapped - file for i/o).

    -
- -
-

II.3. How do I select the modules I need in my build?

-
    -

    The function FT_Init_FreeType creates a new instance - of the FT2 library and registers a set of "default" modules before - returning to the calling application. Its default implementation - is in the file "src/base/ftinit.c".

    - -

    The list of default modules used by ftinit.c is located in - the configuration file "include/freetype/config/ftmodule.h". - It is normally automatically generated by the build system by - invoking the "make modules" command in the top - level FT2 directory (note: only works with GNU Make, you can - edit the file by hand otherwise). It does so by parsing all - sub-directories of "src" that contain a file named - module.mk.

    - -

    Note that a specific port or project is free to provide its own - implementation of ftinit.c in order to ensure a different - initialisation sequence. For example, one could do something like:

    - -
      -
    • compile each module as a shared library (DLL or .so) with - a common "entry point" to retrieve a pointer to its - module class (there is already some code that allows this - when compiling each module).

    • - -
    • place these modules in a directory like - "/usr/lib/freetype2/modules/"

    • - -
    • provide an implementation of ftinit.c that would - scan the directory for valid modules.

    • -
    - -

    This example only emphasize the flexibility that is left to - developers when building the library.

    - -
- -
-

II.4. How do I compile all FreeType 2 files in a single directory?

-
    -

    Some projects may need, for the sake of simplicity or ease of - building, to compile the FT2 library with all source files - copied to a single directory. This is possible.

    - -

    To do so, you'll need to copy all source files located under - "src" to your own directory (you must retain the - include files in a distinct hierarchy though), then compile - each of the FreeType 2 component with the macro - FT_FLAT_COMPILE. This will change the way - #include works during the build.

    -
- -
- -
-

Using the FreeType 2 library

-
- -
- -
-

The FreeType 2 auto-hinter

-
- - -

IV.1. Under which license is the FreeType 2 auto-hinter released

-
    -

    The auto-hinter was initially designed and implemented under contract - for Catharon Productions, Inc - which gladly accepted to released it under an open-source license - compatible with the FreeType one.

    - -

    This license can be found in "src/autohint/CatharonLicense.txt" - and requires that you cite Catharon Productions in your documentation - (just like you do with FreeType) when using the auto-hinting module.

    - -

    Other than that, you still have the same freedom than with the good old - FreeType license. Enjoy !

    -
- - -

IV.2. How does the auto-hinter works ?

-
    -

    Well, a complete description would be difficult. Have a look at the - dedicated auto-hinter pages on the FreeType - site, as they describe most of its details with graphics and explanations. - You could also look at the source code if you want to :-)

    - -

    To give a few details, the auto-hinter is used to perform grid-fitting - on scalable font formats that use bezier outlines as their primary glyph - image format (this means nearly all scalable font formats today). When - a given font driver doesn't provide its own hinter, the auto-hinter is - used by default. When a format-specific hinter is provided, it is still - possible to use the auto-hinter using the - FT_LOAD_FORCE_AUTOHINT bit flag when calling - FT_Load_Glyph.

    - -

    The auto-hinter currently doesn't use external hints to do its job, - as it automatically computes global metrics (when it "opens" a font - for the first time) and glyph "hints" from their outline. Note that - we plan the ability to specify external hints, given that it is based - on a constraint system. That could be used to support native hints - in Type 1/Type 2 fonts, for example.

    -
- - -

IV.3. Why does the auto-hinter doesn't work correctly with CJK fonts ?

-
    -

    The auto-hinter was first designed to manage and hint latin-based fonts, - as they consist of most of the fonts available today. It doesn't hint - asian fonts, as well as a few other complex scripts, because we didn't - put enough research on the topic yet. Hinting CJK isn't really more - difficult than latin, just different with a set of different constraints - (basically, more distortion of glyphs is acceptable as long as certain - features like triple-stem positions are respected more strictly..).

    - -

    We thus plan to handle such a case rather rapidly.. Please be patient.

    -
- - -
- -
-

Other questions

-
- - -

V.1. What is the anti-aliasing algorithm used by FreeType 2 ?

-
    -

    The algorithm has been specifically designed for FreeType. It is - based on ideas that were originally found in the implementation - of the libArt graphics - library to compute the exact pixel coverage of a vector - image with absolutely now sub-sampling/filtering. -

    - -

    However, these two implementations are radically distinct and use - vastly different models. The FreeType 2 renderer is optimized - specifically for rendering small complex shapes, like glyphs, at - very high speed while using very few memory; while libArt shines - at general shape/polygon processing, especially large ones.

    - -

    The FT2 anti-aliasing renderer is indeed faster than the - monochrome renderer for small character sizes (typically < 20 pixels). - This is explained because the monochrome renderer must perform two - passes on the outline in order to perform drop-out control according - to the TrueType spec (we could drop this requirement later though).

    - -

    We'll try to document its design in a later document, though this is - not a priority for now.

    -
- - -

V.2. When will FreeType 2 support OpenType ?

-
    -

    Well, the engine already reads OpenType/CFF files perfectly. What it - doesn't do is handle "OpenType Layout" tables yet.

    - -

    FreeType 1 comes with a set of extensions that are used to load - and manage OpenType Layout tables. It even has a demonstration program - named "ftstrtto" used to demonstrate its capabilities that - runs pretty smooth.

    - -

    For FreeType 2, we have decided that the layout operations provided - through these tables is better placed in a specific text-layout library, - (many people having asked for such a thing). This new engine would not - depend on FT2 explicitely and will be developed as a separate project. - We plan to announce it in a few weeks with all gory details, - once the definitive 2.0 release of FreeType has been made.

    -
- -
- -


-

-Back to FreeType homepage

- -

- - diff --git a/subsys/win32k/freetype/docs/glnames.py b/subsys/win32k/freetype/docs/glnames.py deleted file mode 100644 index 7b72669..0000000 --- a/subsys/win32k/freetype/docs/glnames.py +++ /dev/null @@ -1,1706 +0,0 @@ -#!/usr/bin/env python -# - -# -# FreeType 2 glyph name builder -# - - -# Copyright 1996-2000 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. - - -"""\ - -usage: %s - - This very simple python script is used to generate the glyph names - tables defined in the PSNames module. - - Its single argument is the name of the header file to be created. -""" - - -import sys, string - - -# This table is used to name the glyph according to the Macintosh -# specification. It is used by the TrueType Postscript names table -# -mac_standard_names = \ -[ - # 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" -] - - -t1_standard_strings = \ -[ - # 0 - ".notdef", "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quoteright", "parenleft", - - # 10 - "parenright", "asterisk", "plus", "comma", "hyphen", - "period", "slash", "zero", "one", "two", - - # 20 - "three", "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", "less", - - # 30 - "equal", "greater", "question", "at", "A", - "B", "C", "D", "E", "F", - - # 40 - "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", - - # 50 - "Q", "R", "S", "T", "U", - "V", "W", "X", "Y", "Z", - - # 60 - "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", - "quoteleft", "a", "b", "c", "d", - - # 70 - "e", "f", "g", "h", "i", - "j", "k", "l", "m", "n", - - # 80 - "o", "p", "q", "r", "s", - "t", "u", "v", "w", "x", - - # 90 - "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", - - # 100 - "yen", "florin", "section", "currency", "quotesingle", - "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", - - # 110 - "fl", "endash", "dagger", "daggerdbl", "periodcenter", - "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", - - # 120 - "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", - "acute", "circumflex", "tilde", "macron", "breve", - - # 130 - "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", - "ogonek", "caron", "emdash", "AE", "ordfeminine", - - # 140 - "Lslash", "Oslash", "OE", "ordmasculine", "ae", - "dotlessi", "Islash", "oslash", "oe", "germandbls", - - # 150 - "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", - - # 160 - "brokenbar", "degree", "thorn", "threequarters", "twosuperior", - "registered", "minus", "eth", "multiply", "threesuperior", - - # 170 - "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", - "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", - - # 180 - "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", - - # 190 - "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", - "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", - - # 200 - "aacute", "acircumflex", "adieresis", "agrave", "aring", - "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", - - # 210 - "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", - - # 220 - "otilde", "scaron", "uacute", "ucircumflex", "udieresis", - "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", - - # 230 - "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", - "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "zerooldstyle", - - # 240 - "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", - "commasuperior", - - # 250 - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", - "bsuperior", - "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", - - # 260 - "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", - "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - - # 270 - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", - "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", - - # 280 - "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", - "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", - - # 290 - "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", - - # 300 - "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", - "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", - "Dieresissmall", - - # 310 - "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", - "questiondownsmall", - - # 320 - "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", - "twothirds", "zerosuperior", "foursuperior", "fivesuperior", - "sixsuperior", - - # 330 - "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", - "oneinferior", - "twoinferior", "threeinferior", "fourinferior", "fiveinferior", - "sixinferior", - - # 340 - "seveninferior", "eightinferior", "nineinferior", "centinferior", - "dollarinferior", - "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", - "Acircumflexsmall", - - # 350 - "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", - "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", - "Igravesmall", - - # 360 - "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", - "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", - - # 370 - "OEsmall", "Oslashsmall", "Ugravesmall", "Uacautesmall", - "Ucircumflexsmall", - "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", - "001.000", - - # 380 - "001.001", "001.002", "001.003", "Black", "Bold", - "Book", "Light", "Medium", "Regular", "Roman", - - # 390 - "Semibold" -] - - -t1_standard_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, - 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, - 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, - - 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, - 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, - 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, - - 148, 149, 0, 0, 0, 0 -] - - -t1_expert_encoding = \ -[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 229, 230, 0, 231, 232, 233, 234, - 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, - - 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, - 249, 250, 251, 252, 0, 253, 254, 255, 256, 257, - 0, 0, 0, 258, 0, 0, 259, 260, 261, 262, - 0, 0, 263, 264, 265, 0, 266, 109, 110, 267, - 268, 269, 0, 270, 271, 272, 273, 274, 275, 276, - - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 305, 306, 0, 0, 307, 308, 309, 310, - 311, 0, 312, 0, 0, 312, 0, 0, 314, 315, - 0, 0, 316, 317, 318, 0, 0, 0, 158, 155, - 163, 319, 320, 321, 322, 323, 324, 325, 0, 0, - - 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - - 373, 374, 375, 376, 377, 378 -] - - -# This data has been taken literally from the file `glyphlist.txt', -# version 1.2, 22 Oct 1998. It is available from -# -# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html -# -adobe_glyph_list = """\ -0041;A;LATIN CAPITAL LETTER A -00C6;AE;LATIN CAPITAL LETTER AE -01FC;AEacute;LATIN CAPITAL LETTER AE WITH ACUTE -F7E6;AEsmall;LATIN SMALL CAPITAL LETTER AE -00C1;Aacute;LATIN CAPITAL LETTER A WITH ACUTE -F7E1;Aacutesmall;LATIN SMALL CAPITAL LETTER A WITH ACUTE -0102;Abreve;LATIN CAPITAL LETTER A WITH BREVE -00C2;Acircumflex;LATIN CAPITAL LETTER A WITH CIRCUMFLEX -F7E2;Acircumflexsmall;LATIN SMALL CAPITAL LETTER A WITH CIRCUMFLEX -F6C9;Acute;CAPITAL ACUTE ACCENT -F7B4;Acutesmall;SMALL CAPITAL ACUTE ACCENT -00C4;Adieresis;LATIN CAPITAL LETTER A WITH DIAERESIS -F7E4;Adieresissmall;LATIN SMALL CAPITAL LETTER A WITH DIAERESIS -00C0;Agrave;LATIN CAPITAL LETTER A WITH GRAVE -F7E0;Agravesmall;LATIN SMALL CAPITAL LETTER A WITH GRAVE -0391;Alpha;GREEK CAPITAL LETTER ALPHA -0386;Alphatonos;GREEK CAPITAL LETTER ALPHA WITH TONOS -0100;Amacron;LATIN CAPITAL LETTER A WITH MACRON -0104;Aogonek;LATIN CAPITAL LETTER A WITH OGONEK -00C5;Aring;LATIN CAPITAL LETTER A WITH RING ABOVE -01FA;Aringacute;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -F7E5;Aringsmall;LATIN SMALL CAPITAL LETTER A WITH RING ABOVE -F761;Asmall;LATIN SMALL CAPITAL LETTER A -00C3;Atilde;LATIN CAPITAL LETTER A WITH TILDE -F7E3;Atildesmall;LATIN SMALL CAPITAL LETTER A WITH TILDE -0042;B;LATIN CAPITAL LETTER B -0392;Beta;GREEK CAPITAL LETTER BETA -F6F4;Brevesmall;SMALL CAPITAL BREVE -F762;Bsmall;LATIN SMALL CAPITAL LETTER B -0043;C;LATIN CAPITAL LETTER C -0106;Cacute;LATIN CAPITAL LETTER C WITH ACUTE -F6CA;Caron;CAPITAL CARON -F6F5;Caronsmall;SMALL CAPITAL CARON -010C;Ccaron;LATIN CAPITAL LETTER C WITH CARON -00C7;Ccedilla;LATIN CAPITAL LETTER C WITH CEDILLA -F7E7;Ccedillasmall;LATIN SMALL CAPITAL LETTER C WITH CEDILLA -0108;Ccircumflex;LATIN CAPITAL LETTER C WITH CIRCUMFLEX -010A;Cdotaccent;LATIN CAPITAL LETTER C WITH DOT ABOVE -F7B8;Cedillasmall;SMALL CAPITAL CEDILLA -03A7;Chi;GREEK CAPITAL LETTER CHI -F6F6;Circumflexsmall;SMALL CAPITAL MODIFIER LETTER CIRCUMFLEX ACCENT -F763;Csmall;LATIN SMALL CAPITAL LETTER C -0044;D;LATIN CAPITAL LETTER D -010E;Dcaron;LATIN CAPITAL LETTER D WITH CARON -0110;Dcroat;LATIN CAPITAL LETTER D WITH STROKE -2206;Delta;INCREMENT -0394;Delta;GREEK CAPITAL LETTER DELTA;Duplicate -F6CB;Dieresis;CAPITAL DIAERESIS -F6CC;DieresisAcute;CAPITAL DIAERESIS ACUTE ACCENT -F6CD;DieresisGrave;CAPITAL DIAERESIS GRAVE ACCENT -F7A8;Dieresissmall;SMALL CAPITAL DIAERESIS -F6F7;Dotaccentsmall;SMALL CAPITAL DOT ABOVE -F764;Dsmall;LATIN SMALL CAPITAL LETTER D -0045;E;LATIN CAPITAL LETTER E -00C9;Eacute;LATIN CAPITAL LETTER E WITH ACUTE -F7E9;Eacutesmall;LATIN SMALL CAPITAL LETTER E WITH ACUTE -0114;Ebreve;LATIN CAPITAL LETTER E WITH BREVE -011A;Ecaron;LATIN CAPITAL LETTER E WITH CARON -00CA;Ecircumflex;LATIN CAPITAL LETTER E WITH CIRCUMFLEX -F7EA;Ecircumflexsmall;LATIN SMALL CAPITAL LETTER E WITH CIRCUMFLEX -00CB;Edieresis;LATIN CAPITAL LETTER E WITH DIAERESIS -F7EB;Edieresissmall;LATIN SMALL CAPITAL LETTER E WITH DIAERESIS -0116;Edotaccent;LATIN CAPITAL LETTER E WITH DOT ABOVE -00C8;Egrave;LATIN CAPITAL LETTER E WITH GRAVE -F7E8;Egravesmall;LATIN SMALL CAPITAL LETTER E WITH GRAVE -0112;Emacron;LATIN CAPITAL LETTER E WITH MACRON -014A;Eng;LATIN CAPITAL LETTER ENG -0118;Eogonek;LATIN CAPITAL LETTER E WITH OGONEK -0395;Epsilon;GREEK CAPITAL LETTER EPSILON -0388;Epsilontonos;GREEK CAPITAL LETTER EPSILON WITH TONOS -F765;Esmall;LATIN SMALL CAPITAL LETTER E -0397;Eta;GREEK CAPITAL LETTER ETA -0389;Etatonos;GREEK CAPITAL LETTER ETA WITH TONOS -00D0;Eth;LATIN CAPITAL LETTER ETH -F7F0;Ethsmall;LATIN SMALL CAPITAL LETTER ETH -20AC;Euro;EURO SIGN -0046;F;LATIN CAPITAL LETTER F -F766;Fsmall;LATIN SMALL CAPITAL LETTER F -0047;G;LATIN CAPITAL LETTER G -0393;Gamma;GREEK CAPITAL LETTER GAMMA -011E;Gbreve;LATIN CAPITAL LETTER G WITH BREVE -01E6;Gcaron;LATIN CAPITAL LETTER G WITH CARON -011C;Gcircumflex;LATIN CAPITAL LETTER G WITH CIRCUMFLEX -0122;Gcommaaccent;LATIN CAPITAL LETTER G WITH CEDILLA -0120;Gdotaccent;LATIN CAPITAL LETTER G WITH DOT ABOVE -F6CE;Grave;CAPITAL GRAVE ACCENT -F760;Gravesmall;SMALL CAPITAL GRAVE ACCENT -F767;Gsmall;LATIN SMALL CAPITAL LETTER G -0048;H;LATIN CAPITAL LETTER H -25CF;H18533;BLACK CIRCLE -25AA;H18543;BLACK SMALL SQUARE -25AB;H18551;WHITE SMALL SQUARE -25A1;H22073;WHITE SQUARE -0126;Hbar;LATIN CAPITAL LETTER H WITH STROKE -0124;Hcircumflex;LATIN CAPITAL LETTER H WITH CIRCUMFLEX -F768;Hsmall;LATIN SMALL CAPITAL LETTER H -F6CF;Hungarumlaut;CAPITAL DOUBLE ACUTE ACCENT -F6F8;Hungarumlautsmall;SMALL CAPITAL DOUBLE ACUTE ACCENT -0049;I;LATIN CAPITAL LETTER I -0132;IJ;LATIN CAPITAL LIGATURE IJ -00CD;Iacute;LATIN CAPITAL LETTER I WITH ACUTE -F7ED;Iacutesmall;LATIN SMALL CAPITAL LETTER I WITH ACUTE -012C;Ibreve;LATIN CAPITAL LETTER I WITH BREVE -00CE;Icircumflex;LATIN CAPITAL LETTER I WITH CIRCUMFLEX -F7EE;Icircumflexsmall;LATIN SMALL CAPITAL LETTER I WITH CIRCUMFLEX -00CF;Idieresis;LATIN CAPITAL LETTER I WITH DIAERESIS -F7EF;Idieresissmall;LATIN SMALL CAPITAL LETTER I WITH DIAERESIS -0130;Idotaccent;LATIN CAPITAL LETTER I WITH DOT ABOVE -2111;Ifraktur;BLACK-LETTER CAPITAL I -00CC;Igrave;LATIN CAPITAL LETTER I WITH GRAVE -F7EC;Igravesmall;LATIN SMALL CAPITAL LETTER I WITH GRAVE -012A;Imacron;LATIN CAPITAL LETTER I WITH MACRON -012E;Iogonek;LATIN CAPITAL LETTER I WITH OGONEK -0399;Iota;GREEK CAPITAL LETTER IOTA -03AA;Iotadieresis;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -038A;Iotatonos;GREEK CAPITAL LETTER IOTA WITH TONOS -F769;Ismall;LATIN SMALL CAPITAL LETTER I -0128;Itilde;LATIN CAPITAL LETTER I WITH TILDE -004A;J;LATIN CAPITAL LETTER J -0134;Jcircumflex;LATIN CAPITAL LETTER J WITH CIRCUMFLEX -F76A;Jsmall;LATIN SMALL CAPITAL LETTER J -004B;K;LATIN CAPITAL LETTER K -039A;Kappa;GREEK CAPITAL LETTER KAPPA -0136;Kcommaaccent;LATIN CAPITAL LETTER K WITH CEDILLA -F76B;Ksmall;LATIN SMALL CAPITAL LETTER K -004C;L;LATIN CAPITAL LETTER L -F6BF;LL;LATIN CAPITAL LETTER LL -0139;Lacute;LATIN CAPITAL LETTER L WITH ACUTE -039B;Lambda;GREEK CAPITAL LETTER LAMDA -013D;Lcaron;LATIN CAPITAL LETTER L WITH CARON -013B;Lcommaaccent;LATIN CAPITAL LETTER L WITH CEDILLA -013F;Ldot;LATIN CAPITAL LETTER L WITH MIDDLE DOT -0141;Lslash;LATIN CAPITAL LETTER L WITH STROKE -F6F9;Lslashsmall;LATIN SMALL CAPITAL LETTER L WITH STROKE -F76C;Lsmall;LATIN SMALL CAPITAL LETTER L -004D;M;LATIN CAPITAL LETTER M -F6D0;Macron;CAPITAL MACRON -F7AF;Macronsmall;SMALL CAPITAL MACRON -F76D;Msmall;LATIN SMALL CAPITAL LETTER M -039C;Mu;GREEK CAPITAL LETTER MU -004E;N;LATIN CAPITAL LETTER N -0143;Nacute;LATIN CAPITAL LETTER N WITH ACUTE -0147;Ncaron;LATIN CAPITAL LETTER N WITH CARON -0145;Ncommaaccent;LATIN CAPITAL LETTER N WITH CEDILLA -F76E;Nsmall;LATIN SMALL CAPITAL LETTER N -00D1;Ntilde;LATIN CAPITAL LETTER N WITH TILDE -F7F1;Ntildesmall;LATIN SMALL CAPITAL LETTER N WITH TILDE -039D;Nu;GREEK CAPITAL LETTER NU -004F;O;LATIN CAPITAL LETTER O -0152;OE;LATIN CAPITAL LIGATURE OE -F6FA;OEsmall;LATIN SMALL CAPITAL LIGATURE OE -00D3;Oacute;LATIN CAPITAL LETTER O WITH ACUTE -F7F3;Oacutesmall;LATIN SMALL CAPITAL LETTER O WITH ACUTE -014E;Obreve;LATIN CAPITAL LETTER O WITH BREVE -00D4;Ocircumflex;LATIN CAPITAL LETTER O WITH CIRCUMFLEX -F7F4;Ocircumflexsmall;LATIN SMALL CAPITAL LETTER O WITH CIRCUMFLEX -00D6;Odieresis;LATIN CAPITAL LETTER O WITH DIAERESIS -F7F6;Odieresissmall;LATIN SMALL CAPITAL LETTER O WITH DIAERESIS -F6FB;Ogoneksmall;SMALL CAPITAL OGONEK -00D2;Ograve;LATIN CAPITAL LETTER O WITH GRAVE -F7F2;Ogravesmall;LATIN SMALL CAPITAL LETTER O WITH GRAVE -01A0;Ohorn;LATIN CAPITAL LETTER O WITH HORN -0150;Ohungarumlaut;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -014C;Omacron;LATIN CAPITAL LETTER O WITH MACRON -2126;Omega;OHM SIGN -03A9;Omega;GREEK CAPITAL LETTER OMEGA;Duplicate -038F;Omegatonos;GREEK CAPITAL LETTER OMEGA WITH TONOS -039F;Omicron;GREEK CAPITAL LETTER OMICRON -038C;Omicrontonos;GREEK CAPITAL LETTER OMICRON WITH TONOS -00D8;Oslash;LATIN CAPITAL LETTER O WITH STROKE -01FE;Oslashacute;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -F7F8;Oslashsmall;LATIN SMALL CAPITAL LETTER O WITH STROKE -F76F;Osmall;LATIN SMALL CAPITAL LETTER O -00D5;Otilde;LATIN CAPITAL LETTER O WITH TILDE -F7F5;Otildesmall;LATIN SMALL CAPITAL LETTER O WITH TILDE -0050;P;LATIN CAPITAL LETTER P -03A6;Phi;GREEK CAPITAL LETTER PHI -03A0;Pi;GREEK CAPITAL LETTER PI -03A8;Psi;GREEK CAPITAL LETTER PSI -F770;Psmall;LATIN SMALL CAPITAL LETTER P -0051;Q;LATIN CAPITAL LETTER Q -F771;Qsmall;LATIN SMALL CAPITAL LETTER Q -0052;R;LATIN CAPITAL LETTER R -0154;Racute;LATIN CAPITAL LETTER R WITH ACUTE -0158;Rcaron;LATIN CAPITAL LETTER R WITH CARON -0156;Rcommaaccent;LATIN CAPITAL LETTER R WITH CEDILLA -211C;Rfraktur;BLACK-LETTER CAPITAL R -03A1;Rho;GREEK CAPITAL LETTER RHO -F6FC;Ringsmall;SMALL CAPITAL RING ABOVE -F772;Rsmall;LATIN SMALL CAPITAL LETTER R -0053;S;LATIN CAPITAL LETTER S -250C;SF010000;BOX DRAWINGS LIGHT DOWN AND RIGHT -2514;SF020000;BOX DRAWINGS LIGHT UP AND RIGHT -2510;SF030000;BOX DRAWINGS LIGHT DOWN AND LEFT -2518;SF040000;BOX DRAWINGS LIGHT UP AND LEFT -253C;SF050000;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL -252C;SF060000;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL -2534;SF070000;BOX DRAWINGS LIGHT UP AND HORIZONTAL -251C;SF080000;BOX DRAWINGS LIGHT VERTICAL AND RIGHT -2524;SF090000;BOX DRAWINGS LIGHT VERTICAL AND LEFT -2500;SF100000;BOX DRAWINGS LIGHT HORIZONTAL -2502;SF110000;BOX DRAWINGS LIGHT VERTICAL -2561;SF190000;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE -2562;SF200000;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE -2556;SF210000;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE -2555;SF220000;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE -2563;SF230000;BOX DRAWINGS DOUBLE VERTICAL AND LEFT -2551;SF240000;BOX DRAWINGS DOUBLE VERTICAL -2557;SF250000;BOX DRAWINGS DOUBLE DOWN AND LEFT -255D;SF260000;BOX DRAWINGS DOUBLE UP AND LEFT -255C;SF270000;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE -255B;SF280000;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE -255E;SF360000;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE -255F;SF370000;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE -255A;SF380000;BOX DRAWINGS DOUBLE UP AND RIGHT -2554;SF390000;BOX DRAWINGS DOUBLE DOWN AND RIGHT -2569;SF400000;BOX DRAWINGS DOUBLE UP AND HORIZONTAL -2566;SF410000;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL -2560;SF420000;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -2550;SF430000;BOX DRAWINGS DOUBLE HORIZONTAL -256C;SF440000;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL -2567;SF450000;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE -2568;SF460000;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE -2564;SF470000;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE -2565;SF480000;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE -2559;SF490000;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE -2558;SF500000;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE -2552;SF510000;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -2553;SF520000;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE -256B;SF530000;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE -256A;SF540000;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE -015A;Sacute;LATIN CAPITAL LETTER S WITH ACUTE -0160;Scaron;LATIN CAPITAL LETTER S WITH CARON -F6FD;Scaronsmall;LATIN SMALL CAPITAL LETTER S WITH CARON -015E;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA -F6C1;Scedilla;LATIN CAPITAL LETTER S WITH CEDILLA;Duplicate -015C;Scircumflex;LATIN CAPITAL LETTER S WITH CIRCUMFLEX -0218;Scommaaccent;LATIN CAPITAL LETTER S WITH COMMA BELOW -03A3;Sigma;GREEK CAPITAL LETTER SIGMA -F773;Ssmall;LATIN SMALL CAPITAL LETTER S -0054;T;LATIN CAPITAL LETTER T -03A4;Tau;GREEK CAPITAL LETTER TAU -0166;Tbar;LATIN CAPITAL LETTER T WITH STROKE -0164;Tcaron;LATIN CAPITAL LETTER T WITH CARON -0162;Tcommaaccent;LATIN CAPITAL LETTER T WITH CEDILLA -021A;Tcommaaccent;LATIN CAPITAL LETTER T WITH COMMA BELOW;Duplicate -0398;Theta;GREEK CAPITAL LETTER THETA -00DE;Thorn;LATIN CAPITAL LETTER THORN -F7FE;Thornsmall;LATIN SMALL CAPITAL LETTER THORN -F6FE;Tildesmall;SMALL CAPITAL SMALL TILDE -F774;Tsmall;LATIN SMALL CAPITAL LETTER T -0055;U;LATIN CAPITAL LETTER U -00DA;Uacute;LATIN CAPITAL LETTER U WITH ACUTE -F7FA;Uacutesmall;LATIN SMALL CAPITAL LETTER U WITH ACUTE -016C;Ubreve;LATIN CAPITAL LETTER U WITH BREVE -00DB;Ucircumflex;LATIN CAPITAL LETTER U WITH CIRCUMFLEX -F7FB;Ucircumflexsmall;LATIN SMALL CAPITAL LETTER U WITH CIRCUMFLEX -00DC;Udieresis;LATIN CAPITAL LETTER U WITH DIAERESIS -F7FC;Udieresissmall;LATIN SMALL CAPITAL LETTER U WITH DIAERESIS -00D9;Ugrave;LATIN CAPITAL LETTER U WITH GRAVE -F7F9;Ugravesmall;LATIN SMALL CAPITAL LETTER U WITH GRAVE -01AF;Uhorn;LATIN CAPITAL LETTER U WITH HORN -0170;Uhungarumlaut;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -016A;Umacron;LATIN CAPITAL LETTER U WITH MACRON -0172;Uogonek;LATIN CAPITAL LETTER U WITH OGONEK -03A5;Upsilon;GREEK CAPITAL LETTER UPSILON -03D2;Upsilon1;GREEK UPSILON WITH HOOK SYMBOL -03AB;Upsilondieresis;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -038E;Upsilontonos;GREEK CAPITAL LETTER UPSILON WITH TONOS -016E;Uring;LATIN CAPITAL LETTER U WITH RING ABOVE -F775;Usmall;LATIN SMALL CAPITAL LETTER U -0168;Utilde;LATIN CAPITAL LETTER U WITH TILDE -0056;V;LATIN CAPITAL LETTER V -F776;Vsmall;LATIN SMALL CAPITAL LETTER V -0057;W;LATIN CAPITAL LETTER W -1E82;Wacute;LATIN CAPITAL LETTER W WITH ACUTE -0174;Wcircumflex;LATIN CAPITAL LETTER W WITH CIRCUMFLEX -1E84;Wdieresis;LATIN CAPITAL LETTER W WITH DIAERESIS -1E80;Wgrave;LATIN CAPITAL LETTER W WITH GRAVE -F777;Wsmall;LATIN SMALL CAPITAL LETTER W -0058;X;LATIN CAPITAL LETTER X -039E;Xi;GREEK CAPITAL LETTER XI -F778;Xsmall;LATIN SMALL CAPITAL LETTER X -0059;Y;LATIN CAPITAL LETTER Y -00DD;Yacute;LATIN CAPITAL LETTER Y WITH ACUTE -F7FD;Yacutesmall;LATIN SMALL CAPITAL LETTER Y WITH ACUTE -0176;Ycircumflex;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -0178;Ydieresis;LATIN CAPITAL LETTER Y WITH DIAERESIS -F7FF;Ydieresissmall;LATIN SMALL CAPITAL LETTER Y WITH DIAERESIS -1EF2;Ygrave;LATIN CAPITAL LETTER Y WITH GRAVE -F779;Ysmall;LATIN SMALL CAPITAL LETTER Y -005A;Z;LATIN CAPITAL LETTER Z -0179;Zacute;LATIN CAPITAL LETTER Z WITH ACUTE -017D;Zcaron;LATIN CAPITAL LETTER Z WITH CARON -F6FF;Zcaronsmall;LATIN SMALL CAPITAL LETTER Z WITH CARON -017B;Zdotaccent;LATIN CAPITAL LETTER Z WITH DOT ABOVE -0396;Zeta;GREEK CAPITAL LETTER ZETA -F77A;Zsmall;LATIN SMALL CAPITAL LETTER Z -0061;a;LATIN SMALL LETTER A -00E1;aacute;LATIN SMALL LETTER A WITH ACUTE -0103;abreve;LATIN SMALL LETTER A WITH BREVE -00E2;acircumflex;LATIN SMALL LETTER A WITH CIRCUMFLEX -00B4;acute;ACUTE ACCENT -0301;acutecomb;COMBINING ACUTE ACCENT -00E4;adieresis;LATIN SMALL LETTER A WITH DIAERESIS -00E6;ae;LATIN SMALL LETTER AE -01FD;aeacute;LATIN SMALL LETTER AE WITH ACUTE -2015;afii00208;HORIZONTAL BAR -0410;afii10017;CYRILLIC CAPITAL LETTER A -0411;afii10018;CYRILLIC CAPITAL LETTER BE -0412;afii10019;CYRILLIC CAPITAL LETTER VE -0413;afii10020;CYRILLIC CAPITAL LETTER GHE -0414;afii10021;CYRILLIC CAPITAL LETTER DE -0415;afii10022;CYRILLIC CAPITAL LETTER IE -0401;afii10023;CYRILLIC CAPITAL LETTER IO -0416;afii10024;CYRILLIC CAPITAL LETTER ZHE -0417;afii10025;CYRILLIC CAPITAL LETTER ZE -0418;afii10026;CYRILLIC CAPITAL LETTER I -0419;afii10027;CYRILLIC CAPITAL LETTER SHORT I -041A;afii10028;CYRILLIC CAPITAL LETTER KA -041B;afii10029;CYRILLIC CAPITAL LETTER EL -041C;afii10030;CYRILLIC CAPITAL LETTER EM -041D;afii10031;CYRILLIC CAPITAL LETTER EN -041E;afii10032;CYRILLIC CAPITAL LETTER O -041F;afii10033;CYRILLIC CAPITAL LETTER PE -0420;afii10034;CYRILLIC CAPITAL LETTER ER -0421;afii10035;CYRILLIC CAPITAL LETTER ES -0422;afii10036;CYRILLIC CAPITAL LETTER TE -0423;afii10037;CYRILLIC CAPITAL LETTER U -0424;afii10038;CYRILLIC CAPITAL LETTER EF -0425;afii10039;CYRILLIC CAPITAL LETTER HA -0426;afii10040;CYRILLIC CAPITAL LETTER TSE -0427;afii10041;CYRILLIC CAPITAL LETTER CHE -0428;afii10042;CYRILLIC CAPITAL LETTER SHA -0429;afii10043;CYRILLIC CAPITAL LETTER SHCHA -042A;afii10044;CYRILLIC CAPITAL LETTER HARD SIGN -042B;afii10045;CYRILLIC CAPITAL LETTER YERU -042C;afii10046;CYRILLIC CAPITAL LETTER SOFT SIGN -042D;afii10047;CYRILLIC CAPITAL LETTER E -042E;afii10048;CYRILLIC CAPITAL LETTER YU -042F;afii10049;CYRILLIC CAPITAL LETTER YA -0490;afii10050;CYRILLIC CAPITAL LETTER GHE WITH UPTURN -0402;afii10051;CYRILLIC CAPITAL LETTER DJE -0403;afii10052;CYRILLIC CAPITAL LETTER GJE -0404;afii10053;CYRILLIC CAPITAL LETTER UKRAINIAN IE -0405;afii10054;CYRILLIC CAPITAL LETTER DZE -0406;afii10055;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -0407;afii10056;CYRILLIC CAPITAL LETTER YI -0408;afii10057;CYRILLIC CAPITAL LETTER JE -0409;afii10058;CYRILLIC CAPITAL LETTER LJE -040A;afii10059;CYRILLIC CAPITAL LETTER NJE -040B;afii10060;CYRILLIC CAPITAL LETTER TSHE -040C;afii10061;CYRILLIC CAPITAL LETTER KJE -040E;afii10062;CYRILLIC CAPITAL LETTER SHORT U -F6C4;afii10063;CYRILLIC SMALL LETTER GHE VARIANT -F6C5;afii10064;CYRILLIC SMALL LETTER BE VARIANT -0430;afii10065;CYRILLIC SMALL LETTER A -0431;afii10066;CYRILLIC SMALL LETTER BE -0432;afii10067;CYRILLIC SMALL LETTER VE -0433;afii10068;CYRILLIC SMALL LETTER GHE -0434;afii10069;CYRILLIC SMALL LETTER DE -0435;afii10070;CYRILLIC SMALL LETTER IE -0451;afii10071;CYRILLIC SMALL LETTER IO -0436;afii10072;CYRILLIC SMALL LETTER ZHE -0437;afii10073;CYRILLIC SMALL LETTER ZE -0438;afii10074;CYRILLIC SMALL LETTER I -0439;afii10075;CYRILLIC SMALL LETTER SHORT I -043A;afii10076;CYRILLIC SMALL LETTER KA -043B;afii10077;CYRILLIC SMALL LETTER EL -043C;afii10078;CYRILLIC SMALL LETTER EM -043D;afii10079;CYRILLIC SMALL LETTER EN -043E;afii10080;CYRILLIC SMALL LETTER O -043F;afii10081;CYRILLIC SMALL LETTER PE -0440;afii10082;CYRILLIC SMALL LETTER ER -0441;afii10083;CYRILLIC SMALL LETTER ES -0442;afii10084;CYRILLIC SMALL LETTER TE -0443;afii10085;CYRILLIC SMALL LETTER U -0444;afii10086;CYRILLIC SMALL LETTER EF -0445;afii10087;CYRILLIC SMALL LETTER HA -0446;afii10088;CYRILLIC SMALL LETTER TSE -0447;afii10089;CYRILLIC SMALL LETTER CHE -0448;afii10090;CYRILLIC SMALL LETTER SHA -0449;afii10091;CYRILLIC SMALL LETTER SHCHA -044A;afii10092;CYRILLIC SMALL LETTER HARD SIGN -044B;afii10093;CYRILLIC SMALL LETTER YERU -044C;afii10094;CYRILLIC SMALL LETTER SOFT SIGN -044D;afii10095;CYRILLIC SMALL LETTER E -044E;afii10096;CYRILLIC SMALL LETTER YU -044F;afii10097;CYRILLIC SMALL LETTER YA -0491;afii10098;CYRILLIC SMALL LETTER GHE WITH UPTURN -0452;afii10099;CYRILLIC SMALL LETTER DJE -0453;afii10100;CYRILLIC SMALL LETTER GJE -0454;afii10101;CYRILLIC SMALL LETTER UKRAINIAN IE -0455;afii10102;CYRILLIC SMALL LETTER DZE -0456;afii10103;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -0457;afii10104;CYRILLIC SMALL LETTER YI -0458;afii10105;CYRILLIC SMALL LETTER JE -0459;afii10106;CYRILLIC SMALL LETTER LJE -045A;afii10107;CYRILLIC SMALL LETTER NJE -045B;afii10108;CYRILLIC SMALL LETTER TSHE -045C;afii10109;CYRILLIC SMALL LETTER KJE -045E;afii10110;CYRILLIC SMALL LETTER SHORT U -040F;afii10145;CYRILLIC CAPITAL LETTER DZHE -0462;afii10146;CYRILLIC CAPITAL LETTER YAT -0472;afii10147;CYRILLIC CAPITAL LETTER FITA -0474;afii10148;CYRILLIC CAPITAL LETTER IZHITSA -F6C6;afii10192;CYRILLIC SMALL LETTER DE VARIANT -045F;afii10193;CYRILLIC SMALL LETTER DZHE -0463;afii10194;CYRILLIC SMALL LETTER YAT -0473;afii10195;CYRILLIC SMALL LETTER FITA -0475;afii10196;CYRILLIC SMALL LETTER IZHITSA -F6C7;afii10831;CYRILLIC SMALL LETTER PE VARIANT -F6C8;afii10832;CYRILLIC SMALL LETTER TE VARIANT -04D9;afii10846;CYRILLIC SMALL LETTER SCHWA -200E;afii299;LEFT-TO-RIGHT MARK -200F;afii300;RIGHT-TO-LEFT MARK -200D;afii301;ZERO WIDTH JOINER -066A;afii57381;ARABIC PERCENT SIGN -060C;afii57388;ARABIC COMMA -0660;afii57392;ARABIC-INDIC DIGIT ZERO -0661;afii57393;ARABIC-INDIC DIGIT ONE -0662;afii57394;ARABIC-INDIC DIGIT TWO -0663;afii57395;ARABIC-INDIC DIGIT THREE -0664;afii57396;ARABIC-INDIC DIGIT FOUR -0665;afii57397;ARABIC-INDIC DIGIT FIVE -0666;afii57398;ARABIC-INDIC DIGIT SIX -0667;afii57399;ARABIC-INDIC DIGIT SEVEN -0668;afii57400;ARABIC-INDIC DIGIT EIGHT -0669;afii57401;ARABIC-INDIC DIGIT NINE -061B;afii57403;ARABIC SEMICOLON -061F;afii57407;ARABIC QUESTION MARK -0621;afii57409;ARABIC LETTER HAMZA -0622;afii57410;ARABIC LETTER ALEF WITH MADDA ABOVE -0623;afii57411;ARABIC LETTER ALEF WITH HAMZA ABOVE -0624;afii57412;ARABIC LETTER WAW WITH HAMZA ABOVE -0625;afii57413;ARABIC LETTER ALEF WITH HAMZA BELOW -0626;afii57414;ARABIC LETTER YEH WITH HAMZA ABOVE -0627;afii57415;ARABIC LETTER ALEF -0628;afii57416;ARABIC LETTER BEH -0629;afii57417;ARABIC LETTER TEH MARBUTA -062A;afii57418;ARABIC LETTER TEH -062B;afii57419;ARABIC LETTER THEH -062C;afii57420;ARABIC LETTER JEEM -062D;afii57421;ARABIC LETTER HAH -062E;afii57422;ARABIC LETTER KHAH -062F;afii57423;ARABIC LETTER DAL -0630;afii57424;ARABIC LETTER THAL -0631;afii57425;ARABIC LETTER REH -0632;afii57426;ARABIC LETTER ZAIN -0633;afii57427;ARABIC LETTER SEEN -0634;afii57428;ARABIC LETTER SHEEN -0635;afii57429;ARABIC LETTER SAD -0636;afii57430;ARABIC LETTER DAD -0637;afii57431;ARABIC LETTER TAH -0638;afii57432;ARABIC LETTER ZAH -0639;afii57433;ARABIC LETTER AIN -063A;afii57434;ARABIC LETTER GHAIN -0640;afii57440;ARABIC TATWEEL -0641;afii57441;ARABIC LETTER FEH -0642;afii57442;ARABIC LETTER QAF -0643;afii57443;ARABIC LETTER KAF -0644;afii57444;ARABIC LETTER LAM -0645;afii57445;ARABIC LETTER MEEM -0646;afii57446;ARABIC LETTER NOON -0648;afii57448;ARABIC LETTER WAW -0649;afii57449;ARABIC LETTER ALEF MAKSURA -064A;afii57450;ARABIC LETTER YEH -064B;afii57451;ARABIC FATHATAN -064C;afii57452;ARABIC DAMMATAN -064D;afii57453;ARABIC KASRATAN -064E;afii57454;ARABIC FATHA -064F;afii57455;ARABIC DAMMA -0650;afii57456;ARABIC KASRA -0651;afii57457;ARABIC SHADDA -0652;afii57458;ARABIC SUKUN -0647;afii57470;ARABIC LETTER HEH -06A4;afii57505;ARABIC LETTER VEH -067E;afii57506;ARABIC LETTER PEH -0686;afii57507;ARABIC LETTER TCHEH -0698;afii57508;ARABIC LETTER JEH -06AF;afii57509;ARABIC LETTER GAF -0679;afii57511;ARABIC LETTER TTEH -0688;afii57512;ARABIC LETTER DDAL -0691;afii57513;ARABIC LETTER RREH -06BA;afii57514;ARABIC LETTER NOON GHUNNA -06D2;afii57519;ARABIC LETTER YEH BARREE -06D5;afii57534;ARABIC LETTER AE -20AA;afii57636;NEW SHEQEL SIGN -05BE;afii57645;HEBREW PUNCTUATION MAQAF -05C3;afii57658;HEBREW PUNCTUATION SOF PASUQ -05D0;afii57664;HEBREW LETTER ALEF -05D1;afii57665;HEBREW LETTER BET -05D2;afii57666;HEBREW LETTER GIMEL -05D3;afii57667;HEBREW LETTER DALET -05D4;afii57668;HEBREW LETTER HE -05D5;afii57669;HEBREW LETTER VAV -05D6;afii57670;HEBREW LETTER ZAYIN -05D7;afii57671;HEBREW LETTER HET -05D8;afii57672;HEBREW LETTER TET -05D9;afii57673;HEBREW LETTER YOD -05DA;afii57674;HEBREW LETTER FINAL KAF -05DB;afii57675;HEBREW LETTER KAF -05DC;afii57676;HEBREW LETTER LAMED -05DD;afii57677;HEBREW LETTER FINAL MEM -05DE;afii57678;HEBREW LETTER MEM -05DF;afii57679;HEBREW LETTER FINAL NUN -05E0;afii57680;HEBREW LETTER NUN -05E1;afii57681;HEBREW LETTER SAMEKH -05E2;afii57682;HEBREW LETTER AYIN -05E3;afii57683;HEBREW LETTER FINAL PE -05E4;afii57684;HEBREW LETTER PE -05E5;afii57685;HEBREW LETTER FINAL TSADI -05E6;afii57686;HEBREW LETTER TSADI -05E7;afii57687;HEBREW LETTER QOF -05E8;afii57688;HEBREW LETTER RESH -05E9;afii57689;HEBREW LETTER SHIN -05EA;afii57690;HEBREW LETTER TAV -FB2A;afii57694;HEBREW LETTER SHIN WITH SHIN DOT -FB2B;afii57695;HEBREW LETTER SHIN WITH SIN DOT -FB4B;afii57700;HEBREW LETTER VAV WITH HOLAM -FB1F;afii57705;HEBREW LIGATURE YIDDISH YOD YOD PATAH -05F0;afii57716;HEBREW LIGATURE YIDDISH DOUBLE VAV -05F1;afii57717;HEBREW LIGATURE YIDDISH VAV YOD -05F2;afii57718;HEBREW LIGATURE YIDDISH DOUBLE YOD -FB35;afii57723;HEBREW LETTER VAV WITH DAGESH -05B4;afii57793;HEBREW POINT HIRIQ -05B5;afii57794;HEBREW POINT TSERE -05B6;afii57795;HEBREW POINT SEGOL -05BB;afii57796;HEBREW POINT QUBUTS -05B8;afii57797;HEBREW POINT QAMATS -05B7;afii57798;HEBREW POINT PATAH -05B0;afii57799;HEBREW POINT SHEVA -05B2;afii57800;HEBREW POINT HATAF PATAH -05B1;afii57801;HEBREW POINT HATAF SEGOL -05B3;afii57802;HEBREW POINT HATAF QAMATS -05C2;afii57803;HEBREW POINT SIN DOT -05C1;afii57804;HEBREW POINT SHIN DOT -05B9;afii57806;HEBREW POINT HOLAM -05BC;afii57807;HEBREW POINT DAGESH OR MAPIQ -05BD;afii57839;HEBREW POINT METEG -05BF;afii57841;HEBREW POINT RAFE -05C0;afii57842;HEBREW PUNCTUATION PASEQ -02BC;afii57929;MODIFIER LETTER APOSTROPHE -2105;afii61248;CARE OF -2113;afii61289;SCRIPT SMALL L -2116;afii61352;NUMERO SIGN -202C;afii61573;POP DIRECTIONAL FORMATTING -202D;afii61574;LEFT-TO-RIGHT OVERRIDE -202E;afii61575;RIGHT-TO-LEFT OVERRIDE -200C;afii61664;ZERO WIDTH NON-JOINER -066D;afii63167;ARABIC FIVE POINTED STAR -02BD;afii64937;MODIFIER LETTER REVERSED COMMA -00E0;agrave;LATIN SMALL LETTER A WITH GRAVE -2135;aleph;ALEF SYMBOL -03B1;alpha;GREEK SMALL LETTER ALPHA -03AC;alphatonos;GREEK SMALL LETTER ALPHA WITH TONOS -0101;amacron;LATIN SMALL LETTER A WITH MACRON -0026;ampersand;AMPERSAND -F726;ampersandsmall;SMALL CAPITAL AMPERSAND -2220;angle;ANGLE -2329;angleleft;LEFT-POINTING ANGLE BRACKET -232A;angleright;RIGHT-POINTING ANGLE BRACKET -0387;anoteleia;GREEK ANO TELEIA -0105;aogonek;LATIN SMALL LETTER A WITH OGONEK -2248;approxequal;ALMOST EQUAL TO -00E5;aring;LATIN SMALL LETTER A WITH RING ABOVE -01FB;aringacute;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE -2194;arrowboth;LEFT RIGHT ARROW -21D4;arrowdblboth;LEFT RIGHT DOUBLE ARROW -21D3;arrowdbldown;DOWNWARDS DOUBLE ARROW -21D0;arrowdblleft;LEFTWARDS DOUBLE ARROW -21D2;arrowdblright;RIGHTWARDS DOUBLE ARROW -21D1;arrowdblup;UPWARDS DOUBLE ARROW -2193;arrowdown;DOWNWARDS ARROW -F8E7;arrowhorizex;HORIZONTAL ARROW EXTENDER -2190;arrowleft;LEFTWARDS ARROW -2192;arrowright;RIGHTWARDS ARROW -2191;arrowup;UPWARDS ARROW -2195;arrowupdn;UP DOWN ARROW -21A8;arrowupdnbse;UP DOWN ARROW WITH BASE -F8E6;arrowvertex;VERTICAL ARROW EXTENDER -005E;asciicircum;CIRCUMFLEX ACCENT -007E;asciitilde;TILDE -002A;asterisk;ASTERISK -2217;asteriskmath;ASTERISK OPERATOR -F6E9;asuperior;SUPERSCRIPT LATIN SMALL LETTER A -0040;at;COMMERCIAL AT -00E3;atilde;LATIN SMALL LETTER A WITH TILDE -0062;b;LATIN SMALL LETTER B -005C;backslash;REVERSE SOLIDUS -007C;bar;VERTICAL LINE -03B2;beta;GREEK SMALL LETTER BETA -2588;block;FULL BLOCK -F8F4;braceex;CURLY BRACKET EXTENDER -007B;braceleft;LEFT CURLY BRACKET -F8F3;braceleftbt;LEFT CURLY BRACKET BOTTOM -F8F2;braceleftmid;LEFT CURLY BRACKET MID -F8F1;bracelefttp;LEFT CURLY BRACKET TOP -007D;braceright;RIGHT CURLY BRACKET -F8FE;bracerightbt;RIGHT CURLY BRACKET BOTTOM -F8FD;bracerightmid;RIGHT CURLY BRACKET MID -F8FC;bracerighttp;RIGHT CURLY BRACKET TOP -005B;bracketleft;LEFT SQUARE BRACKET -F8F0;bracketleftbt;LEFT SQUARE BRACKET BOTTOM -F8EF;bracketleftex;LEFT SQUARE BRACKET EXTENDER -F8EE;bracketlefttp;LEFT SQUARE BRACKET TOP -005D;bracketright;RIGHT SQUARE BRACKET -F8FB;bracketrightbt;RIGHT SQUARE BRACKET BOTTOM -F8FA;bracketrightex;RIGHT SQUARE BRACKET EXTENDER -F8F9;bracketrighttp;RIGHT SQUARE BRACKET TOP -02D8;breve;BREVE -00A6;brokenbar;BROKEN BAR -F6EA;bsuperior;SUPERSCRIPT LATIN SMALL LETTER B -2022;bullet;BULLET -0063;c;LATIN SMALL LETTER C -0107;cacute;LATIN SMALL LETTER C WITH ACUTE -02C7;caron;CARON -21B5;carriagereturn;DOWNWARDS ARROW WITH CORNER LEFTWARDS -010D;ccaron;LATIN SMALL LETTER C WITH CARON -00E7;ccedilla;LATIN SMALL LETTER C WITH CEDILLA -0109;ccircumflex;LATIN SMALL LETTER C WITH CIRCUMFLEX -010B;cdotaccent;LATIN SMALL LETTER C WITH DOT ABOVE -00B8;cedilla;CEDILLA -00A2;cent;CENT SIGN -F6DF;centinferior;SUBSCRIPT CENT SIGN -F7A2;centoldstyle;OLDSTYLE CENT SIGN -F6E0;centsuperior;SUPERSCRIPT CENT SIGN -03C7;chi;GREEK SMALL LETTER CHI -25CB;circle;WHITE CIRCLE -2297;circlemultiply;CIRCLED TIMES -2295;circleplus;CIRCLED PLUS -02C6;circumflex;MODIFIER LETTER CIRCUMFLEX ACCENT -2663;club;BLACK CLUB SUIT -003A;colon;COLON -20A1;colonmonetary;COLON SIGN -002C;comma;COMMA -F6C3;commaaccent;COMMA BELOW -F6E1;commainferior;SUBSCRIPT COMMA -F6E2;commasuperior;SUPERSCRIPT COMMA -2245;congruent;APPROXIMATELY EQUAL TO -00A9;copyright;COPYRIGHT SIGN -F8E9;copyrightsans;COPYRIGHT SIGN SANS SERIF -F6D9;copyrightserif;COPYRIGHT SIGN SERIF -00A4;currency;CURRENCY SIGN -F6D1;cyrBreve;CAPITAL CYRILLIC BREVE -F6D2;cyrFlex;CAPITAL CYRILLIC CIRCUMFLEX -F6D4;cyrbreve;CYRILLIC BREVE -F6D5;cyrflex;CYRILLIC CIRCUMFLEX -0064;d;LATIN SMALL LETTER D -2020;dagger;DAGGER -2021;daggerdbl;DOUBLE DAGGER -F6D3;dblGrave;CAPITAL DOUBLE GRAVE ACCENT -F6D6;dblgrave;DOUBLE GRAVE ACCENT -010F;dcaron;LATIN SMALL LETTER D WITH CARON -0111;dcroat;LATIN SMALL LETTER D WITH STROKE -00B0;degree;DEGREE SIGN -03B4;delta;GREEK SMALL LETTER DELTA -2666;diamond;BLACK DIAMOND SUIT -00A8;dieresis;DIAERESIS -F6D7;dieresisacute;DIAERESIS ACUTE ACCENT -F6D8;dieresisgrave;DIAERESIS GRAVE ACCENT -0385;dieresistonos;GREEK DIALYTIKA TONOS -00F7;divide;DIVISION SIGN -2593;dkshade;DARK SHADE -2584;dnblock;LOWER HALF BLOCK -0024;dollar;DOLLAR SIGN -F6E3;dollarinferior;SUBSCRIPT DOLLAR SIGN -F724;dollaroldstyle;OLDSTYLE DOLLAR SIGN -F6E4;dollarsuperior;SUPERSCRIPT DOLLAR SIGN -20AB;dong;DONG SIGN -02D9;dotaccent;DOT ABOVE -0323;dotbelowcomb;COMBINING DOT BELOW -0131;dotlessi;LATIN SMALL LETTER DOTLESS I -F6BE;dotlessj;LATIN SMALL LETTER DOTLESS J -22C5;dotmath;DOT OPERATOR -F6EB;dsuperior;SUPERSCRIPT LATIN SMALL LETTER D -0065;e;LATIN SMALL LETTER E -00E9;eacute;LATIN SMALL LETTER E WITH ACUTE -0115;ebreve;LATIN SMALL LETTER E WITH BREVE -011B;ecaron;LATIN SMALL LETTER E WITH CARON -00EA;ecircumflex;LATIN SMALL LETTER E WITH CIRCUMFLEX -00EB;edieresis;LATIN SMALL LETTER E WITH DIAERESIS -0117;edotaccent;LATIN SMALL LETTER E WITH DOT ABOVE -00E8;egrave;LATIN SMALL LETTER E WITH GRAVE -0038;eight;DIGIT EIGHT -2088;eightinferior;SUBSCRIPT EIGHT -F738;eightoldstyle;OLDSTYLE DIGIT EIGHT -2078;eightsuperior;SUPERSCRIPT EIGHT -2208;element;ELEMENT OF -2026;ellipsis;HORIZONTAL ELLIPSIS -0113;emacron;LATIN SMALL LETTER E WITH MACRON -2014;emdash;EM DASH -2205;emptyset;EMPTY SET -2013;endash;EN DASH -014B;eng;LATIN SMALL LETTER ENG -0119;eogonek;LATIN SMALL LETTER E WITH OGONEK -03B5;epsilon;GREEK SMALL LETTER EPSILON -03AD;epsilontonos;GREEK SMALL LETTER EPSILON WITH TONOS -003D;equal;EQUALS SIGN -2261;equivalence;IDENTICAL TO -212E;estimated;ESTIMATED SYMBOL -F6EC;esuperior;SUPERSCRIPT LATIN SMALL LETTER E -03B7;eta;GREEK SMALL LETTER ETA -03AE;etatonos;GREEK SMALL LETTER ETA WITH TONOS -00F0;eth;LATIN SMALL LETTER ETH -0021;exclam;EXCLAMATION MARK -203C;exclamdbl;DOUBLE EXCLAMATION MARK -00A1;exclamdown;INVERTED EXCLAMATION MARK -F7A1;exclamdownsmall;SMALL CAPITAL INVERTED EXCLAMATION MARK -F721;exclamsmall;SMALL CAPITAL EXCLAMATION MARK -2203;existential;THERE EXISTS -0066;f;LATIN SMALL LETTER F -2640;female;FEMALE SIGN -FB00;ff;LATIN SMALL LIGATURE FF -FB03;ffi;LATIN SMALL LIGATURE FFI -FB04;ffl;LATIN SMALL LIGATURE FFL -FB01;fi;LATIN SMALL LIGATURE FI -2012;figuredash;FIGURE DASH -25A0;filledbox;BLACK SQUARE -25AC;filledrect;BLACK RECTANGLE -0035;five;DIGIT FIVE -215D;fiveeighths;VULGAR FRACTION FIVE EIGHTHS -2085;fiveinferior;SUBSCRIPT FIVE -F735;fiveoldstyle;OLDSTYLE DIGIT FIVE -2075;fivesuperior;SUPERSCRIPT FIVE -FB02;fl;LATIN SMALL LIGATURE FL -0192;florin;LATIN SMALL LETTER F WITH HOOK -0034;four;DIGIT FOUR -2084;fourinferior;SUBSCRIPT FOUR -F734;fouroldstyle;OLDSTYLE DIGIT FOUR -2074;foursuperior;SUPERSCRIPT FOUR -2044;fraction;FRACTION SLASH -2215;fraction;DIVISION SLASH;Duplicate -20A3;franc;FRENCH FRANC SIGN -0067;g;LATIN SMALL LETTER G -03B3;gamma;GREEK SMALL LETTER GAMMA -011F;gbreve;LATIN SMALL LETTER G WITH BREVE -01E7;gcaron;LATIN SMALL LETTER G WITH CARON -011D;gcircumflex;LATIN SMALL LETTER G WITH CIRCUMFLEX -0123;gcommaaccent;LATIN SMALL LETTER G WITH CEDILLA -0121;gdotaccent;LATIN SMALL LETTER G WITH DOT ABOVE -00DF;germandbls;LATIN SMALL LETTER SHARP S -2207;gradient;NABLA -0060;grave;GRAVE ACCENT -0300;gravecomb;COMBINING GRAVE ACCENT -003E;greater;GREATER-THAN SIGN -2265;greaterequal;GREATER-THAN OR EQUAL TO -00AB;guillemotleft;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -00BB;guillemotright;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -2039;guilsinglleft;SINGLE LEFT-POINTING ANGLE QUOTATION MARK -203A;guilsinglright;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -0068;h;LATIN SMALL LETTER H -0127;hbar;LATIN SMALL LETTER H WITH STROKE -0125;hcircumflex;LATIN SMALL LETTER H WITH CIRCUMFLEX -2665;heart;BLACK HEART SUIT -0309;hookabovecomb;COMBINING HOOK ABOVE -2302;house;HOUSE -02DD;hungarumlaut;DOUBLE ACUTE ACCENT -002D;hyphen;HYPHEN-MINUS -00AD;hyphen;SOFT HYPHEN;Duplicate -F6E5;hypheninferior;SUBSCRIPT HYPHEN-MINUS -F6E6;hyphensuperior;SUPERSCRIPT HYPHEN-MINUS -0069;i;LATIN SMALL LETTER I -00ED;iacute;LATIN SMALL LETTER I WITH ACUTE -012D;ibreve;LATIN SMALL LETTER I WITH BREVE -00EE;icircumflex;LATIN SMALL LETTER I WITH CIRCUMFLEX -00EF;idieresis;LATIN SMALL LETTER I WITH DIAERESIS -00EC;igrave;LATIN SMALL LETTER I WITH GRAVE -0133;ij;LATIN SMALL LIGATURE IJ -012B;imacron;LATIN SMALL LETTER I WITH MACRON -221E;infinity;INFINITY -222B;integral;INTEGRAL -2321;integralbt;BOTTOM HALF INTEGRAL -F8F5;integralex;INTEGRAL EXTENDER -2320;integraltp;TOP HALF INTEGRAL -2229;intersection;INTERSECTION -25D8;invbullet;INVERSE BULLET -25D9;invcircle;INVERSE WHITE CIRCLE -263B;invsmileface;BLACK SMILING FACE -012F;iogonek;LATIN SMALL LETTER I WITH OGONEK -03B9;iota;GREEK SMALL LETTER IOTA -03CA;iotadieresis;GREEK SMALL LETTER IOTA WITH DIALYTIKA -0390;iotadieresistonos;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -03AF;iotatonos;GREEK SMALL LETTER IOTA WITH TONOS -F6ED;isuperior;SUPERSCRIPT LATIN SMALL LETTER I -0129;itilde;LATIN SMALL LETTER I WITH TILDE -006A;j;LATIN SMALL LETTER J -0135;jcircumflex;LATIN SMALL LETTER J WITH CIRCUMFLEX -006B;k;LATIN SMALL LETTER K -03BA;kappa;GREEK SMALL LETTER KAPPA -0137;kcommaaccent;LATIN SMALL LETTER K WITH CEDILLA -0138;kgreenlandic;LATIN SMALL LETTER KRA -006C;l;LATIN SMALL LETTER L -013A;lacute;LATIN SMALL LETTER L WITH ACUTE -03BB;lambda;GREEK SMALL LETTER LAMDA -013E;lcaron;LATIN SMALL LETTER L WITH CARON -013C;lcommaaccent;LATIN SMALL LETTER L WITH CEDILLA -0140;ldot;LATIN SMALL LETTER L WITH MIDDLE DOT -003C;less;LESS-THAN SIGN -2264;lessequal;LESS-THAN OR EQUAL TO -258C;lfblock;LEFT HALF BLOCK -20A4;lira;LIRA SIGN -F6C0;ll;LATIN SMALL LETTER LL -2227;logicaland;LOGICAL AND -00AC;logicalnot;NOT SIGN -2228;logicalor;LOGICAL OR -017F;longs;LATIN SMALL LETTER LONG S -25CA;lozenge;LOZENGE -0142;lslash;LATIN SMALL LETTER L WITH STROKE -F6EE;lsuperior;SUPERSCRIPT LATIN SMALL LETTER L -2591;ltshade;LIGHT SHADE -006D;m;LATIN SMALL LETTER M -00AF;macron;MACRON -02C9;macron;MODIFIER LETTER MACRON;Duplicate -2642;male;MALE SIGN -2212;minus;MINUS SIGN -2032;minute;PRIME -F6EF;msuperior;SUPERSCRIPT LATIN SMALL LETTER M -00B5;mu;MICRO SIGN -03BC;mu;GREEK SMALL LETTER MU;Duplicate -00D7;multiply;MULTIPLICATION SIGN -266A;musicalnote;EIGHTH NOTE -266B;musicalnotedbl;BEAMED EIGHTH NOTES -006E;n;LATIN SMALL LETTER N -0144;nacute;LATIN SMALL LETTER N WITH ACUTE -0149;napostrophe;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -0148;ncaron;LATIN SMALL LETTER N WITH CARON -0146;ncommaaccent;LATIN SMALL LETTER N WITH CEDILLA -0039;nine;DIGIT NINE -2089;nineinferior;SUBSCRIPT NINE -F739;nineoldstyle;OLDSTYLE DIGIT NINE -2079;ninesuperior;SUPERSCRIPT NINE -2209;notelement;NOT AN ELEMENT OF -2260;notequal;NOT EQUAL TO -2284;notsubset;NOT A SUBSET OF -207F;nsuperior;SUPERSCRIPT LATIN SMALL LETTER N -00F1;ntilde;LATIN SMALL LETTER N WITH TILDE -03BD;nu;GREEK SMALL LETTER NU -0023;numbersign;NUMBER SIGN -006F;o;LATIN SMALL LETTER O -00F3;oacute;LATIN SMALL LETTER O WITH ACUTE -014F;obreve;LATIN SMALL LETTER O WITH BREVE -00F4;ocircumflex;LATIN SMALL LETTER O WITH CIRCUMFLEX -00F6;odieresis;LATIN SMALL LETTER O WITH DIAERESIS -0153;oe;LATIN SMALL LIGATURE OE -02DB;ogonek;OGONEK -00F2;ograve;LATIN SMALL LETTER O WITH GRAVE -01A1;ohorn;LATIN SMALL LETTER O WITH HORN -0151;ohungarumlaut;LATIN SMALL LETTER O WITH DOUBLE ACUTE -014D;omacron;LATIN SMALL LETTER O WITH MACRON -03C9;omega;GREEK SMALL LETTER OMEGA -03D6;omega1;GREEK PI SYMBOL -03CE;omegatonos;GREEK SMALL LETTER OMEGA WITH TONOS -03BF;omicron;GREEK SMALL LETTER OMICRON -03CC;omicrontonos;GREEK SMALL LETTER OMICRON WITH TONOS -0031;one;DIGIT ONE -2024;onedotenleader;ONE DOT LEADER -215B;oneeighth;VULGAR FRACTION ONE EIGHTH -F6DC;onefitted;PROPORTIONAL DIGIT ONE -00BD;onehalf;VULGAR FRACTION ONE HALF -2081;oneinferior;SUBSCRIPT ONE -F731;oneoldstyle;OLDSTYLE DIGIT ONE -00BC;onequarter;VULGAR FRACTION ONE QUARTER -00B9;onesuperior;SUPERSCRIPT ONE -2153;onethird;VULGAR FRACTION ONE THIRD -25E6;openbullet;WHITE BULLET -00AA;ordfeminine;FEMININE ORDINAL INDICATOR -00BA;ordmasculine;MASCULINE ORDINAL INDICATOR -221F;orthogonal;RIGHT ANGLE -00F8;oslash;LATIN SMALL LETTER O WITH STROKE -01FF;oslashacute;LATIN SMALL LETTER O WITH STROKE AND ACUTE -F6F0;osuperior;SUPERSCRIPT LATIN SMALL LETTER O -00F5;otilde;LATIN SMALL LETTER O WITH TILDE -0070;p;LATIN SMALL LETTER P -00B6;paragraph;PILCROW SIGN -0028;parenleft;LEFT PARENTHESIS -F8ED;parenleftbt;LEFT PAREN BOTTOM -F8EC;parenleftex;LEFT PAREN EXTENDER -208D;parenleftinferior;SUBSCRIPT LEFT PARENTHESIS -207D;parenleftsuperior;SUPERSCRIPT LEFT PARENTHESIS -F8EB;parenlefttp;LEFT PAREN TOP -0029;parenright;RIGHT PARENTHESIS -F8F8;parenrightbt;RIGHT PAREN BOTTOM -F8F7;parenrightex;RIGHT PAREN EXTENDER -208E;parenrightinferior;SUBSCRIPT RIGHT PARENTHESIS -207E;parenrightsuperior;SUPERSCRIPT RIGHT PARENTHESIS -F8F6;parenrighttp;RIGHT PAREN TOP -2202;partialdiff;PARTIAL DIFFERENTIAL -0025;percent;PERCENT SIGN -002E;period;FULL STOP -00B7;periodcentered;MIDDLE DOT -2219;periodcentered;BULLET OPERATOR;Duplicate -F6E7;periodinferior;SUBSCRIPT FULL STOP -F6E8;periodsuperior;SUPERSCRIPT FULL STOP -22A5;perpendicular;UP TACK -2030;perthousand;PER MILLE SIGN -20A7;peseta;PESETA SIGN -03C6;phi;GREEK SMALL LETTER PHI -03D5;phi1;GREEK PHI SYMBOL -03C0;pi;GREEK SMALL LETTER PI -002B;plus;PLUS SIGN -00B1;plusminus;PLUS-MINUS SIGN -211E;prescription;PRESCRIPTION TAKE -220F;product;N-ARY PRODUCT -2282;propersubset;SUBSET OF -2283;propersuperset;SUPERSET OF -221D;proportional;PROPORTIONAL TO -03C8;psi;GREEK SMALL LETTER PSI -0071;q;LATIN SMALL LETTER Q -003F;question;QUESTION MARK -00BF;questiondown;INVERTED QUESTION MARK -F7BF;questiondownsmall;SMALL CAPITAL INVERTED QUESTION MARK -F73F;questionsmall;SMALL CAPITAL QUESTION MARK -0022;quotedbl;QUOTATION MARK -201E;quotedblbase;DOUBLE LOW-9 QUOTATION MARK -201C;quotedblleft;LEFT DOUBLE QUOTATION MARK -201D;quotedblright;RIGHT DOUBLE QUOTATION MARK -2018;quoteleft;LEFT SINGLE QUOTATION MARK -201B;quotereversed;SINGLE HIGH-REVERSED-9 QUOTATION MARK -2019;quoteright;RIGHT SINGLE QUOTATION MARK -201A;quotesinglbase;SINGLE LOW-9 QUOTATION MARK -0027;quotesingle;APOSTROPHE -0072;r;LATIN SMALL LETTER R -0155;racute;LATIN SMALL LETTER R WITH ACUTE -221A;radical;SQUARE ROOT -F8E5;radicalex;RADICAL EXTENDER -0159;rcaron;LATIN SMALL LETTER R WITH CARON -0157;rcommaaccent;LATIN SMALL LETTER R WITH CEDILLA -2286;reflexsubset;SUBSET OF OR EQUAL TO -2287;reflexsuperset;SUPERSET OF OR EQUAL TO -00AE;registered;REGISTERED SIGN -F8E8;registersans;REGISTERED SIGN SANS SERIF -F6DA;registerserif;REGISTERED SIGN SERIF -2310;revlogicalnot;REVERSED NOT SIGN -03C1;rho;GREEK SMALL LETTER RHO -02DA;ring;RING ABOVE -F6F1;rsuperior;SUPERSCRIPT LATIN SMALL LETTER R -2590;rtblock;RIGHT HALF BLOCK -F6DD;rupiah;RUPIAH SIGN -0073;s;LATIN SMALL LETTER S -015B;sacute;LATIN SMALL LETTER S WITH ACUTE -0161;scaron;LATIN SMALL LETTER S WITH CARON -015F;scedilla;LATIN SMALL LETTER S WITH CEDILLA -F6C2;scedilla;LATIN SMALL LETTER S WITH CEDILLA;Duplicate -015D;scircumflex;LATIN SMALL LETTER S WITH CIRCUMFLEX -0219;scommaaccent;LATIN SMALL LETTER S WITH COMMA BELOW -2033;second;DOUBLE PRIME -00A7;section;SECTION SIGN -003B;semicolon;SEMICOLON -0037;seven;DIGIT SEVEN -215E;seveneighths;VULGAR FRACTION SEVEN EIGHTHS -2087;seveninferior;SUBSCRIPT SEVEN -F737;sevenoldstyle;OLDSTYLE DIGIT SEVEN -2077;sevensuperior;SUPERSCRIPT SEVEN -2592;shade;MEDIUM SHADE -03C3;sigma;GREEK SMALL LETTER SIGMA -03C2;sigma1;GREEK SMALL LETTER FINAL SIGMA -223C;similar;TILDE OPERATOR -0036;six;DIGIT SIX -2086;sixinferior;SUBSCRIPT SIX -F736;sixoldstyle;OLDSTYLE DIGIT SIX -2076;sixsuperior;SUPERSCRIPT SIX -002F;slash;SOLIDUS -263A;smileface;WHITE SMILING FACE -0020;space;SPACE -00A0;space;NO-BREAK SPACE;Duplicate -2660;spade;BLACK SPADE SUIT -F6F2;ssuperior;SUPERSCRIPT LATIN SMALL LETTER S -00A3;sterling;POUND SIGN -220B;suchthat;CONTAINS AS MEMBER -2211;summation;N-ARY SUMMATION -263C;sun;WHITE SUN WITH RAYS -0074;t;LATIN SMALL LETTER T -03C4;tau;GREEK SMALL LETTER TAU -0167;tbar;LATIN SMALL LETTER T WITH STROKE -0165;tcaron;LATIN SMALL LETTER T WITH CARON -0163;tcommaaccent;LATIN SMALL LETTER T WITH CEDILLA -021B;tcommaaccent;LATIN SMALL LETTER T WITH COMMA BELOW;Duplicate -2234;therefore;THEREFORE -03B8;theta;GREEK SMALL LETTER THETA -03D1;theta1;GREEK THETA SYMBOL -00FE;thorn;LATIN SMALL LETTER THORN -0033;three;DIGIT THREE -215C;threeeighths;VULGAR FRACTION THREE EIGHTHS -2083;threeinferior;SUBSCRIPT THREE -F733;threeoldstyle;OLDSTYLE DIGIT THREE -00BE;threequarters;VULGAR FRACTION THREE QUARTERS -F6DE;threequartersemdash;THREE QUARTERS EM DASH -00B3;threesuperior;SUPERSCRIPT THREE -02DC;tilde;SMALL TILDE -0303;tildecomb;COMBINING TILDE -0384;tonos;GREEK TONOS -2122;trademark;TRADE MARK SIGN -F8EA;trademarksans;TRADE MARK SIGN SANS SERIF -F6DB;trademarkserif;TRADE MARK SIGN SERIF -25BC;triagdn;BLACK DOWN-POINTING TRIANGLE -25C4;triaglf;BLACK LEFT-POINTING POINTER -25BA;triagrt;BLACK RIGHT-POINTING POINTER -25B2;triagup;BLACK UP-POINTING TRIANGLE -F6F3;tsuperior;SUPERSCRIPT LATIN SMALL LETTER T -0032;two;DIGIT TWO -2025;twodotenleader;TWO DOT LEADER -2082;twoinferior;SUBSCRIPT TWO -F732;twooldstyle;OLDSTYLE DIGIT TWO -00B2;twosuperior;SUPERSCRIPT TWO -2154;twothirds;VULGAR FRACTION TWO THIRDS -0075;u;LATIN SMALL LETTER U -00FA;uacute;LATIN SMALL LETTER U WITH ACUTE -016D;ubreve;LATIN SMALL LETTER U WITH BREVE -00FB;ucircumflex;LATIN SMALL LETTER U WITH CIRCUMFLEX -00FC;udieresis;LATIN SMALL LETTER U WITH DIAERESIS -00F9;ugrave;LATIN SMALL LETTER U WITH GRAVE -01B0;uhorn;LATIN SMALL LETTER U WITH HORN -0171;uhungarumlaut;LATIN SMALL LETTER U WITH DOUBLE ACUTE -016B;umacron;LATIN SMALL LETTER U WITH MACRON -005F;underscore;LOW LINE -2017;underscoredbl;DOUBLE LOW LINE -222A;union;UNION -2200;universal;FOR ALL -0173;uogonek;LATIN SMALL LETTER U WITH OGONEK -2580;upblock;UPPER HALF BLOCK -03C5;upsilon;GREEK SMALL LETTER UPSILON -03CB;upsilondieresis;GREEK SMALL LETTER UPSILON WITH DIALYTIKA -03B0;upsilondieresistonos;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -03CD;upsilontonos;GREEK SMALL LETTER UPSILON WITH TONOS -016F;uring;LATIN SMALL LETTER U WITH RING ABOVE -0169;utilde;LATIN SMALL LETTER U WITH TILDE -0076;v;LATIN SMALL LETTER V -0077;w;LATIN SMALL LETTER W -1E83;wacute;LATIN SMALL LETTER W WITH ACUTE -0175;wcircumflex;LATIN SMALL LETTER W WITH CIRCUMFLEX -1E85;wdieresis;LATIN SMALL LETTER W WITH DIAERESIS -2118;weierstrass;SCRIPT CAPITAL P -1E81;wgrave;LATIN SMALL LETTER W WITH GRAVE -0078;x;LATIN SMALL LETTER X -03BE;xi;GREEK SMALL LETTER XI -0079;y;LATIN SMALL LETTER Y -00FD;yacute;LATIN SMALL LETTER Y WITH ACUTE -0177;ycircumflex;LATIN SMALL LETTER Y WITH CIRCUMFLEX -00FF;ydieresis;LATIN SMALL LETTER Y WITH DIAERESIS -00A5;yen;YEN SIGN -1EF3;ygrave;LATIN SMALL LETTER Y WITH GRAVE -007A;z;LATIN SMALL LETTER Z -017A;zacute;LATIN SMALL LETTER Z WITH ACUTE -017E;zcaron;LATIN SMALL LETTER Z WITH CARON -017C;zdotaccent;LATIN SMALL LETTER Z WITH DOT ABOVE -0030;zero;DIGIT ZERO -2080;zeroinferior;SUBSCRIPT ZERO -F730;zerooldstyle;OLDSTYLE DIGIT ZERO -2070;zerosuperior;SUPERSCRIPT ZERO -03B6;zeta;GREEK SMALL LETTER ZETA -""" - - -t1_bias = 0 -glyph_list = [] - - -def the_adobe_glyph_list(): - """return the list of glyph names in the adobe list""" - - lines = string.split( adobe_glyph_list, '\n' ) - glyphs = [] - - for line in lines: - if line: - fields = string.split( line, ';' ) -# print fields[0] + ' - ' + fields[1] - glyphs.append( fields[1] ) - - return glyphs - - -def the_adobe_glyphs(): - """return the list of unicode values""" - - lines = string.split( adobe_glyph_list, '\n' ) - glyphs = [] - values = [] - - for line in lines: - if line: - fields = string.split( line, ';' ) -# print fields[0] + ' - ' + fields[1] - glyphs.append( fields[1] ) - values.append( fields[0] ) - - return glyphs, values - - -def count_extra_glyphs( alist, filter ): - """count the number of extra glyphs""" - - count = 0 - extras = [] - - for name in alist: - try: - filtered_index = filter.index( name ) - except: - extras.append( name ) - - return extras - - -def dump_mac_indices( file ): - write = file.write - - write( " static const unsigned short mac_standard_names[" + \ - repr( len( mac_standard_names ) + 1 ) + "] =\n" ) - write( " {\n" ) - - count = 0 - for name in mac_standard_names: - try: - t1_index = t1_standard_strings.index( name ) - write( " " + repr( t1_bias + t1_index ) + ",\n" ) - except: - write( " " + repr( count ) + ",\n" ) - count = count + 1 - - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - -def dump_glyph_list( file, glyph_list, adobe_extra ): - write = file.write - - name_list = [] - - write( " static const char* standard_glyph_names[] =\n" ) - write( " {\n" ) - - for name in glyph_list: - write( ' "' + name + '",\n' ) - name_list.append( name ) - - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "\n" ) - - for name in adobe_extra: - write( ' "' + name + '",\n' ) - name_list.append( name ) - - write( "\n" ) - write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) - write( "\n" ) - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - return name_list - - -def dump_unicode_values( file, base_list, adobe_list ): - """build the glyph names to unicode values table""" - - write = file.write - - adobe_glyphs, uni_values = the_adobe_glyphs() - - write( "\n" ) - write( " static const unsigned short names_to_unicode[" + \ - repr( len( base_list ) + len( adobe_list ) + 1 ) + "] =\n" ) - write( " {\n" ) - - for name in base_list: - try: - index = adobe_glyphs.index( name ) - write( " 0x" + uni_values[index] + ",\n" ) - except: - write( " 0,\n" ) - - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "\n" ) - - for name in adobe_list: - try: - index = adobe_glyphs.index( name ) - write( " 0x" + uni_values[index] + ",\n" ) - except: - write( " 0,\n" ) - - write( "\n" ) - write( "#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */\n" ) - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - write( "\n" ) - - -def dump_encoding( file, encoding_name, encoding_list ): - """dumps a given encoding""" - - write = file.write - - write( " static const unsigned short " + encoding_name + "[" + \ - repr( len( encoding_list ) + 1 ) + "] =\n" ) - write( " {\n" ) - - for value in encoding_list: - write( " " + repr( value ) + ",\n" ) - write( " 0\n" ) - write( " };\n" ) - write( "\n" ) - write( "\n" ) - - -def main(): - """main program body""" - - if len( sys.argv ) != 2: - print __doc__ % sys.argv[0] - sys.exit( 1 ) - - file = open( sys.argv[1], "w\n" ) - write = file.write - - count_sid = len( t1_standard_strings ) - - # build mac index table & supplemental glyph names - mac_list = count_extra_glyphs( mac_standard_names, t1_standard_strings ) - count_mac = len( mac_list ) - t1_bias = count_mac - base_list = mac_list + t1_standard_strings - - # build adobe unicode index table & supplemental glyph names - adobe_list = the_adobe_glyph_list() - adobe_list = count_extra_glyphs( adobe_list, base_list ) - count_adobe = len( adobe_list ) - - write( "/***************************************************************************/\n" ) - write( "/* */\n" ) - - write( "/* %-71s*/\n" % sys.argv[1] ) - - write( "/* */\n" ) - write( "/* PostScript glyph names (specification only). */\n" ) - write( "/* */\n" ) - write( "/* Copyright 2000 by */\n" ) - write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) - write( "/* */\n" ) - write( "/* This file is part of the FreeType project, and may only be used, */\n" ) - write( "/* modified, and distributed under the terms of the FreeType project */\n" ) - write( "/* license, LICENSE.TXT. By continuing to use, modify, or distribute */\n" ) - write( "/* this file you indicate that you have read the license and */\n" ) - write( "/* understand and accept it fully. */\n" ) - write( "/* */\n" ) - write( "/***************************************************************************/\n" ) - write( "\n" ) - write( "\n" ) - write( " /* this file has been generated automatically -- do not edit! */\n" ) - write( "\n" ) - write( "\n" ) - - # dump glyph list - name_list = dump_glyph_list( file, base_list, adobe_list ) - - # dump t1_standard_list - write( " static const char** t1_standard_glyphs = " \ - + "standard_glyph_names + " + repr( t1_bias ) + ";\n" ) - write( "\n" ) - write( "\n" ) - - write( "#define NUM_STD_GLYPHS " + repr( len( t1_standard_strings ) ) + "\n" ) - write( "\n" ) - write( "#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST\n" ) - write( "#define NUM_ADOBE_GLYPHS " + \ - repr( len( base_list ) + len( adobe_list ) - t1_bias ) + "\n" ) - write( "#else\n" ) - write( "#define NUM_ADOBE_GLYPHS " + \ - repr( len( base_list ) - t1_bias ) + "\n" ) - write( "#endif\n" ) - write( "\n" ) - write( "\n" ) - - # dump mac indices table - dump_mac_indices( file ) - - # discard mac names from base list - base_list = base_list[t1_bias:] - - # dump unicode values table - dump_unicode_values( file, base_list, adobe_list ) - - dump_encoding( file, "t1_standard_encoding", t1_standard_encoding ) - dump_encoding( file, "t1_expert_encoding", t1_expert_encoding ) - - write( "/* END */\n" ) - - -# Now run the main routine -# -main() - - -# END diff --git a/subsys/win32k/freetype/docs/glyphs/Image1.png b/subsys/win32k/freetype/docs/glyphs/Image1.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/Image1.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/Image2.png b/subsys/win32k/freetype/docs/glyphs/Image2.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/Image2.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/Image3.png b/subsys/win32k/freetype/docs/glyphs/Image3.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/Image3.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/Image4.png b/subsys/win32k/freetype/docs/glyphs/Image4.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/Image4.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/bbox1.png b/subsys/win32k/freetype/docs/glyphs/bbox1.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/bbox1.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/bbox2.png b/subsys/win32k/freetype/docs/glyphs/bbox2.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/bbox2.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/body_comparison.png b/subsys/win32k/freetype/docs/glyphs/body_comparison.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/body_comparison.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/bravo_kerned.png b/subsys/win32k/freetype/docs/glyphs/bravo_kerned.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/bravo_kerned.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/bravo_unkerned.png b/subsys/win32k/freetype/docs/glyphs/bravo_unkerned.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/bravo_unkerned.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/clipping.png b/subsys/win32k/freetype/docs/glyphs/clipping.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/clipping.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/down_flow.png b/subsys/win32k/freetype/docs/glyphs/down_flow.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/down_flow.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/grid_1.png b/subsys/win32k/freetype/docs/glyphs/grid_1.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/grid_1.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/index.html b/subsys/win32k/freetype/docs/glyphs/index.html deleted file mode 100644 index 85dde95..0000000 --- a/subsys/win32k/freetype/docs/glyphs/index.html +++ /dev/null @@ -1,1626 +0,0 @@ - - - - - - - FreeType Glyph Conventions - - - - - -
-

-FreeType Glyph Conventions

- -
-

-version 2.0

- -
-

-Copyright 1998-1999David Turner (david@freetype.org)
-Copyright 1999 The FreeType Development Team (devel@freetype.org)

- -


-


-

-Introduction

- -
This document discusses in great details the definition of -various concepts related to digital typography, as well as a few specific -to the FreeType library. It also explains the ways typographic information, -like glyph metrics, kerning distances, etc.. is to be managed and used. -It relates to the layout and display of text strings, either in a conventional -(i.e. Roman) layout, or with right-to-left or vertical ones. Some aspects -like rotation and transformation are explained too. -

Comments and corrections are highly welcomed, and can be sent to the -FreeType -developers list.

- -
-

-I. Basic typographic concepts

- -
-

-1. Font files, format and information

- -
A font is a collection of various character images that can -be used to display or print text. The images in a single font share some -common properties, including look, style, serifs, etc.. Typographically -speaking, one has to distinguish between a font family and its multiple -font -faces, which usually differ in style though come from the same template. -For example, "Palatino Regular" and "Palatino Italic" are -two distinct faces from the same famous family, called "Palatino" -itself. -

The single term font is nearly always used in ambiguous ways to refer -to either a given family or given face, depending on the context. For example, -most users of word-processors use "font" to describe a font family (e.g. -Courier, Palatino, etc..); however most of these families are implemented -through several data files depending on the file format : for TrueType, -this is usually one per face (i.e. ARIAL.TFF for "Arial Regular", ARIALI.TTF -for "Arial Italic", etc..). The file is also called a "font" but really -contains a font face. -

A digital font is thus a data file that may contain one or -more font faces. For each of these, it contains character images, character -metrics, as well as other kind of information important to the layout of -text and the processing of specific character encodings. In some awkward -formats, like Adobe Type1, a single font face is described through several -files (i.e. one contains the character images, another one the character -metrics). We will ignore this implementation issue in most of this document -and consider digital fonts as single files, though FreeType 2.0 is able -to support multiple-files fonts correctly. -

As a convenience, a font file containing more than one face is called -a font collection. This case is rather rare but can be seen in many asian -fonts, which contain images for two or more scripts for a given language.

- -

-2. Character images and mappings :

- -
The character images are called glyphs. A single character -can have several distinct images, i.e. several glyphs, depending on script, -usage or context. Several characters can also take a single glyph (good -examples are roman ligatures like "oe" and "fi" which can be represented -by a single glyph like "œ" and "?"). The relationships between characters -and glyphs can be a very complex one but won't be detailed in this document. -Moreover, some formats use more or less awkward schemes to store and access -the glyphs. For the sake of clarity, we'll only retain the following notions -when working with FreeType : -
  -
    -
  • -A font file contains a set of glyphs, each one can be stored as a bitmap, -a vector representation or any other scheme (e.g. most scalable formats -use a combination of math representation and control data/programs). These -glyphs can be stored in any order in the font file, and is typically accessed -through a simple glyph index.
  • -
-
-
- -
    -
      -
        -
      • -The font file contains one (or more) table, called a character map (or -charmap in short), which is used to convert character codes for a given -encoding (e.g. ASCII, Unicode, DBCS, Big5, etc..) into glyph indexes relative -to the font file. A single font face may contain several charmaps. For -example, most TrueType fonts contain an Apple-specific charmap as well -as a Unicode charmap, which makes them usable on both Mac and Windows platforms.
      • -
      -
    - -

    -3. Character and font metrics :

    - -
      Each glyph image is associated to various metrics which are used to -describe the way it must be placed and managed when rendering text. Though -they are described in more details in section III, they relate to glyph -placement, cursor advances as well as text layouts. They are extremely -important to compute the flow of text when rendering string of text. -

      Each scalable format also contains some global metrics, expressed in -notional units, used to describe some properties of all glyphs in a same -face. For example : the maximum glyph bounding box, the ascender, descender -and text height for the font. -

      Though these metrics also exist for non-scalable formats, they only -apply for a set of given character dimensions and resolutions, and they're -usually expressed in pixels then.

    -
- -


-


-

-II. Glyph Outlines

- -
This section describes the vectorial representation of glyph -images, called outlines. -
  -

-1. Pixels, Points and Device Resolutions :

- -
Though it is a very common assumption when dealing with computer -graphics programs, the physical dimensions of a given pixel (be it for -screens or printers) are not squared. Often, the output device, be it a -screen or printer exhibits varying resolutions in the horizontal and vertical -directions, and this must be taken care of when rendering text. -

It is thus common to define a device's characteristics through two numbers -expressed in dpi (dots per inch). For example, a printer with a -resolution of 300x600 dpi has 300 pixels per inch in the horizontal direction, -and 600 in the vertical one. The resolution of a typical computer monitor -varies with its size (a 15" and 17" monitors don't have the same pixel -sizes at 640x480), and of course the graphics mode resolution. -

As a consequence, the size of text is usually given in points, -rather than device-specific pixels. Points are a simple physical -unit, where 1 point = 1/72th of an inch, in digital typography. As an example, -most roman books are printed with a body text which size is chosen between -10 and 14 points. -

It is thus possible to compute the size of text in pixels from the size -in points through the following computation : -

-

pixel_size = point_size * resolution / 72

- -

Where resolution is expressed in dpi. Note that because the horizontal -and vertical resolutions may differ, a single point size usually defines -different text width and height in pixels. -
  -

IMPORTANT NOTE: -
Unlike what is often thought, the "size of text in pixels" is not -directly related to the real dimensions of characters when they're displayed -or printed. The relationship between these two concepts is a bit more complex -and relate to some design choice made by the font designer. This is described -in more details the next sub-section (see the explanations on the EM square).

- -

-2. 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 or bezier -arcs. -

The arcs are defined through control points, and can be either -second-order (these are "conic beziers") or third-order ("cubic" beziers) -polynomials, depending on the font format. Hence, each point of the outline -has an associated flag indicating its type (normal or control point). -And scaling the points will scale the whole outline. -

Each glyph's original outline points are located on a grid of indivisible -units. The points are usually stored in a font file as 16-bit integer grid -coordinates, with the grid origin's being at (0,0); they thus range from --16384 to 16383. (even though point coordinates can be floats in other -formats such as Type 1, we'll restrict our analysis to integer ones, driven -by the need for simplicity..). -

IMPORTANT NOTE: -
The grid is always oriented like the traditional mathematical 2D -plane, i.e. the X axis from the left to the right, and the Y axis from -bottom to top. -

In creating the glyph outlines, a type designer uses an imaginary square -called the "EM square". Typically, the EM square can be thought of as a -tablet on which the character are drawn. 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 text dimension. -For example, a size of 12pt at 300x300 dpi 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 so. The EM is used as a convenience, and is a valuable convenience -from traditional typography. -
    -

    Note : Grid units are very often called "font units" or "EM units".

    - -

    NOTE: -
    As said before, the pixel_size computed in  the above formula -does not relate directly to the size of characters on the screen. It simply -is the size of the EM square if it was to be displayed directly. Each font -designer is free to place its glyphs as it pleases him within the square. -This explains why the letters of the following text have not the same height, -even though they're displayed at the same point size with distinct fonts -: -

    -

    - -

    As one can see, the glyphs of the Courier family are smaller than those -of Times New Roman, which themselves are slightly smaller than those of -Arial, even though everything is displayed or printed  at a size of -16 points. This only reflect design choices. -
     

    - -

    -3. Hinting and Bitmap rendering

    - -
    The outline as stored in a font file is called the "master" -outline, as its points coordinates are expressed in font units. Before -it can be converted into a bitmap, it must be scaled to a given size/resolution. -This is done through a very simple transform, but always creates undesirable -artifacts, e.g. stems of different widths or heights in letters like "E" -or "H". -

    As a consequence, proper glyph rendering needs the scaled points to -be aligned along the target device pixel grid, through an operation called -"grid-fitting", and often "hinting". One of its main purpose is to ensure -that important widths and heights are respected throughout the whole font -(for example, it is very often desirable that the "I" and the "T" have -their central vertical line of the same pixel width), as well as manage -features like stems and overshoots, which can cause problems at small pixel -sizes. -

    There are several ways to perform grid-fitting properly, for example -most scalable formats associate some control data or programs with each -glyph outline. Here is an overview : -
      -

    -
    explicit grid-fitting : -
    The TrueType format defines a stack-based virtual machine, -for which programs can be written with the help of more than 200 opcodes -(most of these relating to geometrical operations). Each glyph is thus -made of both an outline and a control program, its purpose being to perform -the actual grid-fitting in the way defined by the font designer.
    - -


    implicit grid-fitting (also called hinting) : -

    The Type 1 format takes a much simpler approach : each glyph -is made of an outline as well as several pieces called "hints" which are -used to describe some important features of the glyph, like the presence -of stems, some width regularities, and the like. There aren't a lot of -hint types, and it's up to the final renderer to interpret the hints in -order to produce a fitted outline.
    - -


    automatic grid-fitting : -

    Some formats simply include no control information with each -glyph outline, apart metrics like the advance width and height. It's then -up to the renderer to "guess" the more interesting features of the outline -in order to perform some decent grid-fitting.
    -
    -
    - -
    -


    The following table summarises the pros and cons of each scheme -:

    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    Grid-fitting scheme
    -
    -
    -
    -
    Pros
    -
    -
    -
    -
    Cons
    -
    -
    -
    -
    Explicit
    -
    -
    -
    -
    Quality -
    excellence at small sizes is possible. This is -very important for screen display. -

    Consistency -
    all renderers produce the same glyph bitmaps.

    -
    -
    -
    -
    Speed -
    intepreting bytecode can be slow if the glyph -programs are complex. -

    Size -
    glyph programs can be long -

    Technicity -
    it is extremely difficult to write good hinting -programs. Very few tools available.

    -
    -
    -
    -
    Implicit
    -
    -
    -
    -
    Size -
    hints are usually much smaller than explicit -glyph programs. -

    Speed -
    grid-fitting is usually a fast process

    -
    -
    -
    -
    Quality -
    often questionable at small sizes. Better with -anti-aliasing though. -

    Inconsistency -
    results can vary between different renderers, -or even distinct versions of the same engine.

    -
    -
    -
    -
    Automatic
    -
    -
    -
    -
    Size -
    no need for control information, resulting in -smaller font files. -

    Speed -
    depends on the grid-fitting algo.Usually faster -than explicit grid-fitting.

    -
    -
    -
    -
    Quality -
    often questionable at small sizes. Better with -anti-aliasing though -

    Speed -
    depends on the grid-fitting algo. -

    Inconsistency -
    results can vary between different renderers, -or even distinct versions of the same engine.

    -
    -
    -
    - -
    -

    -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, Korean, etc). Moreover, to render text, a virtual -point, located on the baseline, called the "pen position" or "origin", -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.

      - -
      - -
        -
      • -with a 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. -

        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.
        -Other, simpler metrics are: -

        the glyph's bounding box, also called "bbox" -

          this is an imaginary box that encloses all glyphs from the font, as -tightly as possible. It is represented by four fields, namely xMin, -yMin, -xMax, -and yMax, that can be computed for any outline. Their values can -be in font units (if measured in the original outline) or in fractional/integer -pixel units (when 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/bitmap. However, correct rendering of hinted glyphs needs the preservation -of important grid alignment on each glyph translation/placement on the -baseline.

        -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 line gap.
        -
      - -

      -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: -

        the left side bearing: a.k.a. bearingX -

          this is the horizontal distance from the current pen position to the -glyph's left bbox edge. It is positive for horizontal layouts, and most -generally negative for vertical one.
        - -


        the top side bearing: a.k.a. bearingY -

          this is the vertical distance from the baseline to the top of the glyph's -bbox. It is usually positive for horizontal layouts, and negative for vertical -ones
        - -


        the advance width: a.k.a. advanceX -

          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.
        - -


        the advance height: a.k.a. advanceY -

          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.
        - -


        the glyph width -

          this is simply 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.
        - -


        the glyph height -

          this is simply 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.
        - -


        the right side bearing -

          is 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.
        - -
        advance_width - left_side_bearing - (xMax-xMin)
        - -

        Here is a picture giving all the details for horizontal metrics : -

        -

        - -

        And here is another one for the vertical metrics : -

        -

        -
      - -

      -4. The effects of grid-fitting

      - -
        Because hinting aligns the glyph's control points to the pixel grid, -this process slightly modifies the dimensions of character images in ways -that differ from simple scaling. -

        For example, the image of the lowercase "m" letter sometimes fits a -square in the master grid. However, to make it readable at small pixel -sizes, hinting tends to enlarge its scaled outline in order to keep its -three legs distinctly visible, resulting in a larger character bitmap. -

        The glyph metrics are also influenced by the grid-fitting process. Mainly -because : -
          -

          -
        • -The image's width and height are altered. Even if this is only by one pixel, -it can make a big difference at small pixel sizes
        • - -
        • -The image's bounding box is modified, thus modifying the bearings
        • - -
        • -The advances must be updated. For example, the advance width must be incremented -when the hinted bitmap is larger than the scaled one, to reflect the augmented -glyph width.
        • -
        - -


        Note also that : -
          -

          -
        • -Because of hinting, simply scaling the font ascent or descent might not -give correct results. A simple solution consists in keeping the ceiling -of the scaled ascent, and floor of the scaled descent.
        • -
        - -
          -
        • -There is no easy way to get the hinted glyph and advance widths of a range -of glyphs, as hinting works differently on each outline. The only solution -is to hint each glyph separately and record the returned values. Some formats, -like TrueType, even include a table of pre-computed values for a small -set of common character pixel sizes.
        • -
        - -
          -
        • -Hinting depends on the final character width and height in pixels, which -means that it is highly resolution-dependent. This property makes correct -WYSIWYG layouts difficult to implement.
        • -
        - -


        IMPORTANT NOTE: -
        Performing 2D transforms on glyph outlines is very easy with FreeType. -However, when using translation on a hinted outlines, one should aways -take care of  exclusively using integer pixel distances (which -means that the parameters to the FT_Translate_Outline API should all be -multiples of 64, as the point coordinates are in 26.6 fixed float format). -

        Otherwise, the translation will simply ruin the hinter's work, -resulting in a very low quality bitmaps. -
          -
         

      - -

      - 5. Text widths and bounding box :

      - -
        As seen before, the "origin" of a given glyph corresponds to the position -of the pen on the baseline. It is not necessarily located on one of the -glyph's bounding box corners, unlike many typical bitmapped font formats. -In some cases, the origin can be out of the bounding box, in others, it -can be within it, depending on the shape of the given glyph. -

        Likewise, the glyph's "advance width" is the increment to apply to the -pen position during layout, and is not related to the glyph's "width", -which really is the glyph's bounding width. -
          -

        The same conventions apply to strings of text. This means that : -
          -

          -
            -
          • -The bounding box of a given string of text doesn't necessarily contain -the text cursor, nor is the latter located on one of its corners.
          • -
          - -
            -
          • -The string's advance width isn't related to its bounding box's dimensions. -Especially if it contains beginning and terminal spaces or tabs.
          • -
          - -
            -
          • -Finally, additional processing like kerning creates strings of text whose -dimensions are not directly related to the simple juxtaposition of individual -glyph metrics. For example, the advance width of "VA" isn't the sum of -the advances of "V" and "A" taken separately.
          • -
          -
        -
      -
    - -
    -

    - IV. Kerning

    - -
    The term 'kerning' refers to specific information used to adjust -the relative positions of coincident glyphs in a string of text. This section -describes several types of kerning information, as well as the way to process -them when performing text layout. -
      -

    -1. Kerning pairs

    - -
    Kerning consists in modifying the spacing between two successive -glyphs according to their outlines. For example, a "T" and a "y" can be -easily moved closer, as the top of the "y" fits nicely under the "T"'s -upper right bar. -

    When laying out text with only their standard widths, some consecutive -glyphs sometimes seem a bit too close or too distant. For example, the -space between the 'A' and the 'V' in the following word seems a little -wider than needed. -

    -

    - -

    Compare this to the same word, when the distance between these two letters -has been slightly reduced : -

    -

    - -

    As you can see, this adjustment can make a great difference. Some font -faces thus include a table containing kerning distances for a set of given -glyph pairs, used during text layout. Note that : -
      -

    -
      -
    • -The pairs are ordered, i.e. the space for pair (A,V) isn't necessarily -the space for pair (V,A). They also index glyphs, and not characters.
    • -
    - -
      -
    • -Kerning distances can be expressed in horizontal or vertical directions, -depending on layout and/or script. For example, some horizontal layouts -like arabic can make use of vertical kerning adjustments between successive -glyphs. A vertical script can have vertical kerning distances.
    • -
    - -
      -
    • -Kerning distances are expressed in grid units. They are usually oriented -in the X axis, which means that a negative value indicates that two glyphs -must be set closer in a horizontal layout.
    • -
    -
    -
    - -

    -2. Applying kerning

    - -
    Applying kerning when rendering text is a rather easy process. -It merely consists in adding the scaled kern distance to the pen position -before writing each next glyph. However, the typographically correct renderer -must take a few more details in consideration. -

    The "sliding dot" problem is a good example : many font faces include -a kerning distance between capital letters like "T" or "F" and a following -dot ("."), in order to slide the latter glyph just right to their main -leg. I.e. -

    -

    - -

    However, this sometimes requires additional adjustments between the -dot and the letter following it, depending on the shapes of the enclosing -letters. When applying "standard" kerning adjustments, the previous sentence -would become : -

    -

    - -

    Which clearly is too contracted. The solution here, as exhibited in -the first example is to only slide the dots when possible. Of course, this -requires a certain knowledge of the text's meaning. The above adjustments -would not necessarily be welcomed if we were rendering the final dot of -a given paragraph. -

    This is only one example, and there are many others showing that a real -typographer is needed to layout text properly. If not available, some kind -of user interaction or tagging of the text could be used to specify some -adjustments, but in all cases, this requires some support in applications -and text libraries. -

    For more mundane and common uses, however, we can have a very simple -algorithm, which  avoids the sliding dot problem, and others, though -not producing optimal results. It can be seen as : -
      -

    -
      -
    1. -place the first glyph on the baseline
    2. - -
    3. -save the location of the pen position/origin in pen1
    4. - -
    5. -adjust the pen position with the kerning distance between the first and -second glyph
    6. - -
    7. -place the second glyph and compute the next pen position/origin in pen2.
    8. - -
    9. -use pen1 as the next pen position if it is beyond pen2, use pen2 otherwise.
    10. -
    -
    -
    -
    - -

    - -

    - -

    -V. 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 :

    - -
    In this first example, we'll generate a simple string of Roman -text, i.e. with a horizontal left-to-right layout. Using exclusively pixel -metrics, the process looks like : -
    1) convert the character string into a series of glyph -indexes. -
    2) place the pen to the cursor position. -
    3) get or load the glyph image. -
    4) translate the glyph so that its 'origin' matches the pen position -
    5) render the glyph to the target device -
    6) increment the pen position by the glyph's advance width in pixels -
    7) start over at step 3 for each of the remaining glyphs -
    8) when all glyphs are done, set the text cursor to the new pen -position
    -Note that kerning isn't part of this algorithm.
    - -

    -2. Sub-pixel positioning :

    - -
    It is somewhat useful to use sub-pixel positioning when rendering -text. This is crucial, for example, to provide semi-WYSIWYG text layouts. -Text rendering is very similar to the algorithm described in sub-section -1, with the following few differences : -
      -
    • -The pen position is expressed in fractional pixels.
    • - -
    • -Because translating a hinted outline by a non-integer distance will ruin -its grid-fitting, the position of the glyph origin must be rounded before -rendering the character image.
    • - -
    • -The advance width is expressed in fractional pixels, and isn't necessarily -an integer.
    • -
    - -


    Which finally looks like : -

    1. convert the character string into a series of glyph -indexes. -
    2. place the pen to the cursor position. This can be a non-integer -point. -
    3. get or load the glyph image. -
    4. translate the glyph so that its 'origin' matches the rounded -pen position. -
    5. render the glyph to the target device -
    6. increment the pen position by the glyph's advance width in fractional -pixels. -
    7. start over at step 3 for each of the remaining glyphs -
    8. when all glyphs are done, set the text cursor to the new pen -position
    -Note that with fractional pixel positioning, the space between two given -letters isn't fixed, but determined by the accumulation of previous rounding -errors in glyph positioning.
    - -

    -3.  Simple kerning :

    - -
    Adding kerning to the basic text rendering algorithm is easy -: when a kerning pair is found, simply add the scaled kerning distance -to the pen position before step 4. Of course, the distance should be rounded -in the case of algorithm 1, though it doesn't need to for algorithm 2. -This gives us : -

    Algorithm 1 with kerning: -

    3) get or load the glyph image. -
    4) Add the rounded scaled kerning distance, if any, to the pen -position -
    5) translate the glyph so that its 'origin' matches the pen position -
    6) render the glyph to the target device -
    7) increment the pen position by the glyph's advance width in pixels -
    8) start over at step 3 for each of the remaining glyphs
    - -


    Algorithm 2 with kerning: -

    3) get or load the glyph image. -
    4) Add the scaled unrounded kerning distance, if any, to the pen -position. -
    5) translate the glyph so that its 'origin' matches the rounded -pen position. -
    6) render the glyph to the target device -
    7) increment the pen position by the glyph's advance width in fractional -pixels. -
    8) start over at step 3 for each of the remaining glyphs
    -Of course, the algorithm described in section IV can also be applied to -prevent the sliding dot problem if one wants to..
    - -

    -4. Right-To-Left Layout :

    - -
    The process of laying out arabic or hebrew text is extremely -similar. The only difference is that the pen position must be decremented -before the glyph rendering (remember : the advance width is always positive, -even for arabic glyphs). Thus, algorithm 1 becomes : -

    Right-to-left Algorithm 1: -

    3) get or load the glyph image. -
    4) Decrement the pen position by the glyph's advance width in pixels -
    5) translate the glyph so that its 'origin' matches the pen position -
    6) render the glyph to the target device -
    7) start over at step 3 for each of the remaining glyphs
    - -


    The changes to Algorithm 2, as well as the inclusion of kerning -are left as an exercise to the reader. -
      -
     

    - -

    -5. Vertical layouts :

    - -
    Laying out vertical text uses exactly the same processes, with -the following significant differences : -
      -
    -
  • -The baseline is vertical, and the vertical metrics must be used instead -of the horizontal one.
  • - -
  • -The left bearing is usually negative, but this doesn't change the fact -that the glyph origin must be located on the baseline.
  • - -
  • -The advance height is always positive, so the pen position must be decremented -if one wants to write top to bottom (assuming the Y axis is oriented upwards).
  • -
    -Through the following algorithm : -
    1) convert the character string into a series of glyph -indexes. -
    2) place the pen to the cursor position. -
    3) get or load the glyph image. -
    4) translate the glyph so that its 'origin' matches the pen position -
    5) render the glyph to the target device -
    6) decrement the vertical pen position by the glyph's advance height -in pixels -
    7) start over at step 3 for each of the remaining glyphs -
    8) when all glyphs are done, set the text cursor to the new pen -position
    -
    - -

    -6. WYSIWYG text layouts :

    - -
    As you probably know, the acronym WYSIWYG stands for 'What -You See Is What You Get'. Basically, this means that the output of -a document on the screen should match "perfectly" its printed version. -A true wysiwyg system requires two things : -

    device-independent text layout -

    Which means that the document's formatting is the same on the -screen than on any printed output, including line breaks, justification, -ligatures, fonts, position of inline images, etc..
    - -


    matching display and print character sizes -

    Which means that the displayed size of a given character should -match its dimensions when printed. For example, a text string which is -exactly 1 inch tall when printed should also appear 1 inch tall on the -screen (when using a scale of 100%).
    - -


    It is clear that matching sizes cannot be possible if the computer -has no knowledge of the physical resolutions of the display device(s) it -is using. And of course, this is the most common case ! That's not too -unfortunate, however  because most users really don't care about this -feature. Legibility is much more important. -

    When the Mac appeared, Apple decided to choose a resolution of 72 dpi -to describe the Macintosh screen to the font sub-system (whatever the monitor -used). This choice was most probably driven by the fact that, at this resolution, -1 point = 1 pixel. However; it neglected one crucial fact : as most users -tend to choose a document character size between 10 and 14 points, the -resultant displayed text was rather small and not too legible without scaling. -Microsoft engineers took notice of this problem and chose a resolution -of 96 dpi on Windows, which resulted in slightly larger, and more legible, -displayed characters (for the same printed text size). -

    These distinct resolutions explain some differences when displaying -text at the same character size on a Mac and a Windows machine. Moreover, -it is not unusual to find some TrueType fonts with enhanced hinting (tech -note: through delta-hinting) for the sizes of 10, 12, 14 and 16 points -at 96 dpi. -
      -

    As for device-independent text, it is a notion that is, unfortunately, -often abused. For example, many word processors, including MS Word, do -not really use device-independent glyph positioning algorithms when laying -out text. Rather, they use the target printer's resolution to compute hinted -glyph metrics for the layout. Though it guarantees that the printed version -is always the "nicest" it can be, especially for very low resolution printers -(like dot-matrix), it has a very sad effect : changing the printer can -have dramatic effects on the whole document layout, especially if -it makes strong use of justification, uses few page breaks, etc.. -

    Because the glyph metrics vary slightly when the resolution changes -(due to hinting), line breaks can change enormously, when these differences -accumulate over long runs of text. Try for example printing a very long -document (with no page breaks) on a 300 dpi ink-jet printer, then the same -one on a 3000 dpi laser printer : you'll be extremely lucky if your final -page count didn't change between the prints ! Of course, we can still call -this WYSIWYG, as long as the printer resolution is fixed !! -

    Some applications, like Adobe Acrobat, which targeted device-independent -placement from the start, do not suffer from this problem. There are two -ways to achieve this : either use the scaled and unhinted glyph metrics -when laying out text both in the rendering and printing processes, or simply -use wathever metrics you want and store them with the text in order to -get sure they're printed the same on all devices (the latter being probably -the best solution, as it also enables font substitution without breaking -text layouts). -

    Just like matching sizes, device-independent placement isn't necessarily -a feature that most users want. However, it is pretty clear that for any -kind of professional document processing work, it is a requirement.

    -
    - -

    - -

    - -

    -VI. FreeType outlines :

    - -
    The purpose of this section is to present the way FreeType -manages vectorial outlines, as well as the most common operations that -can be applied on them. -
      -

    -1. FreeType outline description and structure :

    - -
    -

    -a. Outline curve decomposition :

    - -
    An outline is described as a series of closed contours in the -2D plane. Each contour is made of a series of line segments and bezier -arcs. Depending on the file format, these can be second-order or third-order -polynomials. The former are also called quadratic or conic arcs, and they -come from the TrueType format. The latter are called cubic arcs and mostly -come from the Type1 format. -

    Each arc is described through a series of start, end and control points. -Each point of the outline has a specific tag which indicates wether it -is used to describe a line segment or an arc. The tags can take the following -values : -
      -
     

    - -
    - - - - - - - - - - - - - - - - - -
    -
    FT_Curve_Tag_On 
    -
    -
    Used when the point is "on" the curve. This corresponds to -start and end points of segments and arcs. The other tags specify what -is called an "off" point, i.e. one which isn't located on the contour itself, -but serves as a control point for a bezier arc.
    -
    -
    FT_Curve_Tag_Conic
    -
    -
    Used for an "off" point used to control a conic bezier arc.
    -
    -
    FT_Curve_Tag_Cubic
    -
    -
    Used for an "off" point used to control a cubic bezier arc.
    -
    - -
      -

    The following rules are applied to decompose the contour's points into -segments and arcs : -

    -
  • -two successive "on" points indicate a line segment joining them.
  • -
    -
    - -
      -
        -
      • -one conic "off" point amidst two "on" points indicates a conic bezier arc, -the "off" point being the control point, and the "on" ones the start and -end points.
      • -
      -
    - -
      -
        -
      • -Two successive cubic "off" points amidst two "on" points indicate a cubic -bezier arc. There must be exactly two cubic control points and two on points -for each cubic arc (using a single cubic "off" point between two "on" points -is forbidden, for example).
      • -
      -
    - -
      -
        -
      • -finally, two successive conic "off" points forces the rasterizer to create -(during the scan-line conversion process exclusively) a virtual "on" point -amidst them, at their exact middle. This greatly facilitates the definition -of successive conic bezier arcs. Moreover, it's the way outlines are described -in the TrueType specification.
      • -
      - -


      Note that it is possible to mix conic and cubic arcs in a single -contour, even though no current font driver produces such outlines. -
       

    - -
    - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -

    -b. Outline descriptor :

    - -
    A FreeType outline is described through a simple structure, -called FT_Outline, which fields are : -
      -
      -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    n_pointsthe number of points in the outline
    n_contoursthe number of contours in the outline
    pointsarray of point coordinates
    contoursarray of contour end indices
    flagsarray of point flags
    - -

    Here, points is a pointer to an array of FT_Vector -records, used to store the vectorial coordinates of each outline point. -These are expressed in 1/64th of a pixel, which is also known as the 26.6 -fixed float format. -

    contours is an array of point indices used to delimit -contours in the outline. For example, the first contour always starts at -point 0, and ends a point contours[0]. The second contour -starts at point "contours[0]+1" and ends at contours[1], -etc.. -

    Note that each contour is closed, and that n_points -should be equal to "contours[n_contours-1]+1" for a valid -outline. -

    Finally, flags is an array of bytes, used to store each -outline point's tag. -
      -
     

    -
    - -

    -2. Bounding and control box computations :

    - -
    A bounding box (also called "bbox") is simply -the smallest possible rectangle that encloses the shape of a given outline. -Because of the way arcs are defined, bezier control points are not necessarily -contained within an outline's bounding box. -

    This situation happens when one bezier arc is, for example, the upper -edge of an outline and an off point happens to be above the bbox. However, -it is very rare in the case of character outlines because most font designers -and creation tools always place on points at the extrema of each curved -edges, as it makes hinting much easier. -

    We thus define the control box (a.k.a. the "cbox") as -the smallest possible rectangle that encloses all points of a given outline -(including its off points). Clearly, it always includes the bbox, and equates -it in most cases. -

    Unlike the bbox, the cbox is also much faster to compute. -
      -

    - - - - - -
    - -

    Control and bounding boxes can be computed automatically through the -functions FT_Get_Outline_CBox and FT_Get_Outline_BBox. -The former function is always very fast, while the latter may be -slow in the case of "outside" control points (as it needs to find the extreme -of conic and cubic arcs for "perfect" computations). If this isn't the -case, it's as fast as computing the control box. -

    Note also that even though most glyph outlines have equal cbox and bbox -to ease hinting, this is not necessary the case anymore when a -
    transform like rotation is applied to them. -
     

    - -

    - 3. Coordinates, scaling and grid-fitting :

    - -
    An outline point's vectorial coordinates are expressed in the -26.6 format, i.e. in 1/64th of a pixel, hence coordinates (1.0, -2.5) is -stored as the integer pair ( x:64, y: -192 ). -

    After a master glyph outline is scaled from the EM grid to the current -character dimensions, the hinter or grid-fitter is in charge of aligning -important outline points (mainly edge delimiters) to the pixel grid. Even -though this process is much too complex to be described in a few lines, -its purpose is mainly to round point positions, while trying to preserve -important properties like widths, stems, etc.. -

    The following operations can be used to round vectorial distances in -the 26.6 format to the grid : -

    -

    round(x)   ==  (x+32) & -64 -
    floor(x)   ==       x & --64 -
    ceiling(x) ==  (x+63) & -64

    - -

    Once a glyph outline is grid-fitted or transformed, it often is interesting -to compute the glyph image's pixel dimensions before rendering it. To do -so, one has to consider the following : -

    The scan-line converter draws all the pixels whose centers fall -inside the glyph shape. It can also detect "drop-outs", i.e. -discontinuities coming from extremely thin shape fragments, in order to -draw the "missing" pixels. These new pixels are always located at a distance -less than half of a pixel but one cannot predict easily where they'll appear -before rendering. -

    This leads to the following computations : -
      -

      -
    • -compute the bbox
    • -
    - -
      -
    • -grid-fit the bounding box with the following :
    • -
    - -
      -
        xmin = floor( bbox.xMin ) -
        xmax = ceiling( bbox.xMax ) -
        ymin = floor( bbox.yMin ) -
        ymax = ceiling( bbox.yMax )
      - -
    • -return pixel dimensions, i.e. width = (xmax - xmin)/64 and height -= (ymax - ymin)/64
    • -
    - -


    By grid-fitting the bounding box, one guarantees that all the pixel -centers that are to be drawn, including those coming from drop-out -control, will be within the adjusted box. Then the -box's dimensions in pixels can be computed. -

    Note also that, when translating a grid-fitted outline, -one should always use integer distances to -move an outline in the 2D plane. Otherwise, glyph edges won't be aligned -on the pixel grid anymore, and the hinter's work will be lost, producing -very -low quality bitmaps and pixmaps..

    -
    - -
    -

    -VII. FreeType bitmaps :

    - -
    The purpose of this section is to present the way FreeType -manages bitmaps and pixmaps, and how they relate to the concepts previously -defined. The relationships between vectorial and pixel coordinates is explained. -
      -

    -1. FreeType bitmap and pixmap descriptor :

    - -
    A bitmap or pixmap is described through a single structure, -called FT_Raster_Map. It is a simple descriptor whose fields are -: -
      -
      -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FT_Raster_Map
    rowsthe number of rows, i.e. lines, in the bitmap
    widththe number of horizontal pixels in the bitmap
    colsthe number of "columns", i.e. bytes per line, in the bitmap
    flowthe bitmap's flow, i.e. orientation of rows (see below)
    pix_bitsthe number of bits per pixels. valid values are 1, 4, 8 and 16
    buffera typeless pointer to the bitmap pixel bufer
    - -

    The bitmap's flow determines wether the rows in the -pixel buffer are stored in ascending or descending order. Possible values -are FT_Flow_Up (value 1) and FT_Flow_Down -(value -1). -

    Remember that FreeType uses the Y upwards convention in the 2D -plane. Which means that a coordinate of (0,0) always refer to the lower-left -corner of a bitmap. -

    In the case of an 'up' flow, the rows are stored in increasing -vertical position, which means that the first bytes of the pixel buffer -are part of the lower bitmap row. On the opposite, a 'down' -flow means that the first buffer bytes are part of the upper bitmap -row, i.e. the last one in ascending order. -

    As a hint, consider that when rendering an outline into a Windows or -X11 bitmap buffer, one should always use a down flow in the bitmap descriptor. -
      -

    - - - - - - - - - - - -
    -
    - -

    -2. Vectorial versus pixel coordinates :

    - -
    This sub-section explains the differences between vectorial -and pixel coordinates. To make things clear, brackets will be used to describe -pixel coordinates, e.g. [3,5], while parentheses will be used for vectorial -ones, e.g. (-2,3.5). -

    In the pixel case, as we use the Y upwards convention, the coordinate -[0,0] always refers to the lower left pixel of a bitmap, while coordinate -[width-1, rows-1] to its upper right pixel. -

    In the vectorial case, point coordinates are expressed in floating units, -like (1.25, -2.3). Such a position doesn't refer to a given pixel, but -simply to an immaterial point in the 2D plane -

    The pixels themselves are indeed square boxes of the 2D plane, -which centers lie in half pixel coordinates. For example, the lower -left pixel of a bitmap is delimited by the square (0,0)-(1,1), -its center being at location (0.5,0.5). -

    This introduces some differences when computing distances. For example, -the "length" in pixels of the line [0,0]-[10,0] is 11. However, -the vectorial distance between (0,0)-(10,0) covers exactly 10 pixel centers, -hence its length if 10. -

    -
    - -

    -3. Converting outlines into bitmaps and pixmaps :

    - -
    Generating a bitmap or pixmap image from a vectorial image -is easy with FreeType. However, one must understand a few points regarding -the positioning of the outline in the 2D plane before calling the function -FT_Get_Outline_Bitmap. -These are : -
      -
      -
    • -The glyph loader and hinter always places the outline in the 2D plane so -that (0,0) matches its character origin. This means that the glyphÂ’s outline, -and corresponding bounding box, can be placed anywhere in the 2D plane -(see the graphics in section III).
    • -
    - -
      -
    • -The target bitmapÂ’s area is mapped to the 2D plane, with its lower left -corner at (0,0). This means that a bitmap or pixmap of dimensions [w,h] -will be mapped to a 2D rectangle window delimited by (0,0)-(w,h).
    • -
    - -
      -
    • -When calling FT_Get_Outline_Bitmap, everything that falls -within the bitmap window is rendered, the rest is ignored.
    • -
    - -


    A common mistake made by many developers when they begin using FreeType -is believing that a loaded outline can be directly rendered in a bitmap -of adequate dimensions. The following images illustrate why this is a problem -: -

      -
        -
      • -the first image shows a loaded outline in the 2D plane.
      • - -
      • -the second one shows the target window for a bitmap of arbitrary dimensions -[w,h]
      • - -
      • -the third one shows the juxtaposition of the outline and window in the -2D plane
      • - -
      • -the last image shows what will really be rendered in the bitmap.
      • -
      -
    - -
    - -


    -
    -
    -
    -
    -

    Indeed, in nearly all cases, the loaded or transformed outline must -be translated before it is rendered into a target bitmap, in order to adjust -its position relative to the target window. -

    For example, the correct way of creating a standalone glyph bitmap -is thus to : -
      -

      -
    • -Compute the size of the glyph bitmap. It can be computed directly from -the glyph metrics, or by computing its bounding box (this is useful when -a transform has been applied to the outline after the load, as the glyph -metrics are not valid anymore).
    • -
    - -
      -
    • -Create the bitmap with the computed dimensions. DonÂ’t forget to fill the -pixel buffer with the background color.
    • -
    - -
      -
    • -Translate the outline so that its lower left corner matches (0,0). DonÂ’t -forget that in order to preserve hinting, one should use integer, i.e. -rounded distances (of course, this isnÂ’t required if preserving hinting -information doesnÂ’t matter, like with rotated text). Usually, this means -translating with a vector ( -ROUND(xMin), -ROUND(yMin) ).
    • -
    - -
      -
    • -Call the function FT_Get_Outline_Bitmap.
    • -
    - -


    In the case where one wants to write glyph images directly into -a large bitmap, the outlines must be translated so that their vectorial -position correspond to the current text cursor/character origin.

    -
    - -

    - -

    - -

    -VII. FreeType anti-aliasing :

    -IMPORTANT NOTE : -
    This section is still in progress, as the way FreeType 2 handles anti-aliased -rendering hasn't been definitely set yet. The main reason being that a -flexible way of doing things is needed in order to allow further improvements -in the raster (i.e. number of gray levels > 100, etc..). -
    -

    -1. What is anti-aliasing :

    - -
    Anti-aliasing works by using various levels of grays to reduce -the "staircase" artefacts visible on the diagonals and curves of glyph -bitmaps. It is a way to artificially enhance the display resolution of -the target device. It can smooth out considerably displayed or printed -text.
    - -

    -2. How does it work with FreeType :

    - -
    FreeType's scan-line converter is able to produce anti-aliased -output directly. It is however limited to 8-bit pixmaps and 5 levels of -grays (or 17 levels, depending on a build configuration option). Here's -how one should use it : -

    -a. Set the gray-level palette :

    - -
    The scan-line converter uses 5 levels for anti-aliased output. -Level 0 corresponds to the text background color (e.g. white), and level -5 to the text foreground color. Intermediate levels are used for intermediate -shades of grays. -

    You must set the raster's palette when you want to use different colors, -use the function FT_Raster_Set_Palette as in : -

    { -
      static const char  gray_palette[5] = { 0, 7, 15, 31, -63 }; -
      Â… -
      error = FT_Set_Raster_Palette( library, 5, palette ); -
    } -
      -

      -
    • -The first parameter is a handle to a FreeType library object. See the user -guide for more details (the library contains a scan-line converter object).
    • -
    - -
      -
    • -The second parameter is the number of entries in the gray-level palette. -Valid values are 5 and 17 for now, but this may change in later implementations.
    • -
    - -
      -
    • -The last parameter is a pointer to a char table containing the pixel value -for each of the gray-levels. In this example, we use a background color -of 0, a foreground color of 63, and intermediate values in-between.
    • -
    - -


    The palette is copied in the raster object, as well as processed -to build several lookup-tables necessary for the internal anti-aliasing -algorithm. -
     

    - -

    -b. Render the pixmap :

    - -
    The scan-line converter doesn't create bitmaps or pixmaps, -it simply renders into those that are passed as parameters to the function -FT_Get_Outline_Bitmap. -To render an anti-aliased pixmap, simply set the target bitmapÂ’s depth -to 8. Note however that this target 8-bit pixmap must always have a 'cols' -field padded to 32-bits, which means that the number of bytes per lines -of the pixmap must be a multiple of 4 ! -

    Once the palette has been set, and the pixmap buffer has been created -to receive the glyph image, simply call FT_Get_Outline_Bitmap. -Take care of clearing the target pixmap with the background color before -calling this function. For the sake of simplicity and efficiency, the raster -is not able to compose anti-aliased glyph images on a pre-existing images. -

    Here's some code demonstrating how to load and render a single glyph -pixmap : -

    { -
      FT_Outline     outline; -
      FT_Raster_Map  pixmap; -
      FT_BBox        cbox; -
      Â… -

      // load the outline -
      Â… -

      // compute glyph dimensions (grid-fit cbox, etc..) -
      FT_Get_Outline_CBox( &outline, &cbox ); -

      cbox.xMin = cbox.xMin & -64;       -// floor(xMin) -
      cbox.yMin = cbox.yMin & -64;       -// floor(yMin) -
      cbox.xMax = (cbox.xMax+32) & -64;  // ceiling(xMax) -
      cbox.yMax = (cbox.yMax+32) & -64;  // ceiling(yMax) -

      pixmap.width = (cbox.xMax - cbox.xMin)/64; -
      pixmap.rows  = (cbox.yMax - cbox.yMin)/64; -

      // fill the pixmap descriptor and create the pixmap buffer -
      // don't forget to pad the 'cols' field to 32 bits -
      pixmap.pix_bits = 8; -
      pixmap.flow     = FT_Flow_Down; -
      pixmap.cols     = (pixmap.width+3) & --4;  // pad 'cols' to 32 bits -
      pixmap.buffer   = malloc( pixmap.cols * pixmap.rows -); -

      // fill the pixmap buffer with the background color -
      // -
      memset( pixmap.buffer, 0, pixmap.cols*pixmap.rows ); -

      // translate the outline to match (0,0) with the glyph's -
      // lower left corner (ignore the bearings) -
      // the cbox is grid-fitted, we won't ruin the hinting. -
      // -
      FT_Translate_Outline( &outline, -cbox.xMin, -cbox.yMin -); -

      // render the anti-aliased glyph pixmap -
      error = FT_Get_Outline_Bitmap( library, &outline, &pixmap -); -

      // save the bearings for later use.. -
      corner_x = cbox.xMin / 64; -
      corner_y = cbox.yMin / 64; -
    } -

    The resulting pixmap is always anti-aliased.

    -
    - -

    -3. Possible enhancements :

    - -
    FreeType's raster (i.e. its scan-line converter) is currently -limited to producing either 1-bit bitmaps or anti-aliased 8-bit pixmaps. -It is not possible, for example, to draw directly a bitmapped glyph image -into a 4, 8 or 16-bit pixmap through a call to FT_Get_Outline_Bitmap. -

    Moreover, the anti-aliasing filter is limited to use 5 or 17 levels -of grays (through 2x2 and 4x4 sub-sampling). There are cases where this -could seem insufficient for optimal results and where a higher number of -levels like 64 or 128 would be a good thing. -

    These enhancements are all possible but not planned for an immediate -future of the FreeType engine.

    -
    - - - diff --git a/subsys/win32k/freetype/docs/glyphs/points_conic.png b/subsys/win32k/freetype/docs/glyphs/points_conic.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/points_conic.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/points_conic2.png b/subsys/win32k/freetype/docs/glyphs/points_conic2.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/points_conic2.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/points_cubic.png b/subsys/win32k/freetype/docs/glyphs/points_cubic.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/points_cubic.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/points_segment.png b/subsys/win32k/freetype/docs/glyphs/points_segment.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/points_segment.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/twlewis1.png b/subsys/win32k/freetype/docs/glyphs/twlewis1.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/twlewis1.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/twlewis2.png b/subsys/win32k/freetype/docs/glyphs/twlewis2.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/twlewis2.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/glyphs/up_flow.png b/subsys/win32k/freetype/docs/glyphs/up_flow.png deleted file mode 100644 index f1ad755..0000000 --- a/subsys/win32k/freetype/docs/glyphs/up_flow.png +++ /dev/null @@ -1 +0,0 @@ -‰PNG diff --git a/subsys/win32k/freetype/docs/tutorial/index.html b/subsys/win32k/freetype/docs/tutorial/index.html deleted file mode 100644 index fb8a5b3..0000000 --- a/subsys/win32k/freetype/docs/tutorial/index.html +++ /dev/null @@ -1,871 +0,0 @@ - - - - - - FreeType 2 Tutorial - - - - -

    - FreeType 2.0 Tutorial -

    - -

    - © 2000 David Turner - (david@freetype.org)
    - © 2000 The FreeType Development Team - (www.freetype.org) -

    - -
    - - -
    - -
    - -

    - Introduction -

    - -

    This short tutorial will teach you how to use the FreeType 2 - library in your own applications.

    - -
    - -

    - 1. Header files -

    - -

    To include the main FreeType header file, simply say

    - - -
    -    #include <freetype/freetype.h>
    -
    - -

    in your application code. Note that other files are available in the - FreeType include directory, most of them being included by - "freetype.h". They will be described later in this - tutorial.

    - -
    - -

    - 2. Initialize the library -

    - -

    Simply create a variable of type FT_Library named, for - example, library, and call the function - FT_Init_FreeType() as in

    - - -
    -    #include <freetype/freetype.h>
    -
    -    FT_Library  library;
    -
    -    ...
    -
    -    {
    -      ...
    -      error = FT_Init_FreeType( &library );
    -      if ( error )
    -      {
    -        ... an error occurred during library initialization ...
    -      }
    -    }
    -
    - -

    This function is in charge of the following:

    - -
      -
    • -

      Creating a new instance of the FreeType 2 library, and set - the handle library to it.

      -
    • -
    • -

      Load each modules that FreeType knows about in the library. - This means that by default, your new library object is able - to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts - gracefully.

      -
    • -
    - -

    As you can see, the function returns an error code, like most others - in the FreeType API. An error code of 0 always means that - the operation was successful; otherwise, the value describes the error, - and library is set to NULL.

    - -
    - -

    - 3. Load a font face -

    - -

    - a. From a font file -

    - -

    Create a new face object by calling FT_New_Face. - A face describes a given typeface and style. For example, - "Times New Roman Regular" and "Times New Roman Italic" correspond to - two different faces.

    - - -
    -    FT_Library   library;   /* handle to library     */
    -    FT_Face      face;      /* handle to face object */
    -
    -    error = FT_Init_FreeType( &library );
    -    if ( error ) { ... }
    -
    -    error = FT_New_Face( library,
    -                         "/usr/share/fonts/truetype/arial.ttf",
    -                         0,
    -                         &face );
    -    if ( error == FT_Err_Unknown_File_Format )
    -    {
    -      ... the font file could be opened and read, but it appears
    -      ... that its font format is unsupported
    -    }
    -    else if ( error )
    -    {
    -      ... another error code means that the font file could not
    -      ... be opened or read, or simply that it is broken...
    -    }
    -
    - -

    As you can certainly imagine, FT_New_Face opens a font - file, then tries to extract one face from it. Its parameters are

    - - - - - - - - - - - - - - - - - - -
    - library - -

    handle to the FreeType library instance where the face object - is created

    -
    - filepathname - -

    the font file pathname (standard C string).

    -
    - face_index - -

    Certain font formats allow several font faces to be embedded - in a single file.

    - -

    This index tells which face you want to load. An error will - be returned if its value is too large.

    - -

    Index 0 always work though.

    -
    - face - -

    A pointer to the handle that will be set to describe - the new face object.

    - -

    It is set to NULL in case of error.

    -
    - -

    To know how many faces a given font file contains, simply load its - first face (use face_index=0), then see the value of - face->num_faces which indicates how many faces are embedded - in the font file.

    - -

    - b. From memory -

    - -

    In the case where you have already loaded the font file in memory, - you can similarly create a new face object for it by calling - FT_New_Memory_Face as in

    - - -
    -    FT_Library   library;   /* handle to library     */
    -    FT_Face      face;      /* handle to face object */
    -
    -    error = FT_Init_FreeType( &library );
    -    if ( error ) { ... }
    -
    -    error = FT_New_Memory_Face( library,
    -                                buffer,    /* first byte in memory */
    -                                size,      /* size in bytes        */
    -                                0,         /* face_index           */
    -                                &face );
    -    if ( error ) { ... }
    -
    - -

    As you can see, FT_New_Memory_Face() simply takes a - pointer to the font file buffer and its size in bytes instead of a - file pathname. Other than that, it has exactly the same semantics as - FT_New_Face().

    - -

    - c. From other sources (compressed files, network, etc.) -

    - -

    There are cases where using a file pathname or preloading the file - in memory is simply not enough. With FreeType 2, it is possible - to provide your own implementation of i/o routines.

    - -

    This is done through the FT_Open_Face() function, which - can be used to open a new font face with a custom input stream, select - a specific driver for opening, or even pass extra parameters to the - font driver when creating the object. We advise you to refer to the - FreeType 2 reference manual in order to learn how to use it.

    - -

    Note that providing a custom stream might also be used to access a - TrueType font embedded in a Postscript Type 42 wrapper.

    - -
    - -

    - 4. Accessing face content -

    - -

    A face object models all information that globally describes - the face. Usually, this data can be accessed directly by dereferencing - a handle, like

    - - - - - - - - - - - - - - - - - - - - - - -
    - face->num_glyphs - -

    Gives the number of glyphs available in the font face. - A glyph is simply a character image. It doesn't necessarily - correspond to a character code though.

    -
    - face->flags - -

    A 32-bit integer containing bit flags used to describe some - face properties. For example, the flag - FT_FACE_FLAG_SCALABLE is used to indicate that the face's - font format is scalable and that glyph images can be rendered for - all character pixel sizes. For more information on face flags, - please read the FreeType 2 API Reference.

    -
    - face->units_per_EM - -

    This field is only valid for scalable formats (it is set to 0 - otherwise). It indicates the number of font units covered by the - EM.

    -
    - face->num_fixed_sizes - -

    This field gives the number of embedded bitmap strikes - in the current face. A strike is simply a series of - glyph images for a given character pixel size. For example, a - font face could include strikes for pixel sizes 10, 12 - and 14. Note that even scalable font formats can have - embedded bitmap strikes!

    -
    - face->fixed_sizes - -

    this is a pointer to an array of FT_Bitmap_Size - elements. Each FT_Bitmap_Size indicates the horizontal - and vertical pixel sizes for each of the strikes that are - present in the face.

    -
    - -

    For a complete listing of all face properties and fields, please read - the FreeType 2 API Reference.

    - -


    - -

    - 5. Setting the current pixel size -

    - -

    FreeType 2 uses "size objects" to model all - information related to a given character size for a given face. - For example, a size object will hold the value of certain metrics - like the ascender or text height, expressed in 1/64th of a pixel, - for a character size of 12 points.

    - -

    When the FT_New_Face function is called (or one of its - cousins), it automatically creates a new size object for - the returned face. This size object is directly accessible as - face->size.

    - -

    NOTA BENE: a single face object can deal with one or more size - objects at a time, however, this is something that few programmers - really need to do. We have thus have decided to simplify the API for - the most common use (i.e. one size per face), while keeping this - feature available through additional fuctions.

    - -

    When a new face object is created, its size object defaults to the - character size of 10 pixels (both horizontally and vertically) for - scalable formats. For fixed-sizes formats, the size is more or less - undefined, which is why you must set it before trying to load a - glyph.

    - -

    To do that, simply call FT_Set_Char_Size(). Here is an - example where the character size is set to 16pt for a 300x300 dpi - device:

    - - -
    -    error = FT_Set_Char_Size(
    -              face,    /* handle to face object           */
    -              0,       /* char_width in 1/64th of points  */
    -              16*64,   /* char_height in 1/64th of points */
    -              300,     /* horizontal device resolution    */
    -              300 );   /* vertical device resolution      */
    -
    - -

    You will notice that:

    - -
      -
    • -

      The character width and heights are specified in 1/64th of - points. A point is a physical distance, equaling 1/72th - of an inch, it's not a pixel..

      -

    • -
    • -

      The horizontal and vertical device resolutions are expressed in - dots-per-inch, or dpi. You can use 72 or - 96 dpi for display devices like the screen. The resolution - is used to compute the character pixel size from the character - point size.

      -
    • -
    • -

      A value of 0 for the character width means "same as - character height", a value of 0 for the character height - means "same as character width". Otherwise, it is possible - to specify different char widths and heights.

      -
    • -
    • -

      Using a value of 0 for the horizontal or vertical resolution means - 72 dpi, which is the default.

      -
    • -
    • -

      The first argument is a handle to a face object, not a size - object. That's normal, and must be seen as a convenience.

      -
    • -
    - -

    This function computes the character pixel size that corresponds to - the character width and height and device resolutions. However, if you - want to specify the pixel sizes yourself, you can simply call - FT_Set_Pixel_Sizes(), as in

    - - -
    -    error = FT_Set_Pixel_Sizes(
    -              face,   /* handle to face object            */
    -              0,      /* pixel_width                      */
    -              16 );   /* pixel_height                     */
    -
    - -

    This example will set the character pixel sizes to 16x16 pixels. - As previously, a value of 0 for one of the dimensions means - "same as the other".

    - -

    Note that both functions return an error code. Usually, an error - occurs with a fixed-size font format (like FNT or PCF) when trying to - set the pixel size to a value that is not listed in the - face->fixed_sizes array.

    - -
    - -

    - 6. Loading a glyph image -

    - -

    - a. Converting a character code into a glyph index -

    - -

    Usually, an application wants to load a glyph image based on its - character code, which is a unique value that defines the - character for a given encoding. For example, the character - code 65 represents the `A' in ASCII encoding.

    - -

    A face object contains one or more tables, called - charmaps, that are used to convert character codes to glyph - indices. For example, most TrueType fonts contain two charmaps. One - is used to convert Unicode character codes to glyph indices, the other - is used to convert Apple Roman encoding into glyph indices. Such - fonts can then be used either on Windows (which uses Unicode) and - Macintosh (which uses Apple Roman, bwerk). Note also that a given - charmap might not map to all the glyphs present in the font.

    - -

    By default, when a new face object is created, it lists all the - charmaps contained in the font face and selects the one that supports - Unicode character codes if it finds one. Otherwise, it tries to find - support for Latin-1, then ASCII.

    - -

    We will describe later how to look for specific charmaps in a face. - For now, we will assume that the face contains at least a Unicode - charmap that was selected during FT_New_Face(). To convert a - Unicode character code to a font glyph index, we use - FT_Get_Char_Index() as in

    - - -
    -    glyph_index = FT_Get_Char_Index( face, charcode );
    -
    - -

    This will look the glyph index corresponding to the given - charcode in the charmap that is currently selected for the - face. If charmap is selected, the function simply returns the - charcode.

    - -

    Note that this is one of the rare FreeType functions that do not - return an error code. However, when a given character code has no - glyph image in the face, the value 0 is returned. By convention, - it always correspond to a special glyph image called the missing - glyph, which usually is represented as a box or a space.

    - -

    - b. Loading a glyph from the face -

    - -

    Once you have a glyph index, you can load the corresponding glyph - image. Note that the glyph image can be in several formats. For - example, it will be a bitmap for fixed-size formats like FNT, FON, or - PCF. It will also be a scalable vector outline for formats like - TrueType or Type 1. The glyph image can also be stored in an - alternate way that is not known at the time of writing this - documentation.

    - -

    The glyph image is always stored in a special object called a - glyph slot. As its name suggests, a glyph slot is simply a - container that is able to hold one glyph image at a time, be it a - bitmap, an outline, or something else. Each face object has a single - glyph slot object that can be accessed as - face->glyph.

    - -

    Loading a glyph image into the slot is performed by calling - FT_Load_Glyph() as in

    - - -
    -    error = FT_Load_Glyph( 
    -              face,          /* handle to face object */
    -              glyph_index,   /* glyph index           */
    -              load_flags );  /* load flags, see below */
    -
    - -

    The load_flags value is a set of bit flags used to - indicate some special operations. The default value - FT_LOAD_DEFAULT is 0.

    - -

    This function will try to load the corresponding glyph image - from the face. Basically, this means that:

    - -
      -
    • -

      If a bitmap is found for the corresponding glyph and pixel - size, it will in the slot (embedded bitmaps are always - favored over native image formats, because we assume that - they are higher-quality versions of the same image. This - can be ignored by using the FT_LOAD_NO_BITMAP flag)

      -
    • - -
    • -

      Otherwise, a native image for the glyph will be loaded. - It will also be scaled to the current pixel size, as - well as hinted for certain formats like TrueType and - Type1.

      -
    • -
    - -

    The field glyph->format describe the format - used to store the glyph image in the slot. If it is not - ft_glyph_format_bitmap, one can immediately - convert it to a bitmap through FT_Render_Glyph, - as in:

    - - -
    -   error = FT_Render_Glyph(
    -                  face->glyph,      /* glyph slot  */
    -		  render_mode );    /* render mode */
    -      
    -
    - -

    The parameter render_mode is a set of bit flags used - to specify how to render the glyph image. Set it to 0 to render - a monochrome bitmap, or to ft_render_mode_antialias to - generate a high-quality (256 gray levels) anti-aliased bitmap - from the glyph image.

    - -

    Once you have a bitmap glyph image, you can access it directly - through glyph->bitmap (a simple bitmap descriptor), - and position it through glyph->bitmap_left and - glyph->bitmap_top.

    - -

    Note that bitmap_left is the horizontal distance from the - current pen position to the left-most border of the glyph bitmap, - while bitmap_top is the vertical distance from the - pen position (on the baseline) to the top-most border of the - glyph bitmap. It is positive to indicate an upwards - distance.

    - -

    The next section will detail the content of a glyph slot and - how to access specific glyph information (including metrics).

    - -

    - c. Using other charmaps -

    - -

    As said before, when a new face object is created, it will look for - a Unicode, Latin-1, or ASCII charmap and select it. The currently - selected charmap is accessed via face->charmap. This - field is NULL when no charmap is selected, which typically happens - when you create a new FT_Face object from a font file that - doesn't contain an ASCII, Latin-1, or Unicode charmap (rare - stuff).

    - -

    There are two ways to select a different charmap with FreeType 2. - The easiest is when the encoding you need already has a corresponding - enumeration defined in <freetype/freetype.h>, as - ft_encoding_big5. In this case, you can simply call - FT_Select_CharMap as in:

    - -
    -    error = FT_Select_CharMap(
    -                    face,                 /* target face object */
    -		    ft_encoding_big5 );   /* encoding..         */
    -      
    - -

    Another way is to manually parse the list of charmaps for the - face, this is accessible through the fields - num_charmaps and charmaps - (notice the 's') of the face object. As you could expect, - the first is the number of charmaps in the face, while the - second is a table of pointers to the charmaps - embedded in the face.

    - -

    Each charmap has a few visible fields used to describe it more - precisely. Mainly, one will look at - charmap->platform_id and - charmap->encoding_id that define a pair of - values that can be used to describe the charmap in a rather - generic way.

    - -

    Each value pair corresponds to a given encoding. For example, - the pair (3,1) corresponds to Unicode. Their list is - defined in the TrueType specification but you can also use the - file <freetype/ftnameid.h> which defines several - helpful constants to deal with them..

    - -

    To look for a specific encoding, you need to find a corresponding - value pair in the specification, then look for it in the charmaps - list. Don't forget that some encoding correspond to several - values pair (yes it's a real mess, but blame Apple and Microsoft - on such stupidity..). Here's some code to do it:

    - - -
    -    FT_CharMap  found = 0;
    -    FT_CharMap  charmap;
    -    int         n;
    -
    -    for ( n = 0; n < face->num_charmaps; n++ )
    -    {
    -      charmap = face->charmaps[n];
    -      if ( charmap->platform_id == my_platform_id &&
    -           charmap->encoding_id == my_encoding_id )
    -      {
    -        found = charmap;
    -        break;
    -      }
    -    }
    -
    -    if ( !found ) { ... }
    -
    -    /* now, select the charmap for the face object */
    -    error = FT_Set_CharMap( face, found );
    -    if ( error ) { ... }
    -
    - -

    Once a charmap has been selected, either through - FT_Select_CharMap or FT_Set_CharMap, - it is used by all subsequent calls to - FT_Get_Char_Index().

    - - -

    - d. Glyph Transforms: -

    - -

    It is possible to specify an affine transformation to be applied - to glyph images when they're loaded. Of course, this will only - work for scalable (vectorial) font formats.

    - -

    To do that, simply call FT_Set_Transform, as in:

    - -
    -   error = FT_Set_Transform(
    -                    face,           /* target face object    */
    -		    &matrix,    /* pointer to 2x2 matrix */
    -		    &delta );   /* pointer to 2d vector  */
    -     
    - -

    This function will set the current transform for a given face - object. Its second parameter is a pointer to a simple - FT_Matrix structure that describes a 2x2 affine matrix. - The third parameter is a pointer to a FT_Vector structure - that describe a simple 2d vector.

    - -

    Note that the matrix pointer can be set to NULL, (in which case - the identity transform will be used). Coefficients of the matrix - are in 16.16 fixed float units.

    - -

    The vector pointer can also be set to NULL (in which case a delta - of (0,0) will be used). The vector coordinates are expressed in - 1/64th of a pixel (also known as 26.6 fixed floats).

    - -

    NOTA BENE: The transform is applied every glyph that is loaded - through FT_Load_Glyph. Note that loading a glyph bitmap - with a non-trivial transform will produce an error..

    - -
    - -

    - 7. Accessing glyph image data -

    - -

    Glyph image data is accessible through face->glyph. - See the definition of the FT_GlyphSlot type for more details. - As stated previously, each face has a single glyph slot, where - one glyph image at a time can be loaded. Each time - you call FT_Load_Glyph(), you erase the content of the glyph - slot with a new glyph image.

    - -

    Note however that the glyph slot object itself doesn't change, only - its content, which means that you can perfectly create a "shortcut" to - access it as in

    - - -
    -    {
    -      /* shortcut to glyph slot */
    -      FT_GlyphSlot  glyph = face->glyph;
    -
    -      for ( n = 0; n < face->num_glyphs; n++ )
    -      {
    -        ... load glyph n ...
    -        ... access glyph data as glyph->xxxx
    -      }
    -    }
    -
    - -

    The glyph variable will be valid until its parent - face is destroyed. Here are a few important fields of the - glyph slot:

    - - - - - - - - - - - - - - - - - - -
    - glyph->format - -

    Indicates the type of the loaded glyph image. Can be either - ft_glyph_format_bitmap, ft_glyph_format_outline, - or other values.

    -
    - glyph->metrics - -

    A simple structure used to hold the glyph image's metrics. - Note that most distances are expressed in 1/64th of - pixels! See the API reference or the user guide for a - description of the FT_Glyph_Metrics structure.

    -
    - glyph->bitmap - -

    If the glyph slot contains a bitmap, a simple - FT_Bitmap that describes it. See the API reference or - user guide for a description of the FT_Bitmap - structure.

    -
    - glyph->outline - -

    When the glyph slot contains a scalable outline, this structure - describes it. See the definition of the FT_Outline - structure.

    -
    - -

    - 8. Rendering glyph outlines into bitmaps -

    - -

    You can easily test the format of the glyph image by inspecting the - face->glyph->format variable. If its value is - ft_glyph_format_bitmap, the glyph image that was loaded is a - bitmap that can be directly blit to your own surfaces through your - favorite graphics library (FreeType 2 doesn't provide bitmap - blitting routines, as you may imagine :-)

    - -

    If the format is ft_glyph_format_outline or something else, - the library provides a means to convert such glyph images to bitmaps - through what are called rasters.

    - -

    On the other hand, if the image is a scalable outline or something - else, FreeType provides a function to convert the glyph image into a - pre-existing bitmap that you will handle to it, named - FT_Get_Glyph_Bitmap. Here's a simple example code - that renders an outline into a monochrome bitmap:

    - - -
    -    {
    -      FT_GlyphSlot  glyph;
    -
    -      ... load glyph ...
    -
    -      glyph = face->glyph;   /* shortcut to glyph data */
    -      if ( glyph->format == ft_glyph_format_outline )
    -      {
    -        FT_Bitmap  bit;
    -
    -        /* set-up a bitmap descriptor for our target bitmap */
    -        bit.rows       = bitmap_height;
    -        bit.width      = bitmap_width;
    -        bit.pitch      = bitmap_row_bytes;
    -        /* render into a mono bitmap */
    -        bit.pixel_mode = ft_pixel_mode_mono;
    -        bit.buffer     = bitmap_buffer;
    -
    -        /* render the outline directly into the bitmap */
    -        error = FT_Get_Glyph_Bitmap( face, &bit );
    -        if ( error ) { ... }
    -      }
    -    }
    -
    - -

    You should note that FT_Get_Glyph_Bitmap() doesn't - create the bitmap. It only needs a descriptor, of type - FT_Bitmap, and writes directly into it.

    - -

    Note that the FreeType scan-converter for outlines can also generate - anti-aliased glyph bitmaps with 128 level of grays. For now, it is - restricted to rendering to 8-bit gray-level bitmaps, though this may - change in the future. Here is some code to do just that:

    - - -
    -    {
    -      FT_GlyphSlot  glyph;
    -
    -      ... load glyph ...
    -
    -      glyph = face->glyph;   /* shortcut to glyph data */
    -      if ( glyph->format == ft_glyph_format_outline )
    -      {
    -        FT_Bitmap  bit;
    -
    -        /* set-up a bitmap descriptor for our target bitmap */
    -        bit.rows       = bitmap_height;
    -        bit.width      = bitmap_width;
    -        bit.pitch      = bitmap_row_bytes;
    -        /* 8-bit gray-level bitmap */
    -        bit.pixel_mode = ft_pixel_mode_gray;
    -        /* MUST be 128 for now     */
    -        bit.grays      = 128;
    -        bit.buffer     = bitmap_buffer;
    -
    -        /* clean the bitmap - IMPORTANT */
    -        memset( bit.buffer, 0, bit.rows*bit.pitch );
    -
    -        /* render the outline directly into the bitmap */
    -        error = FT_Get_Glyph_Bitmap( face, &bit );
    -        if ( error ) { ... }
    -      }
    -    }
    -
    - -

    You will notice that

    - -
      -
    • -

      As previously, FT_Get_Glyph_Bitmap() doesn't generate - the bitmap, it simply renders to it.

      -
    • -
    • -

      The target bitmap must be cleaned before calling the function. - This is a limitation of our current anti-aliasing algorithm and is - EXTREMELY important.

      -
    • -
    • -

      The anti-aliaser uses 128 levels of grays exclusively for - now (this will probably change in a near future). This means that - you must set bit.grays to 128. The generated - image uses values from 0 (back color) to 127 (foreground color).

      -
    • -
    • -

      It is not possible to render directly an anti-aliased - outline into a pre-existing gray-level bitmap, or even any - colored-format one (like RGB16 or paletted 8-bits). We will not - discuss this issue in great details here, but the reason is that we - do not want to deal with graphics composition (or alpha-blending) - within FreeType.

      -

    • -
    -
    -
    - - - diff --git a/subsys/win32k/freetype/docs/tutorial/step1.html b/subsys/win32k/freetype/docs/tutorial/step1.html deleted file mode 100644 index e184be7..0000000 --- a/subsys/win32k/freetype/docs/tutorial/step1.html +++ /dev/null @@ -1,956 +0,0 @@ - - - - - - FreeType 2 Tutorial - - - - -

    - FreeType 2.0 Tutorial
    - Step 1 - simple glyph loading -

    - -

    - © 2000 David Turner - (david@freetype.org)
    - © 2000 The FreeType Development Team - (www.freetype.org) -

    - -
    - - -
    - -
    - -

    - Introduction -

    - -

    This is the first section of the FreeType 2 tutorial. It will teach - you to do the following:

    - -
      -
    • initialise the library
    • -
    • open a font file by creating a new face object
    • -
    • select a character size in points or in pixels
    • -
    • load a single glyph image and convert it to a bitmap
    • -
    • render a very simple string of text
    • -
    • render a rotated string of text easily
    • -
    - -
    - -

    - 1. Header files -

    - -

    To include the main FreeType header file, simply say

    - - -
    -    #include <freetype/freetype.h>
    -
    - -

    in your application code. Note that other files are available in the - FreeType include directory, most of them being included by - "freetype.h". They will be described later in this - tutorial.

    - -
    - -

    - 2. Initialize the library -

    - -

    Simply create a variable of type FT_Library named, for - example, library, and call the function - FT_Init_FreeType() as in

    - - -
    -    #include <freetype/freetype.h>
    -
    -    FT_Library  library;
    -
    -    ...
    -
    -    {
    -      ...
    -      error = FT_Init_FreeType( &library );
    -      if ( error )
    -      {
    -        ... an error occurred during library initialization ...
    -      }
    -    }
    -
    - -

    This function is in charge of the following:

    - -
      -
    • -

      Creating a new instance of the FreeType 2 library, and set - the handle library to it.

      -
    • -
    • -

      Load each modules that FreeType knows about in the library. - This means that by default, your new library object is able - to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts - gracefully.

      -
    • -
    - -

    As you can see, the function returns an error code, like most others - in the FreeType API. An error code of 0 always means that - the operation was successful; otherwise, the value describes the error, - and library is set to NULL.

    - -
    - -

    - 3. Load a font face -

    - -

    - a. From a font file -

    - -

    Create a new face object by calling FT_New_Face. - A face describes a given typeface and style. For example, - "Times New Roman Regular" and "Times New Roman Italic" correspond to - two different faces.

    - - -
    -    FT_Library   library;   /* handle to library     */
    -    FT_Face      face;      /* handle to face object */
    -
    -    error = FT_Init_FreeType( &library );
    -    if ( error ) { ... }
    -
    -    error = FT_New_Face( library,
    -                         "/usr/share/fonts/truetype/arial.ttf",
    -                         0,
    -                         &face );
    -    if ( error == FT_Err_Unknown_File_Format )
    -    {
    -      ... the font file could be opened and read, but it appears
    -      ... that its font format is unsupported
    -    }
    -    else if ( error )
    -    {
    -      ... another error code means that the font file could not
    -      ... be opened or read, or simply that it is broken...
    -    }
    -
    - -

    As you can certainly imagine, FT_New_Face opens a font - file, then tries to extract one face from it. Its parameters are

    - - - - - - - - - - - - - - - - - - -
    - library - -

    handle to the FreeType library instance where the face object - is created

    -
    - filepathname - -

    the font file pathname (standard C string).

    -
    - face_index - -

    Certain font formats allow several font faces to be embedded - in a single file.

    - -

    This index tells which face you want to load. An error will - be returned if its value is too large.

    - -

    Index 0 always work though.

    -
    - face - -

    A pointer to the handle that will be set to describe - the new face object.

    - -

    It is set to NULL in case of error.

    -
    - -

    To know how many faces a given font file contains, simply load its - first face (use face_index=0), then see the value of - face->num_faces which indicates how many faces are embedded - in the font file.

    - -

    - b. From memory -

    - -

    In the case where you have already loaded the font file in memory, - you can similarly create a new face object for it by calling - FT_New_Memory_Face as in

    - - -
    -    FT_Library   library;   /* handle to library     */
    -    FT_Face      face;      /* handle to face object */
    -
    -    error = FT_Init_FreeType( &library );
    -    if ( error ) { ... }
    -
    -    error = FT_New_Memory_Face( library,
    -                                buffer,    /* first byte in memory */
    -                                size,      /* size in bytes        */
    -                                0,         /* face_index           */
    -                                &face );
    -    if ( error ) { ... }
    -
    - -

    As you can see, FT_New_Memory_Face() simply takes a - pointer to the font file buffer and its size in bytes instead of a - file pathname. Other than that, it has exactly the same semantics as - FT_New_Face().

    - -

    - c. From other sources (compressed files, network, etc.) -

    - -

    There are cases where using a file pathname or preloading the file - in memory is simply not enough. With FreeType 2, it is possible - to provide your own implementation of i/o routines.

    - -

    This is done through the FT_Open_Face() function, which - can be used to open a new font face with a custom input stream, select - a specific driver for opening, or even pass extra parameters to the - font driver when creating the object. We advise you to refer to the - FreeType 2 reference manual in order to learn how to use it.

    - -

    Note that providing a custom stream might also be used to access a - TrueType font embedded in a Postscript Type 42 wrapper.

    - -
    - -

    - 4. Accessing face content -

    - -

    A face object models all information that globally describes - the face. Usually, this data can be accessed directly by dereferencing - a handle, like

    - - - - - - - - - - - - - - - - - - - - - - -
    - face->num_glyphs - -

    Gives the number of glyphs available in the font face. - A glyph is simply a character image. It doesn't necessarily - correspond to a character code though.

    -
    - face->flags - -

    A 32-bit integer containing bit flags used to describe some - face properties. For example, the flag - FT_FACE_FLAG_SCALABLE is used to indicate that the face's - font format is scalable and that glyph images can be rendered for - all character pixel sizes. For more information on face flags, - please read the FreeType 2 API Reference.

    -
    - face->units_per_EM - -

    This field is only valid for scalable formats (it is set to 0 - otherwise). It indicates the number of font units covered by the - EM.

    -
    - face->num_fixed_sizes - -

    This field gives the number of embedded bitmap strikes - in the current face. A strike is simply a series of - glyph images for a given character pixel size. For example, a - font face could include strikes for pixel sizes 10, 12 - and 14. Note that even scalable font formats can have - embedded bitmap strikes!

    -
    - face->fixed_sizes - -

    this is a pointer to an array of FT_Bitmap_Size - elements. Each FT_Bitmap_Size indicates the horizontal - and vertical pixel sizes for each of the strikes that are - present in the face.

    -
    - -

    For a complete listing of all face properties and fields, please read - the FreeType 2 API Reference.

    - -


    - -

    - 5. Setting the current pixel size -

    - -

    FreeType 2 uses "size objects" to model all - information related to a given character size for a given face. - For example, a size object will hold the value of certain metrics - like the ascender or text height, expressed in 1/64th of a pixel, - for a character size of 12 points.

    - -

    When the FT_New_Face function is called (or one of its - cousins), it automatically creates a new size object for - the returned face. This size object is directly accessible as - face->size.

    - -

    NOTA BENE: a single face object can deal with one or more size - objects at a time, however, this is something that few programmers - really need to do. We have thus have decided to simplify the API for - the most common use (i.e. one size per face), while keeping this - feature available through additional fuctions.

    - -

    When a new face object is created, its size object defaults to the - character size of 10 pixels (both horizontally and vertically) for - scalable formats. For fixed-sizes formats, the size is more or less - undefined, which is why you must set it before trying to load a - glyph.

    - -

    To do that, simply call FT_Set_Char_Size(). Here is an - example where the character size is set to 16pt for a 300x300 dpi - device:

    - - -
    -    error = FT_Set_Char_Size(
    -              face,    /* handle to face object           */
    -              0,       /* char_width in 1/64th of points  */
    -              16*64,   /* char_height in 1/64th of points */
    -              300,     /* horizontal device resolution    */
    -              300 );   /* vertical device resolution      */
    -
    - -

    You will notice that:

    - -
      -
    • -

      The character width and heights are specified in 1/64th of - points. A point is a physical distance, equaling 1/72th - of an inch, it's not a pixel..

      -

    • -
    • -

      The horizontal and vertical device resolutions are expressed in - dots-per-inch, or dpi. You can use 72 or - 96 dpi for display devices like the screen. The resolution - is used to compute the character pixel size from the character - point size.

      -
    • -
    • -

      A value of 0 for the character width means "same as - character height", a value of 0 for the character height - means "same as character width". Otherwise, it is possible - to specify different char widths and heights.

      -
    • -
    • -

      Using a value of 0 for the horizontal or vertical resolution means - 72 dpi, which is the default.

      -
    • -
    • -

      The first argument is a handle to a face object, not a size - object. That's normal, and must be seen as a convenience.

      -
    • -
    - -

    This function computes the character pixel size that corresponds to - the character width and height and device resolutions. However, if you - want to specify the pixel sizes yourself, you can simply call - FT_Set_Pixel_Sizes(), as in

    - - -
    -    error = FT_Set_Pixel_Sizes(
    -              face,   /* handle to face object            */
    -              0,      /* pixel_width                      */
    -              16 );   /* pixel_height                     */
    -
    - -

    This example will set the character pixel sizes to 16x16 pixels. - As previously, a value of 0 for one of the dimensions means - "same as the other".

    - -

    Note that both functions return an error code. Usually, an error - occurs with a fixed-size font format (like FNT or PCF) when trying to - set the pixel size to a value that is not listed in the - face->fixed_sizes array.

    - -
    - -

    - 6. Loading a glyph image -

    - -

    - a. Converting a character code into a glyph index -

    - -

    Usually, an application wants to load a glyph image based on its - character code, which is a unique value that defines the - character for a given encoding. For example, the character - code 65 represents the `A' in ASCII encoding.

    - -

    A face object contains one or more tables, called - charmaps, that are used to convert character codes to glyph - indices. For example, most TrueType fonts contain two charmaps. One - is used to convert Unicode character codes to glyph indices, the other - is used to convert Apple Roman encoding into glyph indices. Such - fonts can then be used either on Windows (which uses Unicode) and - Macintosh (which uses Apple Roman, bwerk). Note also that a given - charmap might not map to all the glyphs present in the font.

    - -

    By default, when a new face object is created, it lists all the - charmaps contained in the font face and selects the one that supports - Unicode character codes if it finds one. Otherwise, it tries to find - support for Latin-1, then ASCII.

    - -

    We will describe later how to look for specific charmaps in a face. - For now, we will assume that the face contains at least a Unicode - charmap that was selected during FT_New_Face(). To convert a - Unicode character code to a font glyph index, we use - FT_Get_Char_Index() as in

    - - -
    -    glyph_index = FT_Get_Char_Index( face, charcode );
    -
    - -

    This will look the glyph index corresponding to the given - charcode in the charmap that is currently selected for the - face. If charmap is selected, the function simply returns the - charcode.

    - -

    Note that this is one of the rare FreeType functions that do not - return an error code. However, when a given character code has no - glyph image in the face, the value 0 is returned. By convention, - it always correspond to a special glyph image called the missing - glyph, which usually is represented as a box or a space.

    - -

    - b. Loading a glyph from the face -

    - -

    Once you have a glyph index, you can load the corresponding glyph - image. The latter can be stored in various formats within the font file. - For fixed-size formats like FNT or PCF, each image is a bitmap. Scalable - formats like TrueType or Type 1 use vectorial shapes, named "outlines" - to describe each glyph. Some formats may have even more exotic ways - of representing glyph (e.g. MetaFont). Fortunately, FreeType 2 is - flexible enough to support any kind of glyph format through - a simple API.

    - -

    The glyph image is always stored in a special object called a - glyph slot. As its name suggests, a glyph slot is simply a - container that is able to hold one glyph image at a time, be it a - bitmap, an outline, or something else. Each face object has a single - glyph slot object that can be accessed as - face->glyph.

    - -

    Loading a glyph image into the slot is performed by calling - FT_Load_Glyph() as in

    - - -
    -    error = FT_Load_Glyph( 
    -              face,          /* handle to face object */
    -              glyph_index,   /* glyph index           */
    -              load_flags );  /* load flags, see below */
    -
    - -

    The load_flags value is a set of bit flags used to - indicate some special operations. The default value - FT_LOAD_DEFAULT is 0.

    - -

    This function will try to load the corresponding glyph image - from the face. Basically, this means that:

    - -
      -
    • -

      If a bitmap is found for the corresponding glyph and pixel - size, it will be loaded into the slot (embedded bitmaps are always - favored over native image formats, because we assume that - they are higher-quality versions of the same glyph. This - can be ignored by using the FT_LOAD_NO_BITMAP flag)

      -
    • - -
    • -

      Otherwise, a native image for the glyph will be loaded. - It will also be scaled to the current pixel size, as - well as hinted for certain formats like TrueType and - Type1.

      -
    • -
    - -

    The field glyph->format describe the format - used to store the glyph image in the slot. If it is not - ft_glyph_format_bitmap, one can immediately - convert it to a bitmap through FT_Render_Glyph, - as in:

    - - -
    -   error = FT_Render_Glyph(
    -                  face->glyph,      /* glyph slot  */
    -                  render_mode );    /* render mode */
    -      
    -
    - -

    The parameter render_mode is a set of bit flags used - to specify how to render the glyph image. Set it to 0, or the - equivalent ft_render_mode_normal to render a high-quality - anti-aliased (256 gray levels) bitmap, as this is the default. - You can alternatively use ft_render_mode_mono if you - want to generate a 1-bit monochrome bitmap.

    - -

    Once you have a bitmapped glyph image, you can access it directly - through glyph->bitmap (a simple bitmap descriptor), - and position it through glyph->bitmap_left and - glyph->bitmap_top.

    - -

    Note that bitmap_left is the horizontal distance from the - current pen position to the left-most border of the glyph bitmap, - while bitmap_top is the vertical distance from the - pen position (on the baseline) to the top-most border of the - glyph bitmap. It is positive to indicate an upwards - distance.

    - -

    The next section will detail the content of a glyph slot and - how to access specific glyph information (including metrics).

    - -

    - c. Using other charmaps -

    - -

    As said before, when a new face object is created, it will look for - a Unicode, Latin-1, or ASCII charmap and select it. The currently - selected charmap is accessed via face->charmap. This - field is NULL when no charmap is selected, which typically happens - when you create a new FT_Face object from a font file that - doesn't contain an ASCII, Latin-1, or Unicode charmap (rare - stuff).

    - -

    There are two ways to select a different charmap with FreeType 2. - The easiest is when the encoding you need already has a corresponding - enumeration defined in <freetype/freetype.h>, as - ft_encoding_big5. In this case, you can simply call - FT_Select_CharMap as in:

    - -
    -    error = FT_Select_CharMap(
    -                    face,                 /* target face object */
    -                    ft_encoding_big5 );   /* encoding..         */
    -      
    - -

    Another way is to manually parse the list of charmaps for the - face, this is accessible through the fields - num_charmaps and charmaps - (notice the 's') of the face object. As you could expect, - the first is the number of charmaps in the face, while the - second is a table of pointers to the charmaps - embedded in the face.

    - -

    Each charmap has a few visible fields used to describe it more - precisely. Mainly, one will look at - charmap->platform_id and - charmap->encoding_id that define a pair of - values that can be used to describe the charmap in a rather - generic way.

    - -

    Each value pair corresponds to a given encoding. For example, - the pair (3,1) corresponds to Unicode. Their list is - defined in the TrueType specification but you can also use the - file <freetype/ftnameid.h> which defines several - helpful constants to deal with them..

    - -

    To look for a specific encoding, you need to find a corresponding - value pair in the specification, then look for it in the charmaps - list. Don't forget that some encoding correspond to several - values pair (yes it's a real mess, but blame Apple and Microsoft - on such stupidity..). Here's some code to do it:

    - - -
    -    FT_CharMap  found = 0;
    -    FT_CharMap  charmap;
    -    int         n;
    -
    -    for ( n = 0; n < face->num_charmaps; n++ )
    -    {
    -      charmap = face->charmaps[n];
    -      if ( charmap->platform_id == my_platform_id &&
    -           charmap->encoding_id == my_encoding_id )
    -      {
    -        found = charmap;
    -        break;
    -      }
    -    }
    -
    -    if ( !found ) { ... }
    -
    -    /* now, select the charmap for the face object */
    -    error = FT_Set_CharMap( face, found );
    -    if ( error ) { ... }
    -
    - -

    Once a charmap has been selected, either through - FT_Select_CharMap or FT_Set_CharMap, - it is used by all subsequent calls to - FT_Get_Char_Index().

    - - -

    - d. Glyph Transforms: -

    - -

    It is possible to specify an affine transformation to be applied - to glyph images when they're loaded. Of course, this will only - work for scalable (vectorial) font formats.

    - -

    To do that, simply call FT_Set_Transform, as in:

    - -
    -   error = FT_Set_Transform(
    -                    face,       /* target face object    */
    -                    &matrix,    /* pointer to 2x2 matrix */
    -                    &delta );   /* pointer to 2d vector  */
    -     
    - -

    This function will set the current transform for a given face - object. Its second parameter is a pointer to a simple - FT_Matrix structure that describes a 2x2 affine matrix. - The third parameter is a pointer to a FT_Vector structure - that describe a simple 2d vector that is used to translate the - glyph image after the 2x2 transform.

    - -

    Note that the matrix pointer can be set to NULL, (in which case - the identity transform will be used). Coefficients of the matrix - are otherwise in 16.16 fixed float units.

    - -

    The vector pointer can also be set to NULL (in which case a delta - of (0,0) will be used). The vector coordinates are expressed in - 1/64th of a pixel (also known as 26.6 fixed floats).

    - - -

    NOTA BENE: The transform is applied to every glyph that is loaded - through FT_Load_Glyph and is completely independent - of any hinting process. This means that you won't get the same - results if you load a glyph at the size of 24 pixels, or a glyph at - the size at 12 pixels scaled by 2 through a transform, because the - hints will have been computed differently (unless, of course you - disabled hints).

    - -

    If you ever need to use a non-orthogonal transform with optimal - hints, you first need to decompose your transform into a scaling part - and a rotation/shearing part. Use the scaling part to compute a new - character pixel size, then the other one to call FT_Set_Transform. - This is explained in details in a later section of this tutorial.

    - -

    Note also that loading a glyph bitmap with a non-identity transform - will produce an error..

    -
    - -

    - 7. Simple Text Rendering: -

    - -

    We will now present you with a very simple example used to render - a string of 8-bit Latin-1 text, assuming a face that contains a - Unicode charmap

    - -

    The idea is to create a loop that will, on each iteration, load one - glyph image, convert it to an anti-aliased bitmap, draw it on the - target surface, then increment the current pen position

    - -

    a. basic code :

    - -

    The following code performs our simple text rendering with the - functions previously described.

    - -
    -       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -       int           pen_x, pen_y, n;
    -
    -       .. initialise library ..
    -       .. create face object ..
    -       .. set character size ..
    -       
    -       pen_x = 300;
    -       pen_y = 200;
    -       
    -       for ( n = 0; n < num_chars; n++ )
    -       {
    -         FT_UInt  glyph_index;
    -         
    -         // retrieve glyph index from character code
    -         glyph_index = FT_Get_Char_Index( face, text[n] );
    -         
    -         // load glyph image into the slot (erase previous one)
    -         error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
    -         if (error) continue;  // ignore errors
    -         
    -         // convert to an anti-aliased bitmap
    -         error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
    -         if (error) continue;
    -         
    -         // now, draw to our target surface
    -         my_draw_bitmap( &slot->bitmap,
    -                         pen_x + slot->bitmap_left,
    -                         pen_y - slot->bitmap_top );
    -                         
    -         // increment pen position 
    -         pen_x += slot->advance.x >> 6;
    -         pen_y += slot->advance.y >> 6;   // unuseful for now..
    -       }
    -    
    - -

    This code needs a few explanations:

    -
      -
    • - we define a handle named slot that points to the - face object's glyph slot. (the type FT_GlyphSlot is - a pointer). That's a convenience to avoid using - face->glyph->XXX every time. -

    • - -
    • - we increment the pen position with the vector slot->advance, - which correspond to the glyph's advance width (also known - as its escapement). The advance vector is expressed in - 64/th of pixels, and is truncated to integer pixels on each - iteration.

      -

    • - -
    • - The function my_draw_bitmap is not part of FreeType, but - must be provided by the application to draw the bitmap to the target - surface. In this example, it takes a pointer to a FT_Bitmap descriptor - and the position of its top-left corner as arguments. -

    • - -
    • - The value of slot->bitmap_top is positive for an - upwards vertical distance. Assuming that the coordinates - taken by my_draw_bitmap use the opposite convention - (increasing Y corresponds to downwards scanlines), we substract - it to pen_y, instead of adding it.. -

    • - -
    - -

    b. refined code:

    - -

    The following code is a refined version of the example above. It - uses features and functions of FreeType 2 that have not yet been - introduced, and they'll be explained below:

    - -
    -       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -       FT_UInt       glyph_index;
    -       int           pen_x, pen_y, n;
    -
    -       .. initialise library ..
    -       .. create face object ..
    -       .. set character size ..
    -       
    -       pen_x = 300;
    -       pen_y = 200;
    -       
    -       for ( n = 0; n < num_chars; n++ )
    -       {
    -         // load glyph image into the slot (erase previous one)
    -         error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
    -         if (error) continue;  // ignore errors
    -         
    -         // now, draw to our target surface
    -         my_draw_bitmap( &slot->bitmap,
    -                         pen_x + slot->bitmap_left,
    -                         pen_y - slot->bitmap_top );
    -                         
    -         // increment pen position 
    -         pen_x += slot->advance.x >> 6;
    -       }
    -    
    - -

    We've reduced the size of our code, but it does exactly the same thing, - as:

    - -
      -
    • - We use the function FT_Load_Char instead of - FT_Load_Glyph. As you probably imagine, it's equivalent - to calling FT_Get_Char_Index then FT_Get_Load_Glyph. -

    • - -
    • - We do not use FT_LOAD_DEFAULT for the loading mode, but - the bit flag FT_LOAD_RENDER. It indicates that - the glyph image must be immediately converted to an anti-aliased - bitmap. This is of course a shortcut that avoids calling - FT_Render_Glyph explicitely but is strictly equivalent.

      - -

      - Note that you can also specify that you want a monochrome bitmap - instead by using the addition FT_LOAD_MONOCHROME - load flag. -

    • -
    - -

    c. more advanced rendering:

    - -

    Let's try to render transformed text now (for example through a - rotation). We can do this using FT_Set_Transform. Here's - how to do it:

    - -
    -       FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -       FT_Matrix     matrix;              // transformation matrix
    -       FT_UInt       glyph_index;
    -       FT_Vector     pen;                 // untransformed origin
    -       int           pen_x, pen_y, n;
    -
    -       .. initialise library ..
    -       .. create face object ..
    -       .. set character size ..
    -
    -       // set up matrix
    -       matrix.xx = (FT_Fixed)( cos(angle)*0x10000);
    -       matrix.xy = (FT_Fixed)(-sin(angle)*0x10000);
    -       matrix.yx = (FT_Fixed)( sin(angle)*0x10000);
    -       matrix.yy = (FT_Fixed)( cos(angle)*0x10000);
    -              
    -       // the pen position in 26.6 cartesian space coordinates
    -       pen.x = 300 * 64;
    -       pen.y = ( my_target_height - 200 ) * 64;
    -       
    -       for ( n = 0; n < num_chars; n++ )
    -       {
    -         // set transform
    -         FT_Set_Transform( face, &matrix, &pen );
    -         
    -         // load glyph image into the slot (erase previous one)
    -         error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
    -         if (error) continue;  // ignore errors
    -         
    -         // now, draw to our target surface (convert position)
    -         my_draw_bitmap( &slot->bitmap,
    -                         slot->bitmap_left,
    -                         my_target_height - slot->bitmap_top );
    -                         
    -         // increment pen position 
    -         pen.x += slot->advance.x;
    -         pen.y += slot->advance.y;
    -       }
    -    
    - -

    You'll notice that:

    - -
      -
    • - we now use a vector, of type FT_Vector to store the pen - position, with coordinates expressed as 1/64th of pixels, hence - a multiplication. The position is expressed in cartesian space. -

    • - -
    • - glyph images are always loaded, transformed and described in the - cartesian coordinate system in FreeType (which means that - increasing Y corresponds to upper scanlines), unlike the system - typically used for bitmaps (where the top-most scanline has - coordinate 0). We must thus convert between the two systems - when we define the pen position, and when we compute the top-left - position of the bitmap. -

    • - -
    • - we set the transform on each glyph, to indicate the rotation - matrix, as well as a delta that will move the transformed image - to the current pen position (in cartesian space, not bitmap space). -

    • - -
    • - the advance is always returned transformed, which is why it can - be directly added to the current pen position. Note that it is - not rounded this time. -

    • - -
    - -

    It is important to note that, while this example is a bit more - complex than the previous one, it is strictly equivalent - for the case where the transform is the identity.. Hence it can - be used as a replacement (but a more powerful one).

    - -

    It has however a few short comings that we will explain, and solve, - in the next part of this tutorial.

    - -
    - -

    - Conclusion -

    - -

    In this first section, you have learned the basics of FreeType 2, - as well as sufficient knowledge to know how to render rotated text. - Woww ! Congratulations..

    - -

    The next section will dive into more details of the API in order - to let you access glyph metrics and images directly, as well as - how to deal with scaling, hinting, kerning, etc..

    - -

    The third section will discuss issues like modules, caching and a - few other advanced topics like how to use multiple size objects - with a single face. -

    - -
    -
    - - - diff --git a/subsys/win32k/freetype/docs/tutorial/step2.html b/subsys/win32k/freetype/docs/tutorial/step2.html deleted file mode 100644 index d8cc150..0000000 --- a/subsys/win32k/freetype/docs/tutorial/step2.html +++ /dev/null @@ -1,1399 +0,0 @@ - - - - - - FreeType 2 Tutorial - - - - -

    - FreeType 2.0 Tutorial
    - Step 2 - managing glyphs -

    - -

    - © 2000 David Turner - (david@freetype.org)
    - © 2000 The FreeType Development Team - (www.freetype.org) -

    - -
    - - -
    - -
    - -

    - Introduction -

    - -

    This is the second section of the FreeType 2 tutorial. It will teach - you the following:

    - -
      -
    • how to retrieve glyph metrics
    • -
    • how to easily manage glyph images
    • -
    • how to retrieve global metrics (including kerning)
    • -
    • how to render a simple string of text, with kerning
    • -
    • how to render a centered string of text (with kerning)
    • -
    • how to render a transformed string of text (with centering)
    • -
    • finally, how to access metrics in design font units when needed, - and how to scale them to device space.
    • -
    - -
    - -

    - 1. Glyph metrics: -

    - -

    Glyph metrics are, as their name suggests, certain distances associated - to each glyph in order to describe how to use it to layout text.

    - -

    There are usually two sets of metrics for a single glyph: those used to - layout the glyph in horizontal text layouts (like latin, cyrillic, - arabic, hebrew, etc..), and those used to layout the glyph in vertical - text layouts (like some layouts of Chinese, Japanese, Korean, and - others..).

    - -

    Note that only a few font formats provide vertical metrics. You can - test wether a given face object contains them by using the macro - FT_HAS_VERTICAL(face), which is true when appropriate.

    - -

    Individual glyph metrics can be accessed by first loading the glyph - in a face's glyph slot, then accessing them through the - face->glyph->metrics structure. This will be detailed - later, for now, we'll see that it contains the following fields:

    - -
    - width - -

    This is the width of the glyph image's bounding box. It is independent - of layout direction.

    -
    - height - -

    This is the height of the glyph image's bounding box. It is independent - of layout direction.

    -
    - horiBearingX - -

    For horizontal text layouts, this is the horizontal distance from - the current cursor position to the left-most border of the glyph image's - bounding box.

    -
    - horiBearingY - -

    For horizontal text layouts, this is the vertical distance from - the current cursor position (on the baseline) to the top-most border of - the glyph image's bounding box.

    -
    - horiAdvance - -

    For horizontal text layouts, this is the horizontal distance - used to increment the pen position when the glyph is drawn as part of - a string of text.

    -
    - vertBearingX - -

    For vertical text layouts, this is the horizontal distance from - the current cursor position to the left-most border of the glyph image's - bounding box.

    -
    - vertBearingY - -

    For vertical text layouts, this is the vertical distance from - the current cursor position (on the baseline) to the top-most border of - the glyph image's bounding box.

    -
    - vertAdvance - -

    For vertical text layouts, this is the vertical distance - used to increment the pen position when the glyph is drawn as part of - a string of text.

    -
    - -

    NOTA BENE: As all fonts do not contain vertical - metrics, the values of vertBearingX, vertBearingY - and vertAdvance should not be considered reliable when - FT_HAS_VERTICAL(face) is false.

    - -

    The following graphics illustrate the metrics more clearly. First, for - horizontal metrics, where the baseline is the horizontal axis :

    - -
    - -

    For vertical text layouts, the baseline is vertical and is the - vertical axis:

    - -
    - - -

    The metrics found in face->glyph->metrics are normally - expressed in 26.6 pixels (i.e 1/64th of pixels), unless you use - the FT_LOAD_NO_SCALE flag when calling - FT_Load_Glyph or FT_Load_Char. In this case, - the metrics will be expressed in original font units.

    - -

    The glyph slot object has also a few other interesting fields - that will ease a developer's work. You can access them though - face->glyph->??? :

    - -
    - advance - -

    This field is a FT_Vector which holds the transformed - advance for the glyph. That's useful when you're using a transform - through FT_Set_Transform, as shown in the rotated text - example of section I. Other than that, its value is - by default (metrics.horiAdvance,0), unless you specify - FT_LOAD_VERTICAL when loading the glyph image; - it will then be (0,metrics.vertAdvance)

    -
    - linearHoriAdvance - -

    - This field contains the linearly-scaled value of the glyph's horizontal - advance width. Indeed, the value of metrics.horiAdvance that is - returned in the glyph slot is normally rounded to integer pixel - coordinates (i.e., it will be a multiple of 64) by the font driver used - to load the glyph image. linearHoriAdvance is a 16.16 fixed float - number that gives the value of the original glyph advance width in - 1/65536th of pixels. It can be use to perform pseudo device-independent - text layouts.

    -
    - linearVertAdvance - -

    This is the same thing as linearHoriAdvance for the - glyph's vertical advance height. Its value is only reliable if the font - face contains vertical metrics.

    -
    - - - -
    - -

    - 2. Managing glyph images: -

    - -

    The glyph image that is loaded in a glyph slot can be converted into - a bitmap, either by using FT_LOAD_RENDER when loading it, or - by calling FT_Render_Glyph. Each time you load a new glyph - image, the previous one is erased from the glyph slot.

    - -

    There are times however where you may need to extract this image from - the glyph slot, in order to cache it within your application, and - even perform additional transforms and measures on it before converting - it to a bitmap. -

    - -

    The FreeType 2 API has a specific extension which is capable of dealing - with glyph images in a flexible and generic way. To use it, you first need - to include the "ftglyph.h" header file, as in:

    - -
    
    -      #include <freetype/ftglyph.h>
    -  
    - -

    We will now explain how to use the functions defined in this file:

    - -

    a. Extracting the glyph image:

    - -

    You can extract a single glyph image very easily. Here's some code - that shows how to do it:

    - -
    
    -       FT_Glyph    glyph;    // handle to glyph image
    -       
    -       ....
    -       error = FT_Load_Glyph( face, glyph, FT_LOAD_NORMAL );
    -       if (error) { .... }
    -       
    -       error = FT_Get_Glyph( face->glyph, &glyph );
    -       if (error) { .... }
    -  
    - -

    As you see, we have:

    - -
      -
    • - Created a variable, named glyph, of type FT_Glyph. - This is a handle (pointer) to an individual glyph image. -

    • - -
    • - Loaded the glyph image normally in the face's glyph slot. We did not - use FT_LOAD_RENDER because we want to grab a scalable glyph - image, in order to later transform it. -

    • - -
    • - Copy the glyph image from the slot into a new FT_Glyph object, - by calling FT_Get_Glyph. This function returns an error - code and sets glyph. -

    • -
    - -

    It is important to note that the extracted glyph is in the same format - than the original one that is still in the slot. For example, if we're - loading a glyph from a TrueType font file, the glyph image will really - be a scalable vector outline.

    - -

    You can access the field glyph->format if you want to - know exactly how the glyph is modeled and stored. A new glyph object can - be destroyed with a call to FT_Done_Glyph.

    - -

    The glyph object contains exactly one glyph image and a 2D vector - representing the glyph's advance in 16.16 fixed float coordinates. - The latter can be accessed directly as glyph->advance -

    - -

    Note that unlike - other FreeType objects, the library doesn't keeps a list of all - allocated glyph objects. This means you'll need to destroy them - yourself, instead of relying on FT_Done_FreeType doing - all the clean-up.

    - -

    b. Transforming & copying the glyph image

    - -

    If the glyph image is scalable (i.e. if glyph->format is not - equal to ft_glyph_format_bitmap), it is possible to transform - the image anytime by a call to FT_Glyph_Transform.

    - -

    You can also copy a single glyph image with FT_Glyph_Copy. - Here's some example code:

    - -
    
    -    FT_Glyph  glyph, glyph2;
    -    FT_Matrix matrix;
    -    FT_Vector delta;
    -    
    -    ......
    -    .. load glyph image in "glyph" ..
    -    
    -    // copy glyph to glyph2
    -    //
    -    error = FT_Glyph_Copy( glyph, &glyph2 );
    -    if (error) { ... could not copy (out of memory) }
    -    
    -    // translate "glyph"
    -    //    
    -    delta.x = -100 * 64;   // coordinates are in 26.6 pixels
    -    delta.y =  50  * 64;
    -    
    -    FT_Glyph_Transform( glyph, 0, &delta );
    -    
    -    // transform glyph2 (horizontal shear)
    -    //
    -    matrix.xx = 0x10000;
    -    matrix.xy = 0;
    -    matrix.yx = 0.12 * 0x10000;
    -    matrix.yy = 0x10000;
    -    
    -    FT_Glyph_Transform( glyph2, &matrix, 0 );
    -  
    - -

    Note that the 2x2 transform matrix is always applied to the 16.16 - advance vector in the glyph, you thus don't need to recompute it..

    - -

    c. Measuring the glyph image

    - -

    You can also retrieve the control (bounding) box of any glyph image - (scalable or not), through the FT_Glyph_Get_CBox function, - as in: -

    - -
    
    -     FT_BBox   bbox;
    -     ...
    -     FT_Glyph_BBox(  glyph, bbox_mode, &bbox );
    -  
    - -

    Coordinates are relative to the glyph origin, i.e. (0,0), using the - Y_upwards convention. This function takes a special argument, the - "bbox mode", that is a set of bit flags used to indicate how - box coordinates are expressed. If ft_glyph_bbox_subpixels - is set in the bbox mode, the coordinates are returned in 26.6 pixels - (i.e. 1/64th of pixels). Otherwise, they're in integer pixels.

    - -

    Note that the box's maximum coordinates are exclusive, which means - that you can always compute the width and height of the glyph image, - be in in integer or 26.6 pixels with:

    - -
         
    -     width  = bbox.xMax - bbox.xMin;
    -     height = bbox.yMax - bbox.yMin;
    -  
    - -

    Note also that for 26.6 coordinates, if - ft_glyph_bbox_gridfit is set in the bbox mode, - the coordinates will also be grid-fitted, which corresponds to:

    - -
    
    -     bbox.xMin = FLOOR(bbox.xMin)
    -     bbox.yMin = FLOOR(bbox.yMin)
    -     bbox.xMax = CEILING(bbox.xMax)
    -     bbox.yMax = CEILING(bbox.yMax)
    -  
    - -

    The default value for the bbox mode, which is 0, corresponds to - ft_glyph_bbox_pixels (i.e. integer pixel coordinates).

    - - -

    d. Converting the glyph image to a bitmap

    - -

    You may need to convert the glyph object to a bitmap once you have - convienently cached or transformed it. This can be done easily with - the FT_Glyph_To_Bitmap function. It is chared of - converting any glyph object into a bitmap, as in:

    - -
    
    -    FT_Vector  origin;
    -    
    -    origin.x = 32;   /* 1/2 pixel in 26.26 format */
    -    origin.y = 0;
    -    
    -    error = FT_Glyph_To_Bitmap( &glyph,
    -                                render_mode,
    -                                &origin,
    -                                1 );        // destroy original image == true
    -  
    - -

    We will know details this function's parameters:

    - -
      -
    • - the first parameter is the address of the source glyph's handle. - When the function is called, it reads its to access the source - glyph object. After the call, the handle will point to a - new glyph object that contains the rendered bitmap. -

    • - -
    • - the second parameter is a standard render mode, that is used to specify - what kind of bitmap we want. It can be ft_render_mode_default - for an 8-bit anti-aliased pixmap, or ft_render_mode_mono for - a 1-bit monochrome bitmap. -

    • - -
    • - the third parameter is a pointer to a 2D vector that is used to - translate the source glyph image before the conversion. Note that - the source image will be translated back to its original position - (and will thus be left unchanged) after the call. If you do not need - to translate the source glyph before rendering, set this pointer to 0. -

    • - -
    • - the last parameter is a boolean that indicates wether the source - glyph object should be destroyed by the function. By default, the - original glyph object is never destroyed, even if its handle is - lost (it's up to client applications to keep it). -

    • -
    - -

    The new glyph object always contain a bitmap (when no error is returned), - and you must typecast its handle to the - FT_BitmapGlyph type in order to access its content. - This type is a sort of "subclass" of FT_Glyph that contains - additional fields:

    - -
    - left - -

    Just like the bitmap_left field of a glyph slot, this is the - horizontal distance from the glyph origin (0,0) to the left-most pixel - of the glyph bitmap. It is expressed in integer pixels.

    -
    - top - -

    Just like the bitmap_top field of a glyph slot, this is the - vertical distance from the glyph origin (0,0) to the top-most pixel - of the glyph bitmap (more exactly, to the pixel just above the bitmap). - This distance is expressed in integer pixels, and is positive for upwards - Y.

    -
    - bitmap - -

    This is a bitmap descriptor for the glyph object, just like the - bitmap field in a glyph slot.

    -
    - -
    -

    - 3. Global glyph metrics: -

    - -

    Unlike glyph metrics, global ones are used to describe distances - and features of a whole font face. They can be expressed either in - 26.6 pixels or in design "font units" for scalable formats.

    - -

    - a. Design Global Metrics: -

    - -

    For scalable formats, all global metrics are expressed in font units - in order to be later scaled to device space, according to the rules - described in the last chapter of this section of the tutorial. You - can access them directly as simple fields of a FT_Face - handle.

    - -

    However, you need to check that the font face's format is scalable - before using them. One can do it by using the macro - FT_IS_SCALABLE(face) which returns true when - appropriate.

    - -

    In this case, you can access the global design metrics as:

    - -
    - units_per_EM - -

    This is the size of the EM square for the font face. It is used by scalable - formats to scale design coordinates to device pixels, as described by the - last chapter of this section. Its value usually is 2048 (for TrueType) - or 1000 (for Type1), but others are possible too. It is set to 1 for - fixed-size formats like FNT/FON/PCF/BDF.

    -
    - global_bbox - -

    The global bounding box is defined as the largest rectangle that can - enclose all the glyphs in a font face. It is defined for horizontal - layouts only.

    -
    - ascender - -

    The ascender is the vertical distance from the horizontal baseline to - the highest "character" coordinate in a font face. Unfortunately, font - formats define the ascender differently. For some, it represents - the ascent of all capital latin characters, without accents, for others - it's the ascent of the highest accented character, and finally, other - formats define it as being equal to global_bbox.yMax.

    -
    - descender - -

    The descender is the vertical distance from the horizontal baseline to - the lowest "character" coordinate in a font face. Unfortunately, font - formats define the descender differently. For some, it represents - the descent of all capital latin characters, without accents, for others - it's the ascent of the lowest accented character, and finally, other - formats define it as being equal to global_bbox.yMin. - This field is usually negative

    -
    - text_height - -

    This field is simply used to compute a default line spacing (i.e. the - baseline-to-baseline distance) when writing text with this font. Note that - it usually is larger than the sum of the ascender and descender taken in - absolute value. There is also no guarantee that no glyphs can extend - above or below subsequent baselines when using this distance.

    -
    - max_advance_width - -

    This field gives the maximum horizontal cursor advance for all glyphs - in the font. It can be used to quickly compute the maximum advance width - of a string of text. It doesn't correspond to the maximum glyph image - width !!

    -
    - max_advance_height - -

    Same as max_advance_width but for vertical text layout. It is - only available in fonts providing vertical glyph metrics.

    -
    - underline_position - -

    When displaying or rendering underlined text, this value corresponds to - the vertical position, relative to the baseline, of the underline bar. It - noramlly is negative (as it's below the baseline).

    -
    - underline_thickness - -

    When displaying or rendering underlined text, this value corresponds to - the vertical thickness of the underline.

    -
    - -

    Notice how, unfortunately, the values of the ascender and the descender - are not reliable (due to various discrepancies in font formats).

    - -

    - b. Scaled Global Metrics: -

    - -

    Each size object also contains a scaled versions of some of the global - metrics described above. They can be accessed directly through the - face->size->metrics structure.

    - -

    Note that these values correspond to scaled versions of the design - global metrics, with no rounding/grid-fitting performed.. - They are also completely independent of any hinting process. In other - words, don't rely on them to get exact metrics at the pixel level. - They're expressed in 26.6 pixels.

    - -
    - ascender - -

    This is the scaled version of the original design ascender.

    -
    - descender - -

    This is the scaled version of the original design descender.

    -
    - height - -

    This is the scaled version of the original design text height. - That probably is the only field you should really use in this structure.

    -
    - max_advance - -

    Thi is the scaled version of the original design max advance.

    -
    - -

    Note that the face->size->metrics structure contains other - fields that are used to scale design coordinates to device space. They're - described, in the last chapter.

    - -

    - c. Kerning: -

    - -

    Kerning is the process of adjusting the position of two subsequent - glyph images in a string of text, in order to improve the general - appearance of text. Basically, it means that when the glyph for an - "A" is followed by the glyph for a "V", the space between them can - be slightly reduced to avoid extra "diagonal whitespace".

    - -

    Note that in theory, kerning can happen both in the horizontal and - vertical direction between two glyphs; however, it only happens in - the horizontal direction in nearly all cases except really extreme - ones.

    - -

    Note all font formats contain kerning information. Instead, they sometimes - rely on an additional file that contains various glyph metrics, including - kerning, but no glyph images. A good example would be the Type 1 format, - where glyph images are stored in a file with extension ".pfa" or ".pfb", - and where kerning metrics can be found in an additional file with extension - ".afm" or ".pfm".

    - -

    FreeType 2 allows you to deal with this, by providing the - FT_Attach_File and FT_Attach_Stream APIs. - Both functions are used to load additional metrics into a face object, - by reading them from an additional format-specific file. For example, - you could open a Type 1 font by doing the following:

    - -
    
    -      error = FT_New_Face( library, "/usr/shared/fonts/cour.pfb", 0, &face );
    -      if (error) { ... }
    -      
    -      error = FT_Attach_File( face, "/usr/shared/fonts/cour.afm" );
    -      if (error) { .. could not read kerning and additional metrics .. }
    -  
    - -

    Note that FT_Attach_Stream is similar to - FT_Attach_File except that it doesn't take a C string - to name the extra file, but a FT_Stream handle. Also, - reading a metrics file is in no way, mandatory.

    - -

    Finally, the file attachment APIs are very generic and can be used to - load any kind of extra information for a given face. The nature of the - additional content is entirely font format specific.

    - -

    FreeType 2 allows you to retrieve the kerning information between - two glyphs through the FT_Get_Kerning function, whose - interface looks like:

    - -
    
    -     FT_Vector  kerning;
    -     ...
    -     error = FT_Get_Kerning( face,                  // handle to face object
    -                             left,                  // left glyph index
    -                             right,                 // right glyph index
    -                             kerning_mode,          // kerning mode
    -                             &kerning );            // target vector
    -  
    - -

    As you see, the function takes a handle to a face object, the indices - of the left and right glyphs for which the kerning value is desired, - as well as an integer, called the "kerning mode", and a pointer to - a destination vector that receives the corresponding distances.

    - -

    The kerning mode is very similar to the "bbox mode" described in a - previous chapter. It's a enumeration that indicates how the - kerning distances are expressed in the target vector.

    - -

    The default value is ft_kerning_mode_default which - has value 0. It corresponds to kerning distances expressed in 26.6 - grid-fitted pixels (which means that the values are multiples of 64). - For scalable formats, this means that the design kerning distance is - scaled then rounded.

    - -

    The value ft_kerning_mode_unfitted corresponds to kerning - distances expressed in 26.6 unfitted pixels (i.e. that do not correspond - to integer coordinates). It's the design kerning distance that is simply - scaled without rounding.

    - -

    Finally, the value ft_kerning_mode_unscaled is used to - return the design kerning distance, expressed in font units. You can - later scale it to device space using the computations explained in the - last chapter of this section.

    - -

    Note that the "left" and "right" positions correspond to the visual - order of the glyphs in the string of text. This is important for - - bi-directional text, or simply when writing right-to-left text..

    - -
    - -

    - 4. Simple text rendering: kerning + centering: -

    - -

    In order to show off what we just learned, we will now show how to modify - the example code that was provided in section I to render a string of text, - and enhance it to support kerning and delayed rendering.

    - -

    - a. Kerning support: -

    - -

    Adding support for kerning to our code is trivial, as long as we consider - that we're still dealing with a left-to-right script like Latin. We - simply need to retrieve the kerning distance between two glyphs in order - to alter the pen position appropriately. The code looks like:

    - -
    -      FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -      FT_UInt       glyph_index;
    -      FT_Bool       use_kerning;
    -      FT_UInt       previous;
    -      int           pen_x, pen_y, n;
    -
    -      .. initialise library ..
    -      .. create face object ..
    -      .. set character size ..
    -      
    -      pen_x = 300;
    -      pen_y = 200;
    -      
    -      use_kerning = FT_HAS_KERNING(face);
    -      previous    = 0;
    -      
    -      for ( n = 0; n < num_chars; n++ )
    -      {
    -        // convert character code to glyph index
    -        glyph_index = FT_Get_Char_Index( face, text[n] );
    -        
    -        // retrieve kerning distance and move pen position
    -        if ( use_kerning && previous && glyph_index )
    -        {
    -          FT_Vector  delta;
    -          
    -          FT_Get_Kerning( face, previous, glyph_index,
    -                          ft_kerning_mode_default, &delta );
    -                          
    -          pen_x += delta.x >> 6;
    -        }
    -      
    -        // load glyph image into the slot (erase previous one)
    -        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER );
    -        if (error) continue;  // ignore errors
    -        
    -        // now, draw to our target surface
    -        my_draw_bitmap( &slot->bitmap,
    -                        pen_x + slot->bitmap_left,
    -                        pen_y - slot->bitmap_top );
    -                        
    -        // increment pen position
    -        pen_x += slot->advance.x >> 6;
    -        
    -        // record current glyph index
    -        previous = glyph_index
    -      }
    -   
    - -

    That's it. You'll notice that:

    - -
      -
    • - As kerning is determined from glyph indices, we need to explicitely - convert our character code into a glyph index, then later call - FT_Load_Glyph instead of FT_Load_Char. No big - deal, if you ask me :-) -

    • - -
    • - We use a boolean named use_kerning which is set with the - result of the macro FT_HAS_KERNING(face). It's - certainly faster not to call FT_Get_Kerning when we know - that the font face does not contain kerning information. -

    • - -
    • - We move the position of the pen before a new glyph is drawn. -

    • - -
    • - We did initialize the variable previous with the value 0, - which always correspond to the "missing glyph" (also called - .notdef in the Postscript world). There is never any - kerning distance associated with this glyph. -

    • - -
    • - We do not check the error code returned by FT_get_Kerning. - This is because the function always set the content of delta - to (0,0) when an error occurs. -

    • -
    - -

    As you see, this is not terribly complex :-)

    - -

    - b. Centering: -

    - -

    Our code begins to become interesting but it's still a bit too simple - for normal uses. For example, the position of the pen is determined - before we do the rendering when in a normal situation, you would want - to layout the text and measure it before computing its final position - (e.g. centering) or perform things like word-wrapping.

    - -

    We're thus now going to decompose our text rendering function into two - distinct but successive parts: the first one will position individual - glyph images on the baseline, while the second one will render the - glyphs. As we'll see, this has many advantages.

    - -

    We will thus start by storing individual glyph images, as well as their - position on the baseline. This can be done with code like:

    - -
    -      FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -      FT_UInt       glyph_index;
    -      FT_Bool       use_kerning;
    -      FT_UInt       previous;
    -      int           pen_x, pen_y, n;
    -      
    -      FT_Glyph      glyphs[ MAX_GLYPHS ];   // glyph image
    -      FT_Vector     pos   [ MAX_GLYPHS ];   // glyph position
    -      FT_UInt       num_glyphs;
    -
    -      .. initialise library ..
    -      .. create face object ..
    -      .. set character size ..
    -      
    -      pen_x = 0;   /* start at (0,0) !! */
    -      pen_y = 0;
    -      
    -      num_glyphs  = 0;
    -      use_kerning = FT_HAS_KERNING(face);
    -      previous    = 0;
    -      
    -      for ( n = 0; n < num_chars; n++ )
    -      {
    -        // convert character code to glyph index
    -        glyph_index = FT_Get_Char_Index( face, text[n] );
    -        
    -        // retrieve kerning distance and move pen position
    -        if ( use_kerning && previous && glyph_index )
    -        {
    -          FT_Vector  delta;
    -          
    -          FT_Get_Kerning( face, previous, glyph_index,
    -                          ft_kerning_mode_default, &delta );
    -                          
    -          pen_x += delta.x >> 6;
    -        }
    -      
    -        // store current pen position
    -        pos[ num_glyphs ].x = pen_x;
    -        pos[ num_glyphs ].y = pen_y;
    -      
    -        // load glyph image into the slot. DO NOT RENDER IT !!
    -        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
    -        if (error) continue;  // ignore errors, jump to next glyph
    -        
    -        // extract glyph image and store it in our table
    -        error = FT_Get_Glyph( face->glyph, & glyphs[num_glyphs] );
    -        if (error) continue;  // ignore errors, jump to next glyph
    -        
    -        // increment pen position
    -        pen_x += slot->advance.x >> 6;
    -        
    -        // record current glyph index
    -        previous = glyph_index
    -        
    -        // increment number of glyphs
    -        num_glyphs++;
    -      }
    -   
    - -

    As you see, this is a very simple variation of our previous code - where we extract each glyph image from the slot, and store it, along - with the corresponding position, in our tables.

    - -

    Note also that "pen_x" contains the total advance for the string of - text. We can now compute the bounding box of the text string with - a simple function like:

    - - -
    -      void   compute_string_bbox( FT_BBox  *abbox )
    -      {
    -        FT_BBox  bbox;
    -        
    -        // initialise string bbox to "empty" values
    -        bbox.xMin = bbox.yMin =  32000;
    -        bbox.xMax = bbox.yMax = -32000;
    -        
    -        // for each glyph image, compute its bounding box, translate it,
    -        // and grow the string bbox
    -        for ( n = 0; n < num_glyphs; n++ )
    -        {
    -          FT_BBox   glyph_bbox;
    -
    -          FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox );
    -
    -          glyph_bbox.xMin += pos[n].x;
    -          glyph_bbox.xMax += pos[n].x;
    -          glyph_bbox.yMin += pos[n].y;
    -          glyph_bbox.yMax += pos[n].y;
    -
    -          if (glyph_bbox.xMin < bbox.xMin)
    -            bbox.xMin = glyph_bbox.xMin;
    -
    -          if (glyph_bbox.yMin < bbox.yMin)
    -            bbox.yMin = glyph_bbox.yMin;
    -
    -          if (glyph_bbox.xMax > bbox.xMax)
    -            bbox.xMax = glyph_bbox.xMax;
    -
    -          if (glyph_bbox.yMax &gy; bbox.yMax)
    -            bbox.yMax = glyph_bbox.yMax;
    -        }
    -        
    -        // check that we really grew the string bbox
    -        if ( bbox.xMin > bbox.xMax )
    -        {
    -          bbox.xMin = 0;
    -          bbox.yMin = 0;
    -          bbox.xMax = 0;
    -          bbox.yMax = 0;
    -        }
    -        
    -        // return string bbox
    -        *abbox = bbox;
    -      }
    -   
    - -

    The resulting bounding box dimensions can then be used to compute the - final pen position before rendering the string as in:

    - -
    -      // compute string dimensions in integer pixels
    -      string_width  = (string_bbox.xMax - string_bbox.xMin)/64;
    -      string_height = (string_bbox.yMax - string_bbox.yMin)/64;
    -   
    -      // compute start pen position in 26.6 cartesian pixels
    -      start_x = (( my_target_width  - string_width )/2)*64;
    -      start_y = (( my_target_height - string_height)/2)*64;
    -      
    -      for ( n = 0; n < num_glyphs; n++ )
    -      {
    -        FT_Glyph  image;
    -        FT_Vector pen;
    -        
    -        image = glyphs[n];
    -        
    -        pen.x = start_x + pos[n].x;
    -        pen.y = start_y + pos[n].y;
    -        
    -        error = FT_Glyph_To_Bitmap( &image, ft_render_mode_normal,
    -                                    &pen.x, 0 );
    -        if (!error)
    -        {
    -          FT_BitmapGlyph  bit = (FT_BitmapGlyph)image;
    -          
    -          my_draw_bitmap( bitmap->bitmap,
    -                          bitmap->left,
    -                          my_target_height - bitmap->top );
    -                          
    -          FT_Done_Glyph( image );
    -        }
    -      }
    -   
    - -

    You'll take note that:

    - -
      -
    • - The pen position is expressed in the cartesian space (i.e. Y upwards). -

    • - -
    • - We call FT_Glyph_To_Bitmap with the destroy - parameter set to 0 (false), in order to avoid destroying the original - glyph image. The new glyph bitmap is accessed through image - after the call and is typecasted to a FT_BitmapGlyph. -

    • - -
    • - We use translation when calling FT_Glyph_To_Bitmap. This - ensures that the left and top fields - of the bitmap glyph object are already set to the correct pixel - coordinates in the cartesian space. -

    • - -
    • - Of course, we still need to convert pixel coordinates from cartesian - to device space before rendering, hence the my_target_height - - bitmap->top in the call to my_draw_bitmap. -

    • - -
    - -

    The same loop can be used to render the string anywhere on our display - surface, without the need to reload our glyph images each time.. We - could also decide to implement word wrapping, and only draw

    - -
    -

    - 5. Advanced text rendering: transform + centering + kerning: -

    - -

    We are now going to modify our code in order to be able to easily - transform the rendered string, for example to rotate it. We will - start by performing a few minor improvements:

    - -

    a. packing & translating glyphs:

    - -

    We'll start by packing the information related to a single glyph image - into a single structure, instead of parallel arrays. We thus define the - following structure type:

    - -
    -     typedef struct TGlyph_
    -     {
    -       FT_UInt    index;    // glyph index
    -       FT_Vector  pos;      // glyph origin on the baseline
    -       FT_Glyph   image;    // glyph image
    -     
    -     } TGlyph, *PGlyph;
    -  
    - -

    We will also translate each glyph image directly after it is loaded - to its position on the baseline at load time. As we'll see, this - as several advantages. Our glyph sequence loader thus becomes:

    - -
    -      FT_GlyphSlot  slot = face->glyph;  // a small shortcut
    -      FT_UInt       glyph_index;
    -      FT_Bool       use_kerning;
    -      FT_UInt       previous;
    -      int           pen_x, pen_y, n;
    -      
    -      TGlyph        glyphs[ MAX_GLYPHS ];   // glyphs table
    -      PGlyph        glyph;                  // current glyph in table
    -      FT_UInt       num_glyphs;
    -
    -      .. initialise library ..
    -      .. create face object ..
    -      .. set character size ..
    -      
    -      pen_x = 0;   /* start at (0,0) !! */
    -      pen_y = 0;
    -      
    -      num_glyphs  = 0;
    -      use_kerning = FT_HAS_KERNING(face);
    -      previous    = 0;
    -
    -      glyph = glyphs;      
    -      for ( n = 0; n < num_chars; n++ )
    -      {
    -        glyph->index = FT_Get_Char_Index( face, text[n] );
    -        
    -        if ( use_kerning && previous && glyph->index )
    -        {
    -          FT_Vector  delta;
    -          
    -          FT_Get_Kerning( face, previous, glyph->index,
    -                          ft_kerning_mode_default, &delta );
    -                          
    -          pen_x += delta.x >> 6;
    -        }
    -      
    -        // store current pen position
    -        glyph->pos.x = pen_x;
    -        glyph->pos.y = pen_y;
    -      
    -        error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
    -        if (error) continue;
    -        
    -        error = FT_Get_Glyph( face->glyph, &glyph->image );
    -        if (error) continue;
    -        
    -        // translate the glyph image now..
    -        FT_Glyph_Transform( glyph->image, 0, &glyph->pos );
    -        
    -        pen_x   += slot->advance.x >> 6;
    -        previous = glyph->index
    -        
    -        // increment number of glyphs
    -        glyph++;
    -      }
    -      // count number of glyphs loaded..
    -      num_glyphs = glyph - glyphs;
    -   
    - -

    Note that translating glyphs now has several advantages. The first - one, is that we don't need to translate the glyph bbox when we compute - the string's bounding box. The code becomes:

    - -
    -      void   compute_string_bbox( FT_BBox  *abbox )
    -      {
    -        FT_BBox  bbox;
    -        
    -        bbox.xMin = bbox.yMin =  32000;
    -        bbox.xMax = bbox.yMax = -32000;
    -        
    -        for ( n = 0; n < num_glyphs; n++ )
    -        {
    -          FT_BBox   glyph_bbox;
    -
    -          FT_Glyph_Get_CBox( glyphs[n], &glyph_bbox );
    -
    -          if (glyph_bbox.xMin < bbox.xMin)
    -            bbox.xMin = glyph_bbox.xMin;
    -
    -          if (glyph_bbox.yMin < bbox.yMin)
    -            bbox.yMin = glyph_bbox.yMin;
    -
    -          if (glyph_bbox.xMax > bbox.xMax)
    -            bbox.xMax = glyph_bbox.xMax;
    -
    -          if (glyph_bbox.yMax &gy; bbox.yMax)
    -            bbox.yMax = glyph_bbox.yMax;
    -        }
    -        
    -        if ( bbox.xMin > bbox.xMax )
    -        {
    -          bbox.xMin = 0;
    -          bbox.yMin = 0;
    -          bbox.xMax = 0;
    -          bbox.yMax = 0;
    -        }
    -        
    -        *abbox = bbox;
    -      }
    -   
    - -

    Now take a closer look, the compute_string_bbox can now - compute the bounding box of a transformed glyph string. For example, - we can do something like:

    - -
    
    -      FT_BBox    bbox;
    -      FT_Matrix  matrix;
    -      FT_Vector  delta;
    -   
    -      ... load glyph sequence
    -      
    -      ... setup "matrix" and "delta"
    -      
    -      // transform glyphs
    -      for ( n = 0; n < num_glyphs; n++ )
    -        FT_Glyph_Transform( glyphs[n].image, &matrix, &delta );
    -      
    -      // compute bounding box of transformed glyphs
    -      compute_string_bbox( &bbox );
    -   
    - -

    - b. Rendering a transformed glyph sequence: -

    - -

    However, directly transforming the glyphs in our sequence is not an idea - if we want to re-use them in order to draw the text string with various - angles or transforms. It's better to perform the affine transformation - just before the glyph is rendered, as in the following code:

    - -
    -      FT_Vector  start;
    -      FT_Matrix  transform;
    -   
    -      // get bbox of original glyph sequence
    -      compute_string_bbox( &string_bbox );
    -   
    -      // compute string dimensions in integer pixels
    -      string_width  = (string_bbox.xMax - string_bbox.xMin)/64;
    -      string_height = (string_bbox.yMax - string_bbox.yMin)/64;
    -   
    -      // set up start position in 26.6 cartesian space
    -      start.x = (( my_target_width  - string_width )/2)*64;
    -      start.y = (( my_target_height - string_height)/2)*64;
    -      
    -      // set up transform (a rotation here)
    -      matrix.xx = (FT_Fixed)( cos(angle)*0x10000);
    -      matrix.xy = (FT_Fixed)(-sin(angle)*0x10000);
    -      matrix.yx = (FT_Fixed)( sin(angle)*0x10000);
    -      matrix.yy = (FT_Fixed)( cos(angle)*0x10000);
    -      
    -      for ( n = 0; n < num_glyphs; n++ )
    -      {
    -        FT_Glyph  image;
    -        FT_Vector pen;
    -        FT_BBox   bbox;
    -        
    -        // create a copy of the original glyph
    -        error = FT_Glyph_Copy( glyphs[n].image, &image );
    -        if (error) continue;
    -
    -        // transform copy (this will also translate it to the correct
    -        // position
    -        FT_Glyph_Transform( image, &matrix, &start );
    -        
    -        // check bounding box, if the transformed glyph image
    -        // is not in our target surface, we can avoid rendering it
    -        FT_Glyph_Get_CBox( image, ft_glyph_bbox_pixels, &bbox );
    -        if ( bbox.xMax <= 0 || bbox.xMin >= my_target_width  ||
    -             bbox.yMax <= 0 || bbox.yMin >= my_target_height )
    -          continue;
    -        
    -        // convert glyph image to bitmap (destroy the glyph copy !!)
    -        //
    -        error = FT_Glyph_To_Bitmap( &image,
    -                                    ft_render_mode_normal,
    -                                    0,      // no additional translation
    -                                    1 );    // destroy copy in "image"
    -        if (!error)
    -        {
    -          FT_BitmapGlyph  bit = (FT_BitmapGlyph)image;
    -          
    -          my_draw_bitmap( bitmap->bitmap,
    -                          bitmap->left,
    -                          my_target_height - bitmap->top );
    -                          
    -          FT_Done_Glyph( image );
    -        }
    -      }
    -   
    - -

    You'll notice a few changes compared to the original version of this - code:

    - -
      -
    • - We keep the original glyph images untouched, by transforming a - copy. -

    • - -
    • - We perform clipping computations, in order to avoid rendering & - drawing glyphs that are not within our target surface -

    • - -
    • - We always destroy the copy when calling FT_Glyph_To_Bitmap - in order to get rid of the transformed scalable image. Note that - the image is destroyed even when the function returns an error - code (which is why FT_Done_Glyph is only called within - the compound statement. -

    • - -
    • - The translation of the glyph sequence to the start pen position is - integrated in the call to FT_Glyph_Transform intead of - FT_Glyph_To_Bitmap. -

    • -
    - -

    It's possible to call this function several times to render the string - width different angles, or even change the way "start" is computed in - order to move it to different place.

    - -

    This code is the basis of the FreeType 2 demonstration program - named"ftstring.c". It could be easily extended to perform - advanced text layout or word-wrapping in the first part, without - changing the second one.

    - -

    Note however that a normal implementation would use a glyph cache in - order to reduce memory needs. For example, let's assume that our text - string is "FreeType". We would store three identical glyph images in - our table for the letter "e", which isn't optimal (especially when you - consider longer lines of text, or even whole pages..). -

    - -
    - -

    - 6. Accessing metrics in design font units, and scaling them: -

    - -

    Scalable font formats usually store a single vectorial image, called - an "outline", for each in a face. Each outline is defined in an abstract - grid called the "design space", with coordinates expressed in nominal - "font units". When a glyph image is loaded, the font driver usually - scales the outline to device space according to the current character - pixel size found in a FT_Size object. The driver may also - modify the scaled outline in order to significantly improve its - appearance on a pixel-based surface (a process known as "hinting" - or "grid-fitting").

    - -

    This chapter describes how design coordinates are scaled to device - space, and how to read glyph outlines and metrics in font units. This - is important for a number of things:

    - -
      -
    • - In order to perform "true" WYSIWYG text layout -

    • - -
    • - In order to access font content for conversion or analysis purposes -

    • -
    - -

    a.Scaling distances to device space:

    - -

    Design coordinates are scaled to device space using a simple scaling - transform, whose coefficients are computed with the help of the - character pixel size:

    - -
    
    -     device_x = design_x * x_scale
    -     device_y = design_y * y_scale
    -
    -     x_scale  = pixel_size_x / EM_size
    -     y_scale  = pixel_size_y / EM_size
    -  
    - -

    Here, the value EM_size is font-specific and correspond - to the size of an abstract square of the design space (called the "EM"), - which is used by font designers to create glyph images. It is thus - expressed in font units. It is also accessible directly for scalable - font formats as face->units_per_EM. You should - check that a font face contains scalable glyph images by using the - FT_IS_SCALABLE(face) macro, which returns true when - appropriate.

    - -

    When you call the function FT_Set_Pixel_Sizes, you're - specifying the value of pixel_size_x and pixel_size_y - you want to use to FreeType, which will immediately compute the values - of x_scale and y_scale.

    - -

    When you call the function FT_Set_Char_Size, you're - specifying the character size in physical "points", which is used, - along with the device's resolutions, to compute the character pixel - size, then the scaling factors.

    - -

    Note that after calling any of these two functions, you can access - the values of the character pixel size and scaling factors as fields - of the face->size->metrics structure. These fields are:

    - -
    - -
    - x_ppem - -

    Which stands for "X Pixels Per EM", this is the size in integer pixels - of the EM square, which also is the horizontal character pixel size, - called pixel_size_x in the above example.

    -
    - y_ppem - -

    Which stands for "Y Pixels Per EM", this is the size in integer pixels - of the EM square, which also is the vertical character pixel size, - called pixel_size_y in the above example.

    -
    - x_scale - -

    This is a 16.16 fixed float scale that is used to directly - scale horizontal distances from design space to 1/64th of device pixels. -

    -
    - y_scale - -

    This is a 16.16 fixed float scale that is used to directly scale - vertical distances from design space to 1/64th of device pixels.

    -
    -
    - -

    Basically, this means that you can scale a distance expressed in - font units to 26.6 pixels directly with the help of the FT_MulFix - function, as in:

    - -
    
    -      // convert design distances to 1/64th of pixels
    -      //
    -      pixels_x = FT_MulFix( design_x, face->size->metrics.x_scale );
    -      pixels_y = FT_MulFix( design_y, face->size->metrics.y_scale );
    -  
    - -

    However, you can also scale the value directly with more accuracy - by using doubles and the equations:

    - -
    
    -      FT_Size_Metrics*  metrics = &face->size->metrics;    // shortcut
    -      double            pixels_x, pixels_y;
    -      double            em_size, x_scale, y_scale;
    -
    -      // compute floating point scale factors
    -      //
    -      em_size = 1.0 * face->units_per_EM;
    -      x_scale = metrics->x_ppem / em_size;
    -      y_scale = metrics->y_ppem / em_size;
    -      
    -      // convert design distances to floating point pixels
    -      //
    -      pixels_x = design_x * x_scale;
    -      pixels_y = design_y * y_scale;
    -  
    - -

    - b. Accessing design metrics (glyph & global): -

    - -

    You can access glyph metrics in font units simply by specifying the - FT_LOAD_NO_SCALE bit flag in FT_Load_Glyph - or FT_Load_Char. The metrics returned in - face->glyph->metrics will all be in font units.

    - -

    You can access unscaled kerning data using the - ft_kerning_mode_unscaled mode

    - -

    Finally, a few global metrics are available directly in font units - as fields of the FT_Face handle, as described in chapter 3 - of this section.

    - -
    - -

    - Conclusion -

    - -

    This is the end of the second section of the FreeType 2 tutorial, - you're now able to access glyph metrics, manage glyph images, and - render text much more intelligently (kerning, measuring, transforming - & caching).

    - -

    You have now sufficient knowledge to build a pretty decent text service - on top of FreeType 2, and you could possibly stop there if you want.

    - -

    The next section will deal with FreeType 2 internals (like modules, - vector outlines, font drivers, renderers), as well as a few font format - specific issues (mainly, how to access certain TrueType or Type 1 tables). -

    -
    -
    - - - diff --git a/subsys/win32k/freetype/grfont.c b/subsys/win32k/freetype/grfont.c deleted file mode 100644 index d8e8d41..0000000 --- a/subsys/win32k/freetype/grfont.c +++ /dev/null @@ -1,415 +0,0 @@ -// Taken from FreeType 2 (www.freetype.org) - -#undef WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include "../eng/objects.h" - -//#define NDEBUG -#include - -// #include "grfont.h" -// #include - -/* font characters */ - -const 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 -}; - -static PSURFOBJ CharCellSurfObj; -static HBITMAP hCharCellBitmap; - -VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap); - -// Set things up for a character cell surface -void CreateCellCharSurface() -{ - PSURFGDI surfgdi; - PBITMAPOBJ pbo; - - CharCellSurfObj = ExAllocatePool(NonPagedPool, sizeof(SURFOBJ)); - surfgdi = ExAllocatePool(NonPagedPool, sizeof(SURFGDI)); - - hCharCellBitmap = W32kCreateBitmap(8, 8, 1, 8, NULL); // 8x8, 1 plane, 8 bits per pel - - pbo = BITMAPOBJ_HandleToPtr(hCharCellBitmap); - ASSERT( pbo ); -// VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap) - BitmapToSurf(0, surfgdi, CharCellSurfObj, pbo); // Make the bitmap a surface - BITMAPOBJ_ReleasePtr( hCharCellBitmap ); -} - -void grWriteCellChar(PSURFOBJ target, - int x, - int y, - int charcode, - COLORREF color) -{ - RECTL DestRect; - POINTL SourcePoint; - - char *bigbit, *mover; - unsigned char thebyte, thebit, idxColor; - int i, j, charcode8, i8; - - if (charcode < 0 || charcode > 255) - return; - - DestRect.left = x; - DestRect.top = y; - DestRect.right = x+8; - DestRect.bottom = y+8; - - SourcePoint.x = 0; - SourcePoint.y = 0; - - bigbit = ExAllocatePool(NonPagedPool, 256); - - // Explode the 1BPP character cell into an 8BPP one due to current GDI limitations.. major FIXME - charcode8 = charcode * 8; - mover = bigbit; - - for (i=0; i<8; i++) - { - thebyte = font_8x8[charcode8 + i]; - i8 = i*8; - for (j=8; j>0; j--) - { - thebit = thebyte & (1 << j); - if(thebit>0) thebit = 1; - *mover = thebit; - mover++; - } - } - - W32kSetBitmapBits(hCharCellBitmap, 256, bigbit); - - // Blt bitmap to screen - EngBitBlt(target, CharCellSurfObj, NULL, NULL, NULL, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL); - - ExFreePool(bigbit); -} - -void grWriteCellString(PSURFOBJ target, - int x, - int y, - const char* string, - COLORREF color) -{ - while (*string) - { - grWriteCellChar(target, x, y, *string++, color); - x += 8; - } -} - -static int gr_cursor_x = 0; -static int gr_cursor_y = 0; -static PBITMAPOBJ gr_text_bitmap = 0; -static int gr_margin_right = 0; -static int gr_margin_top = 0; - -void grGotobitmap(PBITMAPOBJ bitmap ) -{ - gr_text_bitmap = bitmap; -} - -void grSetMargin(int right, int top) -{ - gr_margin_top = top << 3; - gr_margin_right = right << 3; -} - -void grGotoxy(int x, int y) -{ - gr_cursor_x = x; - gr_cursor_y = y; -} - -void grWrite(const char* string) -{ - if (string) - { - COLORREF color; - -// color.value = 127; - grWriteCellString( gr_text_bitmap, - gr_margin_right + (gr_cursor_x << 3), - gr_margin_top + (gr_cursor_y << 3), - string, - color ); - - gr_cursor_x += strlen(string); - } -} - -void grLn() -{ - gr_cursor_y ++; - gr_cursor_x = 0; -} - -void grWriteln(const char* string) -{ - grWrite( string ); - grLn(); -} diff --git a/subsys/win32k/freetype/grfont.h b/subsys/win32k/freetype/grfont.h deleted file mode 100644 index 2697e00..0000000 --- a/subsys/win32k/freetype/grfont.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GRFONT_H -#define GRFONT_H - -#include "graph.h" - - extern const unsigned char font_8x8[]; - - extern void grGotobitmap( grBitmap* bitmap ); - extern void grSetMargin( int right, int top ); - extern void grGotoxy ( int x, int y ); - - extern void grWrite ( const char* string ); - extern void grWriteln( const char* string ); - extern void grLn(); - -#endif /* GRFONT_H */ diff --git a/subsys/win32k/freetype/include/freetype/config/ftconfig.h b/subsys/win32k/freetype/include/freetype/config/ftconfig.h deleted file mode 100644 index 338e22c..0000000 --- a/subsys/win32k/freetype/include/freetype/config/ftconfig.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftconfig.h */ -/* */ -/* ANSI-specific configuration file (specification only). */ -/* */ -/* Copyright 1996-2000 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 header file contains a number of macro definitions that are used */ - /* by the rest of the engine. Most of the macros here are automatically */ - /* determined at compile time, and you should not need to change it to */ - /* port FreeType, except to compile the library with a non-ANSI */ - /* compiler. */ - /* */ - /* Note however that if some specific modifications are needed, we */ - /* advise you to place a modified copy in your build directory. */ - /* */ - /* The build directory is usually `freetype/builds/', and */ - /* contains system-specific files that are always included first when */ - /* building the library. */ - /* */ - /* This ANSI version should stay in `include/freetype/config'. */ - /* */ - /*************************************************************************/ - - -#ifndef FTCONFIG_H -#define FTCONFIG_H - - - /* Include the header file containing all developer build options */ -#include - - - /*************************************************************************/ - /* */ - /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled to suit a specific system. The current */ - /* ones are defaults used to compile FreeType in an ANSI C environment */ - /* (16bit compilers are also supported). Copy this file to your own */ - /* `freetype/builds/' directory, and edit it to port the engine. */ - /* */ - /*************************************************************************/ - - - /* We use values to know the sizes of the types. */ -#include - - /* The number of bytes in an `int' type. */ -#if UINT_MAX == 0xFFFFFFFF -#define FT_SIZEOF_INT 4 -#elif UINT_MAX == 0xFFFF -#define FT_SIZEOF_INT 2 -#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF -#define FT_SIZEOF_INT 8 -#else -#error "Unsupported number of bytes in `int' type!" -#endif - - /* The number of bytes in a `long' type. */ -#if ULONG_MAX == 0xFFFFFFFF -#define FT_SIZEOF_LONG 4 -#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF -#define FT_SIZEOF_LONG 8 -#else -#error "Unsupported number of bytes in `long' type!" -#endif - - - /* Preferred alignment of data */ -#define FT_ALIGNMENT 8 - - - /* UNUSED is a macro used to indicate that a given parameter is not used */ - /* -- this is only used to get rid of unpleasant compiler warnings */ -#ifndef FT_UNUSED -#define FT_UNUSED( arg ) ( (arg) = (arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* AUTOMATIC CONFIGURATION MACROS */ - /* */ - /* These macros are computed from the ones defined above. Don't touch */ - /* their definition, unless you know precisely what you are doing. No */ - /* porter should need to mess with them. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* IntN types */ - /* */ - /* Used to guarantee the size of some specific integers. */ - /* */ - typedef signed short FT_Int16; - typedef unsigned short FT_UInt16; - -#if FT_SIZEOF_INT == 4 - - typedef signed int FT_Int32; - typedef unsigned int FT_UInt32; - -#elif FT_SIZEOF_LONG == 4 - - typedef signed long FT_Int32; - typedef unsigned long FT_UInt32; - -#else -#error "no 32bit type found -- please check your configuration files" -#endif - -#if FT_SIZEOF_LONG == 8 - - /* FT_LONG64 must be defined if a 64-bit type is available */ -#define FT_LONG64 -#define FT_INT64 long - -#else - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro in */ - /* `ftoption.h'. */ - /* */ - /* Note that this will produce many -ansi warnings during library */ - /* compilation, and that in many cases, the generated code will be */ - /* neither smaller nor faster! */ - /* */ -#ifdef FTCALC_USE_LONG_LONG - -#define FT_LONG64 -#define FT_INT64 long long - -#endif /* FTCALC_USE_LONG_LONG */ -#endif /* FT_SIZEOF_LONG == 8 */ - - -#ifdef FT_MAKE_OPTION_SINGLE_OBJECT -#define LOCAL_DEF static -#define LOCAL_FUNC static -#else -#define LOCAL_DEF extern -#define LOCAL_FUNC /* nothing */ -#endif - -#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT -#define BASE_DEF( x ) static x -#define BASE_FUNC( x ) static x -#else -#define BASE_DEF( x ) extern x -#define BASE_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_DEF -#define FT_EXPORT_DEF( x ) extern x -#endif - -#ifndef FT_EXPORT_FUNC -#define FT_EXPORT_FUNC( x ) extern x -#endif - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - -#endif /* FTCONFIG_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/config/ftmodule.h b/subsys/win32k/freetype/include/freetype/config/ftmodule.h deleted file mode 100644 index 50cc46b..0000000 --- a/subsys/win32k/freetype/include/freetype/config/ftmodule.h +++ /dev/null @@ -1,10 +0,0 @@ -FT_USE_MODULE(autohint_module_class) -FT_USE_MODULE(cff_driver_class) -FT_USE_MODULE(t1cid_driver_class) -FT_USE_MODULE(psnames_module_class) -FT_USE_MODULE(ft_raster1_renderer_class) -FT_USE_MODULE(sfnt_module_class) -FT_USE_MODULE(ft_smooth_renderer_class) -FT_USE_MODULE(tt_driver_class) -FT_USE_MODULE(t1_driver_class) -FT_USE_MODULE(winfnt_driver_class) diff --git a/subsys/win32k/freetype/include/freetype/config/ftoption.h b/subsys/win32k/freetype/include/freetype/config/ftoption.h deleted file mode 100644 index a7e1f40..0000000 --- a/subsys/win32k/freetype/include/freetype/config/ftoption.h +++ /dev/null @@ -1,395 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2000 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 FTOPTION_H -#define FTOPTION_H - - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* These macros can be toggled by developers to enable or disable */ - /* certain aspects of FreeType. This is a default file, where all major */ - /* options are enabled. */ - /* */ - /* Note that if some modifications are required for your build, we */ - /* advise you to put a modified copy of this file in your build */ - /* directory, rather than modifying it in-place. */ - /* */ - /* The build directory is normally `freetype/builds/' and */ - /* contains build or system-specific files that are included in */ - /* priority when building the library. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Convenience functions support */ - /* */ - /* Some functions of the FreeType 2 API are provided as a convenience */ - /* for client applications and developers. However, they are not */ - /* required to build and run the library itself. */ - /* */ - /* By defining this configuration macro, you'll disable the */ - /* compilation of these functions at build time. This can be useful */ - /* to reduce the library's code size when you don't need any of */ - /* these functions. */ - /* */ - /* All convenience functions are declared as such in their */ - /* documentation. */ - /* */ -#undef FT_CONFIG_OPTION_NO_CONVENIENCE_FUNCS - - - /*************************************************************************/ - /* */ - /* Alternate Glyph Image Format support */ - /* */ - /* By default, the glyph images returned by the FreeType glyph loader */ - /* can either be a pixmap or a vectorial outline defined through */ - /* Bezier control points. When defining the following configuration */ - /* macro, some font drivers will be able to register alternate */ - /* glyph image formats. */ - /* */ - /* Unset this macro if you are sure that you will never use a font */ - /* driver with an alternate glyph format; this will reduce the size of */ - /* the base layer code. */ - /* */ - /* Note that a few Type 1 fonts, as well as Windows `vector' fonts */ - /* use a vector `plotter' format that isn't supported when this */ - /* macro is undefined. */ - /* */ -#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `PSNames' module. This */ - /* This module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `PSNames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthetize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthetize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Many compilers provide the non-ANSI `long long' 64-bit type. You can */ - /* activate it by defining the FTCALC_USE_LONG_LONG macro. Note that */ - /* this will produce many -ansi warnings during library compilation, and */ - /* that in many cases the generated code will not be smaller or faster! */ - /* */ -#undef FTCALC_USE_LONG_LONG - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT_DEF and FT_EXPORT_FUNC. */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_FUNC( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_FUNC( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT_DEF and */ - /* FT_EXPORT_FUNC here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ -#undef FT_EXPORT_DEF -#undef FT_EXPORT_FUNC - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ -#define FT_DEBUG_LEVEL_ERROR -#define FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* Computation Algorithms */ - /* */ - /* Used for debugging, this configuration macro should disappear */ - /* soon. */ - /* */ -#define FT_CONFIG_OPTION_OLD_CALCS - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4kByte. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384 - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 16 is the default. */ - /* */ -#define FT_MAX_MODULES 16 - - - /*************************************************************************/ - /* */ - /* FT_MAX_EXTENSIONS */ - /* */ - /* The maximum number of extensions that can be registered in a single */ - /* font driver. 8 is the default. */ - /* */ - /* If you don't know what this means, you certainly do not need to */ - /* change this value. */ - /* */ -#define FT_MAX_EXTENSIONS 8 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. Note that there are */ - /* important patent issues related to the use of the interpreter. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ -#undef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_STACK_DEPTH is the maximal depth of the token stack used by */ - /* the Type 1 parser (see t1load.c). A minimum of 16 is required. */ - /* */ -#define T1_MAX_STACK_DEPTH 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 8 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 32 - - - /*************************************************************************/ - /* */ - /* Define T1_CONFIG_OPTION_DISABLE_HINTER if you want to generate a */ - /* driver with no hinter. This can be useful to debug the parser. */ - /* */ -#undef T1_CONFIG_OPTION_DISABLE_HINTER - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - -#endif /* FTOPTION_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/freetype.h b/subsys/win32k/freetype/include/freetype/freetype.h deleted file mode 100644 index 29316c6..0000000 --- a/subsys/win32k/freetype/include/freetype/freetype.h +++ /dev/null @@ -1,2286 +0,0 @@ -/***************************************************************************/ -/* */ -/* freetype.h */ -/* */ -/* FreeType high-level API and common types (specification only). */ -/* */ -/* Copyright 1996-2000 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 -#define FREETYPE_H - - - /*************************************************************************/ - /* */ - /* The `raster' component duplicates some of the declarations in */ - /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ - /* */ -#define _FREETYPE_ - - - /*************************************************************************/ - /* */ - /* The FREETYPE_MAJOR and FREETYPE_MINOR macros are used to version the */ - /* new FreeType design, which is able to host several kinds of font */ - /* drivers. It starts at 2.0. */ - /* */ -#define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 0 - - -#include /* read configuration information */ -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S I C T Y P E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Metrics */ - /* */ - /* */ - /* A structure used to model the metrics of a single glyph. Note */ - /* that values are expressed in 26.6 fractional pixel format or in */ - /* font units, depending on context. */ - /* */ - /* */ - /* width :: The glyph's width. */ - /* */ - /* height :: The glyph's height. */ - /* */ - /* horiBearingX :: Horizontal left side bearing. */ - /* */ - /* horiBearingY :: Horizontal top side bearing. */ - /* */ - /* horiAdvance :: Horizontal advance width. */ - /* */ - /* vertBearingX :: Vertical left side bearing. */ - /* */ - /* vertBearingY :: Vertical top side bearing. */ - /* */ - /* vertAdvance :: Vertical advance height. */ - /* */ - typedef struct FT_Glyph_Metrics_ - { - FT_Pos width; /* glyph width */ - FT_Pos height; /* glyph height */ - - FT_Pos horiBearingX; /* left side bearing in horizontal layouts */ - FT_Pos horiBearingY; /* top side bearing in horizontal layouts */ - FT_Pos horiAdvance; /* advance width for horizontal layout */ - - FT_Pos vertBearingX; /* left side bearing in vertical layouts */ - FT_Pos vertBearingY; /* top side bearing in vertical layouts */ - FT_Pos vertAdvance; /* advance height for vertical layout */ - - } FT_Glyph_Metrics; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Generic_Finalizer */ - /* */ - /* */ - /* Describes a function used to destroy the `client' data of any */ - /* FreeType object. See the description of the FT_Generic type for */ - /* details of usage. */ - /* */ - /* */ - /* The address of the FreeType object which is under finalization. */ - /* Its client data is accessed through its `generic' field. */ - /* */ - typedef void (*FT_Generic_Finalizer)(void* object); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Generic */ - /* */ - /* */ - /* Client applications often need to associate their own data to a */ - /* variety of FreeType core objects. For example, a text layout API */ - /* might want to associate a glyph cache to a given size object. */ - /* */ - /* Most FreeType object contains a `generic' field, of type */ - /* FT_Generic, which usage is left to client applications and font */ - /* servers. */ - /* */ - /* It can be used to store a pointer to client-specific data, as well */ - /* as the address of a `finalizer' function, which will be called by */ - /* FreeType when the object is destroyed (for example, the previous */ - /* client example would put the address of the glyph cache destructor */ - /* in the `finalizer' field). */ - /* */ - /* */ - /* data :: A typeless pointer to any client-specified data. This */ - /* field is completely ignored by the FreeType library. */ - /* */ - /* finalizer :: A pointer to a `generic finalizer' function, which */ - /* will be called when the object is destroyed. If this */ - /* field is set to NULL, no code will be called. */ - /* */ - typedef struct FT_Generic_ - { - void* data; - FT_Generic_Finalizer finalizer; - - } FT_Generic; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bitmap_Size */ - /* */ - /* */ - /* An extremely simple structure used to model the size of a bitmap */ - /* strike (i.e., a bitmap instance of the font for a given */ - /* resolution) in a fixed-size font face. This is used for the */ - /* `available_sizes' field of the FT_Face_Properties structure. */ - /* */ - /* */ - /* height :: The character height in pixels. */ - /* */ - /* width :: The character width in pixels. */ - /* */ - typedef struct FT_Bitmap_Size_ - { - FT_Short height; - FT_Short width; - - } FT_Bitmap_Size; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* FT_Library */ - /* */ - /* */ - /* A handle to a FreeType library instance. Each `library' is */ - /* completely independent from the others; it is the `root' of a set */ - /* of objects like fonts, faces, sizes, etc. */ - /* */ - /* It also embeds a system object (see FT_System), as well as a */ - /* scan-line converter object (see FT_Raster). */ - /* */ - /* */ - /* Library objects are created through FT_Init_FreeType(). */ - /* */ - typedef struct FT_LibraryRec_ *FT_Library; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Module */ - /* */ - /* */ - /* A handle to a given FreeType module object. Each module can be a */ - /* font driver, a renderer, or anything else that provides services */ - /* to the formers. */ - /* */ - typedef struct FT_ModuleRec_* FT_Module; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Driver */ - /* */ - /* */ - /* A handle to a given FreeType font driver object. Each font driver */ - /* is able to create faces, sizes, glyph slots, and charmaps from the */ - /* resources whose format it supports. */ - /* */ - /* A driver can support either bitmap, graymap, or scalable font */ - /* formats. */ - /* */ - typedef struct FT_DriverRec_* FT_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Renderer */ - /* */ - /* */ - /* A handle to a given FreeType renderer. A renderer is in charge of */ - /* converting a glyph image to a bitmap, when necessary. Each */ - /* supports a given glyph image format, and one or more target */ - /* surface depths. */ - /* */ - typedef struct FT_RendererRec_* FT_Renderer; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Face */ - /* */ - /* */ - /* A handle to a given driver face object. A face object contains */ - /* all the instance and glyph independent data of a font file */ - /* typeface. */ - /* */ - /* A face object is created from a resource object through the */ - /* new_face() method of a given driver. */ - /* */ - typedef struct FT_FaceRec_* FT_Face; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Size */ - /* */ - /* */ - /* A handle to a given driver size object. Such an object models the */ - /* _resolution_ AND _size_ dependent state of a given driver face */ - /* size. */ - /* */ - /* A size object is always created from a given face object. It is */ - /* discarded automatically by its parent face. */ - /* */ - typedef struct FT_SizeRec_* FT_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphSlot */ - /* */ - /* */ - /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any of the glyphs contained within its parent */ - /* face. */ - /* */ - /* A glyph slot is created from a given face object. It is discarded */ - /* automatically by its parent face. */ - /* */ - typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_CharMap */ - /* */ - /* */ - /* A handle to a given character map. A charmap is used to translate */ - /* character codes in a given encoding into glyph indexes for its */ - /* parent's face. Some font formats may provide several charmaps per */ - /* font. */ - /* */ - /* A charmap is created from a given face object. It is discarded */ - /* automatically by its parent face. */ - /* */ - typedef struct FT_CharMapRec_* FT_CharMap; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Encoding */ - /* */ - /* */ - /* An enumeration used to specify encodings supported by charmaps. */ - /* Used in the FT_Select_CharMap() API function. */ - /* */ - /* */ - /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ - /* all character codes must be expressed as FT_Longs. */ - /* */ - typedef enum FT_Encoding_ - { - ft_encoding_none = 0, - ft_encoding_symbol = FT_MAKE_TAG( 's', 'y', 'm', 'b' ), - ft_encoding_unicode = FT_MAKE_TAG( 'u', 'n', 'i', 'c' ), - ft_encoding_latin_2 = FT_MAKE_TAG( 'l', 'a', 't', '2' ), - ft_encoding_sjis = FT_MAKE_TAG( 's', 'j', 'i', 's' ), - ft_encoding_gb2312 = FT_MAKE_TAG( 'g', 'b', ' ', ' ' ), - ft_encoding_big5 = FT_MAKE_TAG( 'b', 'i', 'g', '5' ), - ft_encoding_wansung = FT_MAKE_TAG( 'w', 'a', 'n', 's' ), - ft_encoding_johab = FT_MAKE_TAG( 'j', 'o', 'h', 'a' ), - - ft_encoding_adobe_standard = FT_MAKE_TAG( 'A', 'D', 'O', 'B' ), - ft_encoding_adobe_expert = FT_MAKE_TAG( 'A', 'D', 'B', 'E' ), - ft_encoding_adobe_custom = FT_MAKE_TAG( 'A', 'D', 'B', 'C' ), - - ft_encoding_apple_roman = FT_MAKE_TAG( 'a', 'r', 'm', 'n' ) - - /* other encodings might be defined in the future */ - - } FT_Encoding; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_CharMapRec */ - /* */ - /* */ - /* The base charmap class. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* flags :: A set of bit flags used to describe the charmap. */ - /* Each bit indicates that a given encoding is */ - /* supported. */ - /* */ - /* platform_id :: An ID number describing the platform for the */ - /* following encoding ID. This comes directly from */ - /* the TrueType specification and should be emulated */ - /* for other formats. */ - /* */ - /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and should be */ - /* emulated similarly. */ - /* */ - /* */ - /* We STRONGLY recommmend emulating a Unicode charmap for drivers */ - /* that do not support TrueType or OpenType. */ - /* */ - typedef struct FT_CharMapRec_ - { - FT_Face face; - FT_Encoding encoding; - FT_UShort platform_id; - FT_UShort encoding_id; - - } FT_CharMapRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* B A S E O B J E C T C L A S S E S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* FreeType base face class */ - /* */ - /* */ - /* FT_FaceRec */ - /* */ - /* */ - /* FreeType root face class structure. A face object models the */ - /* resolution and point-size independent data found in a font file. */ - /* */ - /* */ - /* num_faces :: In the case where the face is located in a */ - /* collection (i.e., a resource which embeds */ - /* several faces), this is the total number of */ - /* faces found in the resource. 1 by default. */ - /* */ - /* face_index :: The index of the face in its resource. */ - /* Usually, this is 0 for all normal font */ - /* formats. It can be more in the case of */ - /* collections (which embed several fonts in a */ - /* single resource/file). */ - /* */ - /* face_flags :: A set of bit flags that give important */ - /* information about the face; see the */ - /* FT_FACE_FLAG_XXX macros for details. */ - /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face (i.e., italic, bold, underline, */ - /* etc). */ - /* */ - /* num_glyphs :: The total number of glyphs in the face. */ - /* */ - /* family_name :: The face's family name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's family (like `Times New */ - /* Roman', `Bodoni', `Garamond', etc). This */ - /* is a least common denominator used to list */ - /* fonts. Some formats (TrueType & OpenType) */ - /* provide localized and Unicode versions of */ - /* this string. Applications should use the */ - /* format specific interface to access them. */ - /* */ - /* style_name :: The face's style name. This is an ASCII */ - /* string, usually in English, which describes */ - /* the typeface's style (like `Italic', */ - /* `Bold', `Condensed', etc). Not all font */ - /* formats provide a style name, so this field */ - /* is optional, and can be set to NULL. As */ - /* for `family_name', some formats provide */ - /* localized/Unicode versions of this string. */ - /* Applications should use the format specific */ - /* interface to access them. */ - /* */ - /* num_fixed_sizes :: The number of fixed sizes available in this */ - /* face. This should be set to 0 for scalable */ - /* fonts, unless its resource includes a */ - /* complete set of glyphs (called a `strike') */ - /* for the specified size. */ - /* */ - /* available_sizes :: An array of sizes specifying the available */ - /* bitmap/graymap sizes that are contained in */ - /* in the font resource. Should be set to */ - /* NULL if the field `num_fixed_sizes' is set */ - /* to 0. */ - /* */ - /* num_charmaps :: The total number of character maps in the */ - /* face. */ - /* */ - /* charmaps :: A table of pointers to the face's charmaps */ - /* Used to scan the list of available charmaps */ - /* this table might change after a call to */ - /* FT_Attach_File/Stream (e.g. when it used */ - /* to hook and additional encoding/CMap to */ - /* the face object). */ - /* */ - /* generic :: A field reserved for client uses. See the */ - /* FT_Generic type description. */ - /* */ - /* bbox :: The font bounding box. Coordinates are */ - /* expressed in font units (see units_per_EM). */ - /* The box is large enough to contain any */ - /* glyph from the font. Thus, bbox.yMax can */ - /* be seen as the `maximal ascender', */ - /* bbox.yMin as the `minimal descender', and */ - /* the maximal glyph width is given by */ - /* `bbox.xMax-bbox.xMin' (not to be confused */ - /* with the maximal _advance_width_). Only */ - /* relevant for scalable formats. */ - /* */ - /* units_per_EM :: The number of font units per EM square for */ - /* this face. This is typically 2048 for */ - /* TrueType fonts, 1000 for Type1 fonts, and */ - /* should be set to the (unrealistic) value 1 */ - /* for fixed-sizes fonts. Only relevant for */ - /* scalable formats. */ - /* */ - /* ascender :: The face's ascender is the vertical */ - /* distance from the baseline to the topmost */ - /* point of any glyph in the face. This */ - /* field's value is positive, expressed in */ - /* font units. Some font designs use a value */ - /* different from `bbox.yMax'. Only relevant */ - /* for scalable formats. */ - /* */ - /* descender :: The face's descender is the vertical */ - /* distance from the baseline to the */ - /* bottommost point of any glyph in the face. */ - /* This field's value is positive, expressed */ - /* in font units. Some font designs use a */ - /* value different from `-bbox.yMin'. Only */ - /* relevant for scalable formats. */ - /* */ - /* height :: The face's height is the vertical distance */ - /* from one baseline to the next when writing */ - /* several lines of text. Its value is always */ - /* positive, expressed in font units. The */ - /* value can be computed as */ - /* `ascender+descender+line_gap' where the */ - /* value of `line_gap' is also called */ - /* `external leading'. Only relevant for */ - /* scalable formats. */ - /* */ - /* max_advance_width :: The maximal advance width, in font units, */ - /* for all glyphs in this face. This can be */ - /* used to make word wrapping computations */ - /* faster. Only relevant for scalable */ - /* formats. */ - /* */ - /* max_advance_height :: The maximal advance height, in font units, */ - /* for all glyphs in this face. This is only */ - /* relevant for vertical layouts, and should */ - /* be set to the `height' for fonts that do */ - /* not provide vertical metrics. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_position :: The position, in font units, of the */ - /* underline line for this face. It's the */ - /* center of the underlining stem. Only */ - /* relevant for scalable formats. */ - /* */ - /* underline_thickness :: The thickness, in font units, of the */ - /* underline for this face. Only relevant for */ - /* scalable formats. */ - /* */ - /* driver :: A handle to the face's parent driver */ - /* object. */ - /* */ - /* memory :: A handle to the face's parent memory */ - /* object. Used for the allocation of */ - /* subsequent objects. */ - /* */ - /* stream :: A handle to the face's stream. */ - /* */ - /* glyph :: The face's associated glyph slot(s). This */ - /* object is created automatically with a new */ - /* face object. However, certain kinds of */ - /* applications (mainly tools like converters) */ - /* can need more than one slot to ease their */ - /* task. */ - /* */ - /* sizes_list :: The list of child sizes for this face. */ - /* */ - /* max_points :: The maximal number of points used to store */ - /* the vectorial outline of any glyph in this */ - /* face. If this value cannot be known in */ - /* advance, or if the face isn't scalable, */ - /* this should be set to 0. Only relevant for */ - /* scalable formats. */ - /* */ - /* max_contours :: The maximal number of contours used to */ - /* store the vectorial outline of any glyph in */ - /* this face. If this value cannot be known */ - /* in advance, or if the face isn't scalable, */ - /* this should be set to 0. Only relevant for */ - /* scalable formats. */ - /* */ - /* transform_matrix :: A 2x2 matrix of 16.16 coefficients used */ - /* to transform glyph outlines after they are */ - /* loaded from the font. Only used by the */ - /* convenience functions. */ - /* */ - /* transform_delta :: A translation vector used to transform */ - /* glyph outlines after they are loaded from */ - /* the font. Only used by the convenience */ - /* functions. */ - /* */ - /* transform_flags :: Some flags used to classify the transform. */ - /* Only used by the convenience functions. */ - /* */ - typedef struct FT_FaceRec_ - { - FT_Long num_faces; - FT_Long face_index; - - FT_Long face_flags; - FT_Long style_flags; - - FT_Long num_glyphs; - - FT_String* family_name; - FT_String* style_name; - - FT_Int num_fixed_sizes; - FT_Bitmap_Size* available_sizes; - - /* the face's table of available charmaps */ - FT_Int num_charmaps; - FT_CharMap* charmaps; - - FT_Generic generic; - - /* the following are only relevant for scalable outlines */ - FT_BBox bbox; - - FT_UShort units_per_EM; - FT_Short ascender; - FT_Short descender; - FT_Short height; - - FT_Short max_advance_width; - FT_Short max_advance_height; - - FT_Short underline_position; - FT_Short underline_thickness; - - FT_GlyphSlot glyph; - FT_Size size; - - /************************************************************/ - /* The following fields should be considered private and */ - /* rarely, if ever, used directly by client applications. */ - - FT_Driver driver; - FT_Memory memory; - FT_Stream stream; - - FT_CharMap charmap; - FT_ListRec sizes_list; - - FT_Generic autohint; - void* extensions; - - FT_UShort max_points; - FT_Short max_contours; - - FT_Matrix transform_matrix; - FT_Vector transform_delta; - FT_Int transform_flags; - - } FT_FaceRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_SCALABLE */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face provides */ - /* vectorial outlines (i.e., TrueType or Type1). This doesn't */ - /* prevent embedding of bitmap strikes though, i.e., a given face can */ - /* have both this bit set, and a `num_fixed_sizes' property > 0. */ - /* */ -#define FT_FACE_FLAG_SCALABLE 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FIXED_SIZES */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* `fixed sizes', i.e., bitmap strikes for some given pixel sizes. */ - /* See the `num_fixed_sizes' and `available_sizes' face properties */ - /* for more information. */ - /* */ -#define FT_FACE_FLAG_FIXED_SIZES 2 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FIXED_WIDTH */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* fixed-width characters (like Courier, Lucida, MonoType, etc.). */ - /* */ -#define FT_FACE_FLAG_FIXED_WIDTH 4 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_SFNT */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face uses the */ - /* `sfnt' storage fomat. For now, this means TrueType or OpenType. */ - /* */ -#define FT_FACE_FLAG_SFNT 8 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_HORIZONTAL */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* horizontal glyph metrics. This should be set for all common */ - /* formats, but who knows. */ - /* */ -#define FT_FACE_FLAG_HORIZONTAL 0x10 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_VERTICAL */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* vertical glyph metrics. If not set, the glyph loader will */ - /* synthetize vertical metrics itself to help display vertical text */ - /* correctly. */ - /* */ -#define FT_FACE_FLAG_VERTICAL 0x20 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_KERNING */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face contains */ - /* kerning information. When set, this information can be retrieved */ - /* through the function FT_Get_Kerning(). Note that when unset, this */ - /* function will always return the kerning vector (0,0). */ - /* */ -#define FT_FACE_FLAG_KERNING 0x40 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_FAST_GLYPHS */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the glyphs in a given */ - /* font can be retrieved very quickly, and that a glyph cache is thus */ - /* not necessary for any of its child size objects. */ - /* */ - /* This flag should really be set for fixed-size formats like FNT, */ - /* where each glyph bitmap is available directly in binary form */ - /* without any kind of compression. */ - /* */ -#define FT_FACE_FLAG_FAST_GLYPHS 0x80 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_MULTIPLE_MASTERS */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the font contains */ - /* multiple masters and is capable of interpolating between them. */ - /* */ -#define FT_FACE_FLAG_MULTIPLE_MASTERS 0x100 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_GLYPH_NAMES */ - /* */ - /* */ - /* A bit-field constant, used to indicate that the font contains */ - /* glyph names that can be retrieved through FT_Get_Glyph_Name(). */ - /* */ -#define FT_FACE_FLAG_GLYPH_NAMES 0x200 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FACE_FLAG_EXTERNAL_STREAM */ - /* */ - /* */ - /* This bit field is used internally by FreeType to indicate that */ - /* a face's stream was provided by the client application and should */ - /* not be destroyed by FT_Done_Face(). */ - /* */ -#define FT_FACE_FLAG_EXTERNAL_STREAM 0x4000 - - -#define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) -#define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) -#define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) -#define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) -#define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) -#define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) -#define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) -#define FT_HAS_FAST_GLYPHS( face ) \ - ( face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) -#define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) - -#define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_STYLE_FLAG_ITALIC */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face is */ - /* italicized. */ - /* */ -#define FT_STYLE_FLAG_ITALIC 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_STYLE_FLAG_BOLD */ - /* */ - /* */ - /* A bit-field constant, used to indicate that a given face is */ - /* emboldened. */ - /* */ -#define FT_STYLE_FLAG_BOLD 2 - - - /*************************************************************************/ - /* */ - /* FreeType base size metrics */ - /* */ - /* */ - /* FT_Size_Metrics */ - /* */ - /* */ - /* The size metrics structure returned scaled important distances for */ - /* a given size object. */ - /* */ - /* */ - /* x_ppem :: The character width, expressed in integer pixels. */ - /* This is the width of the EM square expressed in */ - /* pixels, hence the term `ppem' (pixels per EM). */ - /* */ - /* y_ppem :: The character height, expressed in integer pixels. */ - /* This is the height of the EM square expressed in */ - /* pixels, hence the term `ppem' (pixels per EM). */ - /* */ - /* x_scale :: A simple 16.16 fixed point format coefficient used */ - /* to scale horizontal distances expressed in font */ - /* units to fractional (26.6) pixel coordinates. */ - /* */ - /* y_scale :: A simple 16.16 fixed point format coefficient used */ - /* to scale vertical distances expressed in font */ - /* units to fractional (26.6) pixel coordinates. */ - /* */ - /* x_resolution :: The horizontal device resolution for this size */ - /* object, expressed in integer dots per inches */ - /* (dpi). As a convention, fixed font formats set */ - /* this value to 72. */ - /* */ - /* y_resolution :: The vertical device resolution for this size */ - /* object, expressed in integer dots per inches */ - /* (dpi). As a convention, fixed font formats set */ - /* this value to 72. */ - /* */ - /* ascender :: The ascender, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* descender :: The descender, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* height :: The text height, expressed in 26.6 fixed point */ - /* pixels. Always positive. */ - /* */ - /* max_advance :: Maximum horizontal advance, expressed in 26.6 */ - /* fixed point pixels. Always positive. */ - /* */ - /* */ - /* The values of `ascender', `descender', and `height' are only the */ - /* scaled versions of `face->ascender', `face->descender', and */ - /* `face->height'. */ - /* */ - /* Unfortunately, due to glyph hinting, these values might not be */ - /* exact for certain fonts, they thus must be treated as unreliable */ - /* with an error margin of at least one pixel! */ - /* */ - /* Indeed, the only way to get the exact pixel ascender and descender */ - /* is to render _all_ glyphs. As this would be a definite */ - /* performance hit, it is up to client applications to perform such */ - /* computations. */ - /* */ - typedef struct FT_Size_Metrics_ - { - FT_UShort x_ppem; /* horizontal pixels per EM */ - FT_UShort y_ppem; /* vertical pixels per EM */ - - FT_Fixed x_scale; /* two scales used to convert font units */ - FT_Fixed y_scale; /* to 26.6 frac. pixel coordinates.. */ - - FT_Pos ascender; /* ascender in 26.6 frac. pixels */ - FT_Pos descender; /* descender in 26.6 frac. pixels */ - FT_Pos height; /* text height in 26.6 frac. pixels */ - FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ - - } FT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* FreeType base size class */ - /* */ - /* */ - /* FT_SizeRec */ - /* */ - /* */ - /* FreeType root size class structure. A size object models the */ - /* resolution and pointsize dependent data of a given face. */ - /* */ - /* */ - /* face :: Handle to the parent face object. */ - /* */ - /* generic :: A typeless pointer, which is unused by the FreeType */ - /* library or any of its drivers. It can be used by */ - /* client applications to link their own data to each size */ - /* object. */ - /* */ - /* metrics :: Metrics for this size object. This field is read-only. */ - /* */ - typedef struct FT_SizeRec_ - { - FT_Face face; /* parent face object */ - FT_Generic generic; /* generic pointer for client uses */ - FT_Size_Metrics metrics; /* size metrics */ - - } FT_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_SubGlyph */ - /* */ - /* */ - /* The subglyph structure is an internal object used to describe */ - /* subglyphs (for example, in the case of composites). */ - /* */ - /* */ - /* The subglyph implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_SubGlyph_ FT_SubGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphLoader */ - /* */ - /* */ - /* The glyph loader is an internal object used to load several glyphs */ - /* together (for example, in the case of composites). */ - /* */ - /* */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoader_ FT_GlyphLoader; - - - /*************************************************************************/ - /* */ - /* FreeType Glyph Slot base class */ - /* */ - /* */ - /* FT_GlyphSlotRec */ - /* */ - /* */ - /* FreeType root glyph slot class structure. A glyph slot is a */ - /* container where individual glyphs can be loaded, be they */ - /* vectorial or bitmap/graymaps. */ - /* */ - /* */ - /* library :: A handle to the FreeType library instance */ - /* this slot belongs to. */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* next :: In some cases (like some font tools), several */ - /* glyph slots per face object can be a good */ - /* thing. As this is rare, the glyph slots are */ - /* listed through a direct, single-linked list */ - /* using its `next' field. */ - /* */ - /* generic :: A typeless pointer which is unused by the */ - /* FreeType library or any of its drivers. It */ - /* can be used by client applications to link */ - /* their own data to each size object. */ - /* */ - /* metrics :: The metrics of the last loaded glyph in the */ - /* slot. The returned values depend on the last */ - /* load flags (see the FT_Load_Glyph() API */ - /* function) and can be expressed either in 26.6 */ - /* fractional pixels or font units. */ - /* */ - /* Note that even when the glyph image is */ - /* transformed, the metrics are not. */ - /* */ - /* linearHoriAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled horizontal advance width */ - /* for the glyph (i.e. the scaled and unhinted */ - /* value of the hori advance). This can be */ - /* important to perform correct WYSIWYG layout */ - /* */ - /* Note that this value is expressed by default */ - /* in 16.16 pixels. However, when the glyph is */ - /* loaded with the FT_LOAD_UNSCALED_LINEAR flag, */ - /* this field contains simply the value of the */ - /* advance in original font units. */ - /* */ - /* linearVertAdvance :: For scalable formats only, this field holds */ - /* the linearly scaled vertical advance height */ - /* for the glyph. See linearHoriAdvance for */ - /* comments. */ - /* */ - /* advance :: This is the transformed advance width for the */ - /* glyph. */ - /* */ - /* format :: This field indicates the format of the image */ - /* contained in the glyph slot. Typically */ - /* ft_glyph_format_bitmap, */ - /* ft_glyph_format_outline, and */ - /* ft_glyph_format_composite, but others are */ - /* possible. */ - /* */ - /* bitmap :: This field is used as a bitmap descriptor */ - /* when the slot format is */ - /* ft_glyph_format_bitmap. Note that the */ - /* address and content of the bitmap buffer can */ - /* change between calls of FT_Load_Glyph() and a */ - /* few other functions. */ - /* */ - /* bitmap_left :: This is the bitmap's left bearing expressed */ - /* in integer pixels. Of course, this is only */ - /* valid if the format is */ - /* ft_glyph_format_bitmap. */ - /* */ - /* bitmap_top :: This is the bitmap's top bearing expressed in */ - /* integer pixels. Remember that this is the */ - /* distance from the baseline to the top-most */ - /* glyph scanline, upwards y-coordinates being */ - /* *positive*. */ - /* */ - /* outline :: The outline descriptor for the current glyph */ - /* image if its format is */ - /* ft_glyph_bitmap_outline. */ - /* */ - /* num_subglyphs :: The number of subglyphs in a composite glyph. */ - /* This format is only valid for the composite */ - /* glyph format, that should normally only be */ - /* loaded with the FT_LOAD_NO_RECURSE flag. */ - /* */ - /* subglyphs :: An array of subglyph descriptors for */ - /* composite glyphs. There are `num_subglyphs' */ - /* elements in there. */ - /* */ - /* control_data :: Certain font drivers can also return the */ - /* control data for a given glyph image (e.g. */ - /* TrueType bytecode, Type 1 charstrings, etc.). */ - /* This field is a pointer to such data. */ - /* */ - /* control_len :: This is the length in bytes of the control */ - /* data. */ - /* */ - /* other :: Really wicked formats can use this pointer to */ - /* present their own glyph image to client apps. */ - /* Note that the app will need to know about the */ - /* image format. */ - /* */ - /* loader :: This is a private object for the glyph slot. */ - /* Do not touch this. */ - /* */ - /* */ - /* If FT_Load_Glyph() is called with default flags (FT_LOAD_DEFAULT), */ - /* the glyph image is loaded in the glyph slot in its native format */ - /* (e.g. a vectorial outline for TrueType and Type 1 formats). */ - /* */ - /* This image can later be converted into a bitmap by calling */ - /* FT_Render_Glyph(). This function finds the current renderer for */ - /* the native image's format then invokes it. */ - /* */ - /* The renderer is in charge of transforming the native image through */ - /* the slot's face transformation fields, then convert it into a */ - /* bitmap that is returned in `slot->bitmap'. */ - /* */ - /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ - /* to specify the position of the bitmap relative to the current pen */ - /* position (e.g. coordinates [0,0] on the baseline). Of course, */ - /* `slot->format' is also changed to `ft_glyph_format_bitmap' . */ - /* */ - typedef struct FT_GlyphSlotRec_ - { - FT_Library library; - FT_Face face; - FT_GlyphSlot next; - FT_UInt flags; - FT_Generic generic; - - FT_Glyph_Metrics metrics; - FT_Fixed linearHoriAdvance; - FT_Fixed linearVertAdvance; - FT_Vector advance; - - FT_Glyph_Format format; - - FT_Bitmap bitmap; - FT_Int bitmap_left; - FT_Int bitmap_top; - - FT_Outline outline; - - FT_UInt num_subglyphs; - FT_SubGlyph* subglyphs; - - void* control_data; - long control_len; - - void* other; - - /* private fields */ - FT_GlyphLoader* loader; - - } FT_GlyphSlotRec; - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* F U N C T I O N S */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Init_FreeType */ - /* */ - /* */ - /* Initializes a new FreeType library object. The set of drivers */ - /* that are registered by this function is determined at build time. */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Init_FreeType( FT_Library* library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_FreeType */ - /* */ - /* */ - /* Destroys a given FreeType library object and all of its childs, */ - /* including resources, drivers, faces, sizes, etc. */ - /* */ - /* */ - /* library :: A handle to the target library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_FreeType( FT_Library library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Flags */ - /* */ - /* */ - /* An enumeration used to list the bit flags used within */ - /* FT_Open_Args(). */ - /* */ - /* */ - /* ft_open_memory :: This is a memory-based stream. */ - /* */ - /* ft_open_stream :: Copy the stream from the `stream' field. */ - /* */ - /* ft_open_pathname :: Create a new input stream from a C pathname. */ - /* */ - /* ft_open_driver :: Use the `driver' field. */ - /* */ - /* ft_open_params :: Use the `num_params' & `params' field. */ - /* */ - typedef enum - { - ft_open_memory = 1, - ft_open_stream = 2, - ft_open_pathname = 4, - ft_open_driver = 8, - ft_open_params = 16 - - } FT_Open_Flags; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Parameter */ - /* */ - /* */ - /* A simple structure used to pass more or less generic parameters */ - /* to FT_Open_Face(). */ - /* */ - /* */ - /* tag :: A 4-byte identification tag. */ - /* */ - /* data :: A pointer to the parameter data. */ - /* */ - /* */ - /* The id and function of parameters are driver-specific. */ - /* */ - typedef struct FT_Parameter_ - { - FT_ULong tag; - FT_Pointer data; - - } FT_Parameter; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Args */ - /* */ - /* */ - /* A structure used to indicate how to open a new font file/stream. */ - /* A pointer to such a structure can be used as a parameter for the */ - /* functions FT_Open_Face() & FT_Attach_Stream(). */ - /* */ - /* */ - /* flags :: A set of bit flags indicating how to use the */ - /* structure. */ - /* */ - /* memory_base :: The first byte of the file in memory. */ - /* */ - /* memory_size :: The size in bytes of the file in memory. */ - /* */ - /* pathname :: A pointer to an 8-bit file pathname. */ - /* */ - /* stream :: A handle to a source stream object. */ - /* */ - /* driver :: This field is exclusively used by FT_Open_Face(); */ - /* it simply specifies the font driver to use to open */ - /* the face. If set to 0, FreeType will try to load */ - /* the face with each one of the drivers in its list. */ - /* */ - /* num_params :: The number of extra parameters. */ - /* */ - /* params :: Extra parameters passed to the font driver when */ - /* opening a new face. */ - /* */ - /* */ - /* `stream_type' determines which fields are used to create a new */ - /* input stream. */ - /* */ - /* If it is `ft_stream_memory', a new memory-based stream will be */ - /* created using the memory block specified by `memory_base' and */ - /* `memory_size'. */ - /* */ - /* If it is `ft_stream_pathname', a new stream will be created with */ - /* the `pathname' field, calling the system-specific FT_New_Stream() */ - /* function. */ - /* */ - /* If is is `ft_stream_copy', then the content of `stream' will be */ - /* copied to a new input stream object. The object will be closed */ - /* and destroyed when the face is destroyed itself. Note that this */ - /* means that you should not close the stream before the library */ - /* does! */ - /* */ - typedef struct FT_Open_Args_ - { - FT_Open_Flags flags; - FT_Byte* memory_base; - FT_Long memory_size; - FT_String* pathname; - FT_Stream stream; - FT_Module driver; - FT_Int num_params; - FT_Parameter* params; - - } FT_Open_Args; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a pathname to the font file. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* pathname :: A path to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Face( FT_Library library, - const char* filepathname, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a font file already loaded into memory. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* file_base :: A pointer to the beginning of the font data. */ - /* */ - /* file_size :: The size of the memory chunk used by the font data. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* face :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Memory_Face() can be used to determine and/or check the */ - /* font format of a given font resource. If the `face_index' field */ - /* is negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Memory_Face( FT_Library library, - FT_Byte* file_base, - FT_Long file_size, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Face */ - /* */ - /* */ - /* Opens a face object from a given resource and typeface index using */ - /* an `FT_Open_Args' structure. If the face object doesn't exist, it */ - /* will be created. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ - /* be filled by the caller. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_Open_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Open_Face( FT_Library library, - FT_Open_Args* args, - FT_Long face_index, - FT_Face* face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_File */ - /* */ - /* */ - /* `Attaches' a given font file to an existing face. This is usually */ - /* to read additional information for a single face object. For */ - /* example, it is used to read the AFM files that come with Type 1 */ - /* fonts in order to add kerning data and other metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* */ - /* filepathname :: An 8-bit pathname naming the `metrics' file. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If your font file is in memory, or if you want to provide your */ - /* own input stream object, use FT_Attach_Stream(). */ - /* */ - /* The meaning of the `attach' action (i.e., what really happens when */ - /* the new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Attach_File( FT_Face face, - const char* filepathname ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_Stream */ - /* */ - /* */ - /* This function is similar to FT_Attach_File() with the exception */ - /* that it reads the attachment from an arbitrary stream. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* parameters :: A pointer to an FT_Open_Args structure used to */ - /* describe the input stream to FreeType. */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The meaning of the `attach' (i.e. what really happens when the */ - /* new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Face */ - /* */ - /* */ - /* Discards a given face object, as well as all of its child slots */ - /* and sizes. */ - /* */ - /* */ - /* face :: A handle to a target face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_Face( FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Char_Size */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The */ - /* `char_width' and `char_height' values are used for the width and */ - /* height, respectively, expressed in 26.6 fractional points. */ - /* */ - /* If the horizontal or vertical resolution values are zero, a */ - /* default value of 72dpi is used. Similarly, if one of the */ - /* character dimensions is zero, its value is set equal to the other. */ - /* */ - /* */ - /* size :: A handle to a target size object. */ - /* */ - /* */ - /* char_width :: The character width, in 26.6 fractional points. */ - /* */ - /* char_height :: The character height, in 26.6 fractional */ - /* points. */ - /* */ - /* horz_resolution :: The horizontal resolution. */ - /* */ - /* vert_resolution :: The vertical resolution. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* When dealing with fixed-size faces (i.e., non-scalable formats), */ - /* use the function FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Pixel_Sizes */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The width */ - /* and height are expressed in integer pixels. */ - /* */ - /* If one of the character dimensions is zero, its value is set equal */ - /* to the other. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* pixel_width :: The character width, in integer pixels. */ - /* */ - /* pixel_height :: The character height, in integer pixels. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* face :: A handle to the target face object where the glyph */ - /* will be loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform. */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Char */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size, according to its character code. */ - /* */ - /* */ - /* face :: A handle to a target face object where the glyph */ - /* will be loaded. */ - /* */ - /* char_code :: The glyph's character code, according to the */ - /* current charmap used in the face. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the face has no current charmap, or if the character code */ - /* is not defined in the charmap, this function will return an */ - /* error. */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform(). */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_SCALE */ - /* */ - /* */ - /* A bit field constant, used with FT_Load_Glyph() to indicate that */ - /* the vector outline being loaded should not be scaled to 26.6 */ - /* fractional pixels, but kept in notional units. */ - /* */ -#define FT_LOAD_NO_SCALE 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_HINTING */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the vector outline being loaded should not be fitted to the pixel */ - /* grid but simply scaled to 26.6 fractional pixels. */ - /* */ - /* This flag is ignored if FT_LOAD_NO_SCALE is set. */ - /* */ -#define FT_LOAD_NO_HINTING 2 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_RENDER */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should load the glyph and immediately convert it into */ - /* a bitmap, if necessary, by calling FT_Render_Glyph(). */ - /* */ - /* Note that by default, FT_Load_Glyph() loads the glyph image in its */ - /* native format. */ - /* */ -#define FT_LOAD_RENDER 4 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_BITMAP */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should not load the bitmap or pixmap of a given */ - /* glyph. This is useful when you do not want to load the embedded */ - /* bitmaps of scalable formats, as the native glyph image will be */ - /* loaded, and can then be rendered through FT_Render_Glyph(). */ - /* */ -#define FT_LOAD_NO_BITMAP 8 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_VERTICAL_LAYOUT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph image should be prepared for vertical layout. This */ - /* basically means that `face.glyph.advance' will correspond to the */ - /* vertical advance height (instead of the default horizontal */ - /* advance width), and that the glyph image will translated to match */ - /* the vertical bearings positions. */ - /* */ -#define FT_LOAD_VERTICAL_LAYOUT 16 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_FORCE_AUTOHINT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should try to auto-hint the glyphs, even if a driver */ - /* specific hinter is available. */ - /* */ -#define FT_LOAD_FORCE_AUTOHINT 32 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_CROP_BITMAP */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the font driver should try to crop the bitmap (i.e. remove all */ - /* space around its black bits) when loading it. For now, this */ - /* really only works with embedded bitmaps in TrueType fonts. */ - /* */ -#define FT_LOAD_CROP_BITMAP 64 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_PEDANTIC */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should perform a pedantic bytecode */ - /* interpretation. Many popular fonts come with broken glyph */ - /* programs. When this flag is set, loading them will return an */ - /* error. Otherwise, errors are ignored by the loader, sometimes */ - /* resulting in ugly glyphs. */ - /* */ -#define FT_LOAD_PEDANTIC 128 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should ignore the global advance width defined */ - /* in the font. As far as we know, this is only used by the */ - /* X-TrueType font server, in order to deal correctly with the */ - /* incorrect metrics contained in DynaLab's TrueType CJK fonts. */ - /* */ -#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 512 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_NO_RECURSE */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should not load composite glyph recursively. */ - /* Rather, when a composite glyph is encountered, it should set */ - /* the values of `num_subglyphs' and `subglyphs', as well as set */ - /* `face->glyph.format' to ft_glyph_format_composite. */ - /* */ - /* This is for use by the auto-hinter and possibly other tools. */ - /* For nearly all applications, this flags should be left unset */ - /* when invoking FT_Load_Glyph(). */ - /* */ - /* Note that the flag forces the load of unscaled glyphs. */ - /* */ -#define FT_LOAD_NO_RECURSE 1024 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_IGNORE_TRANSFORM */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the glyph loader should not try to transform the loaded glyph */ - /* image. */ - /* */ -#define FT_LOAD_IGNORE_TRANSFORM 2048 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_MONOCHROME */ - /* */ - /* */ - /* Only used with FT_LOAD_RENDER set, it indicates that the returned */ - /* glyph image should be 1-bit monochrome. This really tells the */ - /* glyph loader to use `ft_render_mode_mono' when calling */ - /* FT_Render_Glyph(). */ - /* */ -#define FT_LOAD_MONOCHROME 4096 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_LINEAR_DESIGN */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should return the linearly scaled metrics expressed */ - /* in original font units, instead of the default 16.16 pixel values. */ - /* */ -#define FT_LOAD_LINEAR_DESIGN 8192 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LOAD_DEFAULT */ - /* */ - /* */ - /* A bit-field constant, used with FT_Load_Glyph() to indicate that */ - /* the function should try to load the glyph normally, i.e., */ - /* embedded bitmaps are favored over outlines, vectors are always */ - /* scaled and grid-fitted. */ - /* */ -#define FT_LOAD_DEFAULT 0 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Transform */ - /* */ - /* */ - /* A function used to set the transformation that is applied to glyph */ - /* images just before they are converted to bitmaps in a glyph slot */ - /* when FT_Render_Glyph() is called. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ - /* vector. */ - /* */ - /* */ - /* The transformation is only applied to scalable image formats after */ - /* the glyph has been loaded. It means that hinting is unaltered by */ - /* the transformation and is performed on the character size given in */ - /* the last call to FT_Set_Char_Sizes() or FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_DEF( void ) FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Render_Mode */ - /* */ - /* */ - /* An enumeration type that lists the render modes supported by the */ - /* FreeType 2 renderer(s). A renderer is in charge of converting a */ - /* glyph image into a bitmap. */ - /* */ - /* */ - /* ft_render_mode_normal :: This is the default render mode; it */ - /* corresponds to 8-bit anti-aliased */ - /* bitmaps, using 256 levels of gray. */ - /* */ - /* ft_render_mode_mono :: This render mode is used to produce 1-bit */ - /* monochrome bitmaps. */ - /* */ - /* */ - /* There is no render mode to produce 8-bit `monochrome' bitmaps -- */ - /* you have to make the conversion yourself if you need such things */ - /* (besides, FreeType is not a graphics library). */ - /* */ - /* More modes might appear later for specific display modes (e.g. TV, */ - /* LCDs, etc.). They will be supported through the simple addition */ - /* of a renderer module, with no changes to the rest of the engine. */ - /* */ - typedef enum FT_Render_Mode_ - { - ft_render_mode_normal = 0, - ft_render_mode_mono = 1 - - } FT_Render_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Render_Glyph */ - /* */ - /* */ - /* Converts a given glyph image to a bitmap. It does so by */ - /* inspecting the glyph image format, find the relevant renderer, and */ - /* invoke it. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot containing the image to */ - /* convert. */ - /* */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See FT_Render_Mode for a list */ - /* of possible values. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, - FT_UInt render_mode ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Kerning_Mode */ - /* */ - /* */ - /* An enumeration used to specify which kerning values to return in */ - /* FT_Get_Kerning(). */ - /* */ - /* */ - /* ft_kerning_default :: Return scaled and grid-fitted kerning */ - /* distances (value is 0). */ - /* */ - /* ft_kerning_unfitted :: Return scaled but un-grid-fitted kerning */ - /* distances. */ - /* */ - /* ft_kerning_unscaled :: Return the kerning vector in original font */ - /* units. */ - /* */ - typedef enum FT_Kerning_Mode_ - { - ft_kerning_default = 0, - ft_kerning_unfitted, - ft_kerning_unscaled - - } FT_Kerning_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Kerning */ - /* */ - /* */ - /* Returns the kerning vector between two glyphs of a same face. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* kern_mode :: See FT_Kerning_Mode() for more information. */ - /* Determines the scale/dimension of the returned */ - /* kerning vector. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings, are out of the scope of this API function -- they can be */ - /* implemented through format-specific interfaces. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector* kerning ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph_Name */ - /* */ - /* */ - /* Retrieves the ASCII name of a given glyph in a face. This only */ - /* works for those faces where FT_HAS_GLYPH_NAME(face) returns true. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* buffer :: A pointer to a target buffer where the name will be */ - /* copied to. */ - /* */ - /* buffer_max :: The maximal number of bytes available in the */ - /* buffer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error is returned if the face doesn't provide glyph names or if */ - /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' will be set to 0 to indicate an empty name. */ - /* */ - /* The glyph name is truncated to fit within the buffer if it is too */ - /* long. The returned string is always zero-terminated. */ - /* */ - /* This function is not compiled within the library if the config */ - /* macro FT_CONFIG_OPTION_NO_GLYPH_NAMES is defined in */ - /* `include/freetype/config/ftoptions.h' */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Select_Charmap */ - /* */ - /* */ - /* Selects a given charmap by its encoding tag (as listed in */ - /* `freetype.h'). */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* encoding :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if no charmap in the face */ - /* corresponds to the encoding queried here. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Charmap */ - /* */ - /* */ - /* Selects a given charmap for character code to glyph index */ - /* decoding. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* charmap :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if the charmap is not part of */ - /* the face (i.e., if it is not listed in the face->charmaps[] */ - /* table). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Char_Index */ - /* */ - /* */ - /* Returns the glyph index of a given character code. This function */ - /* uses a charmap object to do the translation. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* */ - /* The glyph index. 0 means `undefined character code'. */ - /* */ - FT_EXPORT_DEF( FT_UInt ) FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulDiv */ - /* */ - /* */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximal accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* */ - /* This function has been optimized for the case where the absolute */ - /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ - /* As this happens mainly when scaling from notional units to */ - /* fractional pixels in FreeType, it resulted in noticeable speed */ - /* improvements between versions 2.x and 1.x. */ - /* */ - /* As a conclusion, always try to place a 16.16 factor as the */ - /* _second_ argument of this function; this can make a great */ - /* difference. */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_MulFix( FT_Long a, - FT_Long b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DivFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*0x10000)/b'. */ - /* */ - /* */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ - /* 32 bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of the old FT_MulDiv64(). */ - /* */ - FT_EXPORT_DEF( FT_Long ) FT_DivFix( FT_Long a, - FT_Long b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_DEF( void ) FT_Vector_Transform( FT_Vector* vec, - FT_Matrix* matrix ); - - - -#ifdef __cplusplus - } -#endif - - -#endif /* FREETYPE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftbbox.h b/subsys/win32k/freetype/include/freetype/ftbbox.h deleted file mode 100644 index e144664..0000000 --- a/subsys/win32k/freetype/include/freetype/ftbbox.h +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbbox.h */ -/* */ -/* FreeType bbox computation (specification). */ -/* */ -/* Copyright 1996-2000 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 has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /* It is separated from the rest of the engine for various technical */ - /* reasons. It may well be integrated in `ftoutln' later. */ - /* */ - /*************************************************************************/ - - -#ifndef FTBBOX_H -#define FTBBOX_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_GetBBox */ - /* */ - /* */ - /* Computes the exact bounding box of an outline. This is slower */ - /* than computing the control box. However, it uses an advanced */ - /* algorithm which returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bezier arcs are walked over to */ - /* extract their extrema. */ - /* */ - /* */ - /* outline :: A pointer to the source outline. */ - /* */ - /* */ - /* bbox :: The outline's exact bounding box. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - FT_EXPORT_DEF(FT_Error) FT_Raster_GetBBox( FT_Outline* outline, - FT_BBox* abbox ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTBBOX_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/fterrors.h b/subsys/win32k/freetype/include/freetype/fterrors.h deleted file mode 100644 index 9fb8099..0000000 --- a/subsys/win32k/freetype/include/freetype/fterrors.h +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************/ -/* */ -/* fterrors.h */ -/* */ -/* FreeType error codes (specification). */ -/* */ -/* Copyright 1996-2000 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 define the FreeType error enumeration constants */ - /* It can also be used to create an error message table easily with */ - /* something like: */ - /* */ - /* { */ - /* #undef FTERRORS_H */ - /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ - /* #define FT_ERROR_START_LIST { */ - /* #define FT_ERROR_END_LIST { 0, 0 } }; */ - /* */ - /* const struct */ - /* { */ - /* int err_code; */ - /* const char* err_msg */ - /* } ft_errors[] = */ - /* */ - /* #include */ - /* } */ - /* */ - /*************************************************************************/ - - -#ifndef FTERRORS_H -#define FTERRORS_H - - -#ifndef FT_ERRORDEF - -#define FT_ERRORDEF( e, v, s ) e = v, -#define FT_ERROR_START_LIST enum { -#define FT_ERROR_END_LIST FT_Err_Max }; - -#endif /* !FT_ERRORDEF */ - - -#ifdef FT_ERROR_START_LIST - FT_ERROR_START_LIST -#endif - - FT_ERRORDEF( FT_Err_Ok, 0x0000, \ - "no error" ) - FT_ERRORDEF( FT_Err_Cannot_Open_Resource, 0x0001, \ - "can't open stream" ) - FT_ERRORDEF( FT_Err_Unknown_File_Format, 0x0002, \ - "unknown file format" ) - FT_ERRORDEF( FT_Err_Invalid_File_Format, 0x0003, \ - "broken file" ) - - FT_ERRORDEF( FT_Err_Invalid_Argument, 0x0010, \ - "invalid argument" ) - FT_ERRORDEF( FT_Err_Invalid_Handle, 0x0011, \ - "invalid object handle" ) - FT_ERRORDEF( FT_Err_Invalid_Glyph_Index, 0x0012, \ - "invalid glyph index" ) - FT_ERRORDEF( FT_Err_Invalid_Character_Code, 0x0013, \ - "invalid character code" ) - - FT_ERRORDEF( FT_Err_Unimplemented_Feature, 0x0020, \ - "unimplemented feature" ) - FT_ERRORDEF( FT_Err_Invalid_Glyph_Format, 0x0021, \ - "unsupported glyph image format" ) - FT_ERRORDEF( FT_Err_Cannot_Render_Glyph, 0x0022, \ - "cannot render this glyph format" ) - - FT_ERRORDEF( FT_Err_Invalid_Library_Handle, 0x0030, \ - "invalid library handle" ) - FT_ERRORDEF( FT_Err_Invalid_Driver_Handle, 0x0031, \ - "invalid module handle" ) - FT_ERRORDEF( FT_Err_Invalid_Face_Handle, 0x0032, \ - "invalid face handle" ) - FT_ERRORDEF( FT_Err_Invalid_Size_Handle, 0x0033, \ - "invalid size handle" ) - FT_ERRORDEF( FT_Err_Invalid_Slot_Handle, 0x0034, \ - "invalid glyph slot handle" ) - FT_ERRORDEF( FT_Err_Invalid_CharMap_Handle, 0x0035, \ - "invalid charmap handle" ) - FT_ERRORDEF( FT_Err_Invalid_Outline, 0x0036, \ - "invalid outline" ) - FT_ERRORDEF( FT_Err_Invalid_Version, 0x0037, \ - "invalid FreeType version" ) - FT_ERRORDEF( FT_Err_Lower_Module_Version, 0x0038, \ - "module version is too low" ) - - FT_ERRORDEF( FT_Err_Too_Many_Drivers, 0x0040, \ - "too many modules" ) - FT_ERRORDEF( FT_Err_Too_Many_Extensions, 0x0041, \ - "too many extensions" ) - - FT_ERRORDEF( FT_Err_Out_Of_Memory, 0x0050, \ - "out of memory" ) - FT_ERRORDEF( FT_Err_Unlisted_Object, 0x0051, \ - "unlisted object" ) - - FT_ERRORDEF( FT_Err_Invalid_Stream_Handle, 0x0060, \ - "invalid stream handle" ) - FT_ERRORDEF( FT_Err_Cannot_Open_Stream, 0x0061, \ - "cannot open stream" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Seek, 0x0062, \ - "invalid stream seek" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Skip, 0x0063, \ - "invalid stream skip" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Read, 0x0064, \ - "invalid stream read" ) - FT_ERRORDEF( FT_Err_Invalid_Stream_Operation, 0x0065, \ - "invalid stream operation" ) - FT_ERRORDEF( FT_Err_Invalid_Frame_Operation, 0x0066, \ - "invalid frame operation" ) - FT_ERRORDEF( FT_Err_Nested_Frame_Access, 0x0067, \ - "nested frame access" ) - FT_ERRORDEF( FT_Err_Invalid_Frame_Read, 0x0068, \ - "invalid frame read" ) - - FT_ERRORDEF( FT_Err_Invalid_Composite, 0x0070, \ - "invalid composite glyph" ) - FT_ERRORDEF( FT_Err_Too_Many_Hints, 0x0071, \ - "too many hints" ) - - FT_ERRORDEF( FT_Err_Raster_Uninitialized, 0x0080, \ - "raster uninitialized" ) - FT_ERRORDEF( FT_Err_Raster_Corrupted, 0x0081, \ - "raster corrupted" ) - FT_ERRORDEF( FT_Err_Raster_Overflow, 0x0082, \ - "raster overflow" ) - FT_ERRORDEF( FT_Err_Raster_Negative_Height, 0x0083, \ - "negative height while rastering" ) - - /* range 0x400 - 0x4FF is reserved for TrueType specific stuff */ - - /* range 0x500 - 0x5FF is reserved for CFF specific stuff */ - - /* range 0x600 - 0x6FF is reserved for Type1 specific stuff */ - -#ifdef FT_ERROR_END_LIST - FT_ERROR_END_LIST -#endif - - -#undef FT_ERROR_START_LIST -#undef FT_ERROR_END_LIST -#undef FT_ERRORDEF - - -#endif /* FTERRORS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftglyph.h b/subsys/win32k/freetype/include/freetype/ftglyph.h deleted file mode 100644 index 0647c88..0000000 --- a/subsys/win32k/freetype/include/freetype/ftglyph.h +++ /dev/null @@ -1,422 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.h */ -/* */ -/* FreeType convenience functions to handle glyphs (specification). */ -/* */ -/* Copyright 1996-2000 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 contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#ifndef FTGLYPH_H -#define FTGLYPH_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - /* forward declaration to a private type */ - typedef struct FT_Glyph_Class_ FT_Glyph_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_GlyphRec */ - /* */ - /* */ - /* The root glyph structure contains a given glyph image plus its */ - /* advance width in 16.16 fixed float format. */ - /* */ - /* */ - /* library :: A handle to the FreeType library object. */ - /* */ - /* clazz :: A pointer to the glyph's class. Private. */ - /* */ - /* format :: The format of the glyph's image. */ - /* */ - /* advance :: A 16.16 vector that gives the glyph's advance width. */ - /* */ - typedef struct FT_GlyphRec_ - { - FT_Library library; - const FT_Glyph_Class* clazz; - FT_Glyph_Format format; - FT_Vector advance; - - } FT_GlyphRec, *FT_Glyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_BitmapGlyphRec */ - /* */ - /* */ - /* A structure used for bitmap glyph images. This really is a */ - /* `sub-class' of `FT_GlyphRec'. */ - /* */ - /* */ - /* root :: The root FT_Glyph fields. */ - /* */ - /* left :: The left-side bearing, i.e., the horizontal distance */ - /* from the current pen position to the left border of the */ - /* glyph bitmap. */ - /* */ - /* top :: The top-side bearing, i.e., the vertical distance from */ - /* the current pen position to the top border of the glyph */ - /* bitmap. This distance is positive for upwards-y! */ - /* */ - /* bitmap :: A descriptor for the bitmap. */ - /* */ - /* */ - /* You can typecast FT_Glyph to FT_BitmapGlyph if you have */ - /* glyph->format == ft_glyph_format_bitmap. This lets you access */ - /* the bitmap's contents easily. */ - /* */ - /* The corresponding pixel buffer is always owned by the BitmapGlyph */ - /* and is thus created and destroyed with it. */ - /* */ - typedef struct FT_BitmapGlyphRec_ - { - FT_GlyphRec root; - FT_Int left; - FT_Int top; - FT_Bitmap bitmap; - - } FT_BitmapGlyphRec, *FT_BitmapGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_OutlineGlyphRec */ - /* */ - /* */ - /* A structure used for outline (vectorial) glyph images. This */ - /* really is a `sub-class' of `FT_GlyphRec'. */ - /* */ - /* */ - /* root :: The root FT_Glyph fields. */ - /* */ - /* outline :: A descriptor for the outline. */ - /* */ - /* */ - /* You can typecast FT_Glyph to FT_OutlineGlyph if you have */ - /* glyph->format == ft_glyph_format_outline. This lets you access */ - /* the outline's content easily. */ - /* */ - /* As the outline is extracted from a glyph slot, its coordinates are */ - /* expressed normally in 26.6 pixels, unless the flag */ - /* FT_LOAD_NO_SCALE was used in FT_Load_Glyph() or FT_Load_Char(). */ - /* */ - /* The outline's tables are always owned by the object and are */ - /* destroyed with it. */ - /* */ - typedef struct FT_OutlineGlyphRec_ - { - FT_GlyphRec root; - FT_Outline outline; - - } FT_OutlineGlyphRec, *FT_OutlineGlyph; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph */ - /* */ - /* */ - /* A function used to extract a glyph image from a slot. */ - /* */ - /* */ - /* slot :: A handle to the source glyph slot. */ - /* */ - /* */ - /* aglyph :: A handle to the glyph object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph* aglyph ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Copy */ - /* */ - /* */ - /* A function used to copy a glyph image. */ - /* */ - /* */ - /* source :: A handle to the source glyph object. */ - /* */ - /* */ - /* target :: A handle to the target glyph object. 0 in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_Copy( FT_Glyph source, - FT_Glyph* target ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Transform */ - /* */ - /* */ - /* Transforms a glyph image if its format is scalable. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - /* matrix :: A pointer to a 2x2 matrix to apply. */ - /* */ - /* delta :: A pointer to a 2d vector to apply. Coordinates are */ - /* expressed in 1/64th of a pixel. */ - /* */ - /* */ - /* FreeType error code (the glyph format is not scalable if it is */ - /* not zero). */ - /* */ - /* */ - /* The 2x2 transformation matrix is also applied to the glyph's */ - /* advance vector. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); - - - enum - { - ft_glyph_bbox_pixels = 0, - ft_glyph_bbox_subpixels = 1, - ft_glyph_bbox_gridfit = 2 - }; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Get_CBox */ - /* */ - /* */ - /* Returns the glyph image's bounding box. */ - /* */ - /* */ - /* glyph :: A handle to the source glyph object. */ - /* */ - /* mode :: A set of bit flags that indicate how to interpret the */ - /* returned bounding box values. */ - /* */ - /* */ - /* box :: The glyph bounding box. Coordinates are expressed in */ - /* 1/64th of pixels if it is grid-fitted. */ - /* */ - /* */ - /* Coordinates are relative to the glyph origin, using the Y-upwards */ - /* convention. */ - /* */ - /* If `ft_glyph_bbox_subpixels' is set in `mode', the bbox */ - /* coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). */ - /* Otherwise, coordinates are expressed in integer pixels. */ - /* */ - /* Note that the maximum coordinates are exclusive, which means that */ - /* one can compute the width and height of the glyph image (be it in */ - /* integer or 26.6 pixels) as: */ - /* */ - /* width = bbox.xMax - bbox.xMin; */ - /* height = bbox.yMax - bbox.yMin; */ - /* */ - /* Note also that for 26.6 coordinates, if the */ - /* `ft_glyph_bbox_gridfit' flag is set in `mode;, the coordinates */ - /* will also be grid-fitted, which corresponds to: */ - /* */ - /* bbox.xMin = FLOOR(bbox.xMin); */ - /* bbox.yMin = FLOOR(bbox.yMin); */ - /* bbox.xMax = CEILING(bbox.xMax); */ - /* bbox.yMax = CEILING(bbox.yMax); */ - /* */ - /* The default value (0) for `bbox_mode' is `ft_glyph_bbox_pixels'. */ - /* */ - FT_EXPORT_DEF( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox* cbox ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_To_Bitmap */ - /* */ - /* */ - /* Converts a given glyph object to a bitmap glyph object. */ - /* */ - /* */ - /* glyph :: A pointer to a handle to the target glyph. */ - /* */ - /* */ - /* render_mode :: A set of bit flags that describe how the data is */ - /* */ - /* */ - /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be 0 (if no */ - /* translation). The origin is expressed in */ - /* 26.6 pixels. */ - /* */ - /* destroy :: A boolean that indicates that the original glyph */ - /* image should be destroyed by this function. It is */ - /* never destroyed in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The glyph image is translated with the `origin' vector before */ - /* rendering. In case of error, it it translated back to its */ - /* original position and the glyph is left untouched. */ - /* */ - /* The first parameter is a pointer to a FT_Glyph handle, that will */ - /* be replaced by this function. Typically, you would use (omitting */ - /* error handling): */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyph; */ - /* FT_BitmapGlyph glyph_bitmap; */ - /* */ - /* */ - /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ - /* */ - /* // extract glyph image */ - /* error = FT_Get_Glyph( face->glyph, &glyph ); */ - /* */ - /* // convert to a bitmap (default render mode + destroy old) */ - /* if ( glyph->format != ft_glyph_format_bitmap ) */ - /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_default, */ - /* 0, 1 ); */ - /* if ( error ) // glyph unchanged */ - /* ... */ - /* } */ - /* */ - /* // access bitmap content by typecasting */ - /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ - /* */ - /* // do funny stuff with it, like blitting/drawing */ - /* ... */ - /* */ - /* // discard glyph image (bitmap or not) */ - /* FT_Done_Glyph( glyph ); */ - /* } */ - /* */ - /* */ - /* This function will always fail if the glyph's format isn't */ - /* scalable. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_ULong render_mode, - FT_Vector* origin, - FT_Bool destroy ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Glyph */ - /* */ - /* */ - /* Destroys a given glyph. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - FT_EXPORT_DEF( void ) FT_Done_Glyph( FT_Glyph glyph ); - - - /* other helpful functions */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Multiply */ - /* */ - /* */ - /* Performs the matrix operation `b = a*b'. */ - /* */ - /* */ - /* a :: A pointer to matrix `a'. */ - /* */ - /* */ - /* b :: A pointer to matrix `b'. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `a' or `b' is zero. */ - /* */ - FT_EXPORT_DEF( void ) FT_Matrix_Multiply( FT_Matrix* a, - FT_Matrix* b ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Invert */ - /* */ - /* */ - /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ - /* */ - /* */ - /* matrix :: A pointer to the target matrix. Remains untouched in */ - /* case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTGLYPH_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftimage.h b/subsys/win32k/freetype/include/freetype/ftimage.h deleted file mode 100644 index 4dd1c3d..0000000 --- a/subsys/win32k/freetype/include/freetype/ftimage.h +++ /dev/null @@ -1,1003 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftimage.h */ -/* */ -/* FreeType glyph image formats and default raster interface */ -/* (specification). */ -/* */ -/* Copyright 1996-2000 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: A `raster' is simply a scan-line converter, used to render */ - /* FT_Outlines into FT_Bitmaps. */ - /* */ - /*************************************************************************/ - - -#ifndef FTIMAGE_H -#define FTIMAGE_H - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pos */ - /* */ - /* */ - /* The type FT_Pos is a 32-bit integer used to store vectorial */ - /* coordinates. Depending on the context, these can represent */ - /* distances in integer font units, or 26.6 fixed float pixel */ - /* coordinates. */ - /* */ - typedef signed long FT_Pos; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector */ - /* */ - /* */ - /* A simple structure used to store a 2D vector; coordinates are of */ - /* the FT_Pos type. */ - /* */ - /* */ - /* x :: The horizontal coordinate. */ - /* y :: The vertical coordinate. */ - /* */ - typedef struct FT_Vector_ - { - FT_Pos x; - FT_Pos y; - - } FT_Vector; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pixel_Mode */ - /* */ - /* */ - /* An enumeration type used to describe the format of pixels in a */ - /* given bitmap. Note that additional formats may be added in the */ - /* future. */ - /* */ - /* */ - /* ft_pixel_mode_mono :: A monochrome bitmap (1 bit/pixel). */ - /* */ - /* ft_pixel_mode_grays :: An 8-bit gray-levels bitmap. Note that the */ - /* total number of gray levels is given in the */ - /* `num_grays' field of the FT_Bitmap */ - /* structure. */ - /* */ - /* ft_pixel_mode_pal2 :: A 2-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_pal4 :: A 4-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_pal8 :: An 8-bit paletted bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb15 :: A 15-bit RGB bitmap. Uses 5:5:5 encoding. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb16 :: A 16-bit RGB bitmap. Uses 5:6:5 encoding. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb24 :: A 24-bit RGB bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* ft_pixel_mode_rgb32 :: A 32-bit RGB bitmap. */ - /* Currently unused by FreeType. */ - /* */ - /* */ - /* Some anti-aliased bitmaps might be embedded in TrueType fonts */ - /* using formats pal2 or pal4, though no fonts presenting those have */ - /* been found to date. */ - /* */ - typedef enum FT_Pixel_Mode_ - { - ft_pixel_mode_none = 0, - ft_pixel_mode_mono, - ft_pixel_mode_grays, - ft_pixel_mode_pal2, - ft_pixel_mode_pal4, - ft_pixel_mode_pal8, - ft_pixel_mode_rgb15, - ft_pixel_mode_rgb16, - ft_pixel_mode_rgb24, - ft_pixel_mode_rgb32, - - ft_pixel_mode_max /* do not remove */ - - } FT_Pixel_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Palette_Mode */ - /* */ - /* */ - /* An enumeration type used to describe the format of a bitmap */ - /* palette, used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ - /* */ - /* */ - /* ft_palette_mode_rgb :: The palette is an array of 3-bytes RGB */ - /* records. */ - /* */ - /* ft_palette_mode_rgba :: The palette is an array of 4-bytes RGBA */ - /* records. */ - /* */ - /* */ - /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ - /* FreeType, these types are not handled by the library itself. */ - /* */ - typedef enum FT_Palette_Mode_ - { - ft_palette_mode_rgb = 0, - ft_palette_mode_rgba, - - ft_palettte_mode_max /* do not remove */ - - } FT_Palette_Mode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bitmap */ - /* */ - /* */ - /* A structure used to describe a bitmap or pixmap to the raster. */ - /* Note that we now manage pixmaps of various depths through the */ - /* `pixel_mode' field. */ - /* */ - /* */ - /* rows :: The number of bitmap rows. */ - /* */ - /* width :: The number of pixels in bitmap row. */ - /* */ - /* pitch :: The pitch's absolute value is the number of bytes */ - /* taken by one bitmap row, including padding. */ - /* However, the pitch is positive when the bitmap has */ - /* a `down' flow, and negative when it has an `up' */ - /* flow. In all cases, the pitch is an offset to add */ - /* to a bitmap pointer in order to go down one row. */ - /* */ - /* buffer :: A typeless pointer to the bitmap buffer. This */ - /* value should be aligned on 32-bit boundaries in */ - /* most cases. */ - /* */ - /* num_grays :: This field is only used with */ - /* `ft_pixel_mode_grays'; it gives the number of gray */ - /* levels used in the bitmap. */ - /* */ - /* pixel_mode :: The pixel_mode, i.e., how pixel bits are stored. */ - /* */ - /* palette_mode :: This field is only used with paletted pixel modes; */ - /* it indicates how the palette is stored. */ - /* */ - /* palette :: A typeless pointer to the bitmap palette; only */ - /* used for paletted pixel modes. */ - /* */ - /* */ - /* For now, the only pixel mode supported by FreeType are mono and */ - /* grays. However, drivers might be added in the future to support */ - /* more `colorful' options. */ - /* */ - /* When using pixel modes pal2, pal4 and pal8 with a void `palette' */ - /* field, a gray pixmap with respectively 4, 16, and 256 levels of */ - /* gray is assumed. This, in order to be compatible with some */ - /* embedded bitmap formats defined in the TrueType specification. */ - /* */ - /* Note that no font was found presenting such embedded bitmaps, so */ - /* this is currently completely unhandled by the library. */ - /* */ - typedef struct FT_Bitmap_ - { - int rows; - int width; - int pitch; - unsigned char* buffer; - short num_grays; - char pixel_mode; - char palette_mode; - void* palette; - - } FT_Bitmap; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline */ - /* */ - /* */ - /* This structure is used to describe an outline to the scan-line */ - /* converter. */ - /* */ - /* */ - /* n_contours :: The number of contours in the outline. */ - /* */ - /* n_points :: The number of points in the outline. */ - /* */ - /* points :: A pointer to an array of `n_points' FT_Vector */ - /* elements, giving the outline's point coordinates. */ - /* */ - /* tags :: A pointer to an array of `n_points' chars, giving */ - /* giving each outline point's type. If bit 0 is */ - /* unset, the point is 'off' the curve, i.e. a Bezier */ - /* control point, while it is `on' when unset. */ - /* */ - /* Bit 1 is meaningful for `off' points only. If set, */ - /* it indicates a third-order Bezier arc control point; */ - /* and a second-order control point if unset. */ - /* */ - /* contours :: An array of `n_contours' shorts, giving the end */ - /* point of each contour within the outline. For */ - /* example, the first contour is defined by the points */ - /* `0' to `contours[0]', the second one is defined by */ - /* the points `contours[0]+1' to `contours[1]', etc. */ - /* */ - /* flags :: A set of bit flags used to characterize the outline */ - /* and give hints to the scan-converter and hinter on */ - /* how to convert/grid-fit it. See FT_Outline_Flags. */ - /* */ - typedef struct FT_Outline_ - { - short n_contours; /* number of contours in glyph */ - short n_points; /* number of points in the glyph */ - - FT_Vector* points; /* the outline's points */ - char* tags; /* the points flags */ - short* contours; /* the contour end points */ - - int flags; /* outline masks */ - - } FT_Outline; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Flags */ - /* */ - /* */ - /* A simple type used to enumerates the flags in an outline's */ - /* `outline_flags' field. */ - /* */ - /* */ - /* ft_outline_owner :: If set, this flag indicates that the */ - /* outline's field arrays (i.e. */ - /* `points', `flags' & `contours') are */ - /* `owned' by the outline object, and */ - /* should thus be freed when it is */ - /* destroyed. */ - /* */ - /* ft_outline_even_odd_fill :: By default, outlines are filled using */ - /* the non-zero winding rule. If set to */ - /* 1, the outline will be filled using */ - /* the even-odd fill rule (only works */ - /* with the smooth raster). */ - /* */ - /* ft_outline_reverse_fill :: By default, outside contours of an */ - /* outline are oriented in clock-wise */ - /* direction, as defined in the TrueType */ - /* specification. This flag is set if */ - /* the outline uses the opposite */ - /* direction (typically for Type 1 */ - /* fonts). This flag is ignored by the */ - /* scan-converter. However, it is very */ - /* important for the auto-hinter. */ - /* */ - /* ft_outline_ignore_dropouts :: By default, the scan converter will */ - /* try to detect drop-outs in an outline */ - /* and correct the glyph bitmap to */ - /* ensure consistent shape continuity. */ - /* If set, this flag hints the scan-line */ - /* converter to ignore such cases. */ - /* */ - /* ft_outline_high_precision :: This flag indicates that the */ - /* scan-line converter should try to */ - /* convert this outline to bitmaps with */ - /* the highest possible quality. It is */ - /* typically set for small character */ - /* sizes. Note that this is only a */ - /* hint, that might be completely */ - /* ignored by a given scan-converter. */ - /* */ - /* ft_outline_single_pass :: This flag is set to force a given */ - /* scan-converter to only use a single */ - /* pass over the outline to render a */ - /* bitmap glyph image. Normally, it is */ - /* set for very large character sizes. */ - /* It is only a hint, that might be */ - /* completely ignored by a given */ - /* scan-converter. */ - /* */ - typedef enum FT_Outline_Flags_ - { - ft_outline_none = 0, - ft_outline_owner = 1, - ft_outline_even_odd_fill = 2, - ft_outline_reverse_fill = 4, - ft_outline_ignore_dropouts = 8, - ft_outline_high_precision = 256, - ft_outline_single_pass = 512 - - } FT_Outline_Flags; - - -#define FT_CURVE_TAG( flag ) ( flag & 3 ) - -#define FT_Curve_Tag_On 1 -#define FT_Curve_Tag_Conic 0 -#define FT_Curve_Tag_Cubic 2 - -#define FT_Curve_Tag_Touch_X 8 /* reserved for the TrueType hinter */ -#define FT_Curve_Tag_Touch_Y 16 /* reserved for the TrueType hinter */ - -#define FT_Curve_Tag_Touch_Both ( FT_Curve_Tag_Touch_X | \ - FT_Curve_Tag_Touch_Y ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_MoveTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `move */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `move to' is emitted to start a new contour in an outline. */ - /* */ - /* */ - /* to :: A pointer to the target point of the `move to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_MoveTo_Func)( FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_LineTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `line */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `line to' is emitted to indicate a segment in the outline. */ - /* */ - /* */ - /* to :: A pointer to the target point of the `line to'. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of the */ - /* decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_LineTo_Func)( FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_ConicTo_Func */ - /* */ - /* */ - /* A function pointer type use to describe the signature of a `conic */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `conic to' is emitted to indicate a second-order Bezier arc in */ - /* the outline. */ - /* */ - /* */ - /* control :: An intermediate control point between the last position */ - /* and the new target in `to'. */ - /* */ - /* to :: A pointer to the target end point of the conic arc. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_ConicTo_Func)( FT_Vector* control, - FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_CubicTo_Func */ - /* */ - /* */ - /* A function pointer type used to describe the signature of a `cubic */ - /* to' function during outline walking/decomposition. */ - /* */ - /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ - /* */ - /* */ - /* control1 :: A pointer to the first Bezier control point. */ - /* */ - /* control2 :: A pointer to the second Bezier control point. */ - /* */ - /* to :: A pointer to the target end point. */ - /* */ - /* user :: A typeless pointer which is passed from the caller of */ - /* the decomposition function. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - typedef int (*FT_Outline_CubicTo_Func)( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Funcs */ - /* */ - /* */ - /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Beziers, */ - /* as well as `move to' and `close to' operations. */ - /* */ - /* */ - /* move_to :: The `move to' emitter. */ - /* */ - /* line_to :: The segment emitter. */ - /* */ - /* conic_to :: The second-order Bezier arc emitter. */ - /* */ - /* cubic_to :: The third-order Bezier arc emitter. */ - /* */ - /* shift :: The shift that is applied to coordinates before they */ - /* are sent to the emitter. */ - /* */ - /* delta :: The delta that is applied to coordinates before they */ - /* are sent to the emitter, but after the shift. */ - /* */ - /* */ - /* The point coordinates sent to the emitters are the transformed */ - /* version of the original coordinates (this is important for high */ - /* accuracy during scan-conversion). The transformation is simple: */ - /* */ - /* x' = (x << shift) - delta */ - /* y' = (x << shift) - delta */ - /* */ - /* Set the value of `shift' and `delta' to 0 to get the original */ - /* point coordinates. */ - /* */ - typedef struct FT_Outline_Funcs_ - { - FT_Outline_MoveTo_Func move_to; - FT_Outline_LineTo_Func line_to; - FT_Outline_ConicTo_Func conic_to; - FT_Outline_CubicTo_Func cubic_to; - - int shift; - FT_Pos delta; - - } FT_Outline_Funcs; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_IMAGE_TAG */ - /* */ - /* */ - /* This macro converts four letter tags into an unsigned long. */ - /* */ -#define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (unsigned long)_x1 << 24 ) | \ - ( (unsigned long)_x2 << 16 ) | \ - ( (unsigned long)_x3 << 8 ) | \ - (unsigned long)_x4 ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Format */ - /* */ - /* */ - /* An enumeration type used to describe the format of a given glyph */ - /* image. Note that this version of FreeType only supports two image */ - /* formats, even though future font drivers will be able to register */ - /* their own format. */ - /* */ - /* */ - /* ft_glyph_format_composite :: The glyph image is a composite of */ - /* several other images. This glyph */ - /* format is _only_ used with the */ - /* FT_LOAD_FLAG_NO_RECURSE flag (XXX: */ - /* Which is currently unimplemented). */ - /* */ - /* ft_glyph_format_bitmap :: The glyph image is a bitmap, and can */ - /* be described as a FT_Bitmap. */ - /* */ - /* ft_glyph_format_outline :: The glyph image is a vectorial image */ - /* made of bezier control points, and */ - /* can be described as a FT_Outline. */ - /* */ - /* ft_glyph_format_plotter :: The glyph image is a vectorial image */ - /* made of plotter lines (some T1 fonts */ - /* like Hershey contain glyph in this */ - /* format). */ - /* */ - typedef enum FT_Glyph_Format_ - { - ft_glyph_format_none = 0, - ft_glyph_format_composite = FT_IMAGE_TAG( 'c', 'o', 'm', 'p' ), - ft_glyph_format_bitmap = FT_IMAGE_TAG( 'b', 'i', 't', 's' ), - ft_glyph_format_outline = FT_IMAGE_TAG( 'o', 'u', 't', 'l' ), - ft_glyph_format_plotter = FT_IMAGE_TAG( 'p', 'l', 'o', 't' ) - - } FT_Glyph_Format; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** R A S T E R D E F I N I T I O N S *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ - /* */ - /* Note that in FreeType 2, all rasters are now encapsulated within */ - /* specific modules called `renderers'. See `freetype/ftrender.h' for */ - /* more details on renderers. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster */ - /* */ - /* */ - /* A handle (pointer) to a raster object. Each object can be used */ - /* independently to convert an outline into a bitmap or pixmap. */ - /* */ - typedef struct FT_RasterRec_* FT_Raster; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Span */ - /* */ - /* */ - /* A structure used to model a single span of gray (or black) pixels */ - /* when rendering a monochrome or anti-aliased bitmap. */ - /* */ - /* */ - /* x :: The span's horizontal start position. */ - /* */ - /* len :: The span's length in pixels. */ - /* */ - /* coverage :: The span color/coverage, ranging from 0 (background) */ - /* to 255 (foreground). Only used for anti-aliased */ - /* rendering. */ - /* */ - /* */ - /* This structure is used by the span drawing callback type named */ - /* FT_Raster_Span_Func(), which takes the y-coordinate of the span as */ - /* a parameter. */ - /* */ - /* The coverage value is always between 0 and 255, even if the number */ - /* of gray levels have been set through FT_Set_Gray_Levels(). */ - /* */ - typedef struct FT_Span_ - { - short x; - unsigned short len; - unsigned char coverage; - - } FT_Span; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Span_Func */ - /* */ - /* */ - /* A function used as a call-back by the anti-aliased renderer in */ - /* order to let client applications draw themselves the gray pixel */ - /* spans on each scan line. */ - /* */ - /* */ - /* y :: The scanline's y-coordinate. */ - /* */ - /* count :: The number of spans to draw on this scanline. */ - /* */ - /* spans :: A table of `count' spans to draw on the scanline. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* This callback allows client applications to directly render the */ - /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ - /* */ - /* This can be used to write anti-aliased outlines directly to a */ - /* given background bitmap, and even perform translucency. */ - /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the FT_MAX_GRAY_SPANS configuration macro in */ - /* ftoption.h. By default, this value is set to 32, which means that */ - /* if there are more than 32 spans on a given scanline, the callback */ - /* will be called several times with the same `y' parameter in order */ - /* to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ - typedef void (*FT_Raster_Span_Func)( int y, - int count, - FT_Span* spans, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_BitTest_Func */ - /* */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to test whether a given target pixel is already set to the drawing */ - /* `color'. These tests are crucial to implement drop-out control */ - /* per-se the TrueType spec. */ - /* */ - /* */ - /* y :: The pixel's y-coordinate. */ - /* */ - /* x :: The pixel's x-coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* 1 if the pixel is `set', 0 otherwise. */ - /* */ - typedef int (*FT_Raster_BitTest_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_BitSet_Func */ - /* */ - /* */ - /* A function used as a call-back by the monochrome scan-converter */ - /* to set an individual target pixel. This is crucial to implement */ - /* drop-out control according to the TrueType specification. */ - /* */ - /* */ - /* y :: The pixel's y-coordinate. */ - /* */ - /* x :: The pixel's x-coordinate. */ - /* */ - /* user :: User-supplied data that is passed to the callback. */ - /* */ - /* */ - /* 1 if the pixel is `set', 0 otherwise. */ - /* */ - typedef void (*FT_Raster_BitSet_Func)( int y, - int x, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Flag */ - /* */ - /* */ - /* An enumeration to list the bit flags as used in the `flags' field */ - /* of a FT_Raster_Params structure. */ - /* */ - /* */ - /* ft_raster_flag_default :: This value is 0. */ - /* */ - /* ft_raster_flag_aa :: Requests the rendering of an */ - /* anti-aliased glyph bitmap. If unset, a */ - /* monchrome bitmap will be rendered. */ - /* */ - /* ft_raster_flag_direct :: Requests direct rendering over the */ - /* target bitmap. Direct rendering uses */ - /* user-provided callbacks in order to */ - /* perform direct drawing or composition */ - /* over an existing bitmap. If this bit is */ - /* unset, the content of the target bitmap */ - /* *must be zeroed*! */ - /* */ - typedef enum - { - ft_raster_flag_default = 0, - ft_raster_flag_aa = 1, - ft_raster_flag_direct = 2 - - } FT_Raster_Flag; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Params */ - /* */ - /* */ - /* A structure to hold the arguments used by a raster's render */ - /* function. */ - /* */ - /* */ - /* target :: The target bitmap. */ - /* */ - /* source :: A pointer to the source glyph image (e.g. an */ - /* FT_Outline). */ - /* */ - /* flags :: The rendering flags. */ - /* */ - /* gray_spans :: The gray span drawing callback. */ - /* */ - /* black_spans :: The black span drawing callback. */ - /* */ - /* bit_test :: The bit test callback. */ - /* */ - /* bit_set :: The bit set callback. */ - /* */ - /* user :: User-supplied data that is passed to each drawing */ - /* callback. */ - /* */ - /* */ - /* An anti-aliased glyph bitmap is drawn if the ft_raster_flag_aa bit */ - /* flag is set in the `flags' field, otherwise a monochrome bitmap */ - /* will be generated. */ - /* */ - /* If the ft_raster_flag_direct bit flag is set in `flags', the */ - /* raster will call the `gray_spans' callback to draw gray pixel */ - /* spans, in the case of an aa glyph bitmap, it will call */ - /* `black_spans', and `bit_test' and `bit_set' in the case of a */ - /* monochrome bitmap. This allows direct composition over a */ - /* pre-existing bitmap through user-provided callbacks to perform the */ - /* span drawing/composition. */ - /* */ - /* Note that the `bit_test' and `bit_set' callbacks are required when */ - /* rendering a monochrome bitmap, as they are crucial to implement */ - /* correct drop-out control as defined in the TrueType specification. */ - /* */ - typedef struct FT_Raster_Params_ - { - FT_Bitmap* target; - void* source; - int flags; - FT_Raster_Span_Func gray_spans; - FT_Raster_Span_Func black_spans; - FT_Raster_BitTest_Func bit_test; - FT_Raster_BitSet_Func bit_set; - void* user; - - } FT_Raster_Params; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_New_Func */ - /* */ - /* */ - /* A function used to create a new raster object. */ - /* */ - /* */ - /* memory :: A handle to the memory allocator. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - /* */ - /* The `memory' parameter is a typeless pointer in order to avoid */ - /* un-wanted dependencies on the rest of the FreeType code. In */ - /* practice, it is a FT_Memory, i.e., a handle to the standard */ - /* FreeType memory allocator. However, this field can be completely */ - /* ignored by a given raster implementation. */ - /* */ - typedef int (*FT_Raster_New_Func)( void* memory, - FT_Raster* raster ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Done_Func */ - /* */ - /* */ - /* A function used to destroy a given raster object. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - typedef void (*FT_Raster_Done_Func)( FT_Raster raster ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Reset_Func */ - /* */ - /* */ - /* FreeType provides an area of memory called the `render pool', */ - /* available to all registered rasters. This pool can be freely used */ - /* during a given scan-conversion but is shared by all rasters. Its */ - /* content is thus transient. */ - /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* pool_base :: The address in memory of the render pool. */ - /* */ - /* pool_size :: The size in bytes of the render pool. */ - /* */ - /* */ - /* Rasters can ignore the render pool and rely on dynamic memory */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). However, this is not */ - /* recommended for efficiency purposes. */ - /* */ - typedef void (*FT_Raster_Reset_Func)( FT_Raster raster, - unsigned char* pool_base, - unsigned long pool_size ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Set_Mode_Func */ - /* */ - /* */ - /* This function is a generic facility to change modes or attributes */ - /* in a given raster. This can be used for debugging purposes, or */ - /* simply to allow implementation-specific `features' in a given */ - /* raster module. */ - /* */ - /* */ - /* raster :: A handle to the new raster object. */ - /* */ - /* mode :: A 4-byte tag used to name the mode or property. */ - /* */ - /* args :: A pointer to the new mode/property to use. */ - /* */ - typedef int (*FT_Raster_Set_Mode_Func)( FT_Raster raster, - unsigned long mode, - void* args ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Render_Func */ - /* */ - /* */ - /* Invokes a given raster to scan-convert a given glyph image into a */ - /* target bitmap. */ - /* */ - /* */ - /* raster :: A handle to the raster object. */ - /* */ - /* params :: A pointer to a FT_Raster_Params structure used to store */ - /* the rendering parameters. */ - /* */ - /* */ - /* Error code. 0 means success. */ - /* */ - /* */ - /* The exact format of the source image depends on the raster's glyph */ - /* format defined in its FT_Raster_Funcs structure. It can be an */ - /* FT_Outline or anything else in order to support a large array of */ - /* glyph formats. */ - /* */ - /* Note also that the render function can fail and return a */ - /* FT_Err_Unimplemented_Feature error code if the raster used does */ - /* not support direct composition. */ - /* */ - /* XXX: For now, the standard raster doesn't support direct */ - /* composition but this should change for the final release (see */ - /* the files demos/src/ftgrays.c and demos/src/ftgrays2.c for */ - /* examples of distinct implementations which support direct */ - /* composition). */ - /* */ - typedef int (*FT_Raster_Render_Func)( FT_Raster raster, - FT_Raster_Params* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Raster_Funcs */ - /* */ - /* */ - /* A structure used to describe a given raster class to the library. */ - /* */ - /* */ - /* glyph_format :: The supported glyph format for this raster. */ - /* */ - /* raster_new :: The raster constructor. */ - /* */ - /* raster_reset :: Used to reset the render pool within the raster. */ - /* */ - /* raster_render :: A function to render a glyph into a given bitmap. */ - /* */ - /* raster_done :: The raster destructor. */ - /* */ - typedef struct FT_Raster_Funcs_ - { - FT_Glyph_Format glyph_format; - FT_Raster_New_Func raster_new; - FT_Raster_Reset_Func raster_reset; - FT_Raster_Set_Mode_Func raster_set_mode; - FT_Raster_Render_Func raster_render; - FT_Raster_Done_Func raster_done; - - } FT_Raster_Funcs; - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTIMAGE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftmm.h b/subsys/win32k/freetype/include/freetype/ftmm.h deleted file mode 100644 index db5db04..0000000 --- a/subsys/win32k/freetype/include/freetype/ftmm.h +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.h */ -/* */ -/* FreeType Multiple Master font interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMM_H -#define FTMM_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MM_Axis */ - /* */ - /* */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters fonts. */ - /* */ - /* */ - /* name :: The axis's name. */ - /* */ - /* minimum :: The axis's minimum design coordinate. */ - /* */ - /* maximum :: The axis's maximum design coordinate. */ - /* */ - typedef struct FT_MM_Axis_ - { - FT_String* name; - FT_Long minimum; - FT_Long maximum; - - } FT_MM_Axis; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Multi_Master */ - /* */ - /* */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* font. */ - /* */ - /* */ - /* num_axis :: Number of axes. Cannot exceed 4. */ - /* */ - /* num_designs :: Number of designs; should ne normally 2^num_axis */ - /* even though the Type 1 specification strangely */ - /* allows for intermediate designs to be present. This */ - /* number cannot exceed 16. */ - /* */ - /* axis :: A table of axis descriptors. */ - /* */ - typedef struct FT_Multi_Master_ - { - FT_UInt num_axis; - FT_UInt num_designs; - FT_MM_Axis axis[T1_MAX_MM_AXIS]; - - } FT_Multi_Master; - - - typedef FT_Error (*FT_Get_MM_Func)( FT_Face face, - FT_Multi_Master* master ); - - typedef FT_Error (*FT_Set_MM_Design_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - typedef FT_Error (*FT_Set_MM_Blend_Func)( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Multi_Master */ - /* */ - /* */ - /* Retrieves the Multiple Master descriptor of a given font. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* */ - /* master :: The Multiple Masters descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master* master ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Design_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_MM_Design_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Blend_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through normalized blend coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates (each one must be between 0 */ - /* and 1.0). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_MM_Blend_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTMM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftmodule.h b/subsys/win32k/freetype/include/freetype/ftmodule.h deleted file mode 100644 index 3c09aa2..0000000 --- a/subsys/win32k/freetype/include/freetype/ftmodule.h +++ /dev/null @@ -1,274 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmodule.h */ -/* */ -/* FreeType modules public interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMODULE_H -#define FTMODULE_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* module bit flags */ - typedef enum FT_Module_Flags_ - { - ft_module_font_driver = 1, /* this module is a font driver */ - ft_module_renderer = 2, /* this module is a renderer */ - ft_module_hinter = 4, /* this module is a glyph hinter */ - ft_module_styler = 8, /* this module is a styler */ - - ft_module_driver_scalable = 0x100, /* the driver supports scalable */ - /* fonts */ - ft_module_driver_no_outlines = 0x200, /* the driver does not support */ - /* vector outlines */ - ft_module_driver_has_hinter = 0x400 /* the driver provides its own */ - /* hinter */ - - } FT_Module_Flags; - - - typedef void (*FT_Module_Interface)( void ); - - typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); - - typedef void (*FT_Module_Destructor)( FT_Module module ); - - typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, - const char* name ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Module_Class */ - /* */ - /* */ - /* The module class descriptor. */ - /* */ - /* */ - /* module_flags :: Bit flags describing the module. */ - /* */ - /* module_size :: The size of one module object/instance in */ - /* bytes. */ - /* */ - /* module_name :: The name of the module. */ - /* */ - /* module_version :: The version, as a 16.16 fixed number */ - /* (major.minor). */ - /* */ - /* module_requires :: The version of FreeType this module requires */ - /* (starts at version 2.0, i.e 0x20000) */ - /* */ - /* module_init :: A function used to initialize (not create) a */ - /* new module object. */ - /* */ - /* module_done :: A function used to finalize (not destroy) a */ - /* given module object */ - /* */ - /* get_interface :: Queries a given module for a specific */ - /* interface by name. */ - /* */ - typedef struct FT_Module_Class_ - { - FT_ULong module_flags; - FT_Int module_size; - const FT_String* module_name; - FT_Fixed module_version; - FT_Fixed module_requires; - - const void* module_interface; - - FT_Module_Constructor module_init; - FT_Module_Destructor module_done; - FT_Module_Requester get_interface; - - } FT_Module_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Module */ - /* */ - /* */ - /* Adds a new module to a given library instance. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* clazz :: A pointer to class descriptor for the module. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module */ - /* */ - /* */ - /* Finds a module by its name. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module handle. 0 if none was found. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for :-) */ - /* */ - FT_EXPORT_DEF( FT_Module ) FT_Get_Module( FT_Library library, - const char* module_name ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Remove_Module */ - /* */ - /* */ - /* Removes a given module from a library instance. */ - /* */ - /* */ - /* library :: A handle to a library object. */ - /* */ - /* module :: A handle to a module object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The module object is destroyed by the function in case of success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Remove_Module( FT_Library library, - FT_Module module ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Library */ - /* */ - /* */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ - /* */ - /* */ - /* memory :: A handle to the original memory object. */ - /* */ - /* */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_New_Library( FT_Memory memory, - FT_Library* library ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Library */ - /* */ - /* */ - /* Discards a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* */ - /* library :: A handle to the target library. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Done_Library( FT_Library library ); - - - - typedef void (*FT_DebugHook_Func)( void* arg ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Debug_Hook */ - /* */ - /* */ - /* Sets a debug hook function for debugging the interpreter of a font */ - /* format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in ftobjs.h, e.g. */ - /* FT_DEBUG_HOOK_TRUETYPE */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ - /* */ - FT_EXPORT_DEF( void ) FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ); - - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Default_Modules */ - /* */ - /* */ - /* Adds the set of default drivers to a given library object. */ - /* This is only useful when you create a library object with */ - /* FT_New_Library() (usually to plug a custom memory manager). */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - FT_EXPORT_DEF( void ) FT_Add_Default_Modules( FT_Library library ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTMODULE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftnames.h b/subsys/win32k/freetype/include/freetype/ftnames.h deleted file mode 100644 index 2969214..0000000 --- a/subsys/win32k/freetype/include/freetype/ftnames.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftnames.h */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2000 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 FTNAMES_H -#define FTNAMES_H - - -#include - - - typedef struct FT_SfntName_ - { - FT_UShort platform_id; - FT_UShort encoding_id; - FT_UShort language_id; - FT_UShort name_id; - - FT_Byte* string; - FT_UInt string_len; /* in bytes */ - - } FT_SfntName; - - - FT_EXPORT_DEF( FT_UInt ) FT_Get_Sfnt_Name_Count( FT_Face face ); - - FT_EXPORT_DEF( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, - FT_UInt index, - FT_SfntName* aname ); - - -#endif /* FTNAMES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftoutln.h b/subsys/win32k/freetype/include/freetype/ftoutln.h deleted file mode 100644 index 1e448bd..0000000 --- a/subsys/win32k/freetype/include/freetype/ftoutln.h +++ /dev/null @@ -1,344 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.h */ -/* */ -/* Support for the FT_Outline type used to store glyph shapes of */ -/* most scalable font formats (specification). */ -/* */ -/* Copyright 1996-2000 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 FTOUTLN_H -#define FTOUTLN_H - - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Decompose */ - /* */ - /* */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* */ - /* outline :: A pointer to the source target. */ - /* */ - /* interface :: A table of `emitters', i.e,. function pointers called */ - /* during decomposition to indicate path operations. */ - /* */ - /* user :: A typeless pointer which is passed to each emitter */ - /* during the decomposition. It can be used to store */ - /* the state during the decomposition. */ - /* */ - /* */ - /* FreeType error code. 0 means sucess. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Decompose( - FT_Outline* outline, - FT_Outline_Funcs* interface, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_New */ - /* */ - /* */ - /* Creates a new outline of a given size. */ - /* */ - /* */ - /* library :: A handle to the library object from where the */ - /* outline is allocated. Note however that the new */ - /* outline will NOT necessarily be FREED, when */ - /* destroying the library, by FT_Done_FreeType(). */ - /* */ - /* numPoints :: The maximal number of points within the outline. */ - /* */ - /* numContours :: The maximal number of contours within the outline. */ - /* */ - /* */ - /* outline :: A handle to the new outline. NULL in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* The reason why this function takes a `library' parameter is simply */ - /* to use the library's memory allocator. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ); - - - FT_EXPORT_DEF( FT_Error ) FT_Outline_New_Internal( - FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Done */ - /* */ - /* */ - /* Destroys an outline created with FT_Outline_New(). */ - /* */ - /* */ - /* library :: A handle of the library object used to allocate the */ - /* outline. */ - /* */ - /* outline :: A pointer to the outline object to be discarded. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* If the outline's `owner' field is not set, only the outline */ - /* descriptor will be released. */ - /* */ - /* The reason why this function takes an `outline' parameter is */ - /* simply to use FT_Free(). */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Done( FT_Library library, - FT_Outline* outline ); - - - FT_EXPORT_DEF( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_CBox */ - /* */ - /* */ - /* Returns an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bezier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bezier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ - /* */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* */ - /* cbox :: The outline's control box. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Get_CBox( FT_Outline* outline, - FT_BBox* cbox ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Translate */ - /* */ - /* */ - /* Applies a simple translation to the points of an outline. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* xOffset :: The horizontal offset. */ - /* */ - /* yOffset :: The vertical offset. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Translate( FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Copy */ - /* */ - /* */ - /* Copies an outline into another one. Both objects must have the */ - /* same sizes (number of points & number of contours) when this */ - /* function is called. */ - /* */ - /* */ - /* source :: A handle to the source outline. */ - /* */ - /* */ - /* target :: A handle to the target outline. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Copy( FT_Outline* source, - FT_Outline* target ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Transform( FT_Outline* outline, - FT_Matrix* matrix ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Reverse */ - /* */ - /* */ - /* Reverses the drawing direction of an outline. This is used to */ - /* ensure consistent fill conventions for mirrored glyphs. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* */ - /* This functions toggles the bit flag `ft_outline_reverse_fill' in */ - /* the outline's `flags' field. */ - /* */ - /* It shouldn't be used by a normal client application, unless it */ - /* knows what it is doing. */ - /* */ - FT_EXPORT_DEF( void ) FT_Outline_Reverse( FT_Outline* outline ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* */ - /* Renders an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* map :: A pointer to the target bitmap descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ - /* */ - /* It will use the raster correponding to the default glyph format. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - FT_Bitmap* bitmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Render */ - /* */ - /* */ - /* Renders an outline within a bitmap using the current scan-convert. */ - /* This functions uses an FT_Raster_Params structure as an argument, */ - /* allowing advanced features like direct composition, translucency, */ - /* etc. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* params :: A pointer to a FT_Raster_Params structure used to */ - /* describe the rendering operation. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* You should know what you are doing and how FT_Raster_Params works */ - /* to use this function. */ - /* */ - /* The field `params.source' will be set to `outline' before the scan */ - /* converter is called, which means that the value you give to it is */ - /* actually ignored. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTOUTLN_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftrender.h b/subsys/win32k/freetype/include/freetype/ftrender.h deleted file mode 100644 index fe5acd2..0000000 --- a/subsys/win32k/freetype/include/freetype/ftrender.h +++ /dev/null @@ -1,191 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrender.h */ -/* */ -/* FreeType renderer modules public interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTRENDER_H -#define FTRENDER_H - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* create a new glyph object */ - typedef FT_Error (*FT_Glyph_Init_Func)( FT_Glyph glyph, - FT_GlyphSlot slot ); - - /* destroys a given glyph object */ - typedef void (*FT_Glyph_Done_Func)( FT_Glyph glyph ); - - typedef void (*FT_Glyph_Transform_Func)( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ); - - typedef void (*FT_Glyph_BBox_Func)( FT_Glyph glyph, - FT_BBox* abbox ); - - typedef FT_Error (*FT_Glyph_Copy_Func)( FT_Glyph source, - FT_Glyph target ); - - typedef FT_Error (*FT_Glyph_Prepare_Func)( FT_Glyph glyph, - FT_GlyphSlot slot ); - - struct FT_Glyph_Class_ - { - FT_UInt glyph_size; - FT_Glyph_Format glyph_format; - FT_Glyph_Init_Func glyph_init; - FT_Glyph_Done_Func glyph_done; - FT_Glyph_Copy_Func glyph_copy; - FT_Glyph_Transform_Func glyph_transform; - FT_Glyph_BBox_Func glyph_bbox; - FT_Glyph_Prepare_Func glyph_prepare; - }; - - - typedef FT_Error (*FTRenderer_render)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ); - - typedef FT_Error (*FTRenderer_transform)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ); - - typedef void (*FTRenderer_getCBox)( FT_Renderer renderer, - FT_GlyphSlot slot, - FT_BBox* cbox ); - - typedef FT_Error (*FTRenderer_setMode)( FT_Renderer renderer, - FT_ULong mode_tag, - FT_Pointer mode_ptr ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Renderer_Class */ - /* */ - /* */ - /* The renderer module class descriptor. */ - /* */ - /* */ - /* root :: The root FT_Module_Class fields. */ - /* */ - /* glyph_format :: The glyph image format this renderer handles. */ - /* */ - /* render_glyph :: A method used to render the image that is in a */ - /* given glyph slot into a bitmap. */ - /* */ - /* set_mode :: A method used to pass additional parameters. */ - /* */ - /* raster_class :: For `ft_glyph_format_outline' renderers only, this */ - /* is a pointer to its raster's class. */ - /* */ - /* raster :: For `ft_glyph_format_outline' renderers only. this */ - /* is a pointer to the corresponding raster object, */ - /* if any. */ - /* */ - typedef struct FT_Renderer_Class_ - { - FT_Module_Class root; - - FT_Glyph_Format glyph_format; - - FTRenderer_render render_glyph; - FTRenderer_transform transform_glyph; - FTRenderer_getCBox get_glyph_cbox; - FTRenderer_setMode set_mode; - - FT_Raster_Funcs* raster_class; - - } FT_Renderer_Class; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Renderer */ - /* */ - /* */ - /* Retrieves the current renderer for a given glyph format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* format :: The glyph format. */ - /* */ - /* */ - /* A renderer handle. 0 if none found. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - /* To add a new renderer, simply use FT_Add_Module(). To retrieve a */ - /* renderer by its name, use FT_Get_Module(). */ - /* */ - FT_EXPORT_DEF( FT_Renderer ) FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Renderer */ - /* */ - /* */ - /* Sets the current renderer to use, and set additional mode. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* renderer :: A handle to the renderer object. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* parameters :: Additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* In case of success, the renderer will be used to convert glyph */ - /* images in the renderer's known format into bitmaps. */ - /* */ - /* This doesn't change the current renderer for other formats. */ - /* */ - FT_EXPORT_DEF(FT_Error) FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTRENDER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ftsystem.h b/subsys/win32k/freetype/include/freetype/ftsystem.h deleted file mode 100644 index bc74bce..0000000 --- a/subsys/win32k/freetype/include/freetype/ftsystem.h +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.h */ -/* */ -/* FreeType low-level system interface definition (specification). */ -/* */ -/* Copyright 1996-2000 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 FTSYSTEM_H -#define FTSYSTEM_H - - - /*************************************************************************/ - /* */ - /* M E M O R Y M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - typedef struct FT_MemoryRec_* FT_Memory; - - - typedef void* (*FT_Alloc_Func)( FT_Memory memory, - long size ); - - typedef void (*FT_Free_Func)( FT_Memory memory, - void* block ); - - typedef void* (*FT_Realloc_Func)( FT_Memory memory, - long cur_size, - long new_size, - void* block ); - - - struct FT_MemoryRec_ - { - void* user; - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - }; - - - /*************************************************************************/ - /* */ - /* I / O M A N A G E M E N T */ - /* */ - /*************************************************************************/ - - - typedef union FT_StreamDesc_ - { - long value; - void* pointer; - - } FT_StreamDesc; - - - typedef struct FT_StreamRec_* FT_Stream; - - - typedef unsigned long (*FT_Stream_IO)( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ); - - typedef void (*FT_Stream_Close)( FT_Stream stream ); - - - struct FT_StreamRec_ - { - unsigned char* base; - unsigned long size; - unsigned long pos; - - FT_StreamDesc descriptor; - FT_StreamDesc pathname; /* ignored by FreeType -- */ - /* useful for debugging */ - FT_Stream_IO read; - FT_Stream_Close close; - - FT_Memory memory; - unsigned char* cursor; - unsigned char* limit; - }; - - -#endif /* FTSYSTEM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/fttypes.h b/subsys/win32k/freetype/include/freetype/fttypes.h deleted file mode 100644 index ec90906..0000000 --- a/subsys/win32k/freetype/include/freetype/fttypes.h +++ /dev/null @@ -1,400 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttypes.h */ -/* */ -/* FreeType simple types definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 FTTYPES_H -#define FTTYPES_H - - -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Bool */ - /* */ - /* */ - /* A typedef of unsigned char, used for simple booleans. */ - /* */ - typedef unsigned char FT_Bool; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_FWord */ - /* */ - /* */ - /* A signed 16-bit integer used to store a distance in original font */ - /* units. */ - /* */ - typedef signed short FT_FWord; /* distance in FUnits */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UFWord */ - /* */ - /* */ - /* An unsigned 16-bit integer used to store a distance in original */ - /* font units. */ - /* */ - typedef unsigned short FT_UFWord; /* unsigned distance */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Char */ - /* */ - /* */ - /* A simple typedef for the _signed_ char type. */ - /* */ - typedef signed char FT_Char; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Byte */ - /* */ - /* */ - /* A simple typedef for the _unsigned_ char type. */ - /* */ - typedef unsigned char FT_Byte; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_String */ - /* */ - /* */ - /* A simple typedef for the char type, usually used for strings. */ - /* */ - typedef char FT_String; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Short */ - /* */ - /* */ - /* A typedef for signed short. */ - /* */ - typedef signed short FT_Short; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UShort */ - /* */ - /* */ - /* A typedef for unsigned short. */ - /* */ - typedef unsigned short FT_UShort; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Int */ - /* */ - /* */ - /* A typedef for the int type. */ - /* */ - typedef int FT_Int; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UInt */ - /* */ - /* */ - /* A typedef for the unsigned int type. */ - /* */ - typedef unsigned int FT_UInt; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Long */ - /* */ - /* */ - /* A typedef for signed long. */ - /* */ - typedef signed long FT_Long; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ULong */ - /* */ - /* */ - /* A typedef for unsigned long. */ - /* */ - typedef unsigned long FT_ULong; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_F2Dot14 */ - /* */ - /* */ - /* A signed 2.14 fixed float type used for unit vectors. */ - /* */ - typedef signed short FT_F2Dot14; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_F26Dot6 */ - /* */ - /* */ - /* A signed 26.6 fixed float type used for vectorial pixel */ - /* coordinates. */ - /* */ - typedef signed long FT_F26Dot6; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Fixed */ - /* */ - /* */ - /* This type is used to store 16.16 fixed float values, like scales */ - /* or matrix coefficients. */ - /* */ - typedef signed long FT_Fixed; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Error */ - /* */ - /* */ - /* The FreeType error code type. A value of 0 is always interpreted */ - /* as a successful operation. */ - /* */ - typedef int FT_Error; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Pointer */ - /* */ - /* */ - /* A simple typedef for a typeless pointer. */ - /* */ - typedef void* FT_Pointer; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_UnitVector */ - /* */ - /* */ - /* A simple structure used to store a 2D vector unit vector. Uses */ - /* FT_F2Dot14 types. */ - /* */ - /* */ - /* x :: Horizontal coordinate. */ - /* */ - /* y :: Vertical coordinate. */ - /* */ - typedef struct FT_UnitVector_ - { - FT_F2Dot14 x; - FT_F2Dot14 y; - - } FT_UnitVector; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix */ - /* */ - /* */ - /* A simple structure used to store a 2x2 matrix. Coefficients are */ - /* in 16.16 fixed float format. The computation performed is: */ - /* */ - /* { */ - /* x' = x*xx + y*xy */ - /* y' = x*yx + y*yy */ - /* } */ - /* */ - /* */ - /* xx :: Matrix coefficient. */ - /* */ - /* xy :: Matrix coefficient. */ - /* */ - /* yx :: Matrix coefficient. */ - /* */ - /* yy :: Matrix coefficient. */ - /* */ - typedef struct FT_Matrix_ - { - FT_Fixed xx, xy; - FT_Fixed yx, yy; - - } FT_Matrix; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_BBox */ - /* */ - /* */ - /* A structure used to hold an outline's bounding box, i.e., the */ - /* coordinates of its extrema in the horizontal and vertical */ - /* directions. */ - /* */ - /* */ - /* xMin :: The horizontal minimum (left-most). */ - /* */ - /* yMin :: The vertical minimum (bottom-most). */ - /* */ - /* xMax :: The horizontal maximum (right-most). */ - /* */ - /* yMax :: The vertical maximum (top-most). */ - /* */ - typedef struct FT_BBox_ - { - FT_Pos xMin, yMin; - FT_Pos xMax, yMax; - - } FT_BBox; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MAKE_TAG */ - /* */ - /* */ - /* This macro converts four letter tags which are used to label */ - /* TrueType tables into an unsigned long to be used within FreeType. */ - /* */ -#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ - ( ( (FT_ULong)_x1 << 24 ) | \ - ( (FT_ULong)_x2 << 16 ) | \ - ( (FT_ULong)_x3 << 8 ) | \ - (FT_ULong)_x4 ) - - - /*************************************************************************/ - /*************************************************************************/ - /* */ - /* L I S T M A N A G E M E N T */ - /* */ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListNode */ - /* */ - /* */ - /* Many elements and objects in FreeType are listed through a */ - /* FT_List record (see FT_ListRec). As its name suggests, a */ - /* FT_ListNode is a handle to a single list element. */ - /* */ - typedef struct FT_ListNodeRec_* FT_ListNode; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List */ - /* */ - /* */ - /* A handle to a list record (see FT_ListRec). */ - /* */ - typedef struct FT_ListRec_* FT_List; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListNodeRec */ - /* */ - /* */ - /* A structure used to hold a single list element. */ - /* */ - /* */ - /* prev :: The previous element in the list. NULL if first. */ - /* */ - /* next :: The next element in the list. NULL if last. */ - /* */ - /* data :: A typeless pointer to the listed object. */ - /* */ - typedef struct FT_ListNodeRec_ - { - FT_ListNode prev; - FT_ListNode next; - void* data; - - } FT_ListNodeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ListRec */ - /* */ - /* */ - /* A structure used to hold a simple doubly-linked list. These are */ - /* used in many parts of FreeType. */ - /* */ - /* */ - /* head :: The head (first element) of doubly-linked list. */ - /* */ - /* tail :: The tail (last element) of doubly-linked list. */ - /* */ - typedef struct FT_ListRec_ - { - FT_ListNode head; - FT_ListNode tail; - - } FT_ListRec; - - -#define FT_IS_EMPTY( list ) ( (list).head == 0 ) - - -#endif /* FTTYPES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/autohint.h b/subsys/win32k/freetype/include/freetype/internal/autohint.h deleted file mode 100644 index 5d35a5d..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/autohint.h +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************/ -/* */ -/* autohint.h */ -/* */ -/* High-level `autohint' module-specific interface (specification). */ -/* */ -/* Copyright 1996-2000 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 auto-hinter is used to load and automatically hint glyphs if a */ - /* format-specific hinter isn't available. */ - /* */ - /*************************************************************************/ - - -#ifndef AUTOHINT_H -#define AUTOHINT_H - - - /*************************************************************************/ - /* */ - /* A small technical note regarding automatic hinting in order to */ - /* clarify this module interface. */ - /* */ - /* An automatic hinter might compute two kinds of data for a given face: */ - /* */ - /* - global hints: Usually some metrics that describe global properties */ - /* of the face. It is computed by scanning more or less */ - /* agressively the glyphs in the face, and thus can be */ - /* very slow to compute (even if the size of global */ - /* hints is really small). */ - /* */ - /* - glyph hints: These describe some important features of the glyph */ - /* outline, as well as how to align them. They are */ - /* generally much faster to compute than global hints. */ - /* */ - /* The current FreeType auto-hinter does a pretty good job while */ - /* performing fast computations for both global and glyph hints. */ - /* However, we might be interested in introducing more complex and */ - /* powerful algorithms in the future, like the one described in the John */ - /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ - /* */ - /* Because a sufficiently sophisticated font management system would */ - /* typically implement an LRU cache of opened face objects to reduce */ - /* memory usage, it is a good idea to be able to avoid recomputing */ - /* global hints every time the same face is re-opened. */ - /* */ - /* We thus provide the ability to cache global hints outside of the face */ - /* object, in order to speed up font re-opening time. Of course, this */ - /* feature is purely optional, so most client programs won't even notice */ - /* it. */ - /* */ - /* I initially thought that it would be a good idea to cache the glyph */ - /* hints too. However, my general idea now is that if you really need */ - /* to cache these too, you are simply in need of a new font format, */ - /* where all this information could be stored within the font file and */ - /* decoded on the fly. */ - /* */ - /*************************************************************************/ - - -#include - - - typedef struct FT_AutoHinterRec_ *FT_AutoHinter; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Get_Global_Func */ - /* */ - /* */ - /* Retrieves the global hints computed for a given face object the */ - /* resulting data is dissociated from the face and will survive a */ - /* call to FT_Done_Face(). It must be discarded through the API */ - /* FT_AutoHinter_Done_Global_Func(). */ - /* */ - /* */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* global_hints :: A typeless pointer to the global hints. */ - /* */ - /* global_len :: The size in bytes of the global hints. */ - /* */ - typedef void (*FT_AutoHinter_Get_Global_Func)( - FT_AutoHinter hinter, - FT_Face face, - void** global_hints, - long* global_len ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Done_Global_Func */ - /* */ - /* */ - /* Discards the global hints retrieved through */ - /* FT_AutoHinter_Get_Global_Func(). This is the only way these hints */ - /* are freed from memory. */ - /* */ - /* */ - /* hinter :: A handle to the auto-hinter module. */ - /* */ - /* global :: A pointer to retrieved global hints to discard. */ - /* */ - typedef void (*FT_AutoHinter_Done_Global_Func)( FT_AutoHinter hinter, - void* global ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Reset_Func */ - /* */ - /* */ - /* This function is used to recompute the global metrics in a given */ - /* font. This is useful when global font data changes (e.g. Multiple */ - /* Masters fonts where blend coordinates change). */ - /* */ - /* */ - /* hinter :: A handle to the source auto-hinter. */ - /* */ - /* face :: A handle to the face. */ - /* */ - typedef void (*FT_AutoHinter_Reset_Func)( FT_AutoHinter hinter, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Load_Func */ - /* */ - /* */ - /* This function is used to load, scale, and automatically hint a */ - /* glyph from a given face. */ - /* */ - /* */ - /* face :: A handle to the face. */ - /* glyph_index :: The glyph index. */ - /* load_flags :: The load flags. */ - /* */ - /* */ - /* This function is capable of loading composite glyphs by hinting */ - /* each sub-glyph independently (which improves quality). */ - /* */ - /* It will call the font driver with FT_Load_Glyph(), with */ - /* FT_LOAD_NO_SCALE set. */ - /* */ - typedef FT_Error (*FT_AutoHinter_Load_Func)( FT_AutoHinter hinter, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_ULong load_flags ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_AutoHinter_Interface */ - /* */ - /* */ - /* The auto-hinter module's interface. */ - /* */ - typedef struct FT_AutoHinter_Interface - { - FT_AutoHinter_Reset_Func reset_face; - FT_AutoHinter_Load_Func load_glyph; - - FT_AutoHinter_Get_Global_Func get_global_hints; - FT_AutoHinter_Done_Global_Func done_global_hints; - - } FT_AutoHinter_Interface; - - -#endif /* AUTOHINT_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftcalc.h b/subsys/win32k/freetype/include/freetype/internal/ftcalc.h deleted file mode 100644 index 99b6cfa..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftcalc.h +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.h */ -/* */ -/* Arithmetic computations (specification). */ -/* */ -/* Copyright 1996-2000 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 FTCALC_H -#define FTCALC_H - -#include -#include /* for LONG64 */ - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifdef LONG64 - - - typedef INT64 FT_Int64; - -#define ADD_64( x, y, z ) z = (x) + (y) -#define MUL_64( x, y, z ) z = (FT_Int64)(x) * (y) - -#define DIV_64( x, y ) ( (x) / (y) ) - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_64( z ) FT_Sqrt64( z ) - - FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt64( FT_Int64 l ); - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#else /* LONG64 */ - - - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - - } FT_Int64; - - -#define ADD_64( x, y, z ) FT_Add64( &x, &y, &z ) -#define MUL_64( x, y, z ) FT_MulTo64( x, y, &z ) -#define DIV_64( x, y ) FT_Div64by32( &x, y ) - - - FT_EXPORT_DEF( void ) FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64* z ); - - FT_EXPORT_DEF( void ) FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64* z ); - - FT_EXPORT_DEF( FT_Int32 ) FT_Div64by32( FT_Int64* x, - FT_Int32 y ); - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_64( z ) FT_Sqrt64( &z ) - - FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt64( FT_Int64* x ); - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#endif /* LONG64 */ - - -#ifndef FT_CONFIG_OPTION_OLD_CALCS - -#define SQRT_32( x ) FT_Sqrt32( x ) - - BASE_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ); - -#endif /* !FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) -#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) -#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) -#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) -#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) - -#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ - : ( -( ( 32 - (x) ) & -64 ) ) ) - - -#ifdef __cplusplus - } -#endif - -#endif /* FTCALC_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftdebug.h b/subsys/win32k/freetype/include/freetype/internal/ftdebug.h deleted file mode 100644 index 8b1e4dd..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftdebug.h +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.h */ -/* */ -/* Debugging and logging component (specification). */ -/* */ -/* Copyright 1996-2000 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 FTDEBUG_H -#define FTDEBUG_H - -#include /* for FT_DEBUG_LEVEL_TRACE, */ - /* FT_DEBUG_LEVEL_ERROR */ - -#ifdef __cplusplus - extern "C" { -#endif - - - /* A very stupid pre-processor trick. See K&R version 2 */ - /* section A12.3 for details... */ - /* */ - /* It is also described in the section `Separate */ - /* Expansion of Macro Arguments' in the info file */ - /* `cpp.info', describing GNU cpp. */ - /* */ -#define FT_CAT( x, y ) x ## y -#define FT_XCAT( x, y ) FT_CAT( x, y ) - - -#ifdef FT_DEBUG_LEVEL_TRACE - - - /* note that not all levels are used currently */ - - typedef enum FT_Trace_ - { - /* the first level must always be `trace_any' */ - trace_any = 0, - - /* base components */ - trace_aaraster, /* anti-aliasing raster (ftgrays.c) */ - trace_calc, /* calculations (ftcalc.c) */ - trace_extend, /* extension manager (ftextend.c) */ - trace_glyph, /* glyph manager (ftglyph.c) */ - trace_io, /* i/o monitoring (ftsystem.c) */ - trace_init, /* initialization (ftinit.c) */ - trace_list, /* list manager (ftlist.c) */ - trace_memory, /* memory manager (ftobjs.c) */ - trace_mm, /* MM interface (ftmm.c) */ - trace_objs, /* base objects (ftobjs.c) */ - trace_outline, /* outline management (ftoutln.c) */ - trace_raster, /* rasterizer (ftraster.c) */ - trace_stream, /* stream manager (ftstream.c) */ - - /* SFNT driver components */ - trace_sfobjs, /* SFNT object handler (sfobjs.c) */ - trace_ttcmap, /* charmap handler (ttcmap.c) */ - trace_ttload, /* basic TrueType tables (ttload.c) */ - trace_ttpost, /* PS table processing (ttpost.c) */ - trace_ttsbit, /* TrueType sbit handling (ttsbit.c) */ - - /* TrueType driver components */ - trace_ttdriver, /* TT font driver (ttdriver.c) */ - trace_ttgload, /* TT glyph loader (ttgload.c) */ - trace_ttinterp, /* bytecode interpreter (ttinterp.c) */ - trace_ttobjs, /* TT objects manager (ttobjs.c) */ - trace_ttpload, /* TT data/program loader (ttpload.c) */ - - /* Type 1 driver components */ - trace_t1driver, - trace_t1gload, - trace_t1hint, - trace_t1load, - trace_t1objs, - - /* experimental Type 1 driver components */ - trace_z1driver, - trace_z1gload, - trace_z1hint, - trace_z1load, - trace_z1objs, - trace_z1parse, - - /* Type 2 driver components */ - trace_t2driver, - trace_t2gload, - trace_t2load, - trace_t2objs, - trace_t2parse, - - /* CID driver components */ - trace_cidafm, - trace_ciddriver, - trace_cidgload, - trace_cidload, - trace_cidobjs, - trace_cidparse, - - /* Windows fonts component */ - trace_winfnt, - - /* the last level must always be `trace_max' */ - trace_max - - } FT_Trace; - - - /* declared in ftdebug.c */ - extern char ft_trace_levels[trace_max]; - - - /*************************************************************************/ - /* */ - /* IMPORTANT! */ - /* */ - /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ - /* value before using any TRACE macro. */ - /* */ - /*************************************************************************/ - - -#define FT_TRACE( level, varformat ) \ - do \ - { \ - if ( ft_trace_levels[FT_COMPONENT] >= level ) \ - FT_XCAT( FT_Message, varformat ); \ - } while ( 0 ) - - - FT_EXPORT_DEF( void ) FT_SetTraceLevel( FT_Trace component, - char level ); - - -#elif defined( FT_DEBUG_LEVEL_ERROR ) - - -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ - - -#else /* release mode */ - - -#define FT_Assert( condition ) do ; while ( 0 ) /* nothing */ - -#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ -#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ - - -#endif /* FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* Define macros and functions that are common to the debug and trace */ - /* modes. */ - /* */ - /* You need vprintf() to be able to compile ftdebug.c. */ - /* */ - /*************************************************************************/ - - -#if defined( FT_DEBUG_LEVEL_TRACE ) || defined( FT_DEBUG_LEVEL_ERROR ) - - -#include "stdio.h" /* for vprintf() */ - - -#define FT_Assert( condition ) \ - do \ - { \ - if ( !( condition ) ) \ - FT_Panic( "assertion failed on line %d of file %s\n", \ - __LINE__, __FILE__ ); \ - } while ( 0 ) - - /* print a message */ - FT_EXPORT_DEF( void ) FT_Message( const char* fmt, ... ); - - /* print a message and exit */ - FT_EXPORT_DEF( void ) FT_Panic( const char* fmt, ... ); - -#define FT_ERROR( varformat ) FT_XCAT( FT_Message, varformat ) - - -#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */ - - - /*************************************************************************/ - /* */ - /* You need two opening resp. closing parentheses! */ - /* */ - /* Example: FT_TRACE0(( "Value is %i", foo )) */ - /* */ - /*************************************************************************/ - -#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) -#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) -#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) -#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) -#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) -#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) -#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) -#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTDEBUG_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftdriver.h b/subsys/win32k/freetype/include/freetype/internal/ftdriver.h deleted file mode 100644 index 592de49..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftdriver.h +++ /dev/null @@ -1,182 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdriver.h */ -/* */ -/* FreeType font driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTDRIVER_H -#define FTDRIVER_H - - -#include -#include - - - typedef FT_Error (*FTDriver_initFace)( FT_Stream stream, - FT_Face face, - FT_Int typeface_index, - FT_Int num_params, - FT_Parameter* parameters ); - - typedef void (*FTDriver_doneFace)( FT_Face face ); - - - typedef FT_Error (*FTDriver_initSize)( FT_Size size ); - - typedef void (*FTDriver_doneSize)( FT_Size size ); - - - typedef FT_Error (*FTDriver_initGlyphSlot)( FT_GlyphSlot slot ); - - typedef void (*FTDriver_doneGlyphSlot)( FT_GlyphSlot slot ); - - - typedef FT_Error (*FTDriver_setCharSizes)( FT_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ); - - typedef FT_Error (*FTDriver_setPixelSizes)( FT_Size size, - FT_UInt pixel_width, - FT_UInt pixel_height ); - - typedef FT_Error (*FTDriver_loadGlyph)( FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ); - - - typedef FT_UInt (*FTDriver_getCharIndex)( FT_CharMap charmap, - FT_Long charcode ); - - typedef FT_Error (*FTDriver_getKerning)( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ); - - - typedef FT_Error (*FTDriver_attachFile)( FT_Face face, - FT_Stream stream ); - - - typedef FT_Error (*FTDriver_getAdvances)( FT_Face face, - FT_UInt first, - FT_UInt count, - FT_Bool vertical, - FT_UShort* advances ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Driver_Class */ - /* */ - /* */ - /* The font driver class. This structure mostly contains pointers to */ - /* driver methods. */ - /* */ - /* */ - /* root :: The parent module. */ - /* */ - /* face_object_size :: The size of a face object in bytes. */ - /* */ - /* size_object_size :: The size of a size object in bytes. */ - /* */ - /* slot_object_size :: The size of a glyph object in bytes. */ - /* */ - /* init_face :: The format-specific face constructor. */ - /* */ - /* done_face :: The format-specific face destructor. */ - /* */ - /* init_size :: The format-specific size constructor. */ - /* */ - /* done_size :: The format-specific size destructor. */ - /* */ - /* init_slot :: The format-specific slot constructor. */ - /* */ - /* done_slot :: The format-specific slot destructor. */ - /* */ - /* set_char_sizes :: A handle to a function used to set the new */ - /* character size in points + resolution. Can be */ - /* set to 0 to indicate default behaviour. */ - /* */ - /* set_pixel_sizes :: A handle to a function used to set the new */ - /* character size in pixels. Can be set to 0 to */ - /* indicate default behaviour. */ - /* */ - /* load_glyph :: A function handle to load a given glyph image */ - /* in a slot. This field is mandatory! */ - /* */ - /* get_char_index :: A function handle to return the glyph index of */ - /* a given character for a given charmap. This */ - /* field is mandatory! */ - /* */ - /* get_kerning :: A function handle to return the unscaled */ - /* kerning for a given pair of glyphs. Can be */ - /* set to 0 if the format doesn't support */ - /* kerning. */ - /* */ - /* attach_file :: This function handle is used to read */ - /* additional data for a face from another */ - /* file/stream. For example, this can be used to */ - /* add data from AFM or PFM files on a Type 1 */ - /* face, or a CIDMap on a CID-keyed face. */ - /* */ - /* get_advances :: A function handle used to return the advances */ - /* of 'count' glyphs, starting at `index'. the */ - /* `vertical' flags must be set when vertical */ - /* advances are queried. The advances buffer is */ - /* caller-allocated. */ - /* */ - /* */ - /* Most function pointers, with the exception of `load_glyph' and */ - /* `get_char_index' can be set to 0 to indicate a default behaviour. */ - /* */ - typedef struct FT_Driver_Class_ - { - FT_Module_Class root; - - FT_Int face_object_size; - FT_Int size_object_size; - FT_Int slot_object_size; - - FTDriver_initFace init_face; - FTDriver_doneFace done_face; - - FTDriver_initSize init_size; - FTDriver_doneSize done_size; - - FTDriver_initGlyphSlot init_slot; - FTDriver_doneGlyphSlot done_slot; - - FTDriver_setCharSizes set_char_sizes; - FTDriver_setPixelSizes set_pixel_sizes; - - FTDriver_loadGlyph load_glyph; - FTDriver_getCharIndex get_char_index; - - FTDriver_getKerning get_kerning; - FTDriver_attachFile attach_file; - - FTDriver_getAdvances get_advances; - - } FT_Driver_Class; - - -#endif /* FTDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftextend.h b/subsys/win32k/freetype/include/freetype/internal/ftextend.h deleted file mode 100644 index fdd2c6e..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftextend.h +++ /dev/null @@ -1,178 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftextend.h */ -/* */ -/* FreeType extensions implementation (specification). */ -/* */ -/* Copyright 1996-2000 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 FTEXTEND_H -#define FTEXTEND_H - - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* The extensions don't need to be integrated at compile time into the */ - /* engine, only at link time. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Initializer */ - /* */ - /* */ - /* Each new face object can have several extensions associated with */ - /* it at creation time. This function is used to initialize given */ - /* extension data for a given face. */ - /* */ - /* */ - /* ext :: A typeless pointer to the extension data. */ - /* */ - /* face :: A handle to the source face object the extension is */ - /* associated with. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* In case of error, the initializer should not destroy the extension */ - /* data, as the finalizer will get called later by the function's */ - /* caller. */ - /* */ - typedef FT_Error (*FT_Extension_Initializer)( void* ext, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Finalizer */ - /* */ - /* */ - /* Each new face object can have several extensions associated with */ - /* it at creation time. This function is used to finalize given */ - /* extension data for a given face; it occurs before the face object */ - /* itself is finalized. */ - /* */ - /* */ - /* ext :: A typeless pointer to the extension data. */ - /* */ - /* face :: A handle to the source face object the extension is */ - /* associated with. */ - /* */ - typedef void (*FT_Extension_Finalizer)( void* ext, - FT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Extension_Class */ - /* */ - /* */ - /* A simple structure used to describe a given extension to the */ - /* FreeType base layer. An FT_Extension_Class is used as a parameter */ - /* for FT_Register_Extension(). */ - /* */ - /* */ - /* id :: The extension's ID. This is a normal C string that */ - /* is used to uniquely reference the extension's */ - /* interface. */ - /* */ - /* size :: The size in bytes of the extension data that must be */ - /* associated with each face object. */ - /* */ - /* init :: A pointer to the extension data's initializer. */ - /* */ - /* finalize :: A pointer to the extension data's finalizer. */ - /* */ - /* interface :: This pointer can be anything, but should usually */ - /* point to a table of function pointers which implement */ - /* the extension's interface. */ - /* */ - /* offset :: This field is set and used within the base layer and */ - /* should be set to 0 when registering an extension */ - /* through FT_Register_Extension(). It contains an */ - /* offset within the face's extension block for the */ - /* current extension's data. */ - /* */ - typedef struct FT_Extension_Class_ - { - const char* id; - FT_ULong size; - FT_Extension_Initializer init; - FT_Extension_Finalizer finalize; - void* interface; - - FT_ULong offset; - - } FT_Extension_Class; - - - FT_EXPORT_DEF( FT_Error ) FT_Register_Extension( - FT_Driver driver, - FT_Extension_Class* clazz ); - - -#ifdef FT_CONFIG_OPTION_EXTEND_ENGINE - - - /* Initialize the extension component */ - LOCAL_DEF - FT_Error FT_Init_Extensions( FT_Library library ); - - /* Finalize the extension component */ - LOCAL_DEF - FT_Error FT_Done_Extensions( FT_Library library ); - - /* Create an extension within a face object. Called by the */ - /* face object constructor. */ - LOCAL_DEF - FT_Error FT_Create_Extensions( FT_Face face ); - - /* Destroy all extensions within a face object. Called by the */ - /* face object destructor. */ - LOCAL_DEF - FT_Error FT_Destroy_Extensions( FT_Face face ); - - -#endif - - - /* return an extension's data & interface according to its ID */ - FT_EXPORT_DEF( void* ) FT_Get_Extension( - FT_Face face, - const char* extension_id, - void** extension_interface ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTEXTEND_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftlist.h b/subsys/win32k/freetype/include/freetype/internal/ftlist.h deleted file mode 100644 index 7c6d8ed..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftlist.h +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlist.c */ -/* */ -/* Generic list support for FreeType (specification). */ -/* */ -/* Copyright 1996-2000 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 implements functions relative to list processing. Its */ - /* data structures are defined in `freetype.h'. */ - /* */ - /*************************************************************************/ - - -#ifndef FTLIST_H -#define FTLIST_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - FT_EXPORT_DEF( FT_ListNode ) FT_List_Find( FT_List list, - void* data ); - - FT_EXPORT_DEF( void ) FT_List_Add( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Insert( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Remove( FT_List list, - FT_ListNode node ); - - FT_EXPORT_DEF( void ) FT_List_Up( FT_List list, - FT_ListNode node ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Iterator */ - /* */ - /* */ - /* An FT_List iterator function which is called during a list parse */ - /* by FT_List_Iterate(). */ - /* */ - /* */ - /* node :: The current iteration list node. */ - /* */ - /* user :: A typeless pointer passed to FT_List_Iterate(). */ - /* Can be used to point to the iteration's state. */ - /* */ - typedef FT_Error (*FT_List_Iterator)( FT_ListNode node, - void* user ); - - - FT_EXPORT_DEF( FT_Error ) FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Destructor */ - /* */ - /* */ - /* An FT_List iterator function which is called during a list */ - /* finalization by FT_List_Finalize() to destroy all elements in a */ - /* given list. */ - /* */ - /* */ - /* system :: The current system object. */ - /* */ - /* data :: The current object to destroy. */ - /* */ - /* user :: A typeless pointer passed to FT_List_Iterate(). It can */ - /* be used to point to the iteration's state. */ - /* */ - typedef void (*FT_List_Destructor)( FT_Memory memory, - void* data, - void* user ); - - - FT_EXPORT_DEF( void ) FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ); - - -#ifdef __cplusplus - } -#endif - -#endif /* FTLIST_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftmemory.h b/subsys/win32k/freetype/include/freetype/internal/ftmemory.h deleted file mode 100644 index da8d3a4..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftmemory.h +++ /dev/null @@ -1,127 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmemory.h */ -/* */ -/* The FreeType memory management macros (specification). */ -/* */ -/* Copyright 1996-2000 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 FTMEMORY_H -#define FTMEMORY_H - - -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* FT_SET_ERROR */ - /* */ - /* */ - /* This macro is used to set an implicit `error' variable to a given */ - /* expression's value (usually a function call), and convert it to a */ - /* boolean which is set whenever the value is != 0. */ - /* */ -#undef FT_SET_ERROR -#define FT_SET_ERROR( expression ) \ - ( ( error = (expression) ) != 0 ) - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M E M O R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - BASE_DEF( FT_Error ) FT_Alloc( FT_Memory memory, - FT_Long size, - void** P ); - - BASE_DEF( FT_Error ) FT_Realloc( FT_Memory memory, - FT_Long current, - FT_Long size, - void** P ); - - BASE_DEF( void ) FT_Free( FT_Memory memory, - void** P ); - - - - /* This `#include' is needed by the MEM_xxx() macros; it should be */ - /* available on all platforms we know of. */ -#include - -#define MEM_Set( dest, byte, count ) memset( dest, byte, count ) - -#define MEM_Copy( dest, source, count ) memcpy( dest, source, count ) - -#define MEM_Move( dest, source, count ) memmove( dest, source, count ) - - - /*************************************************************************/ - /* */ - /* We now support closures to produce completely reentrant code. This */ - /* means the allocation functions now takes an additional argument */ - /* (`memory'). It is a handle to a given memory object, responsible for */ - /* all low-level operations, including memory management and */ - /* synchronisation. */ - /* */ - /* In order to keep our code readable and use the same macros in the */ - /* font drivers and the rest of the library, MEM_Alloc(), ALLOC(), and */ - /* ALLOC_ARRAY() now use an implicit variable, `memory'. It must be */ - /* defined at all locations where a memory operation is queried. */ - /* */ -#define MEM_Alloc( _pointer_, _size_ ) \ - FT_Alloc( memory, _size_, (void**)&(_pointer_) ) - -#define MEM_Alloc_Array( _pointer_, _count_, _type_ ) \ - FT_Alloc( memory, (_count_)*sizeof ( _type_ ), \ - (void**)&(_pointer_) ) - -#define MEM_Realloc( _pointer_, _current_, _size_ ) \ - FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) ) - -#define MEM_Realloc_Array( _pointer_, _current_, _new_, _type_ ) \ - FT_Realloc( memory, (_current_)*sizeof ( _type_ ), \ - (_new_)*sizeof ( _type_ ), (void**)&(_pointer_) ) - -#define ALLOC( _pointer_, _size_ ) \ - FT_SET_ERROR( MEM_Alloc( _pointer_, _size_ ) ) - -#define REALLOC( _pointer_, _current_, _size_ ) \ - FT_SET_ERROR( MEM_Realloc( _pointer_, _current_, _size_ ) ) - -#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \ - FT_SET_ERROR( MEM_Alloc( _pointer_, \ - (_count_)*sizeof ( _type_ ) ) ) - -#define REALLOC_ARRAY( _pointer_, _current_, _count_, _type_ ) \ - FT_SET_ERROR( MEM_Realloc( _pointer_, \ - (_current_)*sizeof ( _type_ ), \ - (_count_)*sizeof ( _type_ ) ) ) - -#define FREE( _pointer_ ) FT_Free( memory, (void**)&(_pointer_) ) - - -#endif /* FTMEMORY_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftobjs.h b/subsys/win32k/freetype/include/freetype/internal/ftobjs.h deleted file mode 100644 index 0d0f5d8..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftobjs.h +++ /dev/null @@ -1,532 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.h */ -/* */ -/* The FreeType private base classes (specification). */ -/* */ -/* Copyright 1996-2000 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 contains the definition of all internal FreeType classes. */ - /* */ - /*************************************************************************/ - - -#ifndef FTOBJS_H -#define FTOBJS_H - -#include -#include -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* Some generic definitions. */ - /* */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL (void*)0 -#endif - -#ifndef UNUSED -#define UNUSED( arg ) ( (arg)=(arg) ) -#endif - - - /*************************************************************************/ - /* */ - /* 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 - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_ModuleRec */ - /* */ - /* */ - /* A module object instance. */ - /* */ - /* */ - /* clazz :: A pointer to the module's class. */ - /* */ - /* library :: A handle to the parent library object. */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ - /* generic :: A generic structure for user-level extensibility (?). */ - /* */ - typedef struct FT_ModuleRec_ - { - FT_Module_Class* clazz; - FT_Library library; - FT_Memory memory; - FT_Generic generic; - - } FT_ModuleRec; - - - /* typecast an object to a FT_Module */ -#define FT_MODULE( x ) ((FT_Module)(x)) -#define FT_MODULE_CLASS( x ) FT_MODULE(x)->clazz -#define FT_MODULE_LIBRARY( x ) FT_MODULE(x)->library -#define FT_MODULE_MEMORY( x ) FT_MODULE(x)->memory - -#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_font_driver ) - -#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_renderer ) - -#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_hinter ) - -#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ - ft_module_styler ) - -#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_scalable ) - -#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_no_outlines ) - -#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS(x)->module_flags & \ - ft_module_driver_has_hinter ) - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module_Interface */ - /* */ - /* */ - /* Finds a module and returns its specific interface as a typeless */ - /* pointer. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module-specific interface if available, 0 otherwise. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for, and what its interface is :-) */ - /* */ - BASE_DEF( const void* ) FT_Get_Module_Interface( FT_Library library, - const char* mod_name ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* a few macros used to perform easy typecasts with minimal brain damage */ - -#define FT_FACE( x ) ((FT_Face)(x)) -#define FT_SIZE( x ) ((FT_Size)(x)) -#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) - -#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver -#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library -#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory - -#define FT_SIZE_FACE( x ) FT_SIZE( x )->face -#define FT_SLOT_FACE( x ) FT_SLOT( x )->face - -#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph -#define FT_FACE_SIZE( x ) FT_FACE( x )->size - - - /* this must be kept exported -- tt will be used later in our own */ - /* high-level caching font manager called SemTex (way after the */ - /* 2.0 release though */ - FT_EXPORT_DEF( FT_Error ) FT_New_Size( FT_Face face, - FT_Size* size ); - - FT_EXPORT_DEF( FT_Error ) FT_Done_Size( FT_Size size ); - - - FT_EXPORT_DEF( FT_Error ) FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot* aslot ); - - FT_EXPORT_DEF( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** G L Y P H L O A D E R ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 - - - enum - { - ft_glyph_own_bitmap = 1 - }; - - - struct FT_SubGlyph_ - { - FT_Int index; - FT_UShort flags; - FT_Int arg1; - FT_Int arg2; - FT_Matrix transform; - }; - - - typedef struct FT_GlyphLoad_ - { - FT_Outline outline; /* outline */ - FT_UInt num_subglyphs; /* number of subglyphs */ - FT_SubGlyph* subglyphs; /* subglyphs */ - FT_Vector* extra_points; /* extra points table */ - - } FT_GlyphLoad; - - - struct FT_GlyphLoader_ - { - FT_Memory memory; - FT_UInt max_points; - FT_UInt max_contours; - FT_UInt max_subglyphs; - FT_Bool use_extra; - - FT_GlyphLoad base; - FT_GlyphLoad current; - - void* other; /* for possible future extension? */ - - }; - - - BASE_DEF( FT_Error ) FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader** aloader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Create_Extra( - FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Done( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Points( - FT_GlyphLoader* loader, - FT_UInt n_points, - FT_UInt n_contours ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Subglyphs( - FT_GlyphLoader* loader, - FT_UInt n_subs ); - - BASE_DEF( void ) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ); - - BASE_DEF( void ) FT_GlyphLoader_Add( FT_GlyphLoader* loader ); - - BASE_DEF( FT_Error ) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, - FT_GlyphLoader* source ); - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_RENDERER( x ) ((FT_Renderer)( x )) -#define FT_GLYPH( x ) ((FT_Glyph)( x )) -#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) -#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) - - - typedef struct FT_RendererRec_ - { - FT_ModuleRec root; - FT_Renderer_Class* clazz; - FT_Glyph_Format glyph_format; - const FT_Glyph_Class glyph_class; - - FT_Raster raster; - FT_Raster_Render_Func raster_render; - FTRenderer_render render; - - } FT_RendererRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F O N T D R I V E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* typecast a module into a driver easily */ -#define FT_DRIVER( x ) ((FT_Driver)(x)) - - /* typecast a module as a driver, and get its driver class */ -#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DriverRec */ - /* */ - /* */ - /* The root font driver class. A font driver is responsible for */ - /* managing and loading font files of a given format. */ - /* */ - /* */ - /* root :: Contains the fields of the root module class. */ - /* */ - /* clazz :: A pointer to the font driver's class. Note that */ - /* this is NOT root.clazz. `class' wasn't used */ - /* as it is a reserved word in C++. */ - /* */ - /* faces_list :: The list of faces currently opened by this */ - /* driver. */ - /* */ - /* extensions :: A typeless pointer to the driver's extensions */ - /* registry, if they are supported through the */ - /* configuration macro FT_CONFIG_OPTION_EXTENSIONS. */ - /* */ - /* glyph_loader :: The glyph loader for all faces managed by this */ - /* driver. This object isn't defined for unscalable */ - /* formats. */ - /* */ - typedef struct FT_DriverRec_ - { - FT_ModuleRec root; - FT_Driver_Class* clazz; - - FT_ListRec faces_list; - void* extensions; - - FT_GlyphLoader* glyph_loader; - - } FT_DriverRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R I E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define FT_DEBUG_HOOK_TRUETYPE 0 -#define FT_DEBUG_HOOK_TYPE1 1 - - - /*************************************************************************/ - /* */ - /* */ - /* FT_LibraryRec */ - /* */ - /* */ - /* The FreeType library class. This is the root of all FreeType */ - /* data. Use FT_New_Library() to create a library object, and */ - /* FT_Done_Library() to discard it and all child objects. */ - /* */ - /* */ - /* memory :: The library's memory object. Manages memory */ - /* allocation. */ - /* */ - /* generic :: Client data variable. Used to extend the */ - /* Library class by higher levels and clients. */ - /* */ - /* num_modules :: The number of modules currently registered */ - /* within this library. This is set to 0 for new */ - /* libraries. New modules are added through the */ - /* FT_Add_Module() API function. */ - /* */ - /* modules :: A table used to store handles to the currently */ - /* registered modules. Note that each font driver */ - /* contains a list of its opened faces. */ - /* */ - /* renderers :: The list of renderers currently registered */ - /* within the library. */ - /* */ - /* cur_renderer :: The current outline renderer. This is a */ - /* shortcut used to avoid parsing the list on */ - /* each call to FT_Outline_Render(). It is a */ - /* handle to the current renderer for the */ - /* ft_glyph_format_outline format. */ - /* */ - /* auto_hinter :: XXX */ - /* */ - /* raster_pool :: The raster object's render pool. This can */ - /* ideally be changed dynamically at run-time. */ - /* */ - /* raster_pool_size :: The size of the render pool in bytes. */ - /* */ - /* debug_hooks :: XXX */ - /* */ - typedef struct FT_LibraryRec_ - { - FT_Memory memory; /* library's memory manager */ - - FT_Generic generic; - - FT_UInt num_modules; - FT_Module modules[FT_MAX_MODULES]; /* module objects */ - - FT_ListRec renderers; /* list of renderers */ - FT_Renderer cur_renderer; /* current outline renderer */ - FT_Module auto_hinter; - - FT_Byte* raster_pool; /* scan-line conversion */ - /* render pool */ - FT_ULong raster_pool_size; /* size of render pool in bytes */ - - FT_DebugHook_Func debug_hooks[4]; - - } FT_LibraryRec; - - - BASE_DEF( FT_Renderer ) FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ); - - BASE_DEF( FT_Error ) FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_UInt render_mode ); - - typedef FT_Error (*FT_Glyph_Name_Requester)( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ); - - -#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM - - - FT_EXPORT_DEF( FT_Error ) FT_New_Stream( const char* filepathname, - FT_Stream astream ); - - FT_EXPORT_DEF( void ) FT_Done_Stream( FT_Stream stream ); - - FT_EXPORT_DEF( FT_Memory ) FT_New_Memory( void ); - - -#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ - - - /* Define default raster's interface. The default raster is located in */ - /* `src/base/ftraster.c' */ - /* */ - /* Client applications can register new rasters through the */ - /* FT_Set_Raster() API. */ - -#ifndef FT_NO_DEFAULT_RASTER - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; -#endif - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTOBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/ftstream.h b/subsys/win32k/freetype/include/freetype/internal/ftstream.h deleted file mode 100644 index 365f479..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/ftstream.h +++ /dev/null @@ -1,361 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.h */ -/* */ -/* Stream handling(specification). */ -/* */ -/* Copyright 1996-2000 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 FTSTREAM_H -#define FTSTREAM_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* format of an 8-bit frame_op value = [ xxxxx | e | s ] */ - /* s is set to 1 if the value is signed, */ - /* e is set to 1 if the value is little-endian */ - /* xxxxx is a command */ - -#define FT_FRAME_OP_SHIFT 2 -#define FT_FRAME_OP_SIGNED 1 -#define FT_FRAME_OP_LITTLE 2 -#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) - -#define FT_MAKE_FRAME_OP( command, little, sign ) \ - ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) - -#define FT_FRAME_OP_END 0 -#define FT_FRAME_OP_START 1 /* start a new frame */ -#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ -#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ -#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ -#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ -#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ - - - typedef enum FT_Frame_Op_ - { - ft_frame_end = 0, - ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), - - ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), - ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), - - ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), - ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), - ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), - ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), - - ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), - ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), - ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), - ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), - - ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), - ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), - ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), - ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), - - ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), - ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) - - } FT_Frame_Op; - - - typedef struct FT_Frame_Field_ - { - FT_Frame_Op value; - char size; - FT_UShort offset; - - } FT_Frame_Field; - - - /* make-up a FT_Frame_Field out of a structure type and a field name */ -#define FT_FIELD_REF( s, f ) (((s*)0)->f) - -#define FT_FRAME_FIELD( frame_op, struct_type, field ) \ - { \ - frame_op, \ - sizeof ( FT_FIELD_REF( struct_type,field ) ), \ - (FT_UShort)(char*)&FT_FIELD_REF( struct_type, field ) \ - } - -#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } - -#define FT_FRAME_START( s ) { ft_frame_start, 0, s } -#define FT_FRAME_END { ft_frame_end, 0, 0 } - -#define FT_FRAME_LONG( s, f ) FT_FRAME_FIELD( ft_frame_long_be, s, f ) -#define FT_FRAME_ULONG( s, f ) FT_FRAME_FIELD( ft_frame_ulong_be, s, f ) -#define FT_FRAME_SHORT( s, f ) FT_FRAME_FIELD( ft_frame_short_be, s, f ) -#define FT_FRAME_USHORT( s, f ) FT_FRAME_FIELD( ft_frame_ushort_be, s, f ) -#define FT_FRAME_BYTE( s, f ) FT_FRAME_FIELD( ft_frame_byte, s, f ) -#define FT_FRAME_CHAR( s, f ) FT_FRAME_FIELD( ft_frame_schar, s, f ) - -#define FT_FRAME_LONG_LE( s, f ) FT_FRAME_FIELD( ft_frame_long_le, s, f ) -#define FT_FRAME_ULONG_LE( s, f ) FT_FRAME_FIELD( ft_frame_ulong_le, s, f ) -#define FT_FRAME_SHORT_LE( s, f ) FT_FRAME_FIELD( ft_frame_short_le, s, f ) -#define FT_FRAME_USHORT_LE( s, f ) FT_FRAME_FIELD( ft_frame_ushort_le, s, f ) - -#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } -#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } -#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } - -#define FT_FRAME_BYTES( struct_type, field, count ) \ - { \ - ft_frame_bytes, \ - count, \ - (FT_UShort)(char*)&FT_FIELD_REF( struct_type, field ) \ - } -#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } - - - - /*************************************************************************/ - /* */ - /* integer extraction macros -- the `buffer' parameter must ALWAYS be of */ - /* type `char*' or equivalent (1-byte elements). */ - /* */ -#define NEXT_Char( buffer ) \ - ( (signed char)*buffer++ ) -#define NEXT_Byte( buffer ) \ - ( (unsigned char)*buffer++ ) - -#define NEXT_Short( buffer ) \ - ( buffer += 2, \ - ( (short)( (signed char)buffer[-2] << 8 ) | \ - (unsigned char)buffer[-1] ) ) - -#define NEXT_UShort( buffer ) \ - ( (unsigned short)NEXT_Short( buffer ) ) - -#define NEXT_Offset( buffer ) \ - ( buffer += 3, \ - ( ( (long)(signed char)buffer[-3] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-1] ) ) - -#define NEXT_UOffset( buffer ) \ - ( (unsigned long)NEXT_Offset( buffer ) ) - -#define NEXT_Long( buffer ) \ - ( buffer += 4, \ - ( ( (long)(signed char)buffer[-4] << 24 ) | \ - ( (long)(unsigned char)buffer[-3] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-1] ) ) - -#define NEXT_ULong( buffer ) \ - ( (unsigned long)NEXT_Long( buffer ) ) - - -#define NEXT_ShortLE( buffer ) \ - ( buffer += 2, \ - ( (short)( (signed char)buffer[-1] << 8 ) | \ - (unsigned char)buffer[-2] ) ) - -#define NEXT_UShortLE( buffer ) \ - ( (unsigned short)NEXT_ShortLE( buffer ) ) - -#define NEXT_OffsetLE( buffer ) \ - ( buffer += 3, \ - ( ( (long)(signed char)buffer[-1] << 16 ) | \ - ( (long)(unsigned char)buffer[-2] << 8 ) | \ - (long)(unsigned char)buffer[-3] ) ) - -#define NEXT_UOffsetLE( buffer ) \ - ( (unsigned long)NEXT_OffsetLE( buffer ) ) - - -#define NEXT_LongLE( buffer ) \ - ( buffer += 4, \ - ( ( (long)(signed char)buffer[-1] << 24 ) | \ - ( (long)(unsigned char)buffer[-2] << 16 ) | \ - ( (long)(unsigned char)buffer[-3] << 8 ) | \ - (long)(unsigned char)buffer[-4] ) ) - -#define NEXT_ULongLE( buffer ) \ - ( (unsigned long)NEXT_LongLE( buffer ) ) - - - /*************************************************************************/ - /* */ - /* Each GET_xxxx() macro uses an implicit `stream' variable. */ - /* */ -#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) - -#define GET_Char() FT_GET_MACRO( FT_Get_Char, FT_Char ) -#define GET_Byte() FT_GET_MACRO( FT_Get_Char, FT_Byte ) -#define GET_Short() FT_GET_MACRO( FT_Get_Short, FT_Short ) -#define GET_UShort() FT_GET_MACRO( FT_Get_Short, FT_UShort ) -#define GET_Offset() FT_GET_MACRO( FT_Get_Offset, FT_Long ) -#define GET_UOffset() FT_GET_MACRO( FT_Get_Offset, FT_ULong ) -#define GET_Long() FT_GET_MACRO( FT_Get_Long, FT_Long ) -#define GET_ULong() FT_GET_MACRO( FT_Get_Long, FT_ULong ) -#define GET_Tag4() FT_GET_MACRO( FT_Get_Long, FT_ULong ) - -#define GET_ShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_Short ) -#define GET_UShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_UShort ) -#define GET_LongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) -#define GET_ULongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) - -#define FT_READ_MACRO( func, type, var ) \ - ( var = (type)func( stream, &error ), \ - error != FT_Err_Ok ) - -#define READ_Byte( var ) FT_READ_MACRO( FT_Read_Char, FT_Byte, var ) -#define READ_Char( var ) FT_READ_MACRO( FT_Read_Char, FT_Char, var ) -#define READ_Short( var ) FT_READ_MACRO( FT_Read_Short, FT_Short, var ) -#define READ_UShort( var ) FT_READ_MACRO( FT_Read_Short, FT_UShort, var ) -#define READ_Offset( var ) FT_READ_MACRO( FT_Read_Offset, FT_Long, var ) -#define READ_UOffset( var ) FT_READ_MACRO( FT_Read_Offset, FT_ULong, var ) -#define READ_Long( var ) FT_READ_MACRO( FT_Read_Long, FT_Long, var ) -#define READ_ULong( var ) FT_READ_MACRO( FT_Read_Long, FT_ULong, var ) - -#define READ_ShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_Short, var ) -#define READ_UShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_UShort, var ) -#define READ_LongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_Long, var ) -#define READ_ULongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_ULong, var ) - - - BASE_DEF( void ) FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ); - - BASE_DEF( FT_Error ) FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ); - - BASE_DEF( FT_Error ) FT_Skip_Stream( FT_Stream stream, - FT_Long distance ); - - BASE_DEF( FT_Long ) FT_Stream_Pos( FT_Stream stream ); - - - BASE_DEF( FT_Error ) FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ); - - BASE_DEF( FT_Error ) FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ); - - BASE_DEF( FT_Error ) FT_Access_Frame( FT_Stream stream, - FT_ULong count ); - - BASE_DEF( void ) FT_Forget_Frame( FT_Stream stream ); - - BASE_DEF( FT_Error ) FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ); - - BASE_DEF( void ) FT_Release_Frame( FT_Stream stream, - FT_Byte** pbytes ); - - BASE_DEF( FT_Char ) FT_Get_Char( FT_Stream stream ); - - BASE_DEF( FT_Short ) FT_Get_Short( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_Offset( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_Long( FT_Stream stream ); - - BASE_DEF( FT_Short ) FT_Get_ShortLE( FT_Stream stream ); - - BASE_DEF( FT_Long ) FT_Get_LongLE( FT_Stream stream ); - - - BASE_DEF( FT_Char ) FT_Read_Char( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Short ) FT_Read_Short( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_Offset( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_Long( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Short ) FT_Read_ShortLE( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Long ) FT_Read_LongLE( FT_Stream stream, - FT_Error* error ); - - BASE_DEF( FT_Error ) FT_Read_Fields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ); - - -#define USE_Stream( resource, stream ) \ - FT_SET_ERROR( FT_Open_Stream( resource, stream ) ) - -#define DONE_Stream( stream ) \ - FT_Done_Stream( stream ) - - -#define ACCESS_Frame( size ) \ - FT_SET_ERROR( FT_Access_Frame( stream, size ) ) - -#define FORGET_Frame() \ - FT_Forget_Frame( stream ) - -#define EXTRACT_Frame( size, bytes ) \ - FT_SET_ERROR( FT_Extract_Frame( stream, size, \ - (FT_Byte**)&(bytes) ) ) - -#define RELEASE_Frame( bytes ) \ - FT_Release_Frame( stream, (FT_Byte**)&(bytes) ) - -#define FILE_Seek( position ) \ - FT_SET_ERROR( FT_Seek_Stream( stream, position ) ) - -#define FILE_Skip( distance ) \ - FT_SET_ERROR( FT_Skip_Stream( stream, distance ) ) - -#define FILE_Pos() \ - FT_Stream_Pos( stream ) - -#define FILE_Read( buffer, count ) \ - FT_SET_ERROR( FT_Read_Stream( stream, \ - (FT_Byte*)buffer, \ - count ) ) - -#define FILE_Read_At( position, buffer, count ) \ - FT_SET_ERROR( FT_Read_Stream_At( stream, \ - position, \ - (FT_Byte*)buffer, \ - count ) ) - -#define READ_Fields( fields, object ) \ - ( ( error = FT_Read_Fields( stream, fields, object ) ) != FT_Err_Ok ) - - -#ifdef __cplusplus - } -#endif - - -#endif /* FTSTREAM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/psnames.h b/subsys/win32k/freetype/include/freetype/internal/psnames.h deleted file mode 100644 index ed86235..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/psnames.h +++ /dev/null @@ -1,220 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.h */ -/* */ -/* High-level interface for the `PSNames' module (in charge of */ -/* various functions related to Postscript glyph names conversion). */ -/* */ -/* Copyright 1996-2000 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 PSNAMES_H -#define PSNAMES_H - - -#include - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicode_Value_Func */ - /* */ - /* */ - /* A function used to return the Unicode index corresponding to a */ - /* given glyph name. */ - /* */ - /* */ - /* glyph_name :: The glyph name. */ - /* */ - /* */ - /* The Unicode character index resp. the non-Unicode value 0xFFFF if */ - /* the glyph name has no known Unicode meaning. */ - /* */ - /* */ - /* This function is able to map several different glyph names to the */ - /* same Unicode value, according to the rules defined in the Adobe */ - /* Glyph List table. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_ULong (*PS_Unicode_Value_Func)( const char* glyph_name ); - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicode_Index_Func */ - /* */ - /* */ - /* A function used to return the glyph index corresponding to a given */ - /* Unicode value. */ - /* */ - /* */ - /* num_glyphs :: The number of glyphs in the face. */ - /* */ - /* glyph_names :: An array of glyph name pointers. */ - /* */ - /* unicode :: The Unicode value. */ - /* */ - /* */ - /* The glyph index resp. 0xFFFF if no glyph corresponds to this */ - /* Unicode value. */ - /* */ - /* */ - /* This function is able to recognize several glyph names per Unicode */ - /* value, according to the Adobe Glyph List. */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is undefined. */ - /* */ - typedef FT_UInt (*PS_Unicode_Index_Func)( FT_UInt num_glyphs, - const char** glyph_names, - FT_ULong unicode ); - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Macintosh_Name_Func */ - /* */ - /* */ - /* A function used to return the glyph name corresponding to an Apple */ - /* glyph name index. */ - /* */ - /* */ - /* name_index :: The index of the Mac name. */ - /* */ - /* */ - /* The glyph name, or 0 if the index is invalid. */ - /* */ - /* */ - /* This function will not be compiled if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef const char* (*PS_Macintosh_Name_Func)( FT_UInt name_index ); - - - typedef const char* (*PS_Adobe_Std_Strings_Func)( FT_UInt string_index ); - - - typedef struct PS_UniMap_ - { - FT_UInt unicode; - FT_UInt glyph_index; - - } PS_UniMap; - - - /*************************************************************************/ - /* */ - /* */ - /* PS_Unicodes */ - /* */ - /* */ - /* A simple table used to map Unicode values to glyph indices. It is */ - /* built by the PS_Build_Unicodes table according to the glyphs */ - /* present in a font file. */ - /* */ - /* */ - /* num_codes :: The number of glyphs in the font that match a given */ - /* Unicode value. */ - /* */ - /* unicodes :: An array of unicode values, sorted in increasing */ - /* order. */ - /* */ - /* gindex :: An array of glyph indices, corresponding to each */ - /* Unicode value. */ - /* */ - /* */ - /* Use the function PS_Lookup_Unicode() to retrieve the glyph index */ - /* corresponding to a given Unicode character code. */ - /* */ - typedef struct PS_Unicodes_ - { - FT_UInt num_maps; - PS_UniMap* maps; - - } PS_Unicodes; - - - typedef FT_Error (*PS_Build_Unicodes_Func)( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* unicodes ); - - typedef FT_UInt (*PS_Lookup_Unicode_Func)( PS_Unicodes* unicodes, - FT_UInt unicode ); - - - /*************************************************************************/ - /* */ - /* */ - /* PSNames_Interface */ - /* */ - /* */ - /* This structure defines the PSNames interface. */ - /* */ - /* */ - /* unicode_value :: A function used to convert a glyph name */ - /* into a Unicode character code. */ - /* */ - /* build_unicodes :: A function which builds up the Unicode */ - /* mapping table. */ - /* */ - /* lookup_unicode :: A function used to return the glyph index */ - /* corresponding to a given Unicode */ - /* character. */ - /* */ - /* macintosh_name :: A function used to return the standard */ - /* Apple glyph Postscript name corresponding */ - /* to a given string index (used by the */ - /* TrueType `post' table). */ - /* */ - /* adobe_std_strings :: A function that returns a pointer to a */ - /* Adobe Standard String for a given SID. */ - /* */ - /* adobe_std_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Standard */ - /* Encoding to SIDs. */ - /* */ - /* adobe_expert_encoding :: A table of 256 unsigned shorts that maps */ - /* character codes in the Adobe Expert */ - /* Encoding to SIDs. */ - /* */ - /* */ - /* `unicode_value' and `unicode_index' will be set to 0 if the */ - /* configuration macro FT_CONFIG_OPTION_ADOBE_GLYPH_LIST is */ - /* undefined. */ - /* */ - /* `macintosh_name' will be set to 0 if the configuration macro */ - /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES is undefined. */ - /* */ - typedef struct PSNames_Interface_ - { - PS_Unicode_Value_Func unicode_value; - PS_Build_Unicodes_Func build_unicodes; - PS_Lookup_Unicode_Func lookup_unicode; - PS_Macintosh_Name_Func macintosh_name; - - PS_Adobe_Std_Strings_Func adobe_std_strings; - const unsigned short* adobe_std_encoding; - const unsigned short* adobe_expert_encoding; - - } PSNames_Interface; - - -#endif /* PSNAMES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/sfnt.h b/subsys/win32k/freetype/include/freetype/internal/sfnt.h deleted file mode 100644 index 380ee93..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/sfnt.h +++ /dev/null @@ -1,492 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.h */ -/* */ -/* High-level `sfnt' driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 SFNT_H -#define SFNT_H - - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Face_Func */ - /* */ - /* */ - /* First part of the SFNT face object initialization. This will find */ - /* the face in a SFNT file or collection, and load its format tag in */ - /* face->format_tag. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* Once the format tag has been validated by the font driver, it */ - /* should then call the TT_Load_Face_Func() callback to read the rest */ - /* of the SFNT tables in the object. */ - /* */ - typedef - FT_Error (*TT_Init_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Face_Func */ - /* */ - /* */ - /* Second part of the SFNT face object initialization. This will */ - /* load the common SFNT tables (head, OS/2, maxp, metrics, etc.) in */ - /* the face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* params :: Optional additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function must be called after TT_Init_Face_Func(). */ - /* */ - typedef - FT_Error (*TT_Load_Face_Func)( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Face_Func */ - /* */ - /* */ - /* A callback used to delete the common SFNT data from a face. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* This function does NOT destroy the face object. */ - /* */ - typedef - void (*TT_Done_Face_Func)( TT_Face face ); - - - typedef - FT_Module_Interface (*SFNT_Get_Interface_Func)( FT_Module module, - const char* interface ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SFNT_Header_Func */ - /* */ - /* */ - /* Loads the header of a SFNT font file. Supports collections. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ - /* */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType */ - /* collection'. */ - /* */ - /* This function checks that the header is valid by looking at the */ - /* values of `search_range', `entry_selector', and `range_shift'. */ - /* */ - typedef - FT_Error (*TT_Load_SFNT_Header_Func)( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Directory_Func */ - /* */ - /* */ - /* Loads the table directory into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be on the first byte after the 4-byte font */ - /* format tag. This is the case just after a call to */ - /* TT_Load_Format_Tag(). */ - /* */ - typedef - FT_Error (*TT_Load_Directory_Func)( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Any_Func */ - /* */ - /* */ - /* Loads any font table into client memory. */ - /* */ - /* */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The 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 :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* */ - /* buffer :: The address of target buffer. */ - /* */ - /* */ - /* TrueType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Any_Func)( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Image_Func */ - /* */ - /* */ - /* Loads a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* glyph_index :: The current glyph index. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* map :: The target pixmap. */ - /* */ - /* metrics :: A big sbit metrics structure for the glyph image. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ - typedef - FT_Error (*TT_Load_SBit_Image_Func)( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_PS_Name_Func */ - /* */ - /* */ - /* Gets the PostScript glyph name of a glyph. */ - /* */ - /* */ - /* index :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Get_PS_Name_Func)( TT_Face face, - FT_UInt index, - FT_String** PSname ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics_Func */ - /* */ - /* */ - /* Loads the horizontal or vertical header in a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Metrics_Func)( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Load_Func */ - /* */ - /* */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* stream :: A handle to the current stream object. */ - /* */ - /* */ - /* cmap :: A pointer to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - typedef - FT_Error (*TT_CharMap_Load_Func)( TT_Face face, - TT_CMapTable* cmap, - FT_Stream input ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Free_Func */ - /* */ - /* */ - /* Destroys a character mapping table. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_CharMap_Free_Func)( TT_Face face, - TT_CMapTable* cmap ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Table_Func */ - /* */ - /* */ - /* Loads a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function will use `face->goto_table' to seek the stream to */ - /* the start of the table. */ - /* */ - typedef - FT_Error (*TT_Load_Table_Func)( TT_Face face, - FT_Stream stream ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Table_Func */ - /* */ - /* */ - /* Frees a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - typedef - void (*TT_Free_Table_Func)( TT_Face face ); - - - /*************************************************************************/ - /* */ - /* */ - /* SFNT_Interface */ - /* */ - /* */ - /* This structure holds pointers to the functions used to load and */ - /* free the basic tables that are required in a `sfnt' font file. */ - /* */ - /* */ - /* Check the various xxx_Func() descriptions for details. */ - /* */ - typedef struct SFNT_Interface_ - { - TT_Goto_Table_Func goto_table; - - TT_Init_Face_Func init_face; - TT_Load_Face_Func load_face; - TT_Done_Face_Func done_face; - SFNT_Get_Interface_Func get_interface; - - TT_Load_Any_Func load_any; - TT_Load_SFNT_Header_Func load_sfnt_header; - TT_Load_Directory_Func load_directory; - - /* these functions are called by `load_face' but they can also */ - /* be called from external modules, if there is a need to do so */ - TT_Load_Table_Func load_header; - TT_Load_Metrics_Func load_metrics; - TT_Load_Table_Func load_charmaps; - TT_Load_Table_Func load_max_profile; - TT_Load_Table_Func load_os2; - TT_Load_Table_Func load_psnames; - - TT_Load_Table_Func load_names; - TT_Free_Table_Func free_names; - - /* optional tables */ - TT_Load_Table_Func load_hdmx; - TT_Free_Table_Func free_hdmx; - - TT_Load_Table_Func load_kerning; - TT_Load_Table_Func load_gasp; - TT_Load_Table_Func load_pclt; - - /* see `ttsbit.h' */ - TT_Load_Table_Func load_sbits; - TT_Load_SBit_Image_Func load_sbit_image; - TT_Free_Table_Func free_sbits; - - /* see `ttpost.h' */ - TT_Get_PS_Name_Func get_psname; - TT_Free_Table_Func free_psnames; - - /* see `ttcmap.h' */ - TT_CharMap_Load_Func load_charmap; - TT_CharMap_Free_Func free_charmap; - - } SFNT_Interface; - - -#endif /* SFNT_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/t1errors.h b/subsys/win32k/freetype/include/freetype/internal/t1errors.h deleted file mode 100644 index 58566d8..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/t1errors.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1errors.h */ -/* */ -/* Type 1 error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 T1ERRORS_H -#define T1ERRORS_H - - - /************************ error codes declaration **************/ - - /* The error codes are grouped into `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 T1_Err_Ok FT_Err_Ok - - /* ----------- high level API errors -------- */ - -#define T1_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define T1_Err_Invalid_Argument FT_Err_Invalid_Argument -#define T1_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define T1_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define T1_Err_Invalid_Size_Handle FT_Err_Invalid_Size_Handle -#define T1_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define T1_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define T1_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define T1_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define T1_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* ------------- internal errors ------------ */ - -#define T1_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define T1_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* ------------ general glyph outline errors ------ */ - -#define T1_Err_Invalid_Composite FT_Err_Invalid_Composite - -#define T1_Err_Syntax_Error FT_Err_Invalid_File_Format -#define T1_Err_Stack_Underflow FT_Err_Invalid_File_Format -#define T1_Err_Stack_Overflow FT_Err_Invalid_File_Format - - -#endif /* T1ERRORS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/t1types.h b/subsys/win32k/freetype/include/freetype/internal/t1types.h deleted file mode 100644 index 4d41a6b..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/t1types.h +++ /dev/null @@ -1,188 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1types.h */ -/* */ -/* Basic Type1/Type2 type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T1TYPES_H -#define T1TYPES_H - - -#include -#include - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Encoding */ - /* */ - /* */ - /* A structure modeling a custom encoding */ - /* */ - /* */ - /* num_chars :: The number of character codes in the encoding. */ - /* Usually 256. */ - /* */ - /* code_first :: The lowest valid character code in the encoding. */ - /* */ - /* code_last :: The highest valid character code in the encoding. */ - /* */ - /* char_index :: An array of corresponding glyph indices. */ - /* */ - /* char_name :: An array of corresponding glyph names. */ - /* */ - typedef struct T1_Encoding_ - { - FT_Int num_chars; - FT_Int code_first; - FT_Int code_last; - - FT_UShort* char_index; - FT_String** char_name; - - } T1_Encoding; - - - typedef enum T1_EncodingType_ - { - t1_encoding_none = 0, - t1_encoding_array, - t1_encoding_standard, - t1_encoding_expert - - } T1_EncodingType; - - - typedef struct T1_Font_ - { - - /* font info dictionary */ - T1_FontInfo font_info; - - /* private dictionary */ - T1_Private private_dict; - - /* top-level dictionary */ - FT_String* font_name; - - T1_EncodingType encoding_type; - T1_Encoding encoding; - - FT_Byte* subrs_block; - FT_Byte* charstrings_block; - FT_Byte* glyph_names_block; - - FT_Int num_subrs; - FT_Byte** subrs; - FT_Int* subrs_len; - - FT_Int num_glyphs; - FT_String** glyph_names; /* array of glyph names */ - FT_Byte** charstrings; /* array of glyph charstrings */ - FT_Int* charstrings_len; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - FT_BBox font_bbox; - FT_Long font_id; - - FT_Int stroke_width; - - } T1_Font; - - - typedef struct CID_Subrs_ - { - FT_UInt num_subrs; - FT_Byte** code; - - } CID_Subrs; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined normally in */ - /* `ttobjs.h'. */ - /* */ - /*************************************************************************/ - - typedef struct T1_FaceRec_* T1_Face; - typedef struct CID_FaceRec_* CID_Face; - - - typedef struct T1_FaceRec_ - { - FT_FaceRec root; - T1_Font type1; - void* psnames; - void* afm_data; - FT_CharMapRec charmaprecs[2]; - FT_CharMap charmaps[2]; - PS_Unicodes unicode_map; - - /* support for Multiple Masters fonts */ - T1_Blend* blend; - - } T1_FaceRec; - - - typedef struct CID_FaceRec_ - { - FT_FaceRec root; - void* psnames; - CID_Info cid; - void* afm_data; - CID_Subrs* subrs; - - } CID_FaceRec; - - -#endif /* T1TYPES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/t2errors.h b/subsys/win32k/freetype/include/freetype/internal/t2errors.h deleted file mode 100644 index d685220..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/t2errors.h +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2errors.h */ -/* */ -/* OpenType error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 T2ERRORS_H -#define T2ERRORS_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 T2_Err_Ok FT_Err_Ok - - /* High level API errors. */ - -#define T2_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define T2_Err_Invalid_Argument FT_Err_Invalid_Argument -#define T2_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define T2_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define T2_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle -#define T2_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define T2_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define T2_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define T2_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define T2_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* Internal errors. */ - -#define T2_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define T2_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* General glyph outline errors. */ - -#define T2_Err_Invalid_Composite FT_Err_Invalid_Composite - - /* 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 T2_Err_Invalid_Opcode 0x500 -#define T2_Err_Too_Few_Arguments 0x501 -#define T2_Err_Stack_Overflow 0x502 -#define T2_Err_Code_Overflow 0x503 -#define T2_Err_Bad_Argument 0x504 -#define T2_Err_Divide_By_Zero 0x505 -#define T2_Err_Storage_Overflow 0x506 -#define T2_Err_Cvt_Overflow 0x507 -#define T2_Err_Invalid_Reference 0x508 -#define T2_Err_Invalid_Distance 0x509 -#define T2_Err_Interpolate_Twilight 0x50A -#define T2_Err_Debug_OpCode 0x50B -#define T2_Err_ENDF_In_Exec_Stream 0x50C -#define T2_Err_Out_Of_CodeRanges 0x50D -#define T2_Err_Nested_DEFS 0x50E -#define T2_Err_Invalid_CodeRange 0x50F -#define T2_Err_Invalid_Displacement 0x510 -#define T2_Err_Execution_Too_Long 0x511 - -#define T2_Err_Too_Many_Instruction_Defs 0x512 -#define T2_Err_Too_Many_Function_Defs 0x513 - - /* Other TrueType specific error codes. */ - -#define T2_Err_Table_Missing 0x520 -#define T2_Err_Too_Many_Extensions 0x521 -#define T2_Err_Extensions_Unsupported 0x522 -#define T2_Err_Invalid_Extension_Id 0x523 - -#define T2_Err_No_Vertical_Data 0x524 - -#define T2_Err_Max_Profile_Missing 0x530 -#define T2_Err_Header_Table_Missing 0x531 -#define T2_Err_Horiz_Header_Missing 0x532 -#define T2_Err_Locations_Missing 0x533 -#define T2_Err_Name_Table_Missing 0x534 -#define T2_Err_CMap_Table_Missing 0x535 -#define T2_Err_Hmtx_Table_Missing 0x536 -#define T2_Err_OS2_Table_Missing 0x537 -#define T2_Err_Post_Table_Missing 0x538 - -#define T2_Err_Invalid_Horiz_Metrics 0x540 -#define T2_Err_Invalid_CharMap_Format 0x541 -#define T2_Err_Invalid_PPem 0x542 -#define T2_Err_Invalid_Vert_Metrics 0x543 - -#define T2_Err_Could_Not_Find_Context 0x550 - - -#endif /* T2ERRORS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/t2types.h b/subsys/win32k/freetype/include/freetype/internal/t2types.h deleted file mode 100644 index 033f315..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/t2types.h +++ /dev/null @@ -1,218 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2types.h */ -/* */ -/* Basic OpenType/CFF type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T2TYPES_H -#define T2TYPES_H - - -#include - - - /*************************************************************************/ - /* */ - /* */ - /* CFF_Index */ - /* */ - /* */ - /* A structure used to model a CFF Index table. */ - /* */ - /* */ - /* stream :: XXX */ - /* */ - /* count :: The number of elements in the index. */ - /* */ - /* off_size :: The size in bytes of object offsets in index. */ - /* */ - /* data_offset :: The position of first data byte in the index's */ - /* bytes. */ - /* */ - /* offsets :: XXX */ - /* */ - /* bytes :: If the index is loaded in memory, its bytes. */ - /* */ - typedef struct CFF_Index_ - { - FT_Stream stream; - FT_UInt count; - FT_Byte off_size; - FT_ULong data_offset; - - FT_ULong* offsets; - FT_Byte* bytes; - - } CFF_Index; - - - typedef struct CFF_Font_Dict_ - { - FT_UInt version; - FT_UInt notice; - FT_UInt copyright; - FT_UInt full_name; - FT_UInt family_name; - FT_UInt weight; - FT_Bool is_fixed_pitch; - FT_Fixed italic_angle; - FT_Pos underline_position; - FT_Pos underline_thickness; - FT_Int paint_type; - FT_Int charstring_type; - FT_Matrix font_matrix; - FT_ULong unique_id; - FT_BBox font_bbox; - FT_Pos stroke_width; - FT_ULong charset_offset; - FT_ULong encoding_offset; - FT_ULong charstrings_offset; - FT_ULong private_offset; - FT_ULong private_size; - FT_Long synthetic_base; - FT_UInt embedded_postscript; - FT_UInt base_font_name; - FT_UInt postscript; - - /* these should only be used for the top-level font dictionary */ - FT_UInt cid_registry; - FT_UInt cid_ordering; - FT_ULong cid_supplement; - - FT_Long cid_font_version; - FT_Long cid_font_revision; - FT_Long cid_font_type; - FT_Long cid_count; - FT_ULong cid_uid_base; - FT_ULong cid_fd_array_offset; - FT_ULong cid_fd_select_offset; - FT_UInt cid_font_name; - - } CFF_Font_Dict; - - - typedef struct CFF_Private_ - { - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Pos blue_values[14]; - FT_Pos other_blues[10]; - FT_Pos family_blues[14]; - FT_Pos family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Pos blue_shift; - FT_Pos blue_fuzz; - FT_Pos standard_width; - FT_Pos standard_height; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Pos snap_widths[13]; - FT_Pos snap_heights[13]; - FT_Bool force_bold; - FT_Fixed force_bold_threshold; - FT_Int lenIV; - FT_Int language_group; - FT_Fixed expansion_factor; - FT_Long initial_random_seed; - FT_ULong local_subrs_offset; - FT_Pos default_width; - FT_Pos nominal_width; - - } CFF_Private; - - - typedef struct CFF_FD_Select_ - { - FT_Byte format; - FT_UInt range_count; - - /* that's the table, taken from the file `as is' */ - FT_Byte* data; - FT_UInt data_size; - - /* small cache for format 3 only */ - FT_UInt cache_first; - FT_UInt cache_count; - FT_Byte cache_fd; - - } CFF_FD_Select; - - - /* A SubFont packs a font dict and a private dict together. They are */ - /* needed to support CID-keyed CFF fonts. */ - typedef struct CFF_SubFont_ - { - CFF_Font_Dict font_dict; - CFF_Private private_dict; - - CFF_Index local_subrs_index; - FT_UInt num_local_subrs; - FT_Byte** local_subrs; - - } CFF_SubFont; - - - /* maximum number of sub-fonts in a CID-keyed file */ -#define CFF_MAX_CID_FONTS 16 - - - typedef struct CFF_Font_ - { - FT_Stream stream; - FT_Memory memory; - FT_UInt num_faces; - FT_UInt num_glyphs; - - FT_Byte version_major; - FT_Byte version_minor; - FT_Byte header_size; - FT_Byte absolute_offsize; - - - CFF_Index name_index; - CFF_Index top_dict_index; - CFF_Index string_index; - CFF_Index global_subrs_index; - - /* we don't load the Encoding and CharSet tables */ - - CFF_Index charstrings_index; - CFF_Index font_dict_index; - CFF_Index private_index; - CFF_Index local_subrs_index; - - FT_String* font_name; - FT_UInt num_global_subrs; - FT_Byte** global_subrs; - - CFF_SubFont top_font; - FT_UInt num_subfonts; - CFF_SubFont* subfonts[CFF_MAX_CID_FONTS]; - - CFF_FD_Select fd_select; - - } CFF_Font; - - -#endif /* T2TYPES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/tterrors.h b/subsys/win32k/freetype/include/freetype/internal/tterrors.h deleted file mode 100644 index b53e9f3..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/tterrors.h +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* tterrors.h */ -/* */ -/* TrueType error ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 TTERRORS_H -#define TTERRORS_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 FT_Err_Ok - - /* High level API errors. */ - -#define TT_Err_Invalid_File_Format FT_Err_Invalid_File_Format -#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument -#define TT_Err_Invalid_Driver_Handle FT_Err_Invalid_Driver_Handle -#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle -#define TT_Err_Invalid_Instance_Handle FT_Err_Invalid_Size_Handle -#define TT_Err_Invalid_Glyph_Handle FT_Err_Invalid_Slot_Handle -#define TT_Err_Invalid_CharMap_Handle FT_Err_Invalid_CharMap_Handle -#define TT_Err_Invalid_Glyph_Index FT_Err_Invalid_Glyph_Index - -#define TT_Err_Unimplemented_Feature FT_Err_Unimplemented_Feature - -#define TT_Err_Invalid_Engine FT_Err_Invalid_Driver_Handle - - /* Internal errors. */ - -#define TT_Err_Out_Of_Memory FT_Err_Out_Of_Memory -#define TT_Err_Unlisted_Object FT_Err_Unlisted_Object - - /* General glyph outline errors. */ - -#define TT_Err_Too_Many_Ins FT_Err_Too_Many_Hints -#define TT_Err_Invalid_Composite FT_Err_Invalid_Composite - - /* 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 -#define TT_Err_Too_Many_Function_Defs 0x412 -#define TT_Err_Too_Many_Instruction_Defs 0x413 - - /* Other TrueType specific error codes. */ - -#define TT_Err_Table_Missing 0x420 -#define TT_Err_Too_Many_Extensions 0x421 -#define TT_Err_Extensions_Unsupported 0x422 -#define TT_Err_Invalid_Extension_Id 0x423 - -#define TT_Err_No_Vertical_Data 0x424 - -#define TT_Err_Max_Profile_Missing 0x430 -#define TT_Err_Header_Table_Missing 0x431 -#define TT_Err_Horiz_Header_Missing 0x432 -#define TT_Err_Locations_Missing 0x433 -#define TT_Err_Name_Table_Missing 0x434 -#define TT_Err_CMap_Table_Missing 0x435 -#define TT_Err_Hmtx_Table_Missing 0x436 -#define TT_Err_OS2_Table_Missing 0x437 -#define TT_Err_Post_Table_Missing 0x438 - -#define TT_Err_Invalid_Horiz_Metrics 0x440 -#define TT_Err_Invalid_CharMap_Format 0x441 -#define TT_Err_Invalid_PPem 0x442 -#define TT_Err_Invalid_Vert_Metrics 0x443 - -#define TT_Err_Could_Not_Find_Context 0x450 - - -#endif /* TTERRORS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/internal/tttypes.h b/subsys/win32k/freetype/include/freetype/internal/tttypes.h deleted file mode 100644 index 1fd43ce..0000000 --- a/subsys/win32k/freetype/include/freetype/internal/tttypes.h +++ /dev/null @@ -1,1582 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttypes.h */ -/* */ -/* Basic SFNT/TrueType type definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 TTTYPES_H -#define TTTYPES_H - - -#include - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TTC_Header */ - /* */ - /* */ - /* TrueType collection header. This table contains the offsets of */ - /* the font headers of each distinct TrueType face in the file. */ - /* */ - /* */ - /* tag :: Must be `ttc ' to indicate a TrueType collection. */ - /* */ - /* version :: The version number. */ - /* */ - /* count :: The number of faces in the collection. The */ - /* specification says this should be an unsigned long, but */ - /* we use a signed long since we need the value -1 for */ - /* specific purposes. */ - /* */ - /* offsets :: The offsets of the font headers, one per face. */ - /* */ - typedef struct TTC_Header_ - { - FT_ULong tag; - FT_Fixed version; - FT_Long count; - FT_ULong* offsets; - - } TTC_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* SFNT_Header */ - /* */ - /* */ - /* SFNT file format header. */ - /* */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of tables in file. */ - /* */ - /* search_range :: Must be 16*(max power of 2 <= num_tables). */ - /* */ - /* entry_selector :: Must be log2 of search_range/16. */ - /* */ - /* range_shift :: Must be num_tables*16 - search_range. */ - /* */ - typedef struct SFNT_Header_ - { - FT_ULong format_tag; - FT_UShort num_tables; - FT_UShort search_range; - FT_UShort entry_selector; - FT_UShort range_shift; - - } SFNT_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_TableDir */ - /* */ - /* */ - /* This structure models a TrueType table directory. It is used to */ - /* access the various tables of the font face. */ - /* */ - /* */ - /* version :: The version number; starts with 0x00010000. */ - /* */ - /* numTables :: The number of tables. */ - /* */ - /* searchRange :: Unused. */ - /* */ - /* entrySelector :: Unused. */ - /* */ - /* rangeShift :: Unused. */ - /* */ - /* */ - /* This structure is only used during font opening. */ - /* */ - typedef struct TT_TableDir_ - { - FT_Fixed version; /* should be 0x10000 */ - FT_UShort numTables; /* number of tables */ - - FT_UShort searchRange; /* These parameters are only used */ - FT_UShort entrySelector; /* for a dichotomy search in the */ - FT_UShort rangeShift; /* directory. We ignore them. */ - - } TT_TableDir; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Table */ - /* */ - /* */ - /* This structure describes a given table of a TrueType font. */ - /* */ - /* */ - /* Tag :: A four-bytes tag describing the table. */ - /* */ - /* CheckSum :: The table checksum. This value can be ignored. */ - /* */ - /* Offset :: The offset of the table from the start of the TrueType */ - /* font in its resource. */ - /* */ - /* Length :: The table length (in bytes). */ - /* */ - typedef struct TT_Table_ - { - FT_ULong Tag; /* table type */ - FT_ULong CheckSum; /* table checksum */ - FT_ULong Offset; /* table file offset */ - FT_ULong Length; /* table length */ - - } TT_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CMapDir */ - /* */ - /* */ - /* This structure describes the directory of the `cmap' table, */ - /* containing the font's character mappings table. */ - /* */ - /* */ - /* tableVersionNumber :: The version number. */ - /* */ - /* numCMaps :: The number of charmaps in the font. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDir_ - { - FT_UShort tableVersionNumber; - FT_UShort numCMaps; - - } TT_CMapDir; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CMapDirEntry */ - /* */ - /* */ - /* This structure describes a charmap in a TrueType font. */ - /* */ - /* */ - /* platformID :: An ID used to specify for which platform this */ - /* charmap is defined (FreeType manages all platforms). */ - /* */ - /* encodingID :: A platform-specific ID used to indicate which source */ - /* encoding is used in this charmap. */ - /* */ - /* offset :: The offset of the charmap relative to the start of */ - /* the `cmap' table. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_CMapDirEntry_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_Long offset; - - } TT_CMapDirEntry; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_LongMetrics */ - /* */ - /* */ - /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ - /* TrueType tables. The values are expressed in font units. */ - /* */ - /* */ - /* advance :: The advance width or height for the glyph. */ - /* */ - /* bearing :: The left-side or top-side bearing for the glyph. */ - /* */ - typedef struct TT_LongMetrics_ - { - FT_UShort advance; - FT_Short bearing; - - } TT_LongMetrics; - - - /*************************************************************************/ - /* */ - /* TT_ShortMetrics */ - /* */ - /* */ - /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ - /* tables. */ - /* */ - typedef FT_Short TT_ShortMetrics; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_NameRec */ - /* */ - /* */ - /* A structure modeling TrueType name records. Name records are used */ - /* to store important strings like family name, style name, */ - /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ - /* etc). */ - /* */ - /* */ - /* platformID :: The ID of the name's encoding platform. */ - /* */ - /* encodingID :: The platform-specific ID for the name's encoding. */ - /* */ - /* languageID :: The platform-specific ID for the name's language. */ - /* */ - /* nameID :: The ID specifying what kind of name this is. */ - /* */ - /* stringLength :: The length of the string in bytes. */ - /* */ - /* stringOffset :: The offset to the string in the `name' table. */ - /* */ - /* string :: A pointer to the string's bytes. Note that these */ - /* are usually UTF-16 encoded characters. */ - /* */ - typedef struct TT_NameRec_ - { - FT_UShort platformID; - FT_UShort encodingID; - FT_UShort languageID; - FT_UShort nameID; - FT_UShort stringLength; - FT_UShort stringOffset; - - /* this last field is not defined in the spec */ - /* but used by the FreeType engine */ - - FT_Byte* string; - - } TT_NameRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_NameTable */ - /* */ - /* */ - /* A structure modeling the TrueType name table. */ - /* */ - /* */ - /* format :: The format of the name table. */ - /* */ - /* numNameRecords :: The number of names in table. */ - /* */ - /* storageOffset :: The offset of the name table in the `name' */ - /* TrueType table. */ - /* */ - /* names :: An array of name records. */ - /* */ - /* storage :: The names storage area. */ - /* */ - typedef struct TT_NameTable_ - { - FT_UShort format; - FT_UShort numNameRecords; - FT_UShort storageOffset; - TT_NameRec* names; - FT_Byte* storage; - - } TT_NameTable; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GaspRange */ - /* */ - /* */ - /* A tiny structure used to model a gasp range according to the */ - /* TrueType specification. */ - /* */ - /* */ - /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ - /* */ - /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ - /* modes to be used. */ - /* */ - typedef struct TT_GaspRange_ - { - FT_UShort maxPPEM; - FT_UShort gaspFlag; - - } TT_GaspRange; - - -#define TT_GASP_GRIDFIT 0x01 -#define TT_GASP_DOGRAY 0x02 - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Gasp */ - /* */ - /* */ - /* A structure modeling the TrueType `gasp' table used to specify */ - /* grid-fitting and anti-aliasing behaviour. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* numRanges :: The number of gasp ranges in table. */ - /* */ - /* gaspRanges :: An array of gasp ranges. */ - /* */ - typedef struct TT_Gasp_ - { - FT_UShort version; - FT_UShort numRanges; - TT_GaspRange* gaspRanges; - - } TT_Gasp; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_HdmxRec */ - /* */ - /* */ - /* A small structure used to model the pre-computed widths of a given */ - /* size. They are found in the `hdmx' table. */ - /* */ - /* */ - /* ppem :: The pixels per EM value at which these metrics apply. */ - /* */ - /* max_width :: The maximum advance width for this metric. */ - /* */ - /* widths :: An array of widths. Note: These are 8-bit bytes. */ - /* */ - typedef struct TT_HdmxRec_ - { - FT_Byte ppem; - FT_Byte max_width; - FT_Byte* widths; - - } TT_HdmxRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Hdmx */ - /* */ - /* */ - /* A structure used to model the `hdmx' table, which contains */ - /* pre-computed widths for a set of given sizes/dimensions. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* num_records :: The number of hdmx records. */ - /* */ - /* records :: An array of hdmx records. */ - /* */ - typedef struct TT_Hdmx_ - { - FT_UShort version; - FT_Short num_records; - TT_HdmxRec* records; - - } TT_Hdmx; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Kern_0_Pair */ - /* */ - /* */ - /* A structure used to model a kerning pair for the kerning table */ - /* format 0. The engine now loads this table if it finds one in the */ - /* font file. */ - /* */ - /* */ - /* left :: The index of the left glyph in pair. */ - /* */ - /* right :: The index of the right glyph in pair. */ - /* */ - /* value :: The kerning distance. A positive value spaces the */ - /* glyphs, a negative one makes them closer. */ - /* */ - typedef struct TT_Kern_0_Pair_ - { - FT_UShort left; /* index of left glyph in pair */ - FT_UShort right; /* index of right glyph in pair */ - FT_FWord value; /* kerning value */ - - } TT_Kern_0_Pair; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** EMBEDDED BITMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* 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' (Microsoft) or `bdat' (Apple) table. */ - /* */ - /* */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* horiBearingX :: The horizontal left bearing. */ - /* */ - /* horiBearingY :: The horizontal top bearing. */ - /* */ - /* horiAdvance :: The horizontal advance. */ - /* */ - /* vertBearingX :: The vertical left bearing. */ - /* */ - /* vertBearingY :: The vertical top bearing. */ - /* */ - /* vertAdvance :: The vertical advance. */ - /* */ - typedef struct TT_SBit_Metrics_ - { - FT_Byte height; - FT_Byte width; - - FT_Char horiBearingX; - FT_Char horiBearingY; - FT_Byte horiAdvance; - - FT_Char vertBearingX; - FT_Char vertBearingY; - FT_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' (Microsoft) or the `bdat' (Apple) table. */ - /* */ - /* */ - /* height :: The glyph height in pixels. */ - /* */ - /* width :: The glyph width in pixels. */ - /* */ - /* bearingX :: The left-side bearing. */ - /* */ - /* bearingY :: The top-side bearing. */ - /* */ - /* advance :: The advance width or height. */ - /* */ - typedef struct TT_SBit_Small_Metrics_ - { - FT_Byte height; - FT_Byte width; - - FT_Char bearingX; - FT_Char bearingY; - FT_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 a horizontal or vertical layout. */ - /* */ - /* */ - /* ascender :: The ascender in pixels. */ - /* */ - /* descender :: The descender in pixels. */ - /* */ - /* max_width :: The 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 */ - /* */ - /* horizontal advance - */ - /* ( horiBearingX + width ) */ - /* */ - /* resp. */ - /* */ - /* vertical advance - */ - /* ( vertBearingY + height ) */ - /* */ - /* max_before_BL :: Maximum of horiBearingY (resp. */ - /* vertBearingY). */ - /* */ - /* min_after_BL :: Minimum of */ - /* */ - /* horiBearingY - height */ - /* */ - /* resp. */ - /* */ - /* vertBearingX - width */ - /* */ - /* pads :: Unused (to make the size of the record */ - /* a multiple of 32 bits. */ - /* */ - typedef struct TT_SBit_Line_Metrics_ - { - FT_Char ascender; - FT_Char descender; - FT_Byte max_width; - FT_Char caret_slope_numerator; - FT_Char caret_slope_denominator; - FT_Char caret_offset; - FT_Char min_origin_SB; - FT_Char min_advance_SB; - FT_Char max_before_BL; - FT_Char min_after_BL; - FT_Char pads[2]; - - } TT_SBit_Line_Metrics; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Range */ - /* */ - /* */ - /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* */ - /* first_glyph :: The first glyph index in the range. */ - /* */ - /* last_glyph :: The last glyph index in the range. */ - /* */ - /* index_format :: The format of index table. Valid values are 1 */ - /* to 5. */ - /* */ - /* image_format :: The format of `EBDT' image data. */ - /* */ - /* image_offset :: The offset to image data in `EBDT'. */ - /* */ - /* image_size :: For index formats 2 and 5. This is the size in */ - /* bytes of each 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 :: The offset of the index table in the `EBLC' */ - /* table. Only used during strike loading. */ - /* */ - typedef struct TT_SBit_Range - { - FT_UShort first_glyph; - FT_UShort last_glyph; - - FT_UShort index_format; - FT_UShort image_format; - FT_ULong image_offset; - - FT_ULong image_size; - TT_SBit_Metrics metrics; - FT_ULong num_glyphs; - - FT_ULong* glyph_offsets; - FT_UShort* glyph_codes; - - FT_ULong table_offset; - - } TT_SBit_Range; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Strike */ - /* */ - /* */ - /* A structure used describe a given bitmap strike in the `EBLC' */ - /* (Microsoft) or `bloc' (Apple) tables. */ - /* */ - /* */ - /* num_index_ranges :: The number of index ranges. */ - /* */ - /* index_ranges :: An array of glyph index ranges. */ - /* */ - /* color_ref :: Unused. A color reference? */ - /* */ - /* hori :: The line metrics for horizontal layouts. */ - /* */ - /* vert :: The line metrics for vertical layouts. */ - /* */ - /* start_glyph :: The lowest glyph index for this strike. */ - /* */ - /* end_glyph :: The highest glyph index for this strike. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ - /* and 8. */ - /* */ - /* flags :: Is this a vertical or horizontal strike? */ - /* */ - typedef struct TT_SBit_Strike_ - { - FT_Int num_ranges; - TT_SBit_Range* sbit_ranges; - FT_ULong ranges_offset; - - FT_ULong color_ref; - - TT_SBit_Line_Metrics hori; - TT_SBit_Line_Metrics vert; - - FT_UShort start_glyph; - FT_UShort end_glyph; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte bit_depth; - FT_Char flags; - - } TT_SBit_Strike; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Component */ - /* */ - /* */ - /* A simple structure to describe a compound sbit element. */ - /* */ - /* */ - /* glyph_code :: The element's glyph index. */ - /* */ - /* x_offset :: The element's left bearing. */ - /* */ - /* y_offset :: The element's top bearing. */ - /* */ - typedef struct TT_SBit_Component_ - { - FT_UShort glyph_code; - - FT_Char x_offset; - FT_Char y_offset; - - } TT_SBit_Component; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_SBit_Scale */ - /* */ - /* */ - /* A structure used describe a given bitmap scaling table, as defined */ - /* in the `EBSC' table. */ - /* */ - /* */ - /* hori :: The horizontal line metrics. */ - /* */ - /* vert :: The vertical line metrics. */ - /* */ - /* x_ppem :: The number of horizontal pixels per EM. */ - /* */ - /* y_ppem :: The number of vertical pixels per EM. */ - /* */ - /* x_ppem_substitute :: Substitution x_ppem value. */ - /* */ - /* y_ppem_substitute :: Substitution y_ppem value. */ - /* */ - typedef struct TT_SBit_Scale_ - { - TT_SBit_Line_Metrics hori; - TT_SBit_Line_Metrics vert; - - FT_Byte x_ppem; - FT_Byte y_ppem; - - FT_Byte x_ppem_substitute; - FT_Byte y_ppem_substitute; - - } TT_SBit_Scale; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_20 */ - /* */ - /* */ - /* Postscript names sub-table, format 2.0. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* */ - /* num_glyphs :: The number of named glyphs in the table. */ - /* */ - /* num_names :: The number of PS names stored in the table. */ - /* */ - /* glyph_indices :: The indices of the glyphs in the names arrays. */ - /* */ - /* glyph_names :: The PS names not in Mac Encoding. */ - /* */ - typedef struct TT_Post_20_ - { - FT_UShort num_glyphs; - FT_UShort num_names; - FT_UShort* glyph_indices; - FT_Char** glyph_names; - - } TT_Post_20; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_25 */ - /* */ - /* */ - /* Postscript names sub-table, format 2.5. Stores the PS name of */ - /* each glyph in the font face. */ - /* */ - /* */ - /* num_glyphs :: The number of glyphs in the table. */ - /* */ - /* offsets :: An array of signed offsets in a normal Mac */ - /* Postscript name encoding. */ - /* */ - typedef struct TT_Post_25_ - { - FT_UShort num_glyphs; - FT_Char* offsets; - - } TT_Post_25; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Post_Names */ - /* */ - /* */ - /* Postscript names table, either format 2.0 or 2.5. */ - /* */ - /* */ - /* loaded :: A flag to indicate whether the PS names are loaded. */ - /* */ - /* format_20 :: The sub-table used for format 2.0. */ - /* */ - /* format_25 :: The sub-table used for format 2.5. */ - /* */ - typedef struct TT_Post_Names_ - { - FT_Bool loaded; - - union - { - TT_Post_20 format_20; - TT_Post_25 format_25; - - } names; - - } TT_Post_Names; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** TRUETYPE CHARMAPS SUPPORT ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* format 0 */ - - typedef struct TT_CMap0_ - { - FT_Byte* glyphIdArray; - - } TT_CMap0; - - - /* format 2 */ - - typedef struct TT_CMap2SubHeader_ - { - FT_UShort firstCode; /* first valid low byte */ - FT_UShort entryCount; /* number of valid low bytes */ - FT_Short idDelta; /* delta value to glyphIndex */ - FT_UShort idRangeOffset; /* offset from here to 1st code */ - - } TT_CMap2SubHeader; - - - typedef struct TT_CMap2_ - { - FT_UShort* subHeaderKeys; - /* high byte mapping table */ - /* value = subHeader index * 8 */ - - TT_CMap2SubHeader* subHeaders; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - } TT_CMap2; - - - /* format 4 */ - - typedef struct TT_CMap4Segment_ - { - FT_UShort endCount; - FT_UShort startCount; - FT_Short idDelta; - FT_UShort idRangeOffset; - - } TT_CMap4Segment; - - - typedef struct TT_CMap4_ - { - FT_UShort segCountX2; /* number of segments * 2 */ - FT_UShort searchRange; /* these parameters can be used */ - FT_UShort entrySelector; /* for a binary search */ - FT_UShort rangeShift; - - TT_CMap4Segment* segments; - FT_UShort* glyphIdArray; - FT_UShort numGlyphId; /* control value */ - - TT_CMap4Segment* last_segment; /* last used segment; this is a small */ - /* cache to potentially increase speed */ - } TT_CMap4; - - - /* format 6 */ - - typedef struct TT_CMap6_ - { - FT_UShort firstCode; /* first character code of subrange */ - FT_UShort entryCount; /* number of character codes in subrange */ - - FT_UShort* glyphIdArray; - - } TT_CMap6; - - - typedef struct TT_CMapTable_ TT_CMapTable; - - - typedef - FT_UInt (*TT_CharMap_Func)( TT_CMapTable* charmap, - FT_ULong char_code ); - - - /* charmap table */ - struct TT_CMapTable_ - { - FT_UShort platformID; - FT_UShort platformEncodingID; - FT_UShort format; - FT_UShort length; - FT_UShort version; - - FT_Bool loaded; - FT_ULong offset; - - union - { - TT_CMap0 cmap0; - TT_CMap2 cmap2; - TT_CMap4 cmap4; - TT_CMap6 cmap6; - } c; - - TT_CharMap_Func get_index; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMapRec */ - /* */ - /* */ - /* The TrueType character map object type. */ - /* */ - /* */ - /* root :: The parent character map structure. */ - /* */ - /* cmap :: The used character map. */ - /* */ - typedef struct TT_CharMapRec_ - { - FT_CharMapRec root; - TT_CMapTable cmap; - - } TT_CharMapRec; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** ***/ - /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ - /*** ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This structure/class is defined here because it is common to the */ - /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ - /* */ - /* Note, however, that the classes TT_Size, TT_GlyphSlot, and TT_CharMap */ - /* are not shared between font drivers, and are thus defined normally in */ - /* `ttobjs.h'. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Face */ - /* */ - /* */ - /* A handle to a TrueType face/font object. A TT_Face encapsulates */ - /* the resolution and scaling independent parts of a TrueType font */ - /* resource. */ - /* */ - /* */ - /* The TT_Face structure is also used as a `parent class' for the */ - /* OpenType-CFF class (T2_Face). */ - /* */ - typedef struct TT_FaceRec_* TT_Face; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap */ - /* */ - /* */ - /* A handle to a TrueType character mapping object. */ - /* */ - typedef struct TT_CharMapRec_* TT_CharMap; - - - /* a function type used for the truetype bytecode interpreter hooks */ - typedef FT_Error (*TT_Interpreter)( void* exec_context ); - - /* forward declaration */ - typedef struct TT_Loader_ TT_Loader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_Table_Func */ - /* */ - /* */ - /* Seeks a stream to the start of a given TrueType table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* tag :: A 4-byte tag used to name the table. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* length :: The length of the table in bytes. Set to 0 if not */ - /* needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - typedef - FT_Error (*TT_Goto_Table_Func)( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Access_Glyph_Frame_Func */ - /* */ - /* */ - /* Seeks a stream to the start of a given glyph element, and opens a */ - /* frame for it. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* glyph index :: The index of the glyph to access. */ - /* */ - /* offset :: The offset of the glyph according to the */ - /* `locations' table. */ - /* */ - /* byte_count :: The size of the frame in bytes. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function is normally equivalent to FILE_Seek(offset) */ - /* followed by ACCESS_Frame(byte_count) with the loader's stream, but */ - /* alternative formats (e.g. compressed ones) might use something */ - /* different. */ - /* */ - typedef - FT_Error (*TT_Access_Glyph_Frame_Func)( TT_Loader* loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Glyph_Element_Func */ - /* */ - /* */ - /* Reads one glyph element (its header, a simple glyph, or a */ - /* composite) from the loader's current stream frame. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - typedef - FT_Error (*TT_Load_Glyph_Element_Func)( TT_Loader* loader ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Forget_Glyph_Frame_Func */ - /* */ - /* */ - /* Closes the current loader stream frame for the glyph. */ - /* */ - /* */ - /* loader :: The current TrueType glyph loader object. */ - /* */ - typedef - void (*TT_Forget_Glyph_Frame_Func)( TT_Loader* loader ); - - - - /*************************************************************************/ - /* */ - /* TrueType Face Type */ - /* */ - /* */ - /* TT_Face */ - /* */ - /* */ - /* The TrueType face class. These objects model the resolution and */ - /* point-size independent data found in a TrueType font file. */ - /* */ - /* */ - /* root :: The base FT_Face structure, managed by the */ - /* base layer. */ - /* */ - /* ttc_header :: The TrueType collection header, used when */ - /* the file is a `ttc' rather than a `ttf'. */ - /* For ordinary font files, the field */ - /* `ttc_header.count' is set to 0. */ - /* */ - /* format_tag :: The font format tag. */ - /* */ - /* num_tables :: The number of TrueType tables in this font */ - /* file. */ - /* */ - /* dir_tables :: The directory of TrueType tables for this */ - /* font file. */ - /* */ - /* header :: The font's font header (`head' table). */ - /* Read on font opening. */ - /* */ - /* horizontal :: The font's horizontal header (`hhea' */ - /* table). This field also contains the */ - /* associated horizontal metrics table */ - /* (`hmtx'). */ - /* */ - /* max_profile :: The font's maximum profile table. Read on */ - /* font opening. Note that some maximum */ - /* values cannot be taken directly from this */ - /* table. We thus define additional fields */ - /* below to hold the computed maxima. */ - /* */ - /* max_components :: The maximum number of glyph components */ - /* required to load any composite glyph from */ - /* this font. Used to size the load stack. */ - /* */ - /* vertical_info :: A boolean which is set when the font file */ - /* contains vertical metrics. If not, the */ - /* value of the `vertical' field is */ - /* undefined. */ - /* */ - /* vertical :: The font's vertical header (`vhea' table). */ - /* This field also contains the associated */ - /* vertical metrics table (`vmtx'), if found. */ - /* IMPORTANT: The contents of this field is */ - /* undefined if the `verticalInfo' field is */ - /* unset. */ - /* */ - /* num_names :: The number of name records within this */ - /* TrueType font. */ - /* */ - /* name_table :: The table of name records (`name'). */ - /* */ - /* os2 :: The font's OS/2 table (`OS/2'). */ - /* */ - /* postscript :: The font's PostScript table (`post' */ - /* table). The PostScript glyph names are */ - /* not loaded by the driver on face opening. */ - /* See the `ttpost' module for more details. */ - /* */ - /* num_charmaps :: The number of character mappings in the */ - /* font. */ - /* */ - /* charmaps :: The array of charmap objects for this font */ - /* file. Note that this field is a typeless */ - /* pointer. The Reason is that the format of */ - /* charmaps varies with the underlying font */ - /* format and cannot be determined here. */ - /* */ - /* goto_table :: A function called by each TrueType table */ - /* loader to position a stream's cursor to */ - /* the start of a given table according to */ - /* its tag. It defaults to TT_Goto_Face but */ - /* can be different for strange formats (e.g. */ - /* Type 42). */ - /* */ - /* access_glyph_frame :: XXX */ - /* */ - /* read_glyph_header :: XXX */ - /* */ - /* read_simple_glyph :: XXX */ - /* */ - /* read_composite_glyph :: XXX */ - /* */ - /* forget_glyph_frame :: XXX */ - /* */ - /* sfnt :: A pointer to the SFNT `driver' interface. */ - /* */ - /* psnames :: A pointer to the `PSNames' module */ - /* interface. */ - /* */ - /* hdmx :: The face's horizontal device metrics */ - /* (`hdmx' table). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* gasp :: The grid-fitting and scaling properties */ - /* table (`gasp'). This table is optional in */ - /* TrueType/OpenType fonts. */ - /* */ - /* pclt :: XXX */ - /* */ - /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ - /* sizes, embedded in this font. */ - /* */ - /* sbit_strikes :: An array of sbit strikes embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* num_sbit_scales :: The number of sbit scales for this font. */ - /* */ - /* sbit_scales :: Array of sbit scales embedded in this */ - /* font. This table is optional in a */ - /* TrueType/OpenType font. */ - /* */ - /* postscript_names :: A table used to store the Postscript names */ - /* of the glyphs for this font. See the */ - /* file `ttconfig.h' for comments on the */ - /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ - /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* font_program_size :: Size in bytecodes of the face's font */ - /* program. 0 if none defined. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* font_program :: The face's font program (bytecode stream) */ - /* executed at load time, also used during */ - /* glyph rendering. Comes from the `fpgm' */ - /* table. Ignored for Type 2 font fonts. */ - /* */ - /* cvt_program_size :: The size in bytecodes of the face's cvt */ - /* program. Ignored for Type 2 fonts. */ - /* */ - /* cvt_program :: The face's cvt program (bytecode stream) */ - /* executed each time an instance/size is */ - /* changed/reset. Comes from the `prep' */ - /* table. Ignored for Type 2 fonts. */ - /* */ - /* cvt_size :: Size of the control value table (in */ - /* entries). Ignored for Type 2 fonts. */ - /* */ - /* cvt :: The face's original control value table. */ - /* Coordinates are expressed in unscaled font */ - /* units. Comes from the `cvt ' table. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. You should use */ - /* the `ttxkern' structures if you want to */ - /* access other kerning tables. Ignored */ - /* for Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Only used by the */ - /* ttxkern extension to avoid data */ - /* duplication. Ignored for Type 2 fonts. */ - /* */ - /* interpreter :: A pointer to the TrueType bytecode */ - /* interpreters field is also used to hook */ - /* the debugger in `ttdebug'. */ - /* */ - /* extra :: XXX */ - /* */ - typedef struct TT_FaceRec_ - { - FT_FaceRec root; - - TTC_Header ttc_header; - - FT_ULong format_tag; - FT_UShort num_tables; - TT_Table* dir_tables; - - TT_Header header; /* TrueType header table */ - TT_HoriHeader horizontal; /* TrueType horizontal header */ - - TT_MaxProfile max_profile; - FT_ULong max_components; - - FT_Bool vertical_info; - TT_VertHeader vertical; /* TT Vertical header, if present */ - - FT_Int num_names; /* number of name records */ - TT_NameTable name_table; /* name table */ - - TT_OS2 os2; /* TrueType OS/2 table */ - TT_Postscript postscript; /* TrueType Postscript table */ - - FT_Int num_charmaps; - TT_CharMap charmaps; /* array of TT_CharMapRec */ - - TT_Goto_Table_Func goto_table; - - TT_Access_Glyph_Frame_Func access_glyph_frame; - TT_Load_Glyph_Element_Func read_glyph_header; - TT_Load_Glyph_Element_Func read_simple_glyph; - TT_Load_Glyph_Element_Func read_composite_glyph; - TT_Forget_Glyph_Frame_Func forget_glyph_frame; - - /* a typeless pointer to the SFNT_Interface table used to load */ - /* the basic TrueType tables in the face object */ - void* sfnt; - - /* a typeless pointer to the PSNames_Interface table used to */ - /* handle glyph names <-> unicode & Mac values */ - void* psnames; - - /***********************************************************************/ - /* */ - /* Optional TrueType/OpenType tables */ - /* */ - /***********************************************************************/ - - /* horizontal device metrics */ - TT_Hdmx hdmx; - - /* grid-fitting and scaling table */ - TT_Gasp gasp; /* the `gasp' table */ - - /* PCL 5 table */ - TT_PCLT pclt; - - /* embedded bitmaps support */ - FT_Int num_sbit_strikes; - TT_SBit_Strike* sbit_strikes; - - FT_Int num_sbit_scales; - TT_SBit_Scale* sbit_scales; - - /* postscript names table */ - TT_Post_Names postscript_names; - - - /***********************************************************************/ - /* */ - /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ - /* */ - /***********************************************************************/ - - /* the glyph locations */ - FT_UShort num_locations; - FT_Long* glyph_locations; - - /* the font program, if any */ - FT_ULong font_program_size; - FT_Byte* font_program; - - /* the cvt program, if any */ - FT_ULong cvt_program_size; - FT_Byte* cvt_program; - - /* the original, unscaled, control value table */ - FT_ULong cvt_size; - FT_Short* cvt; - - /* the format 0 kerning table, if any */ - FT_Int num_kern_pairs; - FT_Int kern_table_index; - TT_Kern_0_Pair* kern_pairs; - - /* A pointer to the bytecode interpreter to use. This is also */ - /* used to hook the debugger for the `ttdebug' utility. */ - TT_Interpreter interpreter; - - - /***********************************************************************/ - /* */ - /* Other tables or fields. This is used by derivative formats like */ - /* OpenType. */ - /* */ - /***********************************************************************/ - - FT_Generic extra; - - } TT_FaceRec; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GlyphZone */ - /* */ - /* */ - /* A glyph zone is used to load, scale and hint glyph outline */ - /* coordinates. */ - /* */ - /* */ - /* memory :: A handle to the memory manager. */ - /* */ - /* max_points :: The maximal size in points of the zone. */ - /* */ - /* max_contours :: Max size in links contours of thez one. */ - /* */ - /* n_points :: The current number of points in the zone. */ - /* */ - /* n_contours :: The current number of contours in the zone. */ - /* */ - /* org :: The original glyph coordinates (font */ - /* units/scaled). */ - /* */ - /* cur :: The current glyph coordinates (scaled/hinted). */ - /* */ - /* tags :: The point control tags. */ - /* */ - /* contours :: The contours end points. */ - /* */ - typedef struct TT_GlyphZone_ - { - FT_Memory memory; - FT_UShort max_points; - FT_UShort max_contours; - FT_UShort n_points; /* number of points in zone */ - FT_Short n_contours; /* number of contours */ - - FT_Vector* org; /* original point coordinates */ - FT_Vector* cur; /* current point coordinates */ - - FT_Byte* tags; /* current touch flags */ - FT_UShort* contours; /* contour end points */ - - } TT_GlyphZone; - - - /* handle to execution context */ - typedef struct TT_ExecContextRec_* TT_ExecContext; - - /* glyph loader structure */ - struct TT_Loader_ - { - FT_Face face; - FT_Size size; - FT_GlyphSlot glyph; - FT_GlyphLoader* gloader; - - FT_ULong load_flags; - FT_UInt glyph_index; - - FT_Stream stream; - FT_Int byte_len; - - FT_Short n_contours; - FT_BBox bbox; - FT_Int left_bearing; - FT_Int advance; - FT_Bool preserve_pps; - FT_Vector pp1; - FT_Vector pp2; - - FT_ULong glyf_offset; - - /* the zone where we load our glyphs */ - TT_GlyphZone base; - TT_GlyphZone zone; - - TT_ExecContext exec; - FT_Byte* instructions; - FT_ULong ins_pos; - - /* for possible extensibility in other formats */ - void* other; - - }; - - -#endif /* TTTYPES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/t1tables.h b/subsys/win32k/freetype/include/freetype/t1tables.h deleted file mode 100644 index 323e013..0000000 --- a/subsys/win32k/freetype/include/freetype/t1tables.h +++ /dev/null @@ -1,235 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tables.h */ -/* */ -/* Basic Type 1/Type 2 tables definitions and interface (specification */ -/* only). */ -/* */ -/* Copyright 1996-2000 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 T1TABLES_H -#define T1TABLES_H - - -#include - - - /* Note that we separate font data in T1_FontInfo and T1_Private */ - /* structures in order to support Multiple Master fonts. */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_FontInfo */ - /* */ - /* */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own */ - /* FontInfo. */ - /* */ - typedef struct T1_FontInfo - { - FT_String* version; - FT_String* notice; - FT_String* full_name; - FT_String* family_name; - FT_String* weight; - FT_Long italic_angle; - FT_Bool is_fixed_pitch; - FT_Short underline_position; - FT_UShort underline_thickness; - - } T1_FontInfo; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Private */ - /* */ - /* */ - /* A structure used to model a Type1/Type2 FontInfo dictionary. Note */ - /* that for Multiple Master fonts, each instance has its own Private */ - /* dict. */ - /* */ - typedef struct T1_Private - { - FT_Int unique_id; - FT_Int lenIV; - - FT_Byte num_blue_values; - FT_Byte num_other_blues; - FT_Byte num_family_blues; - FT_Byte num_family_other_blues; - - FT_Short blue_values[14]; - FT_Short other_blues[10]; - - FT_Short family_blues [14]; - FT_Short family_other_blues[10]; - - FT_Fixed blue_scale; - FT_Int blue_shift; - FT_Int blue_fuzz; - - FT_UShort standard_width[1]; - FT_UShort standard_height[1]; - - FT_Byte num_snap_widths; - FT_Byte num_snap_heights; - FT_Bool force_bold; - FT_Bool round_stem_up; - - FT_Short snap_widths [13]; /* reserve one place for the std */ - FT_Short snap_heights[13]; /* reserve one place for the std */ - - FT_Long language_group; - FT_Long password; - - FT_Short min_feature[2]; - - } T1_Private; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Blend_Flags */ - /* */ - /* */ - /* A set of flags used to indicate which fields are present in a */ - /* given blen dictionary (font info or private). Used to support */ - /* Multiple Masters fonts. */ - /* */ - typedef enum - { - /* required fields in a FontInfo blend dictionary */ - t1_blend_underline_position = 0, - t1_blend_underline_thickness, - t1_blend_italic_angle, - - /* required fields in a Private blend dictionary */ - t1_blend_blue_values, - t1_blend_other_blues, - t1_blend_standard_width, - t1_blend_standard_height, - t1_blend_stem_snap_widths, - t1_blend_stem_snap_heights, - t1_blend_blue_scale, - t1_blend_blue_shift, - t1_blend_family_blues, - t1_blend_family_other_blues, - t1_blend_force_bold, - - /* never remove */ - t1_blend_max - - } T1_Blend_Flags; - - - /* maximum number of Multiple Masters designs, as defined in the spec */ -#define T1_MAX_MM_DESIGNS 16 - - /* maximum number of Multiple Masters axes, as defined in the spec */ -#define T1_MAX_MM_AXIS 4 - - /* maximum number of elements in a design map */ -#define T1_MAX_MM_MAP_POINTS 20 - - - /* this structure is used to store the BlendDesignMap entry for an axis */ - typedef struct T1_DesignMap_ - { - FT_Byte num_points; - FT_Fixed* design_points; - FT_Fixed* blend_points; - - } T1_DesignMap; - - - typedef struct T1_Blend_ - { - FT_UInt num_designs; - FT_UInt num_axis; - - FT_String* axis_names[T1_MAX_MM_AXIS]; - FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; - T1_DesignMap design_map[T1_MAX_MM_AXIS]; - - FT_Fixed* weight_vector; - FT_Fixed* default_weight_vector; - - T1_FontInfo* font_infos[T1_MAX_MM_DESIGNS + 1]; - T1_Private* privates [T1_MAX_MM_DESIGNS + 1]; - - FT_ULong blend_bitflags; - - } T1_Blend; - - - typedef struct CID_FontDict_ - { - T1_Private private_dict; - - FT_UInt len_buildchar; - FT_Fixed forcebold_threshold; - FT_Pos stroke_width; - FT_Fixed expansion_factor; - - FT_Byte paint_type; - FT_Byte font_type; - FT_Matrix font_matrix; - - FT_UInt num_subrs; - FT_ULong subrmap_offset; - FT_Int sd_bytes; - - } CID_FontDict; - - - typedef struct CID_Info_ - { - FT_String* cid_font_name; - FT_Fixed cid_version; - FT_Int cid_font_type; - - FT_String* registry; - FT_String* ordering; - FT_Int supplement; - - T1_FontInfo font_info; - FT_BBox font_bbox; - FT_ULong uid_base; - - FT_Int num_xuid; - FT_ULong xuid[16]; - - - FT_ULong cidmap_offset; - FT_Int fd_bytes; - FT_Int gd_bytes; - FT_ULong cid_count; - - FT_Int num_dicts; - CID_FontDict* font_dicts; - - FT_ULong data_offset; - - } CID_Info; - - -#endif /* T1TABLES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/ttnameid.h b/subsys/win32k/freetype/include/freetype/ttnameid.h deleted file mode 100644 index 4890242..0000000 --- a/subsys/win32k/freetype/include/freetype/ttnameid.h +++ /dev/null @@ -1,698 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttmakeid.h */ -/* */ -/* TrueType name ID definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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 TTNAMEID_H -#define TTNAMEID_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 /* deprecated */ -#define TT_PLATFORM_MICROSOFT 3 - - - /*************************************************************************/ - /* */ - /* Possible values of the platform specific encoding identifier field in */ - /* the name records of the TTF `name' table if the `platform' identifier */ - /* code is TT_PLATFORM_APPLE_UNICODE. */ - /* */ -#define TT_APPLE_ID_DEFAULT 0 -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ - - - /*************************************************************************/ - /* */ - /* Possible values of the platform specific encoding identifier field in */ - /* the name records of the TTF `name' table if 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 if the `platform' identifier */ - /* code is TT_PLATFORM_ISO. */ - /* */ - /* This use is now deprecated. */ - /* */ -#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 if 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 if 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_CYRILLIC_SCRIPT 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_MONGOLIAN_SCRIPT 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 - - -#if 0 /* these seem to be errors that have been dropped */ - -#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 -#define TT_MAC_LANGID_IRISH_GAELIC 141 - -#endif - - - /* The following codes are new as of 2000-03-10 */ -#define TT_MAC_LANGID_GALICIAN 140 -#define TT_MAC_LANGID_AFRIKAANS 141 -#define TT_MAC_LANGID_BRETON 142 -#define TT_MAC_LANGID_INUKTITUT 143 -#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 -#define TT_MAC_LANGID_MANX_GAELIC 145 -#define TT_MAC_LANGID_IRISH_GAELIC 146 -#define TT_MAC_LANGID_TONGAN 147 -#define TT_MAC_LANGID_GREEK_POLYTONIC 148 -#define TT_MAC_LANGID_GREELANDIC 149 -#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 - - - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if 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 - -/* The following code is new as of 2000-01-21 */ -#define TT_NAME_ID_SAMPLE_TEXT 19 - - - /*************************************************************************/ - /* */ - /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ - /* */ - /* Updated 02-Jul-2000. */ - /* */ - - /* General Scripts Area */ - - /* Bit 0 C0 Controls and Basic Latin */ -#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ - /* Bit 1 C1 Controls and Latin-1 Supplement */ -#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+00A0-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 + Extended Bopomofo */ -#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ - /* U+31A0-U+31BF */ - /* 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 + */ - /* CJK Radical Supplement + */ - /* Kangxi Radicals + */ - /* Ideographic Description + */ - /* CJK Unified Ideographs Extension A */ -#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ - /* U+2E80-U+2EFF */ - /* U+2F00-U+2FDF */ - /* U+2FF0-U+2FFF */ - /* U+34E0-U+4DB5 */ - - /* 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+FDFF */ - /* 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+FEFE */ - /* 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+FFF0-U+FFFD */ - /* Bit 70 Tibetan */ -#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FCF */ - /* Bit 71 Syriac */ -#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ - /* Bit 72 Thaana */ -#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ - /* Bit 73 Sinhala */ -#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ - /* Bit 74 Myanmar */ -#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ - /* Bit 75 Ethiopic */ -#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+12BF */ - /* Bit 76 Cherokee */ -#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ - /* Bit 77 Canadian Aboriginal Syllabics */ -#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+14DF */ - /* Bit 78 Ogham */ -#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ - /* Bit 79 Runic */ -#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ - /* Bit 80 Khmer */ -#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ - /* Bit 81 Mongolian */ -#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ - /* Bit 82 Braille */ -#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ - /* Bit 83 Yi + Yi Radicals */ -#define TT_UCR_YI (1L << 19) /* U+A000-U+A48C */ - /* U+A490-U+A4CF */ - - - /*************************************************************************/ - /* */ - /* 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 /* !HAVE_LIMIT_ON_IDENTS */ - - -#endif /* TTNAMEID_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/tttables.h b/subsys/win32k/freetype/include/freetype/tttables.h deleted file mode 100644 index 27c46f3..0000000 --- a/subsys/win32k/freetype/include/freetype/tttables.h +++ /dev/null @@ -1,583 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttables.h */ -/* */ -/* Basic SFNT/TrueType tables definitions and interface */ -/* (specification only). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Header */ - /* */ - /* */ - /* A structure used to model a TrueType font header table. All */ - /* fields follow the TrueType specification. */ - /* */ - typedef struct TT_Header_ - { - FT_Fixed Table_Version; - FT_Fixed Font_Revision; - - FT_Long CheckSum_Adjust; - FT_Long Magic_Number; - - FT_UShort Flags; - FT_UShort Units_Per_EM; - - FT_Long Created [2]; - FT_Long Modified[2]; - - FT_Short xMin; - FT_Short yMin; - FT_Short xMax; - FT_Short yMax; - - FT_UShort Mac_Style; - FT_UShort Lowest_Rec_PPEM; - - FT_Short Font_Direction; - FT_Short Index_To_Loc_Format; - FT_Short Glyph_Data_Format; - - } TT_Header; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_HoriHeader */ - /* */ - /* */ - /* A structure used to model a TrueType horizontal header, the `hhea' */ - /* table, as well as the corresponding horizontal metrics table, */ - /* i.e., the `hmtx' table. */ - /* */ - /* */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of all */ - /* glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoAscender' field */ - /* of the OS/2 table instead if you want */ - /* the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the distance */ - /* from the baseline to the bottom-most of */ - /* all glyph points found in the font. It */ - /* is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of the */ - /* glyphs found in the font (maybe ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Width_Max :: This field is the maximum of all advance */ - /* widths found in the font. It can be */ - /* used to compute the maximum width of an */ - /* arbitrary string of text. */ - /* */ - /* min_Left_Side_Bearing :: The minimum left side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Right_Side_Bearing :: The minimum right side bearing of all */ - /* glyphs within the font. */ - /* */ - /* xMax_Extent :: The maximum horizontal extent (i.e., the */ - /* `width' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* Reserved :: 10 reserved bytes. */ - /* */ - /* metric_Data_Format :: Always 0. */ - /* */ - /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ - /* table -- this value can be smaller than */ - /* the total number of glyphs in the font. */ - /* */ - /* long_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `hmtx' table. */ - /* */ - /* */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_HoriHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Width_Max; /* advance width maximum */ - - FT_Short min_Left_Side_Bearing; /* minimum left-sb */ - FT_Short min_Right_Side_Bearing; /* minimum right-sb */ - FT_Short xMax_Extent; /* xmax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_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' table. */ - - void* long_metrics; - void* short_metrics; - - } TT_HoriHeader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_VertHeader */ - /* */ - /* */ - /* A structure used to model a TrueType vertical header, the `vhea' */ - /* table, as well as the corresponding vertical metrics table, i.e., */ - /* the `vmtx' table. */ - /* */ - /* */ - /* Version :: The table version. */ - /* */ - /* Ascender :: The font's ascender, i.e., the distance */ - /* from the baseline to the top-most of */ - /* all glyph points found in the font. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoAscender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Descender :: The font's descender, i.e., the */ - /* distance from the baseline to the */ - /* bottom-most of all glyph points found */ - /* in the font. It is negative. */ - /* */ - /* This value is invalid in many fonts, as */ - /* it is usually set by the font designer, */ - /* and often reflects only a portion of */ - /* the glyphs found in the font (maybe */ - /* ASCII). */ - /* */ - /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ - /* */ - /* Line_Gap :: The font's line gap, i.e., the distance */ - /* to add to the ascender and descender to */ - /* get the BTB, i.e., the */ - /* baseline-to-baseline distance for the */ - /* font. */ - /* */ - /* advance_Height_Max :: This field is the maximum of all */ - /* advance heights found in the font. It */ - /* can be used to compute the maximum */ - /* height of an arbitrary string of text. */ - /* */ - /* min_Top_Side_Bearing :: The minimum top side bearing of all */ - /* glyphs within the font. */ - /* */ - /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ - /* glyphs within the font. */ - /* */ - /* yMax_Extent :: The maximum vertical extent (i.e., the */ - /* `height' of a glyph's bounding box) for */ - /* all glyphs in the font. */ - /* */ - /* caret_Slope_Rise :: The rise coefficient of the cursor's */ - /* slope of the cursor (slope=rise/run). */ - /* */ - /* caret_Slope_Run :: The run coefficient of the cursor's */ - /* slope. */ - /* */ - /* Reserved :: 10 reserved bytes. */ - /* */ - /* metric_Data_Format :: Always 0. */ - /* */ - /* number_Of_HMetrics :: Number of VMetrics entries in the */ - /* `vmtx' table -- this value can be */ - /* smaller than the total number of glyphs */ - /* in the font. */ - /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ - /* */ - /* */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields which */ - /* are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ - /* */ - typedef struct TT_VertHeader_ - { - FT_Fixed Version; - FT_Short Ascender; - FT_Short Descender; - FT_Short Line_Gap; - - FT_UShort advance_Height_Max; /* advance height maximum */ - - FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ - FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ - FT_Short yMax_Extent; /* xmax or ymax extents */ - FT_Short caret_Slope_Rise; - FT_Short caret_Slope_Run; - FT_Short caret_Offset; - - FT_Short Reserved[4]; - - FT_Short metric_Data_Format; - FT_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; - - } TT_VertHeader; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_OS2 */ - /* */ - /* */ - /* A structure used to model a TrueType OS/2 table. This is the long */ - /* table version. All fields comply to the TrueType specification. */ - /* */ - /* Note that we now support old Mac fonts which do not include an */ - /* OS/2 table. In this case, the `version' field is always set to */ - /* 0xFFFF. */ - /* */ - typedef struct TT_OS2_ - { - FT_UShort version; /* 0x0001 - more or 0xFFFF */ - FT_Short xAvgCharWidth; - FT_UShort usWeightClass; - FT_UShort usWidthClass; - FT_Short fsType; - FT_Short ySubscriptXSize; - FT_Short ySubscriptYSize; - FT_Short ySubscriptXOffset; - FT_Short ySubscriptYOffset; - FT_Short ySuperscriptXSize; - FT_Short ySuperscriptYSize; - FT_Short ySuperscriptXOffset; - FT_Short ySuperscriptYOffset; - FT_Short yStrikeoutSize; - FT_Short yStrikeoutPosition; - FT_Short sFamilyClass; - - FT_Byte panose[10]; - - FT_ULong ulUnicodeRange1; /* Bits 0-31 */ - FT_ULong ulUnicodeRange2; /* Bits 32-63 */ - FT_ULong ulUnicodeRange3; /* Bits 64-95 */ - FT_ULong ulUnicodeRange4; /* Bits 96-127 */ - - FT_Char achVendID[4]; - - FT_UShort fsSelection; - FT_UShort usFirstCharIndex; - FT_UShort usLastCharIndex; - FT_Short sTypoAscender; - FT_Short sTypoDescender; - FT_Short sTypoLineGap; - FT_UShort usWinAscent; - FT_UShort usWinDescent; - - /* only version 1 tables: */ - - FT_ULong ulCodePageRange1; /* Bits 0-31 */ - FT_ULong ulCodePageRange2; /* Bits 32-63 */ - - /* only version 2 tables: */ - - FT_Short sxHeight; - FT_Short sCapHeight; - FT_UShort usDefaultChar; - FT_UShort usBreakChar; - FT_UShort usMaxContext; - - } TT_OS2; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Postscript */ - /* */ - /* */ - /* A structure used to model a TrueType Postscript table. All fields */ - /* comply to the TrueType table. This structure does not reference */ - /* the Postscript glyph names, which can be nevertheless accessed */ - /* with the `ttpost' module. */ - /* */ - typedef struct TT_Postscript_ - { - FT_Fixed FormatType; - FT_Fixed italicAngle; - FT_Short underlinePosition; - FT_Short underlineThickness; - FT_ULong isFixedPitch; - FT_ULong minMemType42; - FT_ULong maxMemType42; - FT_ULong minMemType1; - FT_ULong maxMemType1; - - /* Glyph names follow in the file, but we don't */ - /* load them by default. See the ttpost.c file. */ - - } TT_Postscript; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_PCLT */ - /* */ - /* */ - /* A structure used to model a TrueType PCLT table. All fields */ - /* comply to the TrueType table. */ - /* */ - typedef struct TT_PCLT_ - { - FT_Fixed Version; - FT_ULong FontNumber; - FT_UShort Pitch; - FT_UShort xHeight; - FT_UShort Style; - FT_UShort TypeFamily; - FT_UShort CapHeight; - FT_UShort SymbolSet; - FT_Char TypeFace[16]; - FT_Char CharacterComplement[8]; - FT_Char FileName[6]; - FT_Char StrokeWeight; - FT_Char WidthType; - FT_Byte SerifStyle; - FT_Byte Reserved; - - } TT_PCLT; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_MaxProfile */ - /* */ - /* */ - /* The maximum profile is a table containing many max values which */ - /* can be used to pre-allocate arrays. This ensures that no memory */ - /* allocation occurs during a glyph load. */ - /* */ - /* */ - /* version :: The version number. */ - /* */ - /* numGlyphs :: The number of glyphs in this TrueType */ - /* font. */ - /* */ - /* maxPoints :: The maximum number of points in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositePoints'. */ - /* */ - /* maxContours :: The maximum number of contours in a */ - /* non-composite TrueType glyph. See also */ - /* the structure element */ - /* `maxCompositeContours'. */ - /* */ - /* maxCompositePoints :: The maximum number of points in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxPoints'. */ - /* */ - /* maxCompositeContours :: The maximum number of contours in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxContours'. */ - /* */ - /* maxZones :: The maximum number of zones used for */ - /* glyph hinting. */ - /* */ - /* maxTwilightPoints :: The maximum number of points in the */ - /* twilight zone used for glyph hinting. */ - /* */ - /* maxStorage :: The maximum number of elements in the */ - /* storage area used for glyph hinting. */ - /* */ - /* maxFunctionDefs :: The maximum number of function */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxInstructionDefs :: The maximum number of instruction */ - /* definitions in the TrueType bytecode for */ - /* this font. */ - /* */ - /* maxStackElements :: The maximum number of stack elements used */ - /* during bytecode interpretation. */ - /* */ - /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ - /* used for glyph hinting. */ - /* */ - /* maxComponentElements :: An obscure value related to composite */ - /* glyphs definitions. */ - /* */ - /* maxComponentDepth :: An obscure value related to composite */ - /* glyphs definitions. Probably the maximum */ - /* number of simple glyphs in a composite. */ - /* */ - /* */ - /* This structure is only used during font loading. */ - /* */ - typedef struct TT_MaxProfile_ - { - FT_Fixed version; - FT_UShort numGlyphs; - FT_UShort maxPoints; - FT_UShort maxContours; - FT_UShort maxCompositePoints; - FT_UShort maxCompositeContours; - FT_UShort maxZones; - FT_UShort maxTwilightPoints; - FT_UShort maxStorage; - FT_UShort maxFunctionDefs; - FT_UShort maxInstructionDefs; - FT_UShort maxStackElements; - FT_UShort maxSizeOfInstructions; - FT_UShort maxComponentElements; - FT_UShort maxComponentDepth; - - } TT_MaxProfile; - - - typedef enum - { - ft_sfnt_head = 0, - ft_sfnt_maxp = 1, - ft_sfnt_os2 = 2, - ft_sfnt_hhea = 3, - ft_sfnt_vhea = 4, - ft_sfnt_post = 5, - ft_sfnt_pclt = 6, - - sfnt_max /* don't remove */ - - } FT_Sfnt_Tag; - - - /* internal use only */ - typedef void* (*FT_Get_Sfnt_Table_Func)( FT_Face face, - FT_Sfnt_Tag tag ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Sfnt_Table */ - /* */ - /* */ - /* Returns a pointer to a given SFNT table within a face. */ - /* */ - /* */ - /* face :: A handle to the source. */ - /* */ - /* tag :: The index of the SFNT table. */ - /* */ - /* */ - /* A type-less pointer to the table. This will be 0 in case of */ - /* error, or if the corresponding table was not found *OR* loaded */ - /* from the file. */ - /* */ - /* */ - /* The table is owned by the face object and disappears with it. */ - /* */ - /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt/truetype/opentype drivers. See FT_Sfnt_tag for a */ - /* list. */ - /* */ - /* You can load any table using the (internal) SFNT_Interface */ - /* structure -- this is available via FT_Get_Module_Interface(). */ - /* */ - FT_EXPORT_DEF( void* ) FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ); - -#ifdef __cplusplus - } -#endif - - -#endif /* TTTABLES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/include/freetype/tttags.h b/subsys/win32k/freetype/include/freetype/tttags.h deleted file mode 100644 index 9de9810..0000000 --- a/subsys/win32k/freetype/include/freetype/tttags.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************/ -/* */ -/* tttags.h */ -/* */ -/* Tags for TrueType tables (specification only). */ -/* */ -/* Copyright 1996-2000 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 /* for MAKE_TT_TAG() */ - - -#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) -#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) -#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) -#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) -#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) -#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) -#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) -#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) -#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) -#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) -#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) -#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) -#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) -#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) -#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) -#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) -#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) -#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) -#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) -#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) -#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) -#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) -#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) -#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) -#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) -#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) -#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) -#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) -#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) -#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) -#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) -#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) -#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) -#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) -#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) -#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) - -#endif /* TTAGS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/license.txt b/subsys/win32k/freetype/license.txt deleted file mode 100644 index f14087b..0000000 --- a/subsys/win32k/freetype/license.txt +++ /dev/null @@ -1,164 +0,0 @@ - The FreeType Project LICENSE - ---------------------------- - - 2000-Feb-08 - - Copyright 1996-2000 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 have used the - FreeType code. (`credits') - - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering The FreeType Project and - assume no liability related to The FreeType Project. - - -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 Project, 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-2000 by David Turner, - Robert Wilhelm, and Werner Lemberg. All rights reserved except as - specified below. - -1. No Warranty --------------- - - THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS 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. - -2. Redistribution ------------------ - - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the FreeType Project (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: - - o Redistribution of source code must retain this license file - (`LICENSE.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 Project, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. - -3. Advertising --------------- - - Neither the FreeType authors and contributors nor you shall use - the name of the other for commercial, advertising, or promotional - purposes 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'. - - 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. - -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/subsys/win32k/freetype/src/autohint/.cvsignore b/subsys/win32k/freetype/src/autohint/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/autohint/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/autohint/CatharonLicense.txt b/subsys/win32k/freetype/src/autohint/CatharonLicense.txt deleted file mode 100644 index e68bc23..0000000 --- a/subsys/win32k/freetype/src/autohint/CatharonLicense.txt +++ /dev/null @@ -1,123 +0,0 @@ - The Catharon Open Source LICENSE - ---------------------------- - - 2000-Jul-04 - - Copyright (C) 2000 by Catharon Productions, Inc. - - - -Introduction -============ - - This license applies to source files distributed by Catharon - Productions, Inc. in several archive packages. This license - applies to all files found in such packages which do not fall - under their own explicit license. - - 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 - 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 have used the - Catharon Code. (`credits') - - We specifically permit and encourage the inclusion of this - software, with or without modifications, in commercial products. - We disclaim all warranties covering the packages distributed by - Catharon Productions, Inc. and assume no liability related to - their use. - - -Legal Terms -=========== - -0. Definitions --------------- - - Throughout this license, the terms `Catharon Package', `package', - and `Catharon Code' refer to the set of files originally - distributed by Catharon Productions, Inc. - - `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 one of the - Catharon Packages'. - - This license applies to all files distributed in the original - Catharon Package(s), 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 Catharon Packages are copyright (C) 2000 by Catharon - Productions, Inc. All rights reserved except as specified below. - -1. No Warranty --------------- - - THE CATHARON PACKAGES ARE PROVIDED `AS IS' WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESS 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 OF OR THE INABILITY TO - USE THE CATHARON PACKAGE. - -2. Redistribution ------------------ - - This license grants a worldwide, royalty-free, perpetual and - irrevocable right and license to use, execute, perform, compile, - display, copy, create derivative works of, distribute and - sublicense the Catharon Packages (in both source and object code - forms) and derivative works thereof for any purpose; and to - authorize others to exercise some or all of the rights granted - herein, subject to the following conditions: - - o Redistribution of source code must retain this license file - (`license.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 on the work of - Catharon Productions, Inc. in the distribution documentation. - - These conditions apply to any software derived from or based on - the Catharon Packages, not just the unmodified files. If you use - our work, you must acknowledge us. However, no fee need be paid - to us. - -3. Advertising --------------- - - Neither Catharon Productions, Inc. and contributors nor you shall - use the name of the other for commercial, advertising, or - promotional purposes without specific prior written permission. - - We suggest, but do not require, that you use the following phrase - to refer to this software in your documentation: 'this software is - based in part on the Catharon Typography Project'. - - As you have not signed this license, you are not required to - accept it. However, as the Catharon Packages are 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 Catharon - Packages, you indicate that you understand and accept all the - terms of this license. - ---- end of license.txt --- diff --git a/subsys/win32k/freetype/src/autohint/ahangles.c b/subsys/win32k/freetype/src/autohint/ahangles.c deleted file mode 100644 index d50dc5b..0000000 --- a/subsys/win32k/freetype/src/autohint/ahangles.c +++ /dev/null @@ -1,137 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahangles.h */ -/* */ -/* A routine used to compute vector angles with limited accuracy */ -/* and very high speed (body). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "ahangles.h" - -#else - -#include - -#endif - - - /* the following table has been automatically generated with */ - /* the `mather.py' Python script */ - - const AH_Angle ah_arctan[1L << AH_ATAN_BITS] = - { - 0, 0, 1, 1, 1, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 5, - 5, 5, 6, 6, 6, 7, 7, 7, - 8, 8, 8, 9, 9, 9, 10, 10, - 10, 10, 11, 11, 11, 12, 12, 12, - 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 17, 17, 17, - 18, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 21, 21, 22, 22, - 22, 23, 23, 23, 24, 24, 24, 24, - 25, 25, 25, 26, 26, 26, 26, 27, - 27, 27, 28, 28, 28, 28, 29, 29, - 29, 30, 30, 30, 30, 31, 31, 31, - 31, 32, 32, 32, 33, 33, 33, 33, - 34, 34, 34, 34, 35, 35, 35, 35, - 36, 36, 36, 36, 37, 37, 37, 38, - 38, 38, 38, 39, 39, 39, 39, 40, - 40, 40, 40, 41, 41, 41, 41, 42, - 42, 42, 42, 42, 43, 43, 43, 43, - 44, 44, 44, 44, 45, 45, 45, 45, - 46, 46, 46, 46, 46, 47, 47, 47, - 47, 48, 48, 48, 48, 48, 49, 49, - 49, 49, 50, 50, 50, 50, 50, 51, - 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 54, 54, - 54, 54, 54, 55, 55, 55, 55, 55, - 56, 56, 56, 56, 56, 57, 57, 57, - 57, 57, 57, 58, 58, 58, 58, 58, - 59, 59, 59, 59, 59, 59, 60, 60, - 60, 60, 60, 61, 61, 61, 61, 61, - 61, 62, 62, 62, 62, 62, 62, 63, - 63, 63, 63, 63, 63, 64, 64, 64 - }; - - - LOCAL_FUNC - AH_Angle ah_angle( FT_Vector* v ) - { - FT_Pos dx, dy; - AH_Angle angle; - - - dx = v->x; - dy = v->y; - - /* check trivial cases */ - if ( dy == 0 ) - { - angle = 0; - if ( dx < 0 ) - angle = AH_PI; - return angle; - } - else if ( dx == 0 ) - { - angle = AH_HALF_PI; - if ( dy < 0 ) - angle = -AH_HALF_PI; - return angle; - } - - angle = 0; - if ( dx < 0 ) - { - dx = -v->x; - dy = -v->y; - angle = AH_PI; - } - - if ( dy < 0 ) - { - FT_Pos tmp; - - - tmp = dx; - dx = -dy; - dy = tmp; - angle -= AH_HALF_PI; - } - - if ( dx == 0 && dy == 0 ) - return 0; - - if ( dx == dy ) - angle += AH_PI / 4; - else if ( dx > dy ) - angle += ah_arctan[FT_DivFix( dy, dx ) >> ( 16 - AH_ATAN_BITS )]; - else - angle += AH_HALF_PI - - ah_arctan[FT_DivFix( dx, dy ) >> ( 16 - AH_ATAN_BITS )]; - - if ( angle > AH_PI ) - angle -= AH_2PI; - - return angle; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahangles.h b/subsys/win32k/freetype/src/autohint/ahangles.h deleted file mode 100644 index 1df15d4..0000000 --- a/subsys/win32k/freetype/src/autohint/ahangles.h +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahangles.h */ -/* */ -/* A routine used to compute vector angles with limited accuracy */ -/* and very high speed (specification). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHANGLES_H -#define AHANGLES_H - - -#ifdef FT_FLAT_COMPILE - -#include "ahtypes.h" - -#else - -#include - -#endif - - -#include - - - /* PI expressed in ah_angles -- we don't really need an important */ - /* precision, so 256 should be enough */ -#define AH_PI 256 -#define AH_2PI ( AH_PI * 2 ) -#define AH_HALF_PI ( AH_PI / 2 ) -#define AH_2PIMASK ( AH_2PI - 1 ) - - /* the number of bits used to express an arc tangent; */ - /* see the structure of the lookup table */ -#define AH_ATAN_BITS 8 - - extern - const AH_Angle ah_arctan[1L << AH_ATAN_BITS]; - - - LOCAL_DEF - AH_Angle ah_angle( FT_Vector* v ); - - -#endif /* AHANGLES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahglobal.c b/subsys/win32k/freetype/src/autohint/ahglobal.c deleted file mode 100644 index 1ddc43f..0000000 --- a/subsys/win32k/freetype/src/autohint/ahglobal.c +++ /dev/null @@ -1,402 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahglobal.c */ -/* */ -/* Routines used to compute global metrics automatically (body). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "ahglobal.h" -#include "ahglyph.h" - -#else - -#include -#include - -#endif - - -#define MAX_TEST_CHARACTERS 12 - - static - const char* blue_chars[ah_blue_max] = - { - "THEZOCQS", - "HEZLOCUS", - "xzroesc", - "xzroesc", - "pqgjy" - }; - - - /* simple insertion sort */ - static - void sort_values( FT_Int count, - FT_Pos* table ) - { - FT_Int i, j, swap; - - - for ( i = 1; i < count; i++ ) - { - for ( j = i; j > 1; j-- ) - { - if ( table[j] > table[j - 1] ) - break; - - swap = table[j]; - table[j] = table[j - 1]; - table[j - 1] = swap; - } - } - } - - - static - FT_Error ah_hinter_compute_blues( AH_Hinter* hinter ) - { - AH_Blue blue; - AH_Globals* globals = &hinter->globals->design; - FT_Pos flats [MAX_TEST_CHARACTERS]; - FT_Pos rounds[MAX_TEST_CHARACTERS]; - FT_Int num_flats; - FT_Int num_rounds; - - FT_Face face; - FT_GlyphSlot glyph; - FT_Error error; - FT_CharMap charmap; - - - face = hinter->face; - glyph = face->glyph; - - /* save current charmap */ - charmap = face->charmap; - - /* do we have a Unicode charmap in there? */ - error = FT_Select_Charmap( face, ft_encoding_unicode ); - if ( error ) - goto Exit; - - /* we compute the blues simply by loading each character from the */ - /* 'blue_chars[blues]' string, then compute its top-most and */ - /* bottom-most points */ - - AH_LOG(( "blue zones computation\n" )); - AH_LOG(( "------------------------------------------------\n" )); - - for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ ) - { - const char* p = blue_chars[blue]; - const char* limit = p + MAX_TEST_CHARACTERS; - FT_Pos *blue_ref, *blue_shoot; - - - AH_LOG(( "blue %3d: ", blue )); - - num_flats = 0; - num_rounds = 0; - - for ( ; p < limit; p++ ) - { - FT_UInt glyph_index; - FT_Vector* extremum; - FT_Vector* points; - FT_Vector* point_limit; - FT_Vector* point; - FT_Bool round; - - - /* exit if we reach the end of the string */ - if ( !*p ) - break; - - AH_LOG(( "`%c'", *p )); - - /* load the character in the face -- skip unknown or empty ones */ - glyph_index = FT_Get_Char_Index( face, (FT_UInt)*p ); - if ( glyph_index == 0 ) - continue; - - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error || glyph->outline.n_points <= 0 ) - continue; - - /* now compute min or max point indices and coordinates */ - points = glyph->outline.points; - point_limit = points + glyph->outline.n_points; - point = points; - extremum = point; - point++; - - if ( AH_IS_TOP_BLUE( blue ) ) - { - for ( ; point < point_limit; point++ ) - if ( point->y > extremum->y ) - extremum = point; - } - else - { - for ( ; point < point_limit; point++ ) - if ( point->y < extremum->y ) - extremum = point; - } - - AH_LOG(( "%5d", (int)extremum->y )); - - /* now, check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then see its previous and next points */ - { - FT_Int index = extremum - points; - FT_Int n; - FT_Int first, last, prev, next, end; - FT_Pos dist; - - - last = -1; - first = 0; - - for ( n = 0; n < glyph->outline.n_contours; n++ ) - { - end = glyph->outline.contours[n]; - if ( end >= index ) - { - last = end; - break; - } - first = end + 1; - } - - /* XXX: should never happen! */ - if ( last < 0 ) - continue; - - /* now look for the previous and next points that are not on the */ - /* same Y coordinate. Threshold the `closeness'... */ - - prev = index; - next = prev; - - do - { - if ( prev > first ) - prev--; - else - prev = last; - - dist = points[prev].y - extremum->y; - if ( dist < -5 || dist > 5 ) - break; - - } while ( prev != index ); - - do - { - if ( next < last ) - next++; - else - next = first; - - dist = points[next].y - extremum->y; - if ( dist < -5 || dist > 5 ) - break; - - } while ( next != index ); - - /* now, set the `round' flag depending on the segment's kind */ - round = - FT_CURVE_TAG( glyph->outline.tags[prev] ) != FT_Curve_Tag_On || - FT_CURVE_TAG( glyph->outline.tags[next] ) != FT_Curve_Tag_On ; - - AH_LOG(( "%c ", round ? 'r' : 'f' )); - } - - if ( round ) - rounds[num_rounds++] = extremum->y; - else - flats[num_flats++] = extremum->y; - } - - AH_LOG(( "\n" )); - - /* we have computed the contents of the `rounds' and `flats' tables, */ - /* now determine the reference and overshoot position of the blue; */ - /* we simply take the median value after a simple short */ - sort_values( num_rounds, rounds ); - sort_values( num_flats, flats ); - - blue_ref = globals->blue_refs + blue; - blue_shoot = globals->blue_shoots + blue; - if ( num_flats == 0 && num_rounds == 0 ) - { - *blue_ref = -10000; - *blue_shoot = -10000; - } - else if ( num_flats == 0 ) - { - *blue_ref = - *blue_shoot = rounds[num_rounds / 2]; - } - else if ( num_rounds == 0 ) - { - *blue_ref = - *blue_shoot = flats[num_flats / 2]; - } - else - { - *blue_ref = flats[num_flats / 2]; - *blue_shoot = rounds[num_rounds / 2]; - } - - /* there are sometimes problems: if the overshoot position of top */ - /* zones is under its reference position, or the opposite for bottom */ - /* zones. We must thus check everything there and correct the errors */ - if ( *blue_shoot != *blue_ref ) - { - FT_Pos ref = *blue_ref; - FT_Pos shoot = *blue_shoot; - FT_Bool over_ref = ( shoot > ref ); - - - if ( AH_IS_TOP_BLUE( blue ) ^ over_ref ) - *blue_shoot = *blue_ref = ( shoot + ref ) / 2; - } - - AH_LOG(( "-- ref = %ld, shoot = %ld\n", *blue_ref, *blue_shoot )); - } - - /* reset original face charmap */ - FT_Set_Charmap( face, charmap ); - error = 0; - - Exit: - return error; - } - - - static - FT_Error ah_hinter_compute_widths( AH_Hinter* hinter ) - { - /* scan the array of segments in each direction */ - AH_Outline* outline = hinter->glyph; - AH_Segment* segments; - AH_Segment* limit; - AH_Globals* globals = &hinter->globals->design; - FT_Pos* widths; - FT_Int dimension; - FT_Int* p_num_widths; - FT_Error error = 0; - FT_Pos edge_distance_threshold = 32000; - - - globals->num_widths = 0; - globals->num_heights = 0; - - /* For now, compute the standard width and height from the `o' */ - /* character. I started computing the stem width of the `i' and the */ - /* stem height of the "-", but it wasn't too good. Moreover, we now */ - /* have a single character that gives us standard width and height. */ - { - FT_UInt glyph_index; - - - glyph_index = FT_Get_Char_Index( hinter->face, 'o' ); - if ( glyph_index == 0 ) - return 0; - - error = FT_Load_Glyph( hinter->face, glyph_index, FT_LOAD_NO_SCALE ); - if ( error ) - goto Exit; - - error = ah_outline_load( hinter->glyph, hinter->face ); - if ( error ) - goto Exit; - - ah_outline_compute_segments( hinter->glyph ); - ah_outline_link_segments( hinter->glyph ); - } - - segments = outline->horz_segments; - limit = segments + outline->num_hsegments; - widths = globals->heights; - p_num_widths = &globals->num_heights; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Segment* seg = segments; - AH_Segment* link; - FT_Int num_widths = 0; - - - for ( ; seg < limit; seg++ ) - { - link = seg->link; - /* we only consider stem segments there! */ - if ( link && link->link == seg && link > seg ) - { - FT_Int dist; - - - dist = seg->pos - link->pos; - if ( dist < 0 ) - dist = -dist; - - if ( num_widths < 12 ) - widths[num_widths++] = dist; - } - } - - sort_values( num_widths, widths ); - *p_num_widths = num_widths; - - /* we will now try to find the smallest width */ - if ( num_widths > 0 && widths[0] < edge_distance_threshold ) - edge_distance_threshold = widths[0]; - - segments = outline->vert_segments; - limit = segments + outline->num_vsegments; - widths = globals->widths; - p_num_widths = &globals->num_widths; - - } - - /* Now, compute the edge distance threshold as a fraction of the */ - /* smallest width in the font. Set it in `hinter.glyph' too! */ - if ( edge_distance_threshold == 32000 ) - edge_distance_threshold = 50; - - /* let's try 20% */ - hinter->glyph->edge_distance_threshold = edge_distance_threshold / 5; - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Error ah_hinter_compute_globals( AH_Hinter* hinter ) - { - return ah_hinter_compute_widths( hinter ) || - ah_hinter_compute_blues ( hinter ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahglobal.h b/subsys/win32k/freetype/src/autohint/ahglobal.h deleted file mode 100644 index 328bd89..0000000 --- a/subsys/win32k/freetype/src/autohint/ahglobal.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahglobal.h */ -/* */ -/* Routines used to compute global metrics automatically */ -/* (specification). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHGLOBAL_H -#define AHGLOBAL_H - -#ifdef FT_FLAT_COMPILE - -#include "ahtypes.h" - -#else - -#include - -#endif - - -#include /* for LOCAL_DEF/LOCAL_FUNC */ - - -#define AH_IS_TOP_BLUE( b ) ( (b) == ah_blue_capital_top || \ - (b) == ah_blue_small_top ) - - - /* compute global metrics automatically */ - LOCAL_DEF - FT_Error ah_hinter_compute_globals( AH_Hinter* hinter ); - - -#endif /* AHGLOBAL_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahglyph.c b/subsys/win32k/freetype/src/autohint/ahglyph.c deleted file mode 100644 index f7f011e..0000000 --- a/subsys/win32k/freetype/src/autohint/ahglyph.c +++ /dev/null @@ -1,1299 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahglyph.c */ -/* */ -/* Routines used to load and analyze a given glyph before hinting */ -/* (body). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "ahglyph.h" -#include "ahangles.h" -#include "ahglobal.h" - -#else - -#include -#include -#include - -#endif - - -#include - - -#define xxxAH_DEBUG_GLYPH - - - /* compute the direction value of a given vector.. */ - static - AH_Direction ah_compute_direction( FT_Pos dx, - FT_Pos dy ) - { - AH_Direction dir; - FT_Pos ax = ABS( dx ); - FT_Pos ay = ABS( dy ); - - - dir = ah_dir_none; - - /* test for vertical direction */ - if ( ax * 12 < ay ) - { - dir = dy > 0 ? ah_dir_up : ah_dir_down; - } - /* test for horizontal direction */ - else if ( ay * 12 < ax ) - { - dir = dx > 0 ? ah_dir_right : ah_dir_left; - } - - return dir; - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_new */ - /* */ - /* */ - /* Creates a new and empty AH_Outline object. */ - /* */ - LOCAL_FUNC - FT_Error ah_outline_new( FT_Memory memory, - AH_Outline** aoutline ) - { - FT_Error error; - AH_Outline* outline; - - - if ( !ALLOC( outline, sizeof ( *outline ) ) ) - { - outline->memory = memory; - *aoutline = outline; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_done */ - /* */ - /* */ - /* Destroys a given AH_Outline object. */ - /* */ - LOCAL_FUNC - void ah_outline_done( AH_Outline* outline ) - { - FT_Memory memory = outline->memory; - - - FREE( outline->horz_edges ); - FREE( outline->horz_segments ); - FREE( outline->contours ); - FREE( outline->points ); - - FREE( outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_save */ - /* */ - /* */ - /* Saves the content of a given AH_Outline object into a face's glyph */ - /* slot. */ - /* */ - LOCAL_FUNC - void ah_outline_save( AH_Outline* outline, - AH_Loader* gloader ) - { - AH_Point* point = outline->points; - AH_Point* limit = point + outline->num_points; - FT_Vector* vec = gloader->current.outline.points; - char* tag = gloader->current.outline.tags; - - - /* we assume that the glyph loader has already been checked for storage */ - for ( ; point < limit; point++, vec++, tag++ ) - { - vec->x = point->x; - vec->y = point->y; - - if ( point->flags & ah_flah_conic ) - tag[0] = FT_Curve_Tag_Conic; - else if ( point->flags & ah_flah_cubic ) - tag[0] = FT_Curve_Tag_Cubic; - else - tag[0] = FT_Curve_Tag_On; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_load */ - /* */ - /* */ - /* Loads an unscaled outline from a glyph slot into an AH_Outline */ - /* object. */ - /* */ - LOCAL_FUNC - FT_Error ah_outline_load( AH_Outline* outline, - FT_Face face ) - { - FT_Memory memory = outline->memory; - FT_Error error = FT_Err_Ok; - FT_Outline* source = &face->glyph->outline; - FT_Int num_points = source->n_points; - FT_Int num_contours = source->n_contours; - AH_Point* points; - - - /* check arguments */ - if ( !face || - !face->size || - face->glyph->format != ft_glyph_format_outline ) - return FT_Err_Invalid_Argument; - - /* first of all, reallocate the contours array if necessary */ - if ( num_contours > outline->max_contours ) - { - FT_Int new_contours = ( num_contours + 3 ) & -4; - - - if ( REALLOC_ARRAY( outline->contours, outline->max_contours, - new_contours, AH_Point* ) ) - goto Exit; - - outline->max_contours = new_contours; - } - - /* then, realloc the points, segments & edges arrays if needed */ - if ( num_points > outline->max_points ) - { - FT_Int news = ( num_points + 7 ) & -8; - FT_Int max = outline->max_points; - - - if ( REALLOC_ARRAY( outline->points, max, news, AH_Point ) || - REALLOC_ARRAY( outline->horz_edges, max, news, AH_Edge ) || - REALLOC_ARRAY( outline->horz_segments, max, news, AH_Segment ) ) - goto Exit; - - /* readjust some pointers */ - outline->vert_edges = outline->horz_edges + ( news >> 1 ); - outline->vert_segments = outline->horz_segments + ( news >> 1 ); - outline->max_points = news; - } - - outline->num_points = num_points; - outline->num_contours = num_contours; - - outline->num_hedges = 0; - outline->num_vedges = 0; - outline->num_hsegments = 0; - outline->num_vsegments = 0; - - /* Compute the vertical and horizontal major directions; this is */ - /* currently done by inspecting the `ft_outline_reverse_fill' flag. */ - /* However, some fonts have improper glyphs, and it'd be a good idea */ - /* to be able to re-compute these values on the fly. */ - outline->vert_major_dir = ah_dir_up; - outline->horz_major_dir = ah_dir_left; - - if ( source->flags & ft_outline_reverse_fill ) - { - outline->vert_major_dir = ah_dir_down; - outline->horz_major_dir = ah_dir_right; - } - - outline->x_scale = face->size->metrics.x_scale; - outline->y_scale = face->size->metrics.y_scale; - - points = outline->points; - - { - /* do one thing at a time -- it is easier to understand, and */ - /* the code is clearer */ - AH_Point* point = points; - AH_Point* limit = point + outline->num_points; - - - /* compute coordinates */ - { - FT_Vector* vec = source->points; - FT_Fixed x_scale = outline->x_scale; - FT_Fixed y_scale = outline->y_scale; - - - for (; point < limit; vec++, point++ ) - { - point->fx = vec->x; - point->fy = vec->y; - point->ox = point->x = FT_MulFix( vec->x, x_scale ); - point->oy = point->y = FT_MulFix( vec->y, y_scale ); - - point->flags = 0; - } - } - - /* compute Bezier flags */ - { - char* tag = source->tags; - - - for ( point = points; point < limit; point++, tag++ ) - { - switch ( FT_CURVE_TAG( *tag ) ) - { - case FT_Curve_Tag_Conic: - point->flags = ah_flah_conic; break; - case FT_Curve_Tag_Cubic: - point->flags = ah_flah_cubic; break; - default: - ; - } - } - } - - /* compute `next' and `prev' */ - { - FT_Int contour_index; - AH_Point* prev; - AH_Point* first; - AH_Point* end; - - - contour_index = 0; - - first = points; - end = points + source->contours[0]; - prev = end; - - for ( point = points; point < limit; point++ ) - { - point->prev = prev; - if ( point < end ) - { - point->next = point + 1; - prev = point; - } - else - { - point->next = first; - contour_index++; - if ( point + 1 < limit ) - { - end = points + source->contours[contour_index]; - first = point + 1; - prev = end; - } - } - } - } - - /* set-up the contours array */ - { - AH_Point** contour = outline->contours; - AH_Point** limit = contour + outline->num_contours; - short* end = source->contours; - short index = 0; - - - for ( ; contour < limit; contour++, end++ ) - { - contour[0] = points + index; - index = end[0] + 1; - } - } - - /* compute directions of in & out vectors */ - { - for ( point = points; point < limit; point++ ) - { - AH_Point* prev; - AH_Point* next; - FT_Vector vec; - - - prev = point->prev; - vec.x = point->fx - prev->fx; - vec.y = point->fy - prev->fy; - - point->in_dir = ah_compute_direction( vec.x, vec.y ); - -#ifndef AH_OPTION_NO_WEAK_INTERPOLATION - point->in_angle = ah_angle( &vec ); -#endif - - next = point->next; - vec.x = next->fx - point->fx; - vec.y = next->fy - point->fy; - - point->out_dir = ah_compute_direction( vec.x, vec.y ); - -#ifndef AH_OPTION_NO_WEAK_INTERPOLATION - point->out_angle = ah_angle( &vec ); - - { - AH_Angle delta = point->in_angle - point->out_angle; - - - if ( delta < 0 ) - delta = -delta; - if ( delta < 2 ) - point->flags |= ah_flah_weak_interpolation; - } - -#if 0 - if ( point->flags & ( ah_flah_conic | ah_flah_cubic ) ) - point->flags |= ah_flah_weak_interpolation; -#endif - -#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */ - -#ifdef AH_OPTION_NO_STRONG_INTERPOLATION - point->flags |= ah_flah_weak_interpolation; -#endif - } - } - } - - Exit: - return error; - } - - - LOCAL_FUNC - void ah_setup_uv( AH_Outline* outline, - AH_UV source ) - { - AH_Point* point = outline->points; - AH_Point* limit = point + outline->num_points; - - - for ( ; point < limit; point++ ) - { - FT_Pos u, v; - - - switch ( source ) - { - case ah_uv_fxy: - u = point->fx; - v = point->fy; - break; - case ah_uv_fyx: - u = point->fy; - v = point->fx; - break; - case ah_uv_oxy: - u = point->ox; - v = point->oy; - break; - case ah_uv_oyx: - u = point->oy; - v = point->ox; - break; - case ah_uv_yx: - u = point->y; - v = point->x; - break; - case ah_uv_ox: - u = point->x; - v = point->ox; - break; - case ah_uv_oy: - u = point->y; - v = point->oy; - break; - default: - u = point->x; - v = point->y; - break; - } - point->u = u; - point->v = v; - } - } - - - LOCAL_FUNC - void ah_outline_compute_segments( AH_Outline* outline ) - { - int dimension; - AH_Segment* segments; - FT_Int* p_num_segments; - AH_Direction segment_dir; - AH_Direction major_dir; - - - segments = outline->horz_segments; - p_num_segments = &outline->num_hsegments; - major_dir = ah_dir_right; /* This value must be positive! */ - segment_dir = major_dir; - - /* set up (u,v) in each point */ - ah_setup_uv( outline, ah_uv_fyx ); - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Point** contour = outline->contours; - AH_Point** contour_limit = contour + outline->num_contours; - AH_Segment* segment = segments; - FT_Int num_segments = 0; - -#ifdef AH_HINT_METRICS - AH_Point* min_point = 0; - AH_Point* max_point = 0; - FT_Pos min_coord = 32000; - FT_Pos max_coord = -32000; -#endif - - - /* do each contour separately */ - for ( ; contour < contour_limit; contour++ ) - { - AH_Point* point = contour[0]; - AH_Point* last = point->prev; - int on_edge = 0; - FT_Pos min_pos = +32000; /* minimum segment pos != min_coord */ - FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ - FT_Bool passed; - - -#ifdef AH_HINT_METRICS - if ( point->u < min_coord ) - { - min_coord = point->u; - min_point = point; - } - if ( point->u > max_coord ) - { - max_coord = point->u; - max_point = point; - } -#endif - - if ( point == last ) /* skip singletons -- just in case? */ - continue; - - if ( ABS( last->out_dir ) == major_dir && - ABS( point->out_dir ) == major_dir ) - { - /* we are already on an edge, try to locate its start */ - last = point; - - for (;;) - { - point = point->prev; - if ( ABS( point->out_dir ) != major_dir ) - { - point = point->next; - break; - } - if ( point == last ) - break; - } - - } - - last = point; - passed = 0; - - for (;;) - { - FT_Pos u, v; - - - if ( on_edge ) - { - u = point->u; - if ( u < min_pos ) - min_pos = u; - if ( u > max_pos ) - max_pos = u; - - if ( point->out_dir != segment_dir || point == last ) - { - /* we are just leaving an edge; record a new segment! */ - segment->last = point; - segment->pos = ( min_pos + max_pos ) >> 1; - - /* a segment is round if either its first or last point */ - /* is a control point */ - if ( ( segment->first->flags | point->flags ) & - ah_flah_control ) - segment->flags |= ah_edge_round; - - /* compute segment size */ - min_pos = max_pos = point->v; - - v = segment->first->v; - if ( v < min_pos ) - min_pos = v; - if ( v > max_pos ) - max_pos = v; - - segment->min_coord = min_pos; - segment->max_coord = max_pos; - - on_edge = 0; - num_segments++; - segment++; - /* fallthrough */ - } - } - - /* now exit if we are at the start/end point */ - if ( point == last ) - { - if ( passed ) - break; - passed = 1; - } - - if ( !on_edge && ABS( point->out_dir ) == major_dir ) - { - /* this is the start of a new segment! */ - segment_dir = point->out_dir; - - /* clear all segment fields */ - memset( segment, 0, sizeof ( *segment ) ); - - segment->dir = segment_dir; - segment->flags = ah_edge_normal; - min_pos = max_pos = point->u; - segment->first = point; - segment->last = point; - segment->contour = contour; - on_edge = 1; - - if ( point == max_point ) - max_point = 0; - - if ( point == min_point ) - min_point = 0; - } - - point = point->next; - } - - } /* contours */ - -#ifdef AH_HINT_METRICS - /* we need to ensure that there are edges on the left-most and */ - /* right-most points of the glyph in order to hint the metrics; */ - /* we do this by inserting fake segments when needed */ - if ( dimension == 0 ) - { - AH_Point* point = outline->points; - AH_Point* limit = point + outline->num_points; - - AH_Point* min_point = 0; - AH_Point* max_point = 0; - FT_Pos min_pos = 32000; - FT_Pos max_pos = -32000; - - - /* compute minimum and maximum points */ - for ( ; point < limit; point++ ) - { - FT_Pos x = point->fx; - - - if ( x < min_pos ) - { - min_pos = x; - min_point = point; - } - if ( x > max_pos ) - { - max_pos = x; - max_point = point; - } - } - - /* insert minimum segment */ - if ( min_point ) - { - /* clear all segment fields */ - memset( segment, 0, sizeof ( *segment ) ); - - segment->dir = segment_dir; - segment->flags = ah_edge_normal; - segment->first = min_point; - segment->last = min_point; - segment->pos = min_pos; - - num_segments++; - segment++; - } - - /* insert maximum segment */ - if ( max_point ) - { - /* clear all segment fields */ - memset( segment, 0, sizeof ( *segment ) ); - - segment->dir = segment_dir; - segment->flags = ah_edge_normal; - segment->first = max_point; - segment->last = max_point; - segment->pos = max_pos; - - num_segments++; - segment++; - } - } -#endif /* AH_HINT_METRICS */ - - *p_num_segments = num_segments; - - segments = outline->vert_segments; - major_dir = ah_dir_up; - p_num_segments = &outline->num_vsegments; - ah_setup_uv( outline, ah_uv_fxy ); - } - } - - - LOCAL_FUNC - void ah_outline_link_segments( AH_Outline* outline ) - { - AH_Segment* segments; - AH_Segment* limit; - int dimension; - - - ah_setup_uv( outline, ah_uv_fyx ); - - segments = outline->horz_segments; - limit = segments + outline->num_hsegments; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Segment* seg1; - AH_Segment* seg2; - - - /* now compare each segment to the others */ - for ( seg1 = segments; seg1 < limit; seg1++ ) - { - FT_Pos best_score = 32000; - AH_Segment* best_segment = 0; - - - /* the fake segments are introduced to hint the metrics -- */ - /* we must never link them to anything */ - if ( seg1->first == seg1->last ) - continue; - - for ( seg2 = segments; seg2 < limit; seg2++ ) - if ( seg1 != seg2 && seg1->dir + seg2->dir == 0 ) - { - FT_Pos pos1 = seg1->pos; - FT_Pos pos2 = seg2->pos; - FT_Bool is_dir; - FT_Bool is_pos; - - - /* check that the segments are correctly oriented and */ - /* positioned to form a black distance */ - - is_dir = ( seg1->dir == outline->horz_major_dir || - seg1->dir == outline->vert_major_dir ); - is_pos = pos1 > pos2; - - if ( pos1 == pos2 || !(is_dir ^ is_pos) ) - continue; - - /* Check the two segments. We now have a better algorithm */ - /* that doesn't rely on the segment points themselves but */ - /* on their relative position. This gets rids of many */ - /* unpleasant artefacts and incorrect stem/serifs */ - /* computations. */ - - /* first of all, compute the size of the `common' height */ - { - FT_Pos min = seg1->min_coord; - FT_Pos max = seg1->max_coord; - FT_Pos len, score; - FT_Pos size1, size2; - - - size1 = max - min; - size2 = seg2->max_coord - seg2->min_coord; - - if ( min < seg2->min_coord ) - min = seg2->min_coord; - - if ( max < seg2->max_coord ) - max = seg2->max_coord; - - len = max - min; - score = seg2->pos - seg1->pos; - if ( score < 0 ) - score = -score; - - /* before comparing the scores, take care that the segments */ - /* are really facing each other (often not for italics..) */ - if ( 4 * len >= size1 && 4 * len >= size2 ) - if ( score < best_score ) - { - best_score = score; - best_segment = seg2; - } - } - } - - if ( best_segment ) - { - seg1->link = best_segment; - seg1->score = best_score; - - best_segment->num_linked++; - } - - - } /* edges 1 */ - - /* now, compute the `serif' segments */ - for ( seg1 = segments; seg1 < limit; seg1++ ) - { - seg2 = seg1->link; - - if ( seg2 && seg2->link != seg1 ) - { - seg1->link = 0; - seg1->serif = seg2->link; - } - } - - ah_setup_uv( outline, ah_uv_fxy ); - - segments = outline->vert_segments; - limit = segments + outline->num_vsegments; - } - } - - -#ifdef AH_DEBUG_GLYPH - - /* A function used to dump the array of linked segments */ - void ah_dump_segments( AH_Outline* outline ) - { - AH_Segment* segments; - AH_Segment* limit; - AH_Point* points; - FT_Int dimension; - - - points = outline->points; - segments = outline->horz_segments; - limit = segments + outline->num_hsegments; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Segment* seg; - - - printf ( "Table of %s segments:\n", - !dimension ? "vertical" : "horizontal" ); - printf ( " [ index | pos | dir | link | serif |" - " numl | first | start ]\n" ); - - for ( seg = segments; seg < limit; seg++ ) - { - printf ( " [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n", - seg - segments, - (int)seg->pos, - seg->dir == ah_dir_up - ? "up" - : ( seg->dir == ah_dir_down - ? "down" - : ( seg->dir == ah_dir_left - ? "left" - : ( seg->dir == ah_dir_right - ? "right" - : "none" ) ) ), - seg->link ? (seg->link-segments) : -1, - seg->serif ? (seg->serif-segments) : -1, - (int)seg->num_linked, - seg->first - points, - seg->last - points ); - } - - segments = outline->vert_segments; - limit = segments + outline->num_vsegments; - } - } - -#endif /* AH_DEBUG_GLYPH */ - - - static - void ah_outline_compute_edges( AH_Outline* outline ) - { - AH_Edge* edges; - AH_Segment* segments; - AH_Segment* segment_limit; - AH_Direction up_dir; - FT_Int* p_num_edges; - FT_Int dimension; - FT_Fixed scale; - FT_Pos edge_distance_threshold; - - - edges = outline->horz_edges; - segments = outline->horz_segments; - segment_limit = segments + outline->num_hsegments; - p_num_edges = &outline->num_hedges; - up_dir = ah_dir_right; - scale = outline->y_scale; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Edge* edge; - AH_Edge* edge_limit; /* really == edge + num_edges */ - AH_Segment* seg; - - - /*********************************************************************/ - /* */ - /* We will begin by generating a sorted table of edges for the */ - /* current direction. To do so, we simply scan each segment and try */ - /* to find an edge in our table that corresponds to its position. */ - /* */ - /* If no edge is found, we create and insert a new edge in the */ - /* sorted table. Otherwise, we simply add the segment to the edge's */ - /* list which will be processed in the second step to compute the */ - /* edge's properties. */ - /* */ - /* Note that the edges table is sorted along the segment/edge */ - /* position. */ - /* */ - /*********************************************************************/ - - edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold, - scale ); - if ( edge_distance_threshold > 64 / 4 ) - edge_distance_threshold = 64 / 4; - - edge_limit = edges; - for ( seg = segments; seg < segment_limit; seg++ ) - { - AH_Edge* found = 0; - - - /* look for an edge corresponding to the segment */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Pos dist; - - - dist = seg->pos - edge->fpos; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, scale ); - if ( dist < edge_distance_threshold ) - { - found = edge; - break; - } - } - - if ( !found ) - { - /* insert a new edge in the list and */ - /* sort according to the position */ - while ( edge > edges && edge[-1].fpos > seg->pos ) - { - edge[0] = edge[-1]; - edge--; - } - edge_limit++; - - /* clear all edge fields */ - memset( edge, 0, sizeof ( *edge ) ); - - /* add the segment to the new edge's list */ - edge->first = seg; - edge->last = seg; - edge->fpos = seg->pos; - edge->opos = edge->pos = FT_MulFix( seg->pos, scale ); - seg->edge_next = seg; - } - else - { - /* if an edge was found, simply add the segment to the edge's */ - /* list */ - seg->edge_next = edge->first; - edge->last->edge_next = seg; - edge->last = seg; - } - } - - *p_num_edges = edge_limit - edges; - - - /*********************************************************************/ - /* */ - /* Good, we will now compute each edge's properties according to */ - /* segments found on its position. Basically, these are: */ - /* */ - /* - edge's main direction */ - /* - stem edge, serif edge or both (which defaults to stem then) */ - /* - rounded edge, straigth or both (which defaults to straight) */ - /* - link for edge */ - /* */ - /*********************************************************************/ - - /* first of all, set the `edge' field in each segment -- this is */ - /* required in order to compute edge links */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - seg = edge->first; - if ( seg ) - do - { - seg->edge = edge; - seg = seg->edge_next; - } - while ( seg != edge->first ); - } - - /* now, compute each edge properties */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - int is_round = 0; /* does it contain round segments? */ - int is_straight = 0; /* does it contain straight segments? */ - int ups = 0; /* number of upwards segments */ - int downs = 0; /* number of downwards segments */ - - - seg = edge->first; - - do - { - FT_Bool is_serif; - - - /* check for roundness of segment */ - if ( seg->flags & ah_edge_round ) - is_round++; - else - is_straight++; - - /* check for segment direction */ - if ( seg->dir == up_dir ) - ups += seg->max_coord-seg->min_coord; - else - downs += seg->max_coord-seg->min_coord; - - /* check for links -- if seg->serif is set, then seg->link must */ - /* be ignored */ - is_serif = seg->serif && seg->serif->edge != edge; - - if ( seg->link || is_serif ) - { - AH_Edge* edge2; - AH_Segment* seg2; - - - edge2 = edge->link; - seg2 = seg->link; - - if ( is_serif ) - { - seg2 = seg->serif; - edge2 = edge->serif; - } - - if ( edge2 ) - { - FT_Pos edge_delta; - FT_Pos seg_delta; - - - edge_delta = edge->fpos - edge2->fpos; - if ( edge_delta < 0 ) - edge_delta = -edge_delta; - - seg_delta = seg->pos - seg2->pos; - if ( seg_delta < 0 ) - seg_delta = -seg_delta; - - if ( seg_delta < edge_delta ) - edge2 = seg2->edge; - } - else - edge2 = seg2->edge; - - if ( is_serif ) - edge->serif = edge2; - else - edge->link = edge2; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - - /* set the round/straight flags */ - edge->flags = ah_edge_normal; - - if ( is_straight == 0 && is_round ) - edge->flags |= ah_edge_round; - - /* set the edge's main direction */ - edge->dir = ah_dir_none; - - if ( ups > downs ) - edge->dir = up_dir; - - else if ( ups < downs ) - edge->dir = - up_dir; - - else if ( ups == downs ) - edge->dir = 0; /* both up and down !! */ - - /* gets rid of serifs if link is set */ - /* XXX: This gets rid of many unpleasant artefacts! */ - /* Example: the `c' in cour.pfa at size 13 */ - - if ( edge->serif && edge->link ) - edge->serif = 0; - } - - edges = outline->vert_edges; - segments = outline->vert_segments; - segment_limit = segments + outline->num_vsegments; - p_num_edges = &outline->num_vedges; - up_dir = ah_dir_up; - scale = outline->x_scale; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_detect_features */ - /* */ - /* */ - /* Performs feature detection on a given AH_Outline object. */ - /* */ - LOCAL_FUNC - void ah_outline_detect_features( AH_Outline* outline ) - { - ah_outline_compute_segments( outline ); - ah_outline_link_segments ( outline ); - ah_outline_compute_edges ( outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_compute_blue_edges */ - /* */ - /* */ - /* Computes the `blue edges' in a given outline (i.e. those that must */ - /* be snapped to a blue zone edge (top or bottom). */ - /* */ - LOCAL_FUNC - void ah_outline_compute_blue_edges( AH_Outline* outline, - AH_Face_Globals* face_globals ) - { - AH_Edge* edge = outline->horz_edges; - AH_Edge* limit = edge + outline->num_hedges; - AH_Globals* globals = &face_globals->design; - FT_Fixed y_scale = outline->y_scale; - - - /* compute for each horizontal edge, which blue zone is closer */ - for ( ; edge < limit; edge++ ) - { - AH_Blue blue; - FT_Pos* best_blue = 0; - FT_Pos best_dist; /* initial threshold */ - - - /* compute the initial threshold as a fraction of the EM size */ - best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale ); - if ( best_dist > 64 / 4 ) - best_dist = 64 / 4; - - for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ ) - { - /* if it is a top zone, check for right edges -- if it is a bottom */ - /* zone, check for left edges */ - /* */ - /* of course, that's for TrueType XXX */ - FT_Bool is_top_blue = AH_IS_TOP_BLUE( blue ); - FT_Bool is_major_dir = edge->dir == outline->horz_major_dir; - - - /* if it is a top zone, the edge must be against the major */ - /* direction; if it is a bottom zone, it must be in the major */ - /* direction */ - if ( is_top_blue ^ is_major_dir ) - { - FT_Pos dist; - FT_Pos* blue_pos = globals->blue_refs + blue; - - - /* first of all, compare it to the reference position */ - dist = edge->fpos - *blue_pos; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, y_scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = blue_pos; - } - - /* now, compare it to the overshoot position if the edge is */ - /* rounded, and if the edge is over the reference position of a */ - /* top zone, or under the reference position of a bottom zone */ - if ( edge->flags & ah_edge_round && dist != 0 ) - { - FT_Bool is_under_ref = edge->fpos < *blue_pos; - - - if ( is_top_blue ^ is_under_ref ) - { - blue_pos = globals->blue_shoots + blue; - dist = edge->fpos - *blue_pos; - if ( dist < 0 ) - dist = -dist; - - dist = FT_MulFix( dist, y_scale ); - if ( dist < best_dist ) - { - best_dist = dist; - best_blue = blue_pos; - } - } - } - } - } - - if ( best_blue ) - edge->blue_edge = best_blue; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* ah_outline_scale_blue_edges */ - /* */ - /* */ - /* This functions must be called before hinting in order to re-adjust */ - /* the contents of the detected edges (basically change the `blue */ - /* edge' pointer from `design units' to `scaled ones'). */ - /* */ - LOCAL_FUNC - void ah_outline_scale_blue_edges( AH_Outline* outline, - AH_Face_Globals* globals ) - { - AH_Edge* edge = outline->horz_edges; - AH_Edge* limit = edge + outline->num_hedges; - FT_Int delta; - - - delta = globals->scaled.blue_refs - globals->design.blue_refs; - - for ( ; edge < limit; edge++ ) - { - if ( edge->blue_edge ) - edge->blue_edge += delta; - } - } - - -#ifdef AH_DEBUG_GLYPH - - void ah_dump_edges( AH_Outline* outline ) - { - AH_Edge* edges; - AH_Edge* limit; - AH_Segment* segments; - FT_Int dimension; - - - edges = outline->horz_edges; - limit = edges + outline->num_hedges; - segments = outline->horz_segments; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Edge* edge; - - - printf ( "Table of %s edges:\n", - !dimension ? "vertical" : "horizontal" ); - printf ( " [ index | pos | dir | link |" - " serif | blue | opos | pos ]\n" ); - - for ( edge = edges; edge < limit; edge++ ) - { - printf ( " [ %5d | %4d | %5s | %4d | %5d | %c | %5.2f | %5.2f ]\n", - edge - edges, - (int)edge->fpos, - edge->dir == ah_dir_up - ? "up" - : ( edge->dir == ah_dir_down - ? "down" - : ( edge->dir == ah_dir_left - ? "left" - : ( edge->dir == ah_dir_right - ? "right" - : "none" ) ) ), - edge->link ? ( edge->link - edges ) : -1, - edge->serif ? ( edge->serif - edges ) : -1, - edge->blue_edge ? 'y' : 'n', - edge->opos / 64.0, - edge->pos / 64.0 ); - } - - edges = outline->vert_edges; - limit = edges + outline->num_vedges; - segments = outline->vert_segments; - } - } - -#endif /* AH_DEBUG_GLYPH */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahglyph.h b/subsys/win32k/freetype/src/autohint/ahglyph.h deleted file mode 100644 index 1ce5260..0000000 --- a/subsys/win32k/freetype/src/autohint/ahglyph.h +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahglyph.h */ -/* */ -/* Routines used to load and analyze a given glyph before hinting */ -/* (specification). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHGLYPH_H -#define AHGLYPH_H - -#ifdef FT_FLAT_COMPILE - -#include "ahtypes.h" - -#else - -#include - -#endif - - - typedef enum AH_UV_ - { - ah_uv_fxy, - ah_uv_fyx, - ah_uv_oxy, - ah_uv_oyx, - ah_uv_ox, - ah_uv_oy, - ah_uv_yx, - ah_uv_xy /* should always be last! */ - - } AH_UV; - - - LOCAL_DEF - void ah_setup_uv( AH_Outline* outline, - AH_UV source ); - - - /* AH_Outline functions - they should be typically called in this order */ - - LOCAL_DEF - FT_Error ah_outline_new( FT_Memory memory, - AH_Outline** aoutline ); - - LOCAL_DEF - FT_Error ah_outline_load( AH_Outline* outline, - FT_Face face ); - - LOCAL_DEF - void ah_outline_compute_segments( AH_Outline* outline ); - - LOCAL_DEF - void ah_outline_link_segments( AH_Outline* outline ); - - LOCAL_DEF - void ah_outline_detect_features( AH_Outline* outline ); - - LOCAL_DEF - void ah_outline_compute_blue_edges( AH_Outline* outline, - AH_Face_Globals* globals ); - - LOCAL_DEF - void ah_outline_scale_blue_edges( AH_Outline* outline, - AH_Face_Globals* globals ); - - LOCAL_DEF - void ah_outline_save( AH_Outline* outline, AH_Loader* loader ); - - LOCAL_DEF - void ah_outline_done( AH_Outline* outline ); - - -#endif /* AHGLYPH_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahhint.c b/subsys/win32k/freetype/src/autohint/ahhint.c deleted file mode 100644 index 357a641..0000000 --- a/subsys/win32k/freetype/src/autohint/ahhint.c +++ /dev/null @@ -1,1398 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahhint.c */ -/* */ -/* Glyph hinter (body). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "ahhint.h" -#include "ahglyph.h" -#include "ahangles.h" - -#else - -#include -#include -#include - -#endif - -#include - - -#define FACE_GLOBALS( face ) ((AH_Face_Globals*)(face)->autohint.data) - -#define AH_USE_IUP - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** Hinting routines ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - static int disable_horz_edges = 0; - static int disable_vert_edges = 0; - - - /* snap a given width in scaled coordinates to one of the */ - /* current standard widths */ - static - FT_Pos ah_snap_width( FT_Pos* widths, - FT_Int count, - FT_Pos width ) - { - int n; - FT_Pos best = 64 + 32 + 2; - FT_Pos reference = width; - - - for ( n = 0; n < count; n++ ) - { - FT_Pos w; - FT_Pos dist; - - - w = widths[n]; - dist = width - w; - if ( dist < 0 ) - dist = -dist; - if ( dist < best ) - { - best = dist; - reference = w; - } - } - - if ( width >= reference ) - { - width -= 0x21; - if ( width < reference ) - width = reference; - } - else - { - width += 0x21; - if ( width > reference ) - width = reference; - } - - return width; - } - - - /* align one stem edge relative to the previous stem edge */ - static - void ah_align_linked_edge( AH_Hinter* hinter, - AH_Edge* base_edge, - AH_Edge* stem_edge, - int vertical ) - { - FT_Pos dist = stem_edge->opos - base_edge->opos; - AH_Globals* globals = &hinter->globals->scaled; - FT_Pos sign = 1; - - - if ( dist < 0 ) - { - dist = -dist; - sign = -1; - } - - if ( vertical ) - { - dist = ah_snap_width( globals->heights, globals->num_heights, dist ); - - /* in the case of vertical hinting, always round */ - /* the stem heights to integer pixels */ - if ( dist >= 64 ) - dist = ( dist + 16 ) & -64; - else - dist = 64; - } - else - { - dist = ah_snap_width( globals->widths, globals->num_widths, dist ); - - if ( hinter->flags & ah_hinter_monochrome ) - { - /* monochrome horizontal hinting: snap widths to integer pixels */ - /* with a different threshold */ - if ( dist < 64 ) - dist = 64; - else - dist = ( dist + 32 ) & -64; - } - else - { - /* for horizontal anti-aliased hinting, we adopt a more subtle */ - /* approach: we strengthen small stems, round stems whose size */ - /* is between 1 and 2 pixels to an integer, otherwise nothing */ - if ( dist < 48 ) - dist = ( dist + 64 ) >> 1; - - else if ( dist < 128 ) - dist = ( dist + 42 ) & -64; - } - } - - stem_edge->pos = base_edge->pos + sign * dist; - } - - - static - void ah_align_serif_edge( AH_Hinter* hinter, - AH_Edge* base, - AH_Edge* serif ) - { - FT_Pos dist; - FT_Pos sign = 1; - - UNUSED( hinter ); - - - dist = serif->opos - base->opos; - if ( dist < 0 ) - { - dist = -dist; - sign = -1; - } - - /* do not strengthen serifs */ - if ( base->flags & ah_edge_done ) - { - if ( dist > 64 ) - dist = ( dist + 16 ) & -64; - - else if ( dist <= 32 ) - dist = ( dist + 33 ) >> 1; - } - - serif->pos = base->pos + sign * dist; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** E D G E H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* Another alternative edge hinting algorithm */ - static - void ah_hint_edges_3( AH_Hinter* hinter ) - { - AH_Edge* edges; - AH_Edge* edge_limit; - AH_Outline* outline = hinter->glyph; - FT_Int dimension; - - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Edge* edge; - AH_Edge* before = 0; - AH_Edge* after = 0; - AH_Edge* anchor = 0; - int has_serifs = 0; - - - if ( disable_vert_edges && !dimension ) - goto Next_Dimension; - - if ( disable_horz_edges && dimension ) - goto Next_Dimension; - - /* we begin by aligning all stems relative to the blue zone */ - /* if needed -- that's only for horizontal edges */ - if ( dimension ) - { - for ( edge = edges; edge < edge_limit; edge++ ) - { - FT_Pos* blue; - AH_Edge *edge1, *edge2; - - - if ( edge->flags & ah_edge_done ) - continue; - - blue = edge->blue_edge; - edge1 = 0; - edge2 = edge->link; - - if ( blue ) - { - edge1 = edge; - } - else if (edge2 && edge2->blue_edge) - { - blue = edge2->blue_edge; - edge1 = edge2; - edge2 = edge; - } - - if ( !edge1 ) - continue; - - edge1->pos = blue[0]; - edge1->flags |= ah_edge_done; - - if ( edge2 && !edge2->blue_edge ) - { - ah_align_linked_edge( hinter, edge1, edge2, dimension ); - edge2->flags |= ah_edge_done; - } - - if ( !anchor ) - anchor = edge; - } - } - - /* now, we will align all stem edges, trying to maintain the */ - /* relative order of stems in the glyph.. */ - before = 0; - after = 0; - for ( edge = edges; edge < edge_limit; edge++ ) - { - AH_Edge *edge2; - - - if ( edge->flags & ah_edge_done ) - continue; - - /* skip all non-stem edges */ - edge2 = edge->link; - if ( !edge2 ) - { - has_serifs++; - continue; - } - - /* now, align the stem */ - - /* this should not happen, but it's better to be safe.. */ - if ( edge2->blue_edge || edge2 < edge ) - { - -#if 0 - printf( "strange blue alignement, edge %d to %d\n", - edge - edges, edge2 - edges ); -#endif - - ah_align_linked_edge( hinter, edge2, edge, dimension ); - edge->flags |= ah_edge_done; - continue; - } - - { - FT_Bool min = 0; - FT_Pos delta; - - if ( !anchor ) - { - edge->pos = ( edge->opos + 32 ) & -64; - anchor = edge; - } - else - edge->pos = anchor->pos + - ( ( edge->opos - anchor->opos + 32 ) & -64 ); - - edge->flags |= ah_edge_done; - - if ( edge > edges && edge->pos < edge[-1].pos ) - { - edge->pos = edge[-1].pos; - min = 1; - } - - ah_align_linked_edge( hinter, edge, edge2, dimension ); - delta = 0; - if ( edge2 + 1 < edge_limit && - edge2[1].flags & ah_edge_done ) - delta = edge2[1].pos - edge2->pos; - - if ( delta < 0 ) - { - edge2->pos += delta; - if ( !min ) - edge->pos += delta; - } - edge2->flags |= ah_edge_done; - } - } - - if ( !has_serifs ) - goto Next_Dimension; - - /* now, hint the remaining edges (serifs and single) in order */ - /* to complete our processing */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - if ( edge->flags & ah_edge_done ) - continue; - - if ( edge->serif ) - { - ah_align_serif_edge( hinter, edge->serif, edge ); - } - else if ( !anchor ) - { - edge->pos = ( edge->opos + 32 ) & -64; - anchor = edge; - } - else - edge->pos = anchor->pos + - ( ( edge->opos-anchor->opos + 32 ) & -64 ); - - edge->flags |= ah_edge_done; - - if ( edge > edges && edge->pos < edge[-1].pos ) - edge->pos = edge[-1].pos; - - if ( edge + 1 < edge_limit && - edge[1].flags & ah_edge_done && - edge->pos > edge[1].pos ) - edge->pos = edge[1].pos; - } - - Next_Dimension: - edges = outline->vert_edges; - edge_limit = edges + outline->num_vedges; - } - } - - - LOCAL_FUNC - void ah_hinter_hint_edges( AH_Hinter* hinter, - int no_horz_edges, - int no_vert_edges ) - { - disable_horz_edges = no_horz_edges; - disable_vert_edges = no_vert_edges; - - /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help */ - /* reduce the problem of the disappearing eye in the `e' of Times... */ - /* also, creates some artifacts near the blue zones? */ - { - ah_hint_edges_3( hinter ); - -#if 0 - /* outline optimizer removed temporarily */ - if ( hinter->flags & ah_hinter_optimize ) - { - AH_Optimizer opt; - - - if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) ) - { - AH_Optimizer_Compute( &opt ); - AH_Optimizer_Done( &opt ); - } - } -#endif - - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** P O I N T H I N T I N G ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - static - void ah_hinter_align_edge_points( AH_Hinter* hinter ) - { - AH_Outline* outline = hinter->glyph; - AH_Edge* edges; - AH_Edge* edge_limit; - FT_Int dimension; - - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Edge* edge; - AH_Edge* before; - AH_Edge* after; - - - before = 0; - after = 0; - - edge = edges; - for ( ; edge < edge_limit; edge++ ) - { - /* move the points of each segment */ - /* in each edge to the edge's position */ - AH_Segment* seg = edge->first; - - - do - { - AH_Point* point = seg->first; - - - for (;;) - { - if ( dimension ) - { - point->y = edge->pos; - point->flags |= ah_flah_touch_y; - } - else - { - point->x = edge->pos; - point->flags |= ah_flah_touch_x; - } - - if ( point == seg->last ) - break; - - point = point->next; - } - - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - edges = outline->vert_edges; - edge_limit = edges + outline->num_vedges; - } - } - - - /* hint the strong points -- this is equivalent to the TrueType `IP' */ - static - void ah_hinter_align_strong_points( AH_Hinter* hinter ) - { - AH_Outline* outline = hinter->glyph; - FT_Int dimension; - AH_Edge* edges; - AH_Edge* edge_limit; - AH_Point* points; - AH_Point* point_limit; - AH_Flags touch_flag; - - - points = outline->points; - point_limit = points + outline->num_points; - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - touch_flag = ah_flah_touch_y; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Point* point; - AH_Edge* edge; - AH_Edge* before; - AH_Edge* after; - - - before = 0; - after = 0; - - if ( edges < edge_limit ) - for ( point = points; point < point_limit; point++ ) - { - FT_Pos u, ou, fu; /* point position */ - FT_Pos delta; - - - if ( point->flags & touch_flag ) - continue; - -#ifndef AH_OPTION_NO_WEAK_INTERPOLATION - /* if this point is candidate to weak interpolation, we will */ - /* interpolate it after all strong points have been processed */ - if ( point->flags & ah_flah_weak_interpolation ) - continue; -#endif - - if ( dimension ) - { - u = point->fy; - ou = point->oy; - } - else - { - u = point->fx; - ou = point->ox; - } - - fu = u; - - /* is the point before the first edge? */ - edge = edges; - delta = edge->fpos - u; - if ( delta >= 0 ) - { - u = edge->pos - ( edge->opos - ou ); - goto Store_Point; - } - - /* is the point after the last edge ? */ - edge = edge_limit - 1; - delta = u - edge->fpos; - if ( delta >= 0 ) - { - u = edge->pos + ( ou - edge->opos ); - goto Store_Point; - } - - /* otherwise, interpolate the point in between */ - { - AH_Edge* before = 0; - AH_Edge* after = 0; - - - for ( edge = edges; edge < edge_limit; edge++ ) - { - if ( u == edge->fpos ) - { - u = edge->pos; - goto Store_Point; - } - if ( u < edge->fpos ) - break; - before = edge; - } - - for ( edge = edge_limit - 1; edge >= edges; edge-- ) - { - if ( u == edge->fpos ) - { - u = edge->pos; - goto Store_Point; - } - if ( u > edge->fpos ) - break; - after = edge; - } - - /* assert( before && after && before != after ) */ - u = before->pos + FT_MulDiv( fu - before->fpos, - after->pos - before->pos, - after->fpos - before->fpos ); - } - - Store_Point: - - /* save the point position */ - if ( dimension ) - point->y = u; - else - point->x = u; - - point->flags |= touch_flag; - } - - edges = outline->vert_edges; - edge_limit = edges + outline->num_vedges; - touch_flag = ah_flah_touch_x; - } - } - - -#ifndef AH_OPTION_NO_WEAK_INTERPOLATION - - static - void ah_iup_shift( AH_Point* p1, - AH_Point* p2, - AH_Point* ref ) - { - AH_Point* p; - FT_Pos delta = ref->u - ref->v; - - - for ( p = p1; p < ref; p++ ) - p->u = p->v + delta; - - for ( p = ref + 1; p <= p2; p++ ) - p->u = p->v + delta; - } - - - static - void ah_iup_interp( AH_Point* p1, - AH_Point* p2, - AH_Point* ref1, - AH_Point* ref2 ) - { - AH_Point* p; - FT_Pos u; - FT_Pos v1 = ref1->v; - FT_Pos v2 = ref2->v; - FT_Pos d1 = ref1->u - v1; - FT_Pos d2 = ref2->u - v2; - - - if ( p1 > p2 ) - return; - - if ( v1 == v2 ) - { - for ( p = p1; p <= p2; p++ ) - { - FT_Pos u = p->v; - - - if ( u <= v1 ) - u += d1; - else - u += d2; - - p->u = u; - } - return; - } - - if ( v1 < v2 ) - { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v1 ) - u += d1; - else if ( u >= v2 ) - u += d2; - else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); - - p->u = u; - } - } - else - { - for ( p = p1; p <= p2; p++ ) - { - u = p->v; - - if ( u <= v2 ) - u += d2; - else if ( u >= v1 ) - u += d1; - else - u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 ); - - p->u = u; - } - } - } - - - /* interpolate weak points -- this is equivalent to the TrueType `IUP' */ - static - void ah_hinter_align_weak_points( AH_Hinter* hinter ) - { - AH_Outline* outline = hinter->glyph; - FT_Int dimension; - AH_Edge* edges; - AH_Edge* edge_limit; - AH_Point* points; - AH_Point* point_limit; - AH_Point** contour_limit; - AH_Flags touch_flag; - - - points = outline->points; - point_limit = points + outline->num_points; - - /* PASS 1: Move segment points to edge positions */ - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - touch_flag = ah_flah_touch_y; - - contour_limit = outline->contours + outline->num_contours; - - ah_setup_uv( outline, ah_uv_oy ); - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Point* point; - AH_Point* end_point; - AH_Point* first_point; - AH_Point** contour; - - - point = points; - contour = outline->contours; - - for ( ; contour < contour_limit; contour++ ) - { - point = *contour; - end_point = point->prev; - first_point = point; - - while ( point <= end_point && !( point->flags & touch_flag ) ) - point++; - - if ( point <= end_point ) - { - AH_Point* first_touched = point; - AH_Point* cur_touched = point; - - - point++; - while ( point <= end_point ) - { - if ( point->flags & touch_flag ) - { - /* we found two successive touched points; we interpolate */ - /* all contour points between them */ - ah_iup_interp( cur_touched + 1, point - 1, - cur_touched, point ); - cur_touched = point; - } - point++; - } - - if ( cur_touched == first_touched ) - { - /* this is a special case: only one point was touched in the */ - /* contour; we thus simply shift the whole contour */ - ah_iup_shift( first_point, end_point, cur_touched ); - } - else - { - /* now interpolate after the last touched point to the end */ - /* of the contour */ - ah_iup_interp( cur_touched + 1, end_point, - cur_touched, first_touched ); - - /* if the first contour point isn't touched, interpolate */ - /* from the contour start to the first touched point */ - if ( first_touched > points ) - ah_iup_interp( first_point, first_touched - 1, - cur_touched, first_touched ); - } - } - } - - /* now save the interpolated values back to x/y */ - if ( dimension ) - { - for ( point = points; point < point_limit; point++ ) - point->y = point->u; - - touch_flag = ah_flah_touch_x; - ah_setup_uv( outline, ah_uv_ox ); - } - else - { - for ( point = points; point < point_limit; point++ ) - point->x = point->u; - - break; /* exit loop */ - } - } - } - -#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */ - - - LOCAL_FUNC - void ah_hinter_align_points( AH_Hinter* hinter ) - { - ah_hinter_align_edge_points( hinter ); - -#ifndef AH_OPTION_NO_STRONG_INTERPOLATION - ah_hinter_align_strong_points( hinter ); -#endif - -#ifndef AH_OPTION_NO_WEAK_INTERPOLATION - ah_hinter_align_weak_points( hinter ); -#endif - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** H I N T E R O B J E C T M E T H O D S ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* scale and fit the global metrics */ - static - void ah_hinter_scale_globals( AH_Hinter* hinter, - FT_Fixed x_scale, - FT_Fixed y_scale ) - { - FT_Int n; - AH_Face_Globals* globals = hinter->globals; - AH_Globals* design = &globals->design; - AH_Globals* scaled = &globals->scaled; - - - /* copy content */ - *scaled = *design; - - /* scale the standard widths & heights */ - for ( n = 0; n < design->num_widths; n++ ) - scaled->widths[n] = FT_MulFix( design->widths[n], x_scale ); - - for ( n = 0; n < design->num_heights; n++ ) - scaled->heights[n] = FT_MulFix( design->heights[n], y_scale ); - - /* scale the blue zones */ - for ( n = 0; n < ah_blue_max; n++ ) - { - FT_Pos delta, delta2; - - - delta = design->blue_shoots[n] - design->blue_refs[n]; - delta2 = delta; - if ( delta < 0 ) - delta2 = -delta2; - delta2 = FT_MulFix( delta2, y_scale ); - - if ( delta2 < 32 ) - delta2 = 0; - else if ( delta2 < 64 ) - delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 ); - else - delta2 = ( delta2 + 32 ) & -64; - - if ( delta < 0 ) - delta2 = -delta2; - - scaled->blue_refs[n] = - ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64; - scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2; - } - - globals->x_scale = x_scale; - globals->y_scale = y_scale; - } - - - static - void ah_hinter_align( AH_Hinter* hinter ) - { - ah_hinter_align_edge_points( hinter ); - ah_hinter_align_points( hinter ); - } - - - /* finalize a hinter object */ - void ah_hinter_done( AH_Hinter* hinter ) - { - if ( hinter ) - { - FT_Memory memory = hinter->memory; - - - ah_loader_done( hinter->loader ); - ah_outline_done( hinter->glyph ); - - /* note: the `globals' pointer is _not_ owned by the hinter */ - /* but by the current face object, we don't need to */ - /* release it */ - hinter->globals = 0; - hinter->face = 0; - - FREE( hinter ); - } - } - - - /* create a new empty hinter object */ - FT_Error ah_hinter_new( FT_Library library, - AH_Hinter** ahinter ) - { - AH_Hinter* hinter = 0; - FT_Memory memory = library->memory; - FT_Error error; - - - *ahinter = 0; - - /* allocate object */ - if ( ALLOC( hinter, sizeof ( *hinter ) ) ) - goto Exit; - - hinter->memory = memory; - hinter->flags = 0; - - /* allocate outline and loader */ - error = ah_outline_new( memory, &hinter->glyph ) || - ah_loader_new ( memory, &hinter->loader ) || - ah_loader_create_extra( hinter->loader ); - if ( error ) - goto Exit; - - *ahinter = hinter; - - Exit: - if ( error ) - ah_hinter_done( hinter ); - - return error; - } - - - /* create a face's autohint globals */ - FT_Error ah_hinter_new_face_globals( AH_Hinter* hinter, - FT_Face face, - AH_Globals* globals ) - { - FT_Error error; - FT_Memory memory = hinter->memory; - AH_Face_Globals* face_globals; - - - if ( ALLOC( face_globals, sizeof ( *face_globals ) ) ) - goto Exit; - - hinter->face = face; - hinter->globals = face_globals; - - if ( globals ) - face_globals->design = *globals; - else - ah_hinter_compute_globals( hinter ); - - face->autohint.data = face_globals; - face->autohint.finalizer = (FT_Generic_Finalizer) - ah_hinter_done_face_globals; - face_globals->face = face; - - Exit: - return error; - } - - - /* discard a face's autohint globals */ - void ah_hinter_done_face_globals( AH_Face_Globals* globals ) - { - FT_Face face = globals->face; - FT_Memory memory = face->memory; - - - FREE( globals ); - } - - - static - FT_Error ah_hinter_load( AH_Hinter* hinter, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_UInt depth ) - { - FT_Face face = hinter->face; - FT_GlyphSlot slot = face->glyph; - FT_Fixed x_scale = face->size->metrics.x_scale; - FT_Fixed y_scale = face->size->metrics.y_scale; - FT_Glyph_Metrics metrics; /* temporary metrics */ - FT_Error error; - AH_Outline* outline = hinter->glyph; - AH_Loader* gloader = hinter->loader; - FT_Bool no_horz_hints = - ( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0; - FT_Bool no_vert_hints = - ( load_flags & AH_HINT_NO_VERT_EDGES ) != 0; - - - /* load the glyph */ - error = FT_Load_Glyph( face, glyph_index, load_flags ); - if ( error ) - goto Exit; - - /* save current glyph metrics */ - metrics = slot->metrics; - - switch ( slot->format ) - { - case ft_glyph_format_outline: - /* first of all, copy the outline points in the loader's current */ - /* extra points, which is used to keep original glyph coordinates */ - error = ah_loader_check_points( gloader, slot->outline.n_points + 2, - slot->outline.n_contours ); - if ( error ) - goto Exit; - - MEM_Copy( gloader->current.extra_points, slot->outline.points, - slot->outline.n_points * sizeof ( FT_Vector ) ); - - MEM_Copy( gloader->current.outline.contours, slot->outline.contours, - slot->outline.n_contours * sizeof ( short ) ); - - MEM_Copy( gloader->current.outline.tags, slot->outline.tags, - slot->outline.n_points * sizeof ( char ) ); - - gloader->current.outline.n_points = slot->outline.n_points; - gloader->current.outline.n_contours = slot->outline.n_contours; - - /* compute original phantom points */ - hinter->pp1.x = 0; - hinter->pp1.y = 0; - hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale ); - hinter->pp2.y = 0; - - /* be sure to check for spacing glyphs */ - if ( slot->outline.n_points == 0 ) - goto Hint_Metrics; - - /* now, load the slot image into the auto-outline, and run the */ - /* automatic hinting process */ - error = ah_outline_load( outline, face ); /* XXX: change to slot */ - if ( error ) - goto Exit; - - /* perform feature detection */ - ah_outline_detect_features( outline ); - - if ( !no_horz_hints ) - { - ah_outline_compute_blue_edges( outline, hinter->globals ); - ah_outline_scale_blue_edges( outline, hinter->globals ); - } - - /* perform alignment control */ - ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints ); - ah_hinter_align( hinter ); - - /* now save the current outline into the loader's current table */ - ah_outline_save( outline, gloader ); - - /* we now need to hint the metrics according to the change in */ - /* width/positioning that occured during the hinting process */ - { - FT_Pos old_width, new_width; - FT_Pos old_advance, new_advance; - FT_Pos old_lsb, new_lsb; - AH_Edge* edge1 = outline->vert_edges; /* leftmost edge */ - AH_Edge* edge2 = edge1 + - outline->num_vedges - 1; /* rightmost edge */ - - - old_width = edge2->opos - edge1->opos; - new_width = edge2->pos - edge1->pos; - - old_advance = hinter->pp2.x; - old_lsb = edge1->opos; - new_lsb = edge1->pos; - - new_advance = old_advance + - ( new_width + new_lsb - old_width - old_lsb ); - - hinter->pp1.x = ( ( new_lsb - old_lsb ) + 32 ) & -64; - hinter->pp2.x = ( ( edge2->pos + - ( old_advance - edge2->opos ) ) + 32 ) & -64; - } - - /* good, we simply add the glyph to our loader's base */ - ah_loader_add( gloader ); - break; - - case ft_glyph_format_composite: - { - FT_UInt nn, num_subglyphs = slot->num_subglyphs; - FT_UInt num_base_subgs, start_point, start_contour; - FT_SubGlyph* subglyph; - - - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; - - /* first of all, copy the subglyph descriptors in the glyph loader */ - error = ah_loader_check_subglyphs( gloader, num_subglyphs ); - if ( error ) - goto Exit; - - MEM_Copy( gloader->current.subglyphs, slot->subglyphs, - num_subglyphs * sizeof ( FT_SubGlyph ) ); - - gloader->current.num_subglyphs = num_subglyphs; - num_base_subgs = gloader->base.num_subglyphs; - - /* now, read each subglyph independently */ - for ( nn = 0; nn < num_subglyphs; nn++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - FT_UInt num_points, num_new_points, num_base_points; - - - /* gloader.current.subglyphs can change during glyph loading due */ - /* to re-allocation -- we must recompute the current subglyph on */ - /* each iteration */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - pp1 = hinter->pp1; - pp2 = hinter->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = ah_hinter_load( hinter, subglyph->index, - load_flags, depth + 1 ); - if ( error ) - goto Exit; - - /* recompute subglyph pointer */ - subglyph = gloader->base.subglyphs + num_base_subgs + nn; - - if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) - { - pp1 = hinter->pp1; - pp2 = hinter->pp2; - } - else - { - hinter->pp1 = pp1; - hinter->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - num_new_points = num_points - num_base_points; - - /* now perform the transform required for this subglyph */ - - if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | - FT_SUBGLYPH_FLAG_XY_SCALE | - FT_SUBGLYPH_FLAG_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* org = gloader->base.extra_points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++, org++ ) - { - FT_Vector_Transform( cur, &subglyph->transform ); - FT_Vector_Transform( org, &subglyph->transform ); - } - } - - /* apply offset */ - - if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) - { - FT_Int k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = FT_Err_Invalid_Composite; - goto Exit; - } - - l += num_base_points; - - /* for now, only use the current point coordinates */ - /* we may consider another approach in the near future */ - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = FT_MulFix( subglyph->arg1, x_scale ); - y = FT_MulFix( subglyph->arg2, y_scale ); - - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; - } - - { - FT_Outline dummy = gloader->base.outline; - - - dummy.points += num_base_points; - dummy.n_points = num_new_points; - - FT_Outline_Translate( &dummy, x, y ); - } - } - } - break; - - default: - /* we don't support other formats (yet?) */ - error = FT_Err_Unimplemented_Feature; - } - - Hint_Metrics: - if ( depth == 0 ) - { - FT_BBox bbox; - - - /* we must translate our final outline by -pp1.x, and compute */ - /* the new metrics */ - if ( hinter->pp1.x ) - FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 ); - - FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; - - slot->metrics.width = bbox.xMax - bbox.xMin; - slot->metrics.height = bbox.yMax - bbox.yMin; - slot->metrics.horiBearingX = bbox.xMin; - slot->metrics.horiBearingY = bbox.yMax; - slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x; - /* XXX: TO DO - slot->linearHoriAdvance */ - - /* now copy outline into glyph slot */ - ah_loader_rewind( slot->loader ); - error = ah_loader_copy_points( slot->loader, gloader ); - if ( error ) - goto Exit; - - slot->outline = slot->loader->base.outline; - slot->format = ft_glyph_format_outline; - } - - Exit: - return error; - } - - - /* load and hint a given glyph */ - FT_Error ah_hinter_load_glyph( AH_Hinter* hinter, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ) - { - FT_Face face = slot->face; - FT_Error error; - FT_Fixed x_scale = size->metrics.x_scale; - FT_Fixed y_scale = size->metrics.y_scale; - AH_Face_Globals* face_globals = FACE_GLOBALS( face ); - - - /* first of all, we need to check that we're using the correct face and */ - /* global hints to load the glyph */ - if ( hinter->face != face || hinter->globals != face_globals ) - { - hinter->face = face; - if ( !face_globals ) - { - error = ah_hinter_new_face_globals( hinter, face, 0 ); - if ( error ) - goto Exit; - } - hinter->globals = FACE_GLOBALS( face ); - face_globals = FACE_GLOBALS( face ); - } - - /* now, we must check the current character pixel size to see if we */ - /* need to rescale the global metrics */ - if ( face_globals->x_scale != x_scale || - face_globals->y_scale != y_scale ) - ah_hinter_scale_globals( hinter, x_scale, y_scale ); - - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE; - - ah_loader_rewind( hinter->loader ); - - error = ah_hinter_load( hinter, glyph_index, load_flags, 0 ); - - Exit: - return error; - } - - - /* retrieve a face's autohint globals for client applications */ - void ah_hinter_get_global_hints( AH_Hinter* hinter, - FT_Face face, - void** global_hints, - long* global_len ) - { - AH_Globals* globals = 0; - FT_Memory memory = hinter->memory; - FT_Error error; - - - /* allocate new master globals */ - if ( ALLOC( globals, sizeof ( *globals ) ) ) - goto Fail; - - /* compute face globals if needed */ - if ( !FACE_GLOBALS( face ) ) - { - error = ah_hinter_new_face_globals( hinter, face, 0 ); - if ( error ) - goto Fail; - } - - *globals = FACE_GLOBALS( face )->design; - *global_hints = globals; - *global_len = sizeof( *globals ); - - return; - - Fail: - FREE( globals ); - - *global_hints = 0; - *global_len = 0; - } - - - void ah_hinter_done_global_hints( AH_Hinter* hinter, - void* global_hints ) - { - FT_Memory memory = hinter->memory; - - - FREE( global_hints ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahhint.h b/subsys/win32k/freetype/src/autohint/ahhint.h deleted file mode 100644 index e9eb981..0000000 --- a/subsys/win32k/freetype/src/autohint/ahhint.h +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahhint.h */ -/* */ -/* Glyph hinter (declaration). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHHINT_H -#define AHHINT_H - - -#ifdef FT_FLAT_COMPILE - -#include "ahglobal.h" - -#else - -#include - -#endif - - -#define AH_HINT_DEFAULT 0 -#define AH_HINT_NO_ALIGNMENT 1 -#define AH_HINT_NO_HORZ_EDGES 0x20000L -#define AH_HINT_NO_VERT_EDGES 0x40000L - - - /* create a new empty hinter object */ - FT_Error ah_hinter_new( FT_Library library, - AH_Hinter** ahinter ); - - /* Load a hinted glyph in the hinter */ - FT_Error ah_hinter_load_glyph( AH_Hinter* hinter, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ); - - /* finalize a hinter object */ - void ah_hinter_done( AH_Hinter* hinter ); - - LOCAL_DEF - void ah_hinter_done_face_globals( AH_Face_Globals* globals ); - - void ah_hinter_get_global_hints( AH_Hinter* hinter, - FT_Face face, - void** global_hints, - long* global_len ); - - void ah_hinter_done_global_hints( AH_Hinter* hinter, - void* global_hints ); - - -#endif /* AHHINT_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahloader.h b/subsys/win32k/freetype/src/autohint/ahloader.h deleted file mode 100644 index 4a8563c..0000000 --- a/subsys/win32k/freetype/src/autohint/ahloader.h +++ /dev/null @@ -1,124 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahloader.h */ -/* */ -/* Glyph loader for the auto-hinting module (declaration only). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This defines the AH_GlyphLoader type in two different ways: */ - /* */ - /* - If the module is compiled within FreeType 2, the type is simply a */ - /* typedef to FT_GlyphLoader. */ - /* */ - /* - If the module is compiled as a standalone object, AH_GlyphLoader */ - /* has its own implementation. */ - /* */ - /*************************************************************************/ - - -#ifndef AHLOADER_H -#define AHLOADER_H - - -#ifdef _STANDALONE_ - - typedef struct AH_GlyphLoad_ - { - FT_Outline outline; /* outline */ - FT_UInt num_subglyphs; /* number of subglyphs */ - FT_SubGlyph* subglyphs; /* subglyphs */ - FT_Vector* extra_points; /* extra points table */ - - } AH_GlyphLoad; - - - struct AH_GlyphLoader_ - { - FT_Memory memory; - FT_UInt max_points; - FT_UInt max_contours; - FT_UInt max_subglyphs; - FT_Bool use_extra; - - AH_GlyphLoad base; - AH_GlyphLoad current; - - void* other; /* for possible future extensions */ - }; - - - LOCAL_DEF - FT_Error AH_GlyphLoader_New( FT_Memory memory, - AH_GlyphLoader** aloader ); - - LOCAL_DEF - FT_Error AH_GlyphLoader_Create_Extra( AH_GlyphLoader* loader ); - - LOCAL_DEF - void AH_GlyphLoader_Done( AH_GlyphLoader* loader ); - - LOCAL_DEF - void AH_GlyphLoader_Reset( AH_GlyphLoader* loader ); - - LOCAL_DEF - void AH_GlyphLoader_Rewind( AH_GlyphLoader* loader ); - - LOCAL_DEF - FT_Error AH_GlyphLoader_Check_Points( AH_GlyphLoader* loader, - FT_UInt n_points, - FT_UInt n_contours ); - - LOCAL_DEF - FT_Error AH_GlyphLoader_Check_Subglyphs( AH_GlyphLoader* loader, - FT_UInt n_subs ); - - LOCAL_DEF - void AH_GlyphLoader_Prepare( AH_GlyphLoader* loader ); - - LOCAL_DEF - void AH_GlyphLoader_Add( AH_GlyphLoader* loader ); - - LOCAL_DEF - FT_Error AH_GlyphLoader_Copy_Points( AH_GlyphLoader* target, - FT_GlyphLoader* source ); - -#else /* _STANDALONE */ - -#include - - #define AH_Load FT_GlyphLoad - #define AH_Loader FT_GlyphLoader - - #define ah_loader_new FT_GlyphLoader_New - #define ah_loader_done FT_GlyphLoader_Done - #define ah_loader_reset FT_GlyphLoader_Reset - #define ah_loader_rewind FT_GlyphLoader_Rewind - #define ah_loader_create_extra FT_GlyphLoader_Create_Extra - #define ah_loader_check_points FT_GlyphLoader_Check_Points - #define ah_loader_check_subglyphs FT_GlyphLoader_Check_Subglyphs - #define ah_loader_prepare FT_GlyphLoader_Prepare - #define ah_loader_add FT_GlyphLoader_Add - #define ah_loader_copy_points FT_GlyphLoader_Copy_Points - -#endif /* _STANDALONE_ */ - -#endif /* AHLOADER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahmodule.c b/subsys/win32k/freetype/src/autohint/ahmodule.c deleted file mode 100644 index 2e4f707..0000000 --- a/subsys/win32k/freetype/src/autohint/ahmodule.c +++ /dev/null @@ -1,127 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahmodule.c */ -/* */ -/* Auto-hinting module implementation (declaration). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ahhint.h" - -#else - -#include - -#endif - - - typedef struct FT_AutoHinterRec_ - { - FT_ModuleRec root; - AH_Hinter* hinter; - - } FT_AutoHinterRec; - - - static - FT_Error ft_autohinter_init( FT_AutoHinter module ) - { - return ah_hinter_new( module->root.library, &module->hinter ); - } - - - static - void ft_autohinter_done( FT_AutoHinter module ) - { - ah_hinter_done( module->hinter ); - } - - - static - FT_Error ft_autohinter_load( FT_AutoHinter module, - FT_GlyphSlot slot, - FT_Size size, - FT_UInt glyph_index, - FT_ULong load_flags ) - { - return ah_hinter_load_glyph( module->hinter, - slot, size, glyph_index, load_flags ); - } - - - static - void ft_autohinter_reset( FT_AutoHinter module, - FT_Face face ) - { - UNUSED( module ); - - if ( face->autohint.data ) - ah_hinter_done_face_globals( (AH_Face_Globals*)(face->autohint.data) ); - } - - - static - void ft_autohinter_get_globals( FT_AutoHinter module, - FT_Face face, - void** global_hints, - long* global_len ) - { - ah_hinter_get_global_hints( module->hinter, face, - global_hints, global_len ); - } - - - static - void ft_autohinter_done_globals( FT_AutoHinter module, - void* global_hints ) - { - ah_hinter_done_global_hints( module->hinter, global_hints ); - } - - - static - const FT_AutoHinter_Interface autohinter_interface = - { - ft_autohinter_reset, - ft_autohinter_load, - ft_autohinter_get_globals, - ft_autohinter_done_globals - }; - - - const FT_Module_Class autohint_module_class = - { - ft_module_hinter, - sizeof ( FT_AutoHinterRec ), - - "autohinter", - 0x10000L, /* version 1.0 of the autohinter */ - 0x20000L, /* requires FreeType 2.0 or above */ - - (const void*)&autohinter_interface, - - (FT_Module_Constructor)ft_autohinter_init, - (FT_Module_Destructor) ft_autohinter_done, - (FT_Module_Requester) 0 - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahmodule.h b/subsys/win32k/freetype/src/autohint/ahmodule.h deleted file mode 100644 index 28b0753..0000000 --- a/subsys/win32k/freetype/src/autohint/ahmodule.h +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahmodule.h */ -/* */ -/* Auto-hinting module (declaration). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHMODULE_H -#define AHMODULE_H - -#include - - FT_EXPORT_VAR( const FT_Module_Class ) autohint_module_class; - -#endif /* AHMODULE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahoptim.c b/subsys/win32k/freetype/src/autohint/ahoptim.c deleted file mode 100644 index 191f5fa..0000000 --- a/subsys/win32k/freetype/src/autohint/ahoptim.c +++ /dev/null @@ -1,889 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahoptim.c */ -/* */ -/* FreeType auto hinting outline optimization (body). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This module is in charge of optimising the outlines produced by the */ - /* auto-hinter in direct mode. This is required at small pixel sizes in */ - /* order to ensure coherent spacing, among other things.. */ - /* */ - /* The technique used in this module is a simplified simulated */ - /* annealing. */ - /* */ - /*************************************************************************/ - - -#include /* for ALLOC_ARRAY() and FREE() */ - - -#ifdef FT_FLAT_COMPILE - -#include "ahoptim.h" - -#else - -#include - -#endif - - - /* define this macro to use brute force optimisation -- this is slow, */ - /* but a good way to perfect the distortion function `by hand' through */ - /* tweaking */ -#define AH_BRUTE_FORCE - - -#define xxxAH_DEBUG_OPTIM - - -#undef LOG -#ifdef AH_DEBUG_OPTIM - -#define LOG( x ) optim_log##x - -#else - -#define LOG( x ) - -#endif /* AH_DEBUG_OPTIM */ - - -#ifdef AH_DEBUG_OPTIM - -#include -#include -#include - -#define FLOAT( x ) ( (float)( (x) / 64.0 ) ) - - static - void optim_log( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); -/* vprintf( fmt, ap ); FIXME */ - va_end( ap ); - } - - - static - void AH_Dump_Stems( AH_Optimizer* optimizer ) - { - int n; - AH_Stem* stem; - - - stem = optimizer->stems; - for ( n = 0; n < optimizer->num_stems; n++, stem++ ) - { - LOG(( " %c%2d [%.1f:%.1f]={%.1f:%.1f}=" - "<%1.f..%1.f> force=%.1f speed=%.1f\n", - optimizer->vertical ? 'V' : 'H', n, - FLOAT( stem->edge1->opos ), FLOAT( stem->edge2->opos ), - FLOAT( stem->edge1->pos ), FLOAT( stem->edge2->pos ), - FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), - FLOAT( stem->force ), FLOAT( stem->velocity ) )); - } - } - - - static - void AH_Dump_Stems2( AH_Optimizer* optimizer ) - { - int n; - AH_Stem* stem; - - - stem = optimizer->stems; - for ( n = 0; n < optimizer->num_stems; n++, stem++ ) - { - LOG(( " %c%2d [%.1f]=<%1.f..%1.f> force=%.1f speed=%.1f\n", - optimizer->vertical ? 'V' : 'H', n, - FLOAT( stem->pos ), - FLOAT( stem->min_pos ), FLOAT( stem->max_pos ), - FLOAT( stem->force ), FLOAT( stem->velocity ) )); - } - } - - - static - void AH_Dump_Springs( AH_Optimizer* optimizer ) - { - int n; - AH_Spring* spring; - AH_Stem* stems; - - - spring = optimizer->springs; - stems = optimizer->stems; - LOG(( "%cSprings ", optimizer->vertical ? 'V' : 'H' )); - - for ( n = 0; n < optimizer->num_springs; n++, spring++ ) - { - LOG(( " [%d-%d:%.1f:%1.f:%.1f]", - spring->stem1 - stems, spring->stem2 - stems, - FLOAT( spring->owidth ), - FLOAT( spring->stem2->pos - - ( spring->stem1->pos + spring->stem1->width ) ), - FLOAT( spring->tension ) )); - } - - LOG(( "\n" )); - } - -#endif /* AH_DEBUG_OPTIM */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** COMPUTE STEMS AND SPRINGS IN AN OUTLINE ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - int valid_stem_segments( AH_Segment* seg1, - AH_Segment* seg2 ) - { - return seg1->serif == 0 && - seg2 && - seg2->link == seg1 && - seg1->pos < seg2->pos && - seg1->min_coord <= seg2->max_coord && - seg2->min_coord <= seg1->max_coord; - } - - - /* compute all stems in an outline */ - static - int optim_compute_stems( AH_Optimizer* optimizer ) - { - AH_Outline* outline = optimizer->outline; - FT_Fixed scale; - FT_Memory memory = optimizer->memory; - FT_Error error = 0; - FT_Int dimension; - AH_Edge* edges; - AH_Edge* edge_limit; - AH_Stem** p_stems; - FT_Int* p_num_stems; - - - edges = outline->horz_edges; - edge_limit = edges + outline->num_hedges; - scale = outline->y_scale; - - p_stems = &optimizer->horz_stems; - p_num_stems = &optimizer->num_hstems; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - AH_Stem* stems = 0; - FT_Int num_stems = 0; - AH_Edge* edge; - - - /* first of all, count the number of stems in this direction */ - for ( edge = edges; edge < edge_limit; edge++ ) - { - AH_Segment* seg = edge->first; - - - do - { - if (valid_stem_segments( seg, seg->link ) ) - num_stems++; - - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - - /* now allocate the stems and build their table */ - if ( num_stems > 0 ) - { - AH_Stem* stem; - - - if ( ALLOC_ARRAY( stems, num_stems, AH_Stem ) ) - goto Exit; - - stem = stems; - for ( edge = edges; edge < edge_limit; edge++ ) - { - AH_Segment* seg = edge->first; - AH_Segment* seg2; - - - do - { - seg2 = seg->link; - if ( valid_stem_segments( seg, seg2 ) ) - { - AH_Edge* edge1 = seg->edge; - AH_Edge* edge2 = seg2->edge; - - - stem->edge1 = edge1; - stem->edge2 = edge2; - stem->opos = edge1->opos; - stem->pos = edge1->pos; - stem->owidth = edge2->opos - edge1->opos; - stem->width = edge2->pos - edge1->pos; - - /* compute min_coord and max_coord */ - { - FT_Pos min_coord = seg->min_coord; - FT_Pos max_coord = seg->max_coord; - - - if ( seg2->min_coord > min_coord ) - min_coord = seg2->min_coord; - - if ( seg2->max_coord < max_coord ) - max_coord = seg2->max_coord; - - stem->min_coord = min_coord; - stem->max_coord = max_coord; - } - - /* compute minimum and maximum positions for stem -- */ - /* note that the left-most/bottom-most stem has always */ - /* a fixed position */ - if ( stem == stems || edge1->blue_edge || edge2->blue_edge ) - { - /* this stem cannot move; it is snapped to a blue edge */ - stem->min_pos = stem->pos; - stem->max_pos = stem->pos; - } - else - { - /* this edge can move; compute its min and max positions */ - FT_Pos pos1 = stem->opos; - FT_Pos pos2 = pos1 + stem->owidth - stem->width; - FT_Pos min1 = pos1 & -64; - FT_Pos min2 = pos2 & -64; - - - stem->min_pos = min1; - stem->max_pos = min1 + 64; - if ( min2 < min1 ) - stem->min_pos = min2; - else - stem->max_pos = min2 + 64; - - /* XXX: just to see what it does */ - stem->max_pos += 64; - - /* just for the case where direct hinting did some */ - /* incredible things (e.g. blue edge shifts) */ - if ( stem->min_pos > stem->pos ) - stem->min_pos = stem->pos; - - if ( stem->max_pos < stem->pos ) - stem->max_pos = stem->pos; - } - - stem->velocity = 0; - stem->force = 0; - - stem++; - } - seg = seg->edge_next; - - } while ( seg != edge->first ); - } - } - - *p_stems = stems; - *p_num_stems = num_stems; - - edges = outline->vert_edges; - edge_limit = edges + outline->num_vedges; - scale = outline->x_scale; - - p_stems = &optimizer->vert_stems; - p_num_stems = &optimizer->num_vstems; - } - - Exit: - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Stems( optimizer ); -#endif - - return error; - } - - - /* returns the spring area between two stems, 0 if none */ - static - FT_Pos stem_spring_area( AH_Stem* stem1, - AH_Stem* stem2 ) - { - FT_Pos area1 = stem1->max_coord - stem1->min_coord; - FT_Pos area2 = stem2->max_coord - stem2->min_coord; - FT_Pos min = stem1->min_coord; - FT_Pos max = stem1->max_coord; - FT_Pos area; - - - /* order stems */ - if ( stem2->opos <= stem1->opos + stem1->owidth ) - return 0; - - if ( min < stem2->min_coord ) - min = stem2->min_coord; - - if ( max < stem2->max_coord ) - max = stem2->max_coord; - - area = ( max-min ); - if ( 2 * area < area1 && 2 * area < area2 ) - area = 0; - - return area; - } - - - /* compute all springs in an outline */ - static - int optim_compute_springs( AH_Optimizer* optimizer ) - { - /* basically, a spring exists between two stems if most of their */ - /* surface is aligned */ - FT_Memory memory = optimizer->memory; - - AH_Stem* stems; - AH_Stem* stem_limit; - AH_Stem* stem; - int dimension; - int error = 0; - - FT_Int* p_num_springs; - AH_Spring** p_springs; - - - stems = optimizer->horz_stems; - stem_limit = stems + optimizer->num_hstems; - - p_springs = &optimizer->horz_springs; - p_num_springs = &optimizer->num_hsprings; - - for ( dimension = 1; dimension >= 0; dimension-- ) - { - FT_Int num_springs = 0; - AH_Spring* springs = 0; - - - /* first of all, count stem springs */ - for ( stem = stems; stem + 1 < stem_limit; stem++ ) - { - AH_Stem* stem2; - - - for ( stem2 = stem+1; stem2 < stem_limit; stem2++ ) - if ( stem_spring_area( stem, stem2 ) ) - num_springs++; - } - - /* then allocate and build the springs table */ - if ( num_springs > 0 ) - { - AH_Spring* spring; - - - /* allocate table of springs */ - if ( ALLOC_ARRAY( springs, num_springs, AH_Spring ) ) - goto Exit; - - /* fill the springs table */ - spring = springs; - for ( stem = stems; stem+1 < stem_limit; stem++ ) - { - AH_Stem* stem2; - FT_Pos area; - - - for ( stem2 = stem + 1; stem2 < stem_limit; stem2++ ) - { - area = stem_spring_area( stem, stem2 ); - if ( area ) - { - /* add a new spring here */ - spring->stem1 = stem; - spring->stem2 = stem2; - spring->owidth = stem2->opos - ( stem->opos + stem->owidth ); - spring->tension = 0; - - spring++; - } - } - } - } - *p_num_springs = num_springs; - *p_springs = springs; - - stems = optimizer->vert_stems; - stem_limit = stems + optimizer->num_vstems; - - p_springs = &optimizer->vert_springs; - p_num_springs = &optimizer->num_vsprings; - } - - Exit: - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Springs( optimizer ); -#endif - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** OPTIMIZE THROUGH MY STRANGE SIMULATED ANNEALING ALGO ;-) ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#ifndef AH_BRUTE_FORCE - - /* compute all spring tensions */ - static - void optim_compute_tensions( AH_Optimizer* optimizer ) - { - AH_Spring* spring = optimizer->springs; - AH_Spring* limit = spring + optimizer->num_springs; - - - for ( ; spring < limit; spring++ ) - { - AH_Stem* stem1 = spring->stem1; - AH_Stem* stem2 = spring->stem2; - FT_Int status; - - FT_Pos width; - FT_Pos tension; - FT_Pos sign; - - - /* compute the tension; it simply is -K*(new_width-old_width) */ - width = stem2->pos - ( stem1->pos + stem1->width ); - tension = width - spring->owidth; - - sign = 1; - if ( tension < 0 ) - { - sign = -1; - tension = -tension; - } - - if ( width <= 0 ) - tension = 32000; - else - tension = ( tension << 10 ) / width; - - tension = -sign * FT_MulFix( tension, optimizer->tension_scale ); - spring->tension = tension; - - /* now, distribute tension among the englobing stems, if they */ - /* are able to move */ - status = 0; - if ( stem1->pos <= stem1->min_pos ) - status |= 1; - if ( stem2->pos >= stem2->max_pos ) - status |= 2; - - if ( !status ) - tension /= 2; - - if ( ( status & 1 ) == 0 ) - stem1->force -= tension; - - if ( ( status & 2 ) == 0 ) - stem2->force += tension; - } - } - - - /* compute all stem movements -- returns 0 if nothing moved */ - static - int optim_compute_stem_movements( AH_Optimizer* optimizer ) - { - AH_Stem* stems = optimizer->stems; - AH_Stem* limit = stems + optimizer->num_stems; - AH_Stem* stem = stems; - int moved = 0; - - - /* set initial forces to velocity */ - for ( stem = stems; stem < limit; stem++ ) - { - stem->force = stem->velocity; - stem->velocity /= 2; /* XXX: Heuristics */ - } - - /* compute the sum of forces applied on each stem */ - optim_compute_tensions( optimizer ); - -#ifdef AH_DEBUG_OPTIM - AH_Dump_Springs( optimizer ); - AH_Dump_Stems2( optimizer ); -#endif - - /* now, see whether something can move */ - for ( stem = stems; stem < limit; stem++ ) - { - if ( stem->force > optimizer->tension_threshold ) - { - /* there is enough tension to move the stem to the right */ - if ( stem->pos < stem->max_pos ) - { - stem->pos += 64; - stem->velocity = stem->force / 2; - moved = 1; - } - else - stem->velocity = 0; - } - else if ( stem->force < optimizer->tension_threshold ) - { - /* there is enough tension to move the stem to the left */ - if ( stem->pos > stem->min_pos ) - { - stem->pos -= 64; - stem->velocity = stem->force / 2; - moved = 1; - } - else - stem->velocity = 0; - } - } - - /* return 0 if nothing moved */ - return moved; - } - -#endif /* AH_BRUTE_FORCE */ - - - /* compute current global distortion from springs */ - static - FT_Pos optim_compute_distortion( AH_Optimizer* optimizer ) - { - AH_Spring* spring = optimizer->springs; - AH_Spring* limit = spring + optimizer->num_springs; - FT_Pos distortion = 0; - - - for ( ; spring < limit; spring++ ) - { - AH_Stem* stem1 = spring->stem1; - AH_Stem* stem2 = spring->stem2; - FT_Pos width; - - width = stem2->pos - ( stem1->pos + stem1->width ); - width -= spring->owidth; - if ( width < 0 ) - width = -width; - - distortion += width; - } - - return distortion; - } - - - /* record stems configuration in `best of' history */ - static - void optim_record_configuration( AH_Optimizer* optimizer ) - { - FT_Pos distortion; - AH_Configuration* configs = optimizer->configs; - AH_Configuration* limit = configs + optimizer->num_configs; - AH_Configuration* config; - - - distortion = optim_compute_distortion( optimizer ); - LOG(( "config distortion = %.1f ", FLOAT( distortion * 64 ) )); - - /* check that we really need to add this configuration to our */ - /* sorted history */ - if ( limit > configs && limit[-1].distortion < distortion ) - { - LOG(( "ejected\n" )); - return; - } - - /* add new configuration at the end of the table */ - { - int n; - - - config = limit; - if ( optimizer->num_configs < AH_MAX_CONFIGS ) - optimizer->num_configs++; - else - config--; - - config->distortion = distortion; - - for ( n = 0; n < optimizer->num_stems; n++ ) - config->positions[n] = optimizer->stems[n].pos; - } - - /* move the current configuration towards the front of the list */ - /* when necessary -- yes this is slow bubble sort ;-) */ - while ( config > configs && config[0].distortion < config[-1].distortion ) - { - AH_Configuration temp; - - - config--; - temp = config[0]; - config[0] = config[1]; - config[1] = temp; - } - LOG(( "recorded!\n" )); - } - - -#ifdef AH_BRUTE_FORCE - - /* optimize outline in a single direction */ - static - void optim_compute( AH_Optimizer* optimizer ) - { - int n; - FT_Bool moved; - - AH_Stem* stem = optimizer->stems; - AH_Stem* limit = stem + optimizer->num_stems; - - - /* empty, exit */ - if ( stem >= limit ) - return; - - optimizer->num_configs = 0; - - stem = optimizer->stems; - for ( ; stem < limit; stem++ ) - stem->pos = stem->min_pos; - - do - { - /* record current configuration */ - optim_record_configuration( optimizer ); - - /* now change configuration */ - moved = 0; - for ( stem = optimizer->stems; stem < limit; stem++ ) - { - if ( stem->pos < stem->max_pos ) - { - stem->pos += 64; - moved = 1; - break; - } - - stem->pos = stem->min_pos; - } - } while ( moved ); - - /* now, set the best stem positions */ - for ( n = 0; n < optimizer->num_stems; n++ ) - { - AH_Stem* stem = optimizer->stems + n; - FT_Pos pos = optimizer->configs[0].positions[n]; - - - stem->edge1->pos = pos; - stem->edge2->pos = pos + stem->width; - - stem->edge1->flags |= ah_edge_done; - stem->edge2->flags |= ah_edge_done; - } - } - -#else /* AH_BRUTE_FORCE */ - - /* optimize outline in a single direction */ - static - void optim_compute( AH_Optimizer* optimizer ) - { - int n, counter, counter2; - - - optimizer->num_configs = 0; - optimizer->tension_scale = 0x80000L; - optimizer->tension_threshold = 64; - - /* record initial configuration threshold */ - optim_record_configuration( optimizer ); - - counter = 0; - for ( counter2 = optimizer->num_stems*8; counter2 >= 0; counter2-- ) - { - if ( counter == 0 ) - counter = 2 * optimizer->num_stems; - - if ( !optim_compute_stem_movements( optimizer ) ) - break; - - optim_record_configuration( optimizer ); - - counter--; - if ( counter == 0 ) - optimizer->tension_scale /= 2; - } - - /* now, set the best stem positions */ - for ( n = 0; n < optimizer->num_stems; n++ ) - { - AH_Stem* stem = optimizer->stems + n; - FT_Pos pos = optimizer->configs[0].positions[n]; - - - stem->edge1->pos = pos; - stem->edge2->pos = pos + stem->width; - - stem->edge1->flags |= ah_edge_done; - stem->edge2->flags |= ah_edge_done; - } - } - -#endif /* AH_BRUTE_FORCE */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** HIGH-LEVEL OPTIMIZER API ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* releases the optimization data */ - void AH_Optimizer_Done( AH_Optimizer* optimizer ) - { - if ( optimizer ) - { - FT_Memory memory = optimizer->memory; - - - FREE( optimizer->horz_stems ); - FREE( optimizer->vert_stems ); - FREE( optimizer->horz_springs ); - FREE( optimizer->vert_springs ); - FREE( optimizer->positions ); - } - } - - - /* loads the outline into the optimizer */ - int AH_Optimizer_Init( AH_Optimizer* optimizer, - AH_Outline* outline, - FT_Memory memory ) - { - FT_Error error; - - - MEM_Set( optimizer, 0, sizeof ( *optimizer ) ); - optimizer->outline = outline; - optimizer->memory = memory; - - LOG(( "initializing new optimizer\n" )); - /* compute stems and springs */ - error = optim_compute_stems ( optimizer ) || - optim_compute_springs( optimizer ); - if ( error ) - goto Fail; - - /* allocate stem positions history and configurations */ - { - int n, max_stems; - - - max_stems = optimizer->num_hstems; - if ( max_stems < optimizer->num_vstems ) - max_stems = optimizer->num_vstems; - - if ( ALLOC_ARRAY( optimizer->positions, - max_stems * AH_MAX_CONFIGS, FT_Pos ) ) - goto Fail; - - optimizer->num_configs = 0; - for ( n = 0; n < AH_MAX_CONFIGS; n++ ) - optimizer->configs[n].positions = optimizer->positions + - n * max_stems; - } - - return error; - - Fail: - AH_Optimizer_Done( optimizer ); - return error; - } - - - /* compute optimal outline */ - void AH_Optimizer_Compute( AH_Optimizer* optimizer ) - { - optimizer->num_stems = optimizer->num_hstems; - optimizer->stems = optimizer->horz_stems; - optimizer->num_springs = optimizer->num_hsprings; - optimizer->springs = optimizer->horz_springs; - - if ( optimizer->num_springs > 0 ) - { - LOG(( "horizontal optimization ------------------------\n" )); - optim_compute( optimizer ); - } - - optimizer->num_stems = optimizer->num_vstems; - optimizer->stems = optimizer->vert_stems; - optimizer->num_springs = optimizer->num_vsprings; - optimizer->springs = optimizer->vert_springs; - - if ( optimizer->num_springs ) - { - LOG(( "vertical optimization --------------------------\n" )); - optim_compute( optimizer ); - } - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahoptim.h b/subsys/win32k/freetype/src/autohint/ahoptim.h deleted file mode 100644 index d6f8542..0000000 --- a/subsys/win32k/freetype/src/autohint/ahoptim.h +++ /dev/null @@ -1,136 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahoptim.h */ -/* */ -/* FreeType auto hinting outline optimization (declaration). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHOPTIM_H -#define AHOPTIM_H - - -#ifdef FT_FLAT_COMPILE - -#include "ahtypes.h" - -#else - -#include - -#endif - - - /* the maximal number of stem configurations to record */ - /* during optimization */ -#define AH_MAX_CONFIGS 8 - - - typedef struct AH_Stem_ - { - FT_Pos pos; /* current position */ - FT_Pos velocity; /* current velocity */ - FT_Pos force; /* sum of current forces */ - FT_Pos width; /* normalized width */ - - FT_Pos min_pos; /* minimum grid position */ - FT_Pos max_pos; /* maximum grid position */ - - AH_Edge* edge1; /* left/bottom edge */ - AH_Edge* edge2; /* right/top edge */ - - FT_Pos opos; /* original position */ - FT_Pos owidth; /* original width */ - - FT_Pos min_coord; /* minimum coordinate */ - FT_Pos max_coord; /* maximum coordinate */ - - } AH_Stem; - - - /* A spring between two stems */ - typedef struct AH_Spring_ - { - AH_Stem* stem1; - AH_Stem* stem2; - FT_Pos owidth; /* original width */ - FT_Pos tension; /* current tension */ - - } AH_Spring; - - - /* A configuration records the position of each stem at a given time */ - /* as well as the associated distortion */ - typedef struct AH_Configuration_ - { - FT_Pos* positions; - FT_Long distortion; - - } AH_Configuration; - - - typedef struct AH_Optimizer_ - { - FT_Memory memory; - AH_Outline* outline; - - FT_Int num_hstems; - AH_Stem* horz_stems; - - FT_Int num_vstems; - AH_Stem* vert_stems; - - FT_Int num_hsprings; - FT_Int num_vsprings; - AH_Spring* horz_springs; - AH_Spring* vert_springs; - - FT_Int num_configs; - AH_Configuration configs[AH_MAX_CONFIGS]; - FT_Pos* positions; - - /* during each pass, use these instead */ - FT_Int num_stems; - AH_Stem* stems; - - FT_Int num_springs; - AH_Spring* springs; - FT_Bool vertical; - - FT_Fixed tension_scale; - FT_Pos tension_threshold; - - } AH_Optimizer; - - - /* loads the outline into the optimizer */ - int AH_Optimizer_Init( AH_Optimizer* optimizer, - AH_Outline* outline, - FT_Memory memory ); - - - /* compute optimal outline */ - void AH_Optimizer_Compute( AH_Optimizer* optimizer ); - - - /* release the optimization data */ - void AH_Optimizer_Done( AH_Optimizer* optimizer ); - - -#endif /* AHOPTIM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/ahtypes.h b/subsys/win32k/freetype/src/autohint/ahtypes.h deleted file mode 100644 index 9d96f15..0000000 --- a/subsys/win32k/freetype/src/autohint/ahtypes.h +++ /dev/null @@ -1,492 +0,0 @@ -/***************************************************************************/ -/* */ -/* ahtypes.h */ -/* */ -/* General types and definitions for the auto-hint module */ -/* (specification only). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#ifndef AHTYPES_H -#define AHTYPES_H - - -#include /* for freetype.h + LOCAL_DEF etc. */ - - -#ifdef FT_FLAT_COMPILE - -#include "ahloader.h" - -#else - -#include - -#endif - - -#define xxAH_DEBUG - - -#ifdef AH_DEBUG - -#include - -#define AH_LOG( x ) printf##x - -#else - -#define AH_LOG( x ) do ; while ( 0 ) /* nothing */ - -#endif - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** COMPILE-TIME BUILD OPTIONS ****/ - /**** ****/ - /**** Toggle these configuration macros to experiment with `features' ****/ - /**** of the auto-hinter. ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* If this option is defined, only strong interpolation will be used to */ - /* place the points between edges. Otherwise, `smooth' points are */ - /* detected and later hinted through weak interpolation to correct some */ - /* unpleasant artefacts. */ - /* */ -#undef AH_OPTION_NO_WEAK_INTERPOLATION - - - /*************************************************************************/ - /* */ - /* If this option is defined, only weak interpolation will be used to */ - /* place the points between edges. Otherwise, `strong' points are */ - /* detected and later hinted through strong interpolation to correct */ - /* some unpleasant artefacts. */ - /* */ -#undef AH_OPTION_NO_STRONG_INTERPOLATION - - - /*************************************************************************/ - /* */ - /* Undefine this macro if you don't want to hint the metrics. There is */ - /* no reason to do this (at least for non-CJK scripts), except for */ - /* experimentation. */ - /* */ -#define AH_HINT_METRICS - - - /*************************************************************************/ - /* */ - /* Define this macro if you do not want to insert extra edges at a */ - /* glyph's x and y extremum (if there isn't one already available). */ - /* This helps to reduce a number of artefacts and allows hinting of */ - /* metrics. */ - /* */ -#undef AH_OPTION_NO_EXTREMUM_EDGES - - - /* don't touch for now */ -#define AH_MAX_WIDTHS 12 -#define AH_MAX_HEIGHTS 12 - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** TYPE DEFINITIONS ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* see agangles.h */ - typedef FT_Int AH_Angle; - - - /* hint flags */ -#define ah_flah_none 0 - - /* bezier control points flags */ -#define ah_flah_conic 1 -#define ah_flah_cubic 2 -#define ah_flah_control ( ah_flah_conic | ah_flah_cubic ) - - /* extrema flags */ -#define ah_flah_extrema_x 4 -#define ah_flah_extrema_y 8 - - /* roundness */ -#define ah_flah_round_x 16 -#define ah_flah_round_y 32 - - /* touched */ -#define ah_flah_touch_x 64 -#define ah_flah_touch_y 128 - - /* weak interpolation */ -#define ah_flah_weak_interpolation 256 - - typedef FT_Int AH_Flags; - - - /* edge hint flags */ -#define ah_edge_normal 0 -#define ah_edge_round 1 -#define ah_edge_serif 2 -#define ah_edge_done 4 - - typedef FT_Int AH_Edge_Flags; - - - /* hint directions -- the values are computed so that two vectors are */ - /* in opposite directions iff `dir1+dir2 == 0' */ -#define ah_dir_none 4 -#define ah_dir_right 1 -#define ah_dir_left -1 -#define ah_dir_up 2 -#define ah_dir_down -2 - - typedef FT_Int AH_Direction; - - - typedef struct AH_Point AH_Point; - typedef struct AH_Segment AH_Segment; - typedef struct AH_Edge AH_Edge; - - - /*************************************************************************/ - /* */ - /* */ - /* AH_Point */ - /* */ - /* */ - /* A structure used to model an outline point to the AH_Outline type. */ - /* */ - /* */ - /* flags :: The current point hint flags. */ - /* */ - /* ox, oy :: The current original scaled coordinates. */ - /* */ - /* fx, fy :: The current coordinates in font units. */ - /* */ - /* x, y :: The current hinter coordinates. */ - /* */ - /* u, v :: Point coordinates -- meaning varies with context. */ - /* */ - /* in_dir :: The direction of the inwards vector (prev->point). */ - /* */ - /* out_dir :: The direction of the outwards vector (point->next). */ - /* */ - /* in_angle :: The angle of the inwards vector. */ - /* */ - /* out_angle :: The angle of the outwards vector. */ - /* */ - /* next :: The next point in same contour. */ - /* */ - /* prev :: The previous point in same contour. */ - /* */ - struct AH_Point - { - AH_Flags flags; /* point flags used by hinter */ - FT_Pos ox, oy; - FT_Pos fx, fy; - FT_Pos x, y; - FT_Pos u, v; - - AH_Direction in_dir; /* direction of inwards vector */ - AH_Direction out_dir; /* direction of outwards vector */ - - AH_Angle in_angle; - AH_Angle out_angle; - - AH_Point* next; /* next point in contour */ - AH_Point* prev; /* previous point in contour */ - }; - - - /*************************************************************************/ - /* */ - /* */ - /* AH_Segment */ - /* */ - /* */ - /* A structure used to describe an edge segment to the auto-hinter. */ - /* A segment is simply a sequence of successive points located on the */ - /* same horizontal or vertical `position', in a given direction. */ - /* */ - /* */ - /* flags :: The segment edge flags (straight, rounded, etc.). */ - /* */ - /* dir :: The segment direction. */ - /* */ - /* first :: The first point in the segment. */ - /* */ - /* last :: The last point in the segment. */ - /* */ - /* contour :: A pointer to the first point of the segment's */ - /* contour. */ - /* */ - /* pos :: The segment position in font units. */ - /* */ - /* size :: The segment size. */ - /* */ - /* edge :: The edge of the current segment. */ - /* */ - /* edge_next :: The next segment on the same edge. */ - /* */ - /* link :: The pairing segment for this edge. */ - /* */ - /* serif :: The primary segment for serifs. */ - /* */ - /* num_linked :: The number of other segments that link to this one. */ - /* */ - /* score :: Used to score the segment when selecting them. */ - /* */ - struct AH_Segment - { - AH_Edge_Flags flags; - AH_Direction dir; - - AH_Point* first; /* first point in edge segment */ - AH_Point* last; /* last point in edge segment */ - AH_Point** contour; /* ptr to first point of segment's contour */ - - FT_Pos pos; /* position of segment */ - FT_Pos min_coord; /* minimum coordinate of segment */ - FT_Pos max_coord; /* maximum coordinate of segment */ - - AH_Edge* edge; - AH_Segment* edge_next; - - AH_Segment* link; /* link segment */ - AH_Segment* serif; /* primary segment for serifs */ - FT_Pos num_linked; /* number of linked segments */ - FT_Int score; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* AH_Edge */ - /* */ - /* */ - /* A structure used to describe an edge, which really is a horizontal */ - /* or vertical coordinate to be hinted depending on the segments */ - /* located on it. */ - /* */ - /* */ - /* flags :: The segment edge flags (straight, rounded, etc.). */ - /* */ - /* dir :: The main segment direction on this edge. */ - /* */ - /* first :: The first edge segment. */ - /* */ - /* last :: The last edge segment. */ - /* */ - /* fpos :: The original edge position in font units. */ - /* */ - /* opos :: The original scaled edge position. */ - /* */ - /* pos :: The hinted edge position. */ - /* */ - /* link :: The linked edge. */ - /* */ - /* serif :: The serif edge. */ - /* */ - /* num_paired :: The number of other edges that pair to this one. */ - /* */ - /* score :: Used to score the edge when selecting them. */ - /* */ - /* blue_edge :: Indicate the blue zone edge this edge is related to. */ - /* Only set for some of the horizontal edges in a Latin */ - /* font. */ - /* */ - struct AH_Edge - { - AH_Edge_Flags flags; - AH_Direction dir; - - AH_Segment* first; - AH_Segment* last; - - FT_Pos fpos; - FT_Pos opos; - FT_Pos pos; - - AH_Edge* link; - AH_Edge* serif; - FT_Int num_linked; - - FT_Int score; - FT_Pos* blue_edge; - }; - - - /* an outline as seen by the hinter */ - typedef struct AH_Outline_ - { - FT_Memory memory; - - AH_Direction vert_major_dir; /* vertical major direction */ - AH_Direction horz_major_dir; /* horizontal major direction */ - - FT_Fixed x_scale; - FT_Fixed y_scale; - FT_Pos edge_distance_threshold; - - FT_Int max_points; - FT_Int num_points; - AH_Point* points; - - FT_Int max_contours; - FT_Int num_contours; - AH_Point** contours; - - FT_Int num_hedges; - AH_Edge* horz_edges; - - FT_Int num_vedges; - AH_Edge* vert_edges; - - FT_Int num_hsegments; - AH_Segment* horz_segments; - - FT_Int num_vsegments; - AH_Segment* vert_segments; - - } AH_Outline; - - -#define ah_blue_capital_top 0 /* THEZOCQS */ -#define ah_blue_capital_bottom ( ah_blue_capital_top + 1 ) /* HEZLOCUS */ -#define ah_blue_small_top ( ah_blue_capital_bottom + 1 ) /* xzroesc */ -#define ah_blue_small_bottom ( ah_blue_small_top + 1 ) /* xzroesc */ -#define ah_blue_small_minor ( ah_blue_small_bottom + 1 ) /* pqgjy */ -#define ah_blue_max ( ah_blue_small_minor + 1 ) - - typedef FT_Int AH_Blue; - - -#define ah_hinter_monochrome 1 -#define ah_hinter_optimize 2 - - typedef FT_Int AH_Hinter_Flags; - - - /*************************************************************************/ - /* */ - /* */ - /* AH_Globals */ - /* */ - /* */ - /* Holds the global metrics for a given font face (be it in design */ - /* units or scaled pixel values). */ - /* */ - /* */ - /* num_widths :: The number of widths. */ - /* */ - /* num_heights :: The number of heights. */ - /* */ - /* widths :: Snap widths, including standard one. */ - /* */ - /* heights :: Snap height, including standard one. */ - /* */ - /* blue_refs :: The reference positions of blue zones. */ - /* */ - /* blue_shoots :: The overshoot positions of blue zones. */ - /* */ - typedef struct AH_Globals_ - { - FT_Int num_widths; - FT_Int num_heights; - - FT_Pos widths [AH_MAX_WIDTHS]; - FT_Pos heights[AH_MAX_HEIGHTS]; - - FT_Pos blue_refs [ah_blue_max]; - FT_Pos blue_shoots[ah_blue_max]; - - } AH_Globals; - - - /*************************************************************************/ - /* */ - /* */ - /* AH_Face_Globals */ - /* */ - /* */ - /* Holds the complete global metrics for a given font face (i.e., the */ - /* design units version + a scaled version + the current scales */ - /* used). */ - /* */ - /* */ - /* face :: A handle to the source face object */ - /* */ - /* design :: The globals in font design units. */ - /* */ - /* scaled :: Scaled globals in sub-pixel values. */ - /* */ - /* x_scale :: The current horizontal scale. */ - /* */ - /* y_scale :: The current vertical scale. */ - /* */ - typedef struct AH_Face_Globals_ - { - FT_Face face; - AH_Globals design; - AH_Globals scaled; - FT_Fixed x_scale; - FT_Fixed y_scale; - FT_Bool control_overshoot; - - } AH_Face_Globals; - - - typedef struct AH_Hinter - { - FT_Memory memory; - AH_Hinter_Flags flags; - - FT_Int algorithm; - FT_Face face; - - AH_Face_Globals* globals; - - AH_Outline* glyph; - - AH_Loader* loader; - FT_Vector pp1; - FT_Vector pp2; - - } AH_Hinter; - - -#endif /* AHTYPES_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/autohint.c b/subsys/win32k/freetype/src/autohint/autohint.c deleted file mode 100644 index 4fb4d80..0000000 --- a/subsys/win32k/freetype/src/autohint/autohint.c +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************/ -/* */ -/* autohint.c */ -/* */ -/* Automatic Hinting wrapper (body only). */ -/* */ -/* Copyright 2000 Catharon Productions Inc. */ -/* Author: David Turner */ -/* */ -/* This file is part of the Catharon Typography Project and shall only */ -/* be used, modified, and distributed under the terms of the Catharon */ -/* Open Source License that should come with this file under the name */ -/* `CatharonLicense.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 that this license is compatible with the FreeType license. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#ifdef FT_FLAT_COMPILE - -#include "ahangles.c" -#include "ahglyph.c" -#include "ahglobal.c" -#include "ahhint.c" -#include "ahmodule.c" - -#else - -#include -#include -#include -#include -#include - -#endif - - -/* END */ diff --git a/subsys/win32k/freetype/src/autohint/mather.py b/subsys/win32k/freetype/src/autohint/mather.py deleted file mode 100644 index b416fdf..0000000 --- a/subsys/win32k/freetype/src/autohint/mather.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# - -# -# autohint math table builder -# - - -# Copyright 1996-2000 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. - - -import math - -ag_pi = 256 - -def print_arctan( atan_bits ): - atan_base = 1 << atan_bits - - print " static AH_Angle ag_arctan[1L << AG_ATAN_BITS] =" - print " {" - - count = 0 - line = " " - - for n in range( atan_base ): - comma = "," - if ( n == atan_base - 1 ): - comma = "" - - angle = math.atan( n * 1.0 / atan_base ) / math.pi * ag_pi - line = line + " " + repr( int( angle + 0.5 ) ) + comma - count = count + 1; - if ( count == 8 ): - count = 0 - print line - line = " " - - if ( count > 0 ): - print line - print " };" - - -# This routine is not used currently. -# -def print_sines(): - print " static FT_Fixed ah_sines[AG_HALF_PI + 1] =" - print " {" - - count = 0 - line = " " - - for n in range( ag_pi / 2 ): - sinus = math.sin( n * math.pi / ag_pi ) - line = line + " " + repr( int( 65536.0 * sinus ) ) + "," - count = count + 1 - if ( count == 8 ): - count = 0 - print line - line = " " - - if ( count > 0 ): - print line - print " 65536" - print " };" - - -print_arctan( 8 ) -print - - -# END diff --git a/subsys/win32k/freetype/src/autohint/module.mk b/subsys/win32k/freetype/src/autohint/module.mk deleted file mode 100644 index 71e5ee3..0000000 --- a/subsys/win32k/freetype/src/autohint/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_autohint_module - -add_autohint_module: - $(OPEN_DRIVER)autohint_module_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)autohint $(ECHO_DRIVER_DESC)automatic hinting module$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/autohint/rules.mk b/subsys/win32k/freetype/src/autohint/rules.mk deleted file mode 100644 index 87f7849..0000000 --- a/subsys/win32k/freetype/src/autohint/rules.mk +++ /dev/null @@ -1,77 +0,0 @@ -# -# FreeType 2 auto-hinter module configuration rules -# - - -# Copyright 2000 Catharon Productions Inc. -# Author: David Turner -# -# This file is part of the Catharon Typography Project and shall only -# be used, modified, and distributed under the terms of the Catharon -# Open Source License that should come with this file under the name -# `CatharonLicense.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 that this license is compatible with the FreeType license. - - -# AUTO driver directory -# -AUTO_DIR := $(SRC_)autohint -AUTO_DIR_ := $(AUTO_DIR)$(SEP) - - -# compilation flags for the driver -# -AUTO_COMPILE := $(FT_COMPILE) - - -# AUTO driver sources (i.e., C files) -# -AUTO_DRV_SRC := $(AUTO_DIR_)ahangles.c \ - $(AUTO_DIR_)ahglobal.c \ - $(AUTO_DIR_)ahglyph.c \ - $(AUTO_DIR_)ahhint.c \ - $(AUTO_DIR_)ahmodule.c - -# AUTO driver headers -# -AUTO_DRV_H := $(AUTO_DRV_SRC:%c=%h) \ - $(AUTO_DIR_)ahloader.h \ - $(AUTO_DIR_)ahtypes.h - - -# AUTO driver object(s) -# -# AUTO_DRV_OBJ_M is used during `multi' builds. -# AUTO_DRV_OBJ_S is used during `single' builds. -# -AUTO_DRV_OBJ_M := $(AUTO_DRV_SRC:$(AUTO_DIR_)%.c=$(OBJ_)%.$O) -AUTO_DRV_OBJ_S := $(OBJ_)autohint.$O - -# AUTO driver source file for single build -# -AUTO_DRV_SRC_S := $(AUTO_DIR_)autohint.c - - -# AUTO driver - single object -# -$(AUTO_DRV_OBJ_S): $(AUTO_DRV_SRC_S) $(AUTO_DRV_SRC) \ - $(FREETYPE_H) $(AUTO_DRV_H) - $(AUTO_COMPILE) $T$@ $(AUTO_DRV_SRC_S) - - -# AUTO driver - multiple objects -# -$(OBJ_)%.$O: $(AUTO_DIR_)%.c $(FREETYPE_H) $(AUTO_DRV_H) - $(AUTO_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(AUTO_DRV_OBJ_S) -DRV_OBJS_M += $(AUTO_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/base/.cvsignore b/subsys/win32k/freetype/src/base/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/base/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/base/ftbase.c b/subsys/win32k/freetype/src/base/ftbase.c deleted file mode 100644 index 1ff4eda..0000000 --- a/subsys/win32k/freetype/src/base/ftbase.c +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbase.c */ -/* */ -/* Single object library component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "ftcalc.c" -#include "ftobjs.c" -#include "ftstream.c" -#include "ftlist.c" -#include "ftoutln.c" -#include "ftextend.c" -#include "ftnames.c" - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include -#include -#include -#include -#include - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftcalc.c b/subsys/win32k/freetype/src/base/ftcalc.c deleted file mode 100644 index d27de26..0000000 --- a/subsys/win32k/freetype/src/base/ftcalc.c +++ /dev/null @@ -1,773 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Support for 1-complement arithmetic has been totally dropped in this */ - /* release. You can still write your own code if you need it. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Implementing basic computation routines. */ - /* */ - /* FT_MulDiv(), FT_MulFix(), and FT_DivFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include /* for ABS() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_calc - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static const FT_Long ft_square_roots[63] = - { - 1L, 1L, 2L, 3L, 4L, 5L, 8L, 11L, - 16L, 22L, 32L, 45L, 64L, 90L, 128L, 181L, - 256L, 362L, 512L, 724L, 1024L, 1448L, 2048L, 2896L, - 4096L, 5892L, 8192L, 11585L, 16384L, 23170L, 32768L, 46340L, - - 65536L, 92681L, 131072L, 185363L, 262144L, 370727L, - 524288L, 741455L, 1048576L, 1482910L, 2097152L, 2965820L, - 4194304L, 5931641L, 8388608L, 11863283L, 16777216L, 23726566L, - - 33554432L, 47453132L, 67108864L, 94906265L, - 134217728L, 189812531L, 268435456L, 379625062L, - 536870912L, 759250125L, 1073741824L, 1518500250L, - 2147483647L - }; - -#else - - /*************************************************************************/ - /* */ - /* */ - /* FT_Sqrt32 */ - /* */ - /* */ - /* Computes the square root of an Int32 integer (which will be */ - /* handled as an unsigned long value). */ - /* */ - /* */ - /* x :: The value to compute the root for. */ - /* */ - /* */ - /* The result of `sqrt(x)'. */ - /* */ - FT_EXPORT_FUNC( FT_Int32 ) FT_Sqrt32( FT_Int32 x ) - { - FT_ULong val, root, newroot, mask; - - - root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; - - do - { - newroot = root + mask; - if ( newroot <= val ) - { - val -= newroot; - root = newroot + mask; - } - - root >>= 1; - mask >>= 2; - - } while ( mask != 0 ); - - return root; - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#ifdef FT_LONG64 - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulDiv */ - /* */ - /* */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximal accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - - - s = 1; - if ( a < 0 ) { a = -a; s = -s; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - return s * ( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* */ - /* This function has been optimized for the case where the absolute */ - /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ - /* As this happens mainly when scaling from notional units to */ - /* fractional pixels in FreeType, it resulted in noticeable speed */ - /* improvements between versions 2.x and 1.x. */ - /* */ - /* As a conclusion, always try to place a 16.16 factor as the */ - /* _second_ argument of this function; this can make a great */ - /* difference. */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_MulFix( FT_Long a, - FT_Long b ) - { - FT_Int s; - - - s = 1; - if ( a < 0 ) { a = -a; s = -s; } - if ( b < 0 ) { b = -b; s = -s; } - - return s * (FT_Long)( ( (FT_Int64)a * b + 0x8000 ) >> 16 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DivFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*0x10000)/b'. */ - /* */ - /* */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits in */ - /* 32 bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of the old FT_MulDiv64(). */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = a; a = ABS(a); - s ^= b; b = ABS(b); - - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = ( (FT_Int64)a << 16 ) / b; - - return (FT_Int32)( s < 0 ? -q : q ); - } - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - /* a helper function for FT_Sqrt64() */ - - static - int ft_order64( FT_Int64 z ) - { - int j = 0; - - - while ( z ) - { - z = (unsigned FT_INT64)z >> 1; - j++; - } - return j - 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Sqrt64 */ - /* */ - /* */ - /* Computes the square root of a 64-bit value. That sounds stupid, */ - /* but it is needed to obtain maximal accuracy in the TrueType */ - /* bytecode interpreter. */ - /* */ - /* */ - /* l :: A 64-bit integer. */ - /* */ - /* */ - /* The 32-bit square-root. */ - /* */ - FT_EXPORT_FUNC( FT_Int32 ) FT_Sqrt64( FT_Int64 l ) - { - FT_Int64 r, s; - - - if ( l <= 0 ) return 0; - if ( l == 1 ) return 1; - - r = ft_square_roots[ft_order64( l )]; - - do - { - s = r; - r = ( r + l / r ) >> 1; - - } while ( r > s || r * r > l ); - - return r; - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - -#else /* FT_LONG64 */ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulDiv */ - /* */ - /* */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximal accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ - /* */ - /* This function isn't necessarily as fast as some processor specific */ - /* operations, but is at least completely portable. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. */ - /* c :: The divisor. */ - /* */ - /* */ - /* The result of `(a*b)/c'. This function never traps when trying to */ - /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ - /* on the signs of `a' and `b'. */ - /* */ - /* */ - /* The FT_MulDiv() function has been optimized thanks to ideas from */ - /* Graham Asher. The trick is to optimize computation if 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. */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_MulDiv( FT_Long a, - FT_Long b, - FT_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 <= 176095L && c > 0 ) - { - a = ( a * b + ( c >> 1 ) ) / c; - } - else if ( c > 0 ) - { - FT_Int64 temp, temp2; - - - FT_MulTo64( a, b, &temp ); - temp2.hi = (FT_Int32)( c >> 31 ); - temp2.lo = (FT_UInt32)( c / 2 ); - FT_Add64( &temp, &temp2, &temp ); - a = FT_Div64by32( &temp, c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximal accuracy. Most of the time, this is */ - /* used to multiply a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*b)/0x10000'. */ - /* */ - /* */ - /* The optimization for FT_MulFix() is different. We could simply be */ - /* happy by applying the same principles as with FT_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 some testing, most cases have `a' < 2048, so a good */ - /* idea is to use bounds like 2048 and 1048576 (=floor((2^31-1)/2048) */ - /* for `a' and `b', respectively. */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_MulFix( FT_Long a, - FT_Long b ) - { - FT_Long s; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - s = a; a = ABS(a); - s ^= b; b = ABS(b); - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - { - ua = ( ua * ub + 0x8000 ) >> 16; - } - else - { - FT_ULong al = ua & 0xFFFF; - - - ua = ( ua >> 16 ) * ub + - al * ( ub >> 16 ) + - ( al * ( ub & 0xFFFF ) >> 16 ); - } - - return ( s < 0 ? -(FT_Long)ua : ua ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_DivFix */ - /* */ - /* */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed float factor. */ - /* */ - /* */ - /* a :: The first multiplier. */ - /* b :: The second multiplier. Use a 16.16 factor here whenever */ - /* possible (see note below). */ - /* */ - /* */ - /* The result of `(a*0x10000)/b'. */ - /* */ - /* */ - /* The optimization for FT_DivFix() is simple: If (a << 16) fits into */ - /* 32 bits, then the division is computed directly. Otherwise, we */ - /* use a specialized version of the old FT_MulDiv64(). */ - /* */ - FT_EXPORT_FUNC( FT_Long ) FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = a; a = ABS(a); - s ^= b; b = ABS(b); - - if ( b == 0 ) - { - /* check for division by 0 */ - q = 0x7FFFFFFFL; - } - else if ( ( a >> 16 ) == 0 ) - { - /* compute result directly */ - q = (FT_UInt32)( a << 16 ) / (FT_UInt32)b; - } - else - { - /* we need more bits; we have to do it by hand */ - FT_UInt32 c; - - - q = ( a / b ) << 16; - c = a % b; - - /* we must compute C*0x10000/B: we simply shift C and B so */ - /* C becomes smaller than 16 bits */ - while ( c >> 16 ) - { - c >>= 1; - b <<= 1; - } - - q += ( c << 16 ) / b; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add64 */ - /* */ - /* */ - /* Add two Int64 values. */ - /* */ - /* */ - /* x :: A pointer to the first value to be added. */ - /* y :: A pointer to the second value to be added. */ - /* */ - /* */ - /* z :: A pointer to the result of `x + y'. */ - /* */ - /* */ - /* Will be wrapped by the ADD_64() macro. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64* z ) - { - register FT_UInt32 lo, hi; - - - lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < x->lo ); - - z->lo = lo; - z->hi = hi; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_MulTo64 */ - /* */ - /* */ - /* Multiplies two Int32 integers. Returns an Int64 integer. */ - /* */ - /* */ - /* x :: The first multiplier. */ - /* y :: The second multiplier. */ - /* */ - /* */ - /* z :: A pointer to the result of `x * y'. */ - /* */ - /* */ - /* Will be wrapped by the MUL_64() macro. */ - /* */ - FT_EXPORT_FUNC( void ) FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64* z ) - { - FT_Int32 s; - - - s = x; x = ABS( x ); - s ^= y; y = ABS( y ); - - { - FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; - - - 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 */ - i1 += i2; - if ( i1 < i2 ) - hi += 1L << 16; - - hi += i1 >> 16; - i1 = i1 << 16; - - /* Check carry overflow of i1 + lo */ - lo += i1; - hi += ( lo < i1 ); - - z->lo = lo; - z->hi = hi; - } - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Div64by32 */ - /* */ - /* */ - /* Divides an Int64 value by an Int32 value. Returns an Int32 */ - /* integer. */ - /* */ - /* */ - /* x :: A pointer to the dividend. */ - /* y :: The divisor. */ - /* */ - /* */ - /* The result of `x / y'. */ - /* */ - /* */ - /* Will be wrapped by the DIV_64() macro. */ - /* */ - FT_EXPORT_FUNC( FT_Int32 ) FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !( x->lo ); - } - s ^= y; y = ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ - return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); - /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - - /* two helper functions for FT_Sqrt64() */ - - static - void FT_Sub64( FT_Int64* x, - FT_Int64* y, - FT_Int64* z ) - { - register FT_UInt32 lo, hi; - - - lo = x->lo - y->lo; - hi = x->hi - y->hi - ( (FT_Int32)lo < 0 ); - - z->lo = lo; - z->hi = hi; - } - - - static - int ft_order64( FT_Int64* z ) - { - FT_UInt32 i; - int j; - - - i = z->lo; - j = 0; - if ( z->hi ) - { - i = z->hi; - j = 32; - } - - while ( i > 0 ) - { - i >>= 1; - j++; - } - return j - 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Sqrt64 */ - /* */ - /* */ - /* Computes the square root of a 64-bits value. That sounds stupid, */ - /* but it is needed to obtain maximal accuracy in the TrueType */ - /* bytecode interpreter. */ - /* */ - /* */ - /* z :: A pointer to a 64-bit integer. */ - /* */ - /* */ - /* The 32-bit square-root. */ - /* */ - FT_EXPORT_FUNC( FT_Int32 ) FT_Sqrt64( FT_Int64* l ) - { - FT_Int64 l2; - FT_Int32 r, s; - - - if ( (FT_Int32)l->hi < 0 || - ( l->hi == 0 && l->lo == 0 ) ) - return 0; - - s = ft_order64( l ); - if ( s == 0 ) - return 1; - - r = ft_square_roots[s]; - do - { - s = r; - r = ( r + FT_Div64by32( l, r ) ) >> 1; - FT_MulTo64( r, r, &l2 ); - FT_Sub64 ( l, &l2, &l2 ); - - } while ( r > s || (FT_Int32)l2.hi < 0 ); - - return r; - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - -#endif /* FT_LONG64 */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftdebug.c b/subsys/win32k/freetype/src/base/ftdebug.c deleted file mode 100644 index da8b3b4..0000000 --- a/subsys/win32k/freetype/src/base/ftdebug.c +++ /dev/null @@ -1,124 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.c */ -/* */ -/* Debugging and logging component (body). */ -/* */ -/* Copyright 1996-2000 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). */ - /* */ - /* - error mode */ - /* */ - /* Only error messages are generated. */ - /* */ - /* - release mode: */ - /* */ - /* No error message is sent or generated. The code is free from any */ - /* debugging parts. */ - /* */ - /*************************************************************************/ - - -#include - -#ifdef FT_DEBUG_LEVEL_TRACE - char ft_trace_levels[trace_max]; -#endif - - -#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE ) - - -#include -#include -#include - - - FT_EXPORT_FUNC( void ) FT_Message( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); -/* vprintf( fmt, ap ); FIXME */ - va_end( ap ); - } - - - FT_EXPORT_FUNC( void ) FT_Panic( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); -/* vprintf( fmt, ap ); FIXME */ - va_end( ap ); - -/* exit( EXIT_FAILURE ); FIXME */ - } - - -#ifdef FT_DEBUG_LEVEL_TRACE - - - /*************************************************************************/ - /* */ - /* */ - /* FT_SetTraceLevel */ - /* */ - /* */ - /* Sets the trace level for debugging. */ - /* */ - /* */ - /* component :: The component which should be traced. See ftdebug.h */ - /* for a complete list. If set to `trace_any', all */ - /* components will be traced. */ - /* level :: The tracing level. */ - /* */ - FT_EXPORT_FUNC( void ) FT_SetTraceLevel( FT_Trace component, - char level ) - { - if ( component >= trace_max ) - return; - - /* if component is `trace_any', change _all_ levels at once */ - if ( component == trace_any ) - { - int n; - - - for ( n = trace_any; n < trace_max; n++ ) - ft_trace_levels[n] = level; - } - else /* otherwise, only change individual component */ - ft_trace_levels[component] = level; - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - -#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftextend.c b/subsys/win32k/freetype/src/base/ftextend.c deleted file mode 100644 index f298b19..0000000 --- a/subsys/win32k/freetype/src/base/ftextend.c +++ /dev/null @@ -1,332 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftextend.h */ -/* */ -/* FreeType extensions implementation (body). */ -/* */ -/* Copyright 1996-2000 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 -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_extend - - - typedef struct FT_Extension_Registry_ - { - FT_Int num_extensions; - FT_Long cur_offset; - FT_Extension_Class classes[FT_MAX_EXTENSIONS]; - - } FT_Extension_Registry; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Init_Extensions */ - /* */ - /* */ - /* Initializes the extension component. */ - /* */ - /* */ - /* driver :: A handle to the driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error FT_Init_Extensions( FT_Driver driver ) - { - FT_Error error; - FT_Memory memory; - FT_Extension_Registry* registry; - - - memory = driver->root.library->memory; - if ( ALLOC( registry, sizeof ( *registry ) ) ) - return error; - - registry->num_extensions = 0; - registry->cur_offset = 0; - driver->extensions = registry; - - FT_TRACE2(( "FT_Init_Extensions: success\n" )); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Extensions */ - /* */ - /* */ - /* Finalizes the extension component. */ - /* */ - /* */ - /* driver :: A handle to the driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error FT_Done_Extensions( FT_Driver driver ) - { - FT_Memory memory = driver->root.memory; - - - FREE( driver->extensions ); - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Register_Extension */ - /* */ - /* */ - /* Registers a new extension. */ - /* */ - /* */ - /* driver :: A handle to the driver object. */ - /* class :: A pointer to a class describing the extension. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Register_Extension( - FT_Driver driver, - FT_Extension_Class* clazz ) - { - FT_Extension_Registry* registry; - - - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - if ( !clazz ) - return FT_Err_Invalid_Argument; - - registry = (FT_Extension_Registry*)driver->extensions; - if ( registry ) - { - FT_Int n = registry->num_extensions; - FT_Extension_Class* cur = registry->classes + n; - - - if ( n >= FT_MAX_EXTENSIONS ) - return FT_Err_Too_Many_Extensions; - - *cur = *clazz; - - cur->offset = registry->cur_offset; - - registry->num_extensions++; - registry->cur_offset += - ( cur->size + FT_ALIGNMENT - 1 ) & -FT_ALIGNMENT; - - FT_TRACE1(( "FT_Register_Extension: `%s' successfully registered\n", - cur->id )); - } - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Extension */ - /* */ - /* */ - /* Queries an extension block by an extension ID string. */ - /* */ - /* */ - /* face :: A handle to the face object. */ - /* extension_id :: An ID string identifying the extension. */ - /* */ - /* */ - /* extension_interface :: A generic pointer, usually pointing to a */ - /* table of functions implementing the */ - /* extension interface. */ - /* */ - /* */ - /* A generic pointer to the extension block. */ - /* */ - FT_EXPORT_FUNC( void* ) FT_Get_Extension( - FT_Face face, - const char* extension_id, - void** extension_interface ) - { - FT_Extension_Registry* registry; - - - if ( !face || !extension_id || !extension_interface ) - return 0; - - registry = (FT_Extension_Registry*)face->driver->extensions; - if ( registry && face->extensions ) - { - FT_Extension_Class* cur = registry->classes; - FT_Extension_Class* limit = cur + registry->num_extensions; - - - for ( ; cur < limit; cur++ ) - if ( strcmp( cur->id, extension_id ) == 0 ) - { - *extension_interface = cur->interface; - - FT_TRACE1(( "FT_Get_Extension: got `%s'\n", extension_id )); - - return (void*)((char*)face->extensions + cur->offset); - } - } - - /* could not find the extension id */ - - FT_ERROR(( "FT_Get_Extension: couldn't find `%s'\n", extension_id )); - - *extension_interface = 0; - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Destroy_Extensions */ - /* */ - /* */ - /* Destroys all extensions within a face object. */ - /* */ - /* */ - /* face :: A handle to the face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Called by the face object destructor. */ - /* */ - LOCAL_FUNC - FT_Error FT_Destroy_Extensions( FT_Face face ) - { - FT_Extension_Registry* registry; - FT_Memory memory; - - - registry = (FT_Extension_Registry*)face->driver->extensions; - if ( registry && face->extensions ) - { - FT_Extension_Class* cur = registry->classes; - FT_Extension_Class* limit = cur + registry->num_extensions; - - - for ( ; cur < limit; cur++ ) - { - char* ext = (char*)face->extensions + cur->offset; - - if ( cur->finalize ) - cur->finalize( ext, face ); - } - - memory = face->driver->root.memory; - FREE( face->extensions ); - } - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Create_Extensions */ - /* */ - /* */ - /* Creates an extension object within a face object for all */ - /* registered extensions. */ - /* */ - /* */ - /* face :: A handle to the face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Called by the face object constructor. */ - /* */ - LOCAL_FUNC - FT_Error FT_Create_Extensions( FT_Face face ) - { - FT_Extension_Registry* registry; - FT_Memory memory; - FT_Error error; - - - face->extensions = 0; - - /* load extensions registry; exit successfully if none is there */ - - registry = (FT_Extension_Registry*)face->driver->extensions; - if ( !registry ) - return FT_Err_Ok; - - memory = face->driver->root.memory; - if ( ALLOC( face->extensions, registry->cur_offset ) ) - return error; - - { - FT_Extension_Class* cur = registry->classes; - FT_Extension_Class* limit = cur + registry->num_extensions; - - - for ( ; cur < limit; cur++ ) - { - char* ext = (char*)face->extensions + cur->offset; - - if ( cur->init ) - { - error = cur->init( ext, face ); - if ( error ) - break; - } - } - } - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftglyph.c b/subsys/win32k/freetype/src/base/ftglyph.c deleted file mode 100644 index 4052e6e..0000000 --- a/subsys/win32k/freetype/src/base/ftglyph.c +++ /dev/null @@ -1,1184 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.c */ -/* */ -/* FreeType convenience functions to handle glyphs (body). */ -/* */ -/* Copyright 1996-2000 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 contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_glyph - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** Convenience functions ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Multiply */ - /* */ - /* */ - /* Performs the matrix operation `b = a*b'. */ - /* */ - /* */ - /* a :: A pointer to matrix `a'. */ - /* */ - /* */ - /* b :: A pointer to matrix `b'. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `a' or `b' is zero. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Matrix_Multiply( FT_Matrix* a, - FT_Matrix* b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Matrix_Invert */ - /* */ - /* */ - /* Inverts a 2x2 matrix. Returns an error if it can't be inverted. */ - /* */ - /* */ - /* matrix :: A pointer to the target matrix. Remains untouched in */ - /* case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_Err_Invalid_Argument; - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_Err_Invalid_Argument; /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_BitmapGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - static - FT_Error ft_bitmap_copy( FT_Memory memory, - FT_Bitmap* source, - FT_Bitmap* target ) - { - FT_Error error; - FT_Int pitch = source->pitch; - FT_ULong size; - - - *target = *source; - - if ( pitch < 0 ) - pitch = -pitch; - - size = (FT_ULong)( pitch * source->rows ); - - if ( !ALLOC( target->buffer, size ) ) - MEM_Copy( source->buffer, target->buffer, size ); - - return error; - } - - - static - FT_Error ft_bitmap_glyph_init( FT_BitmapGlyph glyph, - FT_GlyphSlot slot ) - { - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH(glyph)->library; - FT_Memory memory = library->memory; - - - if ( slot->format != ft_glyph_format_bitmap ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - /* grab the bitmap in the slot - do lazy copying whenever possible */ - glyph->bitmap = slot->bitmap; - glyph->left = slot->bitmap_left; - glyph->top = slot->bitmap_top; - - if ( slot->flags & ft_glyph_own_bitmap ) - slot->flags &= ~ft_glyph_own_bitmap; - else - { - /* copy the bitmap into a new buffer */ - error = ft_bitmap_copy( memory, &slot->bitmap, &glyph->bitmap ); - } - - Exit: - return error; - } - - - static - FT_Error ft_bitmap_glyph_copy( FT_BitmapGlyph source, - FT_BitmapGlyph target ) - { - FT_Memory memory = source->root.library->memory; - - - target->left = source->left; - target->top = source->top; - - return ft_bitmap_copy( memory, &source->bitmap, &target->bitmap ); - } - - - static - void ft_bitmap_glyph_done( FT_BitmapGlyph glyph ) - { - FT_Memory memory = FT_GLYPH(glyph)->library->memory; - - - FREE( glyph->bitmap.buffer ); - } - - - static - void ft_bitmap_glyph_bbox( FT_BitmapGlyph glyph, - FT_BBox* cbox ) - { - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->xMax - ( glyph->bitmap.rows << 6 ); - } - - - const FT_Glyph_Class ft_bitmap_glyph_class = - { - sizeof( FT_BitmapGlyphRec ), - ft_glyph_format_bitmap, - - (FT_Glyph_Init_Func) ft_bitmap_glyph_init, - (FT_Glyph_Done_Func) ft_bitmap_glyph_done, - (FT_Glyph_Copy_Func) ft_bitmap_glyph_copy, - (FT_Glyph_Transform_Func)0, - (FT_Glyph_BBox_Func) ft_bitmap_glyph_bbox, - (FT_Glyph_Prepare_Func) 0 - }; - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_OutlineGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error ft_outline_glyph_init( FT_OutlineGlyph glyph, - FT_GlyphSlot slot ) - { - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH(glyph)->library; - FT_Outline* source = &slot->outline; - FT_Outline* target = &glyph->outline; - - - /* check format in glyph slot */ - if ( slot->format != ft_glyph_format_outline ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, - &glyph->outline ); - if ( error ) - goto Exit; - - /* copy it */ - MEM_Copy( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); - - MEM_Copy( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); - - MEM_Copy( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); - - /* copy all flags, except the `ft_outline_owner' one */ - target->flags = source->flags | ft_outline_owner; - - Exit: - return error; - } - - - static - void ft_outline_glyph_done( FT_OutlineGlyph glyph ) - { - FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); - } - - - static - FT_Error ft_outline_glyph_copy( FT_OutlineGlyph source, - FT_OutlineGlyph target ) - { - FT_Error error; - FT_Library library = FT_GLYPH( source )->library; - - - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); - if ( !error ) - FT_Outline_Copy( &source->outline, &target->outline ); - - return error; - } - - - static - void ft_outline_glyph_transform( FT_OutlineGlyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ) - { - if ( matrix ) - FT_Outline_Transform( &glyph->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); - } - - - static - void ft_outline_glyph_bbox( FT_OutlineGlyph glyph, - FT_BBox* bbox ) - { - FT_Outline_Get_CBox( &glyph->outline, bbox ); - } - - - static - FT_Error ft_outline_glyph_prepare( FT_OutlineGlyph glyph, - FT_GlyphSlot slot ) - { - slot->format = ft_glyph_format_outline; - slot->outline = glyph->outline; - slot->outline.flags &= ~ft_outline_owner; - - return FT_Err_Ok; - } - - - const FT_Glyph_Class ft_outline_glyph_class = - { - sizeof( FT_OutlineGlyphRec ), - ft_glyph_format_outline, - - (FT_Glyph_Init_Func) ft_outline_glyph_init, - (FT_Glyph_Done_Func) ft_outline_glyph_done, - (FT_Glyph_Copy_Func) ft_outline_glyph_copy, - (FT_Glyph_Transform_Func)ft_outline_glyph_transform, - (FT_Glyph_BBox_Func) ft_outline_glyph_bbox, - (FT_Glyph_Prepare_Func) ft_outline_glyph_prepare - }; - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_Glyph class and API ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - static - FT_Error ft_new_glyph( FT_Library library, - const FT_Glyph_Class* clazz, - FT_Glyph* aglyph ) - { - FT_Memory memory = library->memory; - FT_Error error; - FT_Glyph glyph; - - - *aglyph = 0; - - if ( !ALLOC( glyph, clazz->glyph_size ) ) - { - glyph->library = library; - glyph->clazz = clazz; - glyph->format = clazz->glyph_format; - - *aglyph = glyph; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Copy */ - /* */ - /* */ - /* A function used to copy a glyph image. */ - /* */ - /* */ - /* source :: A handle to the source glyph object. */ - /* */ - /* */ - /* target :: A handle to the target glyph object. 0 in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Glyph_Copy( FT_Glyph source, - FT_Glyph* target ) - { - FT_Glyph copy; - FT_Error error; - const FT_Glyph_Class* clazz; - - - /* check arguments */ - if ( !target || !source || !source->clazz ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - *target = 0; - - clazz = source->clazz; - error = ft_new_glyph( source->library, clazz, © ); - if ( error ) - goto Exit; - - if ( clazz->glyph_copy ) - error = clazz->glyph_copy( source, copy ); - - if ( error ) - FT_Done_Glyph( copy ); - else - *target = copy; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph */ - /* */ - /* */ - /* A function used to extract a glyph image from a slot. */ - /* */ - /* */ - /* slot :: A handle to the source glyph slot. */ - /* */ - /* */ - /* aglyph :: A handle to the glyph object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph* aglyph ) - { - FT_Library library = slot->library; - FT_Error error; - FT_Glyph glyph; - - const FT_Glyph_Class* clazz = 0; - - - if ( !slot ) - return FT_Err_Invalid_Slot_Handle; - - if ( !aglyph ) - return FT_Err_Invalid_Argument; - - /* if it is a bitmap, that's easy :-) */ - if ( slot->format == ft_glyph_format_bitmap ) - clazz = &ft_bitmap_glyph_class; - - /* it it is an outline too */ - else if ( slot->format == ft_glyph_format_outline ) - clazz = &ft_outline_glyph_class; - - else - { - /* try to find a renderer that supports the glyph image format */ - FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); - - - if ( render ) - clazz = &render->glyph_class; - } - - if ( !clazz ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - /* create FT_Glyph object */ - error = ft_new_glyph( library, clazz, &glyph ); - if ( error ) - goto Exit; - - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; - - /* now import the image from the glyph slot */ - error = clazz->glyph_init( glyph, slot ); - - /* if an error occurred, destroy the glyph */ - if ( error ) - FT_Done_Glyph( glyph ); - else - *aglyph = glyph; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Transform */ - /* */ - /* */ - /* Transforms a glyph image if its format is scalable. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - /* matrix :: A pointer to a 2x2 matrix to apply. */ - /* */ - /* delta :: A pointer to a 2d vector to apply. Coordinates are */ - /* expressed in 1/64th of a pixel. */ - /* */ - /* */ - /* FreeType error code (the glyph format is not scalable if it is */ - /* not zero). */ - /* */ - /* */ - /* The 2x2 transformation matrix is also applied to the glyph's */ - /* advance vector. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ) - { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; - - - if ( !glyph || !glyph->clazz ) - error = FT_Err_Invalid_Argument; - else - { - clazz = glyph->clazz; - if ( clazz->glyph_transform ) - { - /* transform glyph image */ - clazz->glyph_transform( glyph, matrix, delta ); - - /* transform advance vector */ - if ( matrix ) - FT_Vector_Transform( &glyph->advance, matrix ); - } - else - error = FT_Err_Invalid_Glyph_Format; - } - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_Get_CBox */ - /* */ - /* */ - /* Returns the glyph image's bounding box. */ - /* */ - /* */ - /* glyph :: A handle to the source glyph object. */ - /* */ - /* mode :: A set of bit flags that indicate how to interpret the */ - /* returned bounding box values. */ - /* */ - /* */ - /* box :: The glyph bounding box. Coordinates are expressed in */ - /* 1/64th of pixels if it is grid-fitted. */ - /* */ - /* */ - /* Coordinates are relative to the glyph origin, using the Y-upwards */ - /* convention. */ - /* */ - /* If `ft_glyph_bbox_subpixels' is set in `mode', the bbox */ - /* coordinates are returned in 26.6 pixels (i.e. 1/64th of pixels). */ - /* Otherwise, coordinates are expressed in integer pixels. */ - /* */ - /* Note that the maximum coordinates are exclusive, which means that */ - /* one can compute the width and height of the glyph image (be it in */ - /* integer or 26.6 pixels) as: */ - /* */ - /* width = bbox.xMax - bbox.xMin; */ - /* height = bbox.yMax - bbox.yMin; */ - /* */ - /* Note also that for 26.6 coordinates, if the */ - /* `ft_glyph_bbox_gridfit' flag is set in `mode;, the coordinates */ - /* will also be grid-fitted, which corresponds to: */ - /* */ - /* bbox.xMin = FLOOR(bbox.xMin); */ - /* bbox.yMin = FLOOR(bbox.yMin); */ - /* bbox.xMax = CEILING(bbox.xMax); */ - /* bbox.yMax = CEILING(bbox.yMax); */ - /* */ - /* The default value (0) for `bbox_mode' is `ft_glyph_bbox_pixels'. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox* cbox ) - { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; - - - if ( !cbox || !glyph || !glyph->clazz ) - error = FT_Err_Invalid_Argument; - else - { - clazz = glyph->clazz; - if ( !clazz->glyph_bbox ) - error = FT_Err_Invalid_Glyph_Format; - else - { - /* retrieve bbox in 26.6 coordinates */ - clazz->glyph_bbox( glyph, cbox ); - - /* perform grid fitting if needed */ - if ( bbox_mode & ft_glyph_bbox_gridfit ) - { - cbox->xMin &= -64; - cbox->yMin &= -64; - cbox->xMax = ( cbox->xMax + 63 ) & -64; - cbox->yMax = ( cbox->yMax + 63 ) & -64; - } - - /* convert to integer pixels if needed */ - if ( !( bbox_mode & ft_glyph_bbox_subpixels ) ) - { - cbox->xMin >>= 6; - cbox->yMin >>= 6; - cbox->xMax >>= 6; - cbox->yMax >>= 6; - } - } - } - return; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Glyph_To_Bitmap */ - /* */ - /* */ - /* Converts a given glyph object to a bitmap glyph object. */ - /* */ - /* */ - /* glyph :: A pointer to a handle to the target glyph. */ - /* */ - /* */ - /* render_mode :: A set of bit flags that describe how the data is */ - /* */ - /* */ - /* origin :: A pointer to a vector used to translate the glyph */ - /* image before rendering. Can be 0 (if no */ - /* translation). The origin is expressed in */ - /* 26.6 pixels. */ - /* */ - /* destroy :: A boolean that indicates that the original glyph */ - /* image should be destroyed by this function. It is */ - /* never destroyed in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The glyph image is translated with the `origin' vector before */ - /* rendering. In case of error, it it translated back to its */ - /* original position and the glyph is left untouched. */ - /* */ - /* The first parameter is a pointer to a FT_Glyph handle, that will */ - /* be replaced by this function. Typically, you would use (omitting */ - /* error handling): */ - /* */ - /* */ - /* { */ - /* FT_Glyph glyph; */ - /* FT_BitmapGlyph glyph_bitmap; */ - /* */ - /* */ - /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ - /* */ - /* // extract glyph image */ - /* error = FT_Get_Glyph( face->glyph, &glyph ); */ - /* */ - /* // convert to a bitmap (default render mode + destroy old) */ - /* if ( glyph->format != ft_glyph_format_bitmap ) */ - /* { */ - /* error = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_default, */ - /* 0, 1 ); */ - /* if ( error ) // glyph unchanged */ - /* ... */ - /* } */ - /* */ - /* // access bitmap content by typecasting */ - /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ - /* */ - /* // do funny stuff with it, like blitting/drawing */ - /* ... */ - /* */ - /* // discard glyph image (bitmap or not) */ - /* FT_Done_Glyph( glyph ); */ - /* } */ - /* */ - /* */ - /* This function will always fail if the glyph's format isn't */ - /* scalable. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_ULong render_mode, - FT_Vector* origin, - FT_Bool destroy ) - { - FT_GlyphSlotRec dummy; - FT_Error error; - FT_Glyph glyph; - FT_BitmapGlyph bitmap; - - const FT_Glyph_Class* clazz; - - - /* check argument */ - if ( !the_glyph ) - goto Bad; - - /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ - /* then calling FT_Render_Glyph_Internal() */ - - glyph = *the_glyph; - if ( !glyph ) - goto Bad; - - clazz = glyph->clazz; - if ( !clazz || !clazz->glyph_prepare ) - goto Bad; - - MEM_Set( &dummy, 0, sizeof ( dummy ) ); - dummy.library = glyph->library; - dummy.format = clazz->glyph_format; - - /* if `origin' is set, translate the glyph image */ - if ( origin ) - FT_Glyph_Transform( glyph, 0, origin ); - - /* create result bitmap glyph */ - error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, - (FT_Glyph*)&bitmap ); - if ( error ) - goto Exit; - - /* prepare dummy slot for rendering */ - error = clazz->glyph_prepare( glyph, &dummy ) || - FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); - - if ( !destroy && origin ) - { - FT_Vector v; - - - v.x = -origin->x; - v.y = -origin->y; - FT_Glyph_Transform( glyph, 0, &v ); - } - - /* in case of succes, copy the bitmap to the glyph bitmap */ - if ( !error ) - { - error = ft_bitmap_glyph_init( bitmap, &dummy ); - if ( error ) - { - /* this should never happen, but let's be safe */ - FT_Done_Glyph( FT_GLYPH( bitmap ) ); - goto Exit; - } - - if ( destroy ) - FT_Done_Glyph( glyph ); - - *the_glyph = FT_GLYPH( bitmap ); - } - - Exit: - return error; - - Bad: - error = FT_Err_Invalid_Argument; - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Glyph */ - /* */ - /* */ - /* Destroys a given glyph. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph object. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Done_Glyph( FT_Glyph glyph ) - { - if ( glyph ) - { - FT_Memory memory = glyph->library->memory; - const FT_Glyph_Class* clazz = glyph->clazz; - - - if ( clazz->glyph_done ) - clazz->glyph_done( glyph ); - - FREE( glyph ); - } - } - - -#if 0 - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /* Compute the norm of a vector */ - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static - FT_Pos ft_norm( FT_Vector* vec ) - { - FT_Int64 t1, t2; - - - MUL_64( vec->x, vec->x, t1 ); - MUL_64( vec->y, vec->y, t2 ); - ADD_64( t1, t2, t1 ); - - return (FT_Pos)SQRT_64( t1 ); - } - -#else /* FT_CONFIG_OPTION_OLD_CALCS */ - - static - FT_Pos ft_norm( FT_Vector* vec ) - { - FT_F26Dot6 u, v, d; - FT_Int shift; - FT_ULong H, L, L2, hi, lo, med; - - - u = vec->x; if ( u < 0 ) u = -u; - v = vec->y; if ( v < 0 ) v = -v; - - if ( u < v ) - { - d = u; - u = v; - v = d; - } - - /* check that we are not trying to normalize zero! */ - if ( u == 0 ) - return 0; - - /* compute (u*u + v*v) on 64 bits with two 32-bit registers [H:L] */ - hi = (FT_ULong)u >> 16; - lo = (FT_ULong)u & 0xFFFF; - med = hi * lo; - - H = hi * hi + ( med >> 15 ); - med <<= 17; - L = lo * lo + med; - if ( L < med ) - H++; - - hi = (FT_ULong)v >> 16; - lo = (FT_ULong)v & 0xFFFF; - med = hi * lo; - - H += hi * hi + ( med >> 15 ); - med <<= 17; - L2 = lo * lo + med; - if ( L2 < med ) - H++; - - L += L2; - if ( L < L2 ) - H++; - - /* if the value is smaller than 32 bits */ - shift = 0; - if ( H == 0 ) - { - while ( ( L & 0xC0000000UL ) == 0 ) - { - L <<= 2; - shift++; - } - return ( FT_Sqrt32( L ) >> shift ); - } - else - { - while ( H ) - { - L = ( L >> 2 ) | ( H << 30 ); - H >>= 2; - shift++; - } - return ( FT_Sqrt32( L ) << shift ); - } - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - - static - int ft_test_extrema( FT_Outline* outline, - int n ) - { - FT_Vector *prev, *cur, *next; - FT_Pos product; - FT_Int first, last; - - - /* we need to compute the `previous' and `next' point */ - /* for these extrema. */ - cur = outline->points + n; - prev = cur - 1; - next = cur + 1; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - last = outline->contours[c]; - - if ( n == first ) - prev = outline->points + last; - - if ( n == last ) - next = outline->points + first; - - first = last + 1; - } - - product = FT_MulDiv( cur->x - prev->x, /* in.x */ - next->y - cur->y, /* out.y */ - 0x40 ) - - - FT_MulDiv( cur->y - prev->y, /* in.y */ - next->x - cur->x, /* out.x */ - 0x40 ); - - if ( product ) - product = product > 0 ? 1 : -1; - - return product; - } - - - /* Compute the orientation of path filling. It differs between TrueType */ - /* and Type1 formats. We could use the `ft_outline_reverse_fill' flag, */ - /* but it is better to re-compute it directly (it seems that this flag */ - /* isn't correctly set for some weird composite glyphs currently). */ - /* */ - /* We do this by computing bounding box points, and computing their */ - /* curvature. */ - /* */ - /* The function returns either 1 or -1. */ - /* */ - static - int ft_get_orientation( FT_Outline* outline ) - { - FT_BBox box; - FT_BBox indices; - int n, last; - - - indices.xMin = -1; - indices.yMin = -1; - indices.xMax = -1; - indices.yMax = -1; - - box.xMin = box.yMin = 32767; - box.xMax = box.yMax = -32768; - - /* is it empty ? */ - if ( outline->n_contours < 1 ) - return 1; - - last = outline->contours[outline->n_contours - 1]; - - for ( n = 0; n <= last; n++ ) - { - FT_Pos x, y; - - - x = outline->points[n].x; - if ( x < box.xMin ) - { - box.xMin = x; - indices.xMin = n; - } - if ( x > box.xMax ) - { - box.xMax = x; - indices.xMax = n; - } - - y = outline->points[n].y; - if ( y < box.yMin ) - { - box.yMin = y; - indices.yMin = n; - } - if ( y > box.yMax ) - { - box.yMax = y; - indices.yMax = n; - } - } - - /* test orientation of the xmin */ - return ft_test_extrema( outline, indices.xMin ) || - ft_test_extrema( outline, indices.yMin ) || - ft_test_extrema( outline, indices.xMax ) || - ft_test_extrema( outline, indices.yMax ) || - 1; /* this is an empty glyph? */ - } - - - static - FT_Error ft_embolden( FT_Face original, - FT_Outline* outline, - FT_Pos* advance ) - { - FT_Vector u, v; - FT_Vector* points; - FT_Vector cur, prev, next; - FT_Pos distance; - int c, n, first, orientation; - - FT_UNUSED( advance ); - - - /* compute control distance */ - distance = FT_MulFix( original->em_size / 60, - original->size->metrics.y_scale ); - - orientation = ft_get_orientation( &original->glyph->outline ); - - points = original->glyph->outline.points; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - int last = outline->contours[c]; - - - prev = points[last]; - - for ( n = first; n <= last; n++ ) - { - FT_Pos norm, delta, d; - FT_Vector in, out; - - - cur = points[n]; - if ( n < last ) next = points[n + 1]; - else next = points[first]; - - /* compute the in and out vectors */ - in.x = cur.x - prev.x; - in.y = cur.y - prev.y; - - out.x = next.x - cur.x; - out.y = next.y - cur.y; - - /* compute U and V */ - norm = ft_norm( &in ); - u.x = orientation * FT_DivFix( in.y, norm ); - u.y = orientation * -FT_DivFix( in.x, norm ); - - norm = ft_norm( &out ); - v.x = orientation * FT_DivFix( out.y, norm ); - v.y = orientation * -FT_DivFix( out.x, norm ); - - d = distance; - - if ( ( outline->flags[n] & FT_Curve_Tag_On ) == 0 ) - d *= 2; - - /* Check discriminant for parallel vectors */ - delta = FT_MulFix( u.x, v.y ) - FT_MulFix( u.y, v.x ); - if ( delta > FT_BOLD_THRESHOLD || delta < -FT_BOLD_THRESHOLD ) - { - /* Move point -- compute A and B */ - FT_Pos x, y, A, B; - - - A = d + FT_MulFix( cur.x, u.x ) + FT_MulFix( cur.y, u.y ); - B = d + FT_MulFix( cur.x, v.x ) + FT_MulFix( cur.y, v.y ); - - x = FT_MulFix( A, v.y ) - FT_MulFix( B, u.y ); - y = FT_MulFix( B, u.x ) - FT_MulFix( A, v.x ); - - outline->points[n].x = distance + FT_DivFix( x, delta ); - outline->points[n].y = distance + FT_DivFix( y, delta ); - } - else - { - /* Vectors are nearly parallel */ - FT_Pos x, y; - - - x = distance + cur.x + FT_MulFix( d, u.x + v.x ) / 2; - y = distance + cur.y + FT_MulFix( d, u.y + v.y ) / 2; - - outline->points[n].x = x; - outline->points[n].y = y; - } - - prev = cur; - } - - first = last + 1; - } - - if ( advance ) - *advance = ( *advance + distance * 4 ) & -64; - - return 0; - } - -#endif /* 0 -- EXPERIMENTAL STUFF! */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftinit.c b/subsys/win32k/freetype/src/base/ftinit.c deleted file mode 100644 index 1d6590a..0000000 --- a/subsys/win32k/freetype/src/base/ftinit.c +++ /dev/null @@ -1,156 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftinit.c */ -/* */ -/* FreeType initialization layer (body). */ -/* */ -/* Copyright 1996-2000 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 purpose of this file is to implement the following two */ - /* functions: */ - /* */ - /* FT_Add_Default_Modules(): */ - /* This function is used to add the set of default modules to a */ - /* fresh new library object. The set is taken from the header file */ - /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ - /* Build System' for more information. */ - /* */ - /* FT_Init_FreeType(): */ - /* This function creates a system object for the current platform, */ - /* builds a library out of it, then calls FT_Default_Drivers(). */ - /* */ - /* Note that even if FT_Init_FreeType() uses the implementation of the */ - /* system object defined at build time, client applications are still */ - /* able to provide their own `ftsystem.c'. */ - /* */ - /*************************************************************************/ - - -#include -#include - -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_init - -#undef FT_USE_MODULE -#define FT_USE_MODULE( x ) extern const FT_Module_Class* x; - -#ifdef macintosh - FT_USE_MODULE(fond_driver_class) -#endif -#include - -#undef FT_USE_MODULE -#define FT_USE_MODULE( x ) (const FT_Module_Class*)&x, - -static -const FT_Module_Class* ft_default_modules[] = - { -#ifdef macintosh - FT_USE_MODULE(fond_driver_class) -#endif -#include - 0 - }; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Default_Modules */ - /* */ - /* */ - /* Adds the set of default drivers to a given library object. */ - /* This is only useful when you create a library object with */ - /* FT_New_Library() (usually to plug a custom memory manager). */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Add_Default_Modules( FT_Library library ) - { - FT_Error error; - const FT_Module_Class** cur; - - - /* test for valid `library' delayed to FT_Add_Module() */ - - cur = ft_default_modules; - while ( *cur ) - { - error = FT_Add_Module( library, *cur ); - /* notify errors, but don't stop */ - if ( error ) - { - FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = %x\n", - (*cur)->module_name, error )); - } - cur++; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Init_FreeType */ - /* */ - /* */ - /* Initializes a new FreeType library object. The set of drivers */ - /* that are registered by this function is determined at build time. */ - /* */ - /* */ - /* library :: A handle to a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Init_FreeType( FT_Library* library ) - { - FT_Error error; - FT_Memory memory; - - - /* First of all, allocate a new system object -- this function is part */ - /* of the system-specific component, i.e. `ftsystem.c'. */ - - memory = FT_New_Memory(); - if ( !memory ) - { - FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); - return FT_Err_Unimplemented_Feature; - } - - /* build a library out of it, then fill it with the set of */ - /* default drivers. */ - - error = FT_New_Library( memory, library ); - if ( !error ) - FT_Add_Default_Modules( *library ); - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftlist.c b/subsys/win32k/freetype/src/base/ftlist.c deleted file mode 100644 index 0158ba4..0000000 --- a/subsys/win32k/freetype/src/base/ftlist.c +++ /dev/null @@ -1,301 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlist.c */ -/* */ -/* Generic list support for FreeType (body). */ -/* */ -/* Copyright 1996-2000 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 implements functions relative to list processing. Its */ - /* data structures are defined in `freetype/internal/ftlist.h'. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_list - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Find */ - /* */ - /* */ - /* Finds the list node for a given listed object. */ - /* */ - /* */ - /* list :: A pointer to the parent list. */ - /* data :: The address of the listed object. */ - /* */ - /* */ - /* List node. NULL if it wasn't found. */ - /* */ - BASE_FUNC( FT_ListNode ) FT_List_Find( FT_List list, - void* data ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - if ( cur->data == data ) - return cur; - - cur = cur->next; - } - - return (FT_ListNode)0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Add */ - /* */ - /* */ - /* Appends an element to the end of a list. */ - /* */ - /* */ - /* list :: A pointer to the parent list. */ - /* node :: The node to append. */ - /* */ - BASE_FUNC( void ) FT_List_Add( FT_List list, - FT_ListNode node ) - { - FT_ListNode before = list->tail; - - - node->next = 0; - node->prev = before; - - if ( before ) - before->next = node; - else - list->head = node; - - list->tail = node; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Insert */ - /* */ - /* */ - /* Inserts an element at the head of a list. */ - /* */ - /* */ - /* list :: A pointer to parent list. */ - /* node :: The node to insert. */ - /* */ - BASE_FUNC( void ) FT_List_Insert( FT_List list, - FT_ListNode node ) - { - FT_ListNode after = list->head; - - - node->next = after; - node->prev = 0; - - if ( !after ) - list->tail = node; - else - after->prev = node; - - list->head = node; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Remove */ - /* */ - /* */ - /* Removes a node from a list. This function doesn't check whether */ - /* the node is in the list! */ - /* */ - /* */ - /* node :: The node to remove. */ - /* */ - /* */ - /* list :: A pointer to the parent list. */ - /* */ - BASE_FUNC( void ) FT_List_Remove( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - if ( before ) - before->next = after; - else - list->head = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Up */ - /* */ - /* */ - /* Moves a node to the head/top of a list. Used to maintain LRU */ - /* lists. */ - /* */ - /* */ - /* list :: A pointer to the parent list. */ - /* node :: The node to move. */ - /* */ - BASE_FUNC( void ) FT_List_Up( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - /* check whether we are already on top of the list */ - if ( !before ) - return; - - before->next = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - - node->prev = 0; - node->next = list->head; - list->head->prev = node; - list->head = node; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Iterate */ - /* */ - /* */ - /* Parses a list and calls a given iterator function on each element. */ - /* Note that parsing is stopped as soon as one of the iterator calls */ - /* returns a non-zero value. */ - /* */ - /* */ - /* list :: A handle to the list. */ - /* iterator :: An interator function, called on each node of the */ - /* list. */ - /* user :: A user-supplied field which is passed as the second */ - /* argument to the iterator. */ - /* */ - /* */ - /* The result (a FreeType error code) of the last iterator call. */ - /* */ - BASE_FUNC( FT_Error ) FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) - { - FT_ListNode cur = list->head; - FT_Error error = FT_Err_Ok; - - - while ( cur ) - { - FT_ListNode next = cur->next; - - - error = iterator( cur, user ); - if ( error ) - break; - - cur = next; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_List_Finalize */ - /* */ - /* */ - /* Destroys all elements in the list as well as the list itself. */ - /* */ - /* */ - /* list :: A handle to the list. */ - /* */ - /* destroy :: A list destructor that will be applied to each element */ - /* of the list. */ - /* */ - /* memory :: The current memory object which handles deallocation. */ - /* */ - /* user :: A user-supplied field which is passed as the last */ - /* argument to the destructor. */ - /* */ - BASE_FUNC( void ) FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - FT_ListNode next = cur->next; - void* data = cur->data; - - - if ( destroy ) - destroy( memory, data, user ); - - FREE( cur ); - cur = next; - } - - list->head = 0; - list->tail = 0; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftmm.c b/subsys/win32k/freetype/src/base/ftmm.c deleted file mode 100644 index 0f6fdde..0000000 --- a/subsys/win32k/freetype/src/base/ftmm.c +++ /dev/null @@ -1,176 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.c */ -/* */ -/* Multiple Master font support (body). */ -/* */ -/* Copyright 1996-2000 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 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_mm - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Multi_Master */ - /* */ - /* */ - /* Retrieves the Multiple Master descriptor of a given font. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* */ - /* master :: The Multiple Masters descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master* master ) - { - FT_Error error; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) - { - FT_Driver driver = face->driver; - FT_Get_MM_Func func; - - - func = (FT_Get_MM_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_mm" ); - if ( func ) - error = func( face, master ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Design_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_MM_Design_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - FT_Error error; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) - { - FT_Driver driver = face->driver; - FT_Set_MM_Design_Func func; - - - func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "set_mm_design" ); - if ( func ) - error = func( face, num_coords, coords ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_MM_Blend_Coordinates */ - /* */ - /* */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through normalized blend coordinates. */ - /* */ - /* */ - /* face :: A handle to the source face. */ - /* */ - /* num_coords :: The number of design coordinates (must be equal to */ - /* the number of axes in the font). */ - /* */ - /* coords :: The design coordinates (each one must be between 0 */ - /* and 1.0). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_MM_Blend_Coordinates( - FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) - { - FT_Driver driver = face->driver; - FT_Set_MM_Blend_Func func; - - - func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "set_mm_blend" ); - if ( func ) - error = func( face, num_coords, coords ); - } - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftnames.c b/subsys/win32k/freetype/src/base/ftnames.c deleted file mode 100644 index 43a0d12..0000000 --- a/subsys/win32k/freetype/src/base/ftnames.c +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftnames.c */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_CONFIG_OPTION_SFNT_NAMES - - - FT_EXPORT_FUNC( FT_UInt ) FT_Get_Sfnt_Name_Count( FT_Face face ) - { - return face && ( FT_IS_SFNT( face ) ? ((TT_Face)face)->num_names : 0 ); - } - - - FT_EXPORT_FUNC( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, - FT_UInt index, - FT_SfntName* aname ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - if ( aname && face && FT_IS_SFNT( face ) ) - { - TT_Face ttface = (TT_Face)face; - - - if ( index < ttface->num_names ) - { - TT_NameRec* name = ttface->name_table.names + index; - - - aname->platform_id = name->platformID; - aname->encoding_id = name->encodingID; - aname->language_id = name->languageID; - aname->name_id = name->nameID; - aname->string = (FT_Byte*)name->string; - aname->string_len = name->stringLength; - - error = FT_Err_Ok; - } - } - - return error; - } - - -#endif /* FT_CONFIG_OPTION_SFNT_NAMES */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftobjs.c b/subsys/win32k/freetype/src/base/ftobjs.c deleted file mode 100644 index de74882..0000000 --- a/subsys/win32k/freetype/src/base/ftobjs.c +++ /dev/null @@ -1,3246 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.c */ -/* */ -/* The FreeType private base classes (body). */ -/* */ -/* Copyright 1996-2000 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 /* for strcmp() */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M E M O R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_memory - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Alloc */ - /* */ - /* */ - /* Allocates a new block of memory. The returned area is always */ - /* zero-filled; this is a strong convention in many FreeType parts. */ - /* */ - /* */ - /* memory :: A handle to a given `memory object' which handles */ - /* allocation. */ - /* */ - /* size :: The size in bytes of the block to allocate. */ - /* */ - /* */ - /* P :: A pointer to the fresh new block. It should be set to */ - /* NULL if `size' is 0, or in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - BASE_FUNC( FT_Error ) FT_Alloc( FT_Memory memory, - FT_Long size, - void** P ) - { - FT_Assert( P != 0 ); - - if ( size > 0 ) - { - *P = memory->alloc( memory, size ); - if ( !*P ) - { - FT_ERROR(( "FT_Alloc:" )); - FT_ERROR(( " Out of memory? (%ld requested)\n", - size )); - - return FT_Err_Out_Of_Memory; - } - MEM_Set( *P, 0, size ); - } - else - *P = NULL; - - FT_TRACE7(( "FT_Alloc:" )); - FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", - size, *P, P )); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Realloc */ - /* */ - /* */ - /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */ - /* from the heap, possibly changing `*P'. */ - /* */ - /* */ - /* memory :: A handle to a given `memory object' which handles */ - /* reallocation. */ - /* */ - /* current :: The current block size in bytes. */ - /* */ - /* size :: The new block size in bytes. */ - /* */ - /* */ - /* P :: A pointer to the fresh new block. It should be set to */ - /* NULL if `size' is 0, or in case of error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* All callers of FT_Realloc() _must_ provide the current block size */ - /* as well as the new one. */ - /* */ - BASE_FUNC( FT_Error ) FT_Realloc( FT_Memory memory, - FT_Long current, - FT_Long size, - void** P ) - { - void* Q; - - - FT_Assert( P != 0 ); - - /* if the original pointer is NULL, call FT_Alloc() */ - if ( !*P ) - return FT_Alloc( memory, size, P ); - - /* if the new block if zero-sized, clear the current one */ - if ( size <= 0 ) - { - FT_Free( memory, P ); - return FT_Err_Ok; - } - - Q = memory->realloc( memory, current, size, *P ); - if ( !Q ) - goto Fail; - - *P = Q; - return FT_Err_Ok; - - Fail: - FT_ERROR(( "FT_Realloc:" )); - FT_ERROR(( " Failed (current %ld, requested %ld)\n", - current, size )); - return FT_Err_Out_Of_Memory; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Free */ - /* */ - /* */ - /* Releases a given block of memory allocated through FT_Alloc(). */ - /* */ - /* */ - /* memory :: A handle to a given `memory object' which handles */ - /* memory deallocation */ - /* */ - /* P :: This is the _address_ of a _pointer_ which points to the */ - /* allocated block. It is always set to NULL on exit. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If P or *P are NULL, this function should return successfully. */ - /* This is a strong convention within all of FreeType and its */ - /* drivers. */ - /* */ - BASE_FUNC( void ) FT_Free( FT_Memory memory, - void** P ) - { - FT_TRACE7(( "FT_Free:" )); - FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n", - P, P ? *P : (void*)0 )); - - if ( P && *P ) - { - memory->free( memory, *P ); - *P = 0; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S T R E A M ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* ft_new_input_stream */ - /* */ - /* */ - /* Creates a new input stream object from an FT_Open_Args structure. */ - /* */ - /* */ - /* The function expects a valid `astream' parameter. */ - /* */ - static - FT_Error ft_new_input_stream( FT_Library library, - FT_Open_Args* args, - FT_Stream* astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !args ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - if ( ALLOC( stream, sizeof ( *stream ) ) ) - goto Exit; - - stream->memory = memory; - - /* now, look at the stream flags */ - if ( args->flags & ft_open_memory ) - { - error = 0; - FT_New_Memory_Stream( library, - args->memory_base, - args->memory_size, - stream ); - } - else if ( args->flags & ft_open_pathname ) - { - error = FT_New_Stream( args->pathname, stream ); - stream->pathname.pointer = args->pathname; - } - else if ( args->flags & ft_open_stream && args->stream ) - { - *stream = *(args->stream); - stream->memory = memory; - } - else - error = FT_Err_Invalid_Argument; - - if ( error ) - FREE( stream ); - - *astream = stream; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Stream */ - /* */ - /* */ - /* Closes and destroys a stream object. */ - /* */ - /* */ - /* stream :: The stream to be closed and destroyed. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Done_Stream( FT_Stream stream ) - { - if ( stream && stream->close ) - stream->close( stream ); - } - - - static - void ft_done_stream( FT_Stream* astream ) - { - FT_Stream stream = *astream; - FT_Memory memory = stream->memory; - - - if ( stream->close ) - stream->close( stream ); - - FREE( stream ); - *astream = 0; - } - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** G L Y P H L O A D E R ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The glyph loader is a simple object which is used to load a set of */ - /* glyphs easily. It is critical for the correct loading of composites. */ - /* */ - /* Ideally, one can see it as a stack of abstract `glyph' objects. */ - /* */ - /* loader.base Is really the bottom of the stack. It describes a */ - /* single glyph image made of the juxtaposition of */ - /* several glyphs (those `in the stack'). */ - /* */ - /* loader.current Describes the top of the stack, on which a new */ - /* glyph can be loaded. */ - /* */ - /* Rewind Clears the stack. */ - /* Prepare Set up `loader.current' for addition of a new glyph */ - /* image. */ - /* Add Add the `current' glyph image to the `base' one, */ - /* and prepare for another one. */ - /* */ - /* The glyph loader is now a base object. Each driver used to */ - /* re-implement it in one way or the other, which wasted code and */ - /* energy. */ - /* */ - /*************************************************************************/ - - - /* create a new glyph loader */ - BASE_FUNC( FT_Error ) FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader** aloader ) - { - FT_GlyphLoader* loader; - FT_Error error; - - - if ( !ALLOC( loader, sizeof ( *loader ) ) ) - { - loader->memory = memory; - *aloader = loader; - } - return error; - } - - - /* rewind the glyph loader - reset counters to 0 */ - BASE_FUNC( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ) - { - FT_GlyphLoad* base = &loader->base; - FT_GlyphLoad* current = &loader->current; - - - base->outline.n_points = 0; - base->outline.n_contours = 0; - base->num_subglyphs = 0; - - *current = *base; - } - - - /* reset the glyph loader, frees all allocated tables */ - /* and starts from zero */ - BASE_FUNC( void ) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ) - { - FT_Memory memory = loader->memory; - - - FREE( loader->base.outline.points ); - FREE( loader->base.outline.tags ); - FREE( loader->base.outline.contours ); - FREE( loader->base.extra_points ); - FREE( loader->base.subglyphs ); - - loader->max_points = 0; - loader->max_contours = 0; - loader->max_subglyphs = 0; - - FT_GlyphLoader_Rewind( loader ); - } - - - /* delete a glyph loader */ - BASE_FUNC( void ) FT_GlyphLoader_Done( FT_GlyphLoader* loader ) - { - if ( loader ) - { - FT_Memory memory = loader->memory; - - - FT_GlyphLoader_Reset( loader ); - FREE( loader ); - } - } - - - /* re-adjust the `current' outline fields */ - static - void FT_GlyphLoader_Adjust_Points( FT_GlyphLoader* loader ) - { - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - - - current->points = base->points + base->n_points; - current->tags = base->tags + base->n_points; - current->contours = base->contours + base->n_contours; - - /* handle extra points table - if any */ - if ( loader->use_extra ) - loader->current.extra_points = - loader->base.extra_points + base->n_points; - } - - - BASE_FUNC( FT_Error ) FT_GlyphLoader_Create_Extra( - FT_GlyphLoader* loader ) - { - FT_Error error; - FT_Memory memory = loader->memory; - - - if ( !ALLOC_ARRAY( loader->base.extra_points, - loader->max_points, FT_Vector ) ) - { - loader->use_extra = 1; - FT_GlyphLoader_Adjust_Points( loader ); - } - return error; - } - - - /* re-adjust the `current' subglyphs field */ - static - void FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader* loader ) - { - FT_GlyphLoad* base = &loader->base; - FT_GlyphLoad* current = &loader->current; - - - current->subglyphs = base->subglyphs + base->num_subglyphs; - } - - - /* Ensure that we can add `n_points' and `n_contours' to our glyph. this */ - /* function reallocates its outline tables if necessary. Note that it */ - /* DOESN'T change the number of points within the loader! */ - /* */ - BASE_FUNC( FT_Error ) FT_GlyphLoader_Check_Points( - FT_GlyphLoader* loader, - FT_UInt n_points, - FT_UInt n_contours ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - FT_Bool adjust = 1; - - FT_UInt new_max; - - - /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; - if ( new_max > loader->max_points ) - { - new_max = ( new_max + 7 ) & -8; - if ( REALLOC_ARRAY( base->points, base->n_points, - new_max, FT_Vector ) || - REALLOC_ARRAY( base->tags, base->n_points, - new_max, FT_Byte ) ) - goto Exit; - - if ( loader->use_extra && - REALLOC_ARRAY( loader->base.extra_points, base->n_points, - new_max, FT_Vector ) ) - goto Exit; - - adjust = 1; - loader->max_points = new_max; - } - - /* check contours */ - new_max = base->n_contours + current->n_contours + - n_contours; - if ( new_max > loader->max_contours ) - { - new_max = ( new_max + 3 ) & -4; - if ( REALLOC_ARRAY( base->contours, base->n_contours, - new_max, FT_Short ) ) - goto Exit; - - adjust = 1; - loader->max_contours = new_max; - } - - if ( adjust ) - FT_GlyphLoader_Adjust_Points( loader ); - - Exit: - return error; - } - - - /* Ensure that we can add `n_subglyphs' to our glyph. this function */ - /* reallocates its subglyphs table if necessary. Note that it DOES */ - /* NOT change the number of subglyphs within the loader! */ - /* */ - BASE_FUNC( FT_Error ) FT_GlyphLoader_Check_Subglyphs( - FT_GlyphLoader* loader, - FT_UInt n_subs ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_UInt new_max; - - FT_GlyphLoad* base = &loader->base; - FT_GlyphLoad* current = &loader->current; - - - new_max = base->num_subglyphs + current->num_subglyphs + n_subs; - if ( new_max > loader->max_subglyphs ) - { - new_max = ( new_max + 1 ) & -2; - if ( REALLOC_ARRAY( base->subglyphs, base->num_subglyphs, - new_max, FT_SubGlyph ) ) - goto Exit; - - loader->max_subglyphs = new_max; - - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - Exit: - return error; - } - - - /* prepare loader for the addition of a new glyph on top of the base one */ - BASE_FUNC( void ) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ) - { - FT_GlyphLoad* current = &loader->current; - - - current->outline.n_points = 0; - current->outline.n_contours = 0; - current->num_subglyphs = 0; - - FT_GlyphLoader_Adjust_Points ( loader ); - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - - /* add current glyph to the base image - and prepare for another */ - BASE_FUNC( void ) FT_GlyphLoader_Add( FT_GlyphLoader* loader ) - { - FT_GlyphLoad* base = &loader->base; - FT_GlyphLoad* current = &loader->current; - - FT_UInt n_curr_contours = current->outline.n_contours; - FT_UInt n_base_points = base->outline.n_points; - FT_UInt n; - - - base->outline.n_points += current->outline.n_points; - base->outline.n_contours += current->outline.n_contours; - base->num_subglyphs += current->num_subglyphs; - - /* adjust contours count in newest outline */ - for ( n = 0; n < n_curr_contours; n++ ) - current->outline.contours[n] += n_base_points; - - /* prepare for another new glyph image */ - FT_GlyphLoader_Prepare( loader ); - } - - - BASE_FUNC( FT_Error ) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, - FT_GlyphLoader* source ) - { - FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; - - - error = FT_GlyphLoader_Check_Points( target, num_points, num_contours ); - if ( !error ) - { - FT_Outline* out = &target->base.outline; - FT_Outline* in = &source->base.outline; - - - MEM_Copy( out->points, in->points, - num_points * sizeof ( FT_Vector ) ); - MEM_Copy( out->tags, in->tags, - num_points * sizeof ( char ) ); - MEM_Copy( out->contours, in->contours, - num_contours * sizeof ( short ) ); - - /* do we need to copy the extra points? */ - if ( target->use_extra && source->use_extra ) - MEM_Copy( target->base.extra_points, source->base.extra_points, - num_points * sizeof ( FT_Vector ) ); - - out->n_points = num_points; - out->n_contours = num_contours; - - FT_GlyphLoader_Adjust_Points( target ); - } - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error ft_glyphslot_init( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class* clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - FT_Error error = FT_Err_Ok; - - - slot->library = driver->root.library; - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - error = FT_GlyphLoader_New( memory, &slot->loader ); - - if ( !error && clazz->init_slot ) - error = clazz->init_slot( slot ); - - return error; - } - - - static - void ft_glyphslot_clear( FT_GlyphSlot slot ) - { - /* free bitmap if needed */ - if ( slot->flags & ft_glyph_own_bitmap ) - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - - - FREE( slot->bitmap.buffer ); - slot->flags &= ~ft_glyph_own_bitmap; - } - - /* clear all public fields in the glyph slot */ - MEM_Set( &slot->metrics, 0, sizeof ( slot->metrics ) ); - MEM_Set( &slot->outline, 0, sizeof ( slot->outline ) ); - MEM_Set( &slot->bitmap, 0, sizeof ( slot->bitmap ) ); - - slot->bitmap_left = 0; - slot->bitmap_top = 0; - slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; - slot->control_len = 0; - slot->other = 0; - slot->format = ft_glyph_format_none; - - slot->linearHoriAdvance = 0; - slot->linearVertAdvance = 0; - } - - - static - void ft_glyphslot_done( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class* clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - - - /* free bitmap buffer if needed */ - if ( slot->flags & ft_glyph_own_bitmap ) - FREE( slot->bitmap.buffer ); - - /* free glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - FT_GlyphLoader_Done( slot->loader ); - slot->loader = 0; - } - - if ( clazz->done_slot ) - clazz->done_slot( slot ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_GlyphSlot */ - /* */ - /* */ - /* It is sometimes useful to have more than one glyph slot for a */ - /* given face object. This function is used to create additional */ - /* slots. All of them are automatically discarded when the face is */ - /* destroyed. */ - /* */ - /* */ - /* face :: A handle to a parent face object. */ - /* */ - /* */ - /* aslot :: A handle to a new glyph slot object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot* aslot ) - { - FT_Error error; - FT_Driver driver; - FT_Driver_Class* clazz; - FT_Memory memory; - FT_GlyphSlot slot; - - - if ( !face || !aslot || !face->driver ) - return FT_Err_Invalid_Argument; - - *aslot = 0; - - driver = face->driver; - clazz = driver->clazz; - memory = driver->root.memory; - - FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); - if ( !ALLOC( slot, clazz->slot_object_size ) ) - { - slot->face = face; - - error = ft_glyphslot_init( slot ); - if ( error ) - { - ft_glyphslot_done( slot ); - FREE( slot ); - goto Exit; - } - - *aslot = slot; - } - - Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_GlyphSlot */ - /* */ - /* */ - /* Destroys a given glyph slot. Remember however that all slots are */ - /* automatically destroyed with its parent. Using this function is */ - /* not always mandatory. */ - /* */ - /* */ - /* slot :: A handle to a target glyph slot. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ) - { - if ( slot ) - { - FT_Driver driver = slot->face->driver; - FT_Memory memory = driver->root.memory; - FT_GlyphSlot* parent; - FT_GlyphSlot cur; - - - /* Remove slot from its parent face's list */ - parent = &slot->face->glyph; - cur = *parent; - - while ( cur ) - { - if ( cur == slot ) - { - *parent = cur->next; - ft_glyphslot_done( slot ); - FREE( slot ); - break; - } - cur = cur->next; - } - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Transform */ - /* */ - /* */ - /* A function used to set the transformation that is applied to glyph */ - /* images just before they are converted to bitmaps in a glyph slot */ - /* when FT_Render_Glyph() is called. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use 0 for the null */ - /* vector. */ - /* */ - /* */ - /* The transformation is only applied to scalable image formats after */ - /* the glyph has been loaded. It means that hinting is unaltered by */ - /* the transformation and is performed on the character size given in */ - /* the last call to FT_Set_Char_Sizes() or FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_FUNC( void ) FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ) - { - if ( !face ) - return; - - face->transform_flags = 0; - - if ( !matrix ) - { - face->transform_matrix.xx = 0x10000L; - face->transform_matrix.xy = 0; - face->transform_matrix.yx = 0; - face->transform_matrix.yy = 0x10000L; - matrix = &face->transform_matrix; - } - else - face->transform_matrix = *matrix; - - /* set transform_flags bit flag 0 if `matrix' isn't the identity */ - if ( ( matrix->xy | matrix->yx ) || - matrix->xx != 0x10000L || - matrix->yy != 0x10000L ) - face->transform_flags |= 1; - - if ( !delta ) - { - face->transform_delta.x = 0; - face->transform_delta.y = 0; - delta = &face->transform_delta; - } - else - face->transform_delta = *delta; - - /* set transform_flags bit flag 1 if `delta' isn't the null vector */ - if ( delta->x | delta->y ) - face->transform_flags |= 2; - } - - - static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* face :: A handle to the target face object where the glyph */ - /* will be loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform. */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int load_flags ) - { - FT_Error error; - FT_Driver driver; - FT_GlyphSlot slot; - FT_Library library; - FT_Bool autohint; - FT_Module hinter; - - - if ( !face || !face->size || !face->glyph ) - return FT_Err_Invalid_Face_Handle; - - if ( glyph_index >= (FT_UInt)face->num_glyphs ) - return FT_Err_Invalid_Argument; - - slot = face->glyph; - ft_glyphslot_clear( slot ); - - driver = face->driver; - - /* when the flag NO_RECURSE is set, we disable hinting and scaling */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - /* do we need to load the glyph through the auto-hinter? */ - library = driver->root.library; - hinter = library->auto_hinter; - autohint = hinter && - !( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ); - if ( autohint ) - { - if ( FT_DRIVER_HAS_HINTER( driver ) && - !( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) - autohint = 0; - } - - if ( autohint ) - { - FT_AutoHinter_Interface* hinting; - - - hinting = (FT_AutoHinter_Interface*)hinter->clazz->module_interface; - error = hinting->load_glyph( (FT_AutoHinter)hinter, slot, face->size, - glyph_index, load_flags ); - } - else - error = driver->clazz->load_glyph( slot, - face->size, - glyph_index, - load_flags ); - if ( error ) - goto Exit; - - /* compute the advance */ - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - slot->advance.x = 0; - slot->advance.y = slot->metrics.vertAdvance; - } - else - { - slot->advance.x = slot->metrics.horiAdvance; - slot->advance.y = 0; - } - - /* now, transform the glyph image when needed */ - if ( face->transform_flags ) - { - /* get renderer */ - FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); - - - if ( renderer ) - error = renderer->clazz->transform_glyph( renderer, slot, - &face->transform_matrix, - &face->transform_delta ); - /* transform advance */ - FT_Vector_Transform( &slot->advance, &face->transform_matrix ); - } - - /* do we need to render the image now? */ - if ( !error && - slot->format != ft_glyph_format_bitmap && - slot->format != ft_glyph_format_composite && - load_flags & FT_LOAD_RENDER ) - { - error = FT_Render_Glyph( slot, - ( load_flags & FT_LOAD_MONOCHROME ) - ? ft_render_mode_mono - : ft_render_mode_normal ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Load_Char */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size, according to its character code. */ - /* */ - /* */ - /* face :: A handle to a target face object where the glyph */ - /* will be loaded. */ - /* */ - /* char_code :: The glyph's character code, according to the */ - /* current charmap used in the face. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If the face has no current charmap, or if the character code */ - /* is not defined in the charmap, this function will return an */ - /* error. */ - /* */ - /* If the glyph image is not a bitmap, and if the bit flag */ - /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */ - /* transformed with the information passed to a previous call to */ - /* FT_Set_Transform(). */ - /* */ - /* Note that this also transforms the `face.glyph.advance' field, but */ - /* *not* the values in `face.glyph.metrics'. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int load_flags ) - { - FT_UInt glyph_index; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - glyph_index = (FT_UInt)char_code; - if ( face->charmap ) - glyph_index = FT_Get_Char_Index( face, char_code ); - - return FT_Load_Glyph( face, glyph_index, load_flags ); - } - - - /* destructor for sizes list */ - static - void destroy_size( FT_Memory memory, - FT_Size size, - FT_Driver driver ) - { - /* finalize client-specific data */ - if ( size->generic.finalizer ) - size->generic.finalizer( size ); - - /* finalize format-specific stuff */ - if ( driver->clazz->done_size ) - driver->clazz->done_size( size ); - - FREE( size ); - } - - - /* destructor for faces list */ - static - void destroy_face( FT_Memory memory, - FT_Face face, - FT_Driver driver ) - { - FT_Driver_Class* clazz = driver->clazz; - - - /* discard auto-hinting data */ - if ( face->autohint.finalizer ) - face->autohint.finalizer( face->autohint.data ); - - /* Discard glyph slots for this face */ - /* Beware! FT_Done_GlyphSlot() changes the field `face->slot' */ - while ( face->glyph ) - FT_Done_GlyphSlot( face->glyph ); - - /* Discard all sizes for this face */ - FT_List_Finalize( &face->sizes_list, - (FT_List_Destructor)destroy_size, - memory, - driver ); - face->size = 0; - - /* Now discard client data */ - if ( face->generic.finalizer ) - face->generic.finalizer( face ); - - /* finalize format-specific stuff */ - if ( clazz->done_face ) - clazz->done_face( face ); - - /* close the stream for this face if needed */ - if ( ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) == 0 ) - ft_done_stream( &face->stream ); - - /* get rid of it */ - FREE( face ); - } - - - static - void Destroy_Driver( FT_Driver driver ) - { - FT_List_Finalize( &driver->faces_list, - (FT_List_Destructor)destroy_face, - driver->root.memory, - driver ); - - /* check whether we need to drop the driver's glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* open_face */ - /* */ - /* */ - /* This function does some work for FT_Open_Face(). */ - /* */ - static - FT_Error open_face( FT_Driver driver, - FT_Stream stream, - FT_Long face_index, - FT_Int num_params, - FT_Parameter* params, - FT_Face* aface ) - { - FT_Memory memory; - FT_Driver_Class* clazz; - FT_Face face = 0; - FT_Error error; - - - clazz = driver->clazz; - memory = driver->root.memory; - - /* allocate the face object and perform basic initialization */ - if ( ALLOC( face, clazz->face_object_size ) ) - goto Fail; - - face->driver = driver; - face->memory = memory; - face->stream = stream; - - error = clazz->init_face( stream, - face, - face_index, - num_params, - params ); - if ( error ) - goto Fail; - - *aface = face; - - Fail: - if ( error ) - { - clazz->done_face( face ); - FREE( face ); - *aface = 0; - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a pathname to the font file. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* pathname :: A path to the font file. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Face( FT_Library library, - const char* pathname, - FT_Long face_index, - FT_Face* aface ) - { - FT_Open_Args args; - - - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ - if ( !pathname ) - return FT_Err_Invalid_Argument; - - args.flags = ft_open_pathname; - args.pathname = (char*)pathname; - - return FT_Open_Face( library, &args, face_index, aface ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory_Face */ - /* */ - /* */ - /* Creates a new face object from a given resource and typeface index */ - /* using a font file already loaded into memory. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* file_base :: A pointer to the beginning of the font data. */ - /* */ - /* file_size :: The size of the memory chunk used by the font data. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* face :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_New_Memory_Face() can be used to determine and/or check the */ - /* font format of a given font resource. If the `face_index' field */ - /* is negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Memory_Face( FT_Library library, - FT_Byte* file_base, - FT_Long file_size, - FT_Long face_index, - FT_Face* face ) - { - FT_Open_Args args; - - - /* test for valid `library' and `face' delayed to FT_Open_Face() */ - if ( !file_base ) - return FT_Err_Invalid_Argument; - - args.flags = ft_open_memory; - args.memory_base = file_base; - args.memory_size = file_size; - - return FT_Open_Face( library, &args, face_index, face ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Open_Face */ - /* */ - /* */ - /* Opens a face object from a given resource and typeface index using */ - /* an `FT_Open_Args' structure. If the face object doesn't exist, it */ - /* will be created. */ - /* */ - /* */ - /* library :: A handle to the library resource. */ - /* */ - /* */ - /* args :: A pointer to an `FT_Open_Args' structure which must */ - /* be filled by the caller. */ - /* */ - /* face_index :: The index of the face within the resource. The */ - /* first face has index 0. */ - /* */ - /* aface :: A handle to a new face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Unlike FreeType 1.x, this function automatically creates a glyph */ - /* slot for the face object which can be accessed directly through */ - /* `face->glyph'. */ - /* */ - /* Note that additional slots can be added to each face with the */ - /* FT_New_GlyphSlot() API function. Slots are linked in a single */ - /* list through their `next' field. */ - /* */ - /* FT_Open_Face() can be used to determine and/or check the font */ - /* format of a given font resource. If the `face_index' field is */ - /* negative, the function will _not_ return any face handle in */ - /* `*face'. Its return value should be 0 if the resource is */ - /* recognized, or non-zero if not. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Open_Face( FT_Library library, - FT_Open_Args* args, - FT_Long face_index, - FT_Face* aface ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_Stream stream; - FT_Face face = 0; - FT_ListNode node = 0; - - - /* test for valid `library' and `args' delayed to */ - /* ft_new_input_stream() */ - - if ( !aface ) - return FT_Err_Invalid_Argument; - - *aface = 0; - - /* create input stream */ - error = ft_new_input_stream( library, args, &stream ); - if ( error ) - goto Exit; - - memory = library->memory; - - /* If the font driver is specified in the `args' structure, use */ - /* it. Otherwise, we scan the list of registered drivers. */ - if ( args->flags & ft_open_driver && args->driver ) - { - driver = FT_DRIVER( args->driver ); - - /* not all modules are drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( driver ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - if ( args->flags & ft_open_params ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - } - else - error = FT_Err_Invalid_Handle; - - ft_done_stream( &stream ); - goto Fail; - } - else - { - /* check each font driver for an appropriate format */ - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - /* not all modules are font drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( cur[0] ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - driver = FT_DRIVER( cur[0] ); - - if ( args->flags & ft_open_params ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - - if ( error != FT_Err_Unknown_File_Format ) - goto Fail; - } - } - - ft_done_stream( &stream ); - - /* no driver is able to handle this format */ - error = FT_Err_Unknown_File_Format; - goto Fail; - } - - Success: - FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" )); - - /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ - if ( args->flags & ft_open_stream && args->stream ) - face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; - - /* add the face object to its driver's list */ - if ( ALLOC( node, sizeof ( *node ) ) ) - goto Fail; - - node->data = face; - /* don't assume driver is the same as face->driver, so use */ - /* face->driver instead. */ - FT_List_Add( &face->driver->faces_list, node ); - - /* now allocate a glyph slot object for the face */ - { - FT_GlyphSlot slot; - - - FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); - - error = FT_New_GlyphSlot( face, &slot ); - if ( error ) - goto Fail; - - face->glyph = slot; - } - - /* finally, allocate a size object for the face */ - { - FT_Size size; - - - FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); - - error = FT_New_Size( face, &size ); - if ( error ) - goto Fail; - - face->size = size; - } - - /* initialize transformation for convenience functions */ - face->transform_matrix.xx = 0x10000L; - face->transform_matrix.xy = 0; - face->transform_matrix.yx = 0; - face->transform_matrix.yy = 0x10000L; - - face->transform_delta.x = 0; - face->transform_delta.y = 0; - - *aface = face; - goto Exit; - - Fail: - FT_Done_Face( face ); - - Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_File */ - /* */ - /* */ - /* `Attaches' a given font file to an existing face. This is usually */ - /* to read additional information for a single face object. For */ - /* example, it is used to read the AFM files that come with Type 1 */ - /* fonts in order to add kerning data and other metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* */ - /* filepathname :: An 8-bit pathname naming the `metrics' file. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* If your font file is in memory, or if you want to provide your */ - /* own input stream object, use FT_Attach_Stream(). */ - /* */ - /* The meaning of the `attach' action (i.e., what really happens when */ - /* the new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Attach_File( FT_Face face, - const char* filepathname ) - { - FT_Open_Args open; - - - /* test for valid `face' delayed to FT_Attach_Stream() */ - - if ( !filepathname ) - return FT_Err_Invalid_Argument; - - open.flags = ft_open_pathname; - open.pathname = (char*)filepathname; - - return FT_Attach_Stream( face, &open ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Attach_Stream */ - /* */ - /* */ - /* This function is similar to FT_Attach_File() with the exception */ - /* that it reads the attachment from an arbitrary stream. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* parameters :: A pointer to an FT_Open_Args structure used to */ - /* describe the input stream to FreeType. */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The meaning of the `attach' (i.e. what really happens when the */ - /* new file is read) is not fixed by FreeType itself. It really */ - /* depends on the font format (and thus the font driver). */ - /* */ - /* Client applications are expected to know what they are doing */ - /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ) - { - FT_Stream stream; - FT_Error error; - FT_Driver driver; - - FT_Driver_Class* clazz; - - - /* test for valid `parameters' delayed to ft_new_input_stream() */ - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - error = ft_new_input_stream( driver->root.library, parameters, &stream ); - if ( error ) - goto Exit; - - /* we implement FT_Attach_Stream in each driver through the */ - /* `attach_file' interface */ - - error = FT_Err_Unimplemented_Feature; - clazz = driver->clazz; - if ( clazz->attach_file ) - error = clazz->attach_file( face, stream ); - - /* close the attached stream */ - if ( !parameters->stream || ( parameters->flags & ft_open_stream ) ) - ft_done_stream( &stream ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Face */ - /* */ - /* */ - /* Discards a given face object, as well as all of its child slots */ - /* and sizes. */ - /* */ - /* */ - /* face :: A handle to a target face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Done_Face( FT_Face face ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_ListNode node; - - - error = FT_Err_Invalid_Face_Handle; - if ( face && face->driver ) - { - driver = face->driver; - memory = driver->root.memory; - - /* find face in driver's list */ - node = FT_List_Find( &driver->faces_list, face ); - if ( node ) - { - /* remove face object from the driver's list */ - FT_List_Remove( &driver->faces_list, node ); - FREE( node ); - - /* now destroy the object proper */ - destroy_face( memory, face, driver ); - error = FT_Err_Ok; - } - } - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Size */ - /* */ - /* */ - /* Creates a new size object from a given face object. */ - /* */ - /* */ - /* face :: A handle to a parent face object. */ - /* */ - /* */ - /* asize :: A handle to a new size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Size( FT_Face face, - FT_Size* asize ) - { - FT_Error error; - FT_Memory memory; - FT_Driver driver; - FT_Driver_Class* clazz; - - FT_Size size = 0; - FT_ListNode node = 0; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !asize ) - return FT_Err_Invalid_Size_Handle; - - if ( !face->driver ) - return FT_Err_Invalid_Driver_Handle; - - *asize = 0; - - driver = face->driver; - clazz = driver->clazz; - memory = face->memory; - - /* Allocate new size object and perform basic initialisation */ - if ( ALLOC( size, clazz->size_object_size ) || - ALLOC( node, sizeof ( FT_ListNodeRec ) ) ) - goto Exit; - - size->face = face; - - if ( clazz->init_size ) - error = clazz->init_size( size ); - - /* in case of success, add to the face's list */ - if ( !error ) - { - *asize = size; - node->data = size; - FT_List_Add( &face->sizes_list, node ); - } - - Exit: - if ( error ) - { - FREE( node ); - FREE( size ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Size */ - /* */ - /* */ - /* Discards a given size object. */ - /* */ - /* */ - /* size :: A handle to a target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Done_Size( FT_Size size ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_Face face; - FT_ListNode node; - - - if ( !size ) - return FT_Err_Invalid_Size_Handle; - - face = size->face; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - memory = driver->root.memory; - - error = FT_Err_Ok; - node = FT_List_Find( &face->sizes_list, size ); - if ( node ) - { - FT_List_Remove( &face->sizes_list, node ); - FREE( node ); - - if ( face->size == size ) - { - face->size = 0; - if ( face->sizes_list.head ) - face->size = (FT_Size)(face->sizes_list.head->data); - } - - destroy_size( memory, size, driver ); - } - else - error = FT_Err_Invalid_Size_Handle; - - return FT_Err_Ok; - } - - - static - void ft_recompute_scaled_metrics( FT_Face face, - FT_Size_Metrics* metrics ) - { - /* Compute root ascender, descender, test height, and max_advance */ - - metrics->ascender = ( FT_MulFix( face->ascender, - metrics->y_scale ) + 32 ) & -64; - - metrics->descender = ( FT_MulFix( face->descender, - metrics->y_scale ) + 32 ) & -64; - - metrics->height = ( FT_MulFix( face->height, - metrics->y_scale ) + 32 ) & -64; - - metrics->max_advance = ( FT_MulFix( face->max_advance_width, - metrics->x_scale ) + 32 ) & -64; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Char_Size */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The */ - /* `char_width' and `char_height' values are used for the width and */ - /* height, respectively, expressed in 26.6 fractional points. */ - /* */ - /* If the horizontal or vertical resolution values are zero, a */ - /* default value of 72dpi is used. Similarly, if one of the */ - /* character dimensions is zero, its value is set equal to the other. */ - /* */ - /* */ - /* size :: A handle to a target size object. */ - /* */ - /* */ - /* char_width :: The character width, in 26.6 fractional points. */ - /* */ - /* char_height :: The character height, in 26.6 fractional */ - /* points. */ - /* */ - /* horz_resolution :: The horizontal resolution. */ - /* */ - /* vert_resolution :: The vertical resolution. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* When dealing with fixed-size faces (i.e., non-scalable formats), */ - /* use the function FT_Set_Pixel_Sizes(). */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_Error error = FT_Err_Ok; - FT_Driver driver; - FT_Memory memory; - FT_Driver_Class* clazz; - FT_Size_Metrics* metrics; - FT_Long dim_x, dim_y; - - - if ( !face || !face->size || !face->driver ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - metrics = &face->size->metrics; - - if ( !char_width ) - char_width = char_height; - - else if ( !char_height ) - char_height = char_width; - - if ( !horz_resolution ) - horz_resolution = 72; - - if ( !vert_resolution ) - vert_resolution = 72; - - driver = face->driver; - clazz = driver->clazz; - memory = driver->root.memory; - - /* default processing -- this can be overridden by the driver */ - if ( char_width < 1 * 64 ) - char_width = 1 * 64; - if ( char_height < 1 * 64 ) - char_height = 1 * 64; - - /* Compute pixel sizes in 26.6 units */ - dim_x = ( ( ( char_width * horz_resolution ) / 72 ) + 32 ) & -64; - dim_y = ( ( ( char_height * vert_resolution ) / 72 ) + 32 ) & -64; - - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); - - metrics->x_scale = 0x10000L; - metrics->y_scale = 0x10000L; - - if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) - { - metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM ); - metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM ); - - ft_recompute_scaled_metrics( face, metrics ); - } - - if ( clazz->set_char_sizes ) - error = clazz->set_char_sizes( face->size, - char_width, - char_height, - horz_resolution, - vert_resolution ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Pixel_Sizes */ - /* */ - /* */ - /* Sets the character dimensions of a given face object. The width */ - /* and height are expressed in integer pixels. */ - /* */ - /* If one of the character dimensions is zero, its value is set equal */ - /* to the other. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* pixel_width :: The character width, in integer pixels. */ - /* */ - /* pixel_height :: The character height, in integer pixels. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ) - { - FT_Error error = FT_Err_Ok; - FT_Driver driver; - FT_Memory memory; - FT_Driver_Class* clazz; - FT_Size_Metrics* metrics = &face->size->metrics; - - - if ( !face || !face->size || !face->driver ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - clazz = driver->clazz; - memory = driver->root.memory; - - /* default processing -- this can be overridden by the driver */ - if ( pixel_width == 0 ) - pixel_width = pixel_height; - - else if ( pixel_height == 0 ) - pixel_height = pixel_width; - - if ( pixel_width < 1 ) - pixel_width = 1; - if ( pixel_height < 1 ) - pixel_height = 1; - - metrics->x_ppem = pixel_width; - metrics->y_ppem = pixel_height; - - if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) - { - metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, - face->units_per_EM ); - - metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, - face->units_per_EM ); - - ft_recompute_scaled_metrics( face, metrics ); - } - - if ( clazz->set_pixel_sizes ) - error = clazz->set_pixel_sizes( face->size, - pixel_width, - pixel_height ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Kerning */ - /* */ - /* */ - /* Returns the kerning vector between two glyphs of a same face. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* kern_mode :: See FT_Kerning_Mode() for more information. */ - /* Determines the scale/dimension of the returned */ - /* kerning vector. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this method. Other layouts, or more sophisticated */ - /* kernings, are out of the scope of this API function -- they can be */ - /* implemented through format-specific interfaces. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector* kerning ) - { - FT_Error error = FT_Err_Ok; - FT_Driver driver; - FT_Memory memory; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !kerning ) - return FT_Err_Invalid_Argument; - - driver = face->driver; - memory = driver->root.memory; - - kerning->x = 0; - kerning->y = 0; - - if ( driver->clazz->get_kerning ) - { - error = driver->clazz->get_kerning( face, - left_glyph, - right_glyph, - kerning ); - if ( !error ) - { - if ( kern_mode != ft_kerning_unscaled ) - { - kerning->x = FT_MulFix( kerning->x, face->size->metrics.x_scale ); - kerning->y = FT_MulFix( kerning->y, face->size->metrics.y_scale ); - - if ( kern_mode != ft_kerning_unfitted ) - { - kerning->x = ( kerning->x + 32 ) & -64; - kerning->y = ( kerning->y + 32 ) & -64; - } - } - } - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Select_Charmap */ - /* */ - /* */ - /* Selects a given charmap by its encoding tag (as listed in */ - /* `freetype.h'). */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* encoding :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if no charmap in the face */ - /* corresponds to the encoding queried here. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - cur = face->charmaps; - if ( !cur ) - return FT_Err_Invalid_CharMap_Handle; - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0]->encoding == encoding ) - { - face->charmap = cur[0]; - return 0; - } - } - - return FT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Charmap */ - /* */ - /* */ - /* Selects a given charmap for character code to glyph index */ - /* decoding. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* charmap :: A handle to the selected charmap. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function will return an error if the charmap is not part of */ - /* the face (i.e., if it is not listed in the face->charmaps[] */ - /* table). */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - cur = face->charmaps; - if ( !cur ) - return FT_Err_Invalid_CharMap_Handle; - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == charmap ) - { - face->charmap = cur[0]; - return 0; - } - } - return FT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Char_Index */ - /* */ - /* */ - /* Returns the glyph index of a given character code. This function */ - /* uses a charmap object to do the translation. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* */ - /* The glyph index. 0 means `undefined character code'. */ - /* */ - FT_EXPORT_FUNC( FT_UInt ) FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ) - { - FT_UInt result; - FT_Driver driver; - - - result = 0; - if ( face && face->charmap ) - { - driver = face->driver; - result = driver->clazz->get_char_index( face->charmap, charcode ); - } - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Glyph_Name */ - /* */ - /* */ - /* Retrieves the ASCII name of a given glyph in a face. This only */ - /* works for those faces where FT_HAS_GLYPH_NAME(face) returns true. */ - /* */ - /* */ - /* face :: A handle to a source face object. */ - /* */ - /* glyph_index :: The glyph index. */ - /* */ - /* buffer :: A pointer to a target buffer where the name will be */ - /* copied to. */ - /* */ - /* buffer_max :: The maximal number of bytes available in the */ - /* buffer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error is returned if the face doesn't provide glyph names or if */ - /* the glyph index is invalid. In all cases of failure, the first */ - /* byte of `buffer' will be set to 0 to indicate an empty name. */ - /* */ - /* The glyph name is truncated to fit within the buffer if it is too */ - /* long. The returned string is always zero-terminated. */ - /* */ - /* This function is not compiled within the library if the config */ - /* macro FT_CONFIG_OPTION_NO_GLYPH_NAMES is defined in */ - /* `include/freetype/config/ftoptions.h' */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; - - if ( face && - glyph_index < (FT_UInt)face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - /* now, lookup for glyph name */ - FT_Driver driver = face->driver; - FT_Module_Class* clazz = FT_MODULE_CLASS( driver ); - - - if ( clazz->get_interface ) - { - FT_Glyph_Name_Requester requester; - - - requester = (FT_Glyph_Name_Requester)clazz->get_interface( - FT_MODULE( driver ), "glyph_name" ); - if ( requester ) - error = requester( face, glyph_index, buffer, buffer_max ); - } - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Sfnt_Table */ - /* */ - /* */ - /* Returns a pointer to a given SFNT table within a face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* tag :: An index of an SFNT table. */ - /* */ - /* */ - /* A type-less pointer to the table. This will be 0 in case of */ - /* error, or if the corresponding table was not found *OR* loaded */ - /* from the file. */ - /* */ - /* */ - /* The table is owned by the face object, and disappears with it. */ - /* */ - /* This function is only useful to access SFNT tables that are loaded */ - /* by the sfnt/truetype/opentype drivers. See the FT_Sfnt_Tag */ - /* enumeration in `tttables.h' for a list. */ - /* */ - /* You can load any table with a different function.. XXX */ - /* */ - FT_EXPORT_FUNC( void* ) FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ) - { - void* table = 0; - FT_Get_Sfnt_Table_Func func; - FT_Driver driver; - - - if ( !face || !FT_IS_SFNT( face ) ) - goto Exit; - - driver = face->driver; - func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface( - FT_MODULE( driver ), "get_sfnt" ); - if ( func ) - table = func( face, tag ); - - Exit: - return table; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* lookup a renderer by glyph format in the library's list */ - BASE_FUNC( FT_Renderer ) FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ) - { - FT_ListNode cur; - FT_Renderer result = 0; - - - if ( !library ) - goto Exit; - - cur = library->renderers.head; - - if ( node ) - { - if ( *node ) - cur = (*node)->next; - *node = 0; - } - - while ( cur ) - { - FT_Renderer renderer = FT_RENDERER( cur->data ); - - - if ( renderer->glyph_format == format ) - { - if ( node ) - *node = cur; - - result = renderer; - break; - } - cur = cur->next; - } - - Exit: - return result; - } - - - static - FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ) - { - FT_Face face = slot->face; - FT_Library library = FT_FACE_LIBRARY( face ); - FT_Renderer result = library->cur_renderer; - - - if ( !result || result->glyph_format != slot->format ) - result = FT_Lookup_Renderer( library, slot->format, 0 ); - - return result; - } - - - static - void ft_set_current_renderer( FT_Library library ) - { - FT_Renderer renderer; - - - renderer = FT_Lookup_Renderer( library, ft_glyph_format_outline, 0 ); - library->cur_renderer = renderer; - } - - - static - FT_Error ft_add_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_Error error; - FT_ListNode node; - - - if ( ALLOC( node, sizeof ( *node ) ) ) - goto Exit; - - { - FT_Renderer render = FT_RENDERER( module ); - FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; - - - render->clazz = clazz; - render->glyph_format = clazz->glyph_format; - - /* allocate raster object if needed */ - if ( clazz->glyph_format == ft_glyph_format_outline && - clazz->raster_class->raster_new ) - { - error = clazz->raster_class->raster_new( memory, &render->raster ); - if ( error ) - goto Fail; - - render->raster_render = clazz->raster_class->raster_render; - render->render = clazz->render_glyph; - } - - /* add to list */ - node->data = module; - FT_List_Add( &library->renderers, node ); - - ft_set_current_renderer( library ); - } - - Fail: - if ( error ) - FREE( node ); - - Exit: - return error; - } - - - static - void ft_remove_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_ListNode node; - - - node = FT_List_Find( &library->renderers, module ); - if ( node ) - { - FT_Renderer render = FT_RENDERER( module ); - - - /* release raster object, if any */ - if ( render->raster ) - render->clazz->raster_class->raster_done( render->raster ); - - /* remove from list */ - FT_List_Remove( &library->renderers, node ); - FREE( node ); - - ft_set_current_renderer( library ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Renderer */ - /* */ - /* */ - /* Retrieves the current renderer for a given glyph format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* format :: The glyph format. */ - /* */ - /* */ - /* A renderer handle. 0 if none found. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - /* To add a new renderer, simply use FT_Add_Module(). To retrieve a */ - /* renderer by its name, use FT_Get_Module(). */ - /* */ - FT_EXPORT_FUNC( FT_Renderer ) FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ) - { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ - - return FT_Lookup_Renderer( library, format, 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Renderer */ - /* */ - /* */ - /* Sets the current renderer to use, and set additional mode. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* renderer :: A handle to the renderer object. */ - /* */ - /* num_params :: The number of additional parameters. */ - /* */ - /* parameters :: Additional parameters. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* In case of success, the renderer will be used to convert glyph */ - /* images in the renderer's known format into bitmaps. */ - /* */ - /* This doesn't change the current renderer for other formats. */ - /* */ - FT_EXPORT_DEF( FT_Error ) FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ) - { - FT_ListNode node; - FT_Error error = FT_Err_Ok; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !renderer ) - return FT_Err_Invalid_Argument; - - node = FT_List_Find( &library->renderers, renderer ); - if ( !node ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - FT_List_Up( &library->renderers, node ); - - if ( renderer->glyph_format == ft_glyph_format_outline ) - library->cur_renderer = renderer; - - if ( num_params > 0 ) - { - FTRenderer_setMode set_mode = renderer->clazz->set_mode; - - - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - } - } - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Error FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_UInt render_mode ) - { - FT_Error error = FT_Err_Ok; - FT_Renderer renderer; - - - /* if it is already a bitmap, no need to do anything */ - switch ( slot->format ) - { - case ft_glyph_format_bitmap: /* already a bitmap, don't do anything */ - break; - - default: - { - FT_ListNode node = 0; - FT_Bool update = 0; - - - /* small shortcut for the very common case */ - if ( slot->format == ft_glyph_format_outline ) - { - renderer = library->cur_renderer; - node = library->renderers.head; - } - else - renderer = FT_Lookup_Renderer( library, slot->format, &node ); - - error = FT_Err_Unimplemented_Feature; - while ( renderer ) - { - error = renderer->render( renderer, slot, render_mode, 0 ); - if ( !error || error != FT_Err_Cannot_Render_Glyph ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format. */ - - /* now, look for another renderer that supports the same */ - /* format. */ - renderer = FT_Lookup_Renderer( library, slot->format, &node ); - update = 1; - } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - } - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Render_Glyph */ - /* */ - /* */ - /* Converts a given glyph image to a bitmap. It does so by */ - /* inspecting the glyph image format, find the relevant renderer, and */ - /* invoke it. */ - /* */ - /* */ - /* slot :: A handle to the glyph slot containing the image to */ - /* convert. */ - /* */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See FT_Render_Mode for a list */ - /* of possible values. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, - FT_UInt render_mode ) - { - FT_Library library; - - - if ( !slot ) - return FT_Err_Invalid_Argument; - - library = FT_FACE_LIBRARY( slot->face ); - - return FT_Render_Glyph_Internal( library, slot, render_mode ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Destroy_Module */ - /* */ - /* */ - /* Destroys a given module object. For drivers, this also destroys */ - /* all child faces. */ - /* */ - /* */ - /* module :: A handle to the target driver object. */ - /* */ - /* */ - /* The driver _must_ be LOCKED! */ - /* */ - static - void Destroy_Module( FT_Module module ) - { - FT_Memory memory = module->memory; - FT_Module_Class* clazz = module->clazz; - FT_Library library = module->library; - - - /* finalize client-data - before anything else */ - if ( module->generic.finalizer ) - module->generic.finalizer( module ); - - if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; - - /* if the module is a renderer */ - if ( FT_MODULE_IS_RENDERER( module ) ) - ft_remove_renderer( module ); - - /* if the module is a font driver, add some steps */ - if ( FT_MODULE_IS_DRIVER( module ) ) - Destroy_Driver( FT_DRIVER( module ) ); - - /* finalize the module object */ - if ( clazz->module_done ) - clazz->module_done( module ); - - /* discard it */ - FREE( module ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Add_Module */ - /* */ - /* */ - /* Adds a new module to a given library instance. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* clazz :: A pointer to class descriptor for the module. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* An error will be returned if a module already exists by that name, */ - /* or if the module requires a version of FreeType that is too great. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ) - { - FT_Error error; - FT_Memory memory; - FT_Module module; - FT_UInt nn; - - -#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ - FREETYPE_MINOR ) - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !clazz ) - return FT_Err_Invalid_Argument; - - /* check freetype version */ - if ( clazz->module_requires > FREETYPE_VER_FIXED ) - return FT_Err_Invalid_Version; - - /* look for a module with the same name in the library's table */ - for ( nn = 0; nn < library->num_modules; nn++ ) - { - module = library->modules[nn]; - if ( strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) - { - /* this installed module has the same name, compare their versions */ - if ( clazz->module_version <= module->clazz->module_version ) - return FT_Err_Lower_Module_Version; - - /* remove the module from our list, then exit the loop to replace */ - /* it by our new version.. */ - FT_Remove_Module( library, module ); - break; - } - } - - memory = library->memory; - error = FT_Err_Ok; - - if ( library->num_modules >= FT_MAX_MODULES ) - { - error = FT_Err_Too_Many_Drivers; - goto Exit; - } - - /* allocate module object */ - if ( ALLOC( module,clazz->module_size ) ) - goto Exit; - - /* base initialization */ - module->library = library; - module->memory = memory; - module->clazz = (FT_Module_Class*)clazz; - - /* check whether the module is a renderer - this must be performed */ - /* before the normal module initialization */ - if ( FT_MODULE_IS_RENDERER( module ) ) - { - /* add to the renderers list */ - error = ft_add_renderer( module ); - if ( error ) - goto Fail; - } - - /* is the module a auto-hinter? */ - if ( FT_MODULE_IS_HINTER( module ) ) - library->auto_hinter = module; - - /* if the module is a font driver */ - if ( FT_MODULE_IS_DRIVER( module ) ) - { - /* allocate glyph loader if needed */ - FT_Driver driver = FT_DRIVER( module ); - - - driver->clazz = (FT_Driver_Class*)module->clazz; - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - error = FT_GlyphLoader_New( memory, &driver->glyph_loader ); - if ( error ) - goto Fail; - } - } - - if ( clazz->module_init ) - { - error = clazz->module_init( module ); - if ( error ) - goto Fail; - } - - /* add module to the library's table */ - library->modules[library->num_modules++] = module; - - Exit: - return error; - - Fail: - if ( FT_MODULE_IS_DRIVER( module ) ) - { - FT_Driver driver = FT_DRIVER( module ); - - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - FT_GlyphLoader_Done( driver->glyph_loader ); - } - - if ( FT_MODULE_IS_RENDERER( module ) ) - { - FT_Renderer renderer = FT_RENDERER( module ); - - - if ( renderer->raster ) - renderer->clazz->raster_class->raster_done( renderer->raster ); - } - - FREE( module ); - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module */ - /* */ - /* */ - /* Finds a module by its name. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module handle. 0 if none was found. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for :-) */ - /* */ - FT_EXPORT_FUNC( FT_Module ) FT_Get_Module( FT_Library library, - const char* module_name ) - { - FT_Module result = 0; - FT_Module* cur; - FT_Module* limit; - - - if ( !library || !module_name ) - return result; - - cur = library->modules; - limit = cur + library->num_modules; - - for ( ; cur < limit; cur++ ) - if ( strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) - { - result = cur[0]; - break; - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Get_Module_Interface */ - /* */ - /* */ - /* Finds a module and returns its specific interface as a typeless */ - /* pointer. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* module_name :: The module's name (as an ASCII string). */ - /* */ - /* */ - /* A module-specific interface if available, 0 otherwise. */ - /* */ - /* */ - /* You should better be familiar with FreeType internals to know */ - /* which module to look for, and what its interface is :-) */ - /* */ - BASE_FUNC( const void* ) FT_Get_Module_Interface( FT_Library library, - const char* mod_name ) - { - FT_Module module; - - - /* test for valid `library' delayed to FT_Get_Module() */ - - module = FT_Get_Module( library, mod_name ); - - return module ? module->clazz->module_interface : 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Remove_Module */ - /* */ - /* */ - /* Removes a given module from a library instance. */ - /* */ - /* */ - /* library :: A handle to a library object. */ - /* */ - /* module :: A handle to a module object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The module object is destroyed by the function in case of success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Remove_Module( FT_Library library, - FT_Module module ) - { - /* try to find the module from the table, then remove it from there */ - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( module ) - { - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == module ) - { - /* remove it from the table */ - library->num_modules--; - limit--; - while ( cur < limit ) - { - cur[0] = cur[1]; - cur++; - } - limit[0] = 0; - - /* destroy the module */ - Destroy_Module( module ); - - return FT_Err_Ok; - } - } - } - return FT_Err_Invalid_Driver_Handle; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Library */ - /* */ - /* */ - /* This function is used to create a new FreeType library instance */ - /* from a given memory object. It is thus possible to use libraries */ - /* with distinct memory allocators within the same program. */ - /* */ - /* */ - /* memory :: A handle to the original memory object. */ - /* */ - /* */ - /* alibrary :: A pointer to handle of a new library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Library( FT_Memory memory, - FT_Library* alibrary ) - { - FT_Library library = 0; - FT_Error error; - - - if ( !memory ) - return FT_Err_Invalid_Argument; - - /* first of all, allocate the library object */ - if ( ALLOC( library, sizeof ( *library ) ) ) - return error; - - library->memory = memory; - - /* allocate the render pool */ - library->raster_pool_size = FT_RENDER_POOL_SIZE; - if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) ) - goto Fail; - - /* That's ok now */ - *alibrary = library; - - return FT_Err_Ok; - - Fail: - FREE( library ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_Library */ - /* */ - /* */ - /* Discards a given library object. This closes all drivers and */ - /* discards all resource objects. */ - /* */ - /* */ - /* library :: A handle to the target library. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Done_Library( FT_Library library ) - { - FT_Memory memory; - FT_UInt n; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - memory = library->memory; - - /* Discard client-data */ - if ( library->generic.finalizer ) - library->generic.finalizer( library ); - - /* Close all modules in the library */ - for ( n = 0; n < library->num_modules; n++ ) - { - FT_Module module = library->modules[n]; - - - if ( module ) - { - Destroy_Module( module ); - library->modules[n] = 0; - } - } - - /* Destroy raster objects */ - FREE( library->raster_pool ); - library->raster_pool_size = 0; - - FREE( library ); - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Set_Debug_Hook */ - /* */ - /* */ - /* Sets a debug hook function for debugging the interpreter of a font */ - /* format. */ - /* */ - /* */ - /* library :: A handle to the library object. */ - /* */ - /* hook_index :: The index of the debug hook. You should use the */ - /* values defined in ftobjs.h, e.g. */ - /* FT_DEBUG_HOOK_TRUETYPE */ - /* */ - /* debug_hook :: The function used to debug the interpreter. */ - /* */ - /* */ - /* Currently, four debug hook slots are available, but only two (for */ - /* the TrueType and the Type 1 interpreter) are defined. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ) - { - if ( library && debug_hook && - hook_index < - ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) - library->debug_hooks[hook_index] = debug_hook; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Done_FreeType */ - /* */ - /* */ - /* Destroys a given FreeType library object and all of its childs, */ - /* including resources, drivers, faces, sizes, etc. */ - /* */ - /* */ - /* library :: A handle to the target library object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Done_FreeType( FT_Library library ) - { - /* test for valid `library' delayed to FT_Done_Library() */ - - /* Discard the library object */ - FT_Done_Library( library ); - - return FT_Err_Ok; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftoutln.c b/subsys/win32k/freetype/src/base/ftoutln.c deleted file mode 100644 index 20292d0..0000000 --- a/subsys/win32k/freetype/src/base/ftoutln.c +++ /dev/null @@ -1,842 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.c */ -/* */ -/* FreeType outline management (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* All functions are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_outline - - - static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Decompose */ - /* */ - /* */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* */ - /* outline :: A pointer to the source target. */ - /* */ - /* interface :: A table of `emitters', i.e,. function pointers called */ - /* during decomposition to indicate path operations. */ - /* */ - /* user :: A typeless pointer which is passed to each emitter */ - /* during the decomposition. It can be used to store */ - /* the state during the decomposition. */ - /* */ - /* */ - /* FreeType error code. 0 means sucess. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Decompose( - FT_Outline* outline, - FT_Outline_Funcs* interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - FT_Error error; - - FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ - char tag; /* current point's state */ - - FT_Int shift; - FT_Pos delta; - - - if ( !outline || !interface ) - return FT_Err_Invalid_Argument; - - shift = interface->shift; - delta = interface->delta; - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - FT_Int last; /* index of last point in contour */ - - - last = outline->contours[n]; - limit = outline->points + last; - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_Curve_Tag_Conic ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - error = interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_Curve_Tag_On: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_Curve_Tag_Conic: /* consume conic arcs */ - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_Curve_Tag_On ) - { - error = interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_Curve_Tag_Conic ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = interface->conic_to( &v_control, &v_start, user ); - goto Close; - - default: /* FT_Curve_Tag_Cubic */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - error = interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - error = interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - return 0; - - Exit: - return error; - - Invalid_Outline: - return FT_Err_Invalid_Outline; - } - - - FT_EXPORT_FUNC( FT_Error ) FT_Outline_New_Internal( - FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ) - { - FT_Error error; - - - if ( !outline || !memory ) - return FT_Err_Invalid_Argument; - - *outline = null_outline; - - if ( ALLOC_ARRAY( outline->points, numPoints * 2L, FT_Pos ) || - ALLOC_ARRAY( outline->tags, numPoints, FT_Byte ) || - ALLOC_ARRAY( outline->contours, numContours, FT_UShort ) ) - goto Fail; - - outline->n_points = (FT_UShort)numPoints; - outline->n_contours = (FT_Short)numContours; - outline->flags |= ft_outline_owner; - - return FT_Err_Ok; - - Fail: - outline->flags |= ft_outline_owner; - FT_Outline_Done_Internal( memory, outline ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_New */ - /* */ - /* */ - /* Creates a new outline of a given size. */ - /* */ - /* */ - /* library :: A handle to the library object from where the */ - /* outline is allocated. Note however that the new */ - /* outline will NOT necessarily be FREED, when */ - /* destroying the library, by FT_Done_FreeType(). */ - /* */ - /* numPoints :: The maximal number of points within the outline. */ - /* */ - /* numContours :: The maximal number of contours within the outline. */ - /* */ - /* */ - /* outline :: A handle to the new outline. NULL in case of */ - /* error. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* The reason why this function takes a `library' parameter is simply */ - /* to use the library's memory allocator. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ) - { - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - return FT_Outline_New_Internal( library->memory, numPoints, - numContours, outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Copy */ - /* */ - /* */ - /* Copies an outline into another one. Both objects must have the */ - /* same sizes (number of points & number of contours) when this */ - /* function is called. */ - /* */ - /* */ - /* source :: A handle to the source outline. */ - /* */ - /* */ - /* target :: A handle to the target outline. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Copy( FT_Outline* source, - FT_Outline* target ) - { - FT_Int is_owner; - - - if ( !source || !target || - source->n_points != target->n_points || - source->n_contours != target->n_contours ) - return FT_Err_Invalid_Argument; - - MEM_Copy( target->points, source->points, - source->n_points * sizeof ( FT_Vector ) ); - - MEM_Copy( target->tags, source->tags, - source->n_points * sizeof ( FT_Byte ) ); - - MEM_Copy( target->contours, source->contours, - source->n_contours * sizeof ( FT_Short ) ); - - /* copy all flags, except the `ft_outline_owner' one */ - is_owner = target->flags & ft_outline_owner; - target->flags = source->flags; - - target->flags &= ~ft_outline_owner; - target->flags |= is_owner; - - return FT_Err_Ok; - } - - - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ) - { - if ( outline ) - { - if ( outline->flags & ft_outline_owner ) - { - FREE( outline->points ); - FREE( outline->tags ); - FREE( outline->contours ); - } - *outline = null_outline; - - return FT_Err_Ok; - } - else - return FT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Done */ - /* */ - /* */ - /* Destroys an outline created with FT_Outline_New(). */ - /* */ - /* */ - /* library :: A handle of the library object used to allocate the */ - /* outline. */ - /* */ - /* outline :: A pointer to the outline object to be discarded. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* No. */ - /* */ - /* */ - /* If the outline's `owner' field is not set, only the outline */ - /* descriptor will be released. */ - /* */ - /* The reason why this function takes an `outline' parameter is */ - /* simply to use FT_Free(). */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Done( FT_Library library, - FT_Outline* outline ) - { - /* check for valid `outline' in FT_Outline_Done_Internal() */ - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - return FT_Outline_Done_Internal( library->memory, outline ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_CBox */ - /* */ - /* */ - /* Returns an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bezier control points. Though it */ - /* coincides with the exact bounding box for most glyphs, it can be */ - /* slightly larger in some situations (like when rotating an outline */ - /* which contains Bezier outside arcs). */ - /* */ - /* Computing the control box is very fast, while getting the bounding */ - /* box can take much more time as it needs to walk over all segments */ - /* and arcs in the outline. To get the latter, you can use the */ - /* `ftbbox' component which is dedicated to this single task. */ - /* */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* */ - /* cbox :: The outline's control box. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Outline_Get_CBox( FT_Outline* outline, - FT_BBox* cbox ) - { - FT_Pos xMin, yMin, xMax, yMax; - - - if ( outline && cbox ) - { - if ( outline->n_points == 0 ) - { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } - else - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; - - for ( ; vec < limit; vec++ ) - { - FT_Pos x, y; - - - x = vec->x; - if ( x < xMin ) xMin = x; - if ( x > xMax ) xMax = x; - - y = vec->y; - if ( y < yMin ) yMin = y; - if ( y > yMax ) yMax = y; - } - } - cbox->xMin = xMin; - cbox->xMax = xMax; - cbox->yMin = yMin; - cbox->yMax = yMax; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Translate */ - /* */ - /* */ - /* Applies a simple translation to the points of an outline. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* xOffset :: The horizontal offset. */ - /* */ - /* yOffset :: The vertical offset. */ - /* */ - /* */ - /* Yes. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Outline_Translate( FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ) - { - FT_UShort n; - FT_Vector* vec = outline->points; - - - for ( n = 0; n < outline->n_points; n++ ) - { - vec->x += xOffset; - vec->y += yOffset; - vec++; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Reverse */ - /* */ - /* */ - /* Reverses the drawing direction of an outline. This is used to */ - /* ensure consistent fill conventions for mirrored glyphs. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* */ - /* This functions toggles the bit flag `ft_outline_reverse_fill' in */ - /* the outline's `flags' field. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Outline_Reverse( FT_Outline* outline ) - { - FT_UShort n; - FT_Int first, last; - - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - last = outline->contours[n]; - - /* reverse point table */ - { - FT_Vector* p = outline->points + first; - FT_Vector* q = outline->points + last; - FT_Vector swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - /* reverse tags table */ - { - char* p = outline->tags + first; - char* q = outline->tags + last; - char swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - first = last + 1; - } - - outline->flags ^= ft_outline_reverse_fill; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Render */ - /* */ - /* */ - /* Renders an outline within a bitmap using the current scan-convert. */ - /* This functions uses an FT_Raster_Params structure as an argument, */ - /* allowing advanced features like direct composition, translucency, */ - /* etc. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* params :: A pointer to a FT_Raster_Params structure used to */ - /* describe the rendering operation. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* You should know what you are doing and how FT_Raster_Params works */ - /* to use this function. */ - /* */ - /* The field `params.source' will be set to `outline' before the scan */ - /* converter is called, which means that the value you give to it is */ - /* actually ignored. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ) - { - FT_Error error; - FT_Bool update = 0; - FT_Renderer renderer; - FT_ListNode node; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !params ) - return FT_Err_Invalid_Argument; - - renderer = library->cur_renderer; - node = library->renderers.head; - - params->source = (void*)outline; - - error = FT_Err_Cannot_Render_Glyph; - while ( renderer ) - { - error = renderer->raster_render( renderer->raster, params ); - if ( !error || error != FT_Err_Cannot_Render_Glyph ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format */ - - /* now, look for another renderer that supports the same */ - /* format */ - renderer = FT_Lookup_Renderer( library, ft_glyph_format_outline, - &node ); - update = 1; - } - - /* if we changed the current renderer for the glyph image format */ - /* we need to select it as the next current one */ - if ( !error && update && renderer ) - FT_Set_Renderer( library, renderer, 0, 0 ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Get_Bitmap */ - /* */ - /* */ - /* Renders an outline within a bitmap. The outline's image is simply */ - /* OR-ed to the target bitmap. */ - /* */ - /* */ - /* library :: A handle to a FreeType library object. */ - /* */ - /* outline :: A pointer to the source outline descriptor. */ - /* */ - /* map :: A pointer to the target bitmap descriptor. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* YES. Rendering is synchronized, so that concurrent calls to the */ - /* scan-line converter will be serialized. */ - /* */ - /* */ - /* This function does NOT CREATE the bitmap, it only renders an */ - /* outline image within the one you pass to it! */ - /* */ - /* It will use the raster correponding to the default glyph format. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - FT_Bitmap* bitmap ) - { - FT_Raster_Params params; - - - if ( !bitmap ) - return FT_Err_Invalid_Argument; - - /* other checks are delayed to FT_Outline_Render() */ - - params.target = bitmap; - params.flags = 0; - - if ( bitmap->pixel_mode == ft_pixel_mode_grays ) - params.flags |= ft_raster_flag_aa; - - return FT_Outline_Render( library, outline, ¶ms ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Vector_Transform */ - /* */ - /* */ - /* Transforms a single vector through a 2x2 matrix. */ - /* */ - /* */ - /* vector :: The target vector to transform. */ - /* */ - /* */ - /* matrix :: A pointer to the source 2x2 matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* The result is undefined if either `vector' or `matrix' is invalid. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Vector_Transform( FT_Vector* vector, - FT_Matrix* matrix ) - { - FT_Pos xz, yz; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulFix( vector->x, matrix->xx ) + - FT_MulFix( vector->y, matrix->xy ); - - yz = FT_MulFix( vector->x, matrix->yx ) + - FT_MulFix( vector->y, matrix->yy ); - - vector->x = xz; - vector->y = yz; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Transform */ - /* */ - /* */ - /* Applies a simple 2x2 matrix to all of an outline's points. Useful */ - /* for applying rotations, slanting, flipping, etc. */ - /* */ - /* */ - /* outline :: A pointer to the target outline descriptor. */ - /* */ - /* matrix :: A pointer to the transformation matrix. */ - /* */ - /* */ - /* Yes. */ - /* */ - /* */ - /* You can use FT_Outline_Translate() if you need to translate the */ - /* outline's points. */ - /* */ - FT_EXPORT_FUNC( void ) FT_Outline_Transform( FT_Outline* outline, - FT_Matrix* matrix ) - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - for ( ; vec < limit; vec++ ) - FT_Vector_Transform( vec, matrix ); - } - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftstream.c b/subsys/win32k/freetype/src/base/ftstream.c deleted file mode 100644 index 768586e..0000000 --- a/subsys/win32k/freetype/src/base/ftstream.c +++ /dev/null @@ -1,818 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.c */ -/* */ -/* I/O stream support (body). */ -/* */ -/* Copyright 2000 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 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_stream - - - BASE_FUNC( void ) FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ) - { - stream->memory = library->memory; - stream->base = base; - stream->size = size; - stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; - } - - - BASE_FUNC( FT_Error ) FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ) - { - FT_Error error; - - - stream->pos = pos; - - if ( stream->read ) - { - if ( stream->read( stream, pos, 0, 0 ) ) - { - FT_ERROR(( "FT_Seek_Stream:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - } - else - error = FT_Err_Ok; - } - /* note that seeking to the first position after the file is valid */ - else if ( pos > stream->size ) - { - FT_ERROR(( "FT_Seek_Stream:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - } - - else - error = FT_Err_Ok; - - return error; - } - - - BASE_FUNC( FT_Error ) FT_Skip_Stream( FT_Stream stream, - FT_Long distance ) - { - return FT_Seek_Stream( stream, (FT_ULong)( stream->pos + distance ) ); - } - - - BASE_FUNC( FT_Long ) FT_Stream_Pos( FT_Stream stream ) - { - return stream->pos; - } - - - BASE_FUNC( FT_Error ) FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Read_Stream_At( stream, stream->pos, buffer, count ); - } - - - BASE_FUNC( FT_Error ) FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - if ( pos >= stream->size ) - { - FT_ERROR(( "FT_Read_Stream_At:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - return FT_Err_Invalid_Stream_Operation; - } - - if ( stream->read ) - read_bytes = stream->read( stream, pos, buffer, count ); - else - { - read_bytes = stream->size - pos; - if ( read_bytes > count ) - read_bytes = count; - - MEM_Copy( buffer, stream->base + pos, read_bytes ); - } - - stream->pos = pos + read_bytes; - - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Read_Stream_At:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - error = FT_Err_Invalid_Stream_Operation; - } - - return error; - } - - - BASE_FUNC( FT_Error ) FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - FT_Error error; - - - error = FT_Access_Frame( stream, count ); - if ( !error ) - { - *pbytes = (FT_Byte*)stream->cursor; - - /* equivalent to FT_Forget_Frame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; - } - - return error; - } - - - BASE_FUNC( void ) FT_Release_Frame( FT_Stream stream, - FT_Byte** pbytes ) - { - if ( stream->read ) - { - FT_Memory memory = stream->memory; - - - FREE( *pbytes ); - } - *pbytes = 0; - } - - - BASE_FUNC( FT_Error ) FT_Access_Frame( FT_Stream stream, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - /* check for nested frame access */ - FT_Assert( stream && stream->cursor == 0 ); - - if ( stream->read ) - { - /* allocate the frame in memory */ - FT_Memory memory = stream->memory; - - - if ( ALLOC( stream->base, count ) ) - goto Exit; - - /* read it */ - read_bytes = stream->read( stream, stream->pos, - stream->base, count ); - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Access_Frame:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - FREE( stream->base ); - error = FT_Err_Invalid_Stream_Operation; - } - stream->cursor = stream->base; - stream->limit = stream->cursor + count; - stream->pos += read_bytes; - } - else - { - /* check current and new position */ - if ( stream->pos >= stream->size || - stream->pos + count > stream->size ) - { - FT_ERROR(( "FT_Access_Frame:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", - stream->pos, count, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - goto Exit; - } - - /* set cursor */ - stream->cursor = stream->base + stream->pos; - stream->limit = stream->cursor + count; - stream->pos += count; - } - - Exit: - return error; - } - - - BASE_FUNC( void ) FT_Forget_Frame( FT_Stream stream ) - { - /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ - /* that it is possible to access a frame of length 0 in */ - /* some weird fonts (usually, when accessing an array of */ - /* 0 records, like in some strange kern tables). */ - /* */ - /* In this case, the loader code handles the 0-length table */ - /* gracefully; however, stream.cursor is really set to 0 by the */ - /* FT_Access_Frame() call, and this is not an error. */ - /* */ - FT_Assert( stream ); - - if ( stream->read ) - { - FT_Memory memory = stream->memory; - - - FREE( stream->base ); - } - stream->cursor = 0; - stream->limit = 0; - } - - - BASE_FUNC( FT_Char ) FT_Get_Char( FT_Stream stream ) - { - FT_Char result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - if ( stream->cursor < stream->limit ) - result = *stream->cursor++; - - return result; - } - - - BASE_FUNC( FT_Short ) FT_Get_Short( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = NEXT_Short( p ); - stream->cursor = p; - - return result; - } - - - BASE_FUNC( FT_Short ) FT_Get_ShortLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = NEXT_ShortLE( p ); - stream->cursor = p; - - return result; - } - - - BASE_FUNC( FT_Long ) FT_Get_Offset( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 2 < stream->limit ) - result = NEXT_Offset( p ); - stream->cursor = p; - return result; - } - - - BASE_FUNC( FT_Long ) FT_Get_Long( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = NEXT_Long( p ); - stream->cursor = p; - return result; - } - - - BASE_FUNC( FT_Long ) FT_Get_LongLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_Assert( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = NEXT_LongLE( p ); - stream->cursor = p; - return result; - } - - - BASE_FUNC( FT_Char ) FT_Read_Char( FT_Stream stream, - FT_Error* error ) - { - FT_Byte result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) - goto Fail; - } - else - { - if ( stream->pos < stream->size ) - result = stream->base[stream->pos]; - else - goto Fail; - } - stream->pos++; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Read_Char:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - BASE_FUNC( FT_Short ) FT_Read_Short( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = NEXT_Short( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Read_Short:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - BASE_FUNC( FT_Short ) FT_Read_ShortLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = NEXT_ShortLE( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Read_Short:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - BASE_FUNC( FT_Long ) FT_Read_Offset( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 2 < stream->size ) - { - if ( stream->read ) - { - if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = NEXT_Offset( p ); - } - else - goto Fail; - - stream->pos += 3; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Read_Offset:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - BASE_FUNC( FT_Long ) FT_Read_Long( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = NEXT_Long( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - FT_ERROR(( "FT_Read_Long:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - *error = FT_Err_Invalid_Stream_Operation; - - return 0; - } - - - BASE_FUNC( FT_Long ) FT_Read_LongLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_Assert( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = NEXT_LongLE( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - FT_ERROR(( "FT_Read_Long:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - *error = FT_Err_Invalid_Stream_Operation; - - return 0; - } - - - BASE_FUNC( FT_Error ) FT_Read_Fields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ) - { - FT_Error error; - FT_Bool frame_accessed = 0; - - - if ( !fields || !stream ) - return FT_Err_Invalid_Argument; - - error = FT_Err_Ok; - do - { - FT_ULong value; - FT_Int sign_shift; - FT_Byte* p; - - - switch ( fields->value ) - { - case ft_frame_start: /* access a new frame */ - error = FT_Access_Frame( stream, fields->offset ); - if ( error ) - goto Exit; - - frame_accessed = 1; - fields++; - continue; /* loop! */ - - case ft_frame_bytes: /* read a byte sequence */ - case ft_frame_skip: /* skip some bytes */ - { - FT_Int len = fields->size; - - - if ( stream->cursor + len > stream->limit ) - { - error = FT_Err_Invalid_Stream_Operation; - goto Exit; - } - - if ( fields->value == ft_frame_bytes ) - { - p = (FT_Byte*)structure + fields->offset; - MEM_Copy( p, stream->cursor, len ); - } - stream->cursor += len; - fields++; - continue; - } - - case ft_frame_byte: - case ft_frame_schar: /* read a single byte */ - value = GET_Byte(); - sign_shift = 24; - break; - - case ft_frame_short_be: - case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = GET_UShort(); - sign_shift = 16; - break; - - case ft_frame_short_le: - case ft_frame_ushort_le: /* read a 2-byte little-endian short */ - { - FT_Byte* p; - - - value = 0; - p = stream->cursor; - - if ( p + 1 < stream->limit ) - { - value = ( FT_UShort)p[0] | ((FT_UShort)p[1] << 8 ); - stream->cursor += 2; - } - sign_shift = 16; - break; - } - - case ft_frame_long_be: - case ft_frame_ulong_be: /* read a 4-byte big-endian long */ - value = GET_ULong(); - sign_shift = 0; - break; - - case ft_frame_long_le: - case ft_frame_ulong_le: /* read a 4-byte little-endian long */ - { - FT_Byte* p; - - - value = 0; - p = stream->cursor; - - if ( p + 3 < stream->limit ) - { - value = (FT_ULong)p[0] | - ( (FT_ULong)p[1] << 8 ) | - ( (FT_ULong)p[2] << 16 ) | - ( (FT_ULong)p[3] << 24 ); - stream->cursor += 4; - } - sign_shift = 0; - break; - } - - case ft_frame_off3_be: - case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ - value = GET_UOffset(); - sign_shift = 8; - break; - - case ft_frame_off3_le: - case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ - { - FT_Byte* p; - - - value = 0; - p = stream->cursor; - - if ( p + 2 < stream->limit ) - { - value = (FT_ULong)p[0] | - ( (FT_ULong)p[1] << 8 ) | - ( (FT_ULong)p[2] << 16 ); - stream->cursor += 3; - } - sign_shift = 8; - break; - } - - default: - /* otherwise, exit the loop */ - goto Exit; - } - - /* now, compute the signed value is necessary */ - if ( fields->value & FT_FRAME_OP_SIGNED ) - value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); - - /* finally, store the value in the object */ - - p = (FT_Byte*)structure + fields->offset; - switch ( fields->size ) - { - case 1: - *(FT_Byte*)p = (FT_Byte)value; - break; - - case 2: - *(FT_UShort*)p = (FT_UShort)value; - break; - - case 4: - *(FT_UInt32*)p = (FT_UInt32)value; - break; - - default: /* for 64-bit systems */ - *(FT_ULong*)p = (FT_ULong)value; - } - - /* go to next field */ - fields++; - } - while ( 1 ); - - Exit: - /* close the frame if it was opened by this read */ - if ( frame_accessed ) - FT_Forget_Frame( stream ); - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/ftsystem.c b/subsys/win32k/freetype/src/base/ftsystem.c deleted file mode 100644 index 47508af..0000000 --- a/subsys/win32k/freetype/src/base/ftsystem.c +++ /dev/null @@ -1,307 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* ANSI-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2000 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 contains the default interface used by FreeType to access */ - /* low-level, i.e. memory management, i/o access as well as thread */ - /* synchronisation. It can be replaced by user-specific routines if */ - /* necessary. */ - /* */ - /*************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* It is not necessary to do any error checking for the */ - /* allocation-related functions. This will be done by the higher level */ - /* routines like FT_Alloc() or FT_Realloc(). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* ft_alloc */ - /* */ - /* */ - /* The memory allocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* size :: The requested size in bytes. */ - /* */ - /* */ - /* block :: The address of newly allocated block. */ - /* */ - static - void* ft_alloc( FT_Memory memory, - long size ) - { - FT_UNUSED( memory ); - -/* return malloc( size ); */ - return ExAllocatePool(NonPagedPool, size); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_realloc */ - /* */ - /* */ - /* The memory reallocation function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* */ - /* The address of the reallocated memory block. */ - /* */ - static - void* ft_realloc( FT_Memory memory, - long cur_size, - long new_size, - void* block ) - { - FT_UNUSED( memory ); - FT_UNUSED( cur_size ); - -/* return realloc( block, new_size ); */ - ExFreePool(block); - return ExAllocatePool(NonPagedPool, new_size); - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_free */ - /* */ - /* */ - /* The memory release function. */ - /* */ - /* */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ - static - void ft_free( FT_Memory memory, - void* block ) - { - FT_UNUSED( memory ); - -/* free( block ); */ - ExFreePool(block); - } - - - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_io - - /* We use the macro STREAM_FILE for convenience to extract the */ - /* system-specific stream handle from a given FreeType stream object */ -#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) - - - /*************************************************************************/ - /* */ - /* */ - /* ft_close_stream */ - /* */ - /* */ - /* The function to close a stream. */ - /* */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - static - void ft_close_stream( FT_Stream stream ) - { - DbgPrint("ftsystem.c: UNIMPLEMENTED CALL\n"); - -/* fclose( STREAM_FILE( stream ) ); */ - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* ft_io_stream */ - /* */ - /* */ - /* The function to open a stream. */ - /* */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - /* offset :: The position in the data stream to start reading. */ - /* */ - /* buffer :: The address of buffer to store the read data. */ - /* */ - /* count :: The number of bytes to read from the stream. */ - /* */ - /* */ - /* The number of bytes actually read. */ - /* */ - static - unsigned long ft_io_stream( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ) - { - FILE* file; - - DbgPrint("ftsystem.c: UNIMPLEMENTED CALL\n"); - file = STREAM_FILE( stream ); - -/* fseek( file, offset, SEEK_SET ); */ -/* return (unsigned long)fread( buffer, 1, count, file ); */ - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Stream */ - /* */ - /* */ - /* Creates a new stream object. */ - /* */ - /* */ - /* filepathname :: The name of the stream (usually a file) to be */ - /* opened. */ - /* */ - /* stream :: A pointer to the stream object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) FT_New_Stream( const char* filepathname, - FT_Stream stream ) - { -/* FILE* file; FIXME */ - - DbgPrint("ftsystem.c: UNIMPLEMENTED CALL\n"); - -/* if ( !stream ) - return FT_Err_Invalid_Stream_Handle; - - file = fopen( filepathname, "rb" ); - if ( !file ) - { - FT_ERROR(( "FT_New_Stream:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); - - return FT_Err_Cannot_Open_Resource; - } - - fseek( file, 0, SEEK_END ); - stream->size = ftell( file ); - fseek( file, 0, SEEK_SET ); - - stream->descriptor.pointer = file; - stream->pathname.pointer = (char*)filepathname; - stream->pos = 0; - - stream->read = ft_io_stream; - stream->close = ft_close_stream; - - FT_TRACE1(( "FT_New_Stream:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", - filepathname, stream->size )); */ - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* FT_New_Memory */ - /* */ - /* */ - /* Creates a new memory object. */ - /* */ - /* */ - /* A pointer to the new memory object. 0 in case of error. */ - /* */ - FT_EXPORT_FUNC( FT_Memory ) FT_New_Memory( void ) - { - FT_Memory memory; - -/* memory = (FT_Memory)malloc( sizeof ( *memory ) ); */ - - memory = ExAllocatePool(NonPagedPool, sizeof(*memory)); - if ( memory ) - { - memory->user = 0; - memory->alloc = ft_alloc; - memory->realloc = ft_realloc; - memory->free = ft_free; - } - - return memory; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/base/rules.mk b/subsys/win32k/freetype/src/base/rules.mk deleted file mode 100644 index 1763a09..0000000 --- a/subsys/win32k/freetype/src/base/rules.mk +++ /dev/null @@ -1,83 +0,0 @@ -# -# FreeType 2 base layer configuration rules -# - - -# Copyright 1996-2000 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. - - -# It sets the following variables which are used by the master Makefile -# after the call: -# -# BASE_OBJ_S: The single-object base layer. -# BASE_OBJ_M: A list of all objects for a multiple-objects build. -# BASE_EXT_OBJ: A list of base layer extensions, i.e., components found -# in `freetype/src/base' which are not compiled within the -# base layer proper. -# -# BASE_H is defined in freetype.mk to simplify the dependency rules. - - -BASE_COMPILE := $(FT_COMPILE) $I$(SRC_)base - - -# Base layer sources -# -# ftsystem, ftinit, and ftdebug are handled by freetype.mk -# -BASE_SRC := $(BASE_)ftcalc.c \ - $(BASE_)ftextend.c \ - $(BASE_)ftlist.c \ - $(BASE_)ftobjs.c \ - $(BASE_)ftstream.c \ - $(BASE_)ftoutln.c - -# Base layer `extensions' sources -# -# An extension is added to the library file (.a or .lib) as a separate -# object. It will then be linked to the final executable only if one of its -# symbols is used by the application. -# -BASE_EXT_SRC := $(BASE_)ftglyph.c \ - $(BASE_)ftmm.c - -# Default extensions objects -# -BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O) - - -# Base layer object(s) -# -# BASE_OBJ_M is used during `multi' builds (each base source file compiles -# to a single object file). -# -# BASE_OBJ_S is used during `single' builds (the whole base layer is -# compiled as a single object file using ftbase.c). -# -BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O) -BASE_OBJ_S := $(OBJ_)ftbase.$O - -# Base layer root source file for single build -# -BASE_SRC_S := $(BASE_)ftbase.c - - -# Base layer - single object build -# -$(BASE_OBJ_S): $(BASE_SRC_S) $(BASE_SRC) $(FREETYPE_H) - $(BASE_COMPILE) $T$@ $(BASE_SRC_S) - - -# Multiple objects build + extensions -# -$(OBJ_)%.$O: $(BASE_)%.c $(FREETYPE_H) - $(BASE_COMPILE) $T$@ $< - -# EOF diff --git a/subsys/win32k/freetype/src/cff/.cvsignore b/subsys/win32k/freetype/src/cff/.cvsignore deleted file mode 100644 index 31dc307..0000000 --- a/subsys/win32k/freetype/src/cff/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -*.d -*.o diff --git a/subsys/win32k/freetype/src/cff/cff.c b/subsys/win32k/freetype/src/cff/cff.c deleted file mode 100644 index a962839..0000000 --- a/subsys/win32k/freetype/src/cff/cff.c +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* cff.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#ifdef FT_FLAT_COMPILE - -#include "t2driver.c" /* driver interface */ -#include "t2parse.c" /* token parser */ -#include "t2load.c" /* tables loader */ -#include "t2objs.c" /* object management */ -#include "t2gload.c" /* glyph loader */ - -#else - -#include /* driver interface */ -#include /* token parser */ -#include /* tables loader */ -#include /* object management */ -#include /* glyph loader */ - -#endif - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/module.mk b/subsys/win32k/freetype/src/cff/module.mk deleted file mode 100644 index 9bc5c8f..0000000 --- a/subsys/win32k/freetype/src/cff/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_cff_driver - -add_cff_driver: - $(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)cff $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/cff/rules.mk b/subsys/win32k/freetype/src/cff/rules.mk deleted file mode 100644 index ba87af5..0000000 --- a/subsys/win32k/freetype/src/cff/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 OpenType/CFF driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# OpenType driver directory -# -T2_DIR := $(SRC_)cff -T2_DIR_ := $(T2_DIR)$(SEP) - - -T2_COMPILE := $(FT_COMPILE) - - -# T2 driver sources (i.e., C files) -# -T2_DRV_SRC := $(T2_DIR_)t2objs.c \ - $(T2_DIR_)t2load.c \ - $(T2_DIR_)t2gload.c \ - $(T2_DIR_)t2parse.c \ - $(T2_DIR_)t2driver.c - -# T2 driver headers -# -T2_DRV_H := $(T2_DRV_SRC:%.c=%.h) \ - $(T2_DIR_)t2tokens.h - - -# T2 driver object(s) -# -# T2_DRV_OBJ_M is used during `multi' builds -# T2_DRV_OBJ_S is used during `single' builds -# -T2_DRV_OBJ_M := $(T2_DRV_SRC:$(T2_DIR_)%.c=$(OBJ_)%.$O) -T2_DRV_OBJ_S := $(OBJ_)cff.$O - -# T2 driver source file for single build -# -T2_DRV_SRC_S := $(T2_DIR_)cff.c - - -# T2 driver - single object -# -$(T2_DRV_OBJ_S): $(T2_DRV_SRC_S) $(T2_DRV_SRC) $(FREETYPE_H) $(T2_DRV_H) - $(T2_COMPILE) $T$@ $(T2_DRV_SRC_S) - - -# T2 driver - multiple objects -# -$(OBJ_)%.$O: $(T2_DIR_)%.c $(FREETYPE_H) $(T2_DRV_H) - $(T2_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(T2_DRV_OBJ_S) -DRV_OBJS_M += $(T2_DRV_OBJ_M) - -# EOF diff --git a/subsys/win32k/freetype/src/cff/t2driver.c b/subsys/win32k/freetype/src/cff/t2driver.c deleted file mode 100644 index ce73529..0000000 --- a/subsys/win32k/freetype/src/cff/t2driver.c +++ /dev/null @@ -1,377 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2driver.c */ -/* */ -/* OpenType font driver implementation (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t2driver.h" -#include "t2gload.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t2driver - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - TT_Kern_0_Pair* pair; - - - if ( !face ) - return T2_Err_Invalid_Face_Handle; - - kerning->x = 0; - kerning->y = 0; - - if ( face->kern_pairs ) - { - /* there are some kerning pairs in this font file! */ - FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); - FT_Long left, right; - - - left = 0; - right = face->num_kern_pairs - 1; - - while ( left <= right ) - { - FT_Int middle = left + ( ( right - left ) >> 1 ); - FT_ULong cur_pair; - - - pair = face->kern_pairs + middle; - cur_pair = PAIR_TAG( pair->left, pair->right ); - - if ( cur_pair == search_tag ) - goto Found; - - if ( cur_pair < search_tag ) - left = middle + 1; - else - right = middle - 1; - } - } - - Exit: - return T2_Err_Ok; - - Found: - kerning->x = pair->value; - goto Exit; - } - - -#undef PAIR_TAG - - - /*************************************************************************/ - /* */ - /* */ - /* Load_Glyph */ - /* */ - /* */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_Glyph( T2_GlyphSlot slot, - T2_Size size, - FT_UShort glyph_index, - FT_UInt load_flags ) - { - FT_Error error; - - - if ( !slot ) - return T2_Err_Invalid_Glyph_Handle; - - /* check whether we want a scaled outline or bitmap */ - if ( !size ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - if ( load_flags & FT_LOAD_NO_SCALE ) - size = NULL; - - /* reset the size object if necessary */ - if ( size ) - { - /* these two object must have the same parent */ - if ( size->face != slot->root.face ) - return T2_Err_Invalid_Face_Handle; - } - - /* now load the glyph outline if necessary */ - error = T2_Load_Glyph( slot, size, glyph_index, load_flags ); - - /* force drop-out mode to 2 - irrelevant now */ - /* slot->outline.dropout_mode = 2; */ - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R A C T E R M A P P I N G S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt t2_get_char_index( TT_CharMap charmap, - FT_Long charcode ) - { - FT_Error error; - T2_Face face; - TT_CMapTable* cmap; - - - cmap = &charmap->cmap; - face = (T2_Face)charmap->root.face; - - /* Load table if needed */ - if ( !cmap->loaded ) - { - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - error = sfnt->load_charmap( face, cmap, face->root.stream ); - if ( error ) - return 0; - - cmap->loaded = TRUE; - } - - return ( cmap->get_index ? cmap->get_index( cmap, charcode ) : 0 ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Module_Interface t2_get_interface( T2_Driver driver, - const char* interface ) - { - FT_Module sfnt; - - - /* we simply pass our request to the `sfnt' module */ - sfnt = FT_Get_Module( driver->root.root.library, "sfnt" ); - - return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0; - } - - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - - const FT_Driver_Class cff_driver_class = - { - /* begin with the FT_Module_Class fields */ - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( T2_DriverRec ), - "cff", - 0x10000L, - 0x20000L, - - 0, /* module-specific interface */ - - (FT_Module_Constructor)T2_Init_Driver, - (FT_Module_Destructor) T2_Done_Driver, - (FT_Module_Requester) t2_get_interface, - }, - - /* now the specific driver fields */ - sizeof( TT_FaceRec ), - sizeof( FT_SizeRec ), - sizeof( T2_GlyphSlotRec ), - - (FTDriver_initFace) T2_Init_Face, - (FTDriver_doneFace) T2_Done_Face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes)0, - - (FTDriver_loadGlyph) Load_Glyph, - (FTDriver_getCharIndex) t2_get_char_index, - - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverClass */ - /* */ - /* */ - /* This function is used when compiling the TrueType driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( FT_Driver_Class* ) getDriverClass( void ) - { - return &cff_driver_class; - } - - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2driver.h b/subsys/win32k/freetype/src/cff/t2driver.h deleted file mode 100644 index e0b0afd..0000000 --- a/subsys/win32k/freetype/src/cff/t2driver.h +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2driver.h */ -/* */ -/* High-level OpenType driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 T2DRIVER_H -#define T2DRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) cff_driver_class; - - -#endif /* T2DRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2gload.c b/subsys/win32k/freetype/src/cff/t2gload.c deleted file mode 100644 index 4a0ddc0..0000000 --- a/subsys/win32k/freetype/src/cff/t2gload.c +++ /dev/null @@ -1,2045 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2gload.c */ -/* */ -/* OpenType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t2load.h" -#include "t2gload.h" - -#else - -#include -#include - -#endif - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t2gload - - - typedef enum T2_Operator_ - { - t2_op_unknown = 0, - - t2_op_rmoveto, - t2_op_hmoveto, - t2_op_vmoveto, - - t2_op_rlineto, - t2_op_hlineto, - t2_op_vlineto, - - t2_op_rrcurveto, - t2_op_hhcurveto, - t2_op_hvcurveto, - t2_op_rcurveline, - t2_op_rlinecurve, - t2_op_vhcurveto, - t2_op_vvcurveto, - - t2_op_flex, - t2_op_hflex, - t2_op_hflex1, - t2_op_flex1, - - t2_op_endchar, - - t2_op_hstem, - t2_op_vstem, - t2_op_hstemhm, - t2_op_vstemhm, - - t2_op_hintmask, - t2_op_cntrmask, - - t2_op_abs, - t2_op_add, - t2_op_sub, - t2_op_div, - t2_op_neg, - t2_op_random, - t2_op_mul, - t2_op_sqrt, - - t2_op_blend, - - t2_op_drop, - t2_op_exch, - t2_op_index, - t2_op_roll, - t2_op_dup, - - t2_op_put, - t2_op_get, - t2_op_store, - t2_op_load, - - t2_op_and, - t2_op_or, - t2_op_not, - t2_op_eq, - t2_op_ifelse, - - t2_op_callsubr, - t2_op_callgsubr, - t2_op_return, - - /* do not remove */ - t2_op_max - - } T2_Operator; - - -#define T2_COUNT_CHECK_WIDTH 0x80 -#define T2_COUNT_EXACT 0x40 -#define T2_COUNT_CLEAR_STACK 0x20 - - - static const FT_Byte t2_argument_counts[] = - { - 0, /* unknown */ - - 2 | T2_COUNT_CHECK_WIDTH | T2_COUNT_EXACT, /* rmoveto */ - 1 | T2_COUNT_CHECK_WIDTH | T2_COUNT_EXACT, - 1 | T2_COUNT_CHECK_WIDTH | T2_COUNT_EXACT, - - 0 | T2_COUNT_CLEAR_STACK, /* rlineto */ - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - - 0 | T2_COUNT_CLEAR_STACK, /* rrcurveto */ - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - 0 | T2_COUNT_CLEAR_STACK, - - 13, /* flex */ - 7, - 9, - 11, - - 0, /* endchar */ - - 2 | T2_COUNT_CHECK_WIDTH, /* hstem */ - 2 | T2_COUNT_CHECK_WIDTH, - 2 | T2_COUNT_CHECK_WIDTH, - 2 | T2_COUNT_CHECK_WIDTH, - - 0, /* hintmask */ - 0, /* cntrmask */ - - 1, /* abs */ - 2, - 2, - 2, - 1, - 0, - 2, - 1, - - 1, /* blend */ - - 1, /* drop */ - 2, - 1, - 2, - 1, - - 2, /* put */ - 1, - 4, - 3, - - 2, /* and */ - 2, - 1, - 2, - 4, - - 1, /* callsubr */ - 1, - 0 - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - static - void T2_Init_Builder( T2_Builder* builder, - TT_Face face, - T2_Size size, - T2_GlyphSlot glyph ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = glyph->root.loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - FT_GlyphLoader_Rewind( loader ); - } - - if ( size ) - { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - static - void T2_Done_Builder( T2_Builder* builder ) - { - T2_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t2_compute_bias */ - /* */ - /* */ - /* Computes the bias value in dependence of the number of glyph */ - /* subroutines. */ - /* */ - /* */ - /* num_subrs :: The number of glyph subroutines. */ - /* */ - /* */ - /* The bias value. */ - static - FT_Int t2_compute_bias( FT_UInt num_subrs ) - { - FT_Int result; - - - if ( num_subrs < 1240 ) - result = 107; - else if ( num_subrs < 33900 ) - result = 1131; - else - result = 32768; - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* slot :: The current glyph object. */ - /* */ - LOCAL_FUNC - void T2_Init_Decoder( T2_Decoder* decoder, - TT_Face face, - T2_Size size, - T2_GlyphSlot slot ) - { - CFF_Font* cff = (CFF_Font*)face->extra.data; - - - /* clear everything */ - MEM_Set( decoder, 0, sizeof ( *decoder ) ); - - /* initialize builder */ - T2_Init_Builder( &decoder->builder, face, size, slot ); - - /* initialize Type2 decoder */ - decoder->num_globals = cff->num_global_subrs; - decoder->globals = cff->global_subrs; - decoder->globals_bias = t2_compute_bias( decoder->num_globals ); - } - - - /* this function is used to select the locals subrs array */ - LOCAL_DEF - void T2_Prepare_Decoder( T2_Decoder* decoder, - FT_UInt glyph_index ) - { - CFF_Font* cff = (CFF_Font*)decoder->builder.face->extra.data; - CFF_SubFont* sub = &cff->top_font; - - - /* manage CID fonts */ - if ( cff->num_subfonts >= 1 ) - { - FT_Byte fd_index = CFF_Get_FD( &cff->fd_select, glyph_index ); - - - sub = cff->subfonts[fd_index]; - } - - decoder->num_locals = sub->num_local_subrs; - decoder->locals = sub->local_subrs; - decoder->locals_bias = t2_compute_bias( decoder->num_locals ); - - decoder->glyph_width = sub->private_dict.default_width; - decoder->nominal_width = sub->private_dict.nominal_width; - } - - - /* check that there is enough room for `count' more points */ - static - FT_Error check_points( T2_Builder* builder, - FT_Int count ) - { - return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); - } - - - /* add a new point, do not check space */ - static - void add_point( T2_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = x >> 16; - point->y = y >> 16; - *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; - - builder->last = *point; - } - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - static - FT_Error add_point1( T2_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = check_points( builder, 1 ); - if ( !error ) - add_point( builder, x, y, 1 ); - - return error; - } - - - /* check room for a new contour, then add it */ - static - FT_Error add_contour( T2_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return T2_Err_Ok; - } - - error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - static - FT_Error start_point( T2_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error = 0; - - - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - builder->path_begun = 1; - error = add_contour( builder ); - if ( !error ) - error = add_point1( builder, x, y ); - } - return error; - } - - - /* close the current contour */ - static - void close_contour( T2_Builder* builder ) - { - FT_Outline* outline = builder->current; - - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - } - - -#define USE_ARGS( n ) do \ - { \ - top -= n; \ - if ( top < decoder->stack ) \ - goto Stack_Underflow; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 2 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T2_Parse_CharStrings( T2_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ) - { - FT_Error error; - T2_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - T2_Builder* builder = &decoder->builder; - FT_Outline* outline; - FT_Pos x, y; - FT_Fixed seed; - FT_Fixed* stack; - - - /* set default width */ - decoder->num_hints = 0; - decoder->read_width = 1; - - /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)(char*)&seed ^ - (FT_Fixed)(char*)&decoder ^ - (FT_Fixed)(char*)&charstring_base; - seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFF; - if ( seed == 0 ) - seed = 0x7384; - - /* initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - stack = decoder->top; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T2_Err_Ok; - outline = builder->current; - - x = builder->pos_x; - y = builder->pos_y; - - /* now, execute loop */ - while ( ip < limit ) - { - T2_Operator op; - FT_Byte v; - FT_Byte count; - - - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - v = *ip++; - if ( v >= 32 || v == 28 ) - { - FT_Int shift = 16; - FT_Int32 val; - - - /* this is an operand, push it on the stack */ - if ( v == 28 ) - { - if ( ip + 1 >= limit ) - goto Syntax_Error; - val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] ); - ip += 2; - } - else if ( v < 247 ) - val = (FT_Long)v - 139; - else if ( v < 251 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108; - } - else if ( v < 255 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108; - } - else - { - if ( ip + 3 >= limit ) - goto Syntax_Error; - val = ( (FT_Int32)ip[0] << 24 ) | - ( (FT_Int32)ip[1] << 16 ) | - ( (FT_Int32)ip[2] << 8 ) | - ip[3]; - ip += 4; - shift = 0; - } - if ( decoder->top - stack >= T2_MAX_OPERANDS ) - goto Stack_Overflow; - - val <<= shift; - *decoder->top++ = val; - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !( val & 0xFFFF ) ) - FT_TRACE4(( " %d", (FT_Int32)( val >> 16 ) )); - else - FT_TRACE4(( " %.2f", val/65536.0 )); -#endif - - } - else - { - FT_Fixed* args = decoder->top; - FT_Int num_args = args - decoder->stack; - FT_Int req_args; - - - /* find operator */ - op = t2_op_unknown; - - switch ( v ) - { - case 1: - op = t2_op_hstem; - break; - case 3: - op = t2_op_vstem; - break; - case 4: - op = t2_op_vmoveto; - break; - case 5: - op = t2_op_rlineto; - break; - case 6: - op = t2_op_hlineto; - break; - case 7: - op = t2_op_vlineto; - break; - case 8: - op = t2_op_rrcurveto; - break; - case 10: - op = t2_op_callsubr; - break; - case 11: - op = t2_op_return; - break; - case 12: - { - if ( ip >= limit ) - goto Syntax_Error; - v = *ip++; - - switch ( v ) - { - case 3: - op = t2_op_and; - break; - case 4: - op = t2_op_or; - break; - case 5: - op = t2_op_not; - break; - case 8: - op = t2_op_store; - break; - case 9: - op = t2_op_abs; - break; - case 10: - op = t2_op_add; - break; - case 11: - op = t2_op_sub; - break; - case 12: - op = t2_op_div; - break; - case 13: - op = t2_op_load; - break; - case 14: - op = t2_op_neg; - break; - case 15: - op = t2_op_eq; - break; - case 18: - op = t2_op_drop; - break; - case 20: - op = t2_op_put; - break; - case 21: - op = t2_op_get; - break; - case 22: - op = t2_op_ifelse; - break; - case 23: - op = t2_op_random; - break; - case 24: - op = t2_op_mul; - break; - case 26: - op = t2_op_sqrt; - break; - case 27: - op = t2_op_dup; - break; - case 28: - op = t2_op_exch; - break; - case 29: - op = t2_op_index; - break; - case 30: - op = t2_op_roll; - break; - case 34: - op = t2_op_hflex; - break; - case 35: - op = t2_op_flex; - break; - case 36: - op = t2_op_hflex1; - break; - case 37: - op = t2_op_flex1; - break; - default: - /* decrement ip for syntax error message */ - ip--; - } - } - break; - case 14: - op = t2_op_endchar; - break; - case 16: - op = t2_op_blend; - break; - case 18: - op = t2_op_hstemhm; - break; - case 19: - op = t2_op_hintmask; - break; - case 20: - op = t2_op_cntrmask; - break; - case 21: - op = t2_op_rmoveto; - break; - case 22: - op = t2_op_hmoveto; - break; - case 23: - op = t2_op_vstemhm; - break; - case 24: - op = t2_op_rcurveline; - break; - case 25: - op = t2_op_rlinecurve; - break; - case 26: - op = t2_op_vvcurveto; - break; - case 27: - op = t2_op_hhcurveto; - break; - case 29: - op = t2_op_callgsubr; - break; - case 30: - op = t2_op_vhcurveto; - break; - case 31: - op = t2_op_hvcurveto; - break; - default: - ; - } - if ( op == t2_op_unknown ) - goto Syntax_Error; - - /* check arguments */ - req_args = count = t2_argument_counts[op]; - if ( req_args & T2_COUNT_CHECK_WIDTH ) - { - args = stack; - if ( num_args & 1 && decoder->read_width ) - { - decoder->glyph_width = decoder->nominal_width + - ( stack[0] >> 16 ); - num_args--; - args++; - } - decoder->read_width = 0; - req_args = 0; - } - - req_args &= 15; - if ( num_args < req_args ) - goto Stack_Underflow; - args -= req_args; - num_args -= req_args; - - switch ( op ) - { - case t2_op_hstem: - case t2_op_vstem: - case t2_op_hstemhm: - case t2_op_vstemhm: - /* if the number of arguments is not even, the first one */ - /* is simply the glyph width, encoded as the difference */ - /* to nominalWidthX */ - FT_TRACE4(( op == t2_op_hstem ? " hstem" : - op == t2_op_vstem ? " vstem" : - op == t2_op_hstemhm ? " hstemhm" : - " vstemhm" )); - decoder->num_hints += num_args / 2; - args = stack; - break; - - case t2_op_hintmask: - case t2_op_cntrmask: - FT_TRACE4(( op == t2_op_hintmask ? " hintmask" - : " cntrmask" )); - - decoder->num_hints += num_args / 2; - ip += ( decoder->num_hints + 7 ) >> 3; - if ( ip >= limit ) - goto Syntax_Error; - args = stack; - break; - - case t2_op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - close_contour( builder ); - builder->path_begun = 0; - x += args[0]; - y += args[1]; - args = stack; - break; - - case t2_op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - close_contour( builder ); - builder->path_begun = 0; - y += args[0]; - args = stack; - break; - - case t2_op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - close_contour( builder ); - builder->path_begun = 0; - x += args[0]; - args = stack; - break; - - case t2_op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( start_point ( builder, x, y ) || - check_points( builder, num_args / 2 ) ) - goto Memory_Error; - - if ( num_args < 2 || num_args & 1 ) - goto Stack_Underflow; - - args = stack; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, 1 ); - args += 2; - } - args = stack; - break; - - case t2_op_hlineto: - case t2_op_vlineto: - { - FT_Int phase = ( op == t2_op_hlineto ); - - - FT_TRACE4(( op == t2_op_hlineto ? " hlineto" - : " vlineto" )); - - if ( start_point ( builder, x, y ) || - check_points( builder, num_args ) ) - goto Memory_Error; - - args = stack; - while (args < decoder->top ) - { - if ( phase ) - x += args[0]; - else - y += args[0]; - - if ( add_point1( builder, x, y ) ) - goto Memory_Error; - - args++; - phase ^= 1; - } - args = stack; - } - break; - - case t2_op_rrcurveto: - FT_TRACE4(( " rrcurveto" )); - - /* check number of arguments; must be a multiple of 6 */ - if ( num_args % 6 != 0 ) - goto Stack_Underflow; - - if ( start_point ( builder, x, y ) || - check_points( builder, num_args / 2 ) ) - goto Memory_Error; - - args = stack; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - add_point( builder, x, y, 1 ); - args += 6; - } - args = stack; - break; - - case t2_op_vvcurveto: - FT_TRACE4(( " vvcurveto" )); - - if ( start_point ( builder, x, y ) ) - goto Memory_Error; - - args = stack; - if ( num_args & 1 ) - { - x += args[0]; - args++; - num_args--; - } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Memory_Error; - - while ( args < decoder->top ) - { - y += args[0]; - add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - add_point( builder, x, y, 0 ); - y += args[3]; - add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - break; - - case t2_op_hhcurveto: - FT_TRACE4(( " hhcurveto" )); - - if ( start_point ( builder, x, y ) ) - goto Memory_Error; - - args = stack; - if ( num_args & 1 ) - { - y += args[0]; - args++; - num_args--; - } - - if ( num_args % 4 != 0 ) - goto Stack_Underflow; - - if ( check_points( builder, 3 * ( num_args / 4 ) ) ) - goto Memory_Error; - - while ( args < decoder->top ) - { - x += args[0]; - add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - add_point( builder, x, y, 0 ); - x += args[3]; - add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - break; - - case t2_op_vhcurveto: - case t2_op_hvcurveto: - { - FT_Int phase; - - - FT_TRACE4(( op == t2_op_vhcurveto ? " vhcurveto" - : " hvcurveto" )); - - if ( start_point ( builder, x, y ) ) - goto Memory_Error; - - args = stack; - if (num_args < 4 || ( num_args % 4 ) > 1 ) - goto Stack_Underflow; - - if ( check_points( builder, ( num_args / 4 ) * 3 ) ) - goto Stack_Underflow; - - phase = ( op == t2_op_hvcurveto ); - - while ( num_args >= 4 ) - { - num_args -= 4; - if ( phase ) - { - x += args[0]; - add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - add_point( builder, x, y, 0 ); - y += args[3]; - if ( num_args == 1 ) - x += args[4]; - add_point( builder, x, y, 1 ); - } - else - { - y += args[0]; - add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - add_point( builder, x, y, 0 ); - x += args[3]; - if ( num_args == 1 ) - y += args[4]; - add_point( builder, x, y, 1 ); - } - args += 4; - phase ^= 1; - } - args = stack; - } - break; - - case t2_op_rlinecurve: - { - FT_Int num_lines = ( num_args - 6 ) / 2; - - - FT_TRACE4(( " rlinecurve" )); - - if ( num_args < 8 || ( num_args - 6 ) & 1 ) - goto Stack_Underflow; - - if ( start_point( builder, x, y ) || - check_points( builder, num_lines + 3 ) ) - goto Memory_Error; - - args = stack; - - /* first, add the line segments */ - while ( num_lines > 0 ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, 1 ); - args += 2; - num_lines--; - } - - /* then the curve */ - x += args[0]; - y += args[1]; - add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case t2_op_rcurveline: - { - FT_Int num_curves = ( num_args - 2 ) / 6; - - - FT_TRACE4(( " rcurveline" )); - - if ( num_args < 8 || ( num_args - 2 ) % 6 ) - goto Stack_Underflow; - - if ( start_point ( builder, x, y ) || - check_points( builder, num_curves*3 + 2 ) ) - goto Memory_Error; - - args = stack; - - /* first, add the curves */ - while ( num_curves > 0 ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - add_point( builder, x, y, 1 ); - args += 6; - num_curves--; - } - - /* then the final line */ - x += args[0]; - y += args[1]; - add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case t2_op_hflex1: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex1" )); - - args = stack; - - /* adding five more points; 4 control points, 1 on-curve point */ - /* make sure we have enough space for the start point if it */ - /* needs to be added.. */ - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - - /* Record the starting point's y postion for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - y += args[1]; - add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[2]; - y += args[3]; - add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[4]; - add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[5]; - add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[6]; - y += args[7]; - add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start */ - x += args[8]; - y = start_y; - add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case t2_op_hflex: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex" )); - - args = stack; - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( start_point( builder, x, y ) || - check_points ( builder, 6 ) ) - goto Memory_Error; - - /* record the starting point's y-position for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[1]; - y += args[2]; - add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[3]; - add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[4]; - add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[5]; - y = start_y; - add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start point's */ - /* y-value -- we don't add this point, though */ - x += args[6]; - add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case t2_op_flex1: - { - FT_Pos start_x, start_y; /* record start x, y values for alter */ - /* use */ - FT_Int dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; - - - FT_TRACE4(( " flex1" )); - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - - /* record the starting point's x, y postion for later use */ - start_x = x; - start_y = y; - - /* XXX: figure out whether this is supposed to be a horizontal */ - /* or vertical flex; the Type 2 specification is vague... */ - - args = stack; - - /* grab up to the last argument */ - for ( count = 5; count > 0; count-- ) - { - dx += args[0]; - dy += args[1]; - args += 2; - } - - /* rewind */ - args = stack; - - if ( dx < 0 ) dx = -dx; - if ( dy < 0 ) dy = -dy; - - /* strange test, but here it is... */ - horizontal = ( dx > dy ); - - for ( count = 5; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, (FT_Bool)( count == 3 ) ); - args += 2; - } - - /* is last operand an x- or y-delta? */ - if ( horizontal ) - { - x += args[0]; - y = start_y; - } - else - { - x = start_x; - y += args[0]; - } - - add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case t2_op_flex: - { - FT_UInt count; - - - FT_TRACE4(( " flex" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - - args = stack; - for ( count = 6; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - add_point( builder, x, y, - (FT_Bool)( count == 3 || count == 0 ) ); - args += 2; - } - - args = stack; - } - break; - - case t2_op_endchar: - FT_TRACE4(( " endchar" )); - - close_contour( builder ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n\n" )); - return T2_Err_Ok; - - case t2_op_abs: - FT_TRACE4(( " abs" )); - - if ( args[0] < 0 ) - args[0] = -args[0]; - args++; - break; - - case t2_op_add: - FT_TRACE4(( " add" )); - - args[0] += args[1]; - args++; - break; - - case t2_op_sub: - FT_TRACE4(( " sub" )); - - args[0] -= args[1]; - args++; - break; - - case t2_op_div: - FT_TRACE4(( " div" )); - - args[0] = FT_DivFix( args[0], args[1] ); - args++; - break; - - case t2_op_neg: - FT_TRACE4(( " neg" )); - - args[0] = -args[0]; - args++; - break; - - case t2_op_random: - { - FT_Fixed rand; - - - FT_TRACE4(( " rand" )); - - rand = seed; - if ( rand >= 0x8000 ) - rand++; - - args[0] = rand; - seed = FT_MulFix( seed, 0x10000L - seed ); - if ( seed == 0 ) - seed += 0x2873; - args++; - } - break; - - case t2_op_mul: - FT_TRACE4(( " mul" )); - - args[0] = FT_MulFix( args[0], args[1] ); - args++; - break; - - case t2_op_sqrt: - FT_TRACE4(( " sqrt" )); - - if ( args[0] > 0 ) - { - FT_Int count = 9; - FT_Fixed root = args[0]; - FT_Fixed new_root; - - - for (;;) - { - new_root = ( root + FT_DivFix(args[0],root) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) - break; - root = new_root; - } - args[0] = new_root; - } - else - args[0] = 0; - args++; - break; - - case t2_op_drop: - /* nothing */ - FT_TRACE4(( " drop" )); - - break; - - case t2_op_exch: - { - FT_Fixed tmp; - - - FT_TRACE4(( " exch" )); - - tmp = args[0]; - args[0] = args[1]; - args[1] = tmp; - args += 2; - } - break; - - case t2_op_index: - { - FT_Int index = args[0] >> 16; - - - FT_TRACE4(( " index" )); - - if ( index < 0 ) - index = 0; - else if ( index > num_args - 2 ) - index = num_args - 2; - args[0] = args[-( index + 1 )]; - args++; - } - break; - - case t2_op_roll: - { - FT_Int count = (FT_Int)( args[0] >> 16 ); - FT_Int index = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " roll" )); - - if ( count <= 0 ) - count = 1; - - args -= count; - if ( args < stack ) - goto Stack_Underflow; - - if ( index >= 0 ) - { - while ( index > 0 ) - { - FT_Fixed tmp = args[count - 1]; - FT_Int i; - - - for ( i = count - 2; i >= 0; i-- ) - args[i + 1] = args[i]; - args[0] = tmp; - index--; - } - } - else - { - while ( index < 0 ) - { - FT_Fixed tmp = args[0]; - FT_Int i; - - - for ( i = 0; i < count - 1; i++ ) - args[i] = args[i + 1]; - args[count - 1] = tmp; - index++; - } - } - args += count; - } - break; - - case t2_op_dup: - FT_TRACE4(( " dup" )); - - args[1] = args[0]; - args++; - break; - - case t2_op_put: - { - FT_Fixed val = args[0]; - FT_Int index = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " put" )); - - if ( index >= 0 && index < decoder->len_buildchar ) - decoder->buildchar[index] = val; - } - break; - - case t2_op_get: - { - FT_Int index = (FT_Int)( args[0] >> 16 ); - FT_Fixed val = 0; - - - FT_TRACE4(( " get" )); - - if ( index >= 0 && index < decoder->len_buildchar ) - val = decoder->buildchar[index]; - - args[0] = val; - args++; - } - break; - - case t2_op_store: - FT_TRACE4(( " store ")); - - goto Unimplemented; - - case t2_op_load: - FT_TRACE4(( " load" )); - - goto Unimplemented; - - case t2_op_and: - { - FT_Fixed cond = args[0] && args[1]; - - - FT_TRACE4(( " and" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case t2_op_or: - { - FT_Fixed cond = args[0] || args[1]; - - - FT_TRACE4(( " or" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case t2_op_eq: - { - FT_Fixed cond = !args[0]; - - - FT_TRACE4(( " eq" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case t2_op_ifelse: - { - FT_Fixed cond = (args[2] <= args[3]); - - - FT_TRACE4(( " ifelse" )); - - if ( !cond ) - args[0] = args[1]; - args++; - } - break; - - case t2_op_callsubr: - { - FT_UInt index = (FT_UInt)( ( args[0] >> 16 ) + - decoder->locals_bias ); - - - FT_TRACE4(( " callsubr(%d)", index )); - - if ( index >= decoder->num_locals ) - { - FT_ERROR(( "T2_Parse_CharStrings:" )); - FT_ERROR(( " invalid local subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T2_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "T2_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->locals[index]; - zone->limit = decoder->locals[index+1]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "T2_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case t2_op_callgsubr: - { - FT_UInt index = (FT_UInt)( ( args[0] >> 16 ) + - decoder->globals_bias ); - - - FT_TRACE4(( " callgsubr(%d)", index )); - - if ( index >= decoder->num_globals ) - { - FT_ERROR(( "T2_Parse_CharStrings:" )); - FT_ERROR(( " invalid global subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T2_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "T2_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->globals[index]; - zone->limit = decoder->globals[index+1]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "T2_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case t2_op_return: - FT_TRACE4(( " return" )); - - if ( decoder->zone <= decoder->zones ) - { - FT_ERROR(( "T2_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - decoder->zone--; - zone = decoder->zone; - ip = zone->cursor; - limit = zone->limit; - break; - - default: - Unimplemented: - FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); - - if ( ip[-1] == 12 ) - FT_ERROR(( " %d", ip[0] )); - FT_ERROR(( "\n" )); - - return T2_Err_Unimplemented_Feature; - } - - decoder->top = args; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - return error; - - Syntax_Error: - FT_TRACE4(( "T2_Parse_CharStrings: syntax error!" )); - return T2_Err_Invalid_File_Format; - - Stack_Underflow: - FT_TRACE4(( "T2_Parse_CharStrings: stack underflow!" )); - return T2_Err_Too_Few_Arguments; - - Stack_Overflow: - FT_TRACE4(( "T2_Parse_CharStrings: stack overflow!" )); - return T2_Err_Stack_Overflow; - - Memory_Error: - return builder->error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#if 0 /* unused until we support pure CFF fonts */ - - - LOCAL_FUNC - FT_Error T2_Compute_Max_Advance( TT_Face face, - FT_Int* max_advance ) - { - FT_Error error = 0; - T2_Decoder decoder; - FT_Int glyph_index; - CFF_Font* cff = (CFF_Font*)face->other; - - - *max_advance = 0; - - /* Initialize load decoder */ - T2_Init_Decoder( &decoder, face, 0, 0 ); - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - /* For each glyph, parse the glyph charstring and extract */ - /* the advance width. */ - for ( glyph_index = 0; glyph_index < face->root.num_glyphs; - glyph_index++ ) - { - FT_Byte* charstring; - FT_ULong charstring_len; - - - /* now get load the unscaled outline */ - error = T2_Access_Element( &cff->charstrings_index, glyph_index, - &charstring, &charstring_len ); - if ( !error ) - { - T2_Prepare_Decoder( &decoder, glyph_index ); - error = T2_Parse_CharStrings( &decoder, charstring, charstring_len ); - - T2_Forget_Element( &cff->charstrings_index, &charstring ); - } - - /* ignore the error if one has occurred -- skip to next glyph */ - error = 0; - } - - *max_advance = decoder.builder.advance.x; - - return T2_Err_Ok; - } - - -#endif /* 0 */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error T2_Load_Glyph( T2_GlyphSlot glyph, - T2_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - T2_Decoder decoder; - TT_Face face = (TT_Face)glyph->root.face; - FT_Bool hinting; - CFF_Font* cff = (CFF_Font*)face->extra.data; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = 0x10000L; - glyph->y_scale = 0x10000L; - if ( size ) - { - glyph->x_scale = size->metrics.x_scale; - glyph->y_scale = size->metrics.y_scale; - } - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0; - - glyph->root.format = ft_glyph_format_outline; /* by default */ - - { - FT_Byte* charstring; - FT_ULong charstring_len; - - - T2_Init_Decoder( &decoder, face, size, glyph ); - - decoder.builder.no_recurse = - (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); - - /* now load the unscaled outline */ - error = T2_Access_Element( &cff->charstrings_index, glyph_index, - &charstring, &charstring_len ); - if ( !error ) - { - T2_Prepare_Decoder( &decoder, glyph_index ); - error = T2_Parse_CharStrings( &decoder, charstring, charstring_len ); - - T2_Forget_Element( &cff->charstrings_index, &charstring ); - } - - /* save new glyph tables */ - T2_Done_Builder( &decoder.builder ); - } - - /* Now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax. */ - if ( !error ) - { - /* for composite glyphs, return only left side bearing and */ - /* advance width */ - if ( glyph->root.format == ft_glyph_format_composite ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.glyph_width; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.glyph_width; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags = 0; - if ( size && size->metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - - glyph->root.outline.flags |= ft_outline_reverse_fill; - - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = &glyph->root.outline; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - } - -#if 0 - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, cff->font_matrix ); -#endif - - /* compute the other metrics */ - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - } - } - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2gload.h b/subsys/win32k/freetype/src/cff/t2gload.h deleted file mode 100644 index 7c0406b..0000000 --- a/subsys/win32k/freetype/src/cff/t2gload.h +++ /dev/null @@ -1,213 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2gload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2000 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 T2GLOAD_H -#define T2GLOAD_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t2objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - -#define T2_MAX_OPERANDS 48 -#define T2_MAX_SUBRS_CALLS 32 - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* max_points :: maximum points in builder outline */ - /* */ - /* max_contours :: Maximal number of contours in builder outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* error :: An error code that is only used to report memory */ - /* allocation problems. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - typedef struct T2_Builder_ - { - FT_Memory memory; - TT_Face face; - T2_GlyphSlot glyph; - FT_GlyphLoader* loader; - FT_Outline* base; - FT_Outline* current; - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; - - } T2_Builder; - - - /* execution context charstring zone */ - - typedef struct T2_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } T2_Decoder_Zone; - - - typedef struct T2_Decoder_ - { - T2_Builder builder; - CFF_Font* cff; - - FT_Fixed stack[T2_MAX_OPERANDS + 1]; - FT_Fixed* top; - - T2_Decoder_Zone zones[T2_MAX_SUBRS_CALLS + 1]; - T2_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - FT_Pos glyph_width; - FT_Pos nominal_width; - - FT_Bool read_width; - FT_Int num_hints; - FT_Fixed* buildchar; - FT_Int len_buildchar; - - FT_UInt num_locals; - FT_UInt num_globals; - - FT_Int locals_bias; - FT_Int globals_bias; - - FT_Byte** locals; - FT_Byte** globals; - - } T2_Decoder; - - - LOCAL_DEF - void T2_Init_Decoder( T2_Decoder* decoder, - TT_Face face, - T2_Size size, - T2_GlyphSlot slot ); - - LOCAL_DEF - void T2_Prepare_Decoder( T2_Decoder* decoder, - FT_UInt glyph_index ); - -#if 0 /* unused until we support pure CFF fonts */ - - /* Compute the maximum advance width of a font through quick parsing */ - LOCAL_DEF - FT_Error T2_Compute_Max_Advance( TT_Face face, - FT_Int* max_advance ); - -#endif /* 0 */ - - LOCAL_DEF - FT_Error T2_Parse_CharStrings( T2_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ); - - LOCAL_DEF - FT_Error T2_Load_Glyph( T2_GlyphSlot glyph, - T2_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T2GLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2load.c b/subsys/win32k/freetype/src/cff/t2load.c deleted file mode 100644 index fa19ecd..0000000 --- a/subsys/win32k/freetype/src/cff/t2load.c +++ /dev/null @@ -1,757 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2load.c */ -/* */ -/* TrueType glyph data/program tables loader (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t2load.h" -#include "t2parse.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t2load - - - /* read a CFF offset from memory */ - static - FT_ULong t2_get_offset( FT_Byte* p, - FT_Byte off_size ) - { - FT_ULong result; - - - for ( result = 0; off_size > 0; off_size-- ) - { - result <<= 8; - result |= *p++; - } - - return result; - } - - - static - FT_Error t2_new_cff_index( CFF_Index* index, - FT_Stream stream, - FT_Bool load ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_UShort count; - - - MEM_Set( index, 0, sizeof ( *index ) ); - - index->stream = stream; - if ( !READ_UShort( count ) && - count > 0 ) - { - FT_Byte* p; - FT_Byte offsize; - FT_ULong data_size; - FT_ULong* poff; - - - /* there is at least one element; read the offset size, */ - /* then access the offset table to compute the index's total size */ - if ( READ_Byte( offsize ) ) - goto Exit; - - index->stream = stream; - index->count = count; - index->off_size = offsize; - data_size = (FT_ULong)( count + 1 ) * offsize; - - if ( ALLOC_ARRAY( index->offsets, count + 1, FT_ULong ) || - ACCESS_Frame( data_size ) ) - goto Exit; - - poff = index->offsets; - p = (FT_Byte*)stream->cursor; - - for ( ; (FT_Short)count >= 0; count-- ) - { - poff[0] = t2_get_offset( p, offsize ); - poff++; - p += offsize; - } - - FORGET_Frame(); - - index->data_offset = FILE_Pos(); - data_size = poff[-1] - 1; - - if ( load ) - { - /* load the data */ - if ( EXTRACT_Frame( data_size, index->bytes ) ) - goto Exit; - } - else - { - /* skip the data */ - (void)FILE_Skip( data_size ); - } - } - - Exit: - if ( error ) - FREE( index->offsets ); - - return error; - } - - - static - void t2_done_cff_index( CFF_Index* index ) - { - if ( index->stream ) - { - FT_Stream stream = index->stream; - FT_Memory memory = stream->memory; - - - if ( index->bytes ) - RELEASE_Frame( index->bytes ); - - FREE( index->offsets ); - MEM_Set( index, 0, sizeof ( *index ) ); - } - } - - - static - FT_Error t2_explicit_cff_index( CFF_Index* index, - FT_Byte*** table ) - { - FT_Error error = 0; - FT_Memory memory = index->stream->memory; - FT_UInt n, offset, old_offset; - FT_Byte** t; - - - *table = 0; - - if ( index->count > 0 && !ALLOC_ARRAY( t, index->count + 1, FT_Byte* ) ) - { - old_offset = 1; - for ( n = 0; n <= index->count; n++ ) - { - offset = index->offsets[n]; - if ( !offset ) - offset = old_offset; - - t[n] = index->bytes + offset - 1; - - old_offset = offset; - } - *table = t; - } - - return error; - } - - - LOCAL_FUNC - FT_Error T2_Access_Element( CFF_Index* index, - FT_UInt element, - FT_Byte** pbytes, - FT_ULong* pbyte_len ) - { - FT_Error error = 0; - - - if ( index && index->count > element ) - { - /* compute start and end offsets */ - FT_ULong off1, off2; - - - off1 = index->offsets[element]; - if ( off1 ) - { - do - { - element++; - off2 = index->offsets[element]; - - } while ( off2 == 0 && element < index->count ); - - if ( !off2 ) - off1 = 0; - } - - /* access element */ - if ( off1 ) - { - *pbyte_len = off2 - off1; - - if ( index->bytes ) - { - /* this index was completely loaded in memory, that's easy */ - *pbytes = index->bytes + off1 - 1; - } - else - { - /* this index is still on disk/file, access it through a frame */ - FT_Stream stream = index->stream; - - - if ( FILE_Seek( index->data_offset + off1 - 1 ) || - EXTRACT_Frame( off2 - off1, *pbytes ) ) - goto Exit; - } - } - else - { - /* empty index element */ - *pbytes = 0; - *pbyte_len = 0; - } - } - else - error = T2_Err_Invalid_Argument; - - Exit: - return error; - } - - - LOCAL_FUNC - void T2_Forget_Element( CFF_Index* index, - FT_Byte** pbytes ) - { - if ( index->bytes == 0 ) - { - FT_Stream stream = index->stream; - - - RELEASE_Frame( *pbytes ); - } - } - - - LOCAL_FUNC - FT_String* T2_Get_Name( CFF_Index* index, - FT_UInt element ) - { - FT_Memory memory = index->stream->memory; - FT_Byte* bytes; - FT_ULong byte_len; - FT_Error error; - FT_String* name = 0; - - - error = T2_Access_Element( index, element, &bytes, &byte_len ); - if ( error ) - goto Exit; - - if ( !ALLOC( name, byte_len + 1 ) ) - { - MEM_Copy( name, bytes, byte_len ); - name[byte_len] = 0; - } - T2_Forget_Element( index, &bytes ); - - Exit: - return name; - } - - - LOCAL_FUNC - FT_String* T2_Get_String( CFF_Index* index, - FT_UInt sid, - PSNames_Interface* interface ) - { - /* if it is not a standard string, return it */ - if ( sid > 390 ) - return T2_Get_Name( index, sid - 390 ); - - /* that's a standard string, fetch a copy from the PSName module */ - { - FT_String* name = 0; - const char* adobe_name = interface->adobe_std_strings( sid ); - FT_UInt len; - - - if ( adobe_name ) - { - FT_Memory memory = index->stream->memory; - FT_Error error; - - - len = (FT_UInt)strlen( adobe_name ); - if ( !ALLOC( name, len + 1 ) ) - { - MEM_Copy( name, adobe_name, len ); - name[len] = 0; - } - } - - return name; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** FD Select table support ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - - - static - void CFF_Done_FD_Select( CFF_FD_Select* select, - FT_Stream stream ) - { - if ( select->data ) - RELEASE_Frame( select->data ); - - select->data_size = 0; - select->format = 0; - select->range_count = 0; - } - - - static - FT_Error CFF_Load_FD_Select( CFF_FD_Select* select, - FT_UInt num_glyphs, - FT_Stream stream, - FT_ULong offset ) - { - FT_Error error; - FT_Byte format; - FT_UInt num_ranges; - - - /* read format */ - if ( FILE_Seek( offset ) || READ_Byte( format ) ) - goto Exit; - - select->format = format; - select->cache_count = 0; /* clear cache */ - - switch ( format ) - { - case 0: /* format 0, that's simple */ - select->data_size = num_glyphs; - goto Load_Data; - - case 3: /* format 3, a tad more complex */ - if ( READ_UShort( num_ranges ) ) - goto Exit; - - select->data_size = num_ranges * 3 + 2; - - Load_Data: - if ( EXTRACT_Frame( select->data_size, select->data ) ) - goto Exit; - break; - - default: /* hmm... that's wrong */ - error = T2_Err_Invalid_File_Format; - } - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Byte CFF_Get_FD( CFF_FD_Select* select, - FT_UInt glyph_index ) - { - FT_Byte fd = 0; - - - switch ( select->format ) - { - case 0: - fd = select->data[glyph_index]; - break; - - case 3: - /* first, compare to cache */ - if ( (FT_UInt)(glyph_index-select->cache_first) < select->cache_count ) - { - fd = select->cache_fd; - break; - } - - /* then, lookup the ranges array */ - { - FT_Byte* p = select->data; - FT_Byte* p_limit = p + select->data_size; - FT_Byte fd2; - FT_UInt first, limit; - - - first = NEXT_UShort( p ); - do - { - if ( glyph_index < first ) - break; - - fd2 = *p++; - limit = NEXT_UShort( p ); - - if ( glyph_index < limit ) - { - fd = fd2; - - /* update cache */ - select->cache_first = first; - select->cache_count = limit-first; - select->cache_fd = fd2; - break; - } - first = limit; - - } while ( p < p_limit ); - } - break; - - default: - ; - } - - return fd; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*** ***/ - /*** CFF font support ***/ - /*** ***/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error CFF_Load_SubFont( CFF_SubFont* font, - CFF_Index* index, - FT_UInt font_index, - FT_Stream stream, - FT_ULong base_offset ) - { - FT_Error error; - T2_Parser parser; - FT_Byte* dict; - FT_ULong dict_len; - CFF_Font_Dict* top = &font->font_dict; - CFF_Private* priv = &font->private_dict; - - - T2_Parser_Init( &parser, T2CODE_TOPDICT, &font->font_dict ); - - /* set defaults */ - MEM_Set( top, 0, sizeof ( *top ) ); - - top->underline_position = -100; - top->underline_thickness = 50; - top->charstring_type = 2; - top->font_matrix.xx = 0x10000L; - top->font_matrix.yy = 0x10000L; - top->cid_count = 8720; - - error = T2_Access_Element( index, font_index, &dict, &dict_len ) || - T2_Parser_Run( &parser, dict, dict + dict_len ); - - T2_Forget_Element( index, &dict ); - - if ( error ) - goto Exit; - - /* if it is a CID font, we stop there */ - if ( top->cid_registry ) - goto Exit; - - /* parse the private dictionary, if any */ - if ( top->private_offset && top->private_size ) - { - /* set defaults */ - MEM_Set( priv, 0, sizeof ( *priv ) ); - - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)0.06 * 0x10000L; - priv->blue_scale = (FT_Fixed)0.039625 * 0x10000L; - - T2_Parser_Init( &parser, T2CODE_PRIVATE, priv ); - - if ( FILE_Seek( base_offset + font->font_dict.private_offset ) || - ACCESS_Frame( font->font_dict.private_size ) ) - goto Exit; - - error = T2_Parser_Run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FORGET_Frame(); - if ( error ) - goto Exit; - } - - /* read the local subrs, if any */ - if ( priv->local_subrs_offset ) - { - if ( FILE_Seek( base_offset + top->private_offset + - priv->local_subrs_offset ) ) - goto Exit; - - error = t2_new_cff_index( &font->local_subrs_index, stream, 1 ); - if ( error ) - goto Exit; - - font->num_local_subrs = font->local_subrs_index.count; - error = t2_explicit_cff_index( &font->local_subrs_index, - &font->local_subrs ); - } - - Exit: - return error; - } - - - static - void CFF_Done_SubFont( FT_Memory memory, - CFF_SubFont* subfont ) - { - if ( subfont ) - { - t2_done_cff_index( &subfont->local_subrs_index ); - FREE( subfont->local_subrs ); - } - } - - - LOCAL_FUNC - FT_Error T2_Load_CFF_Font( FT_Stream stream, - FT_Int face_index, - CFF_Font* font ) - { - static const FT_Frame_Field cff_header_fields[] = - { - FT_FRAME_START( 4 ), - FT_FRAME_BYTE( CFF_Font, version_major ), - FT_FRAME_BYTE( CFF_Font, version_minor ), - FT_FRAME_BYTE( CFF_Font, header_size ), - FT_FRAME_BYTE( CFF_Font, absolute_offsize ), - FT_FRAME_END - }; - - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong base_offset; - CFF_Font_Dict* dict; - - - MEM_Set( font, 0, sizeof ( *font ) ); - font->stream = stream; - font->memory = memory; - dict = &font->top_font.font_dict; - base_offset = FILE_Pos(); - - /* read CFF font header */ - if ( READ_Fields( cff_header_fields, font ) ) - goto Exit; - - /* check format */ - if ( font->version_major != 1 || - font->header_size < 4 || - font->absolute_offsize > 4 ) - { - FT_TRACE2(( "[not a CFF font header!]\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - /* skip the rest of the header */ - (void)FILE_Skip( font->header_size - 4 ); - - /* read the name, top dict, string and global subrs index */ - error = t2_new_cff_index( &font->name_index, stream, 0 ) || - t2_new_cff_index( &font->font_dict_index, stream, 0 ) || - t2_new_cff_index( &font->string_index, stream, 0 ) || - t2_new_cff_index( &font->global_subrs_index, stream, 1 ); - if ( error ) - goto Exit; - - /* well, we don't really forget the `disabled' fonts... */ - font->num_faces = font->name_index.count; - if ( face_index >= (FT_Int)font->num_faces ) - { - FT_ERROR(( "T2_Load_CFF_Font: incorrect face index = %d\n", - face_index )); - error = T2_Err_Invalid_Argument; - } - - /* in case of a font format check, simply exit now */ - if ( face_index < 0 ) - goto Exit; - - /* now, parse the top-level font dictionary */ - error = CFF_Load_SubFont( &font->top_font, - &font->font_dict_index, - face_index, - stream, - base_offset ); - if ( error ) - goto Exit; - - /* now, check for a CID font */ - if ( dict->cid_registry ) - { - CFF_Index fd_index; - CFF_SubFont* sub; - FT_UInt index; - - - /* this is a CID-keyed font, we must now allocate a table of */ - /* sub-fonts, then load each of them separately */ - if ( FILE_Seek( base_offset + dict->cid_fd_array_offset ) ) - goto Exit; - - error = t2_new_cff_index( &fd_index, stream, 0 ); - if ( error ) - goto Exit; - - if ( fd_index.count > CFF_MAX_CID_FONTS ) - { - FT_ERROR(( "T2_Load_CFF_Font: FD array too large in CID font\n" )); - goto Fail_CID; - } - - /* allocate & read each font dict independently */ - font->num_subfonts = fd_index.count; - if ( ALLOC_ARRAY( sub, fd_index.count, CFF_SubFont ) ) - goto Fail_CID; - - /* setup pointer table */ - for ( index = 0; index < fd_index.count; index++ ) - font->subfonts[index] = sub + index; - - /* now load each sub font independently */ - for ( index = 0; index < fd_index.count; index++ ) - { - sub = font->subfonts[index]; - error = CFF_Load_SubFont( sub, &fd_index, index, - stream, base_offset ); - if ( error ) - goto Fail_CID; - } - - /* now load the FD Select array */ - error = CFF_Load_FD_Select( &font->fd_select, - dict->cid_count, - stream, - base_offset + dict->cid_fd_select_offset ); - - Fail_CID: - t2_done_cff_index( &fd_index ); - - if ( error ) - goto Exit; - } - else - font->num_subfonts = 0; - - /* read the charstrings index now */ - if ( dict->charstrings_offset == 0 ) - { - FT_ERROR(( "T2_Load_CFF_Font: no charstrings offset!\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - if ( FILE_Seek( base_offset + dict->charstrings_offset ) ) - goto Exit; - - error = t2_new_cff_index( &font->charstrings_index, stream, 0 ); - if ( error ) - goto Exit; - - /* explicit the global subrs */ - font->num_global_subrs = font->global_subrs_index.count; - font->num_glyphs = font->charstrings_index.count; - - error = t2_explicit_cff_index( &font->global_subrs_index, - &font->global_subrs ) ; - - if ( error ) - goto Exit; - - /* get the font name */ - font->font_name = T2_Get_Name( &font->name_index, face_index ); - - Exit: - return error; - } - - - LOCAL_FUNC - void T2_Done_CFF_Font( CFF_Font* font ) - { - FT_Memory memory = font->memory; - FT_UInt index; - - - t2_done_cff_index( &font->global_subrs_index ); - t2_done_cff_index( &font->string_index ); - t2_done_cff_index( &font->font_dict_index ); - t2_done_cff_index( &font->name_index ); - t2_done_cff_index( &font->charstrings_index ); - - /* release font dictionaries */ - for ( index = 0; index < font->num_subfonts; index++ ) - CFF_Done_SubFont( memory, font->subfonts[index] ); - - CFF_Done_SubFont( memory, &font->top_font ); - - CFF_Done_FD_Select( &font->fd_select, font->stream ); - - FREE( font->global_subrs ); - FREE( font->font_name ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2load.h b/subsys/win32k/freetype/src/cff/t2load.h deleted file mode 100644 index 7ebc76d..0000000 --- a/subsys/win32k/freetype/src/cff/t2load.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2load.h */ -/* */ -/* OpenType glyph data/program tables loader (specification). */ -/* */ -/* Copyright 1996-2000 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 T2LOAD_H -#define T2LOAD_H - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - LOCAL_DEF - FT_String* T2_Get_Name( CFF_Index* index, - FT_UInt element ); - - LOCAL_DEF - FT_String* T2_Get_String( CFF_Index* index, - FT_UInt sid, - PSNames_Interface* interface ); - - LOCAL_DEF - FT_Error T2_Access_Element( CFF_Index* index, - FT_UInt element, - FT_Byte** pbytes, - FT_ULong* pbyte_len ); - - LOCAL_DEF - void T2_Forget_Element( CFF_Index* index, - FT_Byte** pbytes ); - - LOCAL_DEF - FT_Error T2_Load_CFF_Font( FT_Stream stream, - FT_Int face_index, - CFF_Font* font ); - - LOCAL_DEF - void T2_Done_CFF_Font( CFF_Font* font ); - - LOCAL_DEF - FT_Byte CFF_Get_FD( CFF_FD_Select* select, - FT_UInt glyph_index ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T2LOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2objs.c b/subsys/win32k/freetype/src/cff/t2objs.c deleted file mode 100644 index 1d87f0c..0000000 --- a/subsys/win32k/freetype/src/cff/t2objs.c +++ /dev/null @@ -1,600 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2objs.c */ -/* */ -/* OpenType objects manager (body). */ -/* */ -/* Copyright 1996-2000 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 -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t2objs.h" -#include "t2load.h" - -#else - -#include -#include - -#endif - - -#include - -#include /* for strlen() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t2objs - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - static - FT_String* T2_StrCopy( FT_Memory memory, - const FT_String* source ) - { - FT_Error error; - FT_String* result = 0; - FT_Int len = (FT_Int)strlen( source ); - - - if ( !ALLOC( result, len + 1 ) ) - { - MEM_Copy( result, source, len ); - result[len] = 0; - } - return result; - } - - -#if 0 - - /* this function is used to build a Unicode charmap from the glyph names */ - /* in a file */ - static - FT_Error CFF_Build_Unicode_Charmap( T2_Face face, - FT_ULong base_offset, - PSNames_Interface* psnames ) - { - CFF_Font* font = (CFF_Font*)face->extra.data; - FT_Memory memory = FT_FACE_MEMORY(face); - FT_UInt n, num_glyphs = face->root.num_glyphs; - const char** glyph_names; - FT_Error error; - CFF_Font_Dict* dict = &font->top_font.font_dict; - FT_ULong charset_offset; - FT_Byte format; - FT_Stream stream = face->root.stream; - - - charset_offset = dict->charset_offset; - if ( !charset_offset ) - { - FT_ERROR(( "CFF.Build_Unicode_Charmap: charset table is missing\n" )); - error = T2_Err_Invalid_File_Format; - goto Exit; - } - - /* allocate the charmap */ - if ( ALLOC( face->charmap, ... - - /* seek to charset table and allocate glyph names table */ - if ( FILE_Seek( base_offset + charset_offset ) || - ALLOC_ARRAY( glyph_names, num_glyphs, const char* ) ) - goto Exit; - - /* now, read each glyph name and store it in the glyph name table */ - if ( READ_Byte( format ) ) - goto Fail; - - switch ( format ) - { - case 0: /* format 0 - one SID per glyph */ - { - const char** gname = glyph_names; - const char** limit = gname + num_glyphs; - - if ( ACCESS_Frame( num_glyphs*2 ) ) - goto Fail; - - for ( ; gname < limit; gname++ ) - gname[0] = T2_Get_String( &font->string_index, - GET_UShort(), - psnames ); - FORGET_Frame(); - break; - } - - case 1: /* format 1 - sequential ranges */ - case 2: /* format 2 - sequential ranges with 16-bit counts */ - { - const char** gname = glyph_names; - const char** limit = gname + num_glyphs; - FT_UInt len = 3; - - if (format == 2) - len++; - - while (gname < limit) - { - FT_UInt first; - FT_UInt count; - - if ( ACCESS_Frame( len ) ) - goto Fail; - - first = GET_UShort(); - if (format == 3) - count = GET_UShort(); - else - count = GET_Byte(); - - FORGET_Frame(); - - for ( ; count > 0; count-- ) - { - gname[0] = T2_Get_String( &font->string_index, - first, - psnames ); - gname++; - first++; - } - } - break; - } - - default: /* unknown charset format! */ - FT_ERROR(( "CFF: unknown charset format!\n" )); - error = T2_Err_Invalid_File_Format; - goto Fail; - } - - /* all right, the glyph names were loaded, we now need to create */ - /* the corresponding unicode charmap.. */ - - Fail: - for ( n = 0; n < num_glyphs; n++ ) - FREE( glyph_names[n] ); - - FREE( glyph_names ); - - Exit: - return error; - } - -#endif /* 0 */ - - - static - FT_Encoding find_encoding( int platform_id, - int encoding_id ) - { - typedef struct TEncoding - { - int platform_id; - int encoding_id; - FT_Encoding encoding; - - } TEncoding; - - static - const TEncoding tt_encodings[] = - { - { TT_PLATFORM_ISO, -1, ft_encoding_unicode }, - - { TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode }, - - { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman }, - - { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, ft_encoding_gb2312 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, ft_encoding_wansung }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, ft_encoding_johab } - }; - - const TEncoding *cur, *limit; - - - cur = tt_encodings; - limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); - - for ( ; cur < limit; cur++ ) - { - if ( cur->platform_id == platform_id ) - { - if ( cur->encoding_id == encoding_id || - cur->encoding_id == -1 ) - return cur->encoding; - } - } - - return ft_encoding_none; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_Face */ - /* */ - /* */ - /* Initializes a given OpenType face object. */ - /* */ - /* */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The newly built face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error T2_Init_Face( FT_Stream stream, - T2_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - SFNT_Interface* sfnt; - PSNames_Interface* psnames; - FT_Bool pure_cff = 1; - FT_Bool sfnt_format = 0; - - - sfnt = (SFNT_Interface*)FT_Get_Module_Interface( - face->root.driver->root.library, "sfnt" ); - if ( !sfnt ) - goto Bad_Format; - - psnames = (PSNames_Interface*)FT_Get_Module_Interface( - face->root.driver->root.library, "psnames" ); - - /* create input stream from resource */ - if ( FILE_Seek( 0 ) ) - goto Exit; - - /* check that we have a valid OpenType file */ - error = sfnt->init_face( stream, face, face_index, num_params, params ); - if ( !error ) - { - if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ - { - FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); - goto Bad_Format; - } - - /* If we are performing a simple font format check, exit immediately */ - if ( face_index < 0 ) - return T2_Err_Ok; - - sfnt_format = 1; - - /* now, the font can be either an OpenType/CFF font, or a SVG CEF */ - /* font in the later case; it doesn't have a `head' table */ - error = face->goto_table( face, TTAG_head, stream, 0 ); - if ( !error ) - { - pure_cff = 0; - - /* Load font directory */ - error = sfnt->load_face( stream, face, - face_index, num_params, params ); - if ( error ) - goto Exit; - } - else - { - /* load the `cmap' table by hand */ - error = sfnt->load_charmaps( face, stream ); - if ( error ) - goto Exit; - - /* XXX: for now, we don't load the GPOS table, as OpenType Layout */ - /* support will be added later to FreeType 2 as a separate module */ - } - - /* now, load the CFF part of the file */ - error = face->goto_table( face, TTAG_CFF, stream, 0 ); - if ( error ) - goto Exit; - } - else - { - /* rewind to start of file; we are going to load a pure-CFF font */ - (void)FILE_Seek( 0 ); - error = FT_Err_Ok; - } - - /* now load and parse the CFF table in the file */ - { - CFF_Font* cff; - FT_Memory memory = face->root.memory; - FT_Face root; - FT_UInt flags; - FT_ULong base_offset; - - - if ( ALLOC( cff, sizeof ( *cff ) ) ) - goto Exit; - - base_offset = FILE_Pos(); - - face->extra.data = cff; - error = T2_Load_CFF_Font( stream, face_index, cff ); - if ( error ) - goto Exit; - - /* Complement the root flags with some interesting information. */ - /* Note that this is only necessary for pure CFF and CEF fonts */ - - root = &face->root; - if ( pure_cff ) - { - CFF_Font_Dict* dict = &cff->top_font.font_dict; - - - /* we need the `PSNames' module for pure-CFF and CEF formats */ - if ( !psnames ) - { - FT_ERROR(( "T2_Init_Face:" )); - FT_ERROR(( " cannot open CFF & CEF fonts\n" )); - FT_ERROR(( " " )); - FT_ERROR(( " without the `PSNames' module\n" )); - goto Bad_Format; - } - - /* compute number of glyphs */ - if ( dict->cid_registry ) - root->num_glyphs = dict->cid_count; - else - root->num_glyphs = cff->charstrings_index.count; - - /* set global bbox, as well as EM size */ - root->units_per_EM = (FT_UInt)FT_DivFix( 1000L << 16, - dict->font_matrix.yy ) >> 16; - root->bbox = dict->font_bbox; - root->ascender = (FT_Short)root->bbox.yMax; - root->descender = (FT_Short)root->bbox.yMin; - - /* retrieve font family & style name */ - root->family_name = T2_Get_Name( &cff->name_index, face_index ); - if ( dict->cid_registry ) - { - root->style_name = T2_StrCopy( memory, "Regular" ); /* XXXX */ - } - else - { - root->style_name = T2_Get_String( &cff->string_index, - dict->weight, - psnames ); - } - - /*******************************************************************/ - /* */ - /* Compute face flags. */ - /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ - - if ( sfnt_format ) - flags |= FT_FACE_FLAG_SFNT; - - /* fixed width font? */ - if ( dict->is_fixed_pitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; - -/* XXXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ -#if 0 - /* kerning available? */ - if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; -#endif - - root->face_flags = flags; - - /*******************************************************************/ - /* */ - /* Compute style flags. */ - /* */ - flags = 0; - - if ( dict->italic_angle ) - flags |= FT_STYLE_FLAG_ITALIC; - - /* XXX: may not be correct */ - if ( cff->top_font.private_dict.force_bold ) - flags |= FT_STYLE_FLAG_BOLD; - - root->style_flags = flags; - - /* set the charmaps if any */ - if ( sfnt_format ) - { - /*****************************************************************/ - /* */ - /* Polish the charmaps. */ - /* */ - /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. */ - /* */ - TT_CharMap charmap; - FT_Int n; - - - charmap = face->charmaps; - root->num_charmaps = face->num_charmaps; - - /* allocate table of pointers */ - if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) ) - goto Exit; - - for ( n = 0; n < root->num_charmaps; n++, charmap++ ) - { - FT_Int platform = charmap->cmap.platformID; - FT_Int encoding = charmap->cmap.platformEncodingID; - - - charmap->root.face = (FT_Face)face; - charmap->root.platform_id = platform; - charmap->root.encoding_id = encoding; - charmap->root.encoding = find_encoding( platform, encoding ); - - /* now, set root->charmap with a unicode charmap */ - /* wherever available */ - if ( !root->charmap && - charmap->root.encoding == ft_encoding_unicode ) - root->charmap = (FT_CharMap)charmap; - - root->charmaps[n] = (FT_CharMap)charmap; - } - } - } - } - - Exit: - return error; - - Bad_Format: - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Done_Face */ - /* */ - /* */ - /* Finalizes a given face object. */ - /* */ - /* */ - /* face :: A pointer to the face object to destroy. */ - /* */ - LOCAL_DEF - void T2_Done_Face( T2_Face face ) - { - FT_Memory memory = face->root.memory; - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - if ( sfnt ) - sfnt->done_face( face ); - - { - CFF_Font* cff = (CFF_Font*)face->extra.data; - - - if ( cff ) - { - T2_Done_CFF_Font( cff ); - FREE( face->extra.data ); - } - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Init_Driver */ - /* */ - /* */ - /* Initializes a given OpenType driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T2_Init_Driver( T2_Driver driver ) - { - /* init extension registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - - return TT_Init_Extensions( driver ); - -#else - - FT_UNUSED( driver ); - - return T2_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Done_Driver */ - /* */ - /* */ - /* Finalizes a given OpenType driver. */ - /* */ - /* */ - /* driver :: A handle to the target OpenType driver. */ - /* */ - LOCAL_FUNC - void T2_Done_Driver( T2_Driver driver ) - { - /* destroy extensions registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - - TT_Done_Extensions( driver ); - -#else - - FT_UNUSED( driver ); - -#endif - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2objs.h b/subsys/win32k/freetype/src/cff/t2objs.h deleted file mode 100644 index 2602862..0000000 --- a/subsys/win32k/freetype/src/cff/t2objs.h +++ /dev/null @@ -1,148 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2objs.h */ -/* */ -/* OpenType objects manager (specification). */ -/* */ -/* Copyright 1996-2000 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 T2OBJS_H -#define T2OBJS_H - - -#include -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Driver */ - /* */ - /* */ - /* A handle to an OpenType driver object. */ - /* */ - typedef struct T2_DriverRec_* T2_Driver; - - typedef TT_Face T2_Face; - - - /*************************************************************************/ - /* */ - /* */ - /* T2_Size */ - /* */ - /* */ - /* A handle to an OpenType size object. */ - /* */ - typedef FT_Size T2_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* T2_GlyphSlot */ - /* */ - /* */ - /* A handle to an OpenType glyph slot object. */ - /* */ - typedef struct T2_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } T2_GlyphSlotRec, *T2_GlyphSlot; - - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct T2_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } T2_Transform; - - - /* this is only used in the case of a pure CFF font with no charmap */ - typedef struct T2_CharMapRec_ - { - TT_CharMapRec root; - PS_Unicodes unicodes; - - } T2_CharMapRec, *T2_CharMap; - - - /***********************************************************************/ - /* */ - /* TrueType driver class. */ - /* */ - typedef struct T2_DriverRec_ - { - FT_DriverRec root; - - void* extension_component; - - } T2_DriverRec; - - - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ - LOCAL_DEF - FT_Error T2_Init_Face( FT_Stream stream, - T2_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void T2_Done_Face( T2_Face face ); - - - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ - LOCAL_DEF - FT_Error T2_Init_Driver( T2_Driver driver ); - - LOCAL_DEF - void T2_Done_Driver( T2_Driver driver ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T2OBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2parse.c b/subsys/win32k/freetype/src/cff/t2parse.c deleted file mode 100644 index e94a6dd..0000000 --- a/subsys/win32k/freetype/src/cff/t2parse.c +++ /dev/null @@ -1,641 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2parse.c */ -/* */ -/* OpenType parser (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t2parse.h" - -#else - -#include - -#endif - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t2parse - - -#define T2_Err_Stack_Underflow FT_Err_Invalid_Argument -#define T2_Err_Syntax_Error FT_Err_Invalid_Argument - - - enum - { - t2_kind_none = 0, - t2_kind_num, - t2_kind_fixed, - t2_kind_string, - t2_kind_bool, - t2_kind_delta, - t2_kind_callback, - - t2_kind_max /* do not remove */ - }; - - - /* now generate handlers for the most simple fields */ - typedef FT_Error (*T2_Field_Reader)( T2_Parser* parser ); - - typedef struct T2_Field_Handler_ - { - int kind; - int code; - FT_UInt offset; - FT_Byte size; - T2_Field_Reader reader; - FT_UInt array_max; - FT_UInt count_offset; - - } T2_Field_Handler; - - - LOCAL_FUNC - void T2_Parser_Init( T2_Parser* parser, - FT_UInt code, - void* object ) - { - MEM_Set( parser, 0, sizeof ( *parser ) ); - - parser->top = parser->stack; - parser->object_code = code; - parser->object = object; - } - - - /* reads an integer */ - static - FT_Long parse_t2_integer( FT_Byte* start, - FT_Byte* limit ) - { - FT_Byte* p = start; - FT_Int v = *p++; - FT_Long val = 0; - - - if ( v == 28 ) - { - if ( p + 2 > limit ) - goto Bad; - - val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] ); - p += 2; - } - else if ( v == 29 ) - { - if ( p + 4 > limit ) - goto Bad; - - val = ( (FT_Long)p[0] << 24 ) | - ( (FT_Long)p[1] << 16 ) | - ( (FT_Long)p[2] << 8 ) | - p[3]; - p += 4; - } - else if ( v < 247 ) - { - val = v - 139; - } - else if ( v < 251 ) - { - if ( p + 1 > limit ) - goto Bad; - - val = ( v - 247 ) * 256 + p[0] + 108; - p++; - } - else - { - if ( p + 1 > limit ) - goto Bad; - - val = -( v - 251 ) * 256 - p[0] - 108; - p++; - } - - Exit: - return val; - - Bad: - val = 0; - goto Exit; - } - - - /* read a real */ - static - FT_Fixed parse_t2_real( FT_Byte* start, - FT_Byte* limit, - FT_Int power_ten ) - { - FT_Byte* p = start; - FT_Long num, divider, result, exp; - FT_Int sign = 0, exp_sign = 0; - FT_Byte nib; - FT_Byte phase; - - - result = 0; - num = 0; - divider = 1; - - /* first of all, read the integer part */ - phase = 4; - p--; - - for (;;) - { - /* read one nibble at a time */ - if ( phase && ++p >= limit ) - goto Bad; - - nib = ( p[0] >> phase ) & 0xF; - phase = 4 - phase; - - if ( nib == 0xE ) - sign = 1; - else if ( nib > 9 ) - break; - else - result = result * 10 + nib; - } - - /* read decimal part, if any */ - if ( nib == 0xa ) - for (;;) - { - /* read one nibble at a time */ - if ( !phase && ++p >= limit ) - goto Bad; - - phase = 4 - phase; - nib = ( p[0] >> phase ) & 0xF; - - if ( nib >= 10 ) - break; - - if (divider < 10000000L) - { - num = num * 10 + nib; - divider *= 10; - } - } - - /* read exponent, if any */ - if ( nib == 12 ) - { - exp_sign = 1; - nib = 11; - } - - if ( nib == 11 ) - { - exp = 0; - - for (;;) - { - /* read one nibble at a time */ - if ( !phase && ++p >= limit ) - goto Bad; - - phase = 4 - phase; - nib = ( p[0] >> phase ) & 0xF; - - if ( nib >= 10 ) - break; - - exp = exp * 10 + nib; - } - - if ( exp_sign ) - exp = -exp; - - power_ten += exp; - } - - /* raise to power of ten if needed */ - while ( power_ten > 0 ) - { - result = result * 10; - num = num * 10; - - power_ten--; - } - - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - - power_ten++; - } - - if ( num ) - result += FT_DivFix( num, divider ); - - if ( sign ) - result = -result; - - Exit: - return result; - - Bad: - result = 0; - goto Exit; - } - - - /* read a number, either integer or real */ - static - FT_Long t2_parse_num( FT_Byte** d ) - { - return ( **d == 30 ? ( parse_t2_real( d[0], d[1], 0 ) >> 16 ) - : parse_t2_integer( d[0], d[1] ) ); - } - - - /* reads a floating point number, either integer or real */ - static - FT_Fixed t2_parse_fixed( FT_Byte** d ) - { - return ( **d == 30 ? parse_t2_real( d[0], d[1], 0 ) - : parse_t2_integer( d[0], d[1] ) << 16 ); - } - - - static - FT_Error parse_font_matrix( T2_Parser* parser ) - { - CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; - FT_Matrix* matrix = &dict->font_matrix; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = T2_Err_Stack_Underflow; - - if ( parser->top >= parser->stack + 4 ) - { - matrix->xx = t2_parse_fixed( data++ ); - matrix->yx = t2_parse_fixed( data++ ); - matrix->xy = t2_parse_fixed( data++ ); - matrix->yy = t2_parse_fixed( data ); - error = T2_Err_Ok; - } - - return error; - } - - - static - FT_Error parse_font_bbox( T2_Parser* parser ) - { - CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; - FT_BBox* bbox = &dict->font_bbox; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = T2_Err_Stack_Underflow; - - if ( parser->top >= parser->stack + 4 ) - { - bbox->xMin = t2_parse_num( data++ ); - bbox->yMin = t2_parse_num( data++ ); - bbox->xMax = t2_parse_num( data++ ); - bbox->yMax = t2_parse_num( data ); - error = T2_Err_Ok; - } - - return error; - } - - - static - FT_Error parse_private_dict( T2_Parser* parser ) - { - CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = T2_Err_Stack_Underflow; - - if ( parser->top >= parser->stack + 2 ) - { - dict->private_size = t2_parse_num( data++ ); - dict->private_offset = t2_parse_num( data ); - error = T2_Err_Ok; - } - - return error; - } - - - static - FT_Error parse_cid_ros( T2_Parser* parser ) - { - CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object; - FT_Byte** data = parser->stack; - FT_Error error; - - - error = T2_Err_Stack_Underflow; - - if ( parser->top >= parser->stack + 3 ) - { - dict->cid_registry = (FT_UInt)t2_parse_num( data++ ); - dict->cid_ordering = (FT_UInt)t2_parse_num( data++ ); - dict->cid_supplement = (FT_ULong)t2_parse_num( data ); - error = T2_Err_Ok; - } - - return error; - } - - -#define T2_FIELD_NUM( code, name ) \ - T2_FIELD( code, name, t2_kind_num ) -#define T2_FIELD_FIXED( code, name ) \ - T2_FIELD( code, name, t2_kind_fixed ) -#define T2_FIELD_STRING( code, name ) \ - T2_FIELD( code, name, t2_kind_string ) -#define T2_FIELD_BOOL( code, name ) \ - T2_FIELD( code, name, t2_kind_bool ) -#define T2_FIELD_DELTA( code, name,max ) \ - T2_FIELD( code, name, t2_kind_delta ) - -#define T2_REF( s, f ) ( ((s*)0)->f ) - -#define T2_FIELD_CALLBACK( code, name ) \ - { \ - t2_kind_callback, \ - code | T2CODE, \ - 0, 0, \ - parse_ ## name, \ - 0, 0 \ - }, - -#undef T2_FIELD -#define T2_FIELD( code, name, kind ) \ - { \ - kind, \ - code | T2CODE, \ - (FT_UInt)(char*)&T2_REF( T2TYPE, name ), \ - sizeof( T2_REF( T2TYPE, name ) ), \ - 0, 0, 0 \ - }, - -#undef T2_FIELD_DELTA -#define T2_FIELD_DELTA( code, name, max ) \ - { \ - t2_kind_delta, \ - code | T2CODE, \ - (FT_UInt)(char*)&T2_REF( T2TYPE, name ), \ - sizeof( T2_REF( T2TYPE, name )[0] ), \ - 0, \ - max, \ - (FT_UInt)(char*)&T2_REF( T2TYPE, num_ ## name ) \ - }, - -#define T2CODE_TOPDICT 0x1000 -#define T2CODE_PRIVATE 0x2000 - - static const T2_Field_Handler t2_field_handlers[] = - { - -#ifdef FT_FLAT_COMPILE - -#include "t2tokens.h" - -#else - -#include - -#endif - - { 0, 0, 0, 0, 0, 0, 0 } - }; - - - LOCAL_FUNC - FT_Error T2_Parser_Run( T2_Parser* parser, - FT_Byte* start, - FT_Byte* limit ) - { - FT_Byte* p = start; - FT_Error error = T2_Err_Ok; - - - parser->top = parser->stack; - parser->start = start; - parser->limit = limit; - parser->cursor = start; - - while ( p < limit ) - { - FT_Byte v = *p; - - - if ( v >= 27 && v != 31 ) - { - /* it's a number; we will push its position on the stack */ - if ( parser->top - parser->stack >= T2_MAX_STACK_DEPTH ) - goto Stack_Overflow; - - *parser->top ++ = p; - - /* now, skip it */ - if ( v == 30 ) - { - /* skip real number */ - for (;;) - { - if ( p >= limit ) - goto Syntax_Error; - v = p[0] >> 4; - if ( v == 15 ) - break; - v = p[0] & 0xF; - if ( v == 15 ) - break; - p++; - } - p++; - } - else if ( v == 28 ) - p += 2; - else if ( v == 29 ) - p += 4; - else if ( v > 246 ) - p += 1; - } - else - { - /* This is not a number, hence it's an operator. Compute its code */ - /* and look for it in our current list. */ - - FT_UInt code; - FT_UInt num_args = (FT_UInt) - ( parser->top - parser->stack ); - const T2_Field_Handler* field; - - - /* first of all, a trivial check */ - if ( num_args < 1 ) - goto Stack_Underflow; - - *parser->top = p; - code = v; - if ( v == 12 ) - { - /* two byte operator */ - p++; - code = 0x100 | p[0]; - } - code = code | parser->object_code; - - for ( field = t2_field_handlers; field->kind; field++ ) - { - if ( field->code == (FT_Int)code ) - { - /* we found our field's handler; read it */ - FT_Long val; - FT_Byte* q = (FT_Byte*)parser->object + field->offset; - - - switch ( field->kind ) - { - case t2_kind_bool: - case t2_kind_string: - case t2_kind_num: - val = t2_parse_num( parser->stack ); - goto Store_Number; - - case t2_kind_fixed: - val = t2_parse_fixed( parser->stack ); - - Store_Number: - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_Short*)q = (FT_Short)val; - break; - - case 4: - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems where long is 8 bytes */ - *(FT_Long*)q = val; - } - break; - - case t2_kind_delta: - { - FT_Byte* qcount = (FT_Byte*)parser->object + - field->count_offset; - - FT_Long val; - FT_Byte** data = parser->stack; - - - if ( num_args > field->array_max ) - num_args = field->array_max; - - /* store count */ - *qcount = (FT_Byte)num_args; - - val = 0; - while ( num_args > 0 ) - { - val += t2_parse_num( data++ ); - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_Short*)q = (FT_Short)val; - break; - - case 4: - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - - q += field->size; - num_args--; - } - } - break; - - default: /* callback */ - error = field->reader( parser ); - if ( error ) - goto Exit; - } - goto Found; - } - } - - /* this is an unknown operator, or it is unsupported; */ - /* we will ignore it for now. */ - - Found: - /* clear stack */ - parser->top = parser->stack; - } - p++; - } - - Exit: - return error; - - Stack_Overflow: - error = T2_Err_Invalid_Argument; - goto Exit; - - Stack_Underflow: - error = T2_Err_Invalid_Argument; - goto Exit; - - Syntax_Error: - error = T2_Err_Invalid_Argument; - goto Exit; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2parse.h b/subsys/win32k/freetype/src/cff/t2parse.h deleted file mode 100644 index 2238444..0000000 --- a/subsys/win32k/freetype/src/cff/t2parse.h +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2parse.h */ -/* */ -/* OpenType parser (specification). */ -/* */ -/* Copyright 1996-2000 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 T2PARSE_H -#define T2PARSE_H - -#include -#include - -#define T2_MAX_STACK_DEPTH 96 - -#define T2CODE_TOPDICT 0x1000 -#define T2CODE_PRIVATE 0x2000 - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct T2_Parser_ - { - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; - - FT_Byte* stack[T2_MAX_STACK_DEPTH + 1]; - FT_Byte** top; - - FT_UInt object_code; - void* object; - - } T2_Parser; - - - LOCAL_DEF - void T2_Parser_Init( T2_Parser* parser, - FT_UInt code, - void* object ); - - LOCAL_DEF - FT_Error T2_Parser_Run( T2_Parser* parser, - FT_Byte* start, - FT_Byte* limit ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T2PARSE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cff/t2tokens.h b/subsys/win32k/freetype/src/cff/t2tokens.h deleted file mode 100644 index 13a15e4..0000000 --- a/subsys/win32k/freetype/src/cff/t2tokens.h +++ /dev/null @@ -1,96 +0,0 @@ -/***************************************************************************/ -/* */ -/* t2tokens.h */ -/* */ -/* OpenType token definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#undef T2TYPE -#undef T2CODE -#define T2TYPE CFF_Font_Dict -#define T2CODE T2CODE_TOPDICT - - T2_FIELD_STRING ( 0, version ) - T2_FIELD_STRING ( 1, notice ) - T2_FIELD_STRING ( 0x100, copyright ) - T2_FIELD_STRING ( 2, full_name ) - T2_FIELD_STRING ( 3, family_name ) - T2_FIELD_STRING ( 4, weight ) - T2_FIELD_BOOL ( 0x101, is_fixed_pitch ) - T2_FIELD_FIXED ( 0x102, italic_angle ) - T2_FIELD_NUM ( 0x103, underline_position ) - T2_FIELD_NUM ( 0x104, underline_thickness ) - T2_FIELD_NUM ( 0x105, paint_type ) - T2_FIELD_NUM ( 0x106, charstring_type ) - T2_FIELD_CALLBACK( 0x107, font_matrix ) - T2_FIELD_NUM ( 13, unique_id ) - T2_FIELD_CALLBACK( 5, font_bbox ) - T2_FIELD_NUM ( 0x108, stroke_width ) - T2_FIELD_NUM ( 15, charset_offset ) - T2_FIELD_NUM ( 16, encoding_offset ) - T2_FIELD_NUM ( 17, charstrings_offset ) - T2_FIELD_CALLBACK( 18, private_dict ) - T2_FIELD_NUM ( 0x114, synthetic_base ) - T2_FIELD_STRING ( 0x115, postscript ) - T2_FIELD_STRING ( 0x116, base_font_name ) - -#if 0 - T2_FIELD_DELTA ( 0x117, base_font_blend, 16 ) - T2_FIELD_CALLBACK( 0x118, multiple_master ) - T2_FIELD_CALLBACK( 0x119, blend_axit_types ) -#endif - - T2_FIELD_CALLBACK( 0x11E, cid_ros ) - T2_FIELD_NUM ( 0x11F, cid_font_version ) - T2_FIELD_NUM ( 0x120, cid_font_revision ) - T2_FIELD_NUM ( 0x121, cid_font_type ) - T2_FIELD_NUM ( 0x122, cid_count ) - T2_FIELD_NUM ( 0x123, cid_uid_base ) - T2_FIELD_NUM ( 0x124, cid_fd_array_offset ) - T2_FIELD_NUM ( 0x125, cid_fd_select_offset ) - T2_FIELD_STRING ( 0x126, cid_font_name ) - -#if 0 - T2_FIELD_NUM ( 0x127, chameleon ) -#endif - - -#undef T2TYPE -#undef T2CODE -#define T2TYPE CFF_Private -#define T2CODE T2CODE_PRIVATE - - T2_FIELD_DELTA( 6, blue_values, 14 ) - T2_FIELD_DELTA( 7, other_blues, 10 ) - T2_FIELD_DELTA( 8, family_blues, 14 ) - T2_FIELD_DELTA( 9, family_other_blues, 10 ) - T2_FIELD_FIXED( 0x109, blue_scale ) - T2_FIELD_NUM ( 0x10A, blue_shift ) - T2_FIELD_NUM ( 0x10B, blue_fuzz ) - T2_FIELD_NUM ( 10, standard_width ) - T2_FIELD_NUM ( 11, standard_height ) - T2_FIELD_DELTA( 0x10C, snap_widths, 13 ) - T2_FIELD_DELTA( 0x10D, snap_heights, 13 ) - T2_FIELD_BOOL ( 0x10E, force_bold ) - T2_FIELD_FIXED( 0x10F, force_bold_threshold ) - T2_FIELD_NUM ( 0x110, lenIV ) - T2_FIELD_NUM ( 0x111, language_group ) - T2_FIELD_FIXED( 0x112, expansion_factor ) - T2_FIELD_NUM ( 0x113, initial_random_seed ) - T2_FIELD_NUM ( 19, local_subrs_offset ) - T2_FIELD_NUM ( 20, default_width ) - T2_FIELD_NUM ( 21, nominal_width ) - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/.cvsignore b/subsys/win32k/freetype/src/cid/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/cid/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/cid/cidafm.c b/subsys/win32k/freetype/src/cid/cidafm.c deleted file mode 100644 index 7331485..0000000 --- a/subsys/win32k/freetype/src/cid/cidafm.c +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidafm.c */ -/* */ -/* AFM support for CID-keyed fonts (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "cidafm.h" - -#else - -#include - -#endif - - -#include -#include -#include - -#include /* for qsort() */ -#include /* for strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_cidafm - - - LOCAL_FUNC - void CID_Done_AFM( FT_Memory memory, - CID_AFM* afm ) - { - FREE( afm->kern_pairs ); - afm->num_pairs = 0; - } - - -#undef IS_KERN_PAIR -#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) - -#define IS_ALPHANUM( c ) ( isalnum( c ) || \ - c == '_' || \ - c == '.' ) - - - /* read a glyph name and return the equivalent glyph index */ - static - FT_UInt afm_atoindex( FT_Byte** start, - FT_Byte* limit, - T1_Font* type1 ) - { - FT_Byte* p = *start; - FT_Int len; - FT_UInt result = 0; - char temp[64]; - - - /* skip whitespace */ - while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && - p < limit ) - p++; - *start = p; - - /* now, read glyph name */ - while ( IS_ALPHANUM( *p ) && p < limit ) - p++; - - len = p - *start; - - if ( len > 0 && len < 64 ) - { - FT_Int n; - - - /* copy glyph name to intermediate array */ - MEM_Copy( temp, *start, len ); - temp[len] = 0; - - /* lookup glyph name in face array */ - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 ) - { - result = n; - break; - } - } - } - *start = p; - return result; - } - - - /* read an integer */ - static - int afm_atoi( FT_Byte** start, - FT_Byte* limit ) - { - FT_Byte* p = *start; - int sum = 0; - int sign = 1; - - - /* skip everything that is not a number */ - while ( p < limit && !isdigit( *p ) ) - { - sign = 1; - if ( *p == '-' ) - sign = -1; - - p++; - } - - while ( p < limit && isdigit( *p ) ) - { - sum = sum * 10 + ( *p - '0' ); - p++; - } - *start = p; - - return sum * sign; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - static - int compare_kern_pairs( const void* a, - const void* b ) - { - CID_Kern_Pair* pair1 = (CID_Kern_Pair*)a; - CID_Kern_Pair* pair2 = (CID_Kern_Pair*)b; - - FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); - FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - - - return ( index1 - index2 ); - } - - - /* parse an AFM file -- for now, only read the kerning pairs */ - LOCAL_FUNC - FT_Error CID_Read_AFM( FT_Face cid_face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - FT_Int count = 0; - CID_Kern_Pair* pair; - T1_Font* type1 = &((T1_Face)t1_face)->type1; - CID_AFM* afm = 0; - - - if ( ACCESS_Frame( stream->size ) ) - return error; - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - p = start; - - /* we are now going to count the occurrences of `KP' or `KPX' in */ - /* the AFM file. */ - count = 0; - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - count++; - } - - /* Actually, kerning pairs are simply optional! */ - if ( count == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( ALLOC( afm, sizeof ( *afm ) ) || - ALLOC_ARRAY( afm->kern_pairs, count, CID_Kern_Pair ) ) - goto Exit; - - /* now, read each kern pair */ - pair = afm->kern_pairs; - afm->num_pairs = count; - - /* save in face object */ - ((T1_Face)t1_face)->afm_data = afm; - - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - { - FT_Byte* q; - - - /* skip keyword (`KP' or `KPX') */ - q = p + 2; - if ( *q == 'X' ) - q++; - - pair->glyph1 = afm_atoindex( &q, limit, type1 ); - pair->glyph2 = afm_atoindex( &q, limit, type1 ); - pair->kerning.x = afm_atoi( &q, limit ); - - pair->kerning.y = 0; - if ( p[2] != 'X' ) - pair->kerning.y = afm_atoi( &q, limit ); - - pair++; - } - } - - /* now, sort the kern pairs according to their glyph indices */ - qsort( afm->kern_pairs, count, sizeof ( CID_Kern_Pair ), - compare_kern_pairs ); - - Exit: - if ( error ) - FREE( afm ); - - FORGET_Frame(); - - return error; - } - - - /* find the kerning for a given glyph pair */ - LOCAL_FUNC - void CID_Get_Kerning( CID_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - CID_Kern_Pair *min, *mid, *max; - FT_ULong index = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = afm->kern_pairs; - max = min + afm->num_pairs - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); - if ( midi == index ) - { - *kerning = mid->kerning; - return; - } - - if ( midi < index ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidafm.h b/subsys/win32k/freetype/src/cid/cidafm.h deleted file mode 100644 index 0bb4eb0..0000000 --- a/subsys/win32k/freetype/src/cid/cidafm.h +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidafm.h */ -/* */ -/* AFM support for CID-keyed fonts (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDAFM_H -#define CIDAFM_H - - -#ifdef FT_FLAT_COMPILE - -#include "cidobjs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct CID_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; - - } CID_Kern_Pair; - - typedef struct CID_AFM_ - { - FT_UInt num_pairs; - CID_Kern_Pair* kern_pairs; - - } CID_AFM; - - - LOCAL_DEF - FT_Error CID_Read_AFM( FT_Face cid_face, - FT_Stream stream ); - - LOCAL_DEF - void CID_Done_AFM( FT_Memory memory, - CID_AFM* afm ); - - LOCAL_DEF - void CID_Get_Kerning( CID_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* CIDAFM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidgload.c b/subsys/win32k/freetype/src/cid/cidgload.c deleted file mode 100644 index f6dff4b..0000000 --- a/subsys/win32k/freetype/src/cid/cidgload.c +++ /dev/null @@ -1,1558 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidgload.c */ -/* */ -/* CID-keyed Type1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "cidload.h" -#include "cidgload.h" - -#else - -#include -#include - -#endif - - -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_cidgload - - - /* forward */ - static - FT_Error cid_load_glyph( CID_Decoder* decoder, - FT_UInt glyph_index ); - - - typedef enum CID_Operator_ - { - op_none = 0, - - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - - op_dotsection, - - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } CID_Operator; - - static - const FT_Int t1_args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - - 0, /* dotsection */ - - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - LOCAL_FUNC - void CID_Init_Builder( CID_Builder* builder, - CID_Face face, - CID_Size size, - CID_GlyphSlot glyph ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = glyph->root.loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - - FT_GlyphLoader_Rewind( loader ); - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void CID_Done_Builder( CID_Builder* builder ) - { - CID_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - LOCAL_FUNC - void CID_Init_Decoder( CID_Decoder* decoder ) - { - MEM_Set( decoder, 0, sizeof ( *decoder ) ); - - decoder->font_matrix.xx = 0x10000L; - decoder->font_matrix.yy = 0x10000L; - } - - - /* check that there is enough space for `count' more points */ - static - FT_Error check_points( CID_Builder* builder, - FT_Int count ) - { - return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); - } - - - /* add a new point, but do not check space */ - static - void add_point( CID_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = x; - point->y = y; - *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; - - builder->last = *point; - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - static - FT_Error add_point1( CID_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = check_points( builder, 1 ); - if ( !error ) - add_point( builder, x, y, 1 ); - - return error; - } - - - /* check room for a new contour, then add it */ - static - FT_Error add_contour( CID_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return T1_Err_Ok; - } - - error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - } - return error; - } - - - /* if a path has been started, add its first on-curve point */ - static - FT_Error start_point( CID_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - FT_Error error; - - - builder->path_begun = 1; - error = add_contour( builder ); - if ( error ) - return error; - } - - return add_point1( builder, x, y ); - } - - - /* close the current contour */ - static - void close_contour( CID_Builder* builder ) - { - FT_Outline* outline = builder->current; - - - /* XXX: We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - - - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - } - - -#if 0 - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( CID_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); - - for ( n = 0; n < face->cid.cid_count; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name, glyph_name ) == 0 ) - return n; - } - - return -1; - } - - -#endif /* 0 */ - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( CID_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - - - bchar_index = bchar; - achar_index = achar; - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->current.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - if ( decoder->builder.loader ) - FT_GlyphLoader_Prepare( decoder->builder.loader ); - - error = cid_load_glyph( decoder, bchar_index ); /* load one glyph */ - if ( error ) - goto Exit; - - n_base_points = base->n_points; - - { - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load `achar' on top of */ - /* the base outline */ - error = cid_load_glyph( decoder, achar_index ); - if ( error ) - return error; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - FT_Outline_Translate( &dummy, adx - asb, ady ); - } - } - - Exit: - return error; - } - - -#define USE_ARGS( n ) do \ - { \ - top -= n; \ - if ( top < decoder->stack ) \ - goto Stack_Underflow; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given CID charstrings program. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ) - { - FT_Error error; - CID_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - CID_Builder* builder = &decoder->builder; - FT_Outline* outline; - FT_Pos x, y; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - outline = builder->current; - - x = builder->pos_x; - y = builder->pos_y; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - CID_Operator op = op_none; - FT_Long value = 0; - - - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - - /* First of all, decompress operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (long)ip[0] << 24 ) | - ( (long)ip[1] << 16 ) | - ( (long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ( (long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "CID_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "CID_Parse_CharStrings: Stack overflow!\n" )); - goto Syntax_Error; - } - - FT_TRACE4(( " %ld", value )); - *top++ = value; - decoder->top = top; - } - else if ( op == op_callothersubr ) /* callothersubr */ - { - FT_TRACE4(( " callothersubr" )); - - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - switch ( top[1] ) - { - case 1: /* start flex feature ---------------------- */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - break; - - case 2: /* add flex vectors ------------------------ */ - { - FT_Int index; - - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - /* note that we should not add a point for index 0. */ - /* this will move our current position to the flex */ - /* point without adding any point to the outline */ - index = decoder->num_flex_vectors++; - if ( index > 0 && index < 7 ) - add_point( builder, - x, - y, - (FT_Byte)( index==3 || index==6 ) ); - } - break; - - case 0: /* end flex feature ------------------------- */ - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - /* now consume the remaining `pop pop setcurpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ - { - FT_ERROR(( "CID_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - ip += 6; - decoder->flex_state = 0; - break; - - case 3: /* change hints ---------------------------- */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", - ip[0], ip[1] )); - goto Syntax_Error; - } - ip += 2; - break; - - case 12: - case 13: - /* counter control hints, clear stack */ - top = decoder->stack; - break; - -#if 0 - - case 14: - case 15: - case 16: - case 17: - case 18: /* multiple masters */ - { - T1_Blend* blend = decoder->blend; - FT_UInt num_points, nn, mm; - FT_Int* delta; - FT_Int* values; - - - if ( !blend ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected multiple masters operator!\n" )); - goto Syntax_Error; - } - - num_points = top[1] - 13 + ( top[1] == 18 ); - if ( top[0] != num_points * blend->num_designs ) - { - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " incorrect number of mm arguments\n" )); - goto Syntax_Error; - } - - top -= blend->num_designs * num_points; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* We want to compute: */ - /* */ - /* a0*w0 + a1*w1 + ... + ak*wk */ - /* */ - /* but we only have the a0, a1-a0, a2-a0, .. ak-a0. */ - /* However, given that w0 + w1 + ... + wk == 1, we can */ - /* rewrite it easily as: */ - /* */ - /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ - /* */ - /* where k == num_designs-1 */ - /* */ - /* I guess that's why it's written in this `compact' */ - /* form... */ - /* */ - delta = top + num_points; - values = top; - for ( nn = 0; nn < num_points; nn++ ) - { - FT_Int x = values[0]; - - - for ( mm = 1; mm < blend->num_designs; mm++ ) - x += FT_MulFix( *delta++, blend->weight_vector[mm] ); - - *values++ = x; - } - /* note that `top' will be incremented later by calls to `pop' */ - } - break; - -#endif - - default: - Unexpected_OtherSubr: - FT_ERROR(( "CID_Parse_CharStrings: invalid othersubr [%d %d]!\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else /* general operator */ - { - FT_Int num_args = t1_args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - FT_TRACE4(( " endchar" )); - - close_contour( builder ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n\n" )); - return T1_Err_Ok; - - case op_hsbw: - FT_TRACE4(( " hsbw" )); - - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; - - builder->last.x = x = top[0]; - builder->last.y = y = 0; - - /* The `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it. So exit immediately. */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_seac: - /* return immediately after processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - FT_TRACE4(( " sbw" )); - - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; - - builder->last.x = x = top[0]; - builder->last.y = y = top[1]; - - /* The `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it. So exit immediately. */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_closepath: - FT_TRACE4(( " closepath" )); - - close_contour( builder ); - builder->path_begun = 0; - break; - - case op_hlineto: - FT_TRACE4(( " hlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - goto Add_Line; - - case op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - x += top[0]; - break; - - case op_hvcurveto: - FT_TRACE4(( " hvcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - add_point( builder, x, y, 0 ); - - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - - y += top[3]; - add_point( builder, x, y, 1 ); - - break; - - case op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - - Add_Line: - if ( add_point1( builder, x, y ) ) - goto Memory_Error; - break; - - case op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - x += top[0]; - y += top[1]; - break; - - case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - add_point( builder, x, y, 0 ); - - x += top[2]; - y += top[3]; - add_point( builder, x, y, 0 ); - - x += top[4]; - y += top[5]; - add_point( builder, x, y, 1 ); - - break; - - case op_vhcurveto: - FT_TRACE4(( " vhcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - y += top[0]; - add_point( builder, x, y, 0 ); - - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - - x += top[3]; - add_point( builder, x, y, 1 ); - - break; - - case op_vlineto: - FT_TRACE4(( " vlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - y += top[0]; - goto Add_Line; - - case op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - y += top[0]; - break; - - case op_div: - FT_TRACE4(( " div" )); - - if ( top[1] ) - { - *top = top[0] / top[1]; - top++; - } - else - { - FT_ERROR(( "CID_Parse_CharStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index; - - - FT_TRACE4(( " callsubr" )); - - index = top[0]; - if ( index < 0 || index >= (FT_Int)decoder->subrs->num_subrs ) - { - FT_ERROR(( "CID_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "CID_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->subrs->code[index] + decoder->lenIV; - zone->limit = decoder->subrs->code[index + 1]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "CID_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case op_pop: - FT_TRACE4(( " pop" )); - - /* theoretically, the arguments are already on the stack */ - top++; - break; - - case op_return: - FT_TRACE4(( " return" )); - - if ( zone <= decoder->zones ) - { - FT_ERROR(( "CID_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - - break; - - case op_dotsection: - FT_TRACE4(( " dotsection" )); - - break; - - case op_hstem: - FT_TRACE4(( " hstem" )); - - break; - - case op_hstem3: - FT_TRACE4(( " hstem3" )); - - break; - - case op_vstem: - FT_TRACE4(( " vstem" )); - - break; - - case op_vstem3: - FT_TRACE4(( " vstem3" )); - - break; - - case op_setcurrentpoint: - FT_TRACE4(( " setcurrentpoint" )); - - FT_ERROR(( "CID_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - - default: - FT_ERROR(( "CID_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - - Memory_Error: - return builder->error; - } - - -#if 0 - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error CID_Compute_Max_Advance( CID_Face face, - FT_Int* max_advance ) - { - FT_Error error; - CID_Decoder decoder; - FT_Int glyph_index; - - - *max_advance = 0; - - /* Initialize load decoder */ - CID_Init_Decoder( &decoder ); - CID_Init_Builder( &decoder.builder, face, 0, 0 ); - - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - /* for each glyph, parse the glyph charstring and extract */ - /* the advance width */ - for ( glyph_index = 0; glyph_index < face->root.num_glyphs; - glyph_index++ ) - { - /* now get load the unscaled outline */ - error = cid_load_glyph( &decoder, glyph_index ); - /* ignore the error if one occurred - skip to next glyph */ - } - - *max_advance = decoder.builder.advance.x; - - return T1_Err_Ok; - } - - -#endif /* 0 */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error cid_load_glyph( CID_Decoder* decoder, - FT_UInt glyph_index ) - { - CID_Face face = decoder->builder.face; - CID_Info* cid = &face->cid; - FT_Byte* p; - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; - FT_UInt fd_select; - FT_ULong off1, glyph_len; - FT_Stream stream = face->root.stream; - FT_Error error = 0; - - - /* read the CID font dict index and charstring offset from the CIDMap */ - if ( FILE_Seek( cid->data_offset + cid->cidmap_offset + - glyph_index * entry_len) || - ACCESS_Frame( 2 * entry_len ) ) - goto Exit; - - p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; - - FORGET_Frame(); - - /* now, if the glyph is not empty, set up the subrs array, and parse */ - /* the charstrings */ - if ( glyph_len > 0 ) - { - CID_FontDict* dict; - FT_Byte* charstring; - FT_UInt lenIV; - FT_Memory memory = face->root.memory; - - - /* setup subrs */ - decoder->subrs = face->subrs + fd_select; - - /* setup font matrix */ - dict = cid->font_dicts + fd_select; - decoder->font_matrix = dict->font_matrix; - lenIV = dict->private_dict.lenIV; - decoder->lenIV = lenIV; - - /* the charstrings are encoded (stupid!) */ - /* load the charstrings, then execute it */ - - if ( ALLOC( charstring, glyph_len ) ) - goto Exit; - - if ( !FILE_Read_At( cid->data_offset + off1, charstring, glyph_len ) ) - { - cid_decrypt( charstring, glyph_len, 4330 ); - error = CID_Parse_CharStrings( decoder, - charstring + lenIV, - glyph_len - lenIV ); - } - - FREE( charstring ); - } - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Error CID_Load_Glyph( CID_GlyphSlot glyph, - CID_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - CID_Decoder decoder; - CID_Face face = (CID_Face)glyph->root.face; - FT_Bool hinting; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0; - - glyph->root.format = ft_glyph_format_outline; - - { - CID_Init_Decoder( &decoder ); - CID_Init_Builder( &decoder.builder, face, size, glyph ); - - /* set up the decoder */ - decoder.builder.no_recurse = - (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE ); - - error = cid_load_glyph( &decoder, glyph_index ); - - /* save new glyph tables */ - CID_Done_Builder( &decoder.builder ); - } - - /* Now, set the metrics - this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax. */ - if ( !error ) - { - /* for composite glyphs, return only the left side bearing and the */ - /* advance width */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags &= ft_outline_owner; - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - - glyph->root.outline.flags |= ft_outline_reverse_fill; - -#if 0 - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; - glyph->root.outline.dropout_mode = 2; -#endif - - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = &glyph->root.outline; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - } - - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, &decoder.font_matrix ); - - /* compute the other metrics */ - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - } - } - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidgload.h b/subsys/win32k/freetype/src/cid/cidgload.h deleted file mode 100644 index 2784242..0000000 --- a/subsys/win32k/freetype/src/cid/cidgload.h +++ /dev/null @@ -1,198 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidgload.h */ -/* */ -/* OpenType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDGLOAD_H -#define CIDGLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "cidobjs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* max_points :: maximum points in builder outline */ - /* */ - /* max_contours :: Maximal number of contours in builder outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* error :: An error code that is only used to report memory */ - /* allocation problems. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - typedef struct CID_Builder_ - { - FT_Memory memory; - CID_Face face; - CID_GlyphSlot glyph; - FT_GlyphLoader* loader; - FT_Outline* base; - FT_Outline* current; - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; - - } CID_Builder; - - - /* execution context charstring zone */ - - typedef struct CID_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } CID_Decoder_Zone; - - - typedef struct CID_Decoder_ - { - CID_Builder builder; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - CID_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - CID_Decoder_Zone* zone; - - FT_Matrix font_matrix; - CID_Subrs* subrs; - FT_UInt lenIV; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - } CID_Decoder; - - - LOCAL_DEF - void CID_Init_Builder( CID_Builder* builder, - CID_Face face, - CID_Size size, - CID_GlyphSlot glyph ); - - LOCAL_DEF - void CID_Done_Builder( CID_Builder* builder ); - - - LOCAL_DEF - void CID_Init_Decoder( CID_Decoder* decoder ); - - -#if 0 - - /* Compute the maximum advance width of a font through quick parsing */ - LOCAL_DEF - FT_Error CID_Compute_Max_Advance( CID_Face face, - FT_Int* max_advance ); - -#endif - - /* This function is exported, because it is used by the T1Dump utility */ - LOCAL_DEF - FT_Error CID_Parse_CharStrings( CID_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len ); - - LOCAL_DEF - FT_Error CID_Load_Glyph( CID_GlyphSlot glyph, - CID_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* CIDGLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidload.c b/subsys/win32k/freetype/src/cid/cidload.c deleted file mode 100644 index 729dbc9..0000000 --- a/subsys/win32k/freetype/src/cid/cidload.c +++ /dev/null @@ -1,537 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidload.c */ -/* */ -/* CID-keyed Type1 font loader (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "cidload.h" - -#else - -#include - -#endif - - -#include -#include /* for isspace(), isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_cidload - - - /* read a single offset */ - LOCAL_FUNC - FT_Long cid_get_offset( FT_Byte** start, - FT_Byte offsize ) - { - FT_Long result; - FT_Byte* p = *start; - - - for ( result = 0; offsize > 0; offsize-- ) - { - result <<= 8; - result |= *p++; - } - - *start = p; - return result; - } - - - LOCAL_FUNC - void cid_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = ( *buffer ^ ( seed >> 8 ) ); - seed = ( *buffer + seed ) * 52845 + 22719; - *buffer++ = plain; - length--; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 SYMBOL PARSING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error cid_load_keyword( CID_Face face, - CID_Loader* loader, - const CID_Field_Rec* keyword ) - { - FT_Error error; - CID_Parser* parser = &loader->parser; - FT_Byte* object; - CID_Info* cid = &face->cid; - - - /* if the keyword has a dedicated callback, call it */ - if ( keyword->type == t1_field_callback ) - { - error = keyword->reader( face, parser ); - goto Exit; - } - - /* we must now compute the address of our target object */ - switch ( keyword->location ) - { - case t1_field_cid_info: - object = (FT_Byte*)cid; - break; - - case t1_field_font_info: - object = (FT_Byte*)&cid->font_info; - break; - - default: - { - CID_FontDict* dict; - - - if ( parser->num_dict < 0 ) - { - FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", - keyword->ident )); - error = T1_Err_Syntax_Error; - goto Exit; - } - - dict = cid->font_dicts + parser->num_dict; - switch ( keyword->location ) - { - case t1_field_private: - object = (FT_Byte*)&dict->private_dict; - break; - - default: - object = (FT_Byte*)dict; - } - } - } - - /* now, load the keyword data in the object's field(s) */ - if ( keyword->type == t1_field_integer_array || - keyword->type == t1_field_fixed_array ) - error = CID_Load_Field_Table( parser, keyword, object ); - else - error = CID_Load_Field( parser, keyword, object ); - - Exit: - return error; - } - - - static - FT_Error parse_font_bbox( CID_Face face, - CID_Parser* parser ) - { - FT_Short temp[4]; - FT_BBox* bbox = &face->cid.font_bbox; - - - (void)CID_ToCoordArray( parser, 4, temp ); - bbox->xMin = temp[0]; - bbox->yMin = temp[1]; - bbox->xMax = temp[2]; - bbox->yMax = temp[3]; - - return T1_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ - } - - - static - FT_Error parse_font_matrix( CID_Face face, - CID_Parser* parser ) - { - FT_Matrix* matrix; - CID_FontDict* dict; - FT_Fixed temp[4]; - - - if ( parser->num_dict >= 0 ) - { - dict = face->cid.font_dicts + parser->num_dict; - matrix = &dict->font_matrix; - - (void)CID_ToFixedArray( parser, 4, temp, 3 ); - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - } - - return T1_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ - } - - - static - FT_Error parse_fd_array( CID_Face face, - CID_Parser* parser ) - { - CID_Info* cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Error error = T1_Err_Ok; - FT_Long num_dicts; - - - num_dicts = CID_ToInt( parser ); - - if ( !cid->font_dicts ) - { - FT_Int n; - - - if ( ALLOC_ARRAY( cid->font_dicts, num_dicts, CID_FontDict ) ) - goto Exit; - - cid->num_dicts = (FT_UInt)num_dicts; - - /* don't forget to set a few defaults */ - for ( n = 0; n < cid->num_dicts; n++ ) - { - CID_FontDict* dict = cid->font_dicts + n; - - - /* default value for lenIV */ - dict->private_dict.lenIV = 4; - } - } - - Exit: - return error; - } - - - static - const CID_Field_Rec t1_field_records[] = - { - -#ifdef FT_FLAT_COMPILE - -#include "cidtokens.h" - -#else - -#include - -#endif - - { 0, t1_field_cid_info, t1_field_none, 0, 0, 0, 0, 0 } - }; - - - static - int is_alpha( char c ) - { - return ( isalnum( c ) || - c == '.' || - c == '_' ); - } - - - static - void skip_whitespace( CID_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - - while ( cur < parser->limit && isspace( *cur ) ) - cur++; - - parser->cursor = cur; - } - - - static - FT_Error parse_dict( CID_Face face, - CID_Loader* loader, - FT_Byte* base, - FT_Long size ) - { - CID_Parser* parser = &loader->parser; - - - parser->cursor = base; - parser->limit = base + size; - parser->error = 0; - - { - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - - - for ( ;cur < limit; cur++ ) - { - /* look for `%ADOBeginFontDict' */ - if ( *cur == '%' && cur + 20 < limit && - strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) - { - cur += 17; - - /* if /FDArray was found, then cid->num_dicts is > 0, and */ - /* we can start increasing parser->num_dict */ - if ( face->cid.num_dicts > 0 ) - parser->num_dict++; - } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_Byte* cur2; - FT_Int len; - - - cur++; - - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 && len < 22 ) - { - /* now compare the immediate name to the keyword table */ - const CID_Field_Rec* keyword = t1_field_records; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->ident; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == (FT_Int)strlen( (const char*)name ) ) - { - FT_Int n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it - run the parsing callback */ - parser->cursor = cur2; - skip_whitespace( parser ); - parser->error = cid_load_keyword( face, loader, keyword ); - if ( parser->error ) - return parser->error; - - cur = parser->cursor; - break; - } - } - keyword++; - } - } - } - } - } - return parser->error; - } - - - /* read the subrmap and the subrs of each font dict */ - static - FT_Error cid_read_subrs( CID_Face face ) - { - CID_Info* cid = &face->cid; - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; - FT_Error error; - FT_Int n; - CID_Subrs* subr; - FT_UInt max_offsets = 0; - FT_ULong* offsets = 0; - - - if ( ALLOC_ARRAY( face->subrs, cid->num_dicts, CID_Subrs ) ) - goto Exit; - - subr = face->subrs; - for ( n = 0; n < cid->num_dicts; n++, subr++ ) - { - CID_FontDict* dict = cid->font_dicts + n; - FT_UInt count, num_subrs = dict->num_subrs; - FT_ULong data_len; - FT_Byte* p; - - - /* reallocate offsets array if needed */ - if ( num_subrs + 1 > max_offsets ) - { - FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4; - - - if ( REALLOC_ARRAY( offsets, max_offsets, new_max, FT_ULong ) ) - goto Fail; - - max_offsets = new_max; - } - - /* read the subrmap's offsets */ - if ( FILE_Seek( cid->data_offset + dict->subrmap_offset ) || - ACCESS_Frame( ( num_subrs + 1 ) * dict->sd_bytes ) ) - goto Fail; - - p = (FT_Byte*)stream->cursor; - for ( count = 0; count <= num_subrs; count++ ) - offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); - - FORGET_Frame(); - - /* now, compute the size of subrs charstrings, */ - /* allocate, and read them */ - data_len = offsets[num_subrs] - offsets[0]; - - if ( ALLOC_ARRAY( subr->code, num_subrs + 1, FT_Byte* ) || - ALLOC( subr->code[0], data_len ) ) - goto Fail; - - if ( FILE_Seek( cid->data_offset + offsets[0] ) || - FILE_Read( subr->code[0], data_len ) ) - goto Exit; - - /* set up pointers */ - for ( count = 1; count <= num_subrs; count++ ) - { - FT_UInt len; - - - len = offsets[count] - offsets[count - 1]; - subr->code[count] = subr->code[count - 1] + len; - } - - /* decrypt subroutines */ - for ( count = 0; count < num_subrs; count++ ) - { - FT_UInt len; - - - len = offsets[count + 1] - offsets[count]; - cid_decrypt( subr->code[count], len, 4330 ); - } - - subr->num_subrs = num_subrs; - } - - Exit: - FREE( offsets ); - return error; - - Fail: - if ( face->subrs ) - { - for ( n = 0; n < cid->num_dicts; n++ ) - { - if ( face->subrs[n].code ) - FREE( face->subrs[n].code[0] ); - - FREE( face->subrs[n].code ); - } - FREE( face->subrs ); - } - goto Exit; - } - - - static - void t1_init_loader( CID_Loader* loader, - CID_Face face ) - { - FT_UNUSED( face ); - - MEM_Set( loader, 0, sizeof ( *loader ) ); - } - - - static - void t1_done_loader( CID_Loader* loader ) - { - CID_Parser* parser = &loader->parser; - - - /* finalize parser */ - CID_Done_Parser( parser ); - } - - - LOCAL_FUNC - FT_Error CID_Open_Face( CID_Face face ) - { - CID_Loader loader; - CID_Parser* parser; - FT_Error error; - - - t1_init_loader( &loader, face ); - - parser = &loader.parser; - error = CID_New_Parser( parser, face->root.stream, face->root.memory ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, - parser->postscript, - parser->postscript_len ); - if ( error ) - goto Exit; - - face->cid.data_offset = loader.parser.data_offset; - error = cid_read_subrs( face ); - - Exit: - t1_done_loader( &loader ); - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidload.h b/subsys/win32k/freetype/src/cid/cidload.h deleted file mode 100644 index d3b6445..0000000 --- a/subsys/win32k/freetype/src/cid/cidload.h +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidload.h */ -/* */ -/* CID-keyed Type1 font loader (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDLOAD_H -#define CIDLOAD_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "cidparse.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct CID_Loader_ - { - CID_Parser parser; /* parser used to read the stream */ - FT_Int num_chars; /* number of characters in encoding */ - - } CID_Loader; - - - LOCAL_DEF - FT_Long cid_get_offset( FT_Byte** start, - FT_Byte offsize ); - - LOCAL_DEF - void cid_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ); - - LOCAL_DEF - FT_Error CID_Open_Face( CID_Face face ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* CIDLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidobjs.c b/subsys/win32k/freetype/src/cid/cidobjs.c deleted file mode 100644 index 818daa1..0000000 --- a/subsys/win32k/freetype/src/cid/cidobjs.c +++ /dev/null @@ -1,380 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidobjs.c */ -/* */ -/* CID objects manager (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "cidgload.h" -#include "cidload.h" - -#else - -#include -#include - -#endif - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_cidobjs - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Face */ - /* */ - /* */ - /* Finalizes a given face object. */ - /* */ - /* */ - /* face :: A pointer to the face object to destroy. */ - /* */ - LOCAL_FUNC - void CID_Done_Face( CID_Face face ) - { - FT_Memory memory; - - - if ( face ) - { - CID_Info* cid = &face->cid; - T1_FontInfo* info = &cid->font_info; - - - memory = face->root.memory; - - /* release FontInfo strings */ - FREE( info->version ); - FREE( info->notice ); - FREE( info->full_name ); - FREE( info->family_name ); - FREE( info->weight ); - - /* release font dictionaries */ - FREE( cid->font_dicts ); - cid->num_dicts = 0; - - /* release other strings */ - FREE( cid->cid_font_name ); - FREE( cid->registry ); - FREE( cid->ordering ); - - face->root.family_name = 0; - face->root.style_name = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Face */ - /* */ - /* */ - /* Initializes a given CID face object. */ - /* */ - /* */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The newly built face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Init_Face( FT_Stream stream, - CID_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - PSNames_Interface* psnames; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( stream ); - - - face->root.num_faces = 1; - - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Interface*)FT_Get_Module_Interface( - FT_FACE_LIBRARY( face ), "psnames" ); - - face->psnames = psnames; - } - - /* open the tokenizer; this will also check the font format */ - if ( FILE_Seek( 0 ) ) - goto Exit; - - error = CID_Open_Face( face ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - if ( face_index != 0 ) - { - FT_ERROR(( "CID_Init_Face: invalid face index\n" )); - error = T1_Err_Invalid_Argument; - goto Exit; - } - - /* Now, load the font program into the face object */ - { - /* Init the face object fields */ - /* Now set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - - - root->num_glyphs = face->cid.cid_count; - root->num_charmaps = 0; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - if ( face->cid.font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: TODO: add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a /FontName dictionary entry! */ - root->family_name = face->cid.font_info.family_name; - if ( root->family_name ) - { - char* full = face->cid.font_info.full_name; - char* family = root->family_name; - - while ( *family && *full == *family ) - { - family++; - full++; - } - - root->style_name = ( *full == ' ' ) ? full + 1 - : (char *)"Regular"; - } - else - { - /* do we have a `/FontName'? */ - if ( face->cid.cid_font_name ) - { - root->family_name = face->cid.cid_font_name; - root->style_name = "Regular"; - } - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox = face->cid.font_bbox; - root->units_per_EM = 1000; - root->ascender = (FT_Short)face->cid.font_bbox.yMax; - root->descender = -(FT_Short)face->cid.font_bbox.yMin; - root->height = ( ( root->ascender + root->descender ) * 12 ) - / 10; - - -#if 0 - - /* now compute the maximum advance width */ - - root->max_advance_width = face->type1.private_dict.standard_width[0]; - - /* compute max advance width for proportional fonts */ - if ( !face->type1.font_info.is_fixed_pitch ) - { - FT_Int max_advance; - - - error = CID_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = max_advance; - else - error = 0; /* clear error */ - } - - root->max_advance_height = root->height; - -#endif /* 0 */ - - root->underline_position = face->cid.font_info.underline_position; - root->underline_thickness = face->cid.font_info.underline_thickness; - - root->max_points = 0; - root->max_contours = 0; - } - } - -#if 0 - - /* charmap support - synthetize unicode charmap when possible */ - { - FT_Face root = &face->root; - FT_CharMap charmap = face->charmaprecs; - - - /* synthesize a Unicode charmap if there is support in the `psnames' */ - /* module */ - if ( face->psnames ) - { - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - if ( psnames->unicode_value ) - { - error = psnames->build_unicodes( - root->memory, - face->type1.num_glyphs, - (const char**)face->type1.glyph_names, - &face->unicode_map ); - if ( !error ) - { - root->charmap = charmap; - charmap->face = (FT_Face)face; - charmap->encoding = ft_encoding_unicode; - charmap->platform_id = 3; - charmap->encoding_id = 1; - charmap++; - } - - /* simply clear the error in case of failure (which really */ - /* means that out of memory or no unicode glyph names) */ - error = 0; - } - } - - /* now, support either the standard, expert, or custom encodings */ - charmap->face = (FT_Face)face; - charmap->platform_id = 7; /* a new platform id for Adobe fonts? */ - - switch ( face->type1.encoding_type ) - { - case t1_encoding_standard: - charmap->encoding = ft_encoding_adobe_standard; - charmap->encoding_id = 0; - break; - - case t1_encoding_expert: - charmap->encoding = ft_encoding_adobe_expert; - charmap->encoding_id = 1; - break; - - default: - charmap->encoding = ft_encoding_adobe_custom; - charmap->encoding_id = 2; - break; - } - - root->charmaps = face->charmaps; - root->num_charmaps = charmap - face->charmaprecs + 1; - face->charmaps[0] = &face->charmaprecs[0]; - face->charmaps[1] = &face->charmaprecs[1]; - } - -#endif /* 0 */ - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Init_Driver */ - /* */ - /* */ - /* Initializes a given CID driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_Init_Driver( CID_Driver driver ) - { - FT_UNUSED( driver ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Driver */ - /* */ - /* */ - /* Finalizes a given CID driver. */ - /* */ - /* */ - /* driver :: A handle to the target CID driver. */ - /* */ - LOCAL_DEF - void CID_Done_Driver( CID_Driver driver ) - { - FT_UNUSED( driver ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidobjs.h b/subsys/win32k/freetype/src/cid/cidobjs.h deleted file mode 100644 index c28c59b..0000000 --- a/subsys/win32k/freetype/src/cid/cidobjs.h +++ /dev/null @@ -1,141 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidobjs.h */ -/* */ -/* CID objects manager (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDOBJS_H -#define CIDOBJS_H - -#include -#include -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* The following structures must be defined by the hinter */ - typedef struct CID_Size_Hints_ CID_Size_Hints; - typedef struct CID_Glyph_Hints_ CID_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Driver */ - /* */ - /* */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct CID_DriverRec_* CID_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct CID_SizeRec_* CID_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* CID_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct CID_GlyphSlotRec_* CID_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* CID_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct CID_CharMapRec_* CID_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE 1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - typedef struct CID_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - - } CID_SizeRec; - - - typedef struct CID_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } CID_GlyphSlotRec; - - - LOCAL_DEF - FT_Error CID_Init_Face( FT_Stream stream, - CID_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void CID_Done_Face( CID_Face face ); - - - LOCAL_DEF - FT_Error CID_Init_Driver( CID_Driver driver ); - - LOCAL_DEF - void CID_Done_Driver( CID_Driver driver ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* CIDOBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidparse.c b/subsys/win32k/freetype/src/cid/cidparse.c deleted file mode 100644 index 02f36b1..0000000 --- a/subsys/win32k/freetype/src/cid/cidparse.c +++ /dev/null @@ -1,1024 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidparse.c */ -/* */ -/* CID-keyed Type1 parser (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "cidparse.h" - -#else - -#include - -#endif - - -#include /* for strncmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_cidparse - - -#if 0 - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMPLEMENTATION OF CID_TABLE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_New_Table */ - /* */ - /* */ - /* Initializes a CID_Table. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size, i.e., the maximal number of elements. */ - /* */ - /* memory :: The memory object to be used for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error CID_New_Table( CID_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) || - ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - goto Exit; - - table->max_elems = count; - table->init = 0xDEADBEEFL; - table->num_elems = 0; - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - Exit: - if ( error ) - FREE( table->elements ); - - return error; - } - - - static - void shift_elements( CID_Table* table, - FT_Byte* old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset++ ) - { - if ( offset[0] ) - offset[0] += delta; - } - } - - - static - FT_Error reallocate_t1_table( CID_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* realloc the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - - table->capacity = new_size; - - /* shift all offsets when needed */ - if ( old_base ) - shift_elements( table, old_base ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Add_Table */ - /* */ - /* */ - /* Adds an object to a CID_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in the memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if */ - /* reallocation fails. */ - /* */ - LOCAL_FUNC - FT_Error CID_Add_Table( CID_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "CID_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Done_Table */ - /* */ - /* */ - /* Finalizes a CID_Table (reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void CID_Done_Table( CID_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - shift_elements( table, old_base ); - } - - - LOCAL_FUNC - void CID_Release_Table( CID_Table* table ) - { - FT_Memory memory = table->memory; - - - if ( table->init == 0xDEADBEEFL ) - { - FREE( table->block ); - FREE( table->elements ); - FREE( table->lengths ); - table->init = 0; - } - } - -#endif /* 0 */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INPUT STREAM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define IS_CID_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_CID_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) - -#define IS_CID_SPACE( c ) ( IS_CID_WHITESPACE( c ) || IS_CID_LINESPACE( c ) ) - - - LOCAL_FUNC - void CID_Skip_Spaces( CID_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( !IS_CID_SPACE( c ) ) - break; - cur++; - } - - parser->cursor = cur; - } - - - LOCAL_FUNC - void CID_ToToken( CID_Parser* parser, - CID_Token_Rec* token ) - { - FT_Byte* cur; - FT_Byte* limit; - FT_Byte starter, ender; - FT_Int embed; - - - token->type = t1_token_none; - token->start = 0; - token->limit = 0; - - /* first of all, skip space */ - CID_Skip_Spaces( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur < limit ) - { - switch ( *cur ) - { - /************* check for strings ***********************/ - case '(': - token->type = t1_token_string; - ender = ')'; - goto Lookup_Ender; - - /************* check for programs/array ****************/ - case '{': - token->type = t1_token_array; - ender = '}'; - goto Lookup_Ender; - - /************* check for table/array ******************/ - case '[': - token->type = t1_token_array; - ender = ']'; - - Lookup_Ender: - embed = 1; - starter = *cur++; - token->start = cur; - - while ( cur < limit ) - { - if ( *cur == starter ) - embed++; - else if ( *cur == ender ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = cur++; - break; - } - } - cur++; - } - break; - - /* **************** otherwise, it is any token **********/ - default: - token->start = cur++; - token->type = t1_token_any; - while ( cur < limit && !IS_CID_SPACE( *cur ) ) - cur++; - - token->limit = cur; - } - - if ( !token->limit ) - { - token->start = 0; - token->type = t1_token_none; - } - - parser->cursor = cur; - } - } - - - LOCAL_FUNC - void CID_ToTokenArray( CID_Parser* parser, - CID_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) - { - CID_Token_Rec master; - - - *pnum_tokens = -1; - - CID_ToToken( parser, &master ); - - if ( master.type == t1_token_array ) - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - CID_Token_Rec* cur = tokens; - CID_Token_Rec* limit = cur + max_tokens; - - - parser->cursor = master.start; - parser->limit = master.limit; - - while ( parser->cursor < parser->limit ) - { - CID_Token_Rec token; - - - CID_ToToken( parser, &token ); - if ( !token.type ) - break; - - if ( cur < limit ) - *cur = token; - - cur++; - } - - *pnum_tokens = cur - tokens; - - parser->cursor = old_cursor; - parser->limit = old_limit; - } - } - - - static - FT_Long t1_toint( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Long result = 0; - FT_Byte* cur = *cursor; - FT_Byte c, d; - - - for ( ; cur < limit; cur++ ) - { - c = *cur; - d = (FT_Byte)( c - '0' ); - if ( d < 10 ) - break; - - if ( c == '-' ) - { - cur++; - break; - } - } - - if ( cur < limit ) - { - do - { - d = (FT_Byte)( cur[0] - '0' ); - if ( d >= 10 ) - break; - - result = result * 10 + d; - cur++; - - } while ( cur < limit ); - - if ( c == '-' ) - result = -result; - } - - *cursor = cur; - - return result; - } - - - static - FT_Long t1_tofixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) - { - FT_Byte* cur = *cursor; - FT_Long num, divider, result; - FT_Int sign = 0; - FT_Byte d; - - - if ( cur >= limit ) - return 0; - - /* first of all, read the integer part */ - result = t1_toint( &cur, limit ) << 16; - num = 0; - divider = 1; - - if ( result < 0 ) - { - sign = 1; - result = -result; - } - - if ( cur >= limit ) - goto Exit; - - /* read decimal part, if any */ - if ( *cur == '.' && cur + 1 < limit ) - { - cur++; - - for (;;) - { - d = (FT_Byte)( *cur - '0' ); - if ( d >= 10 ) - break; - - if ( divider < 10000000L ) - { - num = num * 10 + d; - divider *= 10; - } - - cur++; - if ( cur >= limit ) - break; - } - } - - /* read exponent, if any */ - if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) - { - cur++; - power_ten += t1_toint( &cur, limit ); - } - - Exit: - /* raise to power of ten if needed */ - while ( power_ten > 0 ) - { - result = result * 10; - num = num * 10; - power_ten--; - } - - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - power_ten++; - } - - if ( num ) - result += FT_DivFix( num, divider ); - - if ( sign ) - result = -result; - - *cursor = cur; - - return result; - } - - - static - int t1_tobool( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Byte* cur = *cursor; - FT_Bool result = 0; - - - /* return 1 if we find a "true", 0 otherwise */ - if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) - { - result = 1; - cur += 5; - } - else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) - { - result = 0; - cur += 6; - } - *cursor = cur; - return result; - } - - - static - FT_Int t1_tocoordarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. */ - /* If not, only one number will be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the coordinates */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_coords || c == ender ) - break; - - coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - - static - FT_Int t1_tofixedarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. */ - /* If not, only one number will be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the values */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_values || c == ender ) - break; - - values[count] = t1_tofixed( &cur, limit, power_ten ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - - return count; - } - - - /* Loads a simple field (i.e. non-table) into the current */ - /* list of objects */ - LOCAL_FUNC - FT_Error CID_Load_Field( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ) - { - CID_Token_Rec token; - FT_Byte* cur; - FT_Byte* limit; - FT_UInt count; - FT_UInt index; - FT_Error error; - - - CID_ToToken( parser, &token ); - if ( !token.type ) - goto Fail; - - count = 1; - index = 0; - cur = token.start; - limit = token.limit; - - { - FT_Byte* q = (FT_Byte*)object + field->offset; - FT_Long val; - FT_String* string; - - - switch ( field->type ) - { - case t1_field_bool: - val = t1_tobool( &cur, limit ); - goto Store_Integer; - - case t1_field_fixed: - val = t1_tofixed( &cur, limit, 0 ); - goto Store_Integer; - - case t1_field_integer: - val = t1_toint( &cur, limit ); - - Store_Integer: - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_UShort*)q = (FT_UShort)val; - break; - - case 4: - *(FT_Int32*)q = (FT_Int)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - break; - - case t1_field_string: - { - FT_Memory memory = parser->memory; - FT_UInt len = limit-cur; - - - if ( ALLOC( string, len + 1 ) ) - goto Exit; - - MEM_Copy( string, cur, len ); - string[len] = 0; - - *(FT_String**)q = string; - } - break; - - default: - /* an error occurred */ - goto Fail; - } - } - - error = 0; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - -#define T1_MAX_TABLE_ELEMENTS 32 - - - LOCAL_FUNC - FT_Error CID_Load_Field_Table( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ) - { - CID_Token_Rec elements[T1_MAX_TABLE_ELEMENTS]; - CID_Token_Rec* token; - FT_Int num_elements; - FT_Error error = 0; - FT_Byte* old_cursor; - FT_Byte* old_limit; - CID_Field_Rec fieldrec = *(CID_Field_Rec*)field; - - - fieldrec.type = t1_field_integer; - if ( field->type == t1_field_fixed_array ) - fieldrec.type = t1_field_fixed; - - CID_ToTokenArray( parser, elements, 32, &num_elements ); - if ( num_elements < 0 ) - goto Fail; - - if ( num_elements > T1_MAX_TABLE_ELEMENTS ) - num_elements = T1_MAX_TABLE_ELEMENTS; - - old_cursor = parser->cursor; - old_limit = parser->limit; - - /* we store the elements count */ - if ( field->count_offset ) - *(FT_Byte*)( (FT_Byte*)object + field->count_offset ) = num_elements; - - /* we now load each element, adjusting the field.offset on each one */ - token = elements; - for ( ; num_elements > 0; num_elements--, token++ ) - { - parser->cursor = token->start; - parser->limit = token->limit; - CID_Load_Field( parser, &fieldrec, object ); - fieldrec.offset += fieldrec.size; - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - - LOCAL_FUNC - FT_Long CID_ToInt( CID_Parser* parser ) - { - return t1_toint( &parser->cursor, parser->limit ); - } - - - LOCAL_FUNC - FT_Int CID_ToCoordArray( CID_Parser* parser, - FT_Int max_coords, - FT_Short* coords ) - { - return t1_tocoordarray( &parser->cursor, parser->limit, - max_coords, coords ); - } - - - LOCAL_FUNC - FT_Int CID_ToFixedArray( CID_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - return t1_tofixedarray( &parser->cursor, parser->limit, - max_values, values, power_ten ); - } - - -#if 0 - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - -#endif /* 0 */ - - - LOCAL_FUNC - FT_Error CID_New_Parser( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory ) - { - FT_Error error; - FT_ULong base_offset, offset, ps_len; - FT_Byte buffer[256 + 10]; - FT_Int buff_len; - - - MEM_Set( parser, 0, sizeof ( *parser ) ); - parser->stream = stream; - parser->memory = memory; - - base_offset = FILE_Pos(); - - /* first of all, check the font format in the header */ - if ( ACCESS_Frame( 31 ) ) - goto Exit; - - if ( strncmp( (char *)stream->cursor, - "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) - { - FT_TRACE2(( "[not a valid CID-keyed font]\n" )); - error = FT_Err_Unknown_File_Format; - } - - FORGET_Frame(); - if ( error ) - goto Exit; - - /* now, read the rest of the file, until we find a `StartData' */ - buff_len = 256; - for (;;) - { - FT_Byte *p, *limit = buffer + 256; - - /* fill input buffer */ - buff_len -= 256; - if ( buff_len > 0 ) - MEM_Move( buffer, limit, buff_len ); - - if ( FILE_Read( buffer, 256 + 10 - buff_len ) ) - goto Exit; - - buff_len = 256 + 10; - - /* look for `StartData' */ - for ( p = buffer; p < limit; p++ ) - { - if ( p[0] == 'S' && strncmp( (char*)p, "StartData", 9 ) == 0 ) - { - /* save offset of binary data after `StartData' */ - offset = FILE_Pos() - ( limit - p ) + 10; - goto Found; - } - } - } - - Found: - /* we have found the start of the binary data. We will now */ - /* rewind and extract the frame of corresponding to the Postscript */ - /* section */ - - ps_len = offset - base_offset; - if ( FILE_Seek( base_offset ) || - EXTRACT_Frame( ps_len, parser->postscript ) ) - goto Exit; - - parser->data_offset = offset; - parser->postscript_len = ps_len; - parser->cursor = parser->postscript; - parser->limit = parser->cursor + ps_len; - parser->num_dict = -1; - - Exit: - return error; - } - - - LOCAL_FUNC - void CID_Done_Parser( CID_Parser* parser ) - { - /* always free the private dictionary */ - if ( parser->postscript ) - { - FT_Stream stream = parser->stream; - - - RELEASE_Frame( parser->postscript ); - } - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidparse.h b/subsys/win32k/freetype/src/cid/cidparse.h deleted file mode 100644 index 7a8211a..0000000 --- a/subsys/win32k/freetype/src/cid/cidparse.h +++ /dev/null @@ -1,353 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidparse.h */ -/* */ -/* CID-keyed Type1 parser (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDPARSE_H -#define CIDPARSE_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* CID_Table */ - /* */ - /* */ - /* A CID_Table is a simple object used to store an array of objects */ - /* in a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to the use */ - /* of `realloc()'. */ - /* */ - /* cursor :: The current top of the growheap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* blocks of 1 kByte. */ - /* */ - /* init :: A boolean. Set when the table has been initialized */ - /* (the table user should set this field). */ - /* */ - /* max_elems :: The maximal number of elements in the table. */ - /* */ - /* num_elems :: The current number of elements (in use) in the table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The memory object used for memory operations */ - /* (allocation resp. reallocation). */ - /* */ - typedef struct CID_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - FT_Long init; - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } CID_Table; - - - LOCAL_DEF - FT_Error CID_New_Table( CID_Table* table, - FT_Int count, - CID_Memory memory ); - - LOCAL_DEF - FT_Error CID_Add_Table( CID_Table* table, - FT_Int index, - void* object, - FT_Int length ); - - LOCAL_DEF - void CID_Release_Table( CID_Table* table ); - -#endif /* 0 */ - - - /*************************************************************************/ - /* */ - /* */ - /* CID_Parser */ - /* */ - /* */ - /* A CID_Parser is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* postscript :: A pointer to the data to be parsed. */ - /* */ - /* postscript_len :: The length of the data to be parsed. */ - /* */ - /* data_offset :: The start position of the binary data (i.e., the */ - /* end of the data to be parsed. */ - /* */ - /* cursor :: The current parser cursor. */ - /* */ - /* limit :: The current parser limit (i.e., the first byte */ - /* after the current dictionary). */ - /* */ - /* error :: The current parsing error. */ - /* */ - /* cid :: A structure which holds the information about */ - /* the current font. */ - /* */ - /* num_dict :: The number of font dictionaries. */ - /* */ - typedef struct CID_Parser_ - { - FT_Stream stream; - FT_Memory memory; - - FT_Byte* postscript; - FT_Int postscript_len; - - FT_ULong data_offset; - - FT_Byte* cursor; - FT_Byte* limit; - FT_Error error; - - CID_Info* cid; - FT_Int num_dict; - - } CID_Parser; - - - LOCAL_DEF - FT_Error CID_New_Parser( CID_Parser* parser, - FT_Stream stream, - FT_Memory memory ); - - LOCAL_DEF - void CID_Done_Parser( CID_Parser* parser ); - - - /*************************************************************************/ - /* */ - /* PARSING ROUTINES */ - /* */ - /*************************************************************************/ - - LOCAL_DEF - FT_Long CID_ToInt( CID_Parser* parser ); - - LOCAL_DEF - FT_Int CID_ToCoordArray( CID_Parser* parser, - FT_Int max_coords, - FT_Short* coords ); - - LOCAL_DEF - FT_Int CID_ToFixedArray( CID_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); - - LOCAL_DEF - void CID_Skip_Spaces( CID_Parser* parser ); - - - /* simple enumeration type used to identify token types */ - typedef enum CID_Token_Type_ - { - t1_token_none = 0, - t1_token_any, - t1_token_string, - t1_token_array, - - /* do not remove */ - t1_token_max - - } CID_Token_Type; - - - /* a simple structure used to identify tokens */ - typedef struct CID_Token_Rec_ - { - FT_Byte* start; /* first character of token in input stream */ - FT_Byte* limit; /* first character after the token */ - CID_Token_Type type; /* type of token */ - - } CID_Token_Rec; - - - LOCAL_DEF - void CID_ToToken( CID_Parser* parser, - CID_Token_Rec* token ); - - - /* enumeration type used to identify object fields */ - typedef enum CID_Field_Type_ - { - t1_field_none = 0, - t1_field_bool, - t1_field_integer, - t1_field_fixed, - t1_field_string, - t1_field_integer_array, - t1_field_fixed_array, - t1_field_callback, - - /* do not remove */ - t1_field_max - - } CID_Field_Type; - - typedef enum CID_Field_Location_ - { - t1_field_cid_info, - t1_field_font_dict, - t1_field_font_info, - t1_field_private, - - /* do not remove */ - t1_field_location_max - - } CID_Field_Location; - - - typedef FT_Error (*CID_Field_Parser)( CID_Face face, - CID_Parser* parser ); - - /* structure type used to model object fields */ - typedef struct CID_Field_Rec_ - { - const char* ident; /* field identifier */ - CID_Field_Location location; - CID_Field_Type type; /* type of field */ - CID_Field_Parser reader; - FT_UInt offset; /* offset of field in object */ - FT_UInt size; /* size of field in bytes */ - FT_UInt array_max; /* maximal number of elements for */ - /* array */ - FT_UInt count_offset; /* offset of element count for */ - /* arrays */ - } CID_Field_Rec; - - -#define CID_FIELD_REF( s, f ) ( ((s*)0)->f ) - -#define CID_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - (FT_UInt)(char*)&CID_FIELD_REF( T1TYPE, _fname ), \ - sizeof ( CID_FIELD_REF( T1TYPE, _fname ) ), \ - 0, 0 \ - }, - -#define CID_NEW_CALLBACK_FIELD( _ident, _reader ) \ - { \ - _ident, T1CODE, t1_field_callback, \ - _reader, \ - 0, 0, \ - 0, 0 \ - }, - -#define CID_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - (FT_UInt)(char*)&CID_FIELD_REF( T1TYPE, _fname ), \ - sizeof ( CID_FIELD_REF( T1TYPE, _fname )[0] ), \ - _max, \ - (FT_UInt)(char*)&CID_FIELD_REF( T1TYPE, num_ ## _fname ) \ - }, - -#define CID_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ - { \ - _ident, T1CODE, _type, \ - 0, \ - (FT_UInt)(char*)&CID_FIELD_REF( T1TYPE, _fname ), \ - sizeof ( CID_FIELD_REF( T1TYPE, _fname )[0] ), \ - _max, 0 \ - }, - - -#define CID_FIELD_BOOL( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_bool, _fname ) - -#define CID_FIELD_NUM( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_integer, _fname ) - -#define CID_FIELD_FIXED( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_fixed, _fname ) - -#define CID_FIELD_STRING( _ident, _fname ) \ - CID_NEW_SIMPLE_FIELD( _ident, t1_field_string, _fname ) - -#define CID_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD( _ident, t1_field_integer_array, \ - _fname, _fmax ) - -#define CID_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD( _ident, t1_field_fixed_array, \ - _fname, _fmax ) - -#define CID_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD2( _ident, t1_field_integer_array, \ - _fname, _fmax ) - -#define CID_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ - CID_NEW_TABLE_FIELD2( _ident, t1_field_fixed_array, \ - _fname, _fmax ) - -#define CID_FIELD_CALLBACK( _ident, _name ) \ - CID_NEW_CALLBACK_FIELD( _ident, parse_ ## _name ) - - - LOCAL_DEF - FT_Error CID_Load_Field( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ); - - LOCAL_DEF - FT_Error CID_Load_Field_Table( CID_Parser* parser, - const CID_Field_Rec* field, - void* object ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* CIDPARSE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidriver.c b/subsys/win32k/freetype/src/cid/cidriver.c deleted file mode 100644 index 0f2bdff..0000000 --- a/subsys/win32k/freetype/src/cid/cidriver.c +++ /dev/null @@ -1,259 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidriver.c */ -/* */ -/* CID driver interface (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "cidriver.h" -#include "cidgload.h" - -#else - -#include -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ciddriver - - - static - FT_Module_Interface CID_Get_Interface( FT_Driver driver, - const FT_String* interface ) - { - FT_UNUSED( driver ); - FT_UNUSED( interface ); - - return 0; - } - - -#if 0 /* unimplemented yet */ - - static - FT_Error cid_Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - CID_AFM* afm; - - - kerning->x = 0; - kerning->y = 0; - - afm = (CID_AFM*)face->afm_data; - if ( afm ) - CID_Get_Kerning( afm, left_glyph, right_glyph, kerning ); - - return T1_Err_Ok; - } - - -#endif /* 0 */ - - - /*************************************************************************/ - /* */ - /* */ - /* Cid_Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt CID_Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) - { - T1_Face face; - FT_UInt result = 0; - PSNames_Interface* psnames; - - - face = (T1_Face)charmap->face; - psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) - { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph. */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - } - - Exit: - return result; - } - - - const FT_Driver_Class t1cid_driver_class = - { - /* first of all, the FT_Module_Class fields */ - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( FT_DriverRec ), - "t1cid", /* module name */ - 0x10000L, /* version 1.0 of driver */ - 0x20000L, /* requires FreeType 2.0 */ - - 0, - - (FT_Module_Constructor)CID_Init_Driver, - (FT_Module_Destructor) CID_Done_Driver, - (FT_Module_Requester) CID_Get_Interface - }, - - /* then the other font drivers fields */ - sizeof( CID_FaceRec ), - sizeof( CID_SizeRec ), - sizeof( CID_GlyphSlotRec ), - - (FTDriver_initFace) CID_Init_Face, - (FTDriver_doneFace) CID_Done_Face, - - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes)0, - - (FTDriver_loadGlyph) CID_Load_Glyph, - (FTDriver_getCharIndex) CID_Get_Char_Index, - - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, - - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverClass */ - /* */ - /* */ - /* This function is used when compiling the TrueType driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( FT_Driver_Class* ) getDriverClass( void ) - { - return &t1cid_driver_class; - } - - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidriver.h b/subsys/win32k/freetype/src/cid/cidriver.h deleted file mode 100644 index a9674ee..0000000 --- a/subsys/win32k/freetype/src/cid/cidriver.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidriver.h */ -/* */ -/* High-level CID driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 CIDRIVER_H -#define CIDRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) t1cid_driver_class; - -#endif /* CIDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/cidtokens.h b/subsys/win32k/freetype/src/cid/cidtokens.h deleted file mode 100644 index a916cea..0000000 --- a/subsys/win32k/freetype/src/cid/cidtokens.h +++ /dev/null @@ -1,99 +0,0 @@ -/***************************************************************************/ -/* */ -/* cidtokens.h */ -/* */ -/* CID token definitions (specification only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#undef T1TYPE -#undef T1CODE -#define T1TYPE CID_Info -#define T1CODE t1_field_cid_info - - CID_FIELD_STRING ( "CIDFontName", cid_font_name ) - CID_FIELD_NUM ( "CIDFontVersion", cid_version ) - CID_FIELD_NUM ( "CIDFontType", cid_font_type ) - CID_FIELD_STRING ( "Registry", registry ) - CID_FIELD_STRING ( "Ordering", ordering ) - CID_FIELD_NUM ( "Supplement", supplement ) - CID_FIELD_CALLBACK( "FontBBox", font_bbox ) - CID_FIELD_NUM ( "UIDBase", uid_base ) - CID_FIELD_CALLBACK( "FDArray", fd_array ) - CID_FIELD_NUM ( "CIDMapOffset", cidmap_offset ) - CID_FIELD_NUM ( "FDBytes", fd_bytes ) - CID_FIELD_NUM ( "GDBytes", gd_bytes ) - CID_FIELD_NUM ( "CIDCount", cid_count ) - - -#undef T1TYPE -#undef T1CODE -#define T1TYPE T1_FontInfo -#define T1CODE t1_field_font_info - - CID_FIELD_STRING( "version", version ) - CID_FIELD_STRING( "Notice", notice ) - CID_FIELD_STRING( "FullName", full_name ) - CID_FIELD_STRING( "FamilyName", family_name ) - CID_FIELD_STRING( "Weight", weight ) - CID_FIELD_FIXED ( "ItalicAngle", italic_angle ) - CID_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch ) - CID_FIELD_NUM ( "UnderlinePosition", underline_position ) - CID_FIELD_NUM ( "UnderlineThickness", underline_thickness ) - - -#undef T1TYPE -#undef T1CODE -#define T1TYPE CID_FontDict -#define T1CODE t1_field_font_dict - - CID_FIELD_CALLBACK( "FontMatrix", font_matrix ) - CID_FIELD_NUM ( "PaintType", paint_type ) - CID_FIELD_NUM ( "FontType", font_type ) - CID_FIELD_NUM ( "SubrMapOffset", subrmap_offset ) - CID_FIELD_NUM ( "SDBytes", sd_bytes ) - CID_FIELD_NUM ( "SubrCount", num_subrs ) - CID_FIELD_NUM ( "lenBuildCharArray", len_buildchar ) - CID_FIELD_FIXED ( "ForceBoldThreshold", forcebold_threshold ) - CID_FIELD_FIXED ( "ExpansionFactor", expansion_factor ) - CID_FIELD_NUM ( "StrokeWidth", stroke_width ) - - -#undef T1TYPE -#undef T1CODE -#define T1TYPE T1_Private -#define T1CODE t1_field_private - - CID_FIELD_NUM ( "UniqueID", unique_id ) - CID_FIELD_NUM ( "lenIV", lenIV ) - CID_FIELD_NUM ( "LanguageGroup", language_group ) - CID_FIELD_NUM ( "password", password ) - - CID_FIELD_FIXED ( "BlueScale", blue_scale ) - CID_FIELD_NUM ( "BlueShift", blue_shift ) - CID_FIELD_NUM ( "BlueFuzz", blue_fuzz ) - - CID_FIELD_NUM_TABLE ( "BlueValues", blue_values, 14 ) - CID_FIELD_NUM_TABLE ( "OtherBlues", other_blues, 10 ) - CID_FIELD_NUM_TABLE ( "FamilyBlues", family_blues, 14 ) - CID_FIELD_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10 ) - - CID_FIELD_NUM_TABLE2( "StdHW", standard_width, 1 ) - CID_FIELD_NUM_TABLE2( "StdVW", standard_height, 1 ) - CID_FIELD_NUM_TABLE2( "MinFeature", min_feature, 2 ) - - CID_FIELD_NUM_TABLE ( "StemSnapH", snap_widths, 12 ) - CID_FIELD_NUM_TABLE ( "StemSnapV", snap_heights, 12 ) - - -/* END */ diff --git a/subsys/win32k/freetype/src/cid/module.mk b/subsys/win32k/freetype/src/cid/module.mk deleted file mode 100644 index 3d13c9c..0000000 --- a/subsys/win32k/freetype/src/cid/module.mk +++ /dev/null @@ -1,6 +0,0 @@ -make_module_list: add_type1cid_driver - -add_type1cid_driver: - $(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)cid $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE) -# EOF diff --git a/subsys/win32k/freetype/src/cid/rules.mk b/subsys/win32k/freetype/src/cid/rules.mk deleted file mode 100644 index cbaaec7..0000000 --- a/subsys/win32k/freetype/src/cid/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 CID driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# CID driver directory -# -CID_DIR := $(SRC_)cid -CID_DIR_ := $(CID_DIR)$(SEP) - - -CID_COMPILE := $(FT_COMPILE) - - -# CID driver sources (i.e., C files) -# -CID_DRV_SRC := $(CID_DIR_)cidparse.c \ - $(CID_DIR_)cidload.c \ - $(CID_DIR_)cidriver.c \ - $(CID_DIR_)cidgload.c \ - $(CID_DIR_)cidobjs.c - -# CID driver headers -# -CID_DRV_H := $(CID_DRV_SRC:%.c=%.h) \ - $(CID_DIR_)cidtokens.h - - -# CID driver object(s) -# -# CID_DRV_OBJ_M is used during `multi' builds -# CID_DRV_OBJ_S is used during `single' builds -# -CID_DRV_OBJ_M := $(CID_DRV_SRC:$(CID_DIR_)%.c=$(OBJ_)%.$O) -CID_DRV_OBJ_S := $(OBJ_)type1cid.$O - -# CID driver source file for single build -# -CID_DRV_SRC_S := $(CID_DIR_)type1cid.c - - -# CID driver - single object -# -$(CID_DRV_OBJ_S): $(CID_DRV_SRC_S) $(CID_DRV_SRC) $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$@ $(CID_DRV_SRC_S) - - -# CID driver - multiple objects -# -$(OBJ_)%.$O: $(CID_DIR_)%.c $(FREETYPE_H) $(CID_DRV_H) - $(CID_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(CID_DRV_OBJ_S) -DRV_OBJS_M += $(CID_DRV_OBJ_M) - -# EOF diff --git a/subsys/win32k/freetype/src/cid/type1cid.c b/subsys/win32k/freetype/src/cid/type1cid.c deleted file mode 100644 index 5f69c6a..0000000 --- a/subsys/win32k/freetype/src/cid/type1cid.c +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* cff.c */ -/* */ -/* FreeType OpenType driver component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#ifdef FT_FLAT_COMPILE - -#include "cidparse.c" -#include "cidload.c" -#include "cidobjs.c" -#include "cidriver.c" -#include "cidgload.c" - -#else - -#include -#include -#include -#include -#include - -#endif - - -/* END */ diff --git a/subsys/win32k/freetype/src/macfond/.cvsignore b/subsys/win32k/freetype/src/macfond/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/macfond/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/macfond/fonddrvr.c b/subsys/win32k/freetype/src/macfond/fonddrvr.c deleted file mode 100644 index 45a9141..0000000 --- a/subsys/win32k/freetype/src/macfond/fonddrvr.c +++ /dev/null @@ -1,616 +0,0 @@ -/***************************************************************************/ -/* */ -/* fonddrvr.c */ -/* */ -/* Mac FOND font driver. Written by just@letterror.com. */ -/* */ -/* Copyright 1996-2000 by */ -/* Just van Rossum, 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 - - Mac suitcase files can (and often do!) contain multiple fonts. To - support this I use the face_index argument of FT_(Open|New)_Face() - functions, and pretend the suitcase file is a collection. - Warning: although the FOND driver sets face->num_faces field to the - number of available fonts, but the Type 1 driver sets it to 1 anyway. - So this field is currently not reliable, and I don't see a clean way - to resolve that. The face_index argument translates to - Get1IndResource( 'FOND', face_index + 1 ); - so clients should figure out the resource index of the FOND. - (I'll try to provide some example code for this at some point.) - - The Mac FOND driver works roughly like this: - - - Check whether the offered stream points to a Mac suitcase file. - This is done by checking the file type: it has to be 'FFIL' or 'tfil'. - The stream that gets passed to our init_face() routine is a stdio - stream, which isn't usable for us, since the FOND resources live - in the resource fork. So we just grab the stream->pathname field. - - - Read the FOND resource into memory, then check whether there is - a TrueType font and/or (!) a Type 1 font available. - - - If there is a Type 1 font available (as a separate 'LWFN' file), - read its data into memory, massage it slightly so it becomes - PFB data, wrap it into a memory stream, load the Type 1 driver - and delegate the rest of the work to it, by calling the init_face() - method of the Type 1 driver. - (XXX TODO: after this has been done, the kerning data from the FOND - resource should be appended to the face: on the Mac there are usually - no AFM files available. However, this is tricky since we need to map - Mac char codes to ps glyph names to glyph ID's...) - - - If there is a TrueType font (an 'sfnt' resource), read it into - memory, wrap it into a memory stream, load the TrueType driver - and delegate the rest of the work to it, by calling the init_face() - method if the TrueType driver. - - - In both cases, the original stream gets closed and *reinitialized* - to become a memory stream. Additionally, the face->driver field -- - which is set to the FOND driver upon entering our init_face() -- - gets *reset* to either the TT or the T1 driver. I had to make a minor - change to ftobjs.c to make this work. - - - We might consider creating an FT_New_Face_Mac() API call, as this - would avoid some of the mess described above. -*/ - -#include -#include - -#include -#include -#include - -#include /* for isupper() and isalnum() */ -#include /* for malloc() and free() */ - - -/* set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over - TrueType in case *both* are available */ -#ifndef PREFER_LWFN -#define PREFER_LWFN 1 -#endif - - - static - FT_Error init_driver( FT_Driver driver ) - { - /* we don't keep no stinkin' state ;-) */ - return FT_Err_Ok; - } - - static - FT_Error done_driver( FT_Driver driver ) - { - return FT_Err_Ok; - } - - - /* MacRoman glyph names, needed for FOND kerning support. */ - /* XXX which is not implemented yet! */ - static const char* mac_roman_glyph_names[256] = { - ".null", - }; - - - /* The FOND face object is just a union of TT and T1: both is possible, - and we don't need anything else. We still need to be able to hold - either, as the face object is not allocated by us. Again, creating - an FT_New_Face_Mac() would avoid this kludge. */ - typedef union FOND_FaceRec_ - { - TT_FaceRec tt; - T1_FaceRec t1; - } FOND_FaceRec, *FOND_Face; - - - /* given a pathname, fill in a File Spec */ - static - int make_file_spec( char* pathname, FSSpec *spec ) - { - Str255 p_path; - int path_len; - - /* convert path to a pascal string */ - path_len = strlen( pathname ); - if ( path_len > 255 ) - return -1; - p_path[0] = path_len; - strncpy( (char*)p_path+1, pathname, path_len ); - - if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr ) - return -1; - else - return 0; - } - - - /* is_suitcase() returns true if the file specified by 'pathname' - is a Mac suitcase file, and false if it ain't. */ - static - int is_suitcase( FSSpec *spec ) - { - FInfo finfo; - - if ( FSpGetFInfo( spec, &finfo ) != noErr ) - return 0; - if ( finfo.fdType == 'FFIL' || finfo.fdType == 'tfil' ) - return 1; - else - return 0; - } - - - /* Quick 'n' Dirty Pascal string to C string converter. - Warning: this call is not thread safe! Use with caution. */ - static - char * p2c_str( unsigned char *pstr ) - { - static char cstr[256]; - - strncpy( cstr, (char*)pstr+1, pstr[0] ); - cstr[pstr[0]] = '\0'; - return cstr; - } - - - /* Given a PostScript font name, create the Macintosh LWFN file name */ - static - void create_lwfn_name( char* ps_name, Str255 lwfn_file_name ) - { - int max = 5, count = 0; - unsigned char* p = lwfn_file_name; - char* q = ps_name; - - lwfn_file_name[0] = 0; - - while ( *q ) - { - if ( isupper(*q) ) - { - if ( count ) - max = 3; - count = 0; - } - if ( count < max && (isalnum(*q) || *q == '_' ) ) - { - *++p = *q; - lwfn_file_name[0]++; - count++; - } - q++; - } - } - - - /* Suck the relevant info out of the FOND data */ - static - FT_Error parse_fond( char* fond_data, - short *have_sfnt, - short *sfnt_id, - Str255 lwfn_file_name ) - { - AsscEntry* assoc; - FamRec* fond; - - *sfnt_id = *have_sfnt = 0; - lwfn_file_name[0] = 0; - - fond = (FamRec*)fond_data; - assoc = (AsscEntry*)(fond_data + sizeof(FamRec) + 2); - - if ( assoc->fontSize == 0 ) - { - *have_sfnt = 1; - *sfnt_id = assoc->fontID; - } - - if ( fond->ffStylOff ) - { - unsigned char* p = (unsigned char*)fond_data; - StyleTable* style; - unsigned short string_count; - unsigned char* name_table = 0; - char ps_name[256]; - unsigned char* names[64]; - int i; - - p += fond->ffStylOff; - style = (StyleTable*)p; - p += sizeof(StyleTable); - string_count = *(unsigned short*)(p); - p += sizeof(short); - - for ( i=0 ; iindexes[0] > 1 ) - { - unsigned char* suffixes = names[style->indexes[0]-1]; - for ( i=1; i<=suffixes[0]; i++ ) - strcat( ps_name, p2c_str(names[suffixes[i]-1]) ); - } - create_lwfn_name( ps_name, lwfn_file_name ); - } - return FT_Err_Ok; - } - - - /* Read Type 1 data from the POST resources inside the LWFN file, return a - PFB buffer -- apparently FT doesn't like a pure binary T1 stream. */ - static - unsigned char* read_type1_data( FT_Memory memory, FSSpec* lwfn_spec, unsigned long *size ) - { - short res_ref, res_id; - unsigned char *buffer, *p, *size_p; - unsigned long total_size = 0; - unsigned long post_size, pfb_chunk_size; - Handle post_data; - char code, last_code; - - res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm ); - if ( ResError() ) - return NULL; - UseResFile( res_ref ); - - /* first pass: load all POST resources, and determine the size of - the output buffer */ - res_id = 501; - last_code = -1; - for (;;) - { - post_data = Get1Resource( 'POST', res_id++ ); - if ( post_data == NULL ) - break; - code = (*post_data)[0]; - if ( code != last_code ) - { - if ( code == 5 ) - total_size += 2; /* just the end code */ - else - total_size += 6; /* code + 4 bytes chunk length */ - } - total_size += GetHandleSize( post_data ) - 2; - last_code = code; - } - - buffer = memory->alloc( memory, total_size ); - if ( !buffer ) - goto error; - - /* second pass: append all POST data to the buffer, add PFB fields */ - p = buffer; - res_id = 501; - last_code = -1; - pfb_chunk_size = 0; - for (;;) - { - post_data = Get1Resource( 'POST', res_id++ ); - if ( post_data == NULL ) - break; - post_size = GetHandleSize( post_data ) - 2; - code = (*post_data)[0]; - if ( code != last_code ) - { - if ( last_code != -1 ) - { - /* we're done adding a chunk, fill in the size field */ - *size_p++ = pfb_chunk_size & 0xFF; - *size_p++ = (pfb_chunk_size >> 8) & 0xFF; - *size_p++ = (pfb_chunk_size >> 16) & 0xFF; - *size_p++ = (pfb_chunk_size >> 24) & 0xFF; - pfb_chunk_size = 0; - } - *p++ = 0x80; - if ( code == 5 ) - *p++ = 0x03; /* the end */ - else if ( code == 2 ) - *p++ = 0x02; /* binary segment */ - else - *p++ = 0x01; /* ASCII segment */ - if ( code != 5 ) - { - size_p = p; /* save for later */ - p += 4; /* make space for size field */ - } - } - memcpy( p, *post_data + 2, post_size ); - pfb_chunk_size += post_size; - p += post_size; - last_code = code; - } - - CloseResFile( res_ref ); - - *size = total_size; -/* printf( "XXX %d %d\n", p - buffer, total_size ); */ - return buffer; - -error: - CloseResFile( res_ref ); - return NULL; - } - - - /* Finalizer for the sfnt stream */ - static - void sfnt_stream_close( FT_Stream stream ) - { - Handle sfnt_data = stream->descriptor.pointer; - HUnlock( sfnt_data ); - DisposeHandle( sfnt_data ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Finalizer for the LWFN stream */ - static - void lwfn_stream_close( FT_Stream stream ) - { - stream->memory->free( stream->memory, stream->base ); - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Main entry point. Determine whether we're dealing with a Mac - suitcase or not; then determine if we're dealing with Type 1 - or TrueType; delegate the work to the proper driver. */ - static - FT_Error init_face( FT_Stream stream, - FT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* parameters ) - { - FT_Error err; - FSSpec suit_spec, lwfn_spec; - short res_ref; - Handle fond_data, sfnt_data; - short res_index, sfnt_id, have_sfnt; - Str255 lwfn_file_name; - - if ( !stream->pathname.pointer ) - return FT_Err_Unknown_File_Format; - - if ( make_file_spec( stream->pathname.pointer, &suit_spec ) ) - return FT_Err_Invalid_Argument; - - if ( !is_suitcase( &suit_spec ) ) - return FT_Err_Unknown_File_Format; - - res_ref = FSpOpenResFile( &suit_spec, fsRdPerm ); - if ( ResError() ) - return FT_Err_Invalid_File_Format; - UseResFile( res_ref ); - - /* face_index may be -1, in which case we - just need to do a sanity check */ - if ( face_index < 0) - res_index = 1; - else - { - res_index = face_index + 1; - face_index = 0; - } - fond_data = Get1IndResource( 'FOND', res_index ); - if ( ResError() ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_File_Format; - } - /* Set the number of faces. Not that it helps much: the t1 driver - just sets it to 1 anyway :-( */ - face->num_faces = Count1Resources('FOND'); - - HLock( fond_data ); - err = parse_fond( *fond_data, &have_sfnt, &sfnt_id, lwfn_file_name ); - HUnlock( fond_data ); - if ( err ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_Handle; - } - - if ( lwfn_file_name[0] ) - { - /* We look for the LWFN file in the same directory as the suitcase - file. ATM would look in other places, too, but this is the usual - situation. */ - err = FSMakeFSSpec( suit_spec.vRefNum, suit_spec.parID, lwfn_file_name, &lwfn_spec ); - if ( err != noErr ) - lwfn_file_name[0] = 0; /* no LWFN file found */ - } - - if ( lwfn_file_name[0] && ( !have_sfnt || PREFER_LWFN ) ) - { - FT_Driver t1_driver; - unsigned char* type1_data; - unsigned long size; - - CloseResFile( res_ref ); /* XXX still need to read kerning! */ - - type1_data = read_type1_data( stream->memory, &lwfn_spec, &size ); - if ( !type1_data ) - { - return FT_Err_Out_Of_Memory; - } - -#if 0 - { - FILE* f; - char * path; - - path = p2c_str( lwfn_file_name ); - strcat( path, ".PFB" ); - f = fopen(path, "wb"); - if ( f ) - { - fwrite( type1_data, 1, size, f ); - fclose( f ); - } - } -#endif - - /* reinitialize the stream */ - if ( stream->close ) - stream->close( stream ); - stream->close = lwfn_stream_close; - stream->read = 0; /* it's now memory based */ - stream->base = type1_data; - stream->size = size; - stream->pos = 0; /* just in case */ - - /* delegate the work to the Type 1 module */ - t1_driver = (FT_Driver)FT_Get_Module( face->driver->root.library, "type1z" ); - if ( t1_driver ) - { - face->driver = t1_driver; - return t1_driver->clazz->init_face( stream, face, face_index, 0, NULL ); - } - else - return FT_Err_Invalid_Driver_Handle; - } - else if ( have_sfnt ) - { - FT_Driver tt_driver; - - sfnt_data = Get1Resource( 'sfnt', sfnt_id ); - if ( ResError() ) - { - CloseResFile( res_ref ); - return FT_Err_Invalid_Handle; - } - DetachResource( sfnt_data ); - CloseResFile( res_ref ); - HLockHi( sfnt_data ); - - /* reinitialize the stream */ - if ( stream->close ) - stream->close( stream ); - stream->close = sfnt_stream_close; - stream->descriptor.pointer = sfnt_data; - stream->read = 0; /* it's now memory based */ - stream->base = (unsigned char *)*sfnt_data; - stream->size = GetHandleSize( sfnt_data ); - stream->pos = 0; /* just in case */ - - /* delegate the work to the TrueType driver */ - tt_driver = (FT_Driver)FT_Get_Module( face->driver->root.library, "truetype" ); - if ( tt_driver ) - { - face->driver = tt_driver; - return tt_driver->clazz->init_face( stream, face, face_index, 0, NULL ); - } - else - return FT_Err_Invalid_Driver_Handle; - } - else - { - CloseResFile( res_ref ); - } - return FT_Err_Invalid_File_Format; - } - - - static - void done_face( FT_Face face ) - { - /* nothing to do */ - } - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - - const FT_Driver_Class fond_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof ( FT_DriverRec ), - - "fond", /* driver name */ - 0x10000L, /* driver version == 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - (void*)0, - - (FT_Module_Constructor) init_driver, - (FT_Module_Destructor) done_driver, - (FT_Module_Requester) 0 - }, - - sizeof ( FOND_FaceRec ), - 0, - 0, - - (FTDriver_initFace) init_face, - (FTDriver_doneFace) done_face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot) 0, - (FTDriver_doneGlyphSlot) 0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes) 0, - (FTDriver_loadGlyph) 0, - (FTDriver_getCharIndex) 0, - - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the FOND driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - FT_EXPORT_FUNC(const FT_Driver_Class*) getDriverClass( void ) - { - return &fond_driver_class; - } - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/otlayout/.cvsignore b/subsys/win32k/freetype/src/otlayout/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/otlayout/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/otlayout/oltypes.c b/subsys/win32k/freetype/src/otlayout/oltypes.c deleted file mode 100644 index bd2fa22..0000000 --- a/subsys/win32k/freetype/src/otlayout/oltypes.c +++ /dev/null @@ -1,614 +0,0 @@ -#include - - LOCAL_FUNC - TT_Error OTL_Table_Init( OTL_Table* table, - FT_Memory memory ) - { - MEM_Set( table, 0, sizeof(*table) ); - table->memory = memory; - } - - /* read a script list table */ - /* use with any table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Scripts( OTL_Table* table, - TT_Byte* bytes, - TT_Long len, - OTL_Type otl_type ) - { - TT_Byte* p; - TT_Byte* start = bytes; - TT_UInt count, max_langs; - TT_Error error; - - /* skip version of the JSTF table */ - if (otl_type == otl_jstf) - start += 4; - - p = start; - - /* we must allocate the script_tags and language_tags arrays */ - /* this requires that we compute the maximum number of languages */ - /* per script.. */ - - count = table->num_scripts = OTL_UShort(p); - max_langs = 0; - for ( ; count > 0; count++ ) - { - TT_Byte* script; - TT_UInt num_langs; - - p += 4; /* skip tag */ - script = bytes + OTL_UShort(p); - - /* skip the baseValues or extenders field of the BASE and JSTF table */ - if (otl_type == otl_type_base || otl_type == otl_type_jstf) - script += 2; - - /* test if there is a default language system */ - if ( OTL_UShort(script) ) - num_langs++; - - /* test other language systems */ - num_langs += OTL_UShort(script); /* add other lang sys */ - - if (num_langs > max_langs) - max_langs = num_langs; - } - - /* good, now allocate the tag arrays */ - if ( !ALLOC_ARRAY( table->script_tags, - table->num_scripts + max_langs, - TT_ULong ) ) - { - table->language_tags = table->script_tags + table->num_scripts; - table->max_languages = max_langs; - table->num_languages = 0; - table->otl_type = otl_type; - - table->scripts_table = bytes; - table->scripts_len = len; - - /* fill the script_tags array */ - { - TT_UInt n; - TT_Byte* p = start + 2; /* skip count */ - - for ( n = 0; n < table->num_scripts; n++ ) - { - table->script_tags[n] = OTL_ULong(p); - p += 2; /* skip offset */ - } - } - } - return error; - } - - - - /* add a features list to the table */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Features( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ) - { - TT_Error error; - TT_Byte* p = bytes; - TT_UInt count; - - table->max_features = count = OTL_UShort(p); - if ( !ALLOC_ARRAY( table->feature_tags, count, TT_ULong ) && - !ALLOC_ARRAY( table->features, count, TT_Bool ) ) - { - table->features_table = bytes; - table->features_len = len; - } - return error; - } - - - /* add a lookup list to the table */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - TT_Error OTL_Table_Set_Lookups( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ) - { - TT_Error error; - TT_Byte* p = bytes; - TT_UInt count; - - table->max_lookups = count = OTL_UShort(p); - if ( !ALLOC_ARRAY( table->lookups, count, TT_Bool ) ) - { - table->lookups_table = bytes; - table->lookups_len = len; - } - return error; - } - - /* discard table arrays */ - LOCAL_FUNC - void OTL_Table_Done( OTL_Table* table ) - { - FREE( table->scrip_tags ); - FREE( table->language_tags ); - FREE( table->feature_tags ); - FREE( table->lookups ); - } - - - /* return the list of available languages for a given script */ - /* use with any table.. */ - LOCAL_FUNC - void OTL_Get_Languages_List( OTL_Table* table, - TT_ULong script_tag ) - { - TT_UInt n; - TT_Byte* p; - TT_Byte* script = 0; - TT_Byte* start = table->scripts_table; - - if ( table->otl_type == otl_type_jstf ) /* skip version for JSTF */ - start += 4; - - p = start + 6; /* skip count+first tag */ - - for ( n = 0; n < table->num_scripts; n++, p += 6 ) - { - if ( table->script_tags[n] == script_tag ) - { - script = table->scripts_table + OTL_UShort(p); - break; - } - } - - table->cur_script = script; - if (!script) - table->num_languages = 0; - else - { - /* now fill the language_tags array with the appropriate values */ - /* not that we put a '0' tag in front of the list to indicate that */ - /* there is a default language for this script.. */ - TT_ULong* tags = table->language_tags; - - switch (table->otl_type) - { - case otl_type_base: - case otl_type_jstf: - script += 2; /* skip basevalue or extenders */ - /* fall-through */ - - default: - if ( OTL_UShort(script) ) - *tags++ = 0; - } - - count = OTL_UShort(script); - for ( ; count > 0; count-- ) - { - *tags++ = OTL_ULong(script); - script += 2; /* skip offset */ - } - - table->num_langs = tags - table->language_tags; - } - } - - - /* return the list of available features for the current script/language */ - /* use with a GPOS or GSUB script table */ - LOCAL_FUNC - void OTL_Get_Features_List( OTL_Table* table, - TT_ULong language_tag ) - { - TT_UInt n; - TT_Byte* script = table->cur_script; - TT_Byte* language = 0; - TT_UShort offset; - - /* clear feature selection table */ - for ( n = 0; n < table->max_features; n++ ) - table->features[n] = 0; - - /* now, look for the current language */ - if ( language_tag == 0 ) - { - offset = OTL_UShort(script); - if (!offset) return; /* if there is no default language, exit */ - - language = script - 2 + offset; - } - else - { - TT_Byte* p = script + 8; /* skip default+count+1st tag */ - TT_UShort index; - - for ( n = 0; n < table->num_languages; n++, p+=6 ) - { - if ( table->language_tags[n] == language_tag ) - { - language = script + OTL_UShort(p); - break; - } - } - - table->cur_language = language; - if (!language) return; - - p = language + 2; /* skip lookup order */ - index = OTL_UShort(p); /* required feature index */ - if (index != 0xFFFF) - { - if (index < table->max_features) - table->features[index] = 1; - } - - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - index = OTL_UShort(p); - if (index < table->max_features) - table->features[index] = 1; - } - } - } - - - /* return the list of lookups for the current features list */ - /* use only with a GSUB or GPOS table */ - LOCAL_FUNC - void OTL_Get_Lookups_List( OTL_Table* table ) - { - TT_UInt n; - TT_Byte* features = table->features_table; - TT_Byte* p = features + 6; /* skip count+1st tag */ - - /* clear lookup list */ - for ( n = 0; n < table->max_lookups; n++ ) - table->lookups[n] = 0; - - /* now, parse the features list */ - for ( n = 0; n < table->features; n++ ) - { - if (table->features[n]) - { - TT_UInt count; - TT_UShort index; - TT_Byte* feature; - - feature = features + OTL_UShort(p); - p += 4; /* skip tag */ - - /* now, select all lookups from this feature */ - count = OTL_UShort(feature); - for ( ; count > 0; count-- ) - { - index = OTL_UShort(feature); - if (index < table->max_lookups) - table->lookups[index] = 1; - } - } - } - } - - - /* find the basevalues and minmax for the current script/language */ - /* only use it with a BASE table.. */ - LOCAL_FUNC - void OTL_Get_Baseline_Values( OTL_Table* table, - TT_ULong language_tag ) - { - TT_Byte* script = table->cur_script; - TT_Byte* p = script; - TT_UShort offset, count; - - table->cur_basevalues = 0; - table->cur_minmax = 0; - - /* read basevalues */ - offset = OTL_UShort(p); - if (offset) - table->cur_basevalues = script + offset; - - offset = OTL_UShort(p); - if (offset) - table->cur_minmax = script + offset; - - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - TT_ULong tag; - - tag = OTL_ULong(p); - if ( language_tag == tag ) - { - table->cur_minmax = script + OTL_UShort(p); - break; - } - p += 2; /* skip offset */ - } - } - - - /* compute the coverage value of a given glyph id */ - LOCAL_FUNC - TT_Long OTL_Get_Coverage_Index( TT_Byte* coverage, - TT_UInt glyph_id ) - { - TT_Long result = -1; - TT_UInt count, index, start, end; - TT_Byte* p = coverage; - - switch ( OTL_UShort(p) ) - { - case 1: /* coverage format 1 - array of glyph indices */ - { - count = OTL_UShort(p); - for ( index = 0; index < count; index++ ) - { - if ( OTL_UShort(p) == glyph_id ) - { - result = index; - break; - } - } - } - break; - - case 2: - { - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - start = OTL_UShort(p); - end = OTL_UShort(p); - index = OTL_UShort(p); - if (start <= glyph_id && glyph_id <= end) - { - result = glyph_id - start + index; - break; - } - } - } - break; - } - return result; - } - - - /* compute the class value of a given glyph_id */ - LOCAL_FUNC - TT_UInt OTL_Get_Glyph_Class( TT_Byte* class_def, - TT_UInt glyph_id ) - { - TT_Byte* p = class_def; - TT_UInt result = 0; - TT_UInt start, end, count, index; - - switch ( OTL_UShort(p) ) - { - case 1: - { - start = OTL_UShort(p); - count = OTL_UShort(p); - - glyph_id -= start; - if (glyph_id < count) - { - p += 2*glyph_id; - result = OTL_UShort(p); - } - } - break; - - case 2: - { - count = OTL_UShort(p); - for ( ; count > 0; count-- ) - { - start = OTL_UShort(p); - end = OTL_UShort(p); - index = OTL_UShort(p); - if ( start <= glyph_id && glyph_id <= end ) - { - result = index; - break; - } - } - } - break; - } - return result; - } - - - /* compute the adjustement necessary for a given device size */ - LOCAL_FUNC - TT_Int OTL_Get_Device_Adjustment( TT_Byte* device, - TT_UInt size ) - { - TT_Byte* p = device; - TT_Int result = 0; - TT_UInt start, end; - TT_Short value; - - start = OTL_UShort(p); - end = OTL_UShort(p); - if (size >= start && size <= end) - { - /* I know we could do all of this without a switch, with */ - /* clever shifts and everything, but it makes the code */ - /* really difficult to understand.. */ - - size -= start; - switch ( OTL_UShort(p) ) - { - case 1: /* 2-bits per value */ - { - p += 2*(size >> 3); - size = (size & 7) << 1; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 14; - } - break; - - case 2: /* 4-bits per value */ - { - p += 2*(size >> 2); - size = (size & 3) << 2; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 12; - } - break; - - case 3: /* 8-bits per value */ - { - p += 2*(size >> 1); - size = (size & 1) << 3; - value = (TT_Short)((TT_Short)OTL_UShort(p) << size); - result = value >> 8; - } - break; - } - } - return result; - } - - /* extract a BaseCoord value */ - LOCAL_FUNC - void OTL_Get_Base_Coordinate( TT_Byte* base_coord, - OTL_ValueRecord* coord ) - { - TT_Byte* p = base_coord; - TT_Int result = 0; - - coord->format = OTL_UShort(p); - coord->coordinate = OTL_Short(p); - coord->device = 0; - - switch (coord->format) - { - case 2: /* format 2 */ - coord->ref_glyph = OTL_UShort(p); - coord->ref_point = OTL_UShort(p); - break; - - case 3: /* format 3 */ - coord->device = p - 4 + OTL_UShort(p); - break; - - default: - ; - } - } - - - /* compute size of ValueRecord */ - LOCAL_FUNC - TT_Int OTL_ValueRecord_Size( TT_UShort format ) - { - TT_Int count; - - /* each bit in the value format corresponds to a single ushort */ - /* we thus count the bits, and multiply the result by 2 */ - - count = (TT_Int)(format & 0xFF); - count = ((count & 0xAA) >> 1) + (count & 0x55); - count = ((count & 0xCC) >> 2) + (count & 0x33); - count = ((count & 0xF0) >> 4) + (count & 0x0F); - - return count*2; - } - - - - /* extract ValueRecord */ - LOCAL_FUNC - void OTL_Get_ValueRecord( TT_Byte* value_record, - TT_UShort value_format, - TT_Byte* pos_table, - OTL_ValueRecord* record ) - { - TT_Byte* p = value_record; - - /* clear vectors */ - record->placement.x = 0; - record->placement.y = 0; - record->advance.x = 0; - record->advance.y = 0; - - record->device_pla_x = 0; - record->device_pla_y = 0; - record->device_adv_x = 0; - record->device_adv_y = 0; - - if (value_format & 1) record->placement.x = NEXT_Short(p); - if (value_format & 2) record->placement.y = NEXT_Short(p); - if (value_format & 4) record->advance.x = NEXT_Short(p); - if (value_format & 8) record->advance.y = NEXT_Short(p); - - if (value_format & 16) record->device_pla_x = pos_table + NEXT_UShort(p); - if (value_format & 32) record->device_pla_y = pos_table + NEXT_UShort(p); - if (value_format & 64) record->device_adv_x = pos_table + NEXT_UShort(p); - if (value_format & 128) record->device_adv_y = pos_table + NEXT_UShort(p); - } - - - - /* extract Anchor */ - LOCAL_FUNC - void OTL_Get_Anchor( TT_Byte* anchor_table, - OTL_Anchor* anchor ) - { - TT_Byte* p = anchor_table; - - anchor->format = NEXT_UShort(p); - anchor->coord.x = NEXT_Short(p); - anchor->coord.y = NEXT_Short(p); - anchor->point = 0; - anchor->device_x = 0; - anchor->device_y = 0; - - switch (anchor->format) - { - case 2: - anchor->point = NEXT_UShort(p); - break; - - case 3: - anchor->device_x = anchor_table + NEXT_UShort(p); - anchor->device_y = anchor_table + NEXT_UShort(p); - break; - - default: - ; - } - } - - - - /* extract Mark from MarkArray */ - LOCAL_FUNC - void OTL_Get_Mark( TT_Byte* mark_array, - TT_UInt index, - TT_UShort* clazz, - OTL_Anchor* anchor ) - { - TT_Byte* p = mark_array; - TT_UInt count; - - *clazz = 0; - MEM_Set( anchor, 0, sizeof(*anchor) ); - - count = NEXT_UShort(p); - if (index < count) - { - p += 4*index; - *clazz = NEXT_UShort(p); - OTL_Get_Anchor( mark_array + NEXT_UShort(p), anchor ); - } - } - diff --git a/subsys/win32k/freetype/src/otlayout/oltypes.h b/subsys/win32k/freetype/src/otlayout/oltypes.h deleted file mode 100644 index b4a4d80..0000000 --- a/subsys/win32k/freetype/src/otlayout/oltypes.h +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef OLTYPES_H -#define OLTYPES_H - -#include -#include - - /************************************************************* - * - * OTL_Table - * - * - * The base table of most OpenType Layout sub-tables. - * Provides a simple way to scan a table for script, - * languages, features and lookups.. - * - * - * num_scripts :: number of scripts in table's script list - * script_tags :: array of tags for each table script - * - * max_languages :: max number of languages for any script in - * the table. - * num_languages :: number of languages available for current script - * language_tags :: tags of all languages available for current script. - * - * max_features :: total number of features in table - * feature_tags :: tags of all features for current script/language - * features :: selection flags for all features in current script/lang - * - * max_lookups :: total number of lookups in table - * lookups :: selection flags for all lookups for current - * feature list. - * - ****************************************************************/ - - typedef enum OTL_Type_ - { - otl_type_none = 0, - otl_type_base, - otl_type_gdef, - otl_type_gpos, - otl_type_gsub, - otl_type_jstf - - } OTL_Type; - - - typedef struct OTL_Table_ - { - FT_Memory memory; - - TT_Int num_scripts; - TT_Tag* script_tags; - - TT_Int max_languages; - TT_Int num_languages; - TT_Tag* language_tags; - - TT_Int max_features; - TT_Tag* feature_tags; - TT_Bool* features; - - TT_Int max_lookups; - TT_Bool* lookups; - - TT_Byte* scripts_table; - TT_Long scripts_len; - - TT_Byte* features_table; - TT_Long* features_len; - - TT_Byte* lookups_table; - TT_Byte* lookups_len; - - TT_Byte* cur_script; /* current script */ - TT_Byte* cur_language; /* current language */ - - TT_Byte* cur_base_values; - TT_Byte* cur_min_max; - - OTL_Type otl_type; - - } OTL_Table; - - - typedef struct OTL_BaseCoord_ - { - TT_UShort format; - TT_Short coordinate; - TT_UShort ref_glyph; - TT_UShort ref_point; - TT_Byte* device; - - } OTL_BaseCoord; - - - typedef struct OTL_ValueRecord_ - { - TT_Vector placement; - TT_Vector advance; - - TT_Byte* device_pla_x; - TT_Byte* device_pla_y; - TT_Byte* device_adv_x; - TT_Byte* device_adv_y; - - } OTL_ValueRecord; - - - typedef struct OTL_Anchor_ - { - TT_UInt format; - TT_Vector coord; - TT_UInt anchor_point; - TT_Byte* device_x; - TT_Byte* device_y; - - } OTL_Anchor; - - LOCAL_DEF - TT_Error OTL_Table_Init( OTL_Table* table, - FT_Memory memory ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Scripts( OTL_Table* table, - TT_Byte* bytes, - TT_Long len, - OTL_Type otl_type ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Features( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - - LOCAL_DEF - TT_Error OTL_Table_Set_Lookups( OTL_Table* table, - TT_Byte* bytes, - TT_Long len ); - - LOCAL_DEF - void OTL_Table_Done( OTL_Table* table ); - - - -/***************************************************** - * - * Typical uses: - * - * - after OTL_Table_Set_Scripts have been called : - * - * table->script_tags contains the list of tags of all - * scripts defined for this table. - * - * table->num_scripts is the number of scripts - * - */ - -/******************************************************** - * - * - after calling OTL_Table_Set_Features: - * - * table->max_features is the number of all features - * in the table - * - * table->feature_tags is the list of tags of all - * features in the table - * - * table->features[] is an array of boolean used to - * indicate which feature is active for a given script/language - * it is empty (zero-filled) by default. - * - */ - -/******************************************************************* - * - * - after calling OTL_Get_Languages_List(script_tag): - * - * table->num_languages is the number of language systems - * available for the script, including the default - * langsys if there is one - * - * table->language_tags contains the list of tags of all - * languages for the script. Note that the default langsys - * has tag "0" and is always placed first in "language_tags". - * - * - * - */ - LOCAL_DEF - void OTL_Get_Languages_List( OTL_Table* table, - TT_ULong script_tag ); - - -/******************************************************************* - * - * - after calling OTL_Get_Features_List(language_tag): - * - * table->features[] is an array of booleans used to indicate - * which features are active for the current script/language - * - * note that this function must be called after OTL_Get_Languages - * which remembers the last "script_tag" used.. - * - * A client application can change the table->features[] array - * to add or remove features from the list. - * - * - * - */ - LOCAL_DEF - void OTL_Get_Features_List( OTL_Table* table, - TT_ULong language_tag ); - - LOCAL_DEF - void OTL_Get_Baseline_Values( OTL_Table* table, - TT_ULong language_tag ); - - LOCAL_DEF - void OTL_Get_Justification( OTL_Table* table, - TT_ULong language_tag ); - -/******************************************************************* - * - * - after calling OTL_Get_Lookups_List(): - * - * The function uses the table->features[] array of boolean - * to determine which lookups must be processed. - * - * It fills the table->lookups[] array accordingly. It is also - * an array of booleans (one for each lookup). - * - * - */ - - LOCAL_DEF - void OTL_Get_Lookups_List( OTL_Table* table ); - - -/*************************************************************** - * - * So the whole thing looks like: - * - * - * 1. A client specifies a given script and requests available - * language through OTL_Get_Languages_List() - * - * 2. It selects the language tag it needs, then calls - * OTL_Get_Features_List() - * - * 3. It updates the list of active features if it needs to - * - * 4. It calls OTL_Get_Lookups_List() - * It now has a list of active lookups in "table->lookups[]" - * - * 5. The lookups are processed according to the table's type.. - * - */ - - - - - LOCAL_DEF - TT_Long OTL_Get_Coverage_Index( TT_Byte* coverage, - TT_UInt glyph_id ); - - LOCAL_DEF - TT_UInt OTL_Get_Glyph_Class( TT_Byte* class_def, - TT_UInt glyph_id ); - - LOCAL_DEF - TT_Int OTL_Get_Device_Adjustment( TT_Byte* device, - TT_UInt size ); - - LOCAL_DEF - void OTL_Get_Base_Coordinate( TT_Byte* base_coord, - OTL_BaseCoord* coord ); - - - LOCAL_DEF - TT_Int OTL_ValueRecord_Size( TT_UShort value_format ); - - - LOCAL_DEF - void OTL_Get_ValueRecord( TT_Byte* value_record, - TT_UShort value_format, - TT_Byte* pos_table, - OTL_ValueRecord* record ); - - - LOCAL_DEF - void OTL_Get_Anchor( TT_Byte* anchor_table, - OTL_Anchor* anchor ); - - - LOCAL_DEF - void OTL_Get_Mark( TT_Byte* mark_array, - TT_UInt index, - TT_UShort* clazz, - OTL_Anchor* anchor ); - - - -#define OTL_Byte(p) (p++, p[-1]) - -#define OTL_UShort(p) (p+=2, ((TT_UShort)p[-2] << 8) | p[-1]) - -#define OTL_ULong(p) (p+=4, ((TT_ULong)p[-4] << 24) | \ - ((TT_ULong)p[-3] << 16) | \ - ((TT_ULong)p[-2] << 8 ) | p[-1] ) - -#endif /* OLTYPES_H */ diff --git a/subsys/win32k/freetype/src/psnames/.cvsignore b/subsys/win32k/freetype/src/psnames/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/psnames/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/psnames/module.mk b/subsys/win32k/freetype/src/psnames/module.mk deleted file mode 100644 index 3d33c12..0000000 --- a/subsys/win32k/freetype/src/psnames/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_psnames_module - -add_psnames_module: - $(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)psnames $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/psnames/psmodule.c b/subsys/win32k/freetype/src/psnames/psmodule.c deleted file mode 100644 index e1e9e77..0000000 --- a/subsys/win32k/freetype/src/psnames/psmodule.c +++ /dev/null @@ -1,320 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.c */ -/* */ -/* PSNames module implementation (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "psmodule.h" -#include "pstables.h" - -#else - -#include -#include - -#endif - - -#include /* for qsort() */ -#include /* for strcmp(), strncpy() */ - - -#ifndef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - - - - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /* return the Unicode value corresponding to a given glyph. Note that */ - /* we do deal with glyph variants by detecting a non-initial dot in */ - /* the name, as in `A.swash' or `e.final', etc. */ - /* */ - static - FT_ULong PS_Unicode_Value( const char* glyph_name ) - { - FT_Int n; - char first = glyph_name[0]; - char temp[64]; - - - /* if the name begins with `uni', then the glyph name may be a */ - /* hard-coded unicode character code. */ - if ( glyph_name[0] == 'u' && - glyph_name[1] == 'n' && - glyph_name[2] == 'i' ) - { - /* determine whether the next four characters following are */ - /* hexadecimal. */ - - /* XXX: Add code to deal with ligatures, i.e. glyph names like */ - /* `uniXXXXYYYYZZZZ'... */ - - FT_Int count; - FT_ULong value = 0; - const char* p = glyph_name + 4; - - - for ( count = 4; count > 0; count--, p++ ) - { - char c = *p; - unsigned char d; - - - d = (unsigned char)c - '0'; - if ( d >= 10 ) - { - d = (unsigned char)c - 'A'; - if ( d >= 6 ) - d = 16; - else - d += 10; - } - - /* exit if a non-uppercase hexadecimal character was found */ - if ( d >= 16 ) - break; - - value = ( value << 4 ) + d; - - if ( count == 0 ) - return value; - } - } - - /* look for a non-initial dot in the glyph name in order to */ - /* sort-out variants like `A.swash', `e.final', etc. */ - { - const char* p; - int len; - - - p = glyph_name; - - while ( *p && *p != '.' ) - p++; - - len = p - glyph_name; - - if ( *p && len < 64 ) - { - strncpy( temp, glyph_name, len ); - temp[len] = 0; - glyph_name = temp; - } - } - - /* now, look up the glyph in the Adobe Glyph List */ - for ( n = 0; n < NUM_ADOBE_GLYPHS; n++ ) - { - const char* name = t1_standard_glyphs[n]; - - - if ( first == name[0] && strcmp( glyph_name, name ) == 0 ) - return names_to_unicode[n]; - } - - /* not found, there is probably no Unicode value for this glyph name */ - return 0; - } - - - /* qsort callback to sort the unicode map */ - static - int compare_uni_maps( const void* a, - const void* b ) - { - PS_UniMap* map1 = (PS_UniMap*)a; - PS_UniMap* map2 = (PS_UniMap*)b; - - - return ( map1->unicode - map2->unicode ); - } - - - /* Builds a table that maps Unicode values to glyph indices */ - static - FT_Error PS_Build_Unicode_Table( FT_Memory memory, - FT_UInt num_glyphs, - const char** glyph_names, - PS_Unicodes* table ) - { - FT_Error error; - - - /* we first allocate the table */ - table->num_maps = 0; - table->maps = 0; - - if ( !ALLOC_ARRAY( table->maps, num_glyphs, PS_UniMap ) ) - { - FT_UInt n; - FT_UInt count; - PS_UniMap* map; - FT_ULong uni_char; - - - map = table->maps; - - for ( n = 0; n < num_glyphs; n++ ) - { - const char* gname = glyph_names[n]; - - - if ( gname ) - { - uni_char = PS_Unicode_Value( gname ); - - if ( uni_char && uni_char != 0xFFFF ) - { - map->unicode = uni_char; - map->glyph_index = n; - map++; - } - } - } - - /* now, compress the table a bit */ - count = map - table->maps; - - if ( count > 0 && REALLOC( table->maps, - num_glyphs * sizeof ( PS_UniMap ), - count * sizeof ( PS_UniMap ) ) ) - count = 0; - - if ( count == 0 ) - { - FREE( table->maps ); - if ( !error ) - error = FT_Err_Invalid_Argument; /* no unicode chars here! */ - } - else - /* sort the table in increasing order of unicode values */ - qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); - - table->num_maps = count; - } - - return error; - } - - - static - FT_UInt PS_Lookup_Unicode( PS_Unicodes* table, - FT_ULong unicode ) - { - PS_UniMap *min, *max, *mid; - - - /* perform a binary search on the table */ - - min = table->maps; - max = min + table->num_maps - 1; - - while ( min <= max ) - { - mid = min + ( max - min ) / 2; - if ( mid->unicode == unicode ) - return mid->glyph_index; - - if ( min == max ) - break; - - if ( mid->unicode < unicode ) - min = mid + 1; - else - max = mid - 1; - } - - return 0xFFFF; - } - - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - - static - const char* PS_Macintosh_Name( FT_UInt name_index ) - { - if ( name_index >= 258 ) - name_index = 0; - - return standard_glyph_names[mac_standard_names[name_index]]; - } - - - static - const char* PS_Standard_Strings( FT_UInt sid ) - { - return ( sid < NUM_STD_GLYPHS ? t1_standard_glyphs[sid] : 0 ); - } - - - static const PSNames_Interface psnames_interface = - { -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - (PS_Unicode_Value_Func) PS_Unicode_Value, - (PS_Build_Unicodes_Func) PS_Build_Unicode_Table, - (PS_Lookup_Unicode_Func) PS_Lookup_Unicode, - -#else - - 0, - 0, - 0, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - (PS_Macintosh_Name_Func) PS_Macintosh_Name, - (PS_Adobe_Std_Strings_Func)PS_Standard_Strings, - - t1_standard_encoding, - t1_expert_encoding - }; - - -#endif /* !FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES */ - - - const FT_Module_Class psnames_module_class = - { - 0, /* this is not a font driver, nor a renderer */ - sizeof( FT_ModuleRec ), - - "psnames", /* driver name */ - 0x10000L, /* driver version */ - 0x20000L, /* driver requires FreeType 2 or above */ - -#ifdef FT_CONFIG_OPTION_NO_POSTSCRIPT_NAMES - 0, -#else - (void*)&psnames_interface, /* module specific interface */ -#endif - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/psnames/psmodule.h b/subsys/win32k/freetype/src/psnames/psmodule.h deleted file mode 100644 index ff7ef06..0000000 --- a/subsys/win32k/freetype/src/psnames/psmodule.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* psmodule.h */ -/* */ -/* High-level PSNames module interface (specification). */ -/* */ -/* Copyright 1996-2000 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 PSDRIVER_H -#define PSDRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Module_Class ) psnames_module_class; - -#endif /* PSDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/psnames/psnames.c b/subsys/win32k/freetype/src/psnames/psnames.c deleted file mode 100644 index 4e4aa1f..0000000 --- a/subsys/win32k/freetype/src/psnames/psnames.c +++ /dev/null @@ -1,24 +0,0 @@ -/***************************************************************************/ -/* */ -/* psnames.c */ -/* */ -/* FreeType PSNames module component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include - - -/* END */ diff --git a/subsys/win32k/freetype/src/psnames/pstables.h b/subsys/win32k/freetype/src/psnames/pstables.h deleted file mode 100644 index 094bc27..0000000 --- a/subsys/win32k/freetype/src/psnames/pstables.h +++ /dev/null @@ -1,2942 +0,0 @@ -/***************************************************************************/ -/* */ -/* pstables.h */ -/* */ -/* PostScript glyph names (specification only). */ -/* */ -/* Copyright 2000 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 has been generated automatically -- do not edit! */ - - - static const char* standard_glyph_names[] = - { - ".null", - "CR", - "notequal", - "infinity", - "lessequal", - "greaterequal", - "partialdiff", - "summation", - "product", - "pi", - "integral", - "Omega", - "radical", - "approxequal", - "Delta", - "nbspace", - "lozenge", - "periodcentered", - "apple", - "lslash", - "franc", - "Gbreve", - "gbreve", - "Idot", - "Scedilla", - "scedilla", - "Cacute", - "cacute", - "Ccaron", - "ccaron", - "dmacron", - ".notdef", - "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", - "asciicircum", - "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", - "asciitilde", - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "endash", - "dagger", - "daggerdbl", - "periodcenter", - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - "questiondown", - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", - "emdash", - "AE", - "ordfeminine", - "Lslash", - "Oslash", - "OE", - "ordmasculine", - "ae", - "dotlessi", - "Islash", - "oslash", - "oe", - "germandbls", - "onesuperior", - "logicalnot", - "mu", - "trademark", - "Eth", - "onehalf", - "plusminus", - "Thorn", - "onequarter", - "divide", - "brokenbar", - "degree", - "thorn", - "threequarters", - "twosuperior", - "registered", - "minus", - "eth", - "multiply", - "threesuperior", - "copyright", - "Aacute", - "Acircumflex", - "Adieresis", - "Agrave", - "Aring", - "Atilde", - "Ccedilla", - "Eacute", - "Ecircumflex", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Ntilde", - "Oacute", - "Ocircumflex", - "Odieresis", - "Ograve", - "Otilde", - "Scaron", - "Uacute", - "Ucircumflex", - "Udieresis", - "Ugrave", - "Yacute", - "Ydieresis", - "Zcaron", - "aacute", - "acircumflex", - "adieresis", - "agrave", - "aring", - "atilde", - "ccedilla", - "eacute", - "ecircumflex", - "edieresis", - "egrave", - "iacute", - "icircumflex", - "idieresis", - "igrave", - "ntilde", - "oacute", - "ocircumflex", - "odieresis", - "ograve", - "otilde", - "scaron", - "uacute", - "ucircumflex", - "udieresis", - "ugrave", - "yacute", - "ydieresis", - "zcaron", - "exclamsmall", - "Hungarumlautsmall", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "commasuperior", - "threequartersemdash", - "periodsuperior", - "questionsmall", - "asuperior", - "bsuperior", - "centsuperior", - "dsuperior", - "esuperior", - "isuperior", - "lsuperior", - "msuperior", - "nsuperior", - "osuperior", - "rsuperior", - "ssuperior", - "tsuperior", - "ff", - "ffi", - "ffl", - "parenleftinferior", - "parenrightinferior", - "Circumflexsmall", - "hyphensuperior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - "exclamdownsmall", - "centoldstyle", - "Lslashsmall", - "Scaronsmall", - "Zcaronsmall", - "Dieresissmall", - "Brevesmall", - "Caronsmall", - "Dotaccentsmall", - "Macronsmall", - "figuredash", - "hypheninferior", - "Ogoneksmall", - "Ringsmall", - "Cedillasmall", - "questiondownsmall", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - "zerosuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "eightsuperior", - "ninesuperior", - "zeroinferior", - "oneinferior", - "twoinferior", - "threeinferior", - "fourinferior", - "fiveinferior", - "sixinferior", - "seveninferior", - "eightinferior", - "nineinferior", - "centinferior", - "dollarinferior", - "periodinferior", - "commainferior", - "Agravesmall", - "Aacutesmall", - "Acircumflexsmall", - "Atildesmall", - "Adieresissmall", - "Aringsmall", - "AEsmall", - "Ccedillasmall", - "Egravesmall", - "Eacutesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Igravesmall", - "Iacutesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ethsmall", - "Ntildesmall", - "Ogravesmall", - "Oacutesmall", - "Ocircumflexsmall", - "Otildesmall", - "Odieresissmall", - "OEsmall", - "Oslashsmall", - "Ugravesmall", - "Uacautesmall", - "Ucircumflexsmall", - "Udieresissmall", - "Yacutesmall", - "Thornsmall", - "Ydieresissmall", - "001.000", - "001.001", - "001.002", - "001.003", - "Black", - "Bold", - "Book", - "Light", - "Medium", - "Regular", - "Roman", - "Semibold", - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - "AEacute", - "Abreve", - "Acute", - "Alpha", - "Alphatonos", - "Amacron", - "Aogonek", - "Aringacute", - "Beta", - "Caron", - "Ccircumflex", - "Cdotaccent", - "Chi", - "Dcaron", - "Dcroat", - "Dieresis", - "DieresisAcute", - "DieresisGrave", - "Ebreve", - "Ecaron", - "Edotaccent", - "Emacron", - "Eng", - "Eogonek", - "Epsilon", - "Epsilontonos", - "Eta", - "Etatonos", - "Euro", - "Gamma", - "Gcaron", - "Gcircumflex", - "Gcommaaccent", - "Gdotaccent", - "Grave", - "H18533", - "H18543", - "H18551", - "H22073", - "Hbar", - "Hcircumflex", - "Hungarumlaut", - "IJ", - "Ibreve", - "Idotaccent", - "Ifraktur", - "Imacron", - "Iogonek", - "Iota", - "Iotadieresis", - "Iotatonos", - "Itilde", - "Jcircumflex", - "Kappa", - "Kcommaaccent", - "LL", - "Lacute", - "Lambda", - "Lcaron", - "Lcommaaccent", - "Ldot", - "Macron", - "Mu", - "Nacute", - "Ncaron", - "Ncommaaccent", - "Nu", - "Obreve", - "Ohorn", - "Ohungarumlaut", - "Omacron", - "Omegatonos", - "Omicron", - "Omicrontonos", - "Oslashacute", - "Phi", - "Pi", - "Psi", - "Racute", - "Rcaron", - "Rcommaaccent", - "Rfraktur", - "Rho", - "SF010000", - "SF020000", - "SF030000", - "SF040000", - "SF050000", - "SF060000", - "SF070000", - "SF080000", - "SF090000", - "SF100000", - "SF110000", - "SF190000", - "SF200000", - "SF210000", - "SF220000", - "SF230000", - "SF240000", - "SF250000", - "SF260000", - "SF270000", - "SF280000", - "SF360000", - "SF370000", - "SF380000", - "SF390000", - "SF400000", - "SF410000", - "SF420000", - "SF430000", - "SF440000", - "SF450000", - "SF460000", - "SF470000", - "SF480000", - "SF490000", - "SF500000", - "SF510000", - "SF520000", - "SF530000", - "SF540000", - "Sacute", - "Scircumflex", - "Scommaaccent", - "Sigma", - "Tau", - "Tbar", - "Tcaron", - "Tcommaaccent", - "Tcommaaccent", - "Theta", - "Uacutesmall", - "Ubreve", - "Uhorn", - "Uhungarumlaut", - "Umacron", - "Uogonek", - "Upsilon", - "Upsilon1", - "Upsilondieresis", - "Upsilontonos", - "Uring", - "Utilde", - "Wacute", - "Wcircumflex", - "Wdieresis", - "Wgrave", - "Xi", - "Ycircumflex", - "Ygrave", - "Zacute", - "Zdotaccent", - "Zeta", - "abreve", - "acutecomb", - "aeacute", - "afii00208", - "afii10017", - "afii10018", - "afii10019", - "afii10020", - "afii10021", - "afii10022", - "afii10023", - "afii10024", - "afii10025", - "afii10026", - "afii10027", - "afii10028", - "afii10029", - "afii10030", - "afii10031", - "afii10032", - "afii10033", - "afii10034", - "afii10035", - "afii10036", - "afii10037", - "afii10038", - "afii10039", - "afii10040", - "afii10041", - "afii10042", - "afii10043", - "afii10044", - "afii10045", - "afii10046", - "afii10047", - "afii10048", - "afii10049", - "afii10050", - "afii10051", - "afii10052", - "afii10053", - "afii10054", - "afii10055", - "afii10056", - "afii10057", - "afii10058", - "afii10059", - "afii10060", - "afii10061", - "afii10062", - "afii10063", - "afii10064", - "afii10065", - "afii10066", - "afii10067", - "afii10068", - "afii10069", - "afii10070", - "afii10071", - "afii10072", - "afii10073", - "afii10074", - "afii10075", - "afii10076", - "afii10077", - "afii10078", - "afii10079", - "afii10080", - "afii10081", - "afii10082", - "afii10083", - "afii10084", - "afii10085", - "afii10086", - "afii10087", - "afii10088", - "afii10089", - "afii10090", - "afii10091", - "afii10092", - "afii10093", - "afii10094", - "afii10095", - "afii10096", - "afii10097", - "afii10098", - "afii10099", - "afii10100", - "afii10101", - "afii10102", - "afii10103", - "afii10104", - "afii10105", - "afii10106", - "afii10107", - "afii10108", - "afii10109", - "afii10110", - "afii10145", - "afii10146", - "afii10147", - "afii10148", - "afii10192", - "afii10193", - "afii10194", - "afii10195", - "afii10196", - "afii10831", - "afii10832", - "afii10846", - "afii299", - "afii300", - "afii301", - "afii57381", - "afii57388", - "afii57392", - "afii57393", - "afii57394", - "afii57395", - "afii57396", - "afii57397", - "afii57398", - "afii57399", - "afii57400", - "afii57401", - "afii57403", - "afii57407", - "afii57409", - "afii57410", - "afii57411", - "afii57412", - "afii57413", - "afii57414", - "afii57415", - "afii57416", - "afii57417", - "afii57418", - "afii57419", - "afii57420", - "afii57421", - "afii57422", - "afii57423", - "afii57424", - "afii57425", - "afii57426", - "afii57427", - "afii57428", - "afii57429", - "afii57430", - "afii57431", - "afii57432", - "afii57433", - "afii57434", - "afii57440", - "afii57441", - "afii57442", - "afii57443", - "afii57444", - "afii57445", - "afii57446", - "afii57448", - "afii57449", - "afii57450", - "afii57451", - "afii57452", - "afii57453", - "afii57454", - "afii57455", - "afii57456", - "afii57457", - "afii57458", - "afii57470", - "afii57505", - "afii57506", - "afii57507", - "afii57508", - "afii57509", - "afii57511", - "afii57512", - "afii57513", - "afii57514", - "afii57519", - "afii57534", - "afii57636", - "afii57645", - "afii57658", - "afii57664", - "afii57665", - "afii57666", - "afii57667", - "afii57668", - "afii57669", - "afii57670", - "afii57671", - "afii57672", - "afii57673", - "afii57674", - "afii57675", - "afii57676", - "afii57677", - "afii57678", - "afii57679", - "afii57680", - "afii57681", - "afii57682", - "afii57683", - "afii57684", - "afii57685", - "afii57686", - "afii57687", - "afii57688", - "afii57689", - "afii57690", - "afii57694", - "afii57695", - "afii57700", - "afii57705", - "afii57716", - "afii57717", - "afii57718", - "afii57723", - "afii57793", - "afii57794", - "afii57795", - "afii57796", - "afii57797", - "afii57798", - "afii57799", - "afii57800", - "afii57801", - "afii57802", - "afii57803", - "afii57804", - "afii57806", - "afii57807", - "afii57839", - "afii57841", - "afii57842", - "afii57929", - "afii61248", - "afii61289", - "afii61352", - "afii61573", - "afii61574", - "afii61575", - "afii61664", - "afii63167", - "afii64937", - "aleph", - "alpha", - "alphatonos", - "amacron", - "angle", - "angleleft", - "angleright", - "anoteleia", - "aogonek", - "aringacute", - "arrowboth", - "arrowdblboth", - "arrowdbldown", - "arrowdblleft", - "arrowdblright", - "arrowdblup", - "arrowdown", - "arrowhorizex", - "arrowleft", - "arrowright", - "arrowup", - "arrowupdn", - "arrowupdnbse", - "arrowvertex", - "asteriskmath", - "beta", - "block", - "braceex", - "braceleftbt", - "braceleftmid", - "bracelefttp", - "bracerightbt", - "bracerightmid", - "bracerighttp", - "bracketleftbt", - "bracketleftex", - "bracketlefttp", - "bracketrightbt", - "bracketrightex", - "bracketrighttp", - "carriagereturn", - "ccircumflex", - "cdotaccent", - "chi", - "circle", - "circlemultiply", - "circleplus", - "club", - "commaaccent", - "congruent", - "copyrightsans", - "copyrightserif", - "cyrBreve", - "cyrFlex", - "cyrbreve", - "cyrflex", - "dblGrave", - "dblgrave", - "dcaron", - "dcroat", - "delta", - "diamond", - "dieresisacute", - "dieresisgrave", - "dieresistonos", - "dkshade", - "dnblock", - "dong", - "dotbelowcomb", - "dotlessj", - "dotmath", - "ebreve", - "ecaron", - "edotaccent", - "element", - "emacron", - "emptyset", - "eng", - "eogonek", - "epsilon", - "epsilontonos", - "equivalence", - "estimated", - "eta", - "etatonos", - "exclamdbl", - "existential", - "female", - "filledbox", - "filledrect", - "gamma", - "gcaron", - "gcircumflex", - "gcommaaccent", - "gdotaccent", - "gradient", - "gravecomb", - "hbar", - "hcircumflex", - "heart", - "hookabovecomb", - "house", - "ibreve", - "ij", - "imacron", - "integralbt", - "integralex", - "integraltp", - "intersection", - "invbullet", - "invcircle", - "invsmileface", - "iogonek", - "iota", - "iotadieresis", - "iotadieresistonos", - "iotatonos", - "itilde", - "jcircumflex", - "kappa", - "kcommaaccent", - "kgreenlandic", - "lacute", - "lambda", - "lcaron", - "lcommaaccent", - "ldot", - "lfblock", - "lira", - "ll", - "logicaland", - "logicalor", - "longs", - "ltshade", - "male", - "minute", - "musicalnote", - "musicalnotedbl", - "nacute", - "napostrophe", - "ncaron", - "ncommaaccent", - "notelement", - "notsubset", - "nu", - "obreve", - "ohorn", - "ohungarumlaut", - "omacron", - "omega", - "omega1", - "omegatonos", - "omicron", - "omicrontonos", - "openbullet", - "orthogonal", - "oslashacute", - "parenleftbt", - "parenleftex", - "parenlefttp", - "parenrightbt", - "parenrightex", - "parenrighttp", - "perpendicular", - "peseta", - "phi", - "phi1", - "prescription", - "propersubset", - "propersuperset", - "proportional", - "psi", - "quotereversed", - "racute", - "radicalex", - "rcaron", - "rcommaaccent", - "reflexsubset", - "reflexsuperset", - "registersans", - "registerserif", - "revlogicalnot", - "rho", - "rtblock", - "sacute", - "scircumflex", - "scommaaccent", - "second", - "shade", - "sigma", - "sigma1", - "similar", - "smileface", - "spade", - "suchthat", - "sun", - "tau", - "tbar", - "tcaron", - "tcommaaccent", - "tcommaaccent", - "therefore", - "theta", - "theta1", - "tildecomb", - "tonos", - "trademarksans", - "trademarkserif", - "triagdn", - "triaglf", - "triagrt", - "triagup", - "ubreve", - "uhorn", - "uhungarumlaut", - "umacron", - "underscoredbl", - "union", - "universal", - "uogonek", - "upblock", - "upsilon", - "upsilondieresis", - "upsilondieresistonos", - "upsilontonos", - "uring", - "utilde", - "wacute", - "wcircumflex", - "wdieresis", - "weierstrass", - "wgrave", - "xi", - "ycircumflex", - "ygrave", - "zacute", - "zdotaccent", - "zeta", - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - - 0 - }; - - - static const char** t1_standard_glyphs = standard_glyph_names + 31; - - -#define NUM_STD_GLYPHS 391 - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST -#define NUM_ADOBE_GLYPHS 1032 -#else -#define NUM_ADOBE_GLYPHS 391 -#endif - - - static const unsigned short mac_standard_names[259] = - { - 0, - 0, - 1, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 104, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 124, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 173, - 175, - 177, - 178, - 186, - 189, - 195, - 200, - 203, - 201, - 202, - 205, - 204, - 206, - 207, - 210, - 208, - 209, - 211, - 214, - 212, - 213, - 215, - 216, - 219, - 217, - 218, - 220, - 222, - 225, - 223, - 224, - 112, - 161, - 97, - 98, - 102, - 116, - 115, - 149, - 165, - 170, - 153, - 125, - 131, - 2, - 138, - 141, - 3, - 156, - 4, - 5, - 100, - 152, - 6, - 7, - 8, - 9, - 10, - 139, - 143, - 11, - 144, - 147, - 123, - 96, - 151, - 12, - 101, - 13, - 14, - 106, - 120, - 121, - 15, - 174, - 176, - 191, - 142, - 148, - 111, - 137, - 105, - 119, - 65, - 8, - 159, - 16, - 227, - 198, - 99, - 103, - 107, - 108, - 109, - 110, - 113, - 17, - 117, - 118, - 122, - 172, - 179, - 171, - 180, - 181, - 182, - 183, - 184, - 185, - 187, - 188, - 18, - 190, - 193, - 194, - 196, - 145, - 126, - 127, - 128, - 129, - 130, - 132, - 133, - 134, - 135, - 136, - 140, - 19, - 192, - 221, - 199, - 228, - 160, - 154, - 167, - 197, - 226, - 157, - 162, - 166, - 168, - 150, - 164, - 169, - 155, - 158, - 163, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 0 - }; - - - - static const unsigned short names_to_unicode[1033] = - { - 0, - 0x0020, - 0x0021, - 0x0022, - 0x0023, - 0x0024, - 0x0025, - 0x0026, - 0x2019, - 0x0028, - 0x0029, - 0x002A, - 0x002B, - 0x002C, - 0x002D, - 0x002E, - 0x002F, - 0x0030, - 0x0031, - 0x0032, - 0x0033, - 0x0034, - 0x0035, - 0x0036, - 0x0037, - 0x0038, - 0x0039, - 0x003A, - 0x003B, - 0x003C, - 0x003D, - 0x003E, - 0x003F, - 0x0040, - 0x0041, - 0x0042, - 0x0043, - 0x0044, - 0x0045, - 0x0046, - 0x0047, - 0x0048, - 0x0049, - 0x004A, - 0x004B, - 0x004C, - 0x004D, - 0x004E, - 0x004F, - 0x0050, - 0x0051, - 0x0052, - 0x0053, - 0x0054, - 0x0055, - 0x0056, - 0x0057, - 0x0058, - 0x0059, - 0x005A, - 0x005B, - 0x005C, - 0x005D, - 0x005E, - 0x005F, - 0x2018, - 0x0061, - 0x0062, - 0x0063, - 0x0064, - 0x0065, - 0x0066, - 0x0067, - 0x0068, - 0x0069, - 0x006A, - 0x006B, - 0x006C, - 0x006D, - 0x006E, - 0x006F, - 0x0070, - 0x0071, - 0x0072, - 0x0073, - 0x0074, - 0x0075, - 0x0076, - 0x0077, - 0x0078, - 0x0079, - 0x007A, - 0x007B, - 0x007C, - 0x007D, - 0x007E, - 0x00A1, - 0x00A2, - 0x00A3, - 0x2044, - 0x00A5, - 0x0192, - 0x00A7, - 0x00A4, - 0x0027, - 0x201C, - 0x00AB, - 0x2039, - 0x203A, - 0xFB01, - 0xFB02, - 0x2013, - 0x2020, - 0x2021, - 0, - 0x00B6, - 0x2022, - 0x201A, - 0x201E, - 0x201D, - 0x00BB, - 0x2026, - 0x2030, - 0x00BF, - 0x0060, - 0x00B4, - 0x02C6, - 0x02DC, - 0x00AF, - 0x02D8, - 0x02D9, - 0x00A8, - 0x02DA, - 0x00B8, - 0x02DD, - 0x02DB, - 0x02C7, - 0x2014, - 0x00C6, - 0x00AA, - 0x0141, - 0x00D8, - 0x0152, - 0x00BA, - 0x00E6, - 0x0131, - 0, - 0x00F8, - 0x0153, - 0x00DF, - 0x00B9, - 0x00AC, - 0x00B5, - 0x2122, - 0x00D0, - 0x00BD, - 0x00B1, - 0x00DE, - 0x00BC, - 0x00F7, - 0x00A6, - 0x00B0, - 0x00FE, - 0x00BE, - 0x00B2, - 0x00AE, - 0x2212, - 0x00F0, - 0x00D7, - 0x00B3, - 0x00A9, - 0x00C1, - 0x00C2, - 0x00C4, - 0x00C0, - 0x00C5, - 0x00C3, - 0x00C7, - 0x00C9, - 0x00CA, - 0x00CB, - 0x00C8, - 0x00CD, - 0x00CE, - 0x00CF, - 0x00CC, - 0x00D1, - 0x00D3, - 0x00D4, - 0x00D6, - 0x00D2, - 0x00D5, - 0x0160, - 0x00DA, - 0x00DB, - 0x00DC, - 0x00D9, - 0x00DD, - 0x0178, - 0x017D, - 0x00E1, - 0x00E2, - 0x00E4, - 0x00E0, - 0x00E5, - 0x00E3, - 0x00E7, - 0x00E9, - 0x00EA, - 0x00EB, - 0x00E8, - 0x00ED, - 0x00EE, - 0x00EF, - 0x00EC, - 0x00F1, - 0x00F3, - 0x00F4, - 0x00F6, - 0x00F2, - 0x00F5, - 0x0161, - 0x00FA, - 0x00FB, - 0x00FC, - 0x00F9, - 0x00FD, - 0x00FF, - 0x017E, - 0xF721, - 0xF6F8, - 0xF724, - 0xF6E4, - 0xF726, - 0xF7B4, - 0x207D, - 0x207E, - 0x2025, - 0x2024, - 0xF730, - 0xF731, - 0xF732, - 0xF733, - 0xF734, - 0xF735, - 0xF736, - 0xF737, - 0xF738, - 0xF739, - 0xF6E2, - 0xF6DE, - 0xF6E8, - 0xF73F, - 0xF6E9, - 0xF6EA, - 0xF6E0, - 0xF6EB, - 0xF6EC, - 0xF6ED, - 0xF6EE, - 0xF6EF, - 0x207F, - 0xF6F0, - 0xF6F1, - 0xF6F2, - 0xF6F3, - 0xFB00, - 0xFB03, - 0xFB04, - 0x208D, - 0x208E, - 0xF6F6, - 0xF6E6, - 0xF760, - 0xF761, - 0xF762, - 0xF763, - 0xF764, - 0xF765, - 0xF766, - 0xF767, - 0xF768, - 0xF769, - 0xF76A, - 0xF76B, - 0xF76C, - 0xF76D, - 0xF76E, - 0xF76F, - 0xF770, - 0xF771, - 0xF772, - 0xF773, - 0xF774, - 0xF775, - 0xF776, - 0xF777, - 0xF778, - 0xF779, - 0xF77A, - 0x20A1, - 0xF6DC, - 0xF6DD, - 0xF6FE, - 0xF7A1, - 0xF7A2, - 0xF6F9, - 0xF6FD, - 0xF6FF, - 0xF7A8, - 0xF6F4, - 0xF6F5, - 0xF6F7, - 0xF7AF, - 0x2012, - 0xF6E5, - 0xF6FB, - 0xF6FC, - 0xF7B8, - 0xF7BF, - 0x215B, - 0x215C, - 0x215D, - 0x215E, - 0x2153, - 0x2154, - 0x2070, - 0x2074, - 0x2075, - 0x2076, - 0x2077, - 0x2078, - 0x2079, - 0x2080, - 0x2081, - 0x2082, - 0x2083, - 0x2084, - 0x2085, - 0x2086, - 0x2087, - 0x2088, - 0x2089, - 0xF6DF, - 0xF6E3, - 0xF6E7, - 0xF6E1, - 0xF7E0, - 0xF7E1, - 0xF7E2, - 0xF7E3, - 0xF7E4, - 0xF7E5, - 0xF7E6, - 0xF7E7, - 0xF7E8, - 0xF7E9, - 0xF7EA, - 0xF7EB, - 0xF7EC, - 0xF7ED, - 0xF7EE, - 0xF7EF, - 0xF7F0, - 0xF7F1, - 0xF7F2, - 0xF7F3, - 0xF7F4, - 0xF7F5, - 0xF7F6, - 0xF6FA, - 0xF7F8, - 0xF7F9, - 0, - 0xF7FB, - 0xF7FC, - 0xF7FD, - 0xF7FE, - 0xF7FF, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - -#ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - 0x01FC, - 0x0102, - 0xF6C9, - 0x0391, - 0x0386, - 0x0100, - 0x0104, - 0x01FA, - 0x0392, - 0xF6CA, - 0x0108, - 0x010A, - 0x03A7, - 0x010E, - 0x0110, - 0xF6CB, - 0xF6CC, - 0xF6CD, - 0x0114, - 0x011A, - 0x0116, - 0x0112, - 0x014A, - 0x0118, - 0x0395, - 0x0388, - 0x0397, - 0x0389, - 0x20AC, - 0x0393, - 0x01E6, - 0x011C, - 0x0122, - 0x0120, - 0xF6CE, - 0x25CF, - 0x25AA, - 0x25AB, - 0x25A1, - 0x0126, - 0x0124, - 0xF6CF, - 0x0132, - 0x012C, - 0x0130, - 0x2111, - 0x012A, - 0x012E, - 0x0399, - 0x03AA, - 0x038A, - 0x0128, - 0x0134, - 0x039A, - 0x0136, - 0xF6BF, - 0x0139, - 0x039B, - 0x013D, - 0x013B, - 0x013F, - 0xF6D0, - 0x039C, - 0x0143, - 0x0147, - 0x0145, - 0x039D, - 0x014E, - 0x01A0, - 0x0150, - 0x014C, - 0x038F, - 0x039F, - 0x038C, - 0x01FE, - 0x03A6, - 0x03A0, - 0x03A8, - 0x0154, - 0x0158, - 0x0156, - 0x211C, - 0x03A1, - 0x250C, - 0x2514, - 0x2510, - 0x2518, - 0x253C, - 0x252C, - 0x2534, - 0x251C, - 0x2524, - 0x2500, - 0x2502, - 0x2561, - 0x2562, - 0x2556, - 0x2555, - 0x2563, - 0x2551, - 0x2557, - 0x255D, - 0x255C, - 0x255B, - 0x255E, - 0x255F, - 0x255A, - 0x2554, - 0x2569, - 0x2566, - 0x2560, - 0x2550, - 0x256C, - 0x2567, - 0x2568, - 0x2564, - 0x2565, - 0x2559, - 0x2558, - 0x2552, - 0x2553, - 0x256B, - 0x256A, - 0x015A, - 0x015C, - 0x0218, - 0x03A3, - 0x03A4, - 0x0166, - 0x0164, - 0x0162, - 0x0162, - 0x0398, - 0xF7FA, - 0x016C, - 0x01AF, - 0x0170, - 0x016A, - 0x0172, - 0x03A5, - 0x03D2, - 0x03AB, - 0x038E, - 0x016E, - 0x0168, - 0x1E82, - 0x0174, - 0x1E84, - 0x1E80, - 0x039E, - 0x0176, - 0x1EF2, - 0x0179, - 0x017B, - 0x0396, - 0x0103, - 0x0301, - 0x01FD, - 0x2015, - 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, - 0x0490, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x0409, - 0x040A, - 0x040B, - 0x040C, - 0x040E, - 0xF6C4, - 0xF6C5, - 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, - 0x0491, - 0x0452, - 0x0453, - 0x0454, - 0x0455, - 0x0456, - 0x0457, - 0x0458, - 0x0459, - 0x045A, - 0x045B, - 0x045C, - 0x045E, - 0x040F, - 0x0462, - 0x0472, - 0x0474, - 0xF6C6, - 0x045F, - 0x0463, - 0x0473, - 0x0475, - 0xF6C7, - 0xF6C8, - 0x04D9, - 0x200E, - 0x200F, - 0x200D, - 0x066A, - 0x060C, - 0x0660, - 0x0661, - 0x0662, - 0x0663, - 0x0664, - 0x0665, - 0x0666, - 0x0667, - 0x0668, - 0x0669, - 0x061B, - 0x061F, - 0x0621, - 0x0622, - 0x0623, - 0x0624, - 0x0625, - 0x0626, - 0x0627, - 0x0628, - 0x0629, - 0x062A, - 0x062B, - 0x062C, - 0x062D, - 0x062E, - 0x062F, - 0x0630, - 0x0631, - 0x0632, - 0x0633, - 0x0634, - 0x0635, - 0x0636, - 0x0637, - 0x0638, - 0x0639, - 0x063A, - 0x0640, - 0x0641, - 0x0642, - 0x0643, - 0x0644, - 0x0645, - 0x0646, - 0x0648, - 0x0649, - 0x064A, - 0x064B, - 0x064C, - 0x064D, - 0x064E, - 0x064F, - 0x0650, - 0x0651, - 0x0652, - 0x0647, - 0x06A4, - 0x067E, - 0x0686, - 0x0698, - 0x06AF, - 0x0679, - 0x0688, - 0x0691, - 0x06BA, - 0x06D2, - 0x06D5, - 0x20AA, - 0x05BE, - 0x05C3, - 0x05D0, - 0x05D1, - 0x05D2, - 0x05D3, - 0x05D4, - 0x05D5, - 0x05D6, - 0x05D7, - 0x05D8, - 0x05D9, - 0x05DA, - 0x05DB, - 0x05DC, - 0x05DD, - 0x05DE, - 0x05DF, - 0x05E0, - 0x05E1, - 0x05E2, - 0x05E3, - 0x05E4, - 0x05E5, - 0x05E6, - 0x05E7, - 0x05E8, - 0x05E9, - 0x05EA, - 0xFB2A, - 0xFB2B, - 0xFB4B, - 0xFB1F, - 0x05F0, - 0x05F1, - 0x05F2, - 0xFB35, - 0x05B4, - 0x05B5, - 0x05B6, - 0x05BB, - 0x05B8, - 0x05B7, - 0x05B0, - 0x05B2, - 0x05B1, - 0x05B3, - 0x05C2, - 0x05C1, - 0x05B9, - 0x05BC, - 0x05BD, - 0x05BF, - 0x05C0, - 0x02BC, - 0x2105, - 0x2113, - 0x2116, - 0x202C, - 0x202D, - 0x202E, - 0x200C, - 0x066D, - 0x02BD, - 0x2135, - 0x03B1, - 0x03AC, - 0x0101, - 0x2220, - 0x2329, - 0x232A, - 0x0387, - 0x0105, - 0x01FB, - 0x2194, - 0x21D4, - 0x21D3, - 0x21D0, - 0x21D2, - 0x21D1, - 0x2193, - 0xF8E7, - 0x2190, - 0x2192, - 0x2191, - 0x2195, - 0x21A8, - 0xF8E6, - 0x2217, - 0x03B2, - 0x2588, - 0xF8F4, - 0xF8F3, - 0xF8F2, - 0xF8F1, - 0xF8FE, - 0xF8FD, - 0xF8FC, - 0xF8F0, - 0xF8EF, - 0xF8EE, - 0xF8FB, - 0xF8FA, - 0xF8F9, - 0x21B5, - 0x0109, - 0x010B, - 0x03C7, - 0x25CB, - 0x2297, - 0x2295, - 0x2663, - 0xF6C3, - 0x2245, - 0xF8E9, - 0xF6D9, - 0xF6D1, - 0xF6D2, - 0xF6D4, - 0xF6D5, - 0xF6D3, - 0xF6D6, - 0x010F, - 0x0111, - 0x03B4, - 0x2666, - 0xF6D7, - 0xF6D8, - 0x0385, - 0x2593, - 0x2584, - 0x20AB, - 0x0323, - 0xF6BE, - 0x22C5, - 0x0115, - 0x011B, - 0x0117, - 0x2208, - 0x0113, - 0x2205, - 0x014B, - 0x0119, - 0x03B5, - 0x03AD, - 0x2261, - 0x212E, - 0x03B7, - 0x03AE, - 0x203C, - 0x2203, - 0x2640, - 0x25A0, - 0x25AC, - 0x03B3, - 0x01E7, - 0x011D, - 0x0123, - 0x0121, - 0x2207, - 0x0300, - 0x0127, - 0x0125, - 0x2665, - 0x0309, - 0x2302, - 0x012D, - 0x0133, - 0x012B, - 0x2321, - 0xF8F5, - 0x2320, - 0x2229, - 0x25D8, - 0x25D9, - 0x263B, - 0x012F, - 0x03B9, - 0x03CA, - 0x0390, - 0x03AF, - 0x0129, - 0x0135, - 0x03BA, - 0x0137, - 0x0138, - 0x013A, - 0x03BB, - 0x013E, - 0x013C, - 0x0140, - 0x258C, - 0x20A4, - 0xF6C0, - 0x2227, - 0x2228, - 0x017F, - 0x2591, - 0x2642, - 0x2032, - 0x266A, - 0x266B, - 0x0144, - 0x0149, - 0x0148, - 0x0146, - 0x2209, - 0x2284, - 0x03BD, - 0x014F, - 0x01A1, - 0x0151, - 0x014D, - 0x03C9, - 0x03D6, - 0x03CE, - 0x03BF, - 0x03CC, - 0x25E6, - 0x221F, - 0x01FF, - 0xF8ED, - 0xF8EC, - 0xF8EB, - 0xF8F8, - 0xF8F7, - 0xF8F6, - 0x22A5, - 0x20A7, - 0x03C6, - 0x03D5, - 0x211E, - 0x2282, - 0x2283, - 0x221D, - 0x03C8, - 0x201B, - 0x0155, - 0xF8E5, - 0x0159, - 0x0157, - 0x2286, - 0x2287, - 0xF8E8, - 0xF6DA, - 0x2310, - 0x03C1, - 0x2590, - 0x015B, - 0x015D, - 0x0219, - 0x2033, - 0x2592, - 0x03C3, - 0x03C2, - 0x223C, - 0x263A, - 0x2660, - 0x220B, - 0x263C, - 0x03C4, - 0x0167, - 0x0165, - 0x0163, - 0x0163, - 0x2234, - 0x03B8, - 0x03D1, - 0x0303, - 0x0384, - 0xF8EA, - 0xF6DB, - 0x25BC, - 0x25C4, - 0x25BA, - 0x25B2, - 0x016D, - 0x01B0, - 0x0171, - 0x016B, - 0x2017, - 0x222A, - 0x2200, - 0x0173, - 0x2580, - 0x03C5, - 0x03CB, - 0x03B0, - 0x03CD, - 0x016F, - 0x0169, - 0x1E83, - 0x0175, - 0x1E85, - 0x2118, - 0x1E81, - 0x03BE, - 0x0177, - 0x1EF3, - 0x017A, - 0x017C, - 0x03B6, - -#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ - 0 - }; - - - - static const unsigned short t1_standard_encoding[257] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 0, - 111, - 112, - 113, - 114, - 0, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 0, - 123, - 0, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 0, - 132, - 133, - 0, - 134, - 135, - 136, - 137, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 138, - 0, - 139, - 0, - 0, - 0, - 0, - 140, - 141, - 142, - 143, - 0, - 0, - 0, - 0, - 0, - 144, - 0, - 0, - 0, - 145, - 0, - 0, - 146, - 147, - 148, - 149, - 0, - 0, - 0, - 0, - 0 - }; - - - static const unsigned short t1_expert_encoding[257] = - { - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 229, - 230, - 0, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 13, - 14, - 15, - 99, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 27, - 28, - 249, - 250, - 251, - 252, - 0, - 253, - 254, - 255, - 256, - 257, - 0, - 0, - 0, - 258, - 0, - 0, - 259, - 260, - 261, - 262, - 0, - 0, - 263, - 264, - 265, - 0, - 266, - 109, - 110, - 267, - 268, - 269, - 0, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 304, - 305, - 306, - 0, - 0, - 307, - 308, - 309, - 310, - 311, - 0, - 312, - 0, - 0, - 312, - 0, - 0, - 314, - 315, - 0, - 0, - 316, - 317, - 318, - 0, - 0, - 0, - 158, - 155, - 163, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 0, - 0, - 326, - 150, - 164, - 169, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378, - 0 - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/psnames/rules.mk b/subsys/win32k/freetype/src/psnames/rules.mk deleted file mode 100644 index 25552b2..0000000 --- a/subsys/win32k/freetype/src/psnames/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 PSNames driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# PSNames driver directory -# -PSNAMES_DIR := $(SRC_)psnames -PSNAMES_DIR_ := $(PSNAMES_DIR)$(SEP) - - -# compilation flags for the driver -# -PSNAMES_COMPILE := $(FT_COMPILE) - - -# PSNames driver sources (i.e., C files) -# -PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c - - -# PSNames driver headers -# -PSNAMES_DRV_H := $(PSNAMES_DRV_SRC:%.c=%.h) \ - $(PSNAMES_DIR_)pstables.h - - -# PSNames driver object(s) -# -# PSNAMES_DRV_OBJ_M is used during `multi' builds -# PSNAMES_DRV_OBJ_S is used during `single' builds -# -PSNAMES_DRV_OBJ_M := $(PSNAMES_DRV_SRC:$(PSNAMES_DIR_)%.c=$(OBJ_)%.$O) -PSNAMES_DRV_OBJ_S := $(OBJ_)psnames.$O - -# PSNames driver source file for single build -# -PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c - - -# PSNames driver - single object -# -$(PSNAMES_DRV_OBJ_S): $(PSNAMES_DRV_SRC_S) $(PSNAMES_DRV_SRC) \ - $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $(PSNAMES_DRV_SRC_S) - - -# PSNames driver - multiple objects -# -$(OBJ_)%.$O: $(PSNAMES_DIR_)%.c $(FREETYPE_H) $(PSNAMES_DRV_H) - $(PSNAMES_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(PSNAMES_DRV_OBJ_S) -DRV_OBJS_M += $(PSNAMES_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/raster1/.cvsignore b/subsys/win32k/freetype/src/raster1/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/raster1/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/raster1/ftraster.c b/subsys/win32k/freetype/src/raster1/ftraster.c deleted file mode 100644 index 65d0405..0000000 --- a/subsys/win32k/freetype/src/raster1/ftraster.c +++ /dev/null @@ -1,3300 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.c */ -/* */ -/* The FreeType glyph rasterizer (body). */ -/* */ -/* Copyright 1996-2000 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 a rewrite of the FreeType 1.x scan-line converter */ - /* */ - /*************************************************************************/ - - -#include "ftraster.h" -#include /* for FT_MulDiv() only */ - - - /*************************************************************************/ - /* */ - /* A simple technical note on how the raster works */ - /* ----------------------------------------------- */ - /* */ - /* Converting an outline into a bitmap is achieved in several steps: */ - /* */ - /* 1 - Decomposing the outline into successive `profiles'. Each */ - /* profile is simply an array of scanline intersections on a given */ - /* dimension. A profile's main attributes are */ - /* */ - /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ - /* */ - /* o an array of intersection coordinates for each scanline */ - /* between `Ymin' and `Ymax'. */ - /* */ - /* o a direction, indicating whether it was built going `up' or */ - /* `down', as this is very important for filling rules. */ - /* */ - /* 2 - Sweeping the target map's scanlines in order to compute segment */ - /* `spans' which are then filled. Additionally, this pass */ - /* performs drop-out control. */ - /* */ - /* The outline data is parsed during step 1 only. The profiles are */ - /* built from the bottom of the render pool, used as a stack. The */ - /* following graphics shows the profile list under construction: */ - /* */ - /* ____________________________________________________________ _ _ */ - /* | | | | | */ - /* | profile | coordinates for | profile | coordinates for |--> */ - /* | 1 | profile 1 | 2 | profile 2 |--> */ - /* |_________|___________________|_________|_________________|__ _ _ */ - /* */ - /* ^ ^ */ - /* | | */ - /* start of render pool top */ - /* */ - /* The top of the profile stack is kept in the `top' variable. */ - /* */ - /* As you can see, a profile record is pushed on top of the render */ - /* pool, which is then followed by its coordinates/intersections. If */ - /* a change of direction is detected in the outline, a new profile is */ - /* generated until the end of the outline. */ - /* */ - /* Note that when all profiles have been generated, the function */ - /* Finalize_Profile_Table() is used to record, for each profile, its */ - /* bottom-most scanline as well as the scanline above its upmost */ - /* boundary. These positions are called `y-turns' because they (sort */ - /* of) correspond to local extrema. They are stored in a sorted list */ - /* built from the top of the render pool as a downwards stack: */ - /* */ - /* _ _ _______________________________________ */ - /* | | */ - /* <--| sorted list of | */ - /* <--| extrema scanlines | */ - /* _ _ __________________|____________________| */ - /* */ - /* ^ ^ */ - /* | | */ - /* maxBuff sizeBuff = end of pool */ - /* */ - /* This list is later used during the sweep phase in order to */ - /* optimize performance (see technical note on the sweep below). */ - /* */ - /* Of course, the raster detects whether the two stacks collide and */ - /* handles the situation propertly. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** CONFIGURATION MACROS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /* define DEBUG_RASTER if you want to compile a debugging version */ -#define xxxDEBUG_RASTER - - /* The default render pool size in bytes */ -#define RASTER_RENDER_POOL 8192 - - /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ - /* 5-levels anti-aliasing */ -#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS -#define FT_RASTER_OPTION_ANTI_ALIASING -#endif - - /* The size of the two-lines intermediate bitmap used */ - /* for anti-aliasing, in bytes. */ -#define RASTER_GRAY_LINES 2048 - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** OTHER MACROS (do not change) **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_raster - - -#ifdef _STANDALONE_ - - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ -#ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ -#endif - -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif - -#define Raster_Err_None 0 -#define Raster_Err_Not_Ini -1 -#define Raster_Err_Overflow -2 -#define Raster_Err_Neg_Height -3 -#define Raster_Err_Invalid -4 -#define Raster_Err_Unsupported -5 - - -#else /* _STANDALONE_ */ - - -#include -#include /* for FT_TRACE() and FT_ERROR() */ - -#define Raster_Err_None FT_Err_Ok -#define Raster_Err_Not_Ini FT_Err_Raster_Uninitialized -#define Raster_Err_Overflow FT_Err_Raster_Overflow -#define Raster_Err_Neg_Height FT_Err_Raster_Negative_Height -#define Raster_Err_Invalid FT_Err_Invalid_Outline -#define Raster_Err_Unsupported FT_Err_Unimplemented_Feature - - -#endif /* _STANDALONE_ */ - - - /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ - /* typically a small value and the result of a*b is known to fit into */ - /* 32 bits. */ -#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) - - /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ - /* for clipping computations. It simply uses the FT_MulDiv() function */ - /* defined in `ftcalc.h'. */ -#define SMulDiv FT_MulDiv - - /* 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 - -#ifndef SUCCESS -#define SUCCESS 0 -#endif - -#ifndef FAILURE -#define FAILURE 1 -#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 */ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SIMPLE TYPE DECLARATIONS **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - typedef int Int; - typedef unsigned int UInt; - typedef short Short; - typedef unsigned short UShort, *PUShort; - typedef long Long, *PLong; - typedef unsigned long ULong; - - typedef unsigned char Byte, *PByte; - typedef char Bool; - - typedef struct TPoint_ - { - Long x; - Long y; - - } TPoint; - - - typedef enum TFlow_ - { - Flow_None = 0, - Flow_Up = 1, - Flow_Down = -1 - - } TFlow; - - - /* States of each line, arc, and profile */ - typedef enum TStates_ - { - Unknown, - Ascending, - Descending, - Flat - - } TStates; - - - typedef struct TProfile_ TProfile; - typedef TProfile* PProfile; - - struct TProfile_ - { - FT_F26Dot6 X; /* current coordinate during sweep */ - PProfile link; /* link to next profile - various purpose */ - PLong 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; - - - /* Simple record used to implement a stack of bands, required */ - /* by the sub-banding mechanism */ - typedef struct TBand_ - { - Short y_min; /* band's minimum */ - Short y_max; /* band's maximum */ - - } TBand; - - -#define AlignProfileSize \ - ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) ) - - -#ifdef TT_STATIC_RASTER - - -#define RAS_ARGS /* void */ -#define RAS_ARG /* void */ - -#define RAS_VARS /* void */ -#define RAS_VAR /* void */ - -#define FT_UNUSED_RASTER do ; while ( 0 ) - - -#else /* TT_STATIC_RASTER */ - - -#define RAS_ARGS TRaster_Instance* raster, -#define RAS_ARG TRaster_Instance* raster - -#define RAS_VARS raster, -#define RAS_VAR raster - -#define FT_UNUSED_RASTER FT_UNUSED( raster ) - - -#endif /* TT_STATIC_RASTER */ - - - typedef struct TRaster_Instance_ TRaster_Instance; - - - /* 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, - FT_F26Dot6 x1, - FT_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 ) - - /* 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 */ - - PLong buff; /* The profiles buffer */ - PLong sizeBuff; /* Render pool size */ - PLong maxBuff; /* Profiles buffer size */ - PLong top; /* Current cursor in buffer */ - - FT_Error error; - - 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 */ - - FT_Bitmap target; /* description of target bit/pixmap */ - FT_Outline outline; - - 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; - - Byte dropOutControl; /* current drop_out control method */ - - 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 */ - - void* memory; - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - Byte grays[5]; /* Palette of gray levels used for */ - /* render. */ - - Byte gray_lines[RASTER_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'. */ - -#endif /* FT_RASTER_ANTI_ALIASING */ - -#if 0 - PByte flags; /* current flags table */ - PUShort outs; /* current outlines table */ - FT_Vector* coords; - - UShort nPoints; /* number of points in current glyph */ - Short nContours; /* number of contours in current glyph */ -#endif - - }; - - -#ifdef FT_CONFIG_OPTION_STATIC_RASTER - - static TRaster_Instance cur_ras; -#define ras cur_ras - -#else - -#define ras (*raster) - -#endif /* FT_CONFIG_OPTION_STATIC_RASTER */ - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** PROFILES COMPUTATION **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_High_Precision */ - /* */ - /* */ - /* Sets precision variables according to param flag. */ - /* */ - /* */ - /* High :: Set to True for high precision (typically for ppem < 18), */ - /* false otherwise. */ - /* */ - static - void Set_High_Precision( RAS_ARGS Int 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; - } - - FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); - - ras.precision = 1L << ras.precision_bits; - ras.precision_half = ras.precision / 2; - ras.precision_shift = ras.precision_bits - Pixel_Bits; - ras.precision_mask = -ras.precision; - } - - - /*************************************************************************/ - /* */ - /* */ - /* New_Profile */ - /* */ - /* */ - /* Creates a new profile in the render pool. */ - /* */ - /* */ - /* aState :: The state/orientation of the new profile. */ - /* */ - /* */ - /* 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 = Flow_Up; - FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); - break; - - case Descending: - ras.cProfile->flow = Flow_Down; - FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); - break; - - default: - FT_ERROR(( "New_Profile: invalid profile direction!\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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* End_Profile */ - /* */ - /* */ - /* Finalizes the current profile. */ - /* */ - /* */ - /* 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 ) - { - FT_ERROR(( "End_Profile: negative height encountered!\n" )); - ras.error = Raster_Err_Neg_Height; - return FAILURE; - } - - if ( h > 0 ) - { - FT_TRACE6(( "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 ) - { - FT_TRACE1(( "overflow in End_Profile\n" )); - ras.error = Raster_Err_Overflow; - return FAILURE; - } - - ras.joint = FALSE; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Insert_Y_Turn */ - /* */ - /* */ - /* Inserts a salient into the sorted list placed on top of the render */ - /* pool. */ - /* */ - /* */ - /* New y scanline position. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - static - Bool Insert_Y_Turn( RAS_ARGS Int y ) - { - PLong 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Finalize_Profile_Table */ - /* */ - /* */ - /* Adjusts all links in the profiles list. */ - /* */ - /* */ - /* SUCCESS on success. FAILURE in case of overflow. */ - /* */ - 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 Flow_Down: - bottom = p->start - p->height+1; - top = p->start; - p->start = bottom; - p->offset += p->height - 1; - break; - - case 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Split_Conic */ - /* */ - /* */ - /* Subdivides one conic Bezier into two joint sub-arcs in the Bezier */ - /* stack. */ - /* */ - /* */ - /* None (subdivided Bezier is taken from the top of the stack). */ - /* */ - /* */ - /* 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_Conic( 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 to be too good at common */ - /* expression substitution and instruction scheduling ;-) */ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Split_Cubic */ - /* */ - /* */ - /* Subdivides a third-order Bezier arc into two joint sub-arcs in the */ - /* Bezier stack. */ - /* */ - /* */ - /* This routine is the `beef' of the component. It is one of _the_ */ - /* inner loops that should be optimized like hell to get the best */ - /* performance. */ - /* */ - static - void Split_Cubic( TPoint* base ) - { - Long a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c + 1 ) >> 1; - base[5].x = b = ( base[3].x + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].x = a = ( a + c + 1 ) >> 1; - base[4].x = b = ( b + c + 1 ) >> 1; - base[3].x = ( a + b + 1 ) >> 1; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c + 1 ) >> 1; - base[5].y = b = ( base[3].y + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].y = a = ( a + c + 1 ) >> 1; - base[4].y = b = ( b + c + 1 ) >> 1; - base[3].y = ( a + b + 1 ) >> 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_Up */ - /* */ - /* */ - /* Computes the x-coordinates of an ascending line segment and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* 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; - - PLong 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; - - x1 += Ix; - Ax += Rx; - if ( Ax >= 0 ) - { - Ax -= Dy; - x1 += Dx; - } - size--; - } - - ras.top = top; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_Down */ - /* */ - /* */ - /* Computes the x-coordinates of an descending line segment and */ - /* stores them in the render pool. */ - /* */ - /* */ - /* x1 :: The x-coordinate of the segment's start point. */ - /* */ - /* y1 :: The y-coordinate of the segment's start point. */ - /* */ - /* x2 :: The x-coordinate of the segment's end point. */ - /* */ - /* y2 :: The y-coordinate of the segment's end point. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - 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; - } - - - /* A function type describing the functions used to split Bezier arcs */ - typedef void (*TSplitter)( TPoint* base ); - - - /*************************************************************************/ - /* */ - /* */ - /* Bezier_Up */ - /* */ - /* */ - /* Computes the x-coordinates of an ascending Bezier arc and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Bezier_Up( RAS_ARGS Int degree, - TSplitter splitter, - Long miny, - Long maxy ) - { - Long y1, y2, e, e2, e0; - Short f1; - - TPoint* arc; - TPoint* start_arc; - - PLong top; - - - arc = ras.arc; - y1 = arc[degree].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[degree].x; - - 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[degree].y; - if ( y2 - y1 >= ras.precision_step ) - { - splitter( arc ); - arc += degree; - } - else - { - *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, - e - y1, y2 - y1 ); - arc -= degree; - e += ras.precision; - } - } - else - { - if ( y2 == e ) - { - ras.joint = TRUE; - *top++ = arc[0].x; - - e += ras.precision; - } - arc -= degree; - } - } - - Fin: - ras.top = top; - ras.arc -= degree; - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Bezier_Down */ - /* */ - /* */ - /* Computes the x-coordinates of an descending Bezier arc and stores */ - /* them in the render pool. */ - /* */ - /* */ - /* degree :: The degree of the Bezier arc (either 2 or 3). */ - /* */ - /* splitter :: The function to split Bezier arcs. */ - /* */ - /* miny :: A lower vertical clipping bound value. */ - /* */ - /* maxy :: An upper vertical clipping bound value. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow. */ - /* */ - static - Bool Bezier_Down( RAS_ARGS Int degree, - TSplitter splitter, - 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; - if ( degree > 2 ) - arc[3].y = -arc[3].y; - - fresh = ras.fresh; - - result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); - - if ( fresh && !ras.fresh ) - ras.cProfile->start = -ras.cProfile->start; - - arc[0].y = -arc[0].y; - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Line_To */ - /* */ - /* */ - /* Injects a new line segment and adjusts Profiles list. */ - /* */ - /* */ - /* x :: The x-coordinate of the segment's end point (its start point */ - /* is stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the segment's end point (its start point */ - /* is stored in `LastY'). */ - /* */ - /* */ - /* 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Conic_To */ - /* */ - /* */ - /* Injects a new conic arc and adjusts the profile list. */ - /* */ - /* */ - /* cx :: The x-coordinate of the arc's new control point. */ - /* */ - /* cy :: The y-coordinate of the arc's new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `LastY'). */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static - Bool Conic_To( RAS_ARGS Long cx, - Long cy, - Long x, - Long y ) - { - Long y1, y2, y3, x3, ymin, ymax; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[2].x = ras.lastX; - ras.arc[2].y = ras.lastY; - ras.arc[1].x = cx; ras.arc[1].y = cy; - ras.arc[0].x = x; ras.arc[0].y = 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 <= y3 ) - { - ymin = y1; - ymax = y3; - } - else - { - ymin = y3; - ymax = y1; - } - - if ( y2 < ymin || y2 > ymax ) - { - /* this arc has no given direction, split it! */ - Split_Conic( ras.arc ); - ras.arc += 2; - } - else if ( y1 == y3 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 2; - } - else - { - /* the arc is y-monotonous, either ascending or descending */ - /* detect a change of direction */ - state_bez = y1 < y3 ? Ascending : Descending; - if ( ras.state != state_bez ) - { - /* finalize current profile if any */ - if ( ras.state != Unknown && - End_Profile( RAS_VAR ) ) - goto Fail; - - /* create a new profile */ - if ( New_Profile( RAS_VARS state_bez ) ) - goto Fail; - } - - /* now call the appropriate routine */ - if ( state_bez == Ascending ) - { - if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x3; - ras.lastY = y3; - - return SUCCESS; - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Cubic_To */ - /* */ - /* */ - /* Injects a new cubic arc and adjusts the profile list. */ - /* */ - /* */ - /* cx1 :: The x-coordinate of the arc's first new control point. */ - /* */ - /* cy1 :: The y-coordinate of the arc's first new control point. */ - /* */ - /* cx2 :: The x-coordinate of the arc's second new control point. */ - /* */ - /* cy2 :: The y-coordinate of the arc's second new control point. */ - /* */ - /* x :: The x-coordinate of the arc's end point (its start point is */ - /* stored in `LastX'). */ - /* */ - /* y :: The y-coordinate of the arc's end point (its start point is */ - /* stored in `LastY'). */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ - /* profile. */ - /* */ - static - Bool Cubic_To( RAS_ARGS Long cx1, - Long cy1, - Long cx2, - Long cy2, - Long x, - Long y ) - { - Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; - TStates state_bez; - - - ras.arc = ras.arcs; - ras.arc[3].x = ras.lastX; - ras.arc[3].y = ras.lastY; - ras.arc[2].x = cx1; ras.arc[2].y = cy1; - ras.arc[1].x = cx2; ras.arc[1].y = cy2; - ras.arc[0].x = x; ras.arc[0].y = y; - - do - { - y1 = ras.arc[3].y; - y2 = ras.arc[2].y; - y3 = ras.arc[1].y; - y4 = ras.arc[0].y; - x4 = ras.arc[0].x; - - /* first, categorize the Bezier arc */ - - if ( y1 <= y4 ) - { - ymin1 = y1; - ymax1 = y4; - } - else - { - ymin1 = y4; - ymax1 = y1; - } - - if ( y2 <= y3 ) - { - ymin2 = y2; - ymax2 = y3; - } - else - { - ymin2 = y3; - ymax2 = y2; - } - - if ( ymin2 < ymin1 || ymax2 > ymax1 ) - { - /* this arc has no given direction, split it! */ - Split_Cubic( ras.arc ); - ras.arc += 3; - } - else if ( y1 == y4 ) - { - /* this arc is flat, ignore it and pop it from the Bezier stack */ - ras.arc -= 3; - } - else - { - state_bez = ( y1 <= y4 ) ? Ascending : Descending; - - /* detect a change of direction */ - if ( ras.state != state_bez ) - { - if ( ras.state != Unknown && - End_Profile( RAS_VAR ) ) - goto Fail; - - if ( New_Profile( RAS_VARS state_bez ) ) - goto Fail; - } - - /* compute intersections */ - if ( state_bez == Ascending ) - { - if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - else - if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) - goto Fail; - } - - } while ( ras.arc >= ras.arcs ); - - ras.lastX = x4; - ras.lastY = y4; - - return SUCCESS; - - Fail: - return FAILURE; - } - - -#undef SWAP_ -#define SWAP_( x, y ) do \ - { \ - Long swap = x; \ - \ - \ - x = y; \ - y = swap; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* Decompose_Curve */ - /* */ - /* */ - /* 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! */ - /* */ - /* */ - /* first :: The index of the first point in the contour. */ - /* */ - /* last :: The index of the last point in the contour. */ - /* */ - /* flipped :: If set, flip the direction of the curve. */ - /* */ - /* */ - /* SUCCESS on success, FAILURE on error. */ - /* */ - static - Bool Decompose_Curve( RAS_ARGS UShort first, - UShort last, - int flipped ) - { - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* points; - FT_Vector* point; - FT_Vector* limit; - char* tags; - - char tag; /* current point's state */ - - - points = ras.outline.points; - limit = points + last; - - v_start.x = SCALED( points[first].x ); - v_start.y = SCALED( points[first].y ); - v_last.x = SCALED( points[last].x ); - v_last.y = SCALED( points[last].y ); - - if ( flipped ) - { - SWAP_( v_start.x, v_start.y ); - SWAP_( v_last.x, v_last.y ); - } - - v_control = v_start; - - point = points + first; - tags = ras.outline.tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_Curve_Tag_Conic ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_Curve_Tag_On ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - ras.lastX = v_start.x; - ras.lastY = v_start.y; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - - switch ( tag ) - { - case FT_Curve_Tag_On: /* emit a single line_to */ - { - Long x, y; - - - x = SCALED( point->x ); - y = SCALED( point->y ); - if ( flipped ) - SWAP_( x, y ); - - if ( Line_To( RAS_VARS x, y ) ) - goto Fail; - continue; - } - - case FT_Curve_Tag_Conic: /* consume conic arcs */ - v_control.x = SCALED( point[0].x ); - v_control.y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( v_control.x, v_control.y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector v_middle; - Long x, y; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - x = SCALED( point[0].x ); - y = SCALED( point[0].y ); - - if ( flipped ) - SWAP_( x, y ); - - if ( tag == FT_Curve_Tag_On ) - { - if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) - goto Fail; - continue; - } - - if ( tag != FT_Curve_Tag_Conic ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + x ) / 2; - v_middle.y = ( v_control.y + y ) / 2; - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_middle.x, v_middle.y ) ) - goto Fail; - - v_control.x = x; - v_control.y = y; - - goto Do_Conic; - } - - if ( Conic_To( RAS_VARS v_control.x, v_control.y, - v_start.x, v_start.y ) ) - goto Fail; - - goto Close; - - default: /* FT_Curve_Tag_Cubic */ - { - Long x1, y1, x2, y2, x3, y3; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - x1 = SCALED( point[-2].x ); - y1 = SCALED( point[-2].y ); - x2 = SCALED( point[-1].x ); - y2 = SCALED( point[-1].y ); - x3 = SCALED( point[ 0].x ); - y3 = SCALED( point[ 0].y ); - - if ( flipped ) - { - SWAP_( x1, y1 ); - SWAP_( x2, y2 ); - SWAP_( x3, y3 ); - } - - if ( point <= limit ) - { - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) - goto Fail; - continue; - } - - if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) - goto Fail; - goto Close; - } - } - } - - /* close the contour with a line segment */ - if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) - goto Fail; - - Close: - return SUCCESS; - - Invalid_Outline: - ras.error = Raster_Err_Invalid; - - Fail: - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Convert_Glyph */ - /* */ - /* */ - /* Converts a glyph into a series of segments and arcs and makes a */ - /* profiles list with them. */ - /* */ - /* */ - /* flipped :: If set, flip the direction of curve. */ - /* */ - /* */ - /* 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.outline.n_contours; i++ ) - { - ras.state = Unknown; - ras.gProfile = NULL; - - if ( Decompose_Curve( RAS_VARS start, ras.outline.contours[i], flipped ) ) - return FAILURE; - - start = ras.outline.contours[i] + 1; - - /* We must now see whether 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 ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /** **/ - /** SCAN-LINE SWEEPS AND DRAWING **/ - /** **/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Init_Linked */ - /* */ - /* Initializes 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 four 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 ) - { - Long pitch = ras.target.pitch; - - FT_UNUSED( max ); - - - ras.traceIncr = (Short)-pitch; - ras.traceOfs = -*min * pitch; - if ( pitch > 0 ) - ras.traceOfs += ( ras.target.rows - 1 ) * pitch; - - ras.gray_min_x = 0; - ras.gray_max_x = 0; - } - - - static - void Vertical_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - Short c1, c2; - Byte f1, f2; - Byte* target; - - FT_UNUSED( y ); - FT_UNUSED( left ); - FT_UNUSED( right ); - - - /* 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 = (unsigned char)0xFF >> ( e1 & 7 ); - f2 = ~( (unsigned char)0x7F >> ( 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; - c2 -= c1; - - if ( c2 > 0 ) - { - target[0] |= f1; - - /* memset() is slower than the following code on many platforms. */ - /* This is due to the fact that, in the vast majority of cases, */ - /* the span length in bytes is relatively small. */ - c2--; - while ( c2 > 0 ) - { - *(++target) = 0xFF; - c2--; - } - target[1] |= f2; - } - else - *target |= ( f1 & f2 ); - } - } - - - static - void Vertical_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_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 if: */ - /* */ - /* 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 0 - if ( x2 - x1 < ras.precision_half ) -#endif - { - /* 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 four 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 */ - FT_UNUSED( raster ); - FT_UNUSED( min ); - FT_UNUSED( max ); - } - - - static - void Horizontal_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - Long e1, e2; - PByte bits; - Byte f1; - - FT_UNUSED( left ); - FT_UNUSED( right ); - - - 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 ) - { - PByte p; - - - p = bits - e1*ras.target.pitch; - if ( ras.target.pitch > 0 ) - p += ( ras.target.rows - 1 ) * ras.target.pitch; - - p[0] |= f1; - } - } - } - } - - - static - void Horizontal_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_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 ) ); - - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - 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 ) - { - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += ( ras.target.rows - 1 ) * ras.target.pitch; - - bits[0] |= f1; - } - } - - - static - void Horizontal_Sweep_Step( RAS_ARG ) - { - /* Nothing, really */ - FT_UNUSED( raster ); - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* 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 ) - { - Long pitch, byte_len; - - - *min = *min & -2; - *max = ( *max + 3 ) & -2; - - ras.traceOfs = 0; - pitch = ras.target.pitch; - byte_len = -pitch; - ras.traceIncr = (Short)byte_len; - ras.traceG = ( *min / 2 ) * byte_len; - - if ( pitch > 0 ) - { - ras.traceG += ( ras.target.rows - 1 ) * pitch; - byte_len = -byte_len; - } - - ras.gray_min_x = (Short)byte_len; - ras.gray_max_x = -(Short)byte_len; - } - - - 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 ) - { - Long last_pixel = ras.target.width - 1; - Int last_cell = last_pixel >> 2; - Int last_bit = last_pixel & 3; - Bool over = 0; - - - if ( ras.gray_max_x >= last_cell && last_bit != 3 ) - { - ras.gray_max_x = last_cell - 1; - over = 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 >> 12) & 0x000F]; - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - pix[3] = grays[ c2 & 0x000F]; - - *bit = 0; - *bit2 = 0; - } - - bit++; - bit2++; - pix += 4; - c1--; - } - - if ( over ) - { - c2 = count[*bit] + count[*bit2]; - if ( c2 ) - { - switch ( last_bit ) - { - case 2: - pix[2] = grays[(c2 >> 4 ) & 0x000F]; - case 1: - pix[1] = grays[(c2 >> 8 ) & 0x000F]; - default: - pix[0] = grays[(c2 >> 12) & 0x000F]; - } - - *bit = 0; - *bit2 = 0; - } - } - } - - ras.traceOfs = 0; - ras.traceG += ras.traceIncr; - - ras.gray_min_x = 32000; - ras.gray_max_x = -32000; - } - } - - - static - void Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_F26Dot6 x2, - PProfile left, - PProfile right ) - { - /* nothing, really */ - FT_UNUSED( raster ); - FT_UNUSED( y ); - FT_UNUSED( x1 ); - FT_UNUSED( x2 ); - FT_UNUSED( left ); - FT_UNUSED( right ); - } - - - static - void Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, - FT_F26Dot6 x1, - FT_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 ) - { - pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; - if ( ras.target.pitch > 0 ) - pixel += ( ras.target.rows - 1 ) * ras.target.pitch; - - if ( pixel[0] == ras.grays[0] ) - pixel[0] = color; - } - } - } - - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - /*************************************************************************/ - /* */ - /* 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 = (Short)P->start; - top = (Short)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 Flow_Up: - InsNew( &draw_left, P ); - break; - - case 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; -#if 0 - dropouts--; /* -- this is useful when debugging only */ -#endif - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Single_Pass */ - /* */ - /* */ - /* Performs one sweep with sub-banding. */ - /* */ - /* */ - /* flipped :: If set, flip the direction of the outline. */ - /* */ - /* */ - /* Renderer error code. */ - /* */ - static - int 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 SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Glyph */ - /* */ - /* */ - /* Renders a glyph in a bitmap. Sub-banding if needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* XXX Fixme: ftraster's error codes don't harmonize with FT2's ones! */ - /* */ - LOCAL_FUNC - FT_Error Render_Glyph( RAS_ARG ) - { - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - ft_outline_high_precision ); - ras.scale_shift = ras.precision_shift; - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & ft_outline_single_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.buffer; - - 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 FT_Err_Ok; - } - - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - - /*************************************************************************/ - /* */ - /* */ - /* Render_Gray_Glyph */ - /* */ - /* */ - /* Renders a glyph with grayscaling. Sub-banding if needed. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Render_Gray_Glyph( RAS_ARG ) - { - Long pixel_width; - FT_Error error; - - - Set_High_Precision( RAS_VARS ras.outline.flags & - ft_outline_high_precision ); - ras.scale_shift = ras.precision_shift + 1; - ras.dropOutControl = 2; - ras.second_pass = !( ras.outline.flags & ft_outline_single_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; - pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); - - if ( ras.bWidth > pixel_width ) - ras.bWidth = pixel_width; - - ras.bWidth = ras.bWidth * 8; - ras.bTarget = (Byte*)ras.gray_lines; - ras.gTarget = (Byte*)ras.target.buffer; - - 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 FT_Err_Ok; - } - -#else /* FT_RASTER_OPTION_ANTI_ALIASING */ - - LOCAL_FUNC - FT_Error Render_Gray_Glyph( RAS_ARG ) - { - FT_UNUSED_RASTER; - - return FT_Err_Cannot_Render_Glyph; - } - -#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ - - - static - void ft_black_init( TRaster_Instance* raster ) - { - FT_UInt n; - FT_ULong c; - - - /* setup count table */ - for ( n = 0; n < 256; n++ ) - { - c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 ); - - c = ( ( c << 6 ) & 0x3000 ) | - ( ( c << 4 ) & 0x0300 ) | - ( ( c << 2 ) & 0x0030 ) | - (c & 0x0003 ); - - raster->count_table[n] = c; - } - -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - /* set default 5-levels gray palette */ - for ( n = 0; n < 5; n++ ) - raster->grays[n] = n * 255 / 4; - - raster->gray_width = RASTER_GRAY_LINES / 2; - -#endif - } - - - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ - - -#ifdef _STANDALONE_ - - - static - int ft_black_new( void* memory, - FT_Raster *araster ) - { - static FT_RasterRec_ the_raster; - - - *araster = &the_raster; - memset( &the_raster, sizeof ( the_raster ), 0 ); - ft_black_init( &the_raster ); - - return 0; - } - - - static - void ft_black_done( FT_Raster raster ) - { - /* nothing */ - raster->init = 0; - } - - -#else /* _STANDALONE_ */ - - - static - int ft_black_new( FT_Memory memory, - TRaster_Instance** araster ) - { - FT_Error error; - TRaster_Instance* raster; - - - *araster = 0; - if ( !ALLOC( raster, sizeof ( *raster ) ) ) - { - raster->memory = memory; - ft_black_init( raster ); - - *araster = raster; - } - - return error; - } - - - static - void ft_black_done( TRaster_Instance* raster ) - { - FT_Memory memory = (FT_Memory)raster->memory; - FREE( raster ); - } - - -#endif /* _STANDALONE_ */ - - - static - void ft_black_reset( TRaster_Instance* raster, - const char* pool_base, - long pool_size ) - { - if ( raster && pool_base && pool_size >= 4096 ) - { - /* save the pool */ - raster->buff = (PLong)pool_base; - raster->sizeBuff = raster->buff + pool_size / sizeof ( Long ); - } - } - - - static - void ft_black_set_mode( TRaster_Instance* raster, - unsigned long mode, - const char* palette ) - { -#ifdef FT_RASTER_OPTION_ANTI_ALIASING - - if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) - { - /* set 5-levels gray palette */ - raster->grays[0] = palette[0]; - raster->grays[1] = palette[1]; - raster->grays[2] = palette[2]; - raster->grays[3] = palette[3]; - raster->grays[4] = palette[4]; - } - -#else - - FT_UNUSED( raster ); - FT_UNUSED( mode ); - FT_UNUSED( palette ); - -#endif - } - - - static - int ft_black_render( TRaster_Instance* raster, - FT_Raster_Params* params ) - { - FT_Outline* outline = (FT_Outline*)params->source; - FT_Bitmap* target_map = params->target; - - - if ( !raster || !raster->buff || !raster->sizeBuff ) - return Raster_Err_Not_Ini; - - if ( !outline || !outline->contours || !outline->points ) - return Raster_Err_Invalid; - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return Raster_Err_None; - - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) - return Raster_Err_Invalid; - - if ( !target_map || !target_map->buffer ) - return Raster_Err_Invalid; - - /* this version of the raster does not support direct rendering, sorry */ - if ( params->flags & ft_raster_flag_direct ) - return Raster_Err_Unsupported; - - ras.outline = *outline; - ras.target = *target_map; - - return ( ( params->flags & ft_raster_flag_aa ) - ? Render_Gray_Glyph( raster ) - : Render_Glyph( raster ) ); - } - - - FT_Raster_Funcs ft_standard_raster = - { - ft_glyph_format_outline, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/raster1/ftraster.h b/subsys/win32k/freetype/src/raster1/ftraster.h deleted file mode 100644 index 5c7faae..0000000 --- a/subsys/win32k/freetype/src/raster1/ftraster.h +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftraster.h */ -/* */ -/* The FreeType glyph rasterizer (specification). */ -/* */ -/* Copyright 1996-2000 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 FTRASTER_H -#define FTRASTER_H - -#ifdef __cplusplus - extern "C" { -#endif - -#include - - - /*************************************************************************/ - /* */ - /* Uncomment the following line if you are using ftraster.c as a */ - /* standalone module, fully independent of FreeType. */ - /* */ -/* #define _STANDALONE_ */ - -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_standard_raster; - -#ifdef __cplusplus - } -#endif - - -#endif /* FTRASTER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/raster1/ftrend1.c b/subsys/win32k/freetype/src/raster1/ftrend1.c deleted file mode 100644 index 096b1e2..0000000 --- a/subsys/win32k/freetype/src/raster1/ftrend1.c +++ /dev/null @@ -1,275 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.c */ -/* */ -/* The FreeType glyph rasterizer interface (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ftrend1.h" -#include "ftraster.h" - -#else - -#include -#include - -#endif - - - /* initialize renderer -- init its raster */ - static - FT_Error ft_raster1_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return FT_Err_Ok; - } - - - /* set render-specific mode */ - static - FT_Error ft_raster1_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - - /* transform a given glyph image */ - static - FT_Error ft_raster1_transform( FT_Renderer render, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static - void ft_raster1_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - MEM_Set( cbox, 0, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static - FT_Error ft_raster1_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ) - { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; - - FT_Raster_Params params; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - /* check rendering mode */ - if ( mode != ft_render_mode_mono ) - { - /* raster1 is only capable of producing monochrome bitmaps */ - if ( render->clazz == &ft_raster1_renderer_class ) - return FT_Err_Cannot_Render_Glyph; - } - else - { - /* raster5 is only capable of producing 5-gray-levels bitmaps */ - if ( render->clazz == &ft_raster5_renderer_class ) - return FT_Err_Cannot_Render_Glyph; - } - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - - width = ( cbox.xMax - cbox.xMin ) >> 6; - height = ( cbox.yMax - cbox.yMin ) >> 6; - bitmap = &slot->bitmap; - memory = render->root.memory; - - /* release old bitmap buffer */ - if ( slot->flags & ft_glyph_own_bitmap ) - { - FREE( bitmap->buffer ); - slot->flags &= ~ft_glyph_own_bitmap; - } - - /* allocate new one, depends on pixel format */ - if ( !( mode & ft_render_mode_mono ) ) - { - /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ - pitch = ( width + 3 ) & -4; - bitmap->pixel_mode = ft_pixel_mode_grays; - bitmap->num_grays = 256; - } - else - { - pitch = ( width + 7 ) >> 3; - bitmap->pixel_mode = ft_pixel_mode_mono; - } - - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - if ( ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) - goto Exit; - - slot->flags |= ft_glyph_own_bitmap; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = 0; - - if ( bitmap->pixel_mode == ft_pixel_mode_grays ) - params.flags |= ft_raster_flag_aa; - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - slot->format = ft_glyph_format_bitmap; - slot->bitmap_left = cbox.xMin >> 6; - slot->bitmap_top = cbox.yMax >> 6; - - Exit: - return error; - } - - - const FT_Renderer_Class ft_raster1_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "raster1", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_raster1_render, - (FTRenderer_transform)ft_raster1_transform, - (FTRenderer_getCBox) ft_raster1_get_cbox, - (FTRenderer_setMode) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &ft_standard_raster - }; - - - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - const FT_Renderer_Class ft_raster5_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "raster5", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_raster1_render, - (FTRenderer_transform)ft_raster1_transform, - (FTRenderer_getCBox) ft_raster1_get_cbox, - (FTRenderer_setMode) ft_raster1_set_mode, - - (FT_Raster_Funcs*) &ft_standard_raster - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/raster1/ftrend1.h b/subsys/win32k/freetype/src/raster1/ftrend1.h deleted file mode 100644 index b8fff83..0000000 --- a/subsys/win32k/freetype/src/raster1/ftrend1.h +++ /dev/null @@ -1,37 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrend1.h */ -/* */ -/* The FreeType glyph rasterizer interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTREND1_H -#define FTREND1_H - -#include - - - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster1_renderer_class; - - /* this renderer is _NOT_ part of the default modules, you'll need */ - /* to register it by hand in your application. It should only be */ - /* used for backwards-compatibility with FT 1.x anyway. */ - /* */ - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_raster5_renderer_class; - - -#endif /* FTREND1_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/raster1/module.mk b/subsys/win32k/freetype/src/raster1/module.mk deleted file mode 100644 index c1ceb21..0000000 --- a/subsys/win32k/freetype/src/raster1/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_raster1_module - -add_raster1_module: - $(OPEN_DRIVER)ft_raster1_renderer_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)raster1 $(ECHO_DRIVER_DESC)monochrome bitmap renderer$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/raster1/raster1.c b/subsys/win32k/freetype/src/raster1/raster1.c deleted file mode 100644 index a77e775..0000000 --- a/subsys/win32k/freetype/src/raster1/raster1.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* raster1.c */ -/* */ -/* FreeType monochrome rasterer module component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ftraster.c" -#include "ftrend1.c" - -#else - -#include -#include - -#endif - - -/* END */ diff --git a/subsys/win32k/freetype/src/raster1/rules.mk b/subsys/win32k/freetype/src/raster1/rules.mk deleted file mode 100644 index 3810845..0000000 --- a/subsys/win32k/freetype/src/raster1/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# Copyright 1996-2000 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. - - -# raster1 driver directory -# -RAS1_DIR := $(SRC_)raster1 -RAS1_DIR_ := $(RAS1_DIR)$(SEP) - -# compilation flags for the driver -# -RAS1_COMPILE := $(FT_COMPILE) - - -# raster1 driver sources (i.e., C files) -# -RAS1_DRV_SRC := $(RAS1_DIR_)ftraster.c \ - $(RAS1_DIR_)ftrend1.c - - -# raster1 driver headers -# -RAS1_DRV_H := $(RAS1_DRV_SRC:%.c=%.h) - - -# raster1 driver object(s) -# -# RAS1_DRV_OBJ_M is used during `multi' builds. -# RAS1_DRV_OBJ_S is used during `single' builds. -# -RAS1_DRV_OBJ_M := $(RAS1_DRV_SRC:$(RAS1_DIR_)%.c=$(OBJ_)%.$O) -RAS1_DRV_OBJ_S := $(OBJ_)raster1.$O - -# raster1 driver source file for single build -# -RAS1_DRV_SRC_S := $(RAS1_DIR_)raster1.c - - -# raster1 driver - single object -# -$(RAS1_DRV_OBJ_S): $(RAS1_DRV_SRC_S) $(RAS1_DRV_SRC) \ - $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $(RAS1_DRV_SRC_S) - - -# raster1 driver - multiple objects -# -$(OBJ_)%.$O: $(RAS1_DIR_)%.c $(FREETYPE_H) $(RAS1_DRV_H) - $(RAS1_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(RAS1_DRV_OBJ_S) -DRV_OBJS_M += $(RAS1_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/sfnt/.cvsignore b/subsys/win32k/freetype/src/sfnt/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/sfnt/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/sfnt/module.mk b/subsys/win32k/freetype/src/sfnt/module.mk deleted file mode 100644 index 48b494f..0000000 --- a/subsys/win32k/freetype/src/sfnt/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_sfnt_module - -add_sfnt_module: - $(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)sfnt $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/sfnt/rules.mk b/subsys/win32k/freetype/src/sfnt/rules.mk deleted file mode 100644 index 2255e6a..0000000 --- a/subsys/win32k/freetype/src/sfnt/rules.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# FreeType 2 SFNT driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# SFNT driver directory -# -SFNT_DIR := $(SRC_)sfnt -SFNT_DIR_ := $(SFNT_DIR)$(SEP) - - -# compilation flags for the driver -# -SFNT_COMPILE := $(FT_COMPILE) - - -# SFNT driver sources (i.e., C files) -# -SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c \ - $(SFNT_DIR_)ttcmap.c \ - $(SFNT_DIR_)ttsbit.c \ - $(SFNT_DIR_)ttpost.c \ - $(SFNT_DIR_)sfobjs.c \ - $(SFNT_DIR_)sfdriver.c - -# SFNT driver headers -# -SFNT_DRV_H := $(SFNT_DRV_SRC:%c=%h) - - -# SFNT driver object(s) -# -# SFNT_DRV_OBJ_M is used during `multi' builds. -# SFNT_DRV_OBJ_S is used during `single' builds. -# -SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O) -SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O - -# SFNT driver source file for single build -# -SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c - - -# SFNT driver - single object -# -$(SFNT_DRV_OBJ_S): $(SFNT_DRV_SRC_S) $(SFNT_DRV_SRC) \ - $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S) - - -# SFNT driver - multiple objects -# -$(OBJ_)%.$O: $(SFNT_DIR_)%.c $(FREETYPE_H) $(SFNT_DRV_H) - $(SFNT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(SFNT_DRV_OBJ_S) -DRV_OBJS_M += $(SFNT_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/sfnt/sfdriver.c b/subsys/win32k/freetype/src/sfnt/sfdriver.c deleted file mode 100644 index 29862e7..0000000 --- a/subsys/win32k/freetype/src/sfnt/sfdriver.c +++ /dev/null @@ -1,225 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.c */ -/* */ -/* High-level SFNT driver interface (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "sfdriver.h" -#include "ttload.h" -#include "ttsbit.h" -#include "ttpost.h" -#include "ttcmap.h" -#include "sfobjs.h" - -#else - -#include -#include -#include -#include -#include -#include - -#endif - - -#include /* for strcmp() */ - - - static - void* get_sfnt_table( TT_Face face, - FT_Sfnt_Tag tag ) - { - void* table; - - - switch ( tag ) - { - case ft_sfnt_head: - table = &face->header; - break; - - case ft_sfnt_hhea: - table = &face->horizontal; - break; - - case ft_sfnt_vhea: - table = face->vertical_info ? &face->vertical : 0; - break; - - case ft_sfnt_os2: - table = face->os2.version == 0xFFFF ? 0 : &face->os2; - break; - - case ft_sfnt_post: - table = &face->postscript; - break; - - case ft_sfnt_maxp: - table = &face->max_profile; - break; - - case ft_sfnt_pclt: - table = face->pclt.Version ? &face->pclt : 0; - break; - - default: - table = 0; - } - - return table; - } - - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - static - FT_Error get_sfnt_glyph_name( TT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - FT_Error error; - - - error = TT_Get_PS_Name( face, glyph_index, &gname ); - if ( !error && buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if ( len >= buffer_max ) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return error; - } - - -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - static - FT_Module_Interface SFNT_Get_Interface( FT_Module module, - const char* interface ) - { - FT_UNUSED( module ); - - if ( strcmp( interface, "get_sfnt" ) == 0 ) - return (FT_Module_Interface)get_sfnt_table; - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - if ( strcmp( interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_sfnt_glyph_name; -#endif - return 0; - } - - - static - const SFNT_Interface sfnt_interface = - { - TT_Goto_Table, - - SFNT_Init_Face, - SFNT_Load_Face, - SFNT_Done_Face, - SFNT_Get_Interface, - - TT_Load_Any, - TT_Load_SFNT_Header, - TT_Load_Directory, - - TT_Load_Header, - TT_Load_Metrics_Header, - TT_Load_CMap, - TT_Load_MaxProfile, - TT_Load_OS2, - TT_Load_PostScript, - - TT_Load_Names, - TT_Free_Names, - - TT_Load_Hdmx, - TT_Free_Hdmx, - - TT_Load_Kern, - TT_Load_Gasp, - TT_Load_PCLT, - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* see `ttsbit.h' */ - TT_Load_SBit_Strikes, - TT_Load_SBit_Image, - TT_Free_SBit_Strikes, - -#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - 0, - 0, - 0, - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - /* see `ttpost.h' */ - TT_Get_PS_Name, - TT_Free_Post_Names, - -#else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - 0, - 0, - -#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - /* see `ttcmap.h' */ - TT_CharMap_Load, - TT_CharMap_Free, - }; - - - const - FT_Module_Class sfnt_module_class = - { - 0, /* not a font driver or renderer */ - sizeof( FT_ModuleRec ), - - "sfnt", /* driver name */ - 0x10000L, /* driver version 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or higher */ - - (const void*)&sfnt_interface, /* module specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) SFNT_Get_Interface - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/sfdriver.h b/subsys/win32k/freetype/src/sfnt/sfdriver.h deleted file mode 100644 index 92c9c81..0000000 --- a/subsys/win32k/freetype/src/sfnt/sfdriver.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfdriver.h */ -/* */ -/* High-level SFNT driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 SFDRIVER_H -#define SFDRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Module_Class ) sfnt_module_class; - -#endif /* SFDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/sfnt.c b/subsys/win32k/freetype/src/sfnt/sfnt.c deleted file mode 100644 index a5ebbc4..0000000 --- a/subsys/win32k/freetype/src/sfnt/sfnt.c +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfnt.c */ -/* */ -/* Single object library component. */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.c" -#include "ttcmap.c" -#include "sfobjs.c" - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include "ttsbit.c" -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include "ttpost.c" -#endif - -#include "sfdriver.c" - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES -#include -#endif - -#include - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/sfobjs.c b/subsys/win32k/freetype/src/sfnt/sfobjs.c deleted file mode 100644 index 38aba0e..0000000 --- a/subsys/win32k/freetype/src/sfnt/sfobjs.c +++ /dev/null @@ -1,561 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfobjs.c */ -/* */ -/* SFNT object management (base). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "sfobjs.h" - -#else - -#include - -#endif - - -#include -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_sfobjs - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Name */ - /* */ - /* */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* */ - /* Character string. NULL if no name is present. */ - /* */ - static - FT_String* Get_Name( TT_Face face, - FT_UShort nameid ) - { - FT_Memory memory = face->root.memory; - FT_UShort n; - TT_NameRec* rec; - FT_Bool wide_chars = 1; - - - rec = face->name_table.names; - for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ ) - { - if ( rec->nameID == nameid ) - { - /* found the name -- now create an ASCII string from it */ - FT_Bool found = 0; - - - /* test for Microsoft English language */ - if ( rec->platformID == TT_PLATFORM_MICROSOFT && - rec->encodingID <= TT_MS_ID_UNICODE_CS && - ( rec->languageID & 0x3FF ) == 0x009 ) - found = 1; - - /* test for Apple Unicode encoding */ - else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE ) - found = 1; - - /* test for Apple Roman */ - else if ( rec->platformID == TT_PLATFORM_MACINTOSH && - rec->languageID == TT_MAC_ID_ROMAN ) - { - found = 1; - wide_chars = 0; - } - - /* found a Unicode name */ - if ( found ) - { - FT_String* string; - FT_UInt len; - - - if ( wide_chars ) - { - FT_UInt m; - - - len = (FT_UInt)rec->stringLength / 2; - if ( MEM_Alloc( string, len + 1 ) ) - return NULL; - - for ( m = 0; m < len; m ++ ) - string[m] = rec->string[2 * m + 1]; - } - else - { - len = rec->stringLength; - if ( MEM_Alloc( string, len + 1 ) ) - return NULL; - - MEM_Copy( string, rec->string, len ); - } - - string[len] = '\0'; - return string; - } - } - } - - return NULL; - } - - - static - FT_Encoding find_encoding( int platform_id, - int encoding_id ) - { - typedef struct TEncoding - { - int platform_id; - int encoding_id; - FT_Encoding encoding; - - } TEncoding; - - static - const TEncoding tt_encodings[] = - { - { TT_PLATFORM_ISO, -1, ft_encoding_unicode }, - - { TT_PLATFORM_APPLE_UNICODE, -1, ft_encoding_unicode }, - - { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, ft_encoding_apple_roman }, - - { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, ft_encoding_unicode }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, ft_encoding_sjis }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, ft_encoding_gb2312 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, ft_encoding_big5 }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, ft_encoding_wansung }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, ft_encoding_johab } - }; - - const TEncoding *cur, *limit; - - - cur = tt_encodings; - limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] ); - - for ( ; cur < limit; cur++ ) - { - if ( cur->platform_id == platform_id ) - { - if ( cur->encoding_id == encoding_id || - cur->encoding_id == -1 ) - return cur->encoding; - } - } - - return ft_encoding_none; - } - - - LOCAL_FUNC - FT_Error SFNT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Interface* sfnt; - SFNT_Header sfnt_header; - - /* for now, parameters are unused */ - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - sfnt = (SFNT_Interface*)face->sfnt; - if ( !sfnt ) - { - sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - { - error = FT_Err_Invalid_File_Format; - goto Exit; - } - - face->sfnt = sfnt; - face->goto_table = sfnt->goto_table; - } - - if ( !face->psnames ) - { - face->psnames = (PSNames_Interface*) - FT_Get_Module_Interface( library, "psnames" ); - } - - /* check that we have a valid TrueType file */ - error = sfnt->load_sfnt_header( face, stream, face_index, &sfnt_header ); - if ( error ) - goto Exit; - - face->format_tag = sfnt_header.format_tag; - face->num_tables = sfnt_header.num_tables; - - /* Load font directory */ - error = sfnt->load_directory( face, stream, &sfnt_header ); - if ( error ) - goto Exit; - - face->root.num_faces = face->ttc_header.count; - if ( face->root.num_faces < 1 ) - face->root.num_faces = 1; - - Exit: - return error; - } - - -#undef LOAD_ -#define LOAD_( x ) ( ( error = sfnt->load_##x( face, stream ) ) \ - != TT_Err_Ok ) - - - LOCAL_FUNC - FT_Error SFNT_Load_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - FT_UNUSED( face_index ); - FT_UNUSED( num_params ); - FT_UNUSED( params ); - - - /* Load tables */ - if ( LOAD_( header ) || - LOAD_( max_profile ) || - - /* load the `hhea' & `hmtx' tables at once */ - ( error = sfnt->load_metrics( face, stream, 0 ) ) != TT_Err_Ok || - - /* try to load the `vhea' & `vmtx' at once if present */ - ( error = sfnt->load_metrics( face, stream, 1 ) ) != TT_Err_Ok || - - LOAD_( charmaps ) || - LOAD_( names ) || - LOAD_( os2 ) || - LOAD_( psnames ) ) - goto Exit; - - /* the optional tables */ - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /* embedded bitmap support. */ - if ( sfnt->load_sbits && LOAD_( sbits ) ) - goto Exit; -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - if ( LOAD_( hdmx ) || - LOAD_( gasp ) || - LOAD_( kerning ) || - LOAD_( pclt ) ) - goto Exit; - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - if ( ( error = TT_Extension_Create( face ) ) != TT_Err_Ok ) - goto Exit; -#endif - - face->root.family_name = Get_Name( face, TT_NAME_ID_FONT_FAMILY ); - face->root.style_name = Get_Name( face, TT_NAME_ID_FONT_SUBFAMILY ); - - /* now set up root fields */ - { - FT_Face root = &face->root; - FT_Int flags; - TT_CharMap charmap; - FT_Int n; - FT_Memory memory; - - - memory = root->memory; - - /*********************************************************************/ - /* */ - /* Compute face flags. */ - /* */ - flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ - FT_FACE_FLAG_SFNT | /* SFNT file format */ - FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /* might need more polish to detect the presence of a Postscript */ - /* name table in the font */ - flags |= FT_FACE_FLAG_GLYPH_NAMES; -#endif - - /* fixed width font? */ - if ( face->postscript.isFixedPitch ) - flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* vertical information? */ - if ( face->vertical_info ) - flags |= FT_FACE_FLAG_VERTICAL; - - /* kerning available ? */ - if ( face->kern_pairs ) - flags |= FT_FACE_FLAG_KERNING; - - root->face_flags = flags; - - /*********************************************************************/ - /* */ - /* Compute style flags. */ - /* */ - flags = 0; - - if ( face->os2.version != 0xFFFF ) - { - /* we have an OS/2 table; use the `fsSelection' field */ - if ( face->os2.fsSelection & 1 ) - flags |= FT_STYLE_FLAG_ITALIC; - - if ( face->os2.fsSelection & 32 ) - flags |= FT_STYLE_FLAG_BOLD; - } - else - { - /* this is an old Mac font, use the header field */ - if ( face->header.Mac_Style & 1 ) - flags |= FT_STYLE_FLAG_BOLD; - - if ( face->header.Mac_Style & 2 ) - flags |= FT_STYLE_FLAG_ITALIC; - } - - root->style_flags = flags; - - /*********************************************************************/ - /* */ - /* Polish the charmaps. */ - /* */ - /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. */ - /* */ - charmap = face->charmaps; - root->num_charmaps = face->num_charmaps; - - /* allocate table of pointers */ - if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) ) - goto Exit; - - for ( n = 0; n < root->num_charmaps; n++, charmap++ ) - { - FT_Int platform = charmap->cmap.platformID; - FT_Int encoding = charmap->cmap.platformEncodingID; - - - charmap->root.face = (FT_Face)face; - charmap->root.platform_id = platform; - charmap->root.encoding_id = encoding; - charmap->root.encoding = find_encoding( platform, encoding ); - - /* now, set root->charmap with a unicode charmap */ - /* wherever available */ - if ( !root->charmap && - charmap->root.encoding == ft_encoding_unicode ) - root->charmap = (FT_CharMap)charmap; - - root->charmaps[n] = (FT_CharMap)charmap; - } - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - if ( face->num_sbit_strikes ) - { - root->num_fixed_sizes = face->num_sbit_strikes; - if ( ALLOC_ARRAY( root->available_sizes, - face->num_sbit_strikes, - FT_Bitmap_Size ) ) - return error; - - for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) - { - root->available_sizes[n].width = - face->sbit_strikes[n].x_ppem; - root->available_sizes[n].height = - face->sbit_strikes[n].y_ppem; - } - } - else - -#else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - { - root->num_fixed_sizes = 0; - root->available_sizes = 0; - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /*********************************************************************/ - /* */ - /* Set up metrics. */ - /* */ - root->bbox.xMin = face->header.xMin; - root->bbox.yMin = face->header.yMin; - root->bbox.xMax = face->header.xMax; - root->bbox.yMax = face->header.yMax; - root->units_per_EM = face->header.Units_Per_EM; - - /* The ascender/descender/height are computed from the OS/2 table */ - /* when found. Otherwise, they're taken from the horizontal header. */ - if ( face->os2.version != 0xFFFF ) - { - root->ascender = face->os2.sTypoAscender; - root->descender = -face->os2.sTypoDescender; - root->height = root->ascender + root->descender + - face->os2.sTypoLineGap; - } - else - { - root->ascender = face->horizontal.Ascender; - root->descender = face->horizontal.Descender; - root->height = root->ascender + root->descender + - face->horizontal.Line_Gap; - } - - root->max_advance_width = face->horizontal.advance_Width_Max; - - root->max_advance_height = face->vertical_info - ? face->vertical.advance_Height_Max - : root->height; - - root->underline_position = face->postscript.underlinePosition; - root->underline_thickness = face->postscript.underlineThickness; - - /* root->max_points -- already set up */ - /* root->max_contours -- already set up */ - } - - Exit: - return error; - } - - -#undef LOAD_ - - - LOCAL_FUNC - void SFNT_Done_Face( TT_Face face ) - { - FT_Memory memory = face->root.memory; - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - if ( sfnt ) - { - /* destroy the postscript names table if it is loaded */ - if ( sfnt->free_psnames ) - sfnt->free_psnames( face ); - - /* destroy the embedded bitmaps table if it is loaded */ - if ( sfnt->free_sbits ) - sfnt->free_sbits( face ); - } - - /* freeing the kerning table */ - FREE( face->kern_pairs ); - face->num_kern_pairs = 0; - - /* freeing the collection table */ - FREE( face->ttc_header.offsets ); - face->ttc_header.count = 0; - - /* freeing table directory */ - FREE( face->dir_tables ); - face->num_tables = 0; - - /* freeing the character mapping tables */ - if ( sfnt && sfnt->load_charmaps ) - { - FT_UShort n; - - - for ( n = 0; n < face->num_charmaps; n++ ) - sfnt->free_charmap( face, &face->charmaps[n].cmap ); - } - - FREE( face->charmaps ); - face->num_charmaps = 0; - - FREE( face->root.charmaps ); - face->root.num_charmaps = 0; - face->root.charmap = 0; - - /* freeing the horizontal metrics */ - FREE( face->horizontal.long_metrics ); - FREE( face->horizontal.short_metrics ); - - /* freeing the vertical ones, if any */ - if ( face->vertical_info ) - { - FREE( face->vertical.long_metrics ); - FREE( face->vertical.short_metrics ); - face->vertical_info = 0; - } - - /* freeing the gasp table */ - FREE( face->gasp.gaspRanges ); - face->gasp.numRanges = 0; - - /* freeing the name table */ - sfnt->free_names( face ); - - /* freeing the hdmx table */ - sfnt->free_hdmx( face ); - - /* freeing family and style name */ - FREE( face->root.family_name ); - FREE( face->root.style_name ); - - /* freeing sbit size table */ - face->root.num_fixed_sizes = 0; - if ( face->root.available_sizes ) - FREE( face->root.available_sizes ); - - face->sfnt = 0; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/sfobjs.h b/subsys/win32k/freetype/src/sfnt/sfobjs.h deleted file mode 100644 index 35d92f9..0000000 --- a/subsys/win32k/freetype/src/sfnt/sfobjs.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* sfobjs.h */ -/* */ -/* SFNT object management (specification). */ -/* */ -/* Copyright 1996-2000 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 SFOBJS_H -#define SFOBJS_H - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error SFNT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - FT_Error SFNT_Load_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void SFNT_Done_Face( TT_Face face ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* SFDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttcmap.c b/subsys/win32k/freetype/src/sfnt/ttcmap.c deleted file mode 100644 index a2f3fd7..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttcmap.c +++ /dev/null @@ -1,550 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.c */ -/* */ -/* TrueType character mapping table (cmap) support (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" -#include "ttcmap.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttcmap - - - static FT_UInt code_to_index0( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index2( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index4( TT_CMapTable* charmap, - FT_ULong char_code ); - static FT_UInt code_to_index6( TT_CMapTable* charmap, - FT_ULong char_code ); - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Load */ - /* */ - /* */ - /* Loads a given TrueType character map into memory. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* stream :: A handle to the current stream object. */ - /* */ - /* */ - /* table :: A pointer to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The function assumes that the stream is already in use (i.e., */ - /* opened). In case of error, all partially allocated tables are */ - /* released. */ - /* */ - LOCAL_FUNC - FT_Error TT_CharMap_Load( TT_Face face, - TT_CMapTable* cmap, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory; - FT_UShort num_SH, num_Seg, i; - - FT_UShort u, l; - - TT_CMap0* cmap0; - TT_CMap2* cmap2; - TT_CMap4* cmap4; - TT_CMap6* cmap6; - - TT_CMap2SubHeader* cmap2sub; - TT_CMap4Segment* segments; - - - if ( cmap->loaded ) - return TT_Err_Ok; - - memory = stream->memory; - - if ( FILE_Seek( cmap->offset ) ) - return error; - - switch ( cmap->format ) - { - case 0: - cmap0 = &cmap->c.cmap0; - - if ( ALLOC( cmap0->glyphIdArray, 256L ) || - FILE_Read( cmap0->glyphIdArray, 256L ) ) - goto Fail; - - cmap->get_index = code_to_index0; - break; - - case 2: - num_SH = 0; - cmap2 = &cmap->c.cmap2; - - /* allocate subheader keys */ - - if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, FT_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, - TT_CMap2SubHeader ) || - 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, FT_UShort ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap2->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - - cmap->get_index = code_to_index2; - 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, - TT_CMap4Segment ) || - 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, FT_UShort ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap4->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - - cmap->get_index = code_to_index4; - - cmap4->last_segment = cmap4->segments; - 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, - FT_Short ) || - ACCESS_Frame( l * 2L ) ) - goto Fail; - - for ( i = 0; i < l; i++ ) - cmap6->glyphIdArray[i] = GET_UShort(); - - FORGET_Frame(); - cmap->get_index = code_to_index6; - break; - - default: /* corrupt character mapping table */ - return TT_Err_Invalid_CharMap_Format; - - } - - return TT_Err_Ok; - - Fail: - TT_CharMap_Free( face, cmap ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_CharMap_Free */ - /* */ - /* */ - /* Destroys a character mapping table. */ - /* */ - /* */ - /* face :: A handle to the parent face object. */ - /* cmap :: A handle to a cmap object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_CharMap_Free( TT_Face face, - TT_CMapTable* cmap ) - { - FT_Memory memory; - - - if ( !cmap ) - return TT_Err_Ok; - - memory = face->root.driver->root.memory; - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index0 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 0. */ - /* `charCode' must be in the range 0x00-0xFF (otherwise 0 is */ - /* returned). */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap0 :: A pointer to a cmap table in format 0. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index0( TT_CMapTable* cmap, - FT_ULong charCode ) - { - TT_CMap0* cmap0 = &cmap->c.cmap0; - - - return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index2 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 2. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap2 :: A pointer to a cmap table in format 2. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index2( TT_CMapTable* cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, offset; - FT_UInt char_lo; - FT_ULong char_hi; - TT_CMap2SubHeader* sh2; - TT_CMap2* cmap2; - - - cmap2 = &cmap->c.cmap2; - result = 0; - char_lo = (FT_UInt)( charCode & 0xFF ); - char_hi = charCode >> 8; - - if ( char_hi == 0 ) - { - /* an 8-bit character code -- we use the subHeader 0 in this case */ - /* to test whether the character code is in the charmap */ - if ( cmap2->subHeaderKeys[char_lo] == 0 ) - result = cmap2->glyphIdArray[char_lo]; - } - else - { - /* a 16-bit character code */ - index1 = cmap2->subHeaderKeys[char_hi & 0xFF]; - if ( index1 ) - { - sh2 = cmap2->subHeaders + index1; - char_lo -= sh2->firstCode; - - if ( char_lo < sh2->entryCount ) - { - offset = sh2->idRangeOffset / 2 + char_lo; - if ( offset < cmap2->numGlyphId ) - { - result = cmap2->glyphIdArray[offset]; - if ( result ) - result = ( result + sh2->idDelta ) & 0xFFFF; - } - } - } - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index4 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 4. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap4 :: A pointer to a cmap table in format 4. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index4( TT_CMapTable* cmap, - FT_ULong charCode ) - { - FT_UInt result, index1, segCount; - TT_CMap4* cmap4; - TT_CMap4Segment *seg4, *limit; - - - cmap4 = &cmap->c.cmap4; - result = 0; - segCount = cmap4->segCountX2 / 2; - seg4 = cmap4->segments; - limit = seg4 + segCount; - - /* check against the last segment */ - seg4 = cmap4->last_segment; - - /* the following is equivalent to performing two tests, as in */ - /* */ - /* if ( charCode >= seg4->startCount && charCode <= seg4->endCount ) */ - /* */ - /* Yes, that's a bit strange, but it's faster, and the idea behind */ - /* the cache is to significantly speed up charcode to glyph index */ - /* conversion. */ - - if ( (FT_ULong)(charCode - seg4->startCount) < - (FT_ULong)(seg4->endCount - seg4->startCount) ) - goto Found; - - for ( seg4 = cmap4->segments; seg4 < limit; seg4++ ) - { - /* the ranges are sorted in increasing order. If we are out of */ - /* the range here, the char code isn't in the charmap, so exit. */ - - if ( charCode > seg4->endCount ) - continue; - - if ( charCode >= seg4->startCount ) - goto Found; - } - return 0; - - Found: - cmap4->last_segment = seg4; - - /* if the idRangeOffset is 0, we can compute the glyph index */ - /* directly */ - - if ( seg4->idRangeOffset == 0 ) - result = ( charCode + seg4->idDelta ) & 0xFFFF; - else - { - /* otherwise, we must use the glyphIdArray to do it */ - index1 = seg4->idRangeOffset / 2 - + ( charCode - seg4->startCount ) - + ( seg4 - cmap4->segments ) - - segCount; - - if ( index1 < cmap4->numGlyphId && - cmap4->glyphIdArray[index1] != 0 ) - result = ( cmap4->glyphIdArray[index1] + seg4->idDelta ) & 0xFFFF; - } - - return result; - } - - - /*************************************************************************/ - /* */ - /* */ - /* code_to_index6 */ - /* */ - /* */ - /* Converts the character code into a glyph index. Uses format 6. */ - /* */ - /* */ - /* charCode :: The wanted character code. */ - /* cmap6 :: A pointer to a cmap table in format 6. */ - /* */ - /* */ - /* Glyph index into the glyphs array. 0 if the glyph does not exist. */ - /* */ - static - FT_UInt code_to_index6( TT_CMapTable* cmap, - FT_ULong charCode ) - { - TT_CMap6* cmap6; - FT_UInt result = 0; - - - cmap6 = &cmap->c.cmap6; - result = 0; - charCode -= cmap6->firstCode; - - if ( charCode < cmap6->entryCount ) - result = cmap6->glyphIdArray[charCode]; - - return result; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttcmap.h b/subsys/win32k/freetype/src/sfnt/ttcmap.h deleted file mode 100644 index 609972a..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttcmap.h +++ /dev/null @@ -1,45 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttcmap.h */ -/* */ -/* TrueType character mapping table (cmap) support (specification). */ -/* */ -/* Copyright 1996-2000 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 - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_CharMap_Load( TT_Face face, - TT_CMapTable* cmap, - FT_Stream input ); - - LOCAL_DEF - FT_Error TT_CharMap_Free( TT_Face face, - TT_CMapTable* cmap ); - -#ifdef __cplusplus - } -#endif - -#endif /* TTCMAP_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttload.c b/subsys/win32k/freetype/src/sfnt/ttload.c deleted file mode 100644 index c3eeed6..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttload.c +++ /dev/null @@ -1,1676 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.c */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" -#include "ttcmap.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttload - - - /*************************************************************************/ - /* */ - /* */ - /* TT_LookUp_Table */ - /* */ - /* */ - /* Looks for a TrueType table by name. */ - /* */ - /* */ - /* face :: A face object handle. */ - /* tag :: The searched tag. */ - /* */ - /* */ - /* A pointer to the table directory entry. 0 if not found. */ - /* */ - LOCAL_FUNC - TT_Table* TT_LookUp_Table( TT_Face face, - FT_ULong tag ) - { - TT_Table* entry; - TT_Table* limit; - - - FT_TRACE3(( "TT_LookUp_Table: %08p, `%c%c%c%c'\n", - face, - (FT_Char)( tag >> 24 ), - (FT_Char)( tag >> 16 ), - (FT_Char)( tag >> 8 ), - (FT_Char)( tag ) )); - - entry = face->dir_tables; - limit = entry + face->num_tables; - - for ( ; entry < limit; entry++ ) - { - if ( entry->Tag == tag ) - return entry; - } - - FT_TRACE3(( " Could not find table!\n" )); - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_Table */ - /* */ - /* */ - /* Looks for a TrueType table by name, then seek a stream to it. */ - /* */ - /* */ - /* face :: A face object handle. */ - /* tag :: The searched tag. */ - /* stream :: The stream to seek when the table is found. */ - /* */ - /* */ - /* length :: The length of the table if found, undefined otherwise. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Goto_Table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ) - { - TT_Table* table; - FT_Error error; - - - table = TT_LookUp_Table( face, tag ); - if ( table ) - { - if ( length ) - *length = table->Length; - - (void)FILE_Seek( table->Offset ); - } - else - error = TT_Err_Table_Missing; - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SFNT_Header */ - /* */ - /* */ - /* Loads the header of a SFNT font file. Supports collections. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* face_index :: If the font is a collection, the number of the font */ - /* in the collection, ignored otherwise. */ - /* */ - /* */ - /* sfnt :: The SFNT header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - /* This function recognizes fonts embedded in a `TrueType collection' */ - /* */ - /* The header will be checked whether it is valid by looking at the */ - /* values of `search_range', `entry_selector', and `range_shift'. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SFNT_Header( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ) - { - FT_Error error; - FT_ULong format_tag; - FT_Memory memory = stream->memory; - - const FT_Frame_Field sfnt_header_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_USHORT( SFNT_Header, num_tables ), - FT_FRAME_USHORT( SFNT_Header, search_range ), - FT_FRAME_USHORT( SFNT_Header, entry_selector ), - FT_FRAME_USHORT( SFNT_Header, range_shift ), - FT_FRAME_END - }; - - const FT_Frame_Field ttc_header_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_LONG( TTC_Header, version ), - FT_FRAME_LONG( TTC_Header, count ), - FT_FRAME_END }; - - - FT_TRACE2(( "TT_Load_SFNT_Header: %08p, %ld\n", - face, face_index )); - - face->ttc_header.tag = 0; - face->ttc_header.version = 0; - face->ttc_header.count = 0; - - face->num_tables = 0; - - /* first of all, read the first 4 bytes. If it is `ttcf', then the */ - /* file is a TrueType collection, otherwise it can be any other */ - /* kind of font. */ - if ( READ_ULong( format_tag ) ) - goto Exit; - - if ( format_tag == TTAG_ttcf ) - { - FT_Int n; - - - FT_TRACE3(( "TT_Load_SFNT_Header: file is a collection\n" )); - - /* it's a TrueType collection, i.e. a file containing several */ - /* font files. Read the font directory now */ - if ( READ_Fields( ttc_header_fields, &face->ttc_header ) ) - goto Exit; - - /* now read the offsets of each font in the file */ - if ( ALLOC_ARRAY( face->ttc_header.offsets, - face->ttc_header.count, - FT_ULong ) || - ACCESS_Frame( face->ttc_header.count * 4L ) ) - goto Exit; - - for ( n = 0; n < face->ttc_header.count; n++ ) - face->ttc_header.offsets[n] = GET_ULong(); - - FORGET_Frame(); - - /* check face index */ - if ( face_index >= face->ttc_header.count ) - { - error = TT_Err_Bad_Argument; - goto Exit; - } - - /* seek to the appropriate TrueType file, then read tag */ - if ( FILE_Seek( face->ttc_header.offsets[face_index] ) || - READ_Long( format_tag ) ) - goto Exit; - } - - /* the format tag was read, now check the rest of the header */ - sfnt->format_tag = format_tag; - if ( READ_Fields( sfnt_header_fields, sfnt ) ) - goto Exit; - - /* now, check the values of `num_tables', `seach_range', etc. */ - { - FT_UInt num_tables = sfnt->num_tables; - FT_ULong entry_selector = 1L << sfnt->entry_selector; - - - /* IMPORTANT: Many fonts have an incorrect `search_range' value, so */ - /* we only check the `entry_selector' correctness here. */ - /* */ - if ( num_tables == 0 || - entry_selector > num_tables || - entry_selector * 2 <= num_tables ) - { - FT_TRACE2(( "TT_Load_SFNT_Header: file is not SFNT!\n" )); - error = FT_Err_Unknown_File_Format; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Directory */ - /* */ - /* */ - /* Loads the table directory into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* sfnt :: The SFNT directory header. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be at the font file's origin. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Directory( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - TT_Table *entry, *limit; - - - FT_TRACE2(( "TT_Load_Directory: %08p\n", face )); - - FT_TRACE2(( "-- Tables count: %12u\n", sfnt->num_tables )); - FT_TRACE2(( "-- Format version: %08lx\n", sfnt->format_tag )); - - face->num_tables = sfnt->num_tables; - - if ( ALLOC_ARRAY( face->dir_tables, - face->num_tables, - TT_Table ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_tables * 16L ) ) - goto Exit; - - entry = face->dir_tables; - limit = entry + face->num_tables; - - for ( ; entry < limit; entry++ ) - { /* loop through the tables and get all entries */ - entry->Tag = GET_Tag4(); - entry->CheckSum = GET_ULong(); - entry->Offset = GET_Long(); - entry->Length = GET_Long(); - - FT_TRACE2(( " %c%c%c%c - %08lx - %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length )); - } - - FORGET_Frame(); - - FT_TRACE2(( "Directory loaded\n\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Any */ - /* */ - /* */ - /* Loads any font table into client memory. */ - /* */ - /* */ - /* face :: The face object to look for. */ - /* */ - /* tag :: The 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 :: The starting offset in the table (or the file if */ - /* tag == 0). */ - /* */ - /* length :: The address of the decision variable: */ - /* */ - /* If length == NULL: */ - /* Loads the whole table. Returns an error if */ - /* `offset' == 0! */ - /* */ - /* If *length == 0: */ - /* Exits immediately; returning the length of the given */ - /* table or of the font file, depending on the value of */ - /* `tag'. */ - /* */ - /* If *length != 0: */ - /* Loads the next `length' bytes of table or font, */ - /* starting at offset `offset' (in table or font too). */ - /* */ - /* */ - /* buffer :: The address of target buffer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) - { - FT_Error error; - FT_Stream stream; - TT_Table* table; - FT_ULong size; - - - if ( tag != 0 ) - { - /* look for tag in font directory */ - table = TT_LookUp_Table( face, tag ); - if ( !table ) - { - error = TT_Err_Table_Missing; - goto Exit; - } - - offset += table->Offset; - size = table->Length; - } - else - /* tag == 0 -- the user wants to access the font file directly */ - size = face->root.stream->size; - - if ( length && *length == 0 ) - { - *length = size; - - return TT_Err_Ok; - } - - if ( length ) - size = *length; - - stream = face->root.stream; - (void)FILE_Read_At( offset, buffer, size ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Header */ - /* */ - /* */ - /* Loads the TrueType font header. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Header( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_Header* header; - - static const FT_Frame_Field header_fields[] = - { - FT_FRAME_START( 54 ), - FT_FRAME_ULONG( TT_Header, Table_Version ), - FT_FRAME_ULONG( TT_Header, Font_Revision ), - FT_FRAME_LONG( TT_Header, CheckSum_Adjust ), - FT_FRAME_LONG( TT_Header, Magic_Number ), - FT_FRAME_USHORT( TT_Header, Flags ), - FT_FRAME_USHORT( TT_Header, Units_Per_EM ), - FT_FRAME_LONG( TT_Header, Created[0] ), - FT_FRAME_LONG( TT_Header, Created[1] ), - FT_FRAME_LONG( TT_Header, Modified[0] ), - FT_FRAME_LONG( TT_Header, Modified[1] ), - FT_FRAME_SHORT( TT_Header, xMin ), - FT_FRAME_SHORT( TT_Header, yMin ), - FT_FRAME_SHORT( TT_Header, xMax ), - FT_FRAME_SHORT( TT_Header, yMax ), - FT_FRAME_USHORT( TT_Header, Mac_Style ), - FT_FRAME_USHORT( TT_Header, Lowest_Rec_PPEM ), - FT_FRAME_SHORT( TT_Header, Font_Direction ), - FT_FRAME_SHORT( TT_Header, Index_To_Loc_Format ), - FT_FRAME_SHORT( TT_Header, Glyph_Data_Format ), - FT_FRAME_END - }; - - - FT_TRACE2(( "Load_TT_Header: %08p\n", face )); - - error = face->goto_table( face, TTAG_head, stream, 0 ); - if ( error ) - { - FT_TRACE0(( "Font Header is missing!\n" )); - goto Exit; - } - - header = &face->header; - - if ( READ_Fields( header_fields, header ) ) - goto Exit; - - FT_TRACE2(( " Units per EM: %8u\n", header->Units_Per_EM )); - FT_TRACE2(( " IndexToLoc: %8d\n", header->Index_To_Loc_Format )); - FT_TRACE2(( "Font Header Loaded.\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_MaxProfile */ - /* */ - /* */ - /* Loads the maximum profile into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_MaxProfile( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_MaxProfile* maxProfile = &face->max_profile; - - const FT_Frame_Field maxp_fields[] = - { - FT_FRAME_START( 32 ), - FT_FRAME_ULONG( TT_MaxProfile, version ), - FT_FRAME_USHORT( TT_MaxProfile, numGlyphs ), - FT_FRAME_USHORT( TT_MaxProfile, maxPoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxContours ), - FT_FRAME_USHORT( TT_MaxProfile, maxCompositePoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxCompositeContours ), - FT_FRAME_USHORT( TT_MaxProfile, maxZones ), - FT_FRAME_USHORT( TT_MaxProfile, maxTwilightPoints ), - FT_FRAME_USHORT( TT_MaxProfile, maxStorage ), - FT_FRAME_USHORT( TT_MaxProfile, maxFunctionDefs ), - FT_FRAME_USHORT( TT_MaxProfile, maxInstructionDefs ), - FT_FRAME_USHORT( TT_MaxProfile, maxStackElements ), - FT_FRAME_USHORT( TT_MaxProfile, maxSizeOfInstructions ), - FT_FRAME_USHORT( TT_MaxProfile, maxComponentElements ), - FT_FRAME_USHORT( TT_MaxProfile, maxComponentDepth ), - FT_FRAME_END }; - - - FT_TRACE2(( "Load_TT_MaxProfile: %08p\n", face )); - - error = face->goto_table( face, TTAG_maxp, stream, 0 ); - if ( error ) - goto Exit; - - if ( READ_Fields( maxp_fields, maxProfile ) ) - goto Exit; - - /* XXX: an adjustment 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->root.num_glyphs = maxProfile->numGlyphs; - - face->root.max_points = MAX( maxProfile->maxCompositePoints, - maxProfile->maxPoints ); - - face->root.max_contours = MAX( maxProfile->maxCompositeContours, - maxProfile->maxContours ); - - face->max_components = (FT_ULong)maxProfile->maxComponentElements + - maxProfile->maxComponentDepth; - - /* XXX: some fonts have maxComponents set to 0; we will */ - /* then use 16 of them by default. */ - if ( face->max_components == 0 ) - face->max_components = 16; - - /* We also increase maxPoints and maxContours in order to support */ - /* some broken fonts. */ - face->root.max_points += 8; - face->root.max_contours += 4; - - FT_TRACE2(( "MAXP loaded.\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics */ - /* */ - /* */ - /* Loads the horizontal or vertical metrics table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error TT_Load_Metrics( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_ULong table_len; - FT_Long num_shorts, num_longs, num_shorts_checked; - - TT_LongMetrics** longs; - TT_ShortMetrics** shorts; - - - FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical" - : "Horizontal", - 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! */ - /* */ - error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); - if ( error ) - { - /* Set number_Of_VMetrics to 0! */ - FT_TRACE2(( " no vertical header in file.\n" )); - face->vertical.number_Of_VMetrics = 0; - error = TT_Err_Ok; - goto Exit; - } - - num_longs = face->vertical.number_Of_VMetrics; - longs = (TT_LongMetrics**)&face->vertical.long_metrics; - shorts = (TT_ShortMetrics**)&face->vertical.short_metrics; - } - else - { - error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); - if ( error ) - { - FT_ERROR(( " no horizontal metrics in file!\n" )); - error = TT_Err_Hmtx_Table_Missing; - goto Exit; - } - - num_longs = face->horizontal.number_Of_HMetrics; - longs = (TT_LongMetrics**)&face->horizontal.long_metrics; - shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics; - } - - /* never trust derived values */ - - num_shorts = face->max_profile.numGlyphs - num_longs; - num_shorts_checked = ( table_len - num_longs * 4L ) / 2; - - if ( num_shorts < 0 ) - { - FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n", - vertical ? "Vertical" - : "Horizontal" )); - - error = vertical ? TT_Err_Invalid_Vert_Metrics - : TT_Err_Invalid_Horiz_Metrics; - goto Exit; - } - - if ( ALLOC_ARRAY( *longs, num_longs, TT_LongMetrics ) || - ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) ) - goto Exit; - - if ( ACCESS_Frame( table_len ) ) - goto Exit; - - { - TT_LongMetrics* cur = *longs; - TT_LongMetrics* limit = cur + num_longs; - - - for ( ; cur < limit; cur++ ) - { - cur->advance = GET_UShort(); - cur->bearing = GET_Short(); - } - } - - /* do we have an inconsistent number of metric values? */ - { - TT_ShortMetrics* cur = *shorts; - TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); - - - for ( ; cur < limit; cur++ ) - *cur = GET_Short(); - - /* we fill up the missing left side bearings with the */ - /* last valid value. Since this will occur for buggy CJK */ - /* fonts usually only, nothing serious will happen */ - if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) - { - FT_Short val = *(shorts)[num_shorts_checked - 1]; - - - limit = *shorts + num_shorts; - for ( ; cur < limit; cur++ ) - *cur = val; - } - } - - FORGET_Frame(); - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Metrics_Header */ - /* */ - /* */ - /* Loads the horizontal or vertical header in a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* vertical :: A boolean flag. If set, load vertical metrics. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Metrics_Header( TT_Face face, - FT_Stream stream, - FT_Bool vertical ) - { - FT_Error error; - TT_HoriHeader* header; - - const FT_Frame_Field metrics_header_fields[] = - { - FT_FRAME_START( 36 ), - FT_FRAME_ULONG( TT_HoriHeader, Version ), - FT_FRAME_SHORT( TT_HoriHeader, Ascender ), - FT_FRAME_SHORT( TT_HoriHeader, Descender ), - FT_FRAME_SHORT( TT_HoriHeader, Line_Gap ), - FT_FRAME_USHORT( TT_HoriHeader, advance_Width_Max ), - FT_FRAME_SHORT( TT_HoriHeader, min_Left_Side_Bearing ), - FT_FRAME_SHORT( TT_HoriHeader, min_Right_Side_Bearing ), - FT_FRAME_SHORT( TT_HoriHeader, xMax_Extent ), - FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Rise ), - FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Run ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[0] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[1] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[2] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[3] ), - FT_FRAME_SHORT( TT_HoriHeader, Reserved[4] ), - FT_FRAME_SHORT( TT_HoriHeader, metric_Data_Format ), - FT_FRAME_USHORT( TT_HoriHeader, number_Of_HMetrics ), - FT_FRAME_END - }; - - - FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " )); - - if ( vertical ) - { - face->vertical_info = 0; - - /* The vertical header table is optional, so return quietly if */ - /* we don't find it. */ - error = face->goto_table( face, TTAG_vhea, stream, 0 ); - if ( error ) - { - error = TT_Err_Ok; - goto Exit; - } - - face->vertical_info = 1; - header = (TT_HoriHeader*)&face->vertical; - } - else - { - /* The horizontal header is mandatory; return an error if we */ - /* don't find it. */ - error = face->goto_table( face, TTAG_hhea, stream, 0 ); - if ( error ) - { - error = TT_Err_Horiz_Header_Missing; - goto Exit; - } - - header = &face->horizontal; - } - - if ( READ_Fields( metrics_header_fields, header ) ) - goto Exit; - - header->long_metrics = NULL; - header->short_metrics = NULL; - - FT_TRACE2(( "loaded\n" )); - - /* Now try to load the corresponding metrics */ - - error = TT_Load_Metrics( face, stream, vertical ); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Names */ - /* */ - /* */ - /* Loads the name records. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Names( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_ULong table_pos, table_len; - FT_ULong storageSize; - - TT_NameTable* names; - - const FT_Frame_Field name_table_fields[] = - { - FT_FRAME_START( 6 ), - FT_FRAME_USHORT( TT_NameTable, format ), - FT_FRAME_USHORT( TT_NameTable, numNameRecords ), - FT_FRAME_USHORT( TT_NameTable, storageOffset ), - FT_FRAME_END - }; - - const FT_Frame_Field name_record_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( TT_NameRec, platformID ), - FT_FRAME_USHORT( TT_NameRec, encodingID ), - FT_FRAME_USHORT( TT_NameRec, languageID ), - FT_FRAME_USHORT( TT_NameRec, nameID ), - FT_FRAME_USHORT( TT_NameRec, stringLength ), - FT_FRAME_USHORT( TT_NameRec, stringOffset ), - FT_FRAME_END - }; - - - FT_TRACE2(( "Names " )); - - error = face->goto_table( face, TTAG_name, stream, &table_len ); - if ( error ) - { - /* The name table is required so indicate failure. */ - FT_TRACE2(( "is missing!\n" )); - error = TT_Err_Name_Table_Missing; - goto Exit; - } - - table_pos = FILE_Pos(); - - names = &face->name_table; - - if ( READ_Fields( name_table_fields, names ) ) - goto Exit; - - /* Allocate the array of name records. */ - if ( ALLOC_ARRAY( names->names, - names->numNameRecords, - TT_NameRec ) || - ACCESS_Frame( names->numNameRecords * 12L ) ) - goto Exit; - - /* Load the name records and determine how much storage is needed */ - /* to hold the strings themselves. */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - storageSize = 0; - - for ( ; cur < limit; cur ++ ) - { - FT_ULong upper; - - - (void)READ_Fields( name_record_fields, cur ); - - upper = (FT_ULong)( cur->stringOffset + cur->stringLength ); - if ( upper > storageSize ) - storageSize = upper; - } - } - - FORGET_Frame(); - - if ( storageSize > 0 ) - { - /* allocate the name storage area in memory, then read it */ - if ( ALLOC( names->storage, storageSize ) || - FILE_Read_At( table_pos + names->storageOffset, - names->storage, storageSize ) ) - goto Exit; - - /* Go through and assign the string pointers to the name records. */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - for ( ; cur < limit; cur++ ) - cur->string = names->storage + cur->stringOffset; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* Print Name Record Table in case of debugging */ - { - TT_NameRec* cur = names->names; - TT_NameRec* limit = cur + names->numNameRecords; - - - for ( ; cur < limit; cur++ ) - { - FT_UInt j; - - - FT_TRACE3(( "%d %d %x %d\n ", - cur->platformID, - cur->encodingID, - cur->languageID, - cur->nameID )); - - /* I know that M$ encoded strings are Unicode, */ - /* but this works reasonable well for debugging purposes. */ - if ( cur->string ) - for ( j = 0; j < cur->stringLength; j++ ) - { - FT_Char c = *( cur->string + j ); - - - if ( (FT_Byte)c < 128 ) - FT_TRACE3(( "%c", c )); - } - } - } - FT_TRACE3(( "\n" )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - } - FT_TRACE2(( "loaded\n" )); - - /* everything went well, update face->num_names */ - face->num_names = names->numNameRecords; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Names */ - /* */ - /* */ - /* Frees the name records. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_Names( TT_Face face ) - { - FT_Memory memory = face->root.driver->root.memory; - TT_NameTable* names = &face->name_table; - - - /* free strings table */ - FREE( names->names ); - - /* free strings storage */ - FREE( names->storage ); - - names->numNameRecords = 0; - names->format = 0; - names->storageOffset = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_CMap */ - /* */ - /* */ - /* Loads the cmap directory in a face object. The cmaps itselves are */ - /* loaded on demand in the `ttcmap.c' module. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_CMap( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Long table_start; - TT_CMapDir cmap_dir; - - const FT_Frame_Field cmap_fields[] = - { - FT_FRAME_START( 4 ), - FT_FRAME_USHORT( TT_CMapDir, tableVersionNumber ), - FT_FRAME_USHORT( TT_CMapDir, numCMaps ), - FT_FRAME_END - }; - - const FT_Frame_Field cmap_rec_fields[] = - { - FT_FRAME_START( 6 ), - FT_FRAME_USHORT( TT_CMapTable, format ), - FT_FRAME_USHORT( TT_CMapTable, length ), - FT_FRAME_USHORT( TT_CMapTable, version ), - FT_FRAME_END - }; - - - FT_TRACE2(( "CMaps " )); - - error = face->goto_table( face, TTAG_cmap, stream, 0 ); - if ( error ) - { - error = TT_Err_CMap_Table_Missing; - goto Exit; - } - - table_start = FILE_Pos(); - - if ( READ_Fields( cmap_fields, &cmap_dir ) ) - goto Exit; - - /* reserve space in face table for cmap tables */ - if ( ALLOC_ARRAY( face->charmaps, - cmap_dir.numCMaps, - TT_CharMapRec ) ) - goto Exit; - - face->num_charmaps = cmap_dir.numCMaps; - { - TT_CharMap charmap = face->charmaps; - TT_CharMap limit = charmap + face->num_charmaps; - - - /* read the header of each charmap first */ - if ( ACCESS_Frame( face->num_charmaps * 8L ) ) - goto Exit; - - for ( ; charmap < limit; charmap++ ) - { - TT_CMapTable* cmap; - - - charmap->root.face = (FT_Face)face; - cmap = &charmap->cmap; - - cmap->loaded = FALSE; - cmap->platformID = GET_UShort(); - cmap->platformEncodingID = GET_UShort(); - cmap->offset = (FT_ULong)GET_Long(); - } - - FORGET_Frame(); - - /* now read the rest of each table */ - for ( charmap = face->charmaps; charmap < limit; charmap++ ) - { - TT_CMapTable* cmap = &charmap->cmap; - - - if ( FILE_Seek( table_start + (FT_Long)cmap->offset ) || - READ_Fields( cmap_rec_fields, cmap ) ) - goto Exit; - - cmap->offset = FILE_Pos(); - } - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_OS2 */ - /* */ - /* */ - /* Loads the OS2 table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_OS2( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_OS2* os2; - - const FT_Frame_Field os2_fields[] = - { - FT_FRAME_START( 78 ), - FT_FRAME_USHORT( TT_OS2, version ), - FT_FRAME_SHORT( TT_OS2, xAvgCharWidth ), - FT_FRAME_USHORT( TT_OS2, usWeightClass ), - FT_FRAME_USHORT( TT_OS2, usWidthClass ), - FT_FRAME_SHORT( TT_OS2, fsType ), - FT_FRAME_SHORT( TT_OS2, ySubscriptXSize ), - FT_FRAME_SHORT( TT_OS2, ySubscriptYSize ), - FT_FRAME_SHORT( TT_OS2, ySubscriptXOffset ), - FT_FRAME_SHORT( TT_OS2, ySubscriptYOffset ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptXSize ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptYSize ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptXOffset ), - FT_FRAME_SHORT( TT_OS2, ySuperscriptYOffset ), - FT_FRAME_SHORT( TT_OS2, yStrikeoutSize ), - FT_FRAME_SHORT( TT_OS2, yStrikeoutPosition ), - FT_FRAME_SHORT( TT_OS2, sFamilyClass ), - FT_FRAME_BYTE( TT_OS2, panose[0] ), - FT_FRAME_BYTE( TT_OS2, panose[1] ), - FT_FRAME_BYTE( TT_OS2, panose[2] ), - FT_FRAME_BYTE( TT_OS2, panose[3] ), - FT_FRAME_BYTE( TT_OS2, panose[4] ), - FT_FRAME_BYTE( TT_OS2, panose[5] ), - FT_FRAME_BYTE( TT_OS2, panose[6] ), - FT_FRAME_BYTE( TT_OS2, panose[7] ), - FT_FRAME_BYTE( TT_OS2, panose[8] ), - FT_FRAME_BYTE( TT_OS2, panose[9] ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange1 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange2 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange3 ), - FT_FRAME_ULONG( TT_OS2, ulUnicodeRange4 ), - FT_FRAME_BYTE( TT_OS2, achVendID[0] ), - FT_FRAME_BYTE( TT_OS2, achVendID[1] ), - FT_FRAME_BYTE( TT_OS2, achVendID[2] ), - FT_FRAME_BYTE( TT_OS2, achVendID[3] ), - - FT_FRAME_USHORT( TT_OS2, fsSelection ), - FT_FRAME_USHORT( TT_OS2, usFirstCharIndex ), - FT_FRAME_USHORT( TT_OS2, usLastCharIndex ), - FT_FRAME_SHORT( TT_OS2, sTypoAscender ), - FT_FRAME_SHORT( TT_OS2, sTypoDescender ), - FT_FRAME_SHORT( TT_OS2, sTypoLineGap ), - FT_FRAME_USHORT( TT_OS2, usWinAscent ), - FT_FRAME_USHORT( TT_OS2, usWinDescent ), - FT_FRAME_END - }; - - const FT_Frame_Field os2_fields_extra[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_ULONG( TT_OS2, ulCodePageRange1 ), - FT_FRAME_ULONG( TT_OS2, ulCodePageRange2 ), - FT_FRAME_END - }; - - const FT_Frame_Field os2_fields_extra2[] = - { - FT_FRAME_START( 10 ), - FT_FRAME_SHORT( TT_OS2, sxHeight ), - FT_FRAME_SHORT( TT_OS2, sCapHeight ), - FT_FRAME_USHORT( TT_OS2, usDefaultChar ), - FT_FRAME_USHORT( TT_OS2, usBreakChar ), - FT_FRAME_USHORT( TT_OS2, usMaxContext ), - FT_FRAME_END - }; - - - FT_TRACE2(( "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. */ - error = face->goto_table( face, TTAG_OS2, stream, 0 ); - if ( error ) - { - FT_TRACE2(( "is missing!\n" )); - face->os2.version = 0xFFFF; - error = TT_Err_Ok; - goto Exit; - } - - os2 = &face->os2; - - if ( READ_Fields( os2_fields, os2 ) ) - goto Exit; - - os2->ulCodePageRange1 = 0; - os2->ulCodePageRange2 = 0; - - if ( os2->version >= 0x0001 ) - { - /* only version 1 tables */ - if ( READ_Fields( os2_fields_extra, os2 ) ) - goto Exit; - - if ( os2->version >= 0x0002 ) - { - /* only version 2 tables */ - if ( READ_Fields( os2_fields_extra2, os2 ) ) - goto Exit; - } - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Postscript */ - /* */ - /* */ - /* Loads the Postscript table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_PostScript( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - TT_Postscript* post = &face->postscript; - - static const FT_Frame_Field post_fields[] = - { - FT_FRAME_START( 32 ), - FT_FRAME_ULONG( TT_Postscript, FormatType ), - FT_FRAME_ULONG( TT_Postscript, italicAngle ), - FT_FRAME_SHORT( TT_Postscript, underlinePosition ), - FT_FRAME_SHORT( TT_Postscript, underlineThickness ), - FT_FRAME_ULONG( TT_Postscript, isFixedPitch ), - FT_FRAME_ULONG( TT_Postscript, minMemType42 ), - FT_FRAME_ULONG( TT_Postscript, maxMemType42 ), - FT_FRAME_ULONG( TT_Postscript, minMemType1 ), - FT_FRAME_ULONG( TT_Postscript, maxMemType1 ), - FT_FRAME_END - }; - - - FT_TRACE2(( "PostScript " )); - - error = face->goto_table( face, TTAG_post, stream, 0 ); - if ( error ) - return TT_Err_Post_Table_Missing; - - if ( READ_Fields( post_fields, post ) ) - return error; - - /* we don't load the glyph names, we do that in another */ - /* module (ttpost). */ - FT_TRACE2(( "loaded\n" )); - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_PCLT */ - /* */ - /* */ - /* Loads the PCL 5 Table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_PCLT( TT_Face face, - FT_Stream stream ) - { - static const FT_Frame_Field pclt_fields[] = - { - FT_FRAME_START( 54 ), - FT_FRAME_ULONG ( TT_PCLT, Version ), - FT_FRAME_ULONG ( TT_PCLT, FontNumber ), - FT_FRAME_USHORT( TT_PCLT, Pitch ), - FT_FRAME_USHORT( TT_PCLT, xHeight ), - FT_FRAME_USHORT( TT_PCLT, Style ), - FT_FRAME_USHORT( TT_PCLT, TypeFamily ), - FT_FRAME_USHORT( TT_PCLT, CapHeight ), - FT_FRAME_BYTES ( TT_PCLT, TypeFace, 16 ), - FT_FRAME_BYTES ( TT_PCLT, CharacterComplement, 8 ), - FT_FRAME_BYTES ( TT_PCLT, FileName, 6 ), - FT_FRAME_CHAR ( TT_PCLT, StrokeWeight ), - FT_FRAME_CHAR ( TT_PCLT, WidthType ), - FT_FRAME_BYTE ( TT_PCLT, SerifStyle ), - FT_FRAME_BYTE ( TT_PCLT, Reserved ), - FT_FRAME_END - }; - - FT_Error error; - TT_PCLT* pclt = &face->pclt; - - - FT_TRACE2(( "PCLT " )); - - /* optional table */ - error = face->goto_table( face, TTAG_PCLT, stream, 0 ); - if ( error ) - { - FT_TRACE2(( "missing (optional)\n" )); - pclt->Version = 0; - return TT_Err_Ok; - } - - if ( READ_Fields( pclt_fields, pclt ) ) - goto Exit; - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Gasp */ - /* */ - /* */ - /* Loads the `gasp' table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Gasp( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt j,num_ranges; - TT_GaspRange* gaspranges; - - - FT_TRACE2(( "TT_Load_Gasp: %08p\n", face )); - - /* the gasp table is optional */ - error = face->goto_table( face, TTAG_gasp, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 4L ) ) - goto Exit; - - face->gasp.version = GET_UShort(); - face->gasp.numRanges = GET_UShort(); - - FORGET_Frame(); - - num_ranges = face->gasp.numRanges; - FT_TRACE3(( "number of ranges = %d\n", num_ranges )); - - if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) || - ACCESS_Frame( num_ranges * 4L ) ) - goto Exit; - - face->gasp.gaspRanges = gaspranges; - - for ( j = 0; j < num_ranges; j++ ) - { - gaspranges[j].maxPPEM = GET_UShort(); - gaspranges[j].gaspFlag = GET_UShort(); - - FT_TRACE3(( " [max:%d flag:%d]", - gaspranges[j].maxPPEM, - gaspranges[j].gaspFlag )); - } - FT_TRACE3(( "\n" )); - - FORGET_Frame(); - FT_TRACE2(( "GASP loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Kern */ - /* */ - /* */ - /* Loads the first kerning table with format 0 in the font. Only */ - /* accepts the first horizontal kerning table. Developers should use */ - /* the `ftxkern' extension to access other kerning tables in the font */ - /* file, if they really want to. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Kern( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - FT_UInt n, num_tables, version; - - - /* the kern table is optional; exit silently if it is missing */ - error = face->goto_table( face, TTAG_kern, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 4L ) ) - goto Exit; - - version = GET_UShort(); - num_tables = GET_UShort(); - - FORGET_Frame(); - - for ( n = 0; n < num_tables; n++ ) - { - FT_UInt coverage; - FT_UInt length; - - - if ( ACCESS_Frame( 6L ) ) - goto Exit; - - version = GET_UShort(); /* version */ - length = GET_UShort() - 6; /* substract header length */ - coverage = GET_UShort(); - - FORGET_Frame(); - - if ( coverage == 0x0001 ) - { - FT_UInt num_pairs; - TT_Kern_0_Pair* pair; - TT_Kern_0_Pair* limit; - - - /* found a horizontal format 0 kerning table! */ - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - num_pairs = GET_UShort(); - - /* skip the rest */ - - FORGET_Frame(); - - /* allocate array of kerning pairs */ - if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) || - ACCESS_Frame( 6L * num_pairs ) ) - goto Exit; - - pair = face->kern_pairs; - limit = pair + num_pairs; - for ( ; pair < limit; pair++ ) - { - pair->left = GET_UShort(); - pair->right = GET_UShort(); - pair->value = GET_UShort(); - } - - FORGET_Frame(); - - face->num_kern_pairs = num_pairs; - face->kern_table_index = n; - goto Exit; - } - - if ( FILE_Skip( length ) ) - goto Exit; - } - - /* no kern table found -- doesn't matter */ - face->kern_table_index = -1; - face->num_kern_pairs = 0; - face->kern_pairs = NULL; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Hdmx */ - /* */ - /* */ - /* Loads the horizontal device metrics table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Hdmx( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - TT_Hdmx* hdmx = &face->hdmx; - FT_Long num_glyphs; - FT_Long record_size; - - - hdmx->version = 0; - hdmx->num_records = 0; - hdmx->records = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_hdmx, stream, 0 ); - if ( error ) - return TT_Err_Ok; - - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - hdmx->version = GET_UShort(); - hdmx->num_records = GET_Short(); - record_size = GET_Long(); - - FORGET_Frame(); - - /* Only recognize format 0 */ - if ( hdmx->version != 0 ) - goto Exit; - - if ( ALLOC_ARRAY( hdmx->records, hdmx->num_records, TT_HdmxRec ) ) - goto Exit; - - num_glyphs = face->root.num_glyphs; - record_size -= num_glyphs + 2; - - { - TT_HdmxRec* cur = hdmx->records; - TT_HdmxRec* limit = cur + hdmx->num_records; - - - for ( ; cur < limit; cur++ ) - { - /* read record */ - if ( READ_Byte( cur->ppem ) || - READ_Byte( cur->max_width ) ) - goto Exit; - - if ( ALLOC( cur->widths, num_glyphs ) || - FILE_Read( cur->widths, num_glyphs ) ) - goto Exit; - - /* skip padding bytes */ - if ( record_size > 0 && FILE_Skip( record_size ) ) - goto Exit; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_Hdmx */ - /* */ - /* */ - /* Frees the horizontal device metrics table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_Hdmx( TT_Face face ) - { - if ( face ) - { - FT_Int n; - FT_Memory memory = face->root.driver->root.memory; - - - for ( n = 0; n < face->hdmx.num_records; n++ ) - FREE( face->hdmx.records[n].widths ); - - FREE( face->hdmx.records ); - face->hdmx.num_records = 0; - } - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttload.h b/subsys/win32k/freetype/src/sfnt/ttload.h deleted file mode 100644 index dd0de6a..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttload.h +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttload.h */ -/* */ -/* Load the basic TrueType tables, i.e., tables that can be either in */ -/* TTF or OTF fonts (specification). */ -/* */ -/* Copyright 1996-2000 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 TTLOAD_H -#define TTLOAD_H - - -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - TT_Table* TT_LookUp_Table( TT_Face face, - FT_ULong tag ); - - LOCAL_DEF - FT_Error TT_Goto_Table( TT_Face face, - FT_ULong tag, - FT_Stream stream, - FT_ULong* length ); - - - LOCAL_DEF - FT_Error TT_Load_SFNT_Header( TT_Face face, - FT_Stream stream, - FT_Long face_index, - SFNT_Header* sfnt ); - LOCAL_DEF - FT_Error TT_Load_Directory( TT_Face face, - FT_Stream stream, - SFNT_Header* sfnt ); - - LOCAL_DEF - FT_Error TT_Load_Any( TT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ); - - - LOCAL_DEF - FT_Error TT_Load_Header( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Metrics_Header( TT_Face face, - FT_Stream stream, - FT_Bool vertical ); - - - LOCAL_DEF - FT_Error TT_Load_CMap( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_MaxProfile( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Names( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_OS2( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_PostScript( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Hdmx( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_PCLT( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void TT_Free_Names( TT_Face face ); - - - LOCAL_DEF - void TT_Free_Hdmx ( TT_Face face ); - - - LOCAL_DEF - FT_Error TT_Load_Kern( TT_Face face, - FT_Stream stream ); - - - LOCAL_DEF - FT_Error TT_Load_Gasp( TT_Face face, - FT_Stream stream ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttpost.c b/subsys/win32k/freetype/src/sfnt/ttpost.c deleted file mode 100644 index 4220c6e..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttpost.c +++ /dev/null @@ -1,536 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.c */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (body). */ -/* */ -/* Copyright 1996-2000 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 -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "ttpost.h" -#include "ttload.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttpost - - - /* If this configuration macro is defined, we rely on the `PSNames' */ - /* module to grab the glyph names. */ - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - -#include - -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) - - -#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - /* Otherwise, we ignore the `PSNames' module, and provide our own */ - /* table of Mac names. Thus, it is possible to build a version of */ - /* FreeType without the Type 1 driver & PSNames module. */ - -#define MAC_NAME( x ) TT_Post_Default_Names[x] - - /* the 258 default Mac PS glyph names */ - - FT_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", - }; - - -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ - - - static - FT_Error Load_Format_20( TT_Face face, - FT_Stream stream ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_Int num_names; - - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; - - - if ( READ_UShort( num_glyphs ) ) - goto Exit; - - /* 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_glyphs > face->root.num_glyphs ) - { - error = TT_Err_Invalid_File_Format; - goto Exit; - } - - /* load the indices */ - { - FT_Int n; - - - if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, FT_UShort ) || - ACCESS_Frame( num_glyphs * 2L ) ) - goto Fail; - - for ( n = 0; n < num_glyphs; n++ ) - glyph_indices[n] = GET_UShort(); - - FORGET_Frame(); - } - - /* compute number of names stored in table */ - { - FT_Int n; - - - num_names = 0; - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Int index; - - - index = glyph_indices[n]; - if ( index >= 258 ) - { - index -= 257; - if ( index > num_names ) - num_names = index; - } - } - } - - /* now load the name strings */ - { - FT_Int n; - - - if ( ALLOC_ARRAY( name_strings, num_names, FT_Char* ) ) - goto Fail; - - for ( n = 0; n < num_names; n++ ) - { - FT_UInt len; - - - if ( READ_Byte ( len ) || - ALLOC_ARRAY( name_strings[n], len + 1, FT_Char ) || - FILE_Read ( name_strings[n], len ) ) - goto Fail1; - - name_strings[n][len] = '\0'; - } - } - - /* all right, set table fields and exit successfuly */ - { - TT_Post_20* table = &face->postscript_names.names.format_20; - - - table->num_glyphs = num_glyphs; - table->num_names = num_names; - table->glyph_indices = glyph_indices; - table->glyph_names = name_strings; - } - return TT_Err_Ok; - - - Fail1: - { - FT_Int n; - - - for ( n = 0; n < num_names; n++ ) - FREE( name_strings[n] ); - } - - Fail: - FREE( name_strings ); - FREE( glyph_indices ); - - Exit: - return error; - } - - - static - FT_Error Load_Format_25( TT_Face face, - FT_Stream stream ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - FT_Int num_glyphs; - FT_Char* offset_table = 0; - - - /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ - if ( READ_UShort( num_glyphs ) ) - goto Exit; - - /* check the number of glyphs */ - if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 ) - { - error = TT_Err_Invalid_File_Format; - goto Exit; - } - - if ( ALLOC ( offset_table, num_glyphs ) || - FILE_Read( offset_table, num_glyphs ) ) - goto Fail; - - /* now check the offset table */ - { - FT_Int n; - - - for ( n = 0; n < num_glyphs; n++ ) - { - FT_Long index = (FT_Long)n + offset_table[n]; - - - if ( index < 0 || index > num_glyphs ) - { - error = TT_Err_Invalid_File_Format; - goto Fail; - } - } - } - - /* OK, set table fields and exit successfuly */ - { - TT_Post_25* table = &face->postscript_names.names.format_25; - - - table->num_glyphs = num_glyphs; - table->offsets = offset_table; - } - - return TT_Err_Ok; - - Fail: - FREE( offset_table ); - - Exit: - return error; - } - - - static - FT_Error Load_Post_Names( TT_Face face ) - { - FT_Stream stream; - FT_Error error; - - /* get a stream for the face's resource */ - stream = face->root.stream; - - /* seek to the beginning of the PS names table */ - error = face->goto_table( face, TTAG_post, stream, 0 ); - if ( error ) - goto Exit; - - /* now read postscript table */ - switch ( face->postscript.FormatType ) - { - case 0x00020000L: - error = Load_Format_20( face, stream ); - break; - - case 0x00028000L: - error = Load_Format_25( face, stream ); - break; - - default: - error = TT_Err_Invalid_File_Format; - } - - face->postscript_names.loaded = 1; - - Exit: - return error; - } - - - LOCAL_FUNC - void TT_Free_Post_Names( TT_Face face ) - { - FT_Memory memory = face->root.memory; - TT_Post_Names* names = &face->postscript_names; - - - if ( names->loaded ) - { - switch ( face->postscript.FormatType ) - { - case 0x00020000L: - { - TT_Post_20* table = &names->names.format_20; - FT_UInt n; - - - FREE( table->glyph_indices ); - table->num_glyphs = 0; - - for ( n = 0; n < table->num_names; n++ ) - FREE( table->glyph_names[n] ); - - FREE( table->glyph_names ); - table->num_names = 0; - } - break; - - case 0x00028000L: - { - TT_Post_25* table = &names->names.format_25; - - - FREE( table->offsets ); - table->num_glyphs = 0; - } - break; - } - } - names->loaded = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_PS_Name */ - /* */ - /* */ - /* Gets the PostScript glyph name of a glyph. */ - /* */ - /* */ - /* face :: A handle to the parent face. */ - /* */ - /* index :: The glyph index. */ - /* */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ - /* */ - /* You must not modify the returned string! */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Get_PS_Name( TT_Face face, - FT_UInt index, - FT_String** PSname ) - { - FT_Error error; - TT_Post_Names* names; - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - PSNames_Interface* psnames; -#endif - - - if ( !face ) - return TT_Err_Invalid_Face_Handle; - - if ( index >= (FT_UInt)face->root.num_glyphs ) - return TT_Err_Invalid_Glyph_Index; - -#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - return TT_Err_Unimplemented_Feature; -#endif - - names = &face->postscript_names; - - /* `.notdef' by default */ - *PSname = MAC_NAME( 0 ); - - switch ( face->postscript.FormatType ) - { - case 0x00010000L: - if ( index < 258 ) /* paranoid checking */ - *PSname = MAC_NAME( index ); - break; - - case 0x00020000L: - { - TT_Post_20* table = &names->names.format_20; - - - if ( !names->loaded ) - { - error = Load_Post_Names( face ); - if ( error ) - break; - } - - if ( index < table->num_glyphs ) - { - FT_UShort name_index = table->glyph_indices[index]; - - - if ( name_index < 258 ) - *PSname = MAC_NAME( name_index ); - else - *PSname = (FT_String*)table->glyph_names[name_index - 258]; - } - } - break; - - case 0x00028000L: - { - TT_Post_25* table = &names->names.format_25; - - - if ( !names->loaded ) - { - error = Load_Post_Names( face ); - if ( error ) - break; - } - - if ( index < table->num_glyphs ) /* paranoid checking */ - { - index += table->offsets[index]; - *PSname = MAC_NAME( index ); - } - } - break; - - case 0x00030000L: - break; /* nothing to do */ - } - - return TT_Err_Ok; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttpost.h b/subsys/win32k/freetype/src/sfnt/ttpost.h deleted file mode 100644 index e3da836..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttpost.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpost.h */ -/* */ -/* Postcript name table processing for TrueType and OpenType fonts */ -/* (specification). */ -/* */ -/* Copyright 1996-2000 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 TTPOST_H -#define TTPOST_H - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -#define TT_Err_Invalid_Post_Table_Format 0x0B00 -#define TT_Err_Invalid_Post_Table 0x0B01 - - - LOCAL_DEF - FT_Error TT_Get_PS_Name( TT_Face face, - FT_UInt index, - FT_String** PSname ); - - LOCAL_DEF - void TT_Free_Post_Names( TT_Face face ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTPOST_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttsbit.c b/subsys/win32k/freetype/src/sfnt/ttsbit.c deleted file mode 100644 index 01d2dbf..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttsbit.c +++ /dev/null @@ -1,1444 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.c */ -/* */ -/* TrueType and OpenType embedded bitmap support (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttsbit.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttsbit - - - /*************************************************************************/ - /* */ - /* */ - /* blit_sbit */ - /* */ - /* */ - /* Blits a bitmap from an input stream into a given target. Supports */ - /* x and y offsets as well as byte padded lines. */ - /* */ - /* */ - /* target :: The target bitmap/pixmap. */ - /* */ - /* source :: The input packed bitmap data. */ - /* */ - /* line_bits :: The number of bits per line. */ - /* */ - /* byte_padded :: A flag which is true if lines are byte-padded. */ - /* */ - /* x_offset :: The horizontal offset. */ - /* */ - /* y_offset :: The vertical offset. */ - /* */ - /* */ - /* IMPORTANT: The x and y offsets are relative to the top corner of */ - /* the target bitmap (unlike the normal TrueType */ - /* convention). A positive y offset indicates a downwards */ - /* direction! */ - /* */ - static - void blit_sbit( FT_Bitmap* target, - FT_Byte* source, - FT_Int line_bits, - FT_Bool byte_padded, - FT_Int x_offset, - FT_Int y_offset ) - { - FT_Byte* line_buff; - FT_Int line_incr; - FT_Int height; - - FT_UShort acc; - FT_Byte loaded; - - - /* first of all, compute starting write position */ - line_incr = target->pitch; - line_buff = target->buffer; - - if ( line_incr < 0 ) - line_buff -= line_incr * ( target->rows - 1 ); - - line_buff += ( x_offset >> 3 ) + y_offset * line_incr; - - /***********************************************************************/ - /* */ - /* We use the extra-classic `accumulator' trick to extract the bits */ - /* from the source byte stream. */ - /* */ - /* Namely, the variable `acc' is a 16-bit accumulator containing the */ - /* last `loaded' bits from the input stream. The bits are shifted to */ - /* the upmost position in `acc'. */ - /* */ - /***********************************************************************/ - - acc = 0; /* clear accumulator */ - loaded = 0; /* no bits were loaded */ - - for ( height = target->rows; height > 0; height-- ) - { - FT_Byte* cur = line_buff; /* current write cursor */ - FT_Int count = line_bits; /* # of bits to extract per line */ - FT_Byte shift = x_offset & 7; /* current write shift */ - FT_Byte space = 8 - shift; - - - /* first of all, read individual source bytes */ - if ( count >= 8 ) - { - count -= 8; - { - do - { - FT_Byte val; - - - /* ensure that there are at least 8 bits in the accumulator */ - if ( loaded < 8 ) - { - acc |= (FT_UShort)*source++ << ( 8 - loaded ); - loaded += 8; - } - - /* now write one byte */ - val = (FT_Byte)( acc >> 8 ); - if ( shift ) - { - cur[0] |= val >> shift; - cur[1] |= val << space; - } - else - cur[0] |= val; - - cur++; - acc <<= 8; /* remove bits from accumulator */ - loaded -= 8; - count -= 8; - - } while ( count >= 0 ); - } - - /* restore `count' to correct value */ - count += 8; - } - - /* now write remaining bits (count < 8) */ - if ( count > 0 ) - { - FT_Byte val; - - - /* ensure that there are at least `count' bits in the accumulator */ - if ( loaded < count ) - { - acc |= (FT_UShort)*source++ << ( 8 - loaded ); - loaded += 8; - } - - /* now write remaining bits */ - val = ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ); - cur[0] |= val >> shift; - - if ( count > space ) - cur[1] |= val << space; - - acc <<= count; - loaded -= count; - } - - /* now, skip to next line */ - if ( byte_padded ) - acc = loaded = 0; /* clear accumulator on byte-padded lines */ - - line_buff += line_incr; - } - } - - - const FT_Frame_Field sbit_metrics_fields[] = - { - FT_FRAME_START( 8 ), - FT_FRAME_BYTE( TT_SBit_Metrics, height ), - FT_FRAME_BYTE( TT_SBit_Metrics, width ), - - FT_FRAME_CHAR( TT_SBit_Metrics, horiBearingX ), - FT_FRAME_CHAR( TT_SBit_Metrics, horiBearingY ), - FT_FRAME_BYTE( TT_SBit_Metrics, horiAdvance ), - - FT_FRAME_CHAR( TT_SBit_Metrics, vertBearingX ), - FT_FRAME_CHAR( TT_SBit_Metrics, vertBearingY ), - FT_FRAME_BYTE( TT_SBit_Metrics, vertAdvance ), - FT_FRAME_END - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Const_Metrics */ - /* */ - /* */ - /* Loads the metrics for `EBLC' index tables format 2 and 5. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range, - FT_Stream stream ) - { - FT_Error error; - - - if ( READ_ULong( range->image_size ) ) - return error; - - return READ_Fields( sbit_metrics_fields, &range->metrics ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Range_Codes */ - /* */ - /* */ - /* Loads the range codes for `EBLC' index tables format 4 and 5. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* load_offsets :: A flag whether to load the glyph offset table. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Range_Codes( TT_SBit_Range* range, - FT_Stream stream, - FT_Bool load_offsets ) - { - FT_Error error; - FT_ULong count, n, size; - FT_Memory memory = stream->memory; - - - if ( READ_ULong( count ) ) - goto Exit; - - range->num_glyphs = count; - - /* Allocate glyph offsets table if needed */ - if ( load_offsets ) - { - if ( ALLOC_ARRAY( range->glyph_offsets, count, FT_ULong ) ) - goto Exit; - - size = count * 4L; - } - else - size = count * 2L; - - /* Allocate glyph codes table and access frame */ - if ( ALLOC_ARRAY ( range->glyph_codes, count, FT_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] = (FT_ULong)range->image_offset + - GET_UShort(); - } - - FORGET_Frame(); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Range */ - /* */ - /* */ - /* Loads a given `EBLC' index/range table. */ - /* */ - /* */ - /* range :: The target range. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_SBit_Range( TT_SBit_Range* range, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - - - switch( range->index_format ) - { - case 1: /* variable metrics with 4-byte offsets */ - case 3: /* variable metrics with 2-byte offsets */ - { - FT_ULong num_glyphs, n; - FT_Int size_elem; - FT_Bool large = ( range->index_format == 1 ); - - - num_glyphs = range->last_glyph - range->first_glyph + 1L; - range->num_glyphs = num_glyphs; - num_glyphs++; /* XXX: BEWARE - see spec */ - - size_elem = large ? 4 : 2; - - if ( ALLOC_ARRAY( range->glyph_offsets, - num_glyphs, FT_ULong ) || - ACCESS_Frame( num_glyphs * size_elem ) ) - goto Exit; - - for ( n = 0; n < num_glyphs; n++ ) - range->glyph_offsets[n] = (FT_ULong)( range->image_offset + - ( large ? GET_ULong() - : GET_UShort() ) ); - FORGET_Frame(); - } - break; - - case 2: /* all glyphs have identical metrics */ - error = Load_SBit_Const_Metrics( range, stream ); - break; - - case 4: - error = Load_SBit_Range_Codes( range, stream, 1 ); - break; - - case 5: - error = Load_SBit_Const_Metrics( range, stream ) || - Load_SBit_Range_Codes( range, stream, 0 ); - break; - - default: - error = TT_Err_Invalid_File_Format; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Strikes */ - /* */ - /* */ - /* Loads the table of embedded bitmap sizes for this face. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SBit_Strikes( TT_Face face, - FT_Stream stream ) - { - FT_Error error = 0; - FT_Memory memory = stream->memory; - FT_Fixed version; - FT_ULong num_strikes; - FT_ULong table_base; - - const FT_Frame_Field sbit_line_metrics_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_CHAR( TT_SBit_Line_Metrics, ascender ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, descender ), - FT_FRAME_BYTE( TT_SBit_Line_Metrics, max_width ), - - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_slope_numerator ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_slope_denominator ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, caret_offset ), - - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_origin_SB ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_advance_SB ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, max_before_BL ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, min_after_BL ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, pads[0] ), - FT_FRAME_CHAR( TT_SBit_Line_Metrics, pads[1] ), - FT_FRAME_END - }; - - const FT_Frame_Field strike_start_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_ULONG( TT_SBit_Strike, ranges_offset ), - FT_FRAME_SKIP_LONG, - FT_FRAME_ULONG( TT_SBit_Strike, num_ranges ), - FT_FRAME_ULONG( TT_SBit_Strike, color_ref ), - FT_FRAME_END - }; - - const FT_Frame_Field strike_end_fields[] = - { - /* no FT_FRAME_START */ - FT_FRAME_USHORT( TT_SBit_Strike, start_glyph ), - FT_FRAME_USHORT( TT_SBit_Strike, end_glyph ), - FT_FRAME_BYTE ( TT_SBit_Strike, x_ppem ), - FT_FRAME_BYTE ( TT_SBit_Strike, y_ppem ), - FT_FRAME_BYTE ( TT_SBit_Strike, bit_depth ), - FT_FRAME_CHAR ( TT_SBit_Strike, flags ), - FT_FRAME_END - }; - - - face->num_sbit_strikes = 0; - - /* this table is optional */ - error = face->goto_table( face, TTAG_EBLC, stream, 0 ); - if (error) - error = face->goto_table( face, TTAG_bloc, stream, 0 ); - if ( error ) - { - error = 0; - goto Exit; - } - - table_base = FILE_Pos(); - if ( ACCESS_Frame( 8L ) ) - goto Exit; - - version = GET_Long(); - num_strikes = GET_ULong(); - - FORGET_Frame(); - - /* check version number and strike count */ - if ( version != 0x00020000L || - num_strikes >= 0x10000L ) - { - FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" )); - error = TT_Err_Invalid_File_Format; - - goto Exit; - } - - /* allocate the strikes table */ - if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) ) - goto Exit; - - face->num_sbit_strikes = num_strikes; - - /* now read each strike table separately */ - { - TT_SBit_Strike* strike = face->sbit_strikes; - FT_ULong count = num_strikes; - - - if ( ACCESS_Frame( 48L * num_strikes ) ) - goto Exit; - - while ( count > 0 ) - { - (void)READ_Fields( strike_start_fields, strike ); - - (void)READ_Fields( sbit_line_metrics_fields, &strike->hori ); - (void)READ_Fields( sbit_line_metrics_fields, &strike->vert ); - - (void)READ_Fields( strike_end_fields, strike ); - - count--; - strike++; - } - - FORGET_Frame(); - } - - /* allocate the index ranges for each strike table */ - { - TT_SBit_Strike* strike = face->sbit_strikes; - FT_ULong count = num_strikes; - - - while ( count > 0 ) - { - TT_SBit_Range* range; - FT_ULong count2 = strike->num_ranges; - - - if ( ALLOC_ARRAY( strike->sbit_ranges, - strike->num_ranges, - TT_SBit_Range ) ) - goto Exit; - - /* read each range */ - if ( FILE_Seek( table_base + strike->ranges_offset ) || - ACCESS_Frame( strike->num_ranges * 8L ) ) - goto Exit; - - range = strike->sbit_ranges; - while ( count2 > 0 ) - { - range->first_glyph = GET_UShort(); - range->last_glyph = GET_UShort(); - range->table_offset = table_base + strike->ranges_offset - + GET_ULong(); - count2--; - range++; - } - - FORGET_Frame(); - - /* Now, read each index table */ - count2 = strike->num_ranges; - range = strike->sbit_ranges; - while ( count2 > 0 ) - { - /* Read the header */ - if ( FILE_Seek( range->table_offset ) || - ACCESS_Frame( 8L ) ) - goto Exit; - - range->index_format = GET_UShort(); - range->image_format = GET_UShort(); - range->image_offset = GET_ULong(); - - FORGET_Frame(); - - error = Load_SBit_Range( range, stream ); - if ( error ) - goto Exit; - - count2--; - range++; - } - - count--; - strike++; - } - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Free_SBit_Strikes */ - /* */ - /* */ - /* Releases the embedded bitmap tables. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - LOCAL_FUNC - void TT_Free_SBit_Strikes( TT_Face face ) - { - FT_Memory memory = face->root.memory; - TT_SBit_Strike* strike = face->sbit_strikes; - TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; - - - if ( strike ) - { - for ( ; strike < strike_limit; strike++ ) - { - TT_SBit_Range* range = strike->sbit_ranges; - TT_SBit_Range* range_limit = range + strike->num_ranges; - - - if ( range ) - { - for ( ; range < range_limit; range++ ) - { - /* release the glyph offsets and codes tables */ - /* where appropriate */ - FREE( range->glyph_offsets ); - FREE( range->glyph_codes ); - } - } - FREE( strike->sbit_ranges ); - strike->num_ranges = 0; - } - FREE( face->sbit_strikes ); - } - face->num_sbit_strikes = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Find_SBit_Range */ - /* */ - /* */ - /* Scans a given strike's ranges and return, for a given glyph */ - /* index, the corresponding sbit range, and `EBDT' offset. */ - /* */ - /* */ - /* glyph_index :: The glyph index. */ - /* strike :: The source/current sbit strike. */ - /* */ - /* */ - /* arange :: The sbit range containing the glyph index. */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* */ - /* FreeType error code. 0 means the glyph index was found. */ - /* */ - static - FT_Error Find_SBit_Range( FT_UInt glyph_index, - TT_SBit_Strike* strike, - TT_SBit_Range** arange, - FT_ULong* aglyph_offset ) - { - TT_SBit_Range *range, *range_limit; - - - /* check whether the glyph index is within this strike's */ - /* glyph range */ - if ( glyph_index < strike->start_glyph || - glyph_index > strike->end_glyph ) - goto Fail; - - /* scan all ranges in strike */ - range = strike->sbit_ranges; - range_limit = range + strike->num_ranges; - if ( !range ) - goto Fail; - - for ( ; range < range_limit; range++ ) - { - if ( glyph_index >= range->first_glyph && - glyph_index <= range->last_glyph ) - { - FT_UShort delta = glyph_index - range->first_glyph; - - - switch ( range->index_format ) - { - case 1: - case 3: - *aglyph_offset = range->glyph_offsets[delta]; - break; - - case 2: - *aglyph_offset = range->image_offset + - range->image_size * delta; - break; - - case 4: - case 5: - { - FT_ULong n; - - - for ( n = 0; n < range->num_glyphs; n++ ) - { - if ( range->glyph_codes[n] == glyph_index ) - { - if ( range->index_format == 4 ) - *aglyph_offset = range->glyph_offsets[n]; - else - *aglyph_offset = range->image_offset + - n * range->image_size; - goto Found; - } - } - } - - /* fall-through */ - default: - goto Fail; - } - - Found: - /* return successfully! */ - *arange = range; - return 0; - } - } - - Fail: - *arange = 0; - *aglyph_offset = 0; - - return TT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Find_SBit_Image */ - /* */ - /* */ - /* Checks whether an embedded bitmap (an `sbit') exists for a given */ - /* glyph, at given x and y ppems. */ - /* */ - /* */ - /* face :: The target face object. */ - /* glyph_index :: The glyph index. */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* */ - /* arange :: The SBit range containing the glyph index. */ - /* astrike :: The SBit strike containing the glyph index. */ - /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns */ - /* TT_Err_Invalid_Argument if no sbit exists for the requested glyph. */ - /* */ - static - FT_Error Find_SBit_Image( TT_Face face, - FT_UInt glyph_index, - FT_Int x_ppem, - FT_Int y_ppem, - - TT_SBit_Range** arange, - TT_SBit_Strike** astrike, - FT_ULong* aglyph_offset ) - { - TT_SBit_Strike* strike = face->sbit_strikes; - TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; - - - if ( !strike ) - goto Fail; - - for ( ; strike < strike_limit; strike++ ) - { - if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem ) - { - FT_Error error; - - - error = Find_SBit_Range( glyph_index, strike, - arange, aglyph_offset ); - if ( error ) - goto Fail; - - *astrike = strike; - - return TT_Err_Ok; - } - } - - Fail: - /* no embedded bitmap for this glyph in face */ - *arange = 0; - *astrike = 0; - *aglyph_offset = 0; - - return TT_Err_Invalid_Argument; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Load_SBit_Metrics */ - /* */ - /* */ - /* Gets the big metrics for a given SBit. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* range :: The SBit range containing the glyph. */ - /* */ - /* */ - /* big_metrics :: A big SBit metrics structure for the glyph. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The stream cursor must be positioned at the glyph's offset within */ - /* the `EBDT' table before the call. */ - /* */ - /* If the image format uses variable metrics, the stream cursor is */ - /* positioned just after the metrics header in the `EBDT' table on */ - /* function exit. */ - /* */ - static - FT_Error Load_SBit_Metrics( FT_Stream stream, - TT_SBit_Range* range, - TT_SBit_Metrics* metrics ) - { - FT_Error error = TT_Err_Ok; - - - switch ( range->image_format ) - { - case 1: - case 2: - case 8: - /* variable small metrics */ - { - TT_SBit_Small_Metrics smetrics; - - const FT_Frame_Field sbit_small_metrics_fields[] = - { - FT_FRAME_START( 5 ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, height ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, width ), - FT_FRAME_CHAR( TT_SBit_Small_Metrics, bearingX ), - FT_FRAME_CHAR( TT_SBit_Small_Metrics, bearingY ), - FT_FRAME_BYTE( TT_SBit_Small_Metrics, advance ), - FT_FRAME_END - }; - - - /* read small metrics */ - if ( READ_Fields( sbit_small_metrics_fields, &smetrics ) ) - goto Exit; - - /* convert it to a big metrics */ - metrics->height = smetrics.height; - metrics->width = smetrics.width; - metrics->horiBearingX = smetrics.bearingX; - metrics->horiBearingY = smetrics.bearingY; - metrics->horiAdvance = smetrics.advance; - - /* these metrics are made up at a higher level when */ - /* needed. */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - } - break; - - case 6: - case 7: - case 9: - /* variable big metrics */ - (void)READ_Fields( sbit_metrics_fields, metrics ); - break; - - case 5: - default: /* constant metrics */ - if ( range->index_format == 2 || range->index_format == 5 ) - *metrics = range->metrics; - else - return TT_Err_Invalid_File_Format; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Crop_Bitmap */ - /* */ - /* */ - /* Crops a bitmap to its tightest bounding box, and adjusts its */ - /* metrics. */ - /* */ - /* */ - /* image :: The input glyph slot. */ - /* */ - /* metrics :: The corresponding metrics structure. */ - /* */ - static - void Crop_Bitmap( FT_Bitmap* map, - TT_SBit_Metrics* metrics ) - { - /***********************************************************************/ - /* */ - /* In this situation, some bounding boxes of embedded bitmaps are too */ - /* large. We need to crop it to a reasonable size. */ - /* */ - /* --------- */ - /* | | ----- */ - /* | *** | |***| */ - /* | * | | * | */ - /* | * | ------> | * | */ - /* | * | | * | */ - /* | * | | * | */ - /* | *** | |***| */ - /* --------- ----- */ - /* */ - /***********************************************************************/ - - FT_Int rows, count; - FT_Long line_len; - FT_Byte* line; - - - /***********************************************************************/ - /* */ - /* first of all, check the top-most lines of the bitmap, and remove */ - /* them if they're empty. */ - /* */ - { - line = (FT_Byte*)map->buffer; - rows = map->rows; - line_len = map->pitch; - - - for ( count = 0; count < rows; count++ ) - { - FT_Byte* cur = line; - FT_Byte* 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 = (FT_Byte*)map->buffer; - - MEM_Move( line, line + count * line_len, - ( rows - count ) * line_len ); - - metrics->height -= count; - metrics->horiBearingY -= count; - metrics->vertBearingY -= count; - - map->rows -= count; - rows -= count; - } - } - - /***********************************************************************/ - /* */ - /* second, crop the lower lines */ - /* */ - { - line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len; - - for ( count = 0; count < rows; count++ ) - { - FT_Byte* cur = line; - FT_Byte* 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 ) - { - metrics->height -= count; - rows -= count; - map->rows -= count; - } - } - - /***********************************************************************/ - /* */ - /* third, get rid of the space on the left side of the glyph */ - /* */ - do - { - FT_Byte* limit; - - - line = (FT_Byte*)map->buffer; - 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 = (FT_Byte*)map->buffer; - limit = line + rows * line_len; - - for ( ; line < limit; line += line_len ) - { - FT_Int n, width = map->width; - FT_Byte old; - FT_Byte* cur = line; - - - old = cur[0] << 1; - for ( n = 8; n < width; n += 8 ) - { - FT_Byte val; - - - val = cur[1]; - cur[0] = old | ( val >> 7 ); - old = val << 1; - cur++; - } - cur[0] = old; - } - - map->width--; - metrics->horiBearingX++; - metrics->vertBearingX++; - metrics->width--; - - } while ( map->width > 0 ); - - Found_Left: - - /***********************************************************************/ - /* */ - /* finally, crop the bitmap width to get rid of the space on the right */ - /* side of the glyph. */ - /* */ - do - { - FT_Int right = map->width - 1; - FT_Byte* limit; - FT_Byte mask; - - - line = (FT_Byte*)map->buffer + ( 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 to the right */ - map->width--; - metrics->width--; - - } while ( map->width > 0 ); - - Found_Right: - /* all right, the bitmap was cropped */ - return; - - Empty_Bitmap: - map->width = 0; - map->rows = 0; - map->pitch = 0; - map->pixel_mode = ft_pixel_mode_mono; - } - - - static - FT_Error Load_SBit_Single( FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Int pix_bits, - FT_UShort image_format, - TT_SBit_Metrics* metrics, - FT_Stream stream ) - { - FT_Error error; - - - /* check that the source bitmap fits into the target pixmap */ - if ( x_offset < 0 || x_offset + metrics->width > map->width || - y_offset < 0 || y_offset + metrics->height > map->rows ) - { - error = TT_Err_Invalid_Argument; - - goto Exit; - } - - { - FT_Int glyph_width = metrics->width; - FT_Int glyph_height = metrics->height; - FT_Int glyph_size; - FT_Int line_bits = pix_bits * glyph_width; - FT_Bool pad_bytes = 0; - - - /* compute size of glyph image */ - switch ( image_format ) - { - case 1: /* byte-padded formats */ - case 6: - { - FT_Int line_length; - - - switch ( pix_bits ) - { - case 1: line_length = ( glyph_width + 7 ) >> 3; break; - case 2: line_length = ( glyph_width + 3 ) >> 2; break; - case 4: line_length = ( glyph_width + 1 ) >> 1; break; - default: line_length = glyph_width; - } - - glyph_size = glyph_height * line_length; - pad_bytes = 1; - } - break; - - case 2: - case 5: - case 7: - line_bits = glyph_width * pix_bits; - glyph_size = ( glyph_height * line_bits + 7 ) >> 3; - break; - - default: /* invalid format */ - return TT_Err_Invalid_File_Format; - } - - /* Now read data and draw glyph into target pixmap */ - if ( ACCESS_Frame( glyph_size ) ) - goto Exit; - - /* don't forget to multiply `x_offset' by `map->pix_bits' as */ - /* the sbit blitter doesn't make a difference between pixmap */ - /* depths. */ - blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes, - x_offset * pix_bits, y_offset ); - - FORGET_Frame(); - } - - Exit: - return error; - } - - - static - FT_Error Load_SBit_Image( TT_SBit_Strike* strike, - TT_SBit_Range* range, - FT_ULong ebdt_pos, - FT_ULong glyph_offset, - FT_Bitmap* map, - FT_Int x_offset, - FT_Int y_offset, - FT_Stream stream, - TT_SBit_Metrics* metrics ) - { - FT_Memory memory = stream->memory; - FT_Error error; - - - /* place stream at beginning of glyph data and read metrics */ - if ( FILE_Seek( ebdt_pos + glyph_offset ) ) - goto Exit; - - error = Load_SBit_Metrics( stream, range, metrics ); - if ( error ) - goto Exit; - - /* this function is recursive. At the top-level call, the */ - /* field map.buffer is NULL. We thus begin by finding the */ - /* dimensions of the higher-level glyph to allocate the */ - /* final pixmap buffer */ - if ( map->buffer == 0 ) - { - FT_Long size; - - - map->width = metrics->width; - map->rows = metrics->height; - - switch ( strike->bit_depth ) - { - case 1: - map->pixel_mode = ft_pixel_mode_mono; - map->pitch = ( map->width + 7 ) >> 3; - break; - - case 2: - map->pixel_mode = ft_pixel_mode_pal2; - map->pitch = ( map->width + 3 ) >> 2; - break; - - case 4: - map->pixel_mode = ft_pixel_mode_pal4; - map->pitch = ( map->width + 1 ) >> 1; - break; - - case 8: - map->pixel_mode = ft_pixel_mode_grays; - map->pitch = map->width; - break; - - default: - return TT_Err_Invalid_File_Format; - } - - size = map->rows * map->pitch; - - /* check that there is no empty image */ - if ( size == 0 ) - goto Exit; /* exit successfully! */ - - if ( ALLOC( map->buffer, size ) ) - goto Exit; - } - - switch ( range->image_format ) - { - case 1: /* single sbit image - load it */ - case 2: - case 5: - case 6: - case 7: - return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth, - range->image_format, metrics, stream ); - - case 8: /* compound format */ - FT_Skip_Stream( stream, 1L ); - /* fallthrough */ - - case 9: - break; - - default: /* invalid image format */ - return TT_Err_Invalid_File_Format; - } - - /* All right, we have a compound format. First of all, read */ - /* the array of elements. */ - { - TT_SBit_Component* components; - TT_SBit_Component* comp; - FT_UShort num_components, count; - - - if ( READ_UShort( num_components ) || - ALLOC_ARRAY( components, num_components, TT_SBit_Component ) ) - goto Exit; - - count = num_components; - - if ( ACCESS_Frame( 4L * num_components ) ) - goto Fail_Memory; - - for ( comp = components; count > 0; count--, comp++ ) - { - comp->glyph_code = GET_UShort(); - comp->x_offset = GET_Char(); - comp->y_offset = GET_Char(); - } - - FORGET_Frame(); - - /* Now recursively load each element glyph */ - count = num_components; - comp = components; - for ( ; count > 0; count--, comp++ ) - { - TT_SBit_Range* elem_range; - TT_SBit_Metrics elem_metrics; - FT_ULong elem_offset; - - - /* find the range for this element */ - error = Find_SBit_Range( comp->glyph_code, - strike, - &elem_range, - &elem_offset ); - if ( error ) - goto Fail_Memory; - - /* now load the element, recursively */ - error = Load_SBit_Image( strike, - elem_range, - ebdt_pos, - elem_offset, - map, - x_offset + comp->x_offset, - y_offset + comp->y_offset, - stream, - &elem_metrics ); - if ( error ) - goto Fail_Memory; - } - - Fail_Memory: - FREE( components ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_SBit_Image */ - /* */ - /* */ - /* Loads a given glyph sbit image from the font resource. This also */ - /* returns its metrics. */ - /* */ - /* */ - /* face :: The target face object. */ - /* */ - /* x_ppem :: The horizontal resolution in points per EM. */ - /* */ - /* y_ppem :: The vertical resolution in points per EM. */ - /* */ - /* glyph_index :: The current glyph index. */ - /* */ - /* load_flags :: The glyph load flags (the code checks for the flag */ - /* FT_LOAD_CROP_BITMAP */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* map :: The target pixmap. */ - /* */ - /* metrics :: A big sbit metrics structure for the glyph image. */ - /* */ - /* */ - /* FreeType error code. 0 means success. Returns an error if no */ - /* glyph sbit exists for the index. */ - /* */ - /* */ - /* The `map.buffer' field is always freed before the glyph is loaded. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_SBit_Image( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong ebdt_pos, glyph_offset; - - TT_SBit_Strike* strike; - TT_SBit_Range* range; - - - /* Check whether there is a glyph sbit for the current index */ - error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem, - &range, &strike, &glyph_offset ); - if ( error ) - goto Exit; - - /* now, find the location of the `EBDT' table in */ - /* the font file */ - error = face->goto_table( face, TTAG_EBDT, stream, 0 ); - if ( error ) - error = face->goto_table( face, TTAG_bdat, stream, 0 ); - if (error) - goto Exit; - - ebdt_pos = FILE_Pos(); - - /* clear the bitmap & load the bitmap */ - if ( face->root.glyph->flags & ft_glyph_own_bitmap ) - FREE( map->buffer ); - - map->rows = map->pitch = map->width = 0; - - error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset, - map, 0, 0, stream, metrics ); - if ( error ) - goto Exit; - - /* the glyph slot owns this bitmap buffer */ - face->root.glyph->flags |= ft_glyph_own_bitmap; - - /* setup vertical metrics if needed */ - if ( strike->flags & 1 ) - { - /* in case of a horizontal strike only */ - FT_Int advance; - FT_Int top; - - - advance = strike->hori.ascender - strike->hori.descender; - top = advance / 10; - - /* some heuristic values */ - - metrics->vertBearingX = -metrics->width / 2; - metrics->vertBearingY = advance / 10; - metrics->vertAdvance = advance * 12 / 10; - } - - /* Crop the bitmap now, unless specified otherwise */ - if ( load_flags & FT_LOAD_CROP_BITMAP ) - Crop_Bitmap( map, metrics ); - - Exit: - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/sfnt/ttsbit.h b/subsys/win32k/freetype/src/sfnt/ttsbit.h deleted file mode 100644 index 46b80f3..0000000 --- a/subsys/win32k/freetype/src/sfnt/ttsbit.h +++ /dev/null @@ -1,65 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttsbit.h */ -/* */ -/* TrueType and OpenType embedded bitmap support (specification). */ -/* */ -/* Copyright 1996-2000 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 TTSBIT_H -#define TTSBIT_H - - -#ifdef FT_FLAT_COMPILE - -#include "ttload.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_Load_SBit_Strikes( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void TT_Free_SBit_Strikes( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Load_SBit_Image( TT_Face face, - FT_Int x_ppem, - FT_Int y_ppem, - FT_UInt glyph_index, - FT_UInt load_flags, - FT_Stream stream, - FT_Bitmap* map, - TT_SBit_Metrics* metrics ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTSBIT_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/smooth/.cvsignore b/subsys/win32k/freetype/src/smooth/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/smooth/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/smooth/ftgrays.c b/subsys/win32k/freetype/src/smooth/ftgrays.c deleted file mode 100644 index 5a444ad..0000000 --- a/subsys/win32k/freetype/src/smooth/ftgrays.c +++ /dev/null @@ -1,1969 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.c */ -/* */ -/* A new `perfect' anti-aliasing renderer (body). */ -/* */ -/* Copyright 2000 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 can be compiled without the rest of the FreeType engine, */ - /* by defining the _STANDALONE_ macro when compiling it. You also need */ - /* to put the files `ftgrays.h' and `ftimage.h' into the current */ - /* compilation directory. Typically, you could do something like */ - /* */ - /* - copy `src/base/ftgrays.c' to your current directory */ - /* */ - /* - copy `include/freetype/ftimage.h' and */ - /* `include/freetype/ftgrays.h' to the same directory */ - /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ - /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ - /* */ - /* The renderer can be initialized with a call to */ - /* `ft_grays_raster.grays_raster_new'; an anti-aliased bitmap can be */ - /* generated with a call to `ft_grays_raster.grays_raster_render'. */ - /* */ - /* See the comments and documentation in the file `ftimage.h' for */ - /* more details on how the raster works. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* This is a new anti-aliasing scan-converter for FreeType 2. The */ - /* algorithm used here is _very_ different from the one in the standard */ - /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ - /* coverage of the outline on each pixel cell. */ - /* */ - /* It is based on ideas that I initially found in Raph Levien's */ - /* excellent LibArt graphics library (see http://www.levien.com/libart */ - /* for more information, though the web pages do not tell anything */ - /* about the renderer; you'll have to dive into the source code to */ - /* understand how it works). */ - /* */ - /* Note, however, that this is a _very_ different implementation */ - /* compared to Raph's. Coverage information is stored in a very */ - /* different way, and I don't use sorted vector paths. Also, it */ - /* doesn't use floating point values. */ - /* */ - /* This renderer has the following advantages: */ - /* */ - /* - It doesn't need an intermediate bitmap. Instead, one can supply */ - /* a callback function that will be called by the renderer to draw */ - /* gray spans on any target surface. You can thus do direct */ - /* composition on any kind of bitmap, provided that you give the */ - /* renderer the right callback. */ - /* */ - /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ - /* each pixel cell */ - /* */ - /* - It performs a single pass on the outline (the `standard' FT2 */ - /* renderer makes two passes). */ - /* */ - /* - It can easily be modified to render to _any_ number of gray levels */ - /* cheaply. */ - /* */ - /* - For small (< 20) pixel sizes, it is faster than the standard */ - /* renderer. */ - /* */ - /*************************************************************************/ - - -#include /* for memcpy() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_aaraster - - -#ifdef _STANDALONE_ - - -#define ErrRaster_Invalid_Mode -2 -#define ErrRaster_Invalid_Outline -1 - -#include "ftimage.h" -#include "ftgrays.h" - - /* This macro is used to indicate that a function parameter is unused. */ - /* Its purpose is simply to reduce compiler warnings. Note also that */ - /* simply defining it as `(void)x' doesn't avoid warnings with certain */ - /* ANSI compilers (e.g. LCC). */ -#define FT_UNUSED( x ) (x) = (x) - - /* Disable the tracing mechanism for simplicity -- developers can */ - /* activate it easily by redefining these two macros. */ -#ifndef FT_ERROR -#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ -#endif - -#ifndef FT_TRACE -#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ -#endif - - -#else /* _STANDALONE_ */ - - -#ifdef FT_FLAT_COMPILE - -#include "ftgrays.h" - -#else - -#include - -#endif - - -#include /* for FT_UNUSED() */ -#include /* for FT_TRACE() and FT_ERROR() */ -#include /* for FT_Outline_Decompose() */ - -#define ErrRaster_Invalid_Mode FT_Err_Cannot_Render_Glyph -#define ErrRaster_Invalid_Outline FT_Err_Invalid_Outline - - -#endif /* _STANDALONE_ */ - - - /* define this to dump debugging information */ -#define xxxDEBUG_GRAYS - - /* as usual, for the speed hungry :-) */ - -#ifndef FT_STATIC_RASTER - - -#define RAS_ARG PRaster raster -#define RAS_ARG_ PRaster raster, - -#define RAS_VAR raster -#define RAS_VAR_ raster, - -#define ras (*raster) - - -#else /* FT_STATIC_RASTER */ - - -#define RAS_ARG /* empty */ -#define RAS_ARG_ /* empty */ -#define RAS_VAR /* empty */ -#define RAS_VAR_ /* empty */ - - static TRaster ras; - - -#endif /* FT_STATIC_RASTER */ - - - /* must be at least 6 bits! */ -#define PIXEL_BITS 8 - -#define ONE_PIXEL ( 1L << PIXEL_BITS ) -#define PIXEL_MASK ( -1L << PIXEL_BITS ) -#define TRUNC( x ) ( (x) >> PIXEL_BITS ) -#define SUBPIXELS( x ) ( (x) << PIXEL_BITS ) -#define FLOOR( x ) ( (x) & -ONE_PIXEL ) -#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) -#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) - -#if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) -#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) -#else -#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) -#endif - - /* Define this if you want to use a more compact storage scheme. This */ - /* increases the number of cells available in the render pool but slows */ - /* down the rendering a bit. It is useful if you have a really tiny */ - /* render pool. */ -#define xxxGRAYS_COMPACT - - - /*************************************************************************/ - /* */ - /* TYPE DEFINITIONS */ - /* */ - typedef int TScan; /* integer scanline/pixel coordinate */ - typedef long TPos; /* sub-pixel coordinate */ - - /* maximal number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 - - -#ifdef GRAYS_COMPACT - - typedef struct TCell_ - { - short x : 14; - short y : 14; - int cover : PIXEL_BITS + 2; - int area : PIXEL_BITS * 2 + 2; - - } TCell, *PCell; - -#else /* GRAYS_COMPACT */ - - typedef struct TCell_ - { - TScan x; - TScan y; - int cover; - int area; - - } TCell, *PCell; - -#endif /* GRAYS_COMPACT */ - - - typedef struct TRaster_ - { - PCell cells; - int max_cells; - int num_cells; - - TScan min_ex, max_ex; - TScan min_ey, max_ey; - - int area; - int cover; - int invalid; - - TScan ex, ey; - TScan cx, cy; - TPos x, y; - - TScan last_ey; - - FT_Vector bez_stack[32 * 3]; - int lev_stack[32]; - - FT_Outline outline; - FT_Bitmap target; - - FT_Span gray_spans[FT_MAX_GRAY_SPANS]; - int num_gray_spans; - - FT_Raster_Span_Func render_span; - void* render_span_data; - int span_y; - - int band_size; - int band_shoot; - int conic_level; - int cubic_level; - - void* memory; - - } TRaster, *PRaster; - - - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ - static - void init_cells( RAS_ARG_ void* buffer, - long byte_size ) - { - ras.cells = (PCell)buffer; - ras.max_cells = byte_size / sizeof ( TCell ); - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; - } - - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ - static - void compute_cbox( RAS_ARG_ FT_Outline* outline ) - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - if ( outline->n_points <= 0 ) - { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; - - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; - - - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; - } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; - } - - - /*************************************************************************/ - /* */ - /* Record the current cell in the table. */ - /* */ - static - int record_cell( RAS_ARG ) - { - PCell cell; - - - if ( !ras.invalid && ( ras.area | ras.cover ) ) - { - if ( ras.num_cells >= ras.max_cells ) - return 1; - - cell = ras.cells + ras.num_cells++; - cell->x = ras.ex - ras.min_ex; - cell->y = ras.ey - ras.min_ey; - cell->area = ras.area; - cell->cover = ras.cover; - } - - return 0; - } - - - /*************************************************************************/ - /* */ - /* Set the current cell to a new position. */ - /* */ - static - int set_cell( RAS_ARG_ TScan ex, - TScan ey ) - { - int invalid, record, clean; - - - /* Move the cell pointer to a new position. We set the `invalid' */ - /* flag to indicate that the cell isn't part of those we're interested */ - /* in during the render phase. This means that: */ - /* */ - /* . the new vertical position must be within min_ey..max_ey-1. */ - /* . the new horizontal position must be strictly less than max_ex */ - /* */ - /* Note that if a cell is to the left of the clipping region, it is */ - /* actually set to the (min_ex-1) horizontal position. */ - - record = 0; - clean = 1; - - invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex ); - if ( !invalid ) - { - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - if ( ex < ras.min_ex ) - ex = ras.min_ex - 1; - - /* if our position is new, then record the previous cell */ - if ( ex != ras.ex || ey != ras.ey ) - record = 1; - else - clean = ras.invalid; /* do not clean if we didn't move from */ - /* a valid cell */ - } - - /* record the previous cell if needed (i.e., if we changed the cell */ - /* position, of changed the `invalid' flag) */ - if ( ( ras.invalid != invalid || record ) && record_cell( RAS_VAR ) ) - return 1; - - if ( clean ) - { - ras.area = 0; - ras.cover = 0; - } - - ras.invalid = invalid; - ras.ex = ex; - ras.ey = ey; - return 0; - } - - - /*************************************************************************/ - /* */ - /* Start a new contour at a given cell. */ - /* */ - static - void start_cell( RAS_ARG_ TScan ex, - TScan ey ) - { - if ( ex < ras.min_ex ) - ex = ras.min_ex - 1; - - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - ras.last_ey = SUBPIXELS( ey ); - ras.invalid = 0; - - (void)set_cell( RAS_VAR_ ex, ey ); - } - - - /*************************************************************************/ - /* */ - /* Render a scanline as one or more cells. */ - /* */ - static - int render_scanline( RAS_ARG_ TScan ey, - TPos x1, - TScan y1, - TPos x2, - TScan y2 ) - { - TScan ex1, ex2, fx1, fx2, delta; - long p, first, dx; - int incr, lift, mod, rem; - - - dx = x2 - x1; - - ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */ - ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */ - fx1 = x1 - SUBPIXELS( ex1 ); - fx2 = x2 - SUBPIXELS( ex2 ); - - /* trivial case. Happens often */ - if ( y1 == y2 ) - return set_cell( RAS_VAR_ ex2, ey ); - - /* everything is located in a single cell. That is easy! */ - /* */ - if ( ex1 == ex2 ) - { - delta = y2 - y1; - ras.area += ( fx1 + fx2 ) * delta; - ras.cover += delta; - return 0; - } - - /* ok, we'll have to render a run of adjacent cells on the same */ - /* scanline... */ - /* */ - p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); - first = ONE_PIXEL; - incr = 1; - - if ( dx < 0 ) - { - p = fx1 * ( y2 - y1 ); - first = 0; - incr = -1; - dx = -dx; - } - - delta = p / dx; - mod = p % dx; - if ( mod < 0 ) - { - delta--; - mod += dx; - } - - ras.area += ( fx1 + first ) * delta; - ras.cover += delta; - - ex1 += incr; - if ( set_cell( RAS_VAR_ ex1, ey ) ) - goto Error; - y1 += delta; - - if ( ex1 != ex2 ) - { - p = ONE_PIXEL * ( y2 - y1 ); - lift = p / dx; - rem = p % dx; - if ( rem < 0 ) - { - lift--; - rem += dx; - } - - mod -= dx; - - while ( ex1 != ex2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= dx; - delta++; - } - - ras.area += ONE_PIXEL * delta; - ras.cover += delta; - y1 += delta; - ex1 += incr; - if ( set_cell( RAS_VAR_ ex1, ey ) ) - goto Error; - } - } - - delta = y2 - y1; - ras.area += ( fx2 + ONE_PIXEL - first ) * delta; - ras.cover += delta; - - return 0; - - Error: - return 1; - } - - - /*************************************************************************/ - /* */ - /* Render a given line as a series of scanlines. */ - /* */ - static - int render_line( RAS_ARG_ TPos to_x, - TPos to_y ) - { - TScan ey1, ey2, fy1, fy2; - TPos dx, dy, x, x2; - int p, rem, mod, lift, delta, first, incr; - - - ey1 = TRUNC( ras.last_ey ); - ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = ras.y - ras.last_ey; - fy2 = to_y - SUBPIXELS( ey2 ); - - dx = to_x - ras.x; - dy = to_y - ras.y; - - /* XXX: we should do something about the trivial case where dx == 0, */ - /* as it happens very often! */ - - /* perform vertical clipping */ - { - TScan min, max; - - - min = ey1; - max = ey2; - if ( ey1 > ey2 ) - { - min = ey2; - max = ey1; - } - if ( min >= ras.max_ey || max < ras.min_ey ) - goto End; - } - - /* everything is on a single scanline */ - if ( ey1 == ey2 ) - { - if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ) ) - goto Error; - goto End; - } - - /* ok, we have to render several scanlines */ - p = ( ONE_PIXEL - fy1 ) * dx; - first = ONE_PIXEL; - incr = 1; - - if ( dy < 0 ) - { - p = fy1 * dx; - first = 0; - incr = -1; - dy = -dy; - } - - delta = p / dy; - mod = p % dy; - if ( mod < 0 ) - { - delta--; - mod += dy; - } - - x = ras.x + delta; - if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ) ) - goto Error; - - ey1 += incr; - if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) ) - goto Error; - - if ( ey1 != ey2 ) - { - p = ONE_PIXEL * dx; - lift = p / dy; - rem = p % dy; - if ( rem < 0 ) - { - lift--; - rem += dy; - } - mod -= dy; - - while ( ey1 != ey2 ) - { - delta = lift; - mod += rem; - if ( mod >= 0 ) - { - mod -= dy; - delta++; - } - - x2 = x + delta; - if ( render_scanline( RAS_VAR_ ey1, - x, ONE_PIXEL - first, x2, first ) ) - goto Error; - x = x2; - ey1 += incr; - if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) ) - goto Error; - } - } - - if ( render_scanline( RAS_VAR_ ey1, - x, ONE_PIXEL - first, to_x, fy2 ) ) - goto Error; - - End: - ras.x = to_x; - ras.y = to_y; - ras.last_ey = SUBPIXELS( ey2 ); - - return 0; - - Error: - return 1; - } - - - static - void split_conic( FT_Vector* base ) - { - TPos 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; - } - - - static - int render_conic( RAS_ARG_ FT_Vector* control, - FT_Vector* to ) - { - TPos dx, dy; - int top, level; - int* levels; - FT_Vector* arc; - - - dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - - level = 1; - dx = dx / ras.conic_level; - while ( dx > 0 ) - { - dx >>= 1; - level++; - } - - /* a shortcut to speed things up */ - if ( level <= 1 ) - { - /* we compute the mid-point directly in order to avoid */ - /* calling split_conic() */ - TPos to_x, to_y, mid_x, mid_y; - - - to_x = UPSCALE( to->x ); - to_y = UPSCALE( to->y ); - mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4; - mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4; - - return render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ); - } - - arc = ras.bez_stack; - levels = ras.lev_stack; - top = 0; - levels[0] = level; - - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control->x ); - arc[1].y = UPSCALE( control->y ); - arc[2].x = ras.x; - arc[2].y = ras.y; - - while ( top >= 0 ) - { - level = levels[top]; - if ( level > 1 ) - { - /* check that the arc crosses the current band */ - TPos min, max, y; - - - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) - goto Draw; - - split_conic( arc ); - arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = arc[0].x; - to_y = arc[0].y; - mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4; - mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4; - - if ( render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ) ) - return 1; - - top--; - arc -= 2; - } - } - return 0; - } - - - static - void split_cubic( FT_Vector* base ) - { - TPos a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; - } - - - static - int render_cubic( RAS_ARG_ FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - TPos dx, dy, da, db; - int top, level; - int* levels; - FT_Vector* arc; - - - dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - da = dx; - - dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x ); - if ( dx < 0 ) - dx = -dx; - dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y ); - if ( dy < 0 ) - dy = -dy; - if ( dx < dy ) - dx = dy; - db = dx; - - level = 1; - da = da / ras.cubic_level; - db = db / ras.conic_level; - while ( da > 0 || db > 0 ) - { - da >>= 1; - db >>= 2; - level++; - } - - if ( level <= 1 ) - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = UPSCALE( to->x ); - to_y = UPSCALE( to->y ); - mid_x = ( ras.x + to_x + - 3 * UPSCALE( control1->x + control2->x ) ) / 8; - mid_y = ( ras.y + to_y + - 3 * UPSCALE( control1->y + control2->y ) ) / 8; - - return render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ); - } - - arc = ras.bez_stack; - arc[0].x = UPSCALE( to->x ); - arc[0].y = UPSCALE( to->y ); - arc[1].x = UPSCALE( control2->x ); - arc[1].y = UPSCALE( control2->y ); - arc[2].x = UPSCALE( control1->x ); - arc[2].y = UPSCALE( control1->y ); - arc[3].x = ras.x; - arc[3].y = ras.y; - - levels = ras.lev_stack; - top = 0; - levels[0] = level; - - while ( top >= 0 ) - { - level = levels[top]; - if ( level > 1 ) - { - /* check that the arc crosses the current band */ - TPos min, max, y; - - - min = max = arc[0].y; - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - y = arc[3].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 ) - goto Draw; - split_cubic( arc ); - arc += 3; - top ++; - levels[top] = levels[top - 1] = level - 1; - continue; - } - - Draw: - { - TPos to_x, to_y, mid_x, mid_y; - - - to_x = arc[0].x; - to_y = arc[0].y; - mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8; - mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8; - - if ( render_line( RAS_VAR_ mid_x, mid_y ) || - render_line( RAS_VAR_ to_x, to_y ) ) - return 1; - top --; - arc -= 3; - } - } - return 0; - } - - - /* a macro comparing two cell pointers. Returns true if a <= b. */ -#if 1 - -#define PACK( a ) ( ( (long)(a)->y << 16 ) + (a)->x ) -#define LESS_THAN( a, b ) ( PACK( a ) < PACK( b ) ) - -#else /* 1 */ - -#define LESS_THAN( a, b ) ( (a)->y < (b)->y || \ - ( (a)->y == (b)->y && (a)->x < (b)->x ) ) - -#endif /* 1 */ - -#define SWAP_CELLS( a, b, temp ) do \ - { \ - temp = *(a); \ - *(a) = *(b); \ - *(b) = temp; \ - } while ( 0 ) -#define DEBUG_SORT -#define QUICK_SORT - -#ifdef SHELL_SORT - - /* a simple shell sort algorithm that works directly on our */ - /* cells table */ - static - void shell_sort ( PCell cells, - int count ) - { - PCell i, j, limit = cells + count; - TCell temp; - int gap; - - - /* compute initial gap */ - for ( gap = 0; ++gap < count; gap *= 3 ) - ; - - while ( gap /= 3 ) - { - for ( i = cells + gap; i < limit; i++ ) - { - for ( j = i - gap; ; j -= gap ) - { - PCell k = j + gap; - - - if ( LESS_THAN( j, k ) ) - break; - - SWAP_CELLS( j, k, temp ); - - if ( j < cells + gap ) - break; - } - } - } - } - -#endif /* SHELL_SORT */ - - -#ifdef QUICK_SORT - - /* This is a non-recursive quicksort that directly process our cells */ - /* array. It should be faster than calling the stdlib qsort(), and we */ - /* can even tailor our insertion threshold... */ - -#define QSORT_THRESHOLD 9 /* below this size, a sub-array will be sorted */ - /* through a normal insertion sort */ - - static - void quick_sort( PCell cells, - int count ) - { - PCell stack[40]; /* should be enough ;-) */ - PCell* top; /* top of stack */ - PCell base, limit; - TCell temp; - - - limit = cells + count; - base = cells; - top = stack; - - for (;;) - { - int len = limit - base; - PCell i, j, pivot; - - - if ( len > QSORT_THRESHOLD ) - { - /* we use base + len/2 as the pivot */ - pivot = base + len / 2; - SWAP_CELLS( base, pivot, temp ); - - i = base + 1; - j = limit - 1; - - /* now ensure that *i <= *base <= *j */ - if ( LESS_THAN( j, i ) ) - SWAP_CELLS( i, j, temp ); - - if ( LESS_THAN( base, i ) ) - SWAP_CELLS( base, i, temp ); - - if ( LESS_THAN( j, base ) ) - SWAP_CELLS( base, j, temp ); - - for (;;) - { - do i++; while ( LESS_THAN( i, base ) ); - do j--; while ( LESS_THAN( base, j ) ); - - if ( i > j ) - break; - - SWAP_CELLS( i, j, temp ); - } - - SWAP_CELLS( base, j, temp ); - - /* now, push the largest sub-array */ - if ( j - base > limit - i ) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - /* the sub-array is small, perform insertion sort */ - j = base; - i = j + 1; - - for ( ; i < limit; j = i, i++ ) - { - for ( ; LESS_THAN( j + 1, j ); j-- ) - { - SWAP_CELLS( j + 1, j, temp ); - if ( j == base ) - break; - } - } - if ( top > stack ) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - break; - } - } - } - -#endif /* QUICK_SORT */ - - -#ifdef DEBUG_GRAYS -#ifdef DEBUG_SORT - - static - int check_sort( PCell cells, - int count ) - { - PCell p, q; - - - for ( p = cells + count - 2; p >= cells; p-- ) - { - q = p + 1; - if ( !LESS_THAN( p, q ) ) - return 0; - } - return 1; - } - -#endif /* DEBUG_SORT */ -#endif /* DEBUG_GRAYS */ - - - static - int Move_To( FT_Vector* to, - FT_Raster raster ) - { - TPos x, y; - - - /* record current cell, if any */ - record_cell( (PRaster)raster ); - - /* start to a new position */ - x = UPSCALE( to->x ); - y = UPSCALE( to->y ); - start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) ); - ((PRaster)raster)->x = x; - ((PRaster)raster)->y = y; - return 0; - } - - - static - int Line_To( FT_Vector* to, - FT_Raster raster ) - { - return render_line( (PRaster)raster, - UPSCALE( to->x ), UPSCALE( to->y ) ); - } - - - static - int Conic_To( FT_Vector* control, - FT_Vector* to, - FT_Raster raster ) - { - return render_conic( (PRaster)raster, control, to ); - } - - - static - int Cubic_To( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - FT_Raster raster ) - { - return render_cubic( (PRaster)raster, control1, control2, to ); - } - - - static - void grays_render_span( int y, - int count, - FT_Span* spans, - PRaster raster ) - { - unsigned char* p; - FT_Bitmap* map = &raster->target; - - - /* first of all, compute the scanline offset */ - p = (unsigned char*)map->buffer - y * map->pitch; - if ( map->pitch >= 0 ) - p += ( map->rows - 1 ) * map->pitch; - - for ( ; count > 0; count--, spans++ ) - { - if ( spans->coverage ) -#if 1 - memset( p + spans->x, (unsigned char)spans->coverage, spans->len ); -#else /* 1 */ - { - q = p + spans->x; - limit = q + spans->len; - for ( ; q < limit; q++ ) - q[0] = (unsigned char)spans->coverage; - } -#endif /* 1 */ - } - } - - -#ifdef DEBUG_GRAYS - -#include - - static - void dump_cells( RAS_ARG ) - { - PCell cell, limit; - int y = -1; - - - cell = ras.cells; - limit = cell + ras.num_cells; - - for ( ; cell < limit; cell++ ) - { - if ( cell->y != y ) - { - fprintf( stderr, "\n%2d: ", cell->y ); - y = cell->y; - } - fprintf( stderr, "[%d %d %d]", - cell->x, cell->area, cell->cover ); - } - fprintf(stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - - static - void grays_hline( RAS_ARG_ TScan x, - TScan y, - TPos area, - int acount ) - { - FT_Span* span; - int count; - int coverage; - - - /* compute the coverage line's coverage, depending on the */ - /* outline fill rule */ - /* */ - /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - /* */ - coverage = area >> ( PIXEL_BITS * 2 + 1 - 8); /* use range 0..256 */ - - if ( ras.outline.flags & ft_outline_even_odd_fill ) - { - if ( coverage < 0 ) - coverage = -coverage; - - while ( coverage >= 512 ) - coverage -= 512; - - if ( coverage > 256 ) - coverage = 512 - coverage; - else if ( coverage == 256 ) - coverage = 255; - } - else - { - /* normal non-zero winding rule */ - if ( coverage < 0 ) - coverage = -coverage; - - if ( coverage >= 256 ) - coverage = 255; - } - - y += ras.min_ey; - x += ras.min_ex; - - if ( coverage ) - { - /* see if we can add this span to the current list */ - count = ras.num_gray_spans; - span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) - { - span->len += acount; - return; - } - - if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) - { - if ( ras.render_span ) - ras.render_span( ras.span_y, count, ras.gray_spans, - ras.render_span_data ); - /* ras.render_span( span->y, ras.gray_spans, count ); */ - -#ifdef DEBUG_GRAYS - - if ( ras.span_y >= 0 ) - { - int n; - - - fprintf( stderr, "y=%3d ", ras.span_y ); - span = ras.gray_spans; - for ( n = 0; n < count; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - ras.num_gray_spans = 0; - ras.span_y = y; - - count = 0; - span = ras.gray_spans; - } - else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - ras.num_gray_spans++; - } - } - - - static - void grays_sweep( RAS_ARG_ FT_Bitmap* target ) - { - TScan x, y, cover, area; - PCell start, cur, limit; - - FT_UNUSED( target ); - - - cur = ras.cells; - limit = cur + ras.num_cells; - - cover = 0; - ras.span_y = -1; - ras.num_gray_spans = 0; - - for (;;) - { - start = cur; - y = start->y; - x = start->x; - - area = start->area; - cover += start->cover; - - /* accumulate all start cells */ - for (;;) - { - ++cur; - if ( cur >= limit || cur->y != start->y || cur->x != start->x ) - break; - - area += cur->area; - cover += cur->cover; - } - - /* if the start cell has a non-null area, we must draw an */ - /* individual gray pixel there */ - if ( area && x >= 0 ) - { - grays_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 ); - x++; - } - - if ( x < 0 ) - x = 0; - - if ( cur < limit && start->y == cur->y ) - { - /* draw a gray span between the start cell and the current one */ - if ( cur->x > x ) - grays_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), cur->x - x ); - } - else - { - /* draw a gray span until the end of the clipping region */ - if ( cover && x < ras.max_ex - ras.min_ex ) - grays_hline( RAS_VAR_ x, y, - cover * ( ONE_PIXEL * 2 ), - ras.max_ex - x - ras.min_ex ); - cover = 0; - } - - if ( cur >= limit ) - break; - } - - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.span_y, ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); - -#ifdef DEBUG_GRAYS - - { - int n; - FT_Span* span; - - - fprintf( stderr, "y=%3d ", ras.span_y ); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - fprintf( stderr, "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage ); - fprintf( stderr, "\n" ); - } - -#endif /* DEBUG_GRAYS */ - - } - - -#ifdef _STANDALONE_ - - /*************************************************************************/ - /* */ - /* The following function should only compile in stand_alone mode, */ - /* i.e., when building this component without the rest of FreeType. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* FT_Outline_Decompose */ - /* */ - /* */ - /* Walks over an outline's structure to decompose it into individual */ - /* segments and Bezier arcs. This function is also able to emit */ - /* `move to' and `close to' operations to indicate the start and end */ - /* of new contours in the outline. */ - /* */ - /* */ - /* outline :: A pointer to the source target. */ - /* */ - /* interface :: A table of `emitters', i.e,. function pointers called */ - /* during decomposition to indicate path operations. */ - /* */ - /* user :: A typeless pointer which is passed to each emitter */ - /* during the decomposition. It can be used to store */ - /* the state during the decomposition. */ - /* */ - /* */ - /* Error code. 0 means sucess. */ - /* */ - static - int FT_Outline_Decompose( FT_Outline* outline, - FT_Outline_Funcs* interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - int n; /* index of contour in outline */ - int first; /* index of first point in contour */ - int error; - char tag; /* current point's state */ - - int shift = interface->shift; - FT_Pos delta = interface->delta; - - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - int last; /* index of last point in contour */ - - - last = outline->contours[n]; - limit = outline->points + last; - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_Curve_Tag_Conic ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_Curve_Tag_On ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - error = interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_Curve_Tag_On: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_Curve_Tag_Conic: /* consume conic arcs */ - { - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_Curve_Tag_On ) - { - error = interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_Curve_Tag_Conic ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = interface->conic_to( &v_control, &v_start, user ); - goto Close; - } - - default: /* FT_Curve_Tag_Cubic */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - error = interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - error = interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - return 0; - - Exit: - return error; - - Invalid_Outline: - return ErrRaster_Invalid_Outline; - } - -#endif /* _STANDALONE_ */ - - - typedef struct TBand_ - { - FT_Pos min, max; - - } TBand; - - - static - int grays_convert_glyph( RAS_ARG_ FT_Outline* outline ) - { - static - FT_Outline_Funcs interface = - { - (FT_Outline_MoveTo_Func) Move_To, - (FT_Outline_LineTo_Func) Line_To, - (FT_Outline_ConicTo_Func)Conic_To, - (FT_Outline_CubicTo_Func)Cubic_To, - 0, - 0 - }; - - TBand bands[40], *band; - int n, num_bands; - TPos min, max, max_y; - - - /* Set up state in the raster object */ - compute_cbox( RAS_VAR_ outline ); - - /* clip to target bitmap, exit if nothing to do */ - if ( ras.max_ex <= 0 || ras.min_ex >= ras.target.width || - ras.max_ey <= 0 || ras.min_ey >= ras.target.rows ) - return 0; - - if ( ras.min_ex < 0 ) ras.min_ex = 0; - if ( ras.min_ey < 0 ) ras.min_ey = 0; - - if ( ras.max_ex > ras.target.width ) ras.max_ex = ras.target.width; - if ( ras.max_ey > ras.target.rows ) ras.max_ey = ras.target.rows; - - /* simple heuristic used to speed-up the bezier decomposition -- see */ - /* the code in render_conic() and render_cubic() for more details */ - ras.conic_level = 32; - ras.cubic_level = 16; - - { - int level = 0; - - - if ( ras.max_ex > 24 || ras.max_ey > 24 ) - level++; - if ( ras.max_ex > 120 || ras.max_ey > 120 ) - level += 2; - - ras.conic_level <<= level; - ras.cubic_level <<= level; - } - - /* setup vertical bands */ - num_bands = ( ras.max_ey - ras.min_ey ) / ras.band_size; - if ( num_bands == 0 ) num_bands = 1; - if ( num_bands >= 39 ) num_bands = 39; - - ras.band_shoot = 0; - - min = ras.min_ey; - max_y = ras.max_ey; - - for ( n = 0; n < num_bands; n++, min = max ) - { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) - max = max_y; - - bands[0].min = min; - bands[0].max = max; - band = bands; - - while ( band >= bands ) - { - FT_Pos bottom, top, middle; - int error; - - - ras.num_cells = 0; - ras.invalid = 1; - ras.min_ey = band->min; - ras.max_ey = band->max; - - error = FT_Outline_Decompose( outline, &interface, &ras ) || - record_cell( RAS_VAR ); - - if ( !error ) - { -#ifdef SHELL_SORT - shell_sort( ras.cells, ras.num_cells ); -#else - quick_sort( ras.cells, ras.num_cells ); -#endif - -#ifdef DEBUG_GRAYS - check_sort( ras.cells, ras.num_cells ); - dump_cells( RAS_VAR ); -#endif - - grays_sweep( RAS_VAR_ &ras.target ); - band--; - continue; - } - - /* render pool overflow, we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ( ( top - bottom ) >> 1 ); - - /* waoow! This is too complex for a single scanline, something */ - /* must be really rotten here! */ - if ( middle == bottom ) - { -#ifdef DEBUG_GRAYS - fprintf( stderr, "Rotten glyph!\n" ); -#endif - return 1; - } - - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; - band++; - } - } - - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - - return 0; - } - - - extern - int grays_raster_render( PRaster raster, - FT_Raster_Params* params ) - { - FT_Outline* outline = (FT_Outline*)params->source; - FT_Bitmap* target_map = params->target; - - - if ( !raster || !raster->cells || !raster->max_cells ) - return -1; - - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return 0; - - if ( !outline || !outline->contours || !outline->points ) - return ErrRaster_Invalid_Outline; - - if ( outline->n_points != - outline->contours[outline->n_contours - 1] + 1 ) - return ErrRaster_Invalid_Outline; - - if ( !target_map || !target_map->buffer ) - return -1; - - /* XXX: this version does not support monochrome rendering yet! */ - if ( !(params->flags & ft_raster_flag_aa) ) - return ErrRaster_Invalid_Mode; - - ras.outline = *outline; - ras.target = *target_map; - ras.num_cells = 0; - ras.invalid = 1; - - ras.render_span = (FT_Raster_Span_Func)grays_render_span; - ras.render_span_data = &ras; - - if ( params->flags & ft_raster_flag_direct ) - { - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - } - - return grays_convert_glyph( (PRaster)raster, outline ); - } - - - /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ - /**** a static object. *****/ - -#ifdef _STANDALONE_ - - static - int grays_raster_new( void* memory, - FT_Raster* araster ) - { - static TRaster the_raster; - - FT_UNUSED( memory ); - - - *araster = (FT_Raster)&the_raster; - memset( &the_raster, 0, sizeof ( the_raster ) ); - - return 0; - } - - - static - void grays_raster_done( FT_Raster raster ) - { - /* nothing */ - FT_UNUSED( raster ); - } - -#else /* _STANDALONE_ */ - - static - int grays_raster_new( FT_Memory memory, - FT_Raster* araster ) - { - FT_Error error; - PRaster raster; - - - *araster = 0; - if ( !ALLOC( raster, sizeof ( TRaster ) ) ) - { - raster->memory = memory; - *araster = (FT_Raster)raster; - } - - return error; - } - - - static - void grays_raster_done( FT_Raster raster ) - { - FT_Memory memory = (FT_Memory)((PRaster)raster)->memory; - - - FREE( raster ); - } - -#endif /* _STANDALONE_ */ - - - static - void grays_raster_reset( FT_Raster raster, - const char* pool_base, - long pool_size ) - { - PRaster rast = (PRaster)raster; - - - if ( raster && pool_base && pool_size >= 4096 ) - init_cells( rast, (char*)pool_base, pool_size ); - - rast->band_size = ( pool_size / sizeof ( TCell ) ) / 8; - } - - - FT_Raster_Funcs ft_grays_raster = - { - ft_glyph_format_outline, - - (FT_Raster_New_Func) grays_raster_new, - (FT_Raster_Reset_Func) grays_raster_reset, - (FT_Raster_Set_Mode_Func)0, - (FT_Raster_Render_Func) grays_raster_render, - (FT_Raster_Done_Func) grays_raster_done - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/smooth/ftgrays.h b/subsys/win32k/freetype/src/smooth/ftgrays.h deleted file mode 100644 index 2423a0e..0000000 --- a/subsys/win32k/freetype/src/smooth/ftgrays.h +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgrays.h */ -/* */ -/* FreeType smooth renderer declaration */ -/* */ -/* Copyright 1996-2000 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 FTGRAYS_H -#define FTGRAYS_H - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef _STANDALONE_ -#include "ftimage.h" -#else -#include -#endif - - /*************************************************************************/ - /* */ - /* To make ftgrays.h independent from configuration files we check */ - /* whether FT_EXPORT_DEF has been defined already. */ - /* */ - /* On some systems and compilers (Win32 mostly), an extra keyword is */ - /* necessary to compile the library as a DLL. */ - /* */ -#ifndef FT_EXPORT_VAR -#define FT_EXPORT_VAR( x ) extern x -#endif - - FT_EXPORT_VAR( FT_Raster_Funcs ) ft_grays_raster; - -#ifdef __cplusplus - } -#endif - -#endif /* FTGRAYS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/smooth/ftsmooth.c b/subsys/win32k/freetype/src/smooth/ftsmooth.c deleted file mode 100644 index 6e0e46a..0000000 --- a/subsys/win32k/freetype/src/smooth/ftsmooth.c +++ /dev/null @@ -1,220 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.c */ -/* */ -/* Anti-aliasing renderer interface (body). */ -/* */ -/* Copyright 2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ftsmooth.h" -#include "ftgrays.h" - -#else - -#include -#include - -#endif - - - /* initialize renderer -- init its raster */ - static - FT_Error ft_smooth_init( FT_Renderer render ) - { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); - - return 0; - } - - - /* sets render-specific mode */ - static - FT_Error ft_smooth_set_mode( FT_Renderer render, - FT_ULong mode_tag, - FT_Pointer data ) - { - /* we simply pass it to the raster */ - return render->clazz->raster_class->raster_set_mode( render->raster, - mode_tag, - data ); - } - - /* transform a given glyph image */ - static - FT_Error ft_smooth_transform( FT_Renderer render, - FT_GlyphSlot slot, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Error error = FT_Err_Ok; - - - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( matrix ) - FT_Outline_Transform( &slot->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &slot->outline, delta->x, delta->y ); - - Exit: - return error; - } - - - /* return the glyph's control box */ - static - void ft_smooth_get_cbox( FT_Renderer render, - FT_GlyphSlot slot, - FT_BBox* cbox ) - { - MEM_Set( cbox, 0, sizeof ( *cbox ) ); - - if ( slot->format == render->glyph_format ) - FT_Outline_Get_CBox( &slot->outline, cbox ); - } - - - /* convert a slot's glyph image into a bitmap */ - static - FT_Error ft_smooth_render( FT_Renderer render, - FT_GlyphSlot slot, - FT_UInt mode, - FT_Vector* origin ) - { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; - - FT_Raster_Params params; - - - /* check glyph image format */ - if ( slot->format != render->glyph_format ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - /* check mode */ - if ( mode != ft_render_mode_normal ) - return FT_Err_Cannot_Render_Glyph; - - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - - width = ( cbox.xMax - cbox.xMin ) >> 6; - height = ( cbox.yMax - cbox.yMin ) >> 6; - bitmap = &slot->bitmap; - memory = render->root.memory; - - /* release old bitmap buffer */ - if ( slot->flags & ft_glyph_own_bitmap ) - { - FREE( bitmap->buffer ); - slot->flags &= ~ft_glyph_own_bitmap; - } - - /* allocate new one, depends on pixel format */ - pitch = width; - bitmap->pixel_mode = ft_pixel_mode_grays; - bitmap->num_grays = 256; - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = pitch; - - if ( ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) ) - goto Exit; - - slot->flags |= ft_glyph_own_bitmap; - - /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); - - /* set up parameters */ - params.target = bitmap; - params.source = outline; - params.flags = ft_raster_flag_aa; - - /* render outline into the bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - slot->format = ft_glyph_format_bitmap; - slot->bitmap_left = cbox.xMin >> 6; - slot->bitmap_top = cbox.yMax >> 6; - - Exit: - return error; - } - - - const FT_Renderer_Class ft_smooth_renderer_class = - { - { - ft_module_renderer, - sizeof( FT_RendererRec ), - - "smooth", - 0x10000L, - 0x20000L, - - 0, /* module specific interface */ - - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - ft_glyph_format_outline, - - (FTRenderer_render) ft_smooth_render, - (FTRenderer_transform)ft_smooth_transform, - (FTRenderer_getCBox) ft_smooth_get_cbox, - (FTRenderer_setMode) ft_smooth_set_mode, - - (FT_Raster_Funcs*) &ft_grays_raster - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/smooth/ftsmooth.h b/subsys/win32k/freetype/src/smooth/ftsmooth.h deleted file mode 100644 index 4b8a533..0000000 --- a/subsys/win32k/freetype/src/smooth/ftsmooth.h +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsmooth.h */ -/* */ -/* Anti-aliasing renderer interface (specification). */ -/* */ -/* Copyright 1996-2000 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 FTSMOOTH_H -#define FTSMOOTH_H - -#include - -#ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_std_renderer_class; -#endif - -#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER - FT_EXPORT_VAR( const FT_Renderer_Class ) ft_smooth_renderer_class; -#endif - -#endif /* FTSMOOTH_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/smooth/module.mk b/subsys/win32k/freetype/src/smooth/module.mk deleted file mode 100644 index b93bc4d..0000000 --- a/subsys/win32k/freetype/src/smooth/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_smooth_renderer - -add_smooth_renderer: - $(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)smooth $(ECHO_DRIVER_DESC)anti-aliased bitmap renderer$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/smooth/rules.mk b/subsys/win32k/freetype/src/smooth/rules.mk deleted file mode 100644 index a81d60a..0000000 --- a/subsys/win32k/freetype/src/smooth/rules.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# FreeType 2 renderer module build rules -# - - -# Copyright 1996-2000 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. - - -# smooth driver directory -# -SMOOTH_DIR := $(SRC_)smooth -SMOOTH_DIR_ := $(SMOOTH_DIR)$(SEP) - -# compilation flags for the driver -# -SMOOTH_COMPILE := $(FT_COMPILE) - - -# smooth driver sources (i.e., C files) -# -SMOOTH_DRV_SRC := $(SMOOTH_DIR_)ftgrays.c \ - $(SMOOTH_DIR_)ftsmooth.c - - -# smooth driver headers -# -SMOOTH_DRV_H := $(SMOOTH_DRV_SRC:%c=%h) - - -# smooth driver object(s) -# -# SMOOTH_DRV_OBJ_M is used during `multi' builds. -# SMOOTH_DRV_OBJ_S is used during `single' builds. -# -SMOOTH_DRV_OBJ_M := $(SMOOTH_DRV_SRC:$(SMOOTH_DIR_)%.c=$(OBJ_)%.$O) -SMOOTH_DRV_OBJ_S := $(OBJ_)smooth.$O - -# smooth driver source file for single build -# -SMOOTH_DRV_SRC_S := $(SMOOTH_DIR_)smooth.c - - -# smooth driver - single object -# -$(SMOOTH_DRV_OBJ_S): $(SMOOTH_DRV_SRC_S) $(SMOOTH_DRV_SRC) \ - $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $(SMOOTH_DRV_SRC_S) - - -# smooth driver - multiple objects -# -$(OBJ_)%.$O: $(SMOOTH_DIR_)%.c $(FREETYPE_H) $(SMOOTH_DRV_H) - $(SMOOTH_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(SMOOTH_DRV_OBJ_S) -DRV_OBJS_M += $(SMOOTH_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/smooth/smooth.c b/subsys/win32k/freetype/src/smooth/smooth.c deleted file mode 100644 index f8d4a59..0000000 --- a/subsys/win32k/freetype/src/smooth/smooth.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************/ -/* */ -/* smooth.c */ -/* */ -/* FreeType anti-aliasing rasterer module component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ftgrays.c" -#include "ftsmooth.c" - -#else - -#include -#include - -#endif - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/.cvsignore b/subsys/win32k/freetype/src/truetype/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/truetype/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/truetype/module.mk b/subsys/win32k/freetype/src/truetype/module.mk deleted file mode 100644 index 79072bb..0000000 --- a/subsys/win32k/freetype/src/truetype/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_truetype_driver - -add_truetype_driver: - $(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)truetype $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/truetype/rules.mk b/subsys/win32k/freetype/src/truetype/rules.mk deleted file mode 100644 index 9289378..0000000 --- a/subsys/win32k/freetype/src/truetype/rules.mk +++ /dev/null @@ -1,70 +0,0 @@ -# -# FreeType 2 TrueType driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# TrueType driver directory -# -TT_DIR := $(SRC_)truetype -TT_DIR_ := $(TT_DIR)$(SEP) - - -# compilation flags for the driver -# -TT_COMPILE := $(FT_COMPILE) - - -# TrueType driver sources (i.e., C files) -# -TT_DRV_SRC := $(TT_DIR_)ttobjs.c \ - $(TT_DIR_)ttpload.c \ - $(TT_DIR_)ttgload.c \ - $(TT_DIR_)ttinterp.c \ - $(TT_DIR_)ttdriver.c - -# TrueType driver headers -# -TT_DRV_H := $(TT_DRV_SRC:%.c=%.h) - - -# TrueType driver object(s) -# -# TT_DRV_OBJ_M is used during `multi' builds -# TT_DRV_OBJ_S is used during `single' builds -# -TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O) -TT_DRV_OBJ_S := $(OBJ_)truetype.$O - -# TrueType driver source file for single build -# -TT_DRV_SRC_S := $(TT_DIR_)truetype.c - - -# TrueType driver - single object -# -$(TT_DRV_OBJ_S): $(TT_DRV_SRC_S) $(TT_DRV_SRC) $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $(TT_DRV_SRC_S) - - -# driver - multiple objects -# -$(OBJ_)%.$O: $(TT_DIR_)%.c $(FREETYPE_H) $(TT_DRV_H) - $(TT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(TT_DRV_OBJ_S) -DRV_OBJS_M += $(TT_DRV_OBJ_M) - -# EOF diff --git a/subsys/win32k/freetype/src/truetype/truetype.c b/subsys/win32k/freetype/src/truetype/truetype.c deleted file mode 100644 index a7e7e8d..0000000 --- a/subsys/win32k/freetype/src/truetype/truetype.c +++ /dev/null @@ -1,47 +0,0 @@ -/***************************************************************************/ -/* */ -/* truetype.c */ -/* */ -/* FreeType TrueType driver component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "ttdriver.c" /* driver interface */ -#include "ttpload.c" /* tables loader */ -#include "ttgload.c" /* glyph loader */ -#include "ttobjs.c" /* object manager */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.c" /* bytecode interpreter */ -#endif - -#else /* FT_FLAT_COMPILE */ - -#include /* driver interface */ -#include /* tables loader */ -#include /* glyph loader */ -#include /* object manager */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include /* bytecode interpreter */ -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttdriver.c b/subsys/win32k/freetype/src/truetype/ttdriver.c deleted file mode 100644 index 558d63e..0000000 --- a/subsys/win32k/freetype/src/truetype/ttdriver.c +++ /dev/null @@ -1,511 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.c */ -/* */ -/* TrueType font driver implementation (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttdriver.h" -#include "ttgload.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttdriver - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** F A C E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#undef PAIR_TAG -#define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ - (FT_ULong)right ) - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings, are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( TT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - TT_Kern_0_Pair* pair; - - - if ( !face ) - return TT_Err_Invalid_Face_Handle; - - kerning->x = 0; - kerning->y = 0; - - if ( face->kern_pairs ) - { - /* there are some kerning pairs in this font file! */ - FT_ULong search_tag = PAIR_TAG( left_glyph, right_glyph ); - FT_Long left, right; - - - left = 0; - right = face->num_kern_pairs - 1; - - while ( left <= right ) - { - FT_Int middle = left + ( ( right - left ) >> 1 ); - FT_ULong cur_pair; - - - pair = face->kern_pairs + middle; - cur_pair = PAIR_TAG( pair->left, pair->right ); - - if ( cur_pair == search_tag ) - goto Found; - - if ( cur_pair < search_tag ) - left = middle + 1; - else - right = middle - 1; - } - } - - Exit: - return TT_Err_Ok; - - Found: - kerning->x = pair->value; - goto Exit; - } - - -#undef PAIR_TAG - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S I Z E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Char_Sizes( TT_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_Size_Metrics* metrics = &size->root.metrics; - TT_Face face = (TT_Face)size->root.face; - FT_Long dim_x, dim_y; - - - /* This bit flag, when set, indicates that the pixel size must be */ - /* truncated to an integer. Nearly all TrueType fonts have this */ - /* bit set, as hinting won't work really well otherwise. */ - /* */ - /* However, for those rare fonts who do not set it, we override */ - /* the default computations performed by the base layer. I */ - /* really don't know whether this is useful, but hey, that's the */ - /* spec :-) */ - /* */ - if ( ( face->header.Flags & 8 ) == 0 ) - { - /* Compute pixel sizes in 26.6 units */ - dim_x = ( char_width * horz_resolution ) / 72; - dim_y = ( char_height * vert_resolution ) / 72; - - metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); - metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); - - metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); - metrics->y_ppem = (FT_UShort)( dim_y >> 6 ); - } - - size->ttmetrics.valid = FALSE; - - return TT_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Pixel_Sizes( TT_Size size, - FT_UInt pixel_width, - FT_UInt pixel_height ) - { - FT_UNUSED( pixel_width ); - FT_UNUSED( pixel_height ); - - /* many things have been pre-computed by the base layer */ - - size->ttmetrics.valid = FALSE; - - return TT_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Load_Glyph */ - /* */ - /* */ - /* A driver method used to load a glyph within a given glyph slot. */ - /* */ - /* */ - /* slot :: A handle to the target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled, loaded, etc. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Load_Glyph( TT_GlyphSlot slot, - TT_Size size, - FT_UShort glyph_index, - FT_UInt load_flags ) - { - FT_Error error; - - - if ( !slot ) - return TT_Err_Invalid_Glyph_Handle; - - /* check whether we want a scaled outline or bitmap */ - if ( !size ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - if ( load_flags & FT_LOAD_NO_SCALE ) - size = NULL; - - /* reset the size object if necessary */ - if ( size ) - { - /* these two object must have the same parent */ - if ( size->root.face != slot->face ) - return TT_Err_Invalid_Face_Handle; - - if ( !size->ttmetrics.valid ) - { - if ( FT_SET_ERROR( TT_Reset_Size( size ) ) ) - return error; - } - } - - /* now load the glyph outline if necessary */ - error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); - - /* force drop-out mode to 2 - irrelevant now */ - /* slot->outline.dropout_mode = 2; */ - - return error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C H A R A C T E R M A P P I N G S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( TT_CharMap charmap, - FT_Long charcode ) - { - FT_Error error; - TT_Face face; - TT_CMapTable* cmap; - - - cmap = &charmap->cmap; - face = (TT_Face)charmap->root.face; - - /* Load table if needed */ - if ( !cmap->loaded ) - { - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - error = sfnt->load_charmap( face, cmap, face->root.stream ); - if ( error ) - return 0; - - cmap->loaded = TRUE; - } - - if ( cmap->get_index ) - return cmap->get_index( cmap, charcode ); - else - return 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** D R I V E R I N T E R F A C E ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Module_Interface tt_get_interface( TT_Driver driver, - const char* interface ) - { - FT_Module sfntd = FT_Get_Module( driver->root.root.library, - "sfnt" ); - SFNT_Interface* sfnt; - - - /* only return the default interface from the SFNT module */ - if ( sfntd ) - { - sfnt = (SFNT_Interface*)( sfntd->clazz->module_interface ); - if ( sfnt ) - return sfnt->get_interface( FT_MODULE( driver ), interface ); - } - - return 0; - } - - - /* The FT_DriverInterface structure is defined in ftdriver.h. */ - - const FT_Driver_Class tt_driver_class = - { - { - ft_module_font_driver | - ft_module_driver_scalable | -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - ft_module_driver_has_hinter, -#else - 0, -#endif - - sizeof ( TT_DriverRec ), - - "truetype", /* driver name */ - 0x10000L, /* driver version == 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - (void*)0, /* driver specific interface */ - - (FT_Module_Constructor)TT_Init_Driver, - (FT_Module_Destructor) TT_Done_Driver, - (FT_Module_Requester) tt_get_interface, - }, - - sizeof ( TT_FaceRec ), - sizeof ( TT_SizeRec ), - sizeof ( FT_GlyphSlotRec ), - - - (FTDriver_initFace) TT_Init_Face, - (FTDriver_doneFace) TT_Done_Face, - (FTDriver_initSize) TT_Init_Size, - (FTDriver_doneSize) TT_Done_Size, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - (FTDriver_loadGlyph) Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - - /*************************************************************************/ - /* */ - /* */ - /* getDriverInterface */ - /* */ - /* */ - /* This function is used when compiling the TrueType driver as a */ - /* shared library (`.DLL' or `.so'). It will be used by the */ - /* high-level library of FreeType to retrieve the address of the */ - /* driver's generic interface. */ - /* */ - /* It shouldn't be implemented in a static build, as each driver must */ - /* have the same function as an exported entry point. */ - /* */ - /* */ - /* The address of the TrueType's driver generic interface. The */ - /* format-specific interface can then be retrieved through the method */ - /* interface->get_format_interface. */ - /* */ - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &tt_driver_class; - } - - -#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttdriver.h b/subsys/win32k/freetype/src/truetype/ttdriver.h deleted file mode 100644 index 9867fbc..0000000 --- a/subsys/win32k/freetype/src/truetype/ttdriver.h +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttdriver.h */ -/* */ -/* High-level TrueType driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 TTDRIVER_H -#define TTDRIVER_H - -#include - - - FT_EXPORT_VAR( const FT_Driver_Class ) tt_driver_class; - - -#endif /* TTDRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttgload.c b/subsys/win32k/freetype/src/truetype/ttgload.c deleted file mode 100644 index 62cb22f..0000000 --- a/subsys/win32k/freetype/src/truetype/ttgload.c +++ /dev/null @@ -1,1477 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.c */ -/* */ -/* TrueType Glyph Loader (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttgload.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttgload - - - /*************************************************************************/ - /* */ - /* 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 - - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Get_Metrics */ - /* */ - /* */ - /* Returns the 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). */ - /* */ - /* */ - /* header :: A pointer to either the horizontal or vertical metrics */ - /* structure. */ - /* */ - /* index :: The glyph index. */ - /* */ - /* */ - /* bearing :: The bearing, either left side or top side. */ - /* */ - /* advance :: The advance width resp. advance height. */ - /* */ - /* */ - /* This function will much probably move to another component in the */ - /* near future, but I haven't decided which yet. */ - /* */ - LOCAL_FUNC - void TT_Get_Metrics( TT_HoriHeader* header, - FT_UInt index, - FT_Short* bearing, - FT_UShort* advance ) - { - TT_LongMetrics* longs_m; - FT_UShort k = header->number_Of_HMetrics; - - - if ( index < k ) - { - longs_m = (TT_LongMetrics*)header->long_metrics + index; - *bearing = longs_m->bearing; - *advance = longs_m->advance; - } - else - { - *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k]; - *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance; - } - } - - - /*************************************************************************/ - /* */ - /* Returns the horizontal metrics in font units for a given glyph. If */ - /* `check' is true, take care of monospaced fonts by returning the */ - /* advance width maximum. */ - /* */ - static - void Get_HMetrics( TT_Face face, - FT_UInt index, - FT_Bool check, - FT_Short* lsb, - FT_UShort* aw ) - { - TT_Get_Metrics( &face->horizontal, index, lsb, aw ); - - if ( check && face->postscript.isFixedPitch ) - *aw = face->horizontal.advance_Width_Max; - } - - - /*************************************************************************/ - /* */ - /* Returns the advance width table for a given pixel size if it is */ - /* found in the font's `hdmx' table (if any). */ - /* */ - static - FT_Byte* Get_Advance_Widths( TT_Face face, - FT_UShort ppem ) - { - FT_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; - } - - -#define cur_to_org( n, zone ) \ - MEM_Copy( (zone)->org, (zone)->cur, n * sizeof ( FT_Vector ) ) - -#define org_to_cur( n, zone ) \ - MEM_Copy( (zone)->cur, (zone)->org, n * sizeof ( FT_Vector ) ) - - - /*************************************************************************/ - /* */ - /* Translates an array of coordinates. */ - /* */ - static - void translate_array( FT_UInt n, - FT_Vector* coords, - FT_Pos delta_x, - FT_Pos delta_y ) - { - FT_UInt 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; - } - - - static - void tt_prepare_zone( TT_GlyphZone* zone, - FT_GlyphLoad* load, - FT_UInt start_point, - FT_UInt start_contour ) - { - zone->n_points = load->outline.n_points - start_point; - zone->n_contours = load->outline.n_contours - start_contour; - zone->org = load->extra_points + start_point; - zone->cur = load->outline.points + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; - } - - -#undef IS_HINTED -#define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 ) - - - /*************************************************************************/ - /* */ - /* The following functions are used by default with TrueType fonts. */ - /* However, they can be replaced by alternatives if we need to support */ - /* TrueType-compressed formats (like MicroType) in the future. */ - /* */ - /*************************************************************************/ - - static - FT_Error TT_Access_Glyph_Frame( TT_Loader* loader, - FT_UInt glyph_index, - FT_ULong offset, - FT_UInt byte_count ) - { - FT_Error error; - FT_Stream stream = loader->stream; - - - /* the following line sets the `error' variable through macros! */ - (void)( FILE_Seek( offset ) || ACCESS_Frame( byte_count ) ); - - FT_TRACE5(( "Glyph %ld\n", glyph_index )); - return error; - } - - - static - void TT_Forget_Glyph_Frame( TT_Loader* loader ) - { - FT_Stream stream = loader->stream; - - - FORGET_Frame(); - } - - - static - FT_Error TT_Load_Glyph_Header( TT_Loader* loader ) - { - FT_Stream stream = loader->stream; - - - loader->n_contours = GET_Short(); - - loader->bbox.xMin = GET_Short(); - loader->bbox.yMin = GET_Short(); - loader->bbox.xMax = GET_Short(); - loader->bbox.yMax = GET_Short(); - - FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); - FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, - loader->bbox.xMax )); - FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, - loader->bbox.yMax )); - - return FT_Err_Ok; - } - - - static - FT_Error TT_Load_Simple_Glyph( TT_Loader* load ) - { - FT_Error error; - FT_Stream stream = load->stream; - FT_GlyphLoader* gloader = load->gloader; - FT_Int n_contours = load->n_contours; - FT_Outline* outline; - TT_Face face = (TT_Face)load->face; - TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph; - FT_UShort n_ins; - FT_Int n, n_points; - - - /* reading the contours endpoints & number of points */ - { - short* cur = gloader->current.outline.contours; - short* limit = cur + n_contours; - - - for ( ; cur < limit; cur++ ) - cur[0] = GET_UShort(); - - n_points = 0; - if ( n_contours > 0 ) - n_points = cur[-1] + 1; - - error = FT_GlyphLoader_Check_Points( gloader, n_points + 2, 0 ); - if ( error ) - goto Fail; - - outline = &gloader->current.outline; - } - - /* reading the bytecode instructions */ - slot->control_len = 0; - slot->control_data = 0; - - n_ins = GET_UShort(); - - FT_TRACE5(( " Instructions size: %d\n", n_ins )); - - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "ERROR: Too many instructions!\n" )); - error = TT_Err_Too_Many_Ins; - goto Fail; - } - - if ( stream->cursor + n_ins > stream->limit ) - { - FT_TRACE0(( "ERROR: Instruction count mismatch!\n" )); - error = TT_Err_Too_Many_Ins; - goto Fail; - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( ( load->load_flags & - ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 && - load->instructions ) - { - slot->control_len = n_ins; - slot->control_data = load->instructions; - - MEM_Copy( load->instructions, stream->cursor, n_ins ); - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - stream->cursor += n_ins; - - /* reading the point tags */ - - { - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Byte* limit = flag + n_points; - FT_Byte c, count; - - - for ( ; flag < limit; flag++ ) - { - *flag = c = GET_Byte(); - if ( c & 8 ) - { - for ( count = GET_Byte(); count > 0; count-- ) - *++flag = c; - } - } - } - - /* reading the X coordinates */ - - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; - - - for ( ; vec < limit; vec++, flag++ ) - { - FT_Pos y = 0; - - - if ( *flag & 2 ) - { - y = GET_Byte(); - if ( ( *flag & 16 ) == 0 ) - y = -y; - } - else if ( ( *flag & 16 ) == 0 ) - y = GET_Short(); - - x += y; - vec->x = x; - } - } - - /* reading the Y coordinates */ - - { - FT_Vector* vec = gloader->current.outline.points; - FT_Vector* limit = vec + n_points; - FT_Byte* flag = (FT_Byte*)outline->tags; - FT_Pos x = 0; - - - for ( ; vec < limit; vec++, flag++ ) - { - FT_Pos y = 0; - - - if ( *flag & 4 ) - { - y = GET_Byte(); - if ( ( *flag & 32 ) == 0 ) - y = -y; - } - else if ( ( *flag & 32 ) == 0 ) - y = GET_Short(); - - x += y; - vec->y = x; - } - } - - /* clear the touch tags */ - for ( n = 0; n < n_points; n++ ) - outline->tags[n] &= FT_Curve_Tag_On; - - outline->n_points = n_points; - outline->n_contours = n_contours; - - Fail: - return error; - } - - - static - FT_Error TT_Load_Composite_Glyph( TT_Loader* loader ) - { - FT_Error error; - FT_Stream stream = loader->stream; - FT_GlyphLoader* gloader = loader->gloader; - FT_SubGlyph* subglyph; - FT_UInt num_subglyphs; - - - num_subglyphs = 0; - - do - { - FT_Fixed xx, xy, yy, yx; - - - /* check that we can load a new subglyph */ - error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs + 1 ); - if ( error ) - goto Fail; - - subglyph = gloader->current.subglyphs + num_subglyphs; - - subglyph->arg1 = subglyph->arg2 = 0; - - subglyph->flags = GET_UShort(); - subglyph->index = GET_UShort(); - - /* read arguments */ - if ( subglyph->flags & ARGS_ARE_WORDS ) - { - subglyph->arg1 = GET_Short(); - subglyph->arg2 = GET_Short(); - } - else - { - subglyph->arg1 = GET_Char(); - subglyph->arg2 = GET_Char(); - } - - /* read transform */ - xx = yy = 0x10000L; - xy = yx = 0; - - if ( subglyph->flags & WE_HAVE_A_SCALE ) - { - xx = (FT_Fixed)GET_Short() << 2; - yy = xx; - } - else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - { - xx = (FT_Fixed)GET_Short() << 2; - yy = (FT_Fixed)GET_Short() << 2; - } - else if ( subglyph->flags & WE_HAVE_A_2X2 ) - { - xx = (FT_Fixed)GET_Short() << 2; - xy = (FT_Fixed)GET_Short() << 2; - yx = (FT_Fixed)GET_Short() << 2; - yy = (FT_Fixed)GET_Short() << 2; - } - - subglyph->transform.xx = xx; - subglyph->transform.xy = xy; - subglyph->transform.yx = yx; - subglyph->transform.yy = yy; - - num_subglyphs++; - - } while ( subglyph->flags & MORE_COMPONENTS ); - - gloader->current.num_subglyphs = num_subglyphs; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - { - /* we must undo the ACCESS_Frame in order to point to the */ - /* composite instructions, if we find some. */ - /* we will process them later... */ - /* */ - loader->ins_pos = FILE_Pos() + stream->cursor - stream->limit; - } -#endif - - Fail: - return error; - } - - - LOCAL_FUNC - void TT_Init_Glyph_Loading( TT_Face face ) - { - face->access_glyph_frame = TT_Access_Glyph_Frame; - face->read_glyph_header = TT_Load_Glyph_Header; - face->read_simple_glyph = TT_Load_Simple_Glyph; - face->read_composite_glyph = TT_Load_Composite_Glyph; - face->forget_glyph_frame = TT_Forget_Glyph_Frame; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Process_Simple_Glyph */ - /* */ - /* */ - /* Once a simple glyph has been loaded, it needs to be processed. */ - /* Usually, this means scaling and hinting through bytecode */ - /* interpretation. */ - /* */ - static - FT_Error TT_Process_Simple_Glyph( TT_Loader* load, - FT_Bool debug ) - { - FT_GlyphLoader* gloader = load->gloader; - FT_Outline* outline = &gloader->current.outline; - FT_UInt n_points = outline->n_points; - FT_UInt n_ins; - TT_GlyphZone* zone = &load->zone; - FT_Error error = FT_Err_Ok; - - - n_ins = load->glyph->control_len; - - /* add shadow points */ - - /* Now add the two shadow points at n and n + 1. */ - /* We need the left side bearing and advance width. */ - - { - FT_Vector* pp1; - FT_Vector* pp2; - - - /* pp1 = xMin - lsb */ - pp1 = outline->points + n_points; - pp1->x = load->bbox.xMin - load->left_bearing; - pp1->y = 0; - - /* pp2 = pp1 + aw */ - pp2 = pp1 + 1; - pp2->x = pp1->x + load->advance; - pp2->y = 0; - - outline->tags[n_points ] = 0; - outline->tags[n_points + 1] = 0; - } - - /* Note that we return two more points that are not */ - /* part of the glyph outline. */ - - n_points += 2; - - /* set up zone for hinting */ - tt_prepare_zone( zone, &gloader->current, 0, 0 ); - - /* eventually scale the glyph */ - if ( !( load->load_flags & FT_LOAD_NO_SCALE ) ) - { - FT_Vector* vec = zone->cur; - FT_Vector* limit = vec + n_points; - FT_Fixed x_scale = load->size->metrics.x_scale; - FT_Fixed y_scale = load->size->metrics.y_scale; - - - /* first scale the glyph points */ - for ( ; vec < limit; vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - } - - cur_to_org( n_points, zone ); - - /* eventually hint the glyph */ - if ( IS_HINTED( load->load_flags ) ) - { - FT_Pos x = zone->org[n_points-2].x; - - - x = ( ( x + 32 ) & -64 ) - x; - translate_array( n_points, zone->org, x, 0 ); - - org_to_cur( n_points, zone ); - - zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* now consider hinting */ - if ( n_ins > 0 ) - { - error = TT_Set_CodeRange( load->exec, tt_coderange_glyph, - load->exec->glyphIns, n_ins ); - if ( error ) - goto Exit; - - load->exec->is_composite = FALSE; - load->exec->pedantic_hinting = (FT_Bool)( load->load_flags & - FT_LOAD_PEDANTIC ); - load->exec->pts = *zone; - load->exec->pts.n_points += 2; - - error = TT_Run_Context( load->exec, debug ); - if ( error && load->exec->pedantic_hinting ) - goto Exit; - - error = FT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */ - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } - - /* save glyph phantom points */ - if ( !load->preserve_pps ) - { - load->pp1 = zone->cur[n_points - 2]; - load->pp2 = zone->cur[n_points - 1]; - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - Exit: -#endif - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* load_truetype_glyph */ - /* */ - /* */ - /* Loads a given truetype glyph. Handles composites and uses a */ - /* TT_Loader object. */ - /* */ - static - FT_Error load_truetype_glyph( TT_Loader* loader, - FT_UInt glyph_index ) - { - FT_Stream stream = loader->stream; - FT_Error error; - TT_Face face = (TT_Face)loader->face; - FT_ULong offset; - FT_Int contours_count; - FT_UInt index, num_points, num_contours, count; - FT_Fixed x_scale, y_scale; - FT_ULong ins_offset; - FT_GlyphLoader* gloader = loader->gloader; - FT_Bool opened_frame = 0; - - - /* check glyph index */ - index = glyph_index; - if ( index >= (FT_UInt)face->root.num_glyphs ) - { - error = TT_Err_Invalid_Glyph_Index; - goto Exit; - } - - loader->glyph_index = glyph_index; - num_contours = 0; - num_points = 0; - ins_offset = 0; - - x_scale = 0x10000L; - y_scale = 0x10000L; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; - } - - /* get horizontal metrics */ - { - FT_Short left_bearing; - FT_UShort advance_width; - - - Get_HMetrics( face, index, - (FT_Bool)!(loader->load_flags & - FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH), - &left_bearing, - &advance_width ); - - loader->left_bearing = left_bearing; - loader->advance = advance_width; - } - - offset = face->glyph_locations[index]; - count = 0; - - if ( index < (FT_UInt)face->num_locations - 1 ) - count = face->glyph_locations[index + 1] - offset; - - if ( count == 0 ) - { - /* as described by Frederic Loyer, these are spaces, and */ - /* not the unknown glyph. */ - loader->bbox.xMin = 0; - loader->bbox.xMax = 0; - loader->bbox.yMin = 0; - loader->bbox.yMax = 0; - - loader->pp1.x = 0; - loader->pp2.x = loader->advance; - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( loader->exec ) - loader->exec->glyphSize = 0; - -#endif - - error = FT_Err_Ok; - goto Exit; - } - - offset = loader->glyf_offset + offset; - - /* access glyph frame */ - error = face->access_glyph_frame( loader, glyph_index, offset, count ); - if ( error ) - goto Exit; - - opened_frame = 1; - - /* read first glyph header */ - error = face->read_glyph_header( loader ); - if ( error ) - goto Fail; - - contours_count = loader->n_contours; - - count -= 10; - - loader->pp1.x = loader->bbox.xMin - loader->left_bearing; - loader->pp1.y = 0; - loader->pp2.x = loader->pp1.x + loader->advance; - loader->pp2.y = 0; - - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale ); - loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale ); - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* if it is a simple glyph, load it */ - - if ( contours_count >= 0 ) - { - /* check that we can add the contours to the glyph */ - error = FT_GlyphLoader_Check_Points( gloader, 0, contours_count ); - if ( error ) - goto Fail; - - error = face->read_simple_glyph( loader ); - if ( error ) - goto Fail; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - { - TT_Size size = (TT_Size)loader->size; - - - error = TT_Process_Simple_Glyph( loader, - (FT_Bool)( size && size->debug ) ); - } - -#else - - error = TT_Process_Simple_Glyph( loader, 0 ); - -#endif - - if ( error ) - goto Fail; - - FT_GlyphLoader_Add( gloader ); - - /* Note: We could have put the simple loader source there */ - /* but the code is fat enough already :-) */ - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - /* otherwise, load a composite! */ - else - { - TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph; - FT_UInt start_point, start_contour; - FT_ULong ins_pos; /* position of composite instructions, if any */ - - - /* for each subglyph, read composite header */ - start_point = gloader->base.outline.n_points; - start_contour = gloader->base.outline.n_contours; - - error = face->read_composite_glyph( loader ); - if ( error ) - goto Fail; - - ins_pos = loader->ins_pos; - face->forget_glyph_frame( loader ); - opened_frame = 0; - - /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ - /* `as is' in the glyph slot (the client application will be */ - /* responsible for interpreting this data)... */ - /* */ - if ( loader->load_flags & FT_LOAD_NO_RECURSE ) - { - /* set up remaining glyph fields */ - FT_GlyphLoader_Add( gloader ); - - glyph->num_subglyphs = gloader->base.num_subglyphs; - glyph->format = ft_glyph_format_composite; - glyph->subglyphs = gloader->base.subglyphs; - - goto Exit; - } - - /*********************************************************************/ - /*********************************************************************/ - /*********************************************************************/ - - /* Now, read each subglyph independently. */ - { - FT_Int n, num_base_points, num_new_points; - FT_SubGlyph* subglyph = 0; - - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; - - - FT_GlyphLoader_Add( gloader ); - - for ( n = 0; n < (FT_Int)num_subglyphs; n++ ) - { - FT_Vector pp1, pp2; - FT_Pos x, y; - - - /* Each time we call load_truetype_glyph in this loop, the */ - /* value of `gloader.base.subglyphs' can change due to table */ - /* reallocations. We thus need to recompute the subglyph */ - /* pointer on each iteration. */ - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - pp1 = loader->pp1; - pp2 = loader->pp2; - - num_base_points = gloader->base.outline.n_points; - - error = load_truetype_glyph( loader, subglyph->index ); - if ( error ) - goto Fail; - - subglyph = gloader->base.subglyphs + num_base_subgs + n; - - if ( subglyph->flags & USE_MY_METRICS ) - { - pp1 = loader->pp1; - pp2 = loader->pp2; - } - else - { - loader->pp1 = pp1; - loader->pp2 = pp2; - } - - num_points = gloader->base.outline.n_points; - - num_new_points = num_points - num_base_points; - - /* now perform the transform required for this subglyph */ - - if ( subglyph->flags & ( WE_HAVE_A_SCALE | - WE_HAVE_AN_XY_SCALE | - WE_HAVE_A_2X2 ) ) - { - FT_Vector* cur = gloader->base.outline.points + - num_base_points; - FT_Vector* org = gloader->base.extra_points + - num_base_points; - FT_Vector* limit = cur + num_new_points; - - - for ( ; cur < limit; cur++, org++ ) - { - FT_Vector_Transform( cur, &subglyph->transform ); - FT_Vector_Transform( org, &subglyph->transform ); - } - } - - /* apply offset */ - - if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) ) - { - FT_UInt k = subglyph->arg1; - FT_UInt l = subglyph->arg2; - FT_Vector* p1; - FT_Vector* p2; - - - if ( start_point + k >= (FT_UInt)num_base_points || - l >= (FT_UInt)num_new_points ) - { - error = TT_Err_Invalid_Composite; - goto Fail; - } - - l += num_base_points; - - p1 = gloader->base.outline.points + start_point + k; - p2 = gloader->base.outline.points + start_point + l; - - x = p1->x - p2->x; - y = p1->y - p2->y; - } - else - { - x = subglyph->arg1; - y = subglyph->arg2; - - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - x = FT_MulFix( x, x_scale ); - y = FT_MulFix( y, y_scale ); - - if ( subglyph->flags & ROUND_XY_TO_GRID ) - { - x = ( x + 32 ) & -64; - y = ( y + 32 ) & -64; - } - } - } - - translate_array( num_new_points, loader->zone.cur, x, y ); - cur_to_org( num_new_points, &loader->zone ); - } - - /*******************************************************************/ - /*******************************************************************/ - /*******************************************************************/ - - /* we have finished loading all sub-glyphs; now, look for */ - /* instructions for this composite! */ - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( num_subglyphs > 0 && - loader->exec && - ins_pos > 0 && - subglyph->flags & WE_HAVE_INSTR ) - { - FT_UShort n_ins; - TT_ExecContext exec = loader->exec; - TT_GlyphZone* pts; - FT_Vector* pp1; - - - /* read size of instructions */ - if ( FILE_Seek( ins_pos ) || - READ_UShort( n_ins ) ) - goto Fail; - FT_TRACE5(( " Instructions size = %d\n", n_ins )); - - /* in some fonts? */ - if ( n_ins == 0xFFFF ) - n_ins = 0; - - /* check it */ - if ( n_ins > face->max_profile.maxSizeOfInstructions ) - { - FT_TRACE0(( "Too many instructions (%d) in composite glyph %ld\n", - n_ins, subglyph->index )); - return TT_Err_Too_Many_Ins; - } - - /* read the instructions */ - if ( FILE_Read( exec->glyphIns, n_ins ) ) - goto Fail; - - glyph->control_data = exec->glyphIns; - glyph->control_len = n_ins; - - error = TT_Set_CodeRange( exec, - tt_coderange_glyph, - exec->glyphIns, - n_ins ); - if ( error ) - goto Fail; - - /* prepare the execution context */ - tt_prepare_zone( &exec->pts, &gloader->base, - start_point, start_contour ); - pts = &exec->pts; - - pts->n_points = num_points + 2; - pts->n_contours = gloader->base.outline.n_contours; - - /* add phantom points */ - pp1 = pts->cur + num_points; - pp1[0] = loader->pp1; - pp1[1] = loader->pp2; - - pts->tags[num_points ] = 0; - pts->tags[num_points + 1] = 0; - - /* if hinting, round the phantom points */ - if ( IS_HINTED( loader->load_flags ) ) - { - pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 ); - pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 ); - } - - { - FT_UInt k; - - - for ( k = 0; k < num_points; k++ ) - pts->tags[k] &= FT_Curve_Tag_On; - } - - cur_to_org( num_points + 2, pts ); - - /* now consider hinting */ - if ( IS_HINTED( loader->load_flags ) && n_ins > 0 ) - { - exec->is_composite = TRUE; - exec->pedantic_hinting = - (FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC ); - - error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug ); - if ( error && exec->pedantic_hinting ) - goto Fail; - } - - /* save glyph origin and advance points */ - loader->pp1 = pp1[0]; - loader->pp2 = pp1[1]; - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } - /* end of composite loading */ - } - - /***********************************************************************/ - /***********************************************************************/ - /***********************************************************************/ - - Fail: - if ( opened_frame ) - face->forget_glyph_frame( loader ); - - Exit: - return error; - } - - - static - void compute_glyph_metrics( TT_Loader* loader, - FT_UInt glyph_index ) - { - FT_BBox bbox; - TT_Face face = (TT_Face)loader->face; - FT_Fixed x_scale, y_scale; - TT_GlyphSlot glyph = loader->glyph; - TT_Size size = (TT_Size)loader->size; - - - x_scale = 0x10000L; - y_scale = 0x10000L; - if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - x_scale = size->root.metrics.x_scale; - y_scale = size->root.metrics.y_scale; - } - - if ( glyph->format != ft_glyph_format_composite ) - { - glyph->outline.flags &= ~ft_outline_single_pass; - - /* copy outline to our glyph slot */ - FT_GlyphLoader_Copy_Points( glyph->loader, loader->gloader ); - glyph->outline = glyph->loader->base.outline; - - /* translate array so that (0,0) is the glyph's origin */ - FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 ); - - FT_Outline_Get_CBox( &glyph->outline, &bbox ); - - if ( IS_HINTED( loader->load_flags ) ) - { - /* grid-fit the bounding box */ - bbox.xMin &= -64; - bbox.yMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; - } - } - else - bbox = loader->bbox; - - /* get the device-independent horizontal advance. It is scaled later */ - /* by the base layer. */ - { - FT_Pos advance = loader->advance; - - - /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */ - /* correctly support DynaLab fonts, which have an incorrect */ - /* `advance_Width_Max' field! It is used, to my knowledge, */ - /* exclusively in the X-TrueType font server. */ - /* */ - if ( face->postscript.isFixedPitch && - ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 ) - advance = face->horizontal.advance_Width_Max; - - /* we need to return the advance in font units in linearHoriAdvance, */ - /* it will be scaled later by the base layer. */ - glyph->linearHoriAdvance = advance; - } - - glyph->metrics.horiBearingX = bbox.xMin; - glyph->metrics.horiBearingY = bbox.yMax; - glyph->metrics.horiAdvance = loader->pp2.x - loader->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'... */ - - { - FT_Short top_bearing; /* vertical top side bearing (EM units) */ - FT_UShort advance_height; /* vertical advance height (EM units) */ - - FT_Pos left; /* scaled vertical left side bearing */ - FT_Pos Top; /* scaled original vertical top side bearing */ - FT_Pos top; /* scaled vertical top side bearing */ - FT_Pos advance; /* scaled vertical advance height */ - - - /* Get the unscaled `tsb' and `ah' */ - if ( face->vertical_info && - face->vertical.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_HoriHeader*)&face->vertical, - 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, if there is an OS/2 */ - /* table in the font. Otherwise, we use the */ - /* values defined in the horizontal header. */ - /* */ - /* NOTE2: The sTypoDescender is negative, which is why */ - /* we compute the baseline-to-baseline distance */ - /* here with: */ - /* ascender - descender + linegap */ - /* */ - if ( face->os2.version != 0xFFFF ) - { - top_bearing = face->os2.sTypoLineGap / 2; - advance_height = (FT_UShort)( face->os2.sTypoAscender - - face->os2.sTypoDescender + - face->os2.sTypoLineGap ); - } - else - { - top_bearing = face->horizontal.Line_Gap / 2; - advance_height = (FT_UShort)( face->horizontal.Ascender + - face->horizontal.Descender + - face->horizontal.Line_Gap ); - } - } - - /* We must adjust the top_bearing value from the bounding box given */ - /* in the glyph header to te bounding box calculated with */ - /* FT_Get_Outline_CBox(). */ - - /* scale the metrics */ - if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) - { - Top = FT_MulFix( top_bearing, y_scale ); - top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale ) - - bbox.yMax; - advance = FT_MulFix( advance_height, y_scale ); - } - else - { - Top = top_bearing; - top = top_bearing + loader->bbox.yMax - bbox.yMax; - advance = advance_height; - } - - /* set the advance height in design units. It is scaled later by */ - /* the base layer. */ - glyph->linearVertAdvance = advance_height; - - /* XXX: for now, we have no better algorithm for the lsb, but it */ - /* should work fine. */ - /* */ - left = ( bbox.xMin - bbox.xMax ) / 2; - - /* grid-fit them if necessary */ - if ( IS_HINTED( loader->load_flags ) ) - { - 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 ( !face->postscript.isFixedPitch && size && - IS_HINTED( loader->load_flags ) ) - { - FT_Byte* widths = Get_Advance_Widths( face, - size->root.metrics.x_ppem ); - - - if ( widths ) - glyph->metrics.horiAdvance = widths[glyph_index] << 6; - } - - /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Glyph */ - /* */ - /* */ - /* A function used to load a single glyph within a given glyph slot, */ - /* for a given size. */ - /* */ - /* */ - /* glyph :: A handle to a target slot object where the glyph */ - /* will be loaded. */ - /* */ - /* size :: A handle to the source face size at which the glyph */ - /* must be scaled/loaded. */ - /* */ - /* glyph_index :: The index of the glyph in the font file. */ - /* */ - /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FT_LOAD_XXX constants can be used to control the */ - /* glyph loading process (e.g., whether the outline */ - /* should be scaled, whether to load bitmaps or not, */ - /* whether to hint the outline, etc). */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UShort glyph_index, - FT_UInt load_flags ) - { - SFNT_Interface* sfnt; - TT_Face face; - FT_Stream stream; - FT_Memory memory; - FT_Error error; - TT_Loader loader; - - - face = (TT_Face)glyph->face; - sfnt = (SFNT_Interface*)face->sfnt; - stream = face->root.stream; - memory = face->root.memory; - error = 0; - - if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) || - ( load_flags & FT_LOAD_NO_RECURSE ) ) - { - size = NULL; - load_flags |= FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP; - } - - glyph->num_subglyphs = 0; - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* try to load embedded bitmap if any */ - if ( size && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && - sfnt->load_sbits ) - { - TT_SBit_Metrics metrics; - - - error = sfnt->load_sbit_image( face, - size->root.metrics.x_ppem, - size->root.metrics.y_ppem, - glyph_index, - load_flags, - stream, - &glyph->bitmap, - &metrics ); - if ( !error ) - { - glyph->outline.n_points = 0; - glyph->outline.n_contours = 0; - - glyph->metrics.width = (FT_Pos)metrics.width << 6; - glyph->metrics.height = (FT_Pos)metrics.height << 6; - - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6; - - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6; - - glyph->format = ft_glyph_format_bitmap; - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - glyph->bitmap_left = metrics.vertBearingX; - glyph->bitmap_top = metrics.vertBearingY; - } - else - { - glyph->bitmap_left = metrics.horiBearingX; - glyph->bitmap_top = metrics.horiBearingY; - } - return error; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - - /* seek to the beginning of the glyph table. For Type 42 fonts */ - /* the table might be accessed from a Postscript stream or something */ - /* else... */ - - error = face->goto_table( face, TTAG_glyf, stream, 0 ); - if ( error ) - { - FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" )); - goto Exit; - } - - MEM_Set( &loader, 0, sizeof ( loader ) ); - - /* update the glyph zone bounds */ - { - FT_GlyphLoader* gloader = FT_FACE_DRIVER(face)->glyph_loader; - - - loader.gloader = gloader; - - FT_GlyphLoader_Rewind( gloader ); - - tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 ); - tt_prepare_zone( &loader.base, &gloader->base, 0, 0 ); - } - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( size ) - { - /* query new execution context */ - loader.exec = size->debug ? size->context : TT_New_Context( face ); - if ( !loader.exec ) - return TT_Err_Could_Not_Find_Context; - - TT_Load_Context( loader.exec, face, size ); - loader.instructions = loader.exec->glyphIns; - - /* load default graphics state - if needed */ - if ( size->GS.instruct_control & 2 ) - loader.exec->GS = tt_default_graphics_state; - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - /* clear all outline flags, except the `owner' one */ - glyph->outline.flags = 0; - - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->outline.flags |= ft_outline_high_precision; - - /* let's initialize the rest of our loader now */ - - loader.load_flags = load_flags; - - loader.face = (FT_Face)face; - loader.size = (FT_Size)size; - loader.glyph = (FT_GlyphSlot)glyph; - loader.stream = stream; - - loader.glyf_offset = FILE_Pos(); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* if the cvt program has disabled hinting, the argument */ - /* is ignored. */ - if ( size && ( size->GS.instruct_control & 1 ) ) - loader.load_flags |= FT_LOAD_NO_HINTING; - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - /* Main loading loop */ - glyph->format = ft_glyph_format_outline; - glyph->num_subglyphs = 0; - error = load_truetype_glyph( &loader, glyph_index ); - if ( !error ) - compute_glyph_metrics( &loader, glyph_index ); - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - if ( !size || !size->debug ) - TT_Done_Context( loader.exec ); - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - Exit: - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttgload.h b/subsys/win32k/freetype/src/truetype/ttgload.h deleted file mode 100644 index d6ca019..0000000 --- a/subsys/win32k/freetype/src/truetype/ttgload.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttgload.h */ -/* */ -/* TrueType Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttobjs.h" - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - void TT_Get_Metrics( TT_HoriHeader* header, - FT_UInt index, - FT_Short* bearing, - FT_UShort* advance ); - - LOCAL_DEF - void TT_Init_Glyph_Loading( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Load_Glyph( TT_Size size, - TT_GlyphSlot glyph, - FT_UShort glyph_index, - FT_UInt load_flags ); - -#ifdef __cplusplus - } -#endif - -#endif /* TTGLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttinterp.c b/subsys/win32k/freetype/src/truetype/ttinterp.c deleted file mode 100644 index bd22e5e..0000000 --- a/subsys/win32k/freetype/src/truetype/ttinterp.c +++ /dev/null @@ -1,7544 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.c */ -/* */ -/* TrueType bytecode interpreter (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttinterp.h" - -#else - -#include - -#endif - - -#include - - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - -#define TT_MULFIX FT_MulFix -#define TT_MULDIV FT_MulDiv - -#define TT_INT64 FT_Int64 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttinterp - -#undef NO_APPLE_PATENT -#define APPLE_THRESHOLD 0x4000000L - - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limitet to a maximal number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L - - - /*************************************************************************/ - /* */ - /* There are two kinds of implementations: */ - /* */ - /* 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 fully re-entrant. */ - /* */ - /* The idea is that an indirect implementation may be slower to execute */ - /* on low-end processors that are used in some systems (like 386s or */ - /* even 486s). */ - /* */ - /* 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 code used for */ - /* development. */ - /* */ - /* - It's much more readable that way! */ - /* */ - /* - It's still open to experimentation and tuning. */ - /* */ - /*************************************************************************/ - - -#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER /* indirect implementation */ - -#define CUR (*exc) /* see ttobjs.h */ - -#else /* static implementation */ - -#define CUR cur - - static - TT_ExecContextRec 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 */ - - - /*************************************************************************/ - /* */ - /* The instruction argument stack. */ - /* */ -#define INS_ARG EXEC_OP_ FT_Long* args /* see ttobjs.h for EXEC_OP_ */ - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `exec' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_EXEC FT_UNUSED( CUR ) - - - /*************************************************************************/ - /* */ - /* This macro is used whenever `args' is unused in a function, to avoid */ - /* stupid warnings from pedantic compilers. */ - /* */ -#define FT_UNUSED_ARG FT_UNUSED_EXEC; FT_UNUSED( args ) - - - /*************************************************************************/ - /* */ - /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to */ - /* increase readabilty of the code. */ - /* */ - /*************************************************************************/ - - -#define SKIP_Code() \ - SkipCode( EXEC_ARG ) - -#define GET_ShortIns() \ - GetShortIns( EXEC_ARG ) - -#define NORMalize( x, y, v ) \ - Normalize( EXEC_ARG_ x, y, v ) - -#define SET_SuperRound( scale, flags ) \ - SetSuperRound( EXEC_ARG_ scale, flags ) - -#define ROUND_None( d, c ) \ - Round_None( EXEC_ARG_ d, c ) - -#define INS_Goto_CodeRange( range, ip ) \ - Ins_Goto_CodeRange( EXEC_ARG_ range, ip ) - -#define CUR_Func_project( x, y ) \ - CUR.func_project( EXEC_ARG_ x, y ) - -#define CUR_Func_move( z, p, d ) \ - CUR.func_move( EXEC_ARG_ z, p, d ) - -#define CUR_Func_dualproj( x, y ) \ - CUR.func_dualproj( EXEC_ARG_ x, y ) - -#define CUR_Func_freeProj( x, y ) \ - CUR.func_freeProj( EXEC_ARG_ x, y ) - -#define CUR_Func_round( d, c ) \ - CUR.func_round( EXEC_ARG_ d, c ) - -#define CUR_Func_read_cvt( index ) \ - CUR.func_read_cvt( EXEC_ARG_ index ) - -#define CUR_Func_write_cvt( index, val ) \ - CUR.func_write_cvt( EXEC_ARG_ index, val ) - -#define CUR_Func_move_cvt( index, val ) \ - CUR.func_move_cvt( EXEC_ARG_ index, val ) - -#define CURRENT_Ratio() \ - Current_Ratio( EXEC_ARG ) - -#define CURRENT_Ppem() \ - Current_Ppem( EXEC_ARG ) - -#define CUR_Ppem() \ - Cur_PPEM( EXEC_ARG ) - -#define CALC_Length() \ - Calc_Length( EXEC_ARG ) - -#define INS_SxVTL( a, b, c, d ) \ - Ins_SxVTL( EXEC_ARG_ a, b, c, d ) - -#define COMPUTE_Funcs() \ - Compute_Funcs( EXEC_ARG ) - -#define COMPUTE_Round( a ) \ - Compute_Round( EXEC_ARG_ a ) - -#define COMPUTE_Point_Displacement( a, b, c, d ) \ - Compute_Point_Displacement( EXEC_ARG_ a, b, c, d ) - -#define MOVE_Zp2_Point( a, b, c, t ) \ - Move_Zp2_Point( EXEC_ARG_ a, b, c, t ) - - - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( INS_ARG ); - - - /*************************************************************************/ - /* */ - /* A simple bounds-checking macro. */ - /* */ -#define BOUNDS( x, n ) ( (FT_UInt)(x) >= (FT_UInt)(n) ) - - -#undef SUCCESS -#define SUCCESS 0 - -#undef FAILURE -#define FAILURE 1 - - - /*************************************************************************/ - /* */ - /* CODERANGE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Goto_CodeRange */ - /* */ - /* */ - /* Switches to a new code range (updates the code related elements in */ - /* `exec', and `IP'). */ - /* */ - /* */ - /* range :: The new execution code range. */ - /* */ - /* IP :: The new IP in the new code range. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ) - { - TT_CodeRange* coderange; - - - FT_Assert( range >= 1 && range <= 3 ); - - coderange = &exec->codeRangeTable[range - 1]; - - FT_Assert( coderange->base != NULL ); - - /* 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. */ - /* */ - FT_Assert( (FT_ULong)IP <= coderange->size ); - - exec->code = coderange->base; - exec->codeSize = coderange->size; - exec->IP = IP; - exec->curRange = range; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Set_CodeRange */ - /* */ - /* */ - /* Sets a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* base :: The new code base. */ - /* */ - /* length :: The range size in bytes. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ) - { - FT_Assert( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = (FT_Byte*)base; - exec->codeRangeTable[range - 1].size = length; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Clear_CodeRange */ - /* */ - /* */ - /* Clears a code range. */ - /* */ - /* */ - /* range :: The code range index. */ - /* */ - /* */ - /* exec :: The target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Does not set the Error variable. */ - /* */ - LOCAL_FUNC - FT_Error TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ) - { - FT_Assert( range >= 1 && range <= 3 ); - - exec->codeRangeTable[range - 1].base = NULL; - exec->codeRangeTable[range - 1].size = 0; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* EXECUTION CONTEXT ROUTINES */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Destroy_Context */ - /* */ - /* */ - /* Destroys a given context. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Destroy_Context( TT_ExecContext exec, - FT_Memory memory ) - { - /* free composite load stack */ - FREE( exec->loadStack ); - exec->loadSize = 0; - - /* points zone */ - 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->size = NULL; - exec->face = NULL; - - FREE( exec ); - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Init_Context */ - /* */ - /* */ - /* Initializes a context object. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* face :: A handle to the source TrueType face object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Init_Context( TT_ExecContext exec, - TT_Face face, - FT_Memory memory ) - { - FT_Error error; - - - FT_TRACE1(( "Init_Context: new object at 0x%08p, parent = 0x%08p\n", - exec, face )); - - exec->memory = memory; - exec->callSize = 32; - - if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TT_CallRec ) ) - 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->size = NULL; - - return TT_Err_Ok; - - Fail_Memory: - FT_ERROR(( "Init_Context: not enough memory for 0x%08lx\n", - (FT_Long)exec )); - TT_Destroy_Context( exec, memory ); - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Update_Max */ - /* */ - /* */ - /* Checks the size of a buffer and reallocates it if necessary. */ - /* */ - /* */ - /* memory :: A handle to the parent memory object. */ - /* */ - /* multiplier :: The size in bytes of each element in the buffer. */ - /* */ - /* new_max :: The new capacity (size) of the buffer. */ - /* */ - /* */ - /* size :: The address of the buffer's current size expressed */ - /* in elements. */ - /* */ - /* buff :: The address of the buffer base pointer. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Update_Max( FT_Memory memory, - FT_ULong* size, - FT_Long multiplier, - void** buff, - FT_ULong new_max ) - { - FT_Error error; - - - if ( *size < new_max ) - { - FREE( *buff ); - if ( ALLOC( *buff, new_max * multiplier ) ) - return error; - *size = new_max; - } - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Context */ - /* */ - /* */ - /* Prepare an execution context for glyph hinting. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* size :: A handle to the source size object. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ) - { - FT_Int i; - FT_ULong tmp; - TT_MaxProfile* maxp; - FT_Error error; - - - exec->face = face; - maxp = &face->max_profile; - exec->size = size; - - if ( size ) - { - exec->numFDefs = size->num_function_defs; - exec->maxFDefs = size->max_function_defs; - exec->numIDefs = size->num_instruction_defs; - exec->maxIDefs = size->max_instruction_defs; - exec->FDefs = size->function_defs; - exec->IDefs = size->instruction_defs; - exec->tt_metrics = size->ttmetrics; - exec->metrics = size->root.metrics; - - exec->maxFunc = size->max_func; - exec->maxIns = size->max_ins; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - exec->codeRangeTable[i] = size->codeRangeTable[i]; - - /* set graphics state */ - exec->GS = size->GS; - - exec->cvtSize = size->cvt_size; - exec->cvt = size->cvt; - - exec->storeSize = size->storage_size; - exec->storage = size->storage; - - exec->twilight = size->twilight; - } - - error = Update_Max( exec->memory, - &exec->loadSize, - sizeof ( TT_SubGlyphRec ), - (void**)&exec->loadStack, - exec->face->max_components + 1 ); - if ( error ) - return error; - - /* XXX: We reserve a little more elements on the stack to deal safely */ - /* with broken fonts like arialbs, courbs, timesbs, etc. */ - tmp = exec->stackSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_F26Dot6 ), - (void**)&exec->stack, - maxp->maxStackElements + 32 ); - exec->stackSize = (FT_UInt)tmp; - if ( error ) - return error; - - tmp = exec->glyphSize; - error = Update_Max( exec->memory, - &tmp, - sizeof ( FT_Byte ), - (void**)&exec->glyphIns, - maxp->maxSizeOfInstructions ); - exec->glyphSize = (FT_UShort)tmp; - if ( error ) - return error; - - exec->pts.n_points = 0; - exec->pts.n_contours = 0; - - exec->instruction_trap = FALSE; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Save_Context */ - /* */ - /* */ - /* Saves the code ranges in a `size' object. */ - /* */ - /* */ - /* exec :: A handle to the source execution context. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Save_Context( TT_ExecContext exec, - TT_Size size ) - { - FT_Int i; - - - /* XXXX: Will probably disappear soon with all the code range */ - /* management, which is now rather obsolete. */ - /* */ - size->num_function_defs = exec->numFDefs; - size->num_instruction_defs = exec->numIDefs; - - size->max_func = exec->maxFunc; - size->max_ins = exec->maxIns; - - for ( i = 0; i < TT_MAX_CODE_RANGES; i++ ) - size->codeRangeTable[i] = exec->codeRangeTable[i]; - - return TT_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Run_Context */ - /* */ - /* */ - /* Executes one or more instructions in the execution context. */ - /* */ - /* */ - /* debug :: A Boolean flag. If set, the function sets some internal */ - /* variables and returns immediately, otherwise TT_RunIns() */ - /* is called. */ - /* */ - /* This is commented out currently. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* TrueTyoe error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ) - { - FT_Error error; - - - if ( ( error = TT_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 1 - FT_UNUSED( debug ); - - return exec->face->interpreter( exec ); -#else - if ( !debug ) - return TT_RunIns( exec ); - else - return TT_Err_Ok; -#endif - } - - - const TT_GraphicsState tt_default_graphics_state = - { - 0, 0, 0, - { 0x4000, 0 }, - { 0x4000, 0 }, - { 0x4000, 0 }, - 1, 64, 1, - TRUE, 68, 0, 0, 9, 3, - 0, FALSE, 2, 1, 1, 1 - }; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_New_Context */ - /* */ - /* */ - /* Queries the face context for a given font. Note that there is */ - /* now a _single_ execution context in the TrueType driver which is */ - /* shared among faces. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* */ - /* A handle to the execution context. Initialized for `face'. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - FT_EXPORT_FUNC( TT_ExecContext ) TT_New_Context( TT_Face face ) - { - TT_Driver driver; - TT_ExecContext exec; - FT_Memory memory; - - - if ( !face ) - return 0; - - driver = (TT_Driver)face->root.driver; - - memory = driver->root.root.memory; - exec = driver->context; - - if ( !driver->context ) - { - FT_Error error; - - - /* allocate object */ - if ( ALLOC( exec, sizeof ( *exec ) ) ) - goto Exit; - - /* initialize it */ - error = Init_Context( exec, face, memory ); - if ( error ) - goto Fail; - - /* store it into the driver */ - driver->context = exec; - } - - Exit: - return driver->context; - - Fail: - FREE( exec ); - - return 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Context */ - /* */ - /* */ - /* Discards an execution context. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the glyph loader and debugger should call this function. */ - /* */ - LOCAL_FUNC - FT_Error TT_Done_Context( TT_ExecContext exec ) - { - /* Nothing at all for now */ - FT_UNUSED( exec ); - - return TT_Err_Ok; - } - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static FT_F26Dot6 Norm( FT_F26Dot6 X, - FT_F26Dot6 Y ) - { - TT_INT64 T1, T2; - - - MUL_64( X, X, T1 ); - MUL_64( Y, Y, T2 ); - - ADD_64( T1, T2, T1 ); - - return (FT_F26Dot6)SQRT_64( T1 ); - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* 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 FT_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 FT_Char opcode_length[256] = - { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11,13,15,17, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - }; - - static - const FT_Vector Null_Vector = {0,0}; - - -#undef PACK - - -#undef NULL_Vector -#define NULL_Vector (FT_Vector*)&Null_Vector - - - /*************************************************************************/ - /* */ - /* */ - /* Current_Ratio */ - /* */ - /* */ - /* Returns the current aspect ratio scaling factor depending on the */ - /* projection vector's state and device resolutions. */ - /* */ - /* */ - /* The aspect ratio in 16.16 format, always <= 1.0 . */ - /* */ - static - FT_Long Current_Ratio( EXEC_OP ) - { - if ( CUR.tt_metrics.ratio ) - return CUR.tt_metrics.ratio; - - if ( CUR.GS.projVector.y == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio; - - else if ( CUR.GS.projVector.x == 0 ) - CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio; - - else - { - FT_Long x, y; - - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 ); - y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 ); - CUR.tt_metrics.ratio = Norm( x, y ); - -#else - - x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x8000 ); - y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x8000 ); - CUR.tt_metrics.ratio = FT_Sqrt32( x * x + y * y ) << 1; - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - } - - return CUR.tt_metrics.ratio; - } - - - static - FT_Long Current_Ppem( EXEC_OP ) - { - return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* Functions related to the control value table (CVT). */ - /* */ - /*************************************************************************/ - - - static - FT_F26Dot6 Read_CVT( EXEC_OP_ FT_ULong index ) - { - return CUR.cvt[index]; - } - - - static - FT_F26Dot6 Read_CVT_Stretched( EXEC_OP_ FT_ULong index ) - { - return TT_MULFIX( CUR.cvt[index], CURRENT_Ratio() ); - } - - - static - void Write_CVT( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] = value; - } - - - static - void Write_CVT_Stretched( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] = FT_DivFix( value, CURRENT_Ratio() ); - } - - - static - void Move_CVT( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] += value; - } - - - static - void Move_CVT_Stretched( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ) - { - CUR.cvt[index] += FT_DivFix( value, CURRENT_Ratio() ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* GetShortIns */ - /* */ - /* */ - /* Returns a short integer taken from the instruction stream at */ - /* address IP. */ - /* */ - /* */ - /* Short read at code[IP]. */ - /* */ - /* */ - /* This one could become a macro. */ - /* */ - static FT_Short GetShortIns( EXEC_OP ) - { - /* Reading a byte stream so there is no endianess (DaveP) */ - CUR.IP += 2; - return (FT_Short)( ( CUR.code[CUR.IP - 2] << 8 ) + - CUR.code[CUR.IP - 1] ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Ins_Goto_CodeRange */ - /* */ - /* */ - /* Goes to a certain code range in the instruction stream. */ - /* */ - /* */ - /* aRange :: The index of the code range. */ - /* */ - /* aIP :: The new IP address in the code range. */ - /* */ - /* */ - /* SUCCESS or FAILURE. */ - /* */ - static - FT_Bool Ins_Goto_CodeRange( EXEC_OP_ FT_Int aRange, - FT_ULong aIP ) - { - TT_CodeRange* range; - - - if ( aRange < 1 || aRange > 3 ) - { - CUR.error = TT_Err_Bad_Argument; - return FAILURE; - } - - range = &CUR.codeRangeTable[aRange - 1]; - - if ( range->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 > range->size ) - { - CUR.error = TT_Err_Code_Overflow; - return FAILURE; - } - - CUR.code = range->base; - CUR.codeSize = range->size; - CUR.IP = aIP; - CUR.curRange = aRange; - - return SUCCESS; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Direct_Move */ - /* */ - /* */ - /* Moves a point by a given distance along the freedom vector. The */ - /* point will be `touched'. */ - /* */ - /* */ - /* point :: The index of the point to move. */ - /* */ - /* distance :: The distance to apply. */ - /* */ - /* */ - /* zone :: The affected glyph zone. */ - /* */ - static - void Direct_Move( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_F26Dot6 v; - - - v = CUR.GS.freeVector.x; - - if ( v != 0 ) - { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].x += distance; - -#else - - zone->cur[point].x += TT_MULDIV( distance, - v * 0x10000L, - CUR.F_dot_P ); - -#endif - - zone->tags[point] |= FT_Curve_Tag_Touch_X; - } - - v = CUR.GS.freeVector.y; - - if ( v != 0 ) - { - -#ifdef NO_APPLE_PATENT - - if ( ABS( CUR.F_dot_P ) > APPLE_THRESHOLD ) - zone->cur[point].y += distance; - -#else - - zone->cur[point].y += TT_MULDIV( distance, - v * 0x10000L, - CUR.F_dot_P ); - -#endif - - zone->tags[point] |= FT_Curve_Tag_Touch_Y; - } - } - - - /*************************************************************************/ - /* */ - /* Special versions of Direct_Move() */ - /* */ - /* The following versions are used whenever both vectors are both */ - /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ - /* */ - /*************************************************************************/ - - - static - void Direct_Move_X( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->cur[point].x += distance; - zone->tags[point] |= FT_Curve_Tag_Touch_X; - } - - - static - void Direct_Move_Y( EXEC_OP_ TT_GlyphZone* zone, - FT_UShort point, - FT_F26Dot6 distance ) - { - FT_UNUSED_EXEC; - - zone->cur[point].y += distance; - zone->tags[point] |= FT_Curve_Tag_Touch_Y; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_None */ - /* */ - /* */ - /* Does not round, but adds engine compensation. */ - /* */ - /* */ - /* distance :: The distance (not) to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* The compensated distance. */ - /* */ - /* */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static - FT_F26Dot6 Round_None( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - if ( distance >= 0 ) - { - val = distance + compensation; - if ( val < 0 ) - val = 0; - } - else { - val = distance - compensation; - if ( val > 0 ) - val = 0; - } - return val; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Grid */ - /* */ - /* */ - /* Rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Half_Grid */ - /* */ - /* */ - /* Rounds value to half grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Half_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Down_To_Grid */ - /* */ - /* */ - /* Rounds value down to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_Down_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Up_To_Grid */ - /* */ - /* */ - /* Rounds value up to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_Up_To_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - - FT_UNUSED_EXEC; - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_To_Double_Grid */ - /* */ - /* */ - /* Rounds value to double grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - static - FT_F26Dot6 Round_To_Double_Grid( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_F26Dot6 val; - - FT_UNUSED_EXEC; - - - 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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Super */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* The TrueType specification says very few about the relationship */ - /* between rounding and engine compensation. However, it seems from */ - /* the description of super round that we should add the compensation */ - /* before rounding. */ - /* */ - static - FT_F26Dot6 Round_Super( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_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; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Round_Super_45 */ - /* */ - /* */ - /* Super-rounds value to grid after adding engine compensation. */ - /* */ - /* */ - /* distance :: The distance to round. */ - /* */ - /* compensation :: The engine compensation. */ - /* */ - /* */ - /* Rounded distance. */ - /* */ - /* */ - /* There is a separate function for Round_Super_45() as we may need */ - /* greater precision. */ - /* */ - static - FT_F26Dot6 Round_Super_45( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ) - { - FT_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 */ - /* */ - /* */ - /* Sets the rounding mode. */ - /* */ - /* */ - /* round_mode :: The rounding mode to be used. */ - /* */ - static - void Compute_Round( EXEC_OP_ FT_Byte round_mode ) - { - switch ( round_mode ) - { - case TT_Round_Off: - CUR.func_round = (TT_Round_Func)Round_None; - break; - - case TT_Round_To_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Grid; - break; - - case TT_Round_Up_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - break; - - case TT_Round_Down_To_Grid: - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - break; - - case TT_Round_To_Half_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - break; - - case TT_Round_To_Double_Grid: - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - break; - - case TT_Round_Super: - CUR.func_round = (TT_Round_Func)Round_Super; - break; - - case TT_Round_Super_45: - CUR.func_round = (TT_Round_Func)Round_Super_45; - break; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* SetSuperRound */ - /* */ - /* */ - /* Sets Super Round parameters. */ - /* */ - /* */ - /* GridPeriod :: Grid period */ - /* selector :: SROUND opcode */ - /* */ - static - void SetSuperRound( EXEC_OP_ FT_F26Dot6 GridPeriod, - FT_Long selector ) - { - switch ( (FT_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 ( (FT_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 = ( (FT_Int)( selector & 0x0F ) - 4 ) * CUR.period / 8; - - CUR.period /= 256; - CUR.phase /= 256; - CUR.threshold /= 256; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project */ - /* */ - /* */ - /* Computes the projection of vector given by (v2-v1) along the */ - /* current projection vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.projVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.projVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Dual_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current dual vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Dual_Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.dualVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.dualVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Free_Project */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* current freedom vector. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Free_Project( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - return TT_MULDIV( v1->x - v2->x, CUR.GS.freeVector.x, 0x4000 ) + - TT_MULDIV( v1->y - v2->y, CUR.GS.freeVector.y, 0x4000 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project_x */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* horizontal axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project_x( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - FT_UNUSED_EXEC; - - return ( v1->x - v2->x ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Project_y */ - /* */ - /* */ - /* Computes the projection of the vector given by (v2-v1) along the */ - /* vertical axis. */ - /* */ - /* */ - /* v1 :: First input vector. */ - /* v2 :: Second input vector. */ - /* */ - /* */ - /* The distance in F26dot6 format. */ - /* */ - static - FT_F26Dot6 Project_y( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ) - { - FT_UNUSED_EXEC; - - return ( v1->y - v2->y ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Compute_Funcs */ - /* */ - /* */ - /* Computes the projection and movement function pointers according */ - /* to the current graphics state. */ - /* */ - static - void Compute_Funcs( EXEC_OP ) - { - if ( CUR.GS.freeVector.x == 0x4000 ) - { - CUR.func_freeProj = (TT_Project_Func)Project_x; - CUR.F_dot_P = CUR.GS.projVector.x * 0x10000L; - } - else - { - if ( CUR.GS.freeVector.y == 0x4000 ) - { - CUR.func_freeProj = (TT_Project_Func)Project_y; - CUR.F_dot_P = CUR.GS.projVector.y * 0x10000L; - } - else - { - CUR.func_freeProj = (TT_Project_Func)Free_Project; - CUR.F_dot_P = (FT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 + - (FT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4; - } - } - - if ( CUR.GS.projVector.x == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_x; - else - { - if ( CUR.GS.projVector.y == 0x4000 ) - CUR.func_project = (TT_Project_Func)Project_y; - else - CUR.func_project = (TT_Project_Func)Project; - } - - if ( CUR.GS.dualVector.x == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_x; - else - { - if ( CUR.GS.dualVector.y == 0x4000 ) - CUR.func_dualproj = (TT_Project_Func)Project_y; - else - CUR.func_dualproj = (TT_Project_Func)Dual_Project; - } - - CUR.func_move = (TT_Move_Func)Direct_Move; - - if ( CUR.F_dot_P == 0x40000000L ) - { - if ( CUR.GS.freeVector.x == 0x4000 ) - CUR.func_move = (TT_Move_Func)Direct_Move_X; - else - { - if ( CUR.GS.freeVector.y == 0x4000 ) - CUR.func_move = (TT_Move_Func)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.tt_metrics.ratio = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Normalize */ - /* */ - /* */ - /* Norms a vector. */ - /* */ - /* */ - /* Vx :: The horizontal input vector coordinate. */ - /* Vy :: The vertical input vector coordinate. */ - /* */ - /* */ - /* R :: The normed unit vector. */ - /* */ - /* */ - /* Returns FAILURE if a vector parameter is zero. */ - /* */ - /* */ - /* In case Vx and Vy are both zero, Normalize() returns SUCCESS, and */ - /* R is undefined. */ - /* */ - -#ifdef FT_CONFIG_OPTION_OLD_CALCS - - static - FT_Bool Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) - { - FT_F26Dot6 W; - FT_Bool S1, S2; - - FT_UNUSED_EXEC; - - - if ( ABS( Vx ) < 0x10000L && ABS( Vy ) < 0x10000L ) - { - Vx *= 0x100; - Vy *= 0x100; - - W = Norm( Vx, Vy ); - - if ( W == 0 ) - { - /* XXX: UNDOCUMENTED! It seems that it is possible to try */ - /* to normalize the vector (0,0). Return immediately. */ - return SUCCESS; - } - - R->x = (FT_F2Dot14)FT_MulDiv( Vx, 0x4000L, W ); - R->y = (FT_F2Dot14)FT_MulDiv( Vy, 0x4000L, W ); - - return SUCCESS; - } - - W = Norm( Vx, Vy ); - - Vx = FT_MulDiv( Vx, 0x4000L, W ); - Vy = FT_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 = (FT_F2Dot14)Vx; /* Type conversion */ - R->y = (FT_F2Dot14)Vy; /* Type conversion */ - - return SUCCESS; - } - -#else - - static - FT_Bool Normalize( EXEC_OP_ FT_F26Dot6 Vx, - FT_F26Dot6 Vy, - FT_UnitVector* R ) - { - FT_F26Dot6 u, v, d; - FT_Int shift; - FT_ULong H, L, L2, hi, lo, med; - - - u = ABS( Vx ); - v = ABS( Vy ); - - if ( u < v ) - { - d = u; - u = v; - v = d; - } - - R->x = 0; - R->y = 0; - - /* check that we are not trying to normalise zero! */ - if ( u == 0 ) - return SUCCESS; - - /* compute (u*u + v*v) on 64 bits with two 32-bit registers [H:L] */ - hi = (FT_ULong)u >> 16; - lo = (FT_ULong)u & 0xFFFF; - med = hi * lo; - - H = hi * hi + ( med >> 15 ); - med <<= 17; - L = lo * lo + med; - if ( L < med ) - H++; - - hi = (FT_ULong)v >> 16; - lo = (FT_ULong)v & 0xFFFF; - med = hi * lo; - - H += hi * hi + ( med >> 15 ); - med <<= 17; - L2 = lo * lo + med; - if ( L2 < med ) - H++; - - L += L2; - if ( L < L2 ) - H++; - - /* if the value is smaller than 32-bits */ - if ( H == 0 ) - { - shift = 0; - while ( ( L & 0xC0000000L ) == 0 ) - { - L <<= 2; - shift++; - } - - d = FT_Sqrt32( L ); - R->x = (FT_F2Dot14)TT_MULDIV( Vx << shift, 0x4000, d ); - R->y = (FT_F2Dot14)TT_MULDIV( Vy << shift, 0x4000, d ); - } - /* if the value is greater than 64-bits */ - else - { - shift = 0; - while ( H ) - { - L = ( L >> 2 ) | ( H << 30 ); - H >>= 2; - shift++; - } - - d = FT_Sqrt32( L ); - R->x = (FT_F2Dot14)TT_MULDIV( Vx >> shift, 0x4000, d ); - R->y = (FT_F2Dot14)TT_MULDIV( Vy >> shift, 0x4000, d ); - } - - { - FT_ULong x, y, w; - FT_Int sx, sy; - - - sx = R->x >= 0 ? 1 : -1; - sy = R->y >= 0 ? 1 : -1; - x = (FT_ULong)sx * R->x; - y = (FT_ULong)sy * R->y; - - w = x * x + y * y; - - /* we now want to adjust (x,y) in order to have sqrt(w) == 0x4000 */ - /* which means 0x1000000 <= w < 0x1004000 */ - while ( w <= 0x10000000L ) - { - /* increment the smallest coordinate */ - if ( x < y ) - x++; - else - y++; - - w = x * x + y * y; - } - - while ( w >= 0x10040000L ) - { - /* decrement the smallest coordinate */ - if ( x < y ) - x--; - else - y--; - - w = x * x + y * y; - } - - R->x = sx * x; - R->y = sy * y; - } - - return SUCCESS; - } - -#endif /* FT_CONFIG_OPTION_OLD_CALCS */ - - - /*************************************************************************/ - /* */ - /* Here we start with the implementation of the various opcodes. */ - /* */ - /*************************************************************************/ - - - static - FT_Bool Ins_SxVTL( EXEC_OP_ FT_UShort aIdx1, - FT_UShort aIdx2, - FT_Int aOpc, - FT_UnitVector* Vec ) - { - FT_Long A, B, C; - FT_Vector* p1; - FT_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; /* counter clockwise 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 are all defined there. */ - -#define DO_SVTCA \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_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 \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_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 \ - { \ - FT_Short A, B; \ - \ - \ - A = (FT_Short)( CUR.opcode & 1 ) << 14; \ - B = A ^ (FT_Short)0x4000; \ - \ - CUR.GS.freeVector.x = A; \ - CUR.GS.freeVector.y = B; \ - \ - COMPUTE_Funcs(); \ - } - - -#define DO_SPVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_UShort)args[0], \ - CUR.opcode, \ - &CUR.GS.projVector ) == SUCCESS ) \ - { \ - CUR.GS.dualVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVTL \ - if ( INS_SxVTL( (FT_UShort)args[1], \ - (FT_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 \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_Short)args[0]; \ - X = (FT_Long)S; \ - \ - NORMalize( X, Y, &CUR.GS.projVector ); \ - \ - CUR.GS.dualVector = CUR.GS.projVector; \ - COMPUTE_Funcs(); \ - } - - -#define DO_SFVFS \ - { \ - FT_Short S; \ - FT_Long X, Y; \ - \ - \ - /* Only use low 16bits, then sign extend */ \ - S = (FT_Short)args[1]; \ - Y = (FT_Long)S; \ - S = (FT_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 = (FT_UShort)args[0]; - - -#define DO_SRP1 \ - CUR.GS.rp1 = (FT_UShort)args[0]; - - -#define DO_SRP2 \ - CUR.GS.rp2 = (FT_UShort)args[0]; - - -#define DO_RTHG \ - CUR.GS.round_state = TT_Round_To_Half_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Half_Grid; - - -#define DO_RTG \ - CUR.GS.round_state = TT_Round_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Grid; - - -#define DO_RTDG \ - CUR.GS.round_state = TT_Round_To_Double_Grid; \ - CUR.func_round = (TT_Round_Func)Round_To_Double_Grid; - - -#define DO_RUTG \ - CUR.GS.round_state = TT_Round_Up_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Up_To_Grid; - - -#define DO_RDTG \ - CUR.GS.round_state = TT_Round_Down_To_Grid; \ - CUR.func_round = (TT_Round_Func)Round_Down_To_Grid; - - -#define DO_ROFF \ - CUR.GS.round_state = TT_Round_Off; \ - CUR.func_round = (TT_Round_Func)Round_None; - - -#define DO_SROUND \ - SET_SuperRound( 0x4000, args[0] ); \ - CUR.GS.round_state = TT_Round_Super; \ - CUR.func_round = (TT_Round_Func)Round_Super; - - -#define DO_S45ROUND \ - SET_SuperRound( 0x2D41, args[0] ); \ - CUR.GS.round_state = TT_Round_Super_45; \ - CUR.func_round = (TT_Round_Func)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 = args[0]; - - -#define DO_SCVTCI \ - CUR.GS.control_value_cutin = (FT_F26Dot6)args[0]; - - -#define DO_SSWCI \ - CUR.GS.single_width_cutin = (FT_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 = (FT_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 = (FT_Short)args[0]; - - -#define DO_SDS \ - CUR.GS.delta_shift = (FT_Short)args[0]; - - -#define DO_MD /* nothing */ - - -#define DO_MPPEM \ - args[0] = CURRENT_Ppem(); - - - /* Note: The pointSize should be irrelevant in a given font program; */ - /* we thus decide to return only the ppem. */ -#if 0 - -#define DO_MPS \ - args[0] = CUR.metrics.pointSize; - -#else - -#define DO_MPS \ - args[0] = CURRENT_Ppem(); - -#endif /* 0 */ - - -#define DO_DUP \ - args[1] = args[0]; - - -#define DO_CLEAR \ - CUR.new_top = 0; - - -#define DO_SWAP \ - { \ - FT_Long L; \ - \ - \ - L = args[0]; \ - args[0] = args[1]; \ - args[1] = L; \ - } - - -#define DO_DEPTH \ - args[0] = CUR.top; - - -#define DO_CINDEX \ - { \ - FT_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 \ - { \ - FT_ULong I = (FT_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 \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.storeSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.storage[I] = args[1]; \ - } - - -#define DO_RCVT \ - { \ - FT_ULong I = (FT_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 \ - { \ - FT_ULong I = (FT_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 \ - { \ - FT_ULong I = (FT_ULong)args[0]; \ - \ - \ - if ( BOUNDS( I, CUR.cvtSize ) ) \ - { \ - if ( CUR.pedantic_hinting ) \ - { \ - ARRAY_BOUND_ERROR; \ - } \ - } \ - else \ - CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \ - } - - -#define DO_DEBUG \ - CUR.error = TT_Err_Debug_OpCode; - - -#define DO_ROUND \ - args[0] = CUR_Func_round( \ - args[0], \ - CUR.tt_metrics.compensations[CUR.opcode - 0x68] ); - - -#define DO_NROUND \ - args[0] = ROUND_None( args[0], \ - CUR.tt_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 Coordinate Axis */ - /* Opcode range: 0x00-0x01 */ - /* Stack: --> */ - /* */ - static - void Ins_SVTCA( INS_ARG ) - { - DO_SVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTCA[a]: Set PVector to Coordinate Axis */ - /* Opcode range: 0x02-0x03 */ - /* Stack: --> */ - /* */ - static - void Ins_SPVTCA( INS_ARG ) - { - DO_SPVTCA - } - - - /*************************************************************************/ - /* */ - /* SFVTCA[a]: Set FVector to Coordinate Axis */ - /* Opcode range: 0x04-0x05 */ - /* Stack: --> */ - /* */ - static - void Ins_SFVTCA( INS_ARG ) - { - DO_SFVTCA - } - - - /*************************************************************************/ - /* */ - /* SPVTL[a]: Set PVector To Line */ - /* Opcode range: 0x06-0x07 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SPVTL( INS_ARG ) - { - DO_SPVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTL[a]: Set FVector To Line */ - /* Opcode range: 0x08-0x09 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SFVTL( INS_ARG ) - { - DO_SFVTL - } - - - /*************************************************************************/ - /* */ - /* SFVTPV[]: Set FVector To PVector */ - /* Opcode range: 0x0E */ - /* Stack: --> */ - /* */ - static - void Ins_SFVTPV( INS_ARG ) - { - DO_SFVTPV - } - - - /*************************************************************************/ - /* */ - /* SPVFS[]: Set PVector From Stack */ - /* Opcode range: 0x0A */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static - void Ins_SPVFS( INS_ARG ) - { - DO_SPVFS - } - - - /*************************************************************************/ - /* */ - /* SFVFS[]: Set FVector From Stack */ - /* Opcode range: 0x0B */ - /* Stack: f2.14 f2.14 --> */ - /* */ - static - void Ins_SFVFS( INS_ARG ) - { - DO_SFVFS - } - - - /*************************************************************************/ - /* */ - /* GPV[]: Get Projection Vector */ - /* Opcode range: 0x0C */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static - void Ins_GPV( INS_ARG ) - { - DO_GPV - } - - - /*************************************************************************/ - /* GFV[]: Get Freedom Vector */ - /* Opcode range: 0x0D */ - /* Stack: ef2.14 --> ef2.14 */ - /* */ - static - void Ins_GFV( INS_ARG ) - { - DO_GFV - } - - - /*************************************************************************/ - /* */ - /* SRP0[]: Set Reference Point 0 */ - /* Opcode range: 0x10 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP0( INS_ARG ) - { - DO_SRP0 - } - - - /*************************************************************************/ - /* */ - /* SRP1[]: Set Reference Point 1 */ - /* Opcode range: 0x11 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP1( INS_ARG ) - { - DO_SRP1 - } - - - /*************************************************************************/ - /* */ - /* SRP2[]: Set Reference Point 2 */ - /* Opcode range: 0x12 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SRP2( INS_ARG ) - { - DO_SRP2 - } - - - /*************************************************************************/ - /* */ - /* RTHG[]: Round To Half Grid */ - /* Opcode range: 0x19 */ - /* Stack: --> */ - /* */ - static - void Ins_RTHG( INS_ARG ) - { - DO_RTHG - } - - - /*************************************************************************/ - /* */ - /* RTG[]: Round To Grid */ - /* Opcode range: 0x18 */ - /* Stack: --> */ - /* */ - static - void Ins_RTG( INS_ARG ) - { - DO_RTG - } - - - /*************************************************************************/ - /* RTDG[]: Round To Double Grid */ - /* Opcode range: 0x3D */ - /* Stack: --> */ - /* */ - static - void Ins_RTDG( INS_ARG ) - { - DO_RTDG - } - - - /*************************************************************************/ - /* RUTG[]: Round Up To Grid */ - /* Opcode range: 0x7C */ - /* Stack: --> */ - /* */ - static - void Ins_RUTG( INS_ARG ) - { - DO_RUTG - } - - - /*************************************************************************/ - /* */ - /* RDTG[]: Round Down To Grid */ - /* Opcode range: 0x7D */ - /* Stack: --> */ - /* */ - static - void Ins_RDTG( INS_ARG ) - { - DO_RDTG - } - - - /*************************************************************************/ - /* */ - /* ROFF[]: Round OFF */ - /* Opcode range: 0x7A */ - /* Stack: --> */ - /* */ - static - void Ins_ROFF( INS_ARG ) - { - DO_ROFF - } - - - /*************************************************************************/ - /* */ - /* SROUND[]: Super ROUND */ - /* Opcode range: 0x76 */ - /* Stack: Eint8 --> */ - /* */ - static - void Ins_SROUND( INS_ARG ) - { - DO_SROUND - } - - - /*************************************************************************/ - /* */ - /* S45ROUND[]: Super ROUND 45 degrees */ - /* Opcode range: 0x77 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_S45ROUND( INS_ARG ) - { - DO_S45ROUND - } - - - /*************************************************************************/ - /* */ - /* SLOOP[]: Set LOOP variable */ - /* Opcode range: 0x17 */ - /* Stack: int32? --> */ - /* */ - static - void Ins_SLOOP( INS_ARG ) - { - DO_SLOOP - } - - - /*************************************************************************/ - /* */ - /* SMD[]: Set Minimum Distance */ - /* Opcode range: 0x1A */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SMD( INS_ARG ) - { - DO_SMD - } - - - /*************************************************************************/ - /* */ - /* SCVTCI[]: Set Control Value Table Cut In */ - /* Opcode range: 0x1D */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SCVTCI( INS_ARG ) - { - DO_SCVTCI - } - - - /*************************************************************************/ - /* */ - /* SSWCI[]: Set Single Width Cut In */ - /* Opcode range: 0x1E */ - /* Stack: f26.6 --> */ - /* */ - static - void Ins_SSWCI( INS_ARG ) - { - DO_SSWCI - } - - - /*************************************************************************/ - /* */ - /* SSW[]: Set Single Width */ - /* Opcode range: 0x1F */ - /* Stack: int32? --> */ - /* */ - static - void Ins_SSW( INS_ARG ) - { - DO_SSW - } - - - /*************************************************************************/ - /* */ - /* FLIPON[]: Set auto-FLIP to ON */ - /* Opcode range: 0x4D */ - /* Stack: --> */ - /* */ - static - void Ins_FLIPON( INS_ARG ) - { - DO_FLIPON - } - - - /*************************************************************************/ - /* */ - /* FLIPOFF[]: Set auto-FLIP to OFF */ - /* Opcode range: 0x4E */ - /* Stack: --> */ - /* */ - static - void Ins_FLIPOFF( INS_ARG ) - { - DO_FLIPOFF - } - - - /*************************************************************************/ - /* */ - /* SANGW[]: Set ANGle Weight */ - /* Opcode range: 0x7E */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SANGW( INS_ARG ) - { - /* instruction not supported anymore */ - } - - - /*************************************************************************/ - /* */ - /* SDB[]: Set Delta Base */ - /* Opcode range: 0x5E */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SDB( INS_ARG ) - { - DO_SDB - } - - - /*************************************************************************/ - /* */ - /* SDS[]: Set Delta Shift */ - /* Opcode range: 0x5F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SDS( INS_ARG ) - { - DO_SDS - } - - - /*************************************************************************/ - /* */ - /* MPPEM[]: Measure Pixel Per EM */ - /* Opcode range: 0x4B */ - /* Stack: --> Euint16 */ - /* */ - static - void Ins_MPPEM( INS_ARG ) - { - DO_MPPEM - } - - - /*************************************************************************/ - /* */ - /* MPS[]: Measure Point Size */ - /* Opcode range: 0x4C */ - /* Stack: --> Euint16 */ - /* */ - static - void Ins_MPS( INS_ARG ) - { - DO_MPS - } - - - /*************************************************************************/ - /* */ - /* DUP[]: DUPlicate the top stack's element */ - /* Opcode range: 0x20 */ - /* Stack: StkElt --> StkElt StkElt */ - /* */ - static - void Ins_DUP( INS_ARG ) - { - DO_DUP - } - - - /*************************************************************************/ - /* */ - /* POP[]: POP the stack's top element */ - /* Opcode range: 0x21 */ - /* Stack: StkElt --> */ - /* */ - static - void Ins_POP( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* CLEAR[]: CLEAR the entire stack */ - /* Opcode range: 0x22 */ - /* Stack: StkElt... --> */ - /* */ - static - void Ins_CLEAR( INS_ARG ) - { - DO_CLEAR - } - - - /*************************************************************************/ - /* */ - /* SWAP[]: SWAP the stack's top two elements */ - /* Opcode range: 0x23 */ - /* Stack: 2 * StkElt --> 2 * StkElt */ - /* */ - static - void Ins_SWAP( INS_ARG ) - { - DO_SWAP - } - - - /*************************************************************************/ - /* */ - /* DEPTH[]: return the stack DEPTH */ - /* Opcode range: 0x24 */ - /* Stack: --> uint32 */ - /* */ - static - void Ins_DEPTH( INS_ARG ) - { - DO_DEPTH - } - - - /*************************************************************************/ - /* */ - /* CINDEX[]: Copy INDEXed element */ - /* Opcode range: 0x25 */ - /* Stack: int32 --> StkElt */ - /* */ - static - void Ins_CINDEX( INS_ARG ) - { - DO_CINDEX - } - - - /*************************************************************************/ - /* */ - /* EIF[]: End IF */ - /* Opcode range: 0x59 */ - /* Stack: --> */ - /* */ - static - void Ins_EIF( INS_ARG ) - { - /* nothing to do */ - } - - - /*************************************************************************/ - /* */ - /* JROT[]: Jump Relative On True */ - /* Opcode range: 0x78 */ - /* Stack: StkElt int32 --> */ - /* */ - static - void Ins_JROT( INS_ARG ) - { - DO_JROT - } - - - /*************************************************************************/ - /* */ - /* JMPR[]: JuMP Relative */ - /* Opcode range: 0x1C */ - /* Stack: int32 --> */ - /* */ - static - void Ins_JMPR( INS_ARG ) - { - DO_JMPR - } - - - /*************************************************************************/ - /* */ - /* JROF[]: Jump Relative On False */ - /* Opcode range: 0x79 */ - /* Stack: StkElt int32 --> */ - /* */ - static - void Ins_JROF( INS_ARG ) - { - DO_JROF - } - - - /*************************************************************************/ - /* */ - /* LT[]: Less Than */ - /* Opcode range: 0x50 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_LT( INS_ARG ) - { - DO_LT - } - - - /*************************************************************************/ - /* */ - /* LTEQ[]: Less Than or EQual */ - /* Opcode range: 0x51 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_LTEQ( INS_ARG ) - { - DO_LTEQ - } - - - /*************************************************************************/ - /* */ - /* GT[]: Greater Than */ - /* Opcode range: 0x52 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_GT( INS_ARG ) - { - DO_GT - } - - - /*************************************************************************/ - /* */ - /* GTEQ[]: Greater Than or EQual */ - /* Opcode range: 0x53 */ - /* Stack: int32? int32? --> bool */ - /* */ - static - void Ins_GTEQ( INS_ARG ) - { - DO_GTEQ - } - - - /*************************************************************************/ - /* */ - /* EQ[]: EQual */ - /* Opcode range: 0x54 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static - void Ins_EQ( INS_ARG ) - { - DO_EQ - } - - - /*************************************************************************/ - /* */ - /* NEQ[]: Not EQual */ - /* Opcode range: 0x55 */ - /* Stack: StkElt StkElt --> bool */ - /* */ - static - void Ins_NEQ( INS_ARG ) - { - DO_NEQ - } - - - /*************************************************************************/ - /* */ - /* ODD[]: Is ODD */ - /* Opcode range: 0x56 */ - /* Stack: f26.6 --> bool */ - /* */ - static - void Ins_ODD( INS_ARG ) - { - DO_ODD - } - - - /*************************************************************************/ - /* */ - /* EVEN[]: Is EVEN */ - /* Opcode range: 0x57 */ - /* Stack: f26.6 --> bool */ - /* */ - static - void Ins_EVEN( INS_ARG ) - { - DO_EVEN - } - - - /*************************************************************************/ - /* */ - /* AND[]: logical AND */ - /* Opcode range: 0x5A */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static - void Ins_AND( INS_ARG ) - { - DO_AND - } - - - /*************************************************************************/ - /* */ - /* OR[]: logical OR */ - /* Opcode range: 0x5B */ - /* Stack: uint32 uint32 --> uint32 */ - /* */ - static - void Ins_OR( INS_ARG ) - { - DO_OR - } - - - /*************************************************************************/ - /* */ - /* NOT[]: logical NOT */ - /* Opcode range: 0x5C */ - /* Stack: StkElt --> uint32 */ - /* */ - static - void Ins_NOT( INS_ARG ) - { - DO_NOT - } - - - /*************************************************************************/ - /* */ - /* ADD[]: ADD */ - /* Opcode range: 0x60 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_ADD( INS_ARG ) - { - DO_ADD - } - - - /*************************************************************************/ - /* */ - /* SUB[]: SUBtract */ - /* Opcode range: 0x61 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_SUB( INS_ARG ) - { - DO_SUB - } - - - /*************************************************************************/ - /* */ - /* DIV[]: DIVide */ - /* Opcode range: 0x62 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_DIV( INS_ARG ) - { - DO_DIV - } - - - /*************************************************************************/ - /* */ - /* MUL[]: MULtiply */ - /* Opcode range: 0x63 */ - /* Stack: f26.6 f26.6 --> f26.6 */ - /* */ - static - void Ins_MUL( INS_ARG ) - { - DO_MUL - } - - - /*************************************************************************/ - /* */ - /* ABS[]: ABSolute value */ - /* Opcode range: 0x64 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_ABS( INS_ARG ) - { - DO_ABS - } - - - /*************************************************************************/ - /* */ - /* NEG[]: NEGate */ - /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_NEG( INS_ARG ) - { - DO_NEG - } - - - /*************************************************************************/ - /* */ - /* FLOOR[]: FLOOR */ - /* Opcode range: 0x66 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_FLOOR( INS_ARG ) - { - DO_FLOOR - } - - - /*************************************************************************/ - /* */ - /* CEILING[]: CEILING */ - /* Opcode range: 0x67 */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_CEILING( INS_ARG ) - { - DO_CEILING - } - - - /*************************************************************************/ - /* */ - /* RS[]: Read Store */ - /* Opcode range: 0x43 */ - /* Stack: uint32 --> uint32 */ - /* */ - static - void Ins_RS( INS_ARG ) - { - DO_RS - } - - - /*************************************************************************/ - /* */ - /* WS[]: Write Store */ - /* Opcode range: 0x42 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_WS( INS_ARG ) - { - DO_WS - } - - - /*************************************************************************/ - /* */ - /* WCVTP[]: Write CVT in Pixel units */ - /* Opcode range: 0x44 */ - /* Stack: f26.6 uint32 --> */ - /* */ - static - void Ins_WCVTP( INS_ARG ) - { - DO_WCVTP - } - - - /*************************************************************************/ - /* */ - /* WCVTF[]: Write CVT in Funits */ - /* Opcode range: 0x70 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_WCVTF( INS_ARG ) - { - DO_WCVTF - } - - - /*************************************************************************/ - /* */ - /* RCVT[]: Read CVT */ - /* Opcode range: 0x45 */ - /* Stack: uint32 --> f26.6 */ - /* */ - static - void Ins_RCVT( INS_ARG ) - { - DO_RCVT - } - - - /*************************************************************************/ - /* */ - /* AA[]: Adjust Angle */ - /* Opcode range: 0x7F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_AA( INS_ARG ) - { - /* intentionally no longer supported */ - } - - - /*************************************************************************/ - /* */ - /* DEBUG[]: DEBUG. Unsupported. */ - /* Opcode range: 0x4F */ - /* Stack: uint32 --> */ - /* */ - /* Note: The original instruction pops a value from the stack. */ - /* */ - static - void Ins_DEBUG( INS_ARG ) - { - DO_DEBUG - } - - - /*************************************************************************/ - /* */ - /* ROUND[ab]: ROUND value */ - /* Opcode range: 0x68-0x6B */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_ROUND( INS_ARG ) - { - DO_ROUND - } - - - /*************************************************************************/ - /* */ - /* NROUND[ab]: No ROUNDing of value */ - /* Opcode range: 0x6C-0x6F */ - /* Stack: f26.6 --> f26.6 */ - /* */ - static - void Ins_NROUND( INS_ARG ) - { - DO_NROUND - } - - - /*************************************************************************/ - /* */ - /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ - /* Stack: int32? int32? --> int32 */ - /* */ - static - void Ins_MAX( INS_ARG ) - { - DO_MAX - } - - - /*************************************************************************/ - /* */ - /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ - /* 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 */ - /* Opcode range: 0x26 */ - /* Stack: int32? --> StkElt */ - /* */ - static - void Ins_MINDEX( INS_ARG ) - { - FT_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 ( FT_Long ) ); - - CUR.stack[CUR.args - 1] = K; - } - - - /*************************************************************************/ - /* */ - /* ROLL[]: ROLL top three elements */ - /* Opcode range: 0x8A */ - /* Stack: 3 * StkElt --> 3 * StkElt */ - /* */ - static - void Ins_ROLL( INS_ARG ) - { - FT_Long A, B, C; - - FT_UNUSED_EXEC; - - - 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 specification's order. */ - /* */ - /*************************************************************************/ - - - static - FT_Bool SkipCode( EXEC_OP ) - { - CUR.IP += CUR.length; - - if ( CUR.IP < CUR.codeSize ) - { - CUR.opcode = CUR.code[CUR.IP]; - - CUR.length = opcode_length[CUR.opcode]; - if ( CUR.length < 0 ) - { - if ( CUR.IP + 1 > CUR.codeSize ) - goto Fail_Overflow; - CUR.length = CUR.code[CUR.IP + 1] + 2; - } - - if ( CUR.IP + CUR.length <= CUR.codeSize ) - return SUCCESS; - } - - Fail_Overflow: - CUR.error = TT_Err_Code_Overflow; - return FAILURE; - } - - - /*************************************************************************/ - /* */ - /* IF[]: IF test */ - /* Opcode range: 0x58 */ - /* Stack: StkElt --> */ - /* */ - static - void Ins_IF( INS_ARG ) - { - FT_Int nIfs; - FT_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 */ - /* Opcode range: 0x1B */ - /* Stack: --> */ - /* */ - static - void Ins_ELSE( INS_ARG ) - { - FT_Int nIfs; - - FT_UNUSED_ARG; - - - 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 specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FDEF[]: Function DEFinition */ - /* Opcode range: 0x2C */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_FDEF( INS_ARG ) - { - FT_ULong n; - TT_DefRecord* rec; - TT_DefRecord* limit; - - - /* some font programs are broken enough to redefine functions! */ - /* We will then parse the current table. */ - - rec = CUR.FDefs; - limit = rec + CUR.numFDefs; - n = args[0]; - - for ( ; rec < limit; rec++ ) - { - if ( rec->opc == n ) - break; - } - - if ( rec == limit ) - { - /* check that there is enough room for new functions */ - if ( CUR.numFDefs >= CUR.maxFDefs ) - { - CUR.error = TT_Err_Too_Many_Function_Defs; - return; - } - CUR.numFDefs++; - } - - rec->range = CUR.curRange; - rec->opc = n; - rec->start = CUR.IP + 1; - rec->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 */ - /* Opcode range: 0x2D */ - /* Stack: --> */ - /* */ - static - void Ins_ENDF( INS_ARG ) - { - TT_CallRec* pRec; - - FT_UNUSED_ARG; - - - 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: If 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 is why we do not test */ - /* the result of Ins_Goto_CodeRange() here! */ - } - - - /*************************************************************************/ - /* */ - /* CALL[]: CALL function */ - /* Opcode range: 0x2B */ - /* Stack: uint32? --> */ - /* */ - static - void Ins_CALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - - F = args[0]; - if ( BOUNDS( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - - /* check the 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; - - Fail: - CUR.error = TT_Err_Invalid_Reference; - } - - - /*************************************************************************/ - /* */ - /* LOOPCALL[]: LOOP and CALL function */ - /* Opcode range: 0x2A */ - /* Stack: uint32? Eint16? --> */ - /* */ - static - void Ins_LOOPCALL( INS_ARG ) - { - FT_ULong F; - TT_CallRec* pCrec; - TT_DefRecord* def; - - - /* first of all, check the index */ - F = args[1]; - if ( BOUNDS( F, CUR.maxFunc + 1 ) ) - goto Fail; - - /* Except for some old Apple fonts, all functions in a TrueType */ - /* font are defined in increasing order, starting from 0. This */ - /* means that we normally have */ - /* */ - /* CUR.maxFunc+1 == CUR.numFDefs */ - /* CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc */ - /* */ - /* If this isn't true, we need to look up the function table. */ - - def = CUR.FDefs + F; - if ( CUR.maxFunc + 1 != CUR.numFDefs || def->opc != F ) - { - /* look up the FDefs table */ - TT_DefRecord* limit; - - - def = CUR.FDefs; - limit = def + CUR.numFDefs; - - while ( def < limit && def->opc != F ) - def++; - - if ( def == limit ) - goto Fail; - } - - /* check that the function is active */ - if ( !def->active ) - goto Fail; - - /* check stack */ - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - if ( args[0] > 0 ) - { - pCrec = CUR.callStack + CUR.callTop; - - pCrec->Caller_Range = CUR.curRange; - pCrec->Caller_IP = CUR.IP + 1; - pCrec->Cur_Count = (FT_Int)args[0]; - pCrec->Cur_Restart = def->start; - - CUR.callTop++; - - INS_Goto_CodeRange( def->range, def->start ); - - CUR.step_ins = FALSE; - } - return; - - Fail: - CUR.error = TT_Err_Invalid_Reference; - } - - - /*************************************************************************/ - /* */ - /* IDEF[]: Instruction DEFinition */ - /* Opcode range: 0x89 */ - /* Stack: Eint8 --> */ - /* */ - static - void Ins_IDEF( INS_ARG ) - { - TT_DefRecord* def; - TT_DefRecord* limit; - - - /* First of all, look for the same function in our table */ - - def = CUR.IDefs; - limit = def + CUR.numIDefs; - - for ( ; def < limit; def++ ) - if ( def->opc == (FT_ULong)args[0] ) - break; - - if ( def == limit ) - { - /* check that there is enough room for a new instruction */ - if ( CUR.numIDefs >= CUR.maxIDefs ) - { - CUR.error = TT_Err_Too_Many_Instruction_Defs; - return; - } - CUR.numIDefs++; - } - - def->opc = args[0]; - def->start = CUR.IP+1; - def->range = CUR.curRange; - def->active = TRUE; - - if ( (FT_ULong)args[0] > CUR.maxIns ) - CUR.maxIns = args[0]; - - /* 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 specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* NPUSHB[]: PUSH N Bytes */ - /* Opcode range: 0x40 */ - /* Stack: --> uint32... */ - /* */ - static - void Ins_NPUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_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 */ - /* Opcode range: 0x41 */ - /* Stack: --> int32... */ - /* */ - static - void Ins_NPUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_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 */ - /* Opcode range: 0xB0-0xB7 */ - /* Stack: --> uint32... */ - /* */ - static - void Ins_PUSHB( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_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 */ - /* Opcode range: 0xB8-0xBF */ - /* Stack: --> int32... */ - /* */ - static - void Ins_PUSHW( INS_ARG ) - { - FT_UShort L, K; - - - L = (FT_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 */ - /* Opcode range: 0x46-0x47 */ - /* Stack: uint32 --> f26.6 */ - /* */ - /* BULLSHIT: Measures from the original glyph must be taken along the */ - /* dual projection vector! */ - /* */ - static void Ins_GC( INS_ARG ) - { - FT_ULong L; - FT_F26Dot6 R; - - - L = (FT_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 */ - /* Opcode range: 0x48 */ - /* Stack: f26.6 uint32 --> */ - /* */ - /* Formula: */ - /* */ - /* OA := OA + ( value - OA.p )/( f.p ) * f */ - /* */ - static - void Ins_SCFS( INS_ARG ) - { - FT_Long K; - FT_UShort L; - - - L = (FT_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 */ - /* Opcode range: 0x49-0x4A */ - /* 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 ) - { - FT_UShort K, L; - FT_F26Dot6 D; - - - K = (FT_UShort)args[1]; - L = (FT_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; - } - 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 */ - /* Opcode range: 0x86-0x87 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_SDPVTL( INS_ARG ) - { - FT_Long A, B, C; - FT_UShort p1, p2; /* was FT_Int in pas type ERROR */ - - - p1 = (FT_UShort)args[1]; - p2 = (FT_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; - } - - { - FT_Vector* v1 = CUR.zp1.org + p2; - FT_Vector* v2 = CUR.zp2.org + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - } - - if ( ( CUR.opcode & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.dualVector ); - - { - FT_Vector* v1 = CUR.zp1.cur + p2; - FT_Vector* v2 = CUR.zp2.cur + p1; - - - A = v1->x - v2->x; - B = v1->y - v2->y; - } - - if ( ( CUR.opcode & 1 ) != 0 ) - { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; - } - - NORMalize( A, B, &CUR.GS.projVector ); - - COMPUTE_Funcs(); - } - - - /*************************************************************************/ - /* */ - /* SZP0[]: Set Zone Pointer 0 */ - /* Opcode range: 0x13 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP0( INS_ARG ) - { - switch ( (FT_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 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP1[]: Set Zone Pointer 1 */ - /* Opcode range: 0x14 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP1( INS_ARG ) - { - switch ( (FT_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 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZP2[]: Set Zone Pointer 2 */ - /* Opcode range: 0x15 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZP2( INS_ARG ) - { - switch ( (FT_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 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* SZPS[]: Set Zone PointerS */ - /* Opcode range: 0x16 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SZPS( INS_ARG ) - { - switch ( (FT_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 = (FT_UShort)args[0]; - CUR.GS.gep1 = (FT_UShort)args[0]; - CUR.GS.gep2 = (FT_UShort)args[0]; - } - - - /*************************************************************************/ - /* */ - /* INSTCTRL[]: INSTruction ConTRoL */ - /* Opcode range: 0x8e */ - /* Stack: int32 int32 --> */ - /* */ - static - void Ins_INSTCTRL( INS_ARG ) - { - FT_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 = - (FT_Byte)( CUR.GS.instruct_control & ~(FT_Byte)K ) | (FT_Byte)L; - } - - - /*************************************************************************/ - /* */ - /* SCANCTRL[]: SCAN ConTRoL */ - /* Opcode range: 0x85 */ - /* Stack: uint32? --> */ - /* */ - static - void Ins_SCANCTRL( INS_ARG ) - { - FT_Int A; - - - /* Get Threshold */ - A = (FT_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 0 - if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A ) - CUR.GS.scan_control = TRUE; -#endif - - if ( (args[0] & 0x200) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = TRUE; - - if ( (args[0] & 0x400) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = TRUE; - -#if 0 - if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A ) - CUR.GS.scan_control = FALSE; -#endif - - if ( (args[0] & 0x1000) != 0 && CUR.tt_metrics.rotated ) - CUR.GS.scan_control = FALSE; - - if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched ) - CUR.GS.scan_control = FALSE; -} - - - /*************************************************************************/ - /* */ - /* SCANTYPE[]: SCAN TYPE */ - /* Opcode range: 0x8D */ - /* 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 = (FT_Int)args[0]; - } - } - - - /*************************************************************************/ - /* */ - /* MANAGING OUTLINES */ - /* */ - /* Instructions appear in the specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* FLIPPT[]: FLIP PoinT */ - /* Opcode range: 0x80 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_FLIPPT( INS_ARG ) - { - FT_UShort point; - - FT_UNUSED_ARG; - - - if ( CUR.top < CUR.GS.loop ) - { - CUR.error = TT_Err_Too_Few_Arguments; - return; - } - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_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.tags[point] ^= FT_Curve_Tag_On; - - CUR.GS.loop--; - } - - CUR.GS.loop = 1; - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGON[]: FLIP RanGe ON */ - /* Opcode range: 0x81 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_FLIPRGON( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_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.tags[I] |= FT_Curve_Tag_On; - } - - - /*************************************************************************/ - /* */ - /* FLIPRGOFF: FLIP RanGe OFF */ - /* Opcode range: 0x82 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_FLIPRGOFF( INS_ARG ) - { - FT_UShort I, K, L; - - - K = (FT_UShort)args[1]; - L = (FT_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.tags[I] &= ~FT_Curve_Tag_On; - } - - - static - FT_Bool Compute_Point_Displacement( EXEC_OP_ FT_F26Dot6* x, - FT_F26Dot6* y, - TT_GlyphZone* zone, - FT_UShort* refp ) - { - TT_GlyphZone zp; - FT_UShort p; - FT_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_Reference; - return FAILURE; - } - - *zone = zp; - *refp = p; - - d = CUR_Func_project( zp.cur + p, zp.org + p ); - -#ifdef NO_APPLE_PATENT - - *x = TT_MULDIV( d, CUR.GS.freeVector.x, 0x4000 ); - *y = TT_MULDIV( d, CUR.GS.freeVector.y, 0x4000 ); - -#else - - *x = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.x * 0x10000L, - CUR.F_dot_P ); - *y = TT_MULDIV( d, - (FT_Long)CUR.GS.freeVector.y * 0x10000L, - CUR.F_dot_P ); - -#endif /* NO_APPLE_PATENT */ - - return SUCCESS; - } - - - static - void Move_Zp2_Point( EXEC_OP_ FT_UShort point, - FT_F26Dot6 dx, - FT_F26Dot6 dy, - FT_Bool touch ) - { - if ( CUR.GS.freeVector.x != 0 ) - { - CUR.zp2.cur[point].x += dx; - if ( touch ) - CUR.zp2.tags[point] |= FT_Curve_Tag_Touch_X; - } - - if ( CUR.GS.freeVector.y != 0 ) - { - CUR.zp2.cur[point].y += dy; - if ( touch ) - CUR.zp2.tags[point] |= FT_Curve_Tag_Touch_Y; - } - } - - - /*************************************************************************/ - /* */ - /* SHP[a]: SHift Point by the last point */ - /* Opcode range: 0x32-0x33 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_SHP( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - - FT_F26Dot6 dx, - dy; - FT_UShort point; - - FT_UNUSED_ARG; - - - 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 = (FT_UShort)CUR.stack[CUR.args]; - - if ( BOUNDS( point, CUR.zp2.n_points ) ) - { - if ( CUR.pedantic_hinting ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - } - else - /* XXX: 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 */ - /* Opcode range: 0x34-35 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SHC( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - FT_F26Dot6 dx, - dy; - - FT_Short contour; - FT_UShort first_point, last_point, i; - - - contour = (FT_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; - } - - /* XXX: 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 */ - /* Opcode range: 0x36-37 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_SHZ( INS_ARG ) - { - TT_GlyphZone zp; - FT_UShort refp; - FT_F26Dot6 dx, - dy; - - FT_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; - - /* XXX: 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 */ - /* Opcode range: 0x38 */ - /* Stack: f26.6 uint32... --> */ - /* */ - static - void Ins_SHPIX( INS_ARG ) - { - FT_F26Dot6 dx, dy; - FT_UShort point; - - - if ( CUR.top < CUR.GS.loop + 1 ) - { - CUR.error = TT_Err_Invalid_Reference; - return; - } - - dx = TT_MULDIV( args[0], - (FT_Long)CUR.GS.freeVector.x, - 0x4000 ); - dy = TT_MULDIV( args[0], - (FT_Long)CUR.GS.freeVector.y, - 0x4000 ); - - while ( CUR.GS.loop > 0 ) - { - CUR.args--; - - point = (FT_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 Position */ - /* Opcode range: 0x3A-0x3B */ - /* Stack: f26.6 uint32 --> */ - /* */ - static - void Ins_MSIRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - - - point = (FT_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 */ - /* Opcode range: 0x2E-0x2F */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_MDAP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 cur_dist, - distance; - - - point = (FT_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.tt_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 */ - /* Opcode range: 0x3E-0x3F */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_MIAP( INS_ARG ) - { - FT_ULong cvtEntry; - FT_UShort point; - FT_F26Dot6 distance, - org_dist; - - - cvtEntry = (FT_ULong)args[1]; - point = (FT_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 */ - /* specification. */ - /* */ - /* 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, 0x4000 ); - CUR.zp0.org[point].y = TT_MULDIV( CUR.GS.freeVector.y, - distance, 0x4000 ); - 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.tt_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 */ - /* Opcode range: 0xC0-0xDF */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_MDRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 org_dist, distance; - - - point = (FT_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.tt_metrics.compensations[CUR.opcode & 3] ); - else - distance = ROUND_None( - org_dist, - CUR.tt_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 */ - /* Opcode range: 0xE0-0xFF */ - /* Stack: int32? uint32 --> */ - /* */ - static - void Ins_MIRP( INS_ARG ) - { - FT_UShort point; - FT_ULong cvtEntry; - - FT_F26Dot6 cvt_dist, - distance, - cur_dist, - org_dist; - - - point = (FT_UShort)args[0]; - cvtEntry = (FT_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.tt_metrics.compensations[CUR.opcode & 3] ); - } - else - distance = ROUND_None( - cvt_dist, - CUR.tt_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; - - /* XXX: UNDOCUMENTED! */ - - CUR.GS.rp2 = point; - } - - - /*************************************************************************/ - /* */ - /* ALIGNRP[]: ALIGN Relative Point */ - /* Opcode range: 0x3C */ - /* Stack: uint32 uint32... --> */ - /* */ - static - void Ins_ALIGNRP( INS_ARG ) - { - FT_UShort point; - FT_F26Dot6 distance; - - FT_UNUSED_ARG; - - - 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 = (FT_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 */ - /* Opcode range: 0x0F */ - /* Stack: 5 * uint32 --> */ - /* */ - static - void Ins_ISECT( INS_ARG ) - { - FT_UShort point, - a0, a1, - b0, b1; - - FT_F26Dot6 discriminant; - - FT_F26Dot6 dx, dy, - dax, day, - dbx, dby; - - FT_F26Dot6 val; - - FT_Vector R; - - - point = (FT_UShort)args[0]; - - a0 = (FT_UShort)args[1]; - a1 = (FT_UShort)args[2]; - b0 = (FT_UShort)args[3]; - b1 = (FT_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.tags[point] |= FT_Curve_Tag_Touch_Both; - - discriminant = TT_MULDIV( dax, -dby, 0x40 ) + - TT_MULDIV( day, dbx, 0x40 ); - - if ( ABS( discriminant ) >= 0x40 ) - { - val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 ); - - 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 */ - /* Opcode range: 0x27 */ - /* Stack: uint32 uint32 --> */ - /* */ - static - void Ins_ALIGNPTS( INS_ARG ) - { - FT_UShort p1, p2; - FT_F26Dot6 distance; - - - p1 = (FT_UShort)args[0]; - p2 = (FT_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 */ - /* Opcode range: 0x39 */ - /* Stack: uint32... --> */ - /* */ - static - void Ins_IP( INS_ARG ) - { - FT_F26Dot6 org_a, org_b, org_x, - cur_a, cur_b, cur_x, - distance; - FT_UShort point; - - FT_UNUSED_ARG; - - - 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 = (FT_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 */ - /* Opcode range: 0x29 */ - /* Stack: uint32 --> */ - /* */ - static - void Ins_UTP( INS_ARG ) - { - FT_UShort point; - FT_Byte mask; - - - point = (FT_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 &= ~FT_Curve_Tag_Touch_X; - - if ( CUR.GS.freeVector.y != 0 ) - mask &= ~FT_Curve_Tag_Touch_Y; - - CUR.zp0.tags[point] &= mask; - } - - - /* Local variables for Ins_IUP: */ - struct LOC_Ins_IUP - { - FT_Vector* orgs; /* original and current coordinate */ - FT_Vector* curs; /* arrays */ - }; - - - static - void Shift( FT_UInt p1, - FT_UInt p2, - FT_UInt p, - struct LOC_Ins_IUP* LINK ) - { - FT_UInt i; - FT_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( FT_UInt p1, - FT_UInt p2, - FT_UInt ref1, - FT_UInt ref2, - struct LOC_Ins_IUP* LINK ) - { - FT_UInt i; - FT_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 */ - /* Opcode range: 0x30-0x31 */ - /* Stack: --> */ - /* */ - static - void Ins_IUP( INS_ARG ) - { - struct LOC_Ins_IUP V; - FT_Byte mask; - - FT_UInt first_point; /* first point of contour */ - FT_UInt end_point; /* end point (last+1) of contour */ - - FT_UInt first_touched; /* first touched point in contour */ - FT_UInt cur_touched; /* current touched point in contour */ - - FT_UInt point; /* current point */ - FT_Short contour; /* current contour */ - - FT_UNUSED_ARG; - - - if ( CUR.opcode & 1 ) - { - mask = FT_Curve_Tag_Touch_X; - V.orgs = CUR.pts.org; - V.curs = CUR.pts.cur; - } - else - { - mask = FT_Curve_Tag_Touch_Y; - V.orgs = (FT_Vector*)( (FT_Pos*)CUR.pts.org + 1 ); - V.curs = (FT_Vector*)( (FT_Pos*)CUR.pts.cur + 1 ); - } - - contour = 0; - point = 0; - - do - { - end_point = CUR.pts.contours[contour]; - first_point = point; - - while ( point <= end_point && (CUR.pts.tags[point] & mask) == 0 ) - point++; - - if ( point <= end_point ) - { - first_touched = point; - cur_touched = point; - - point++; - - while ( point <= end_point ) - { - if ( ( CUR.pts.tags[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( (FT_UShort)( 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 */ - /* Opcode range: 0x5D,0x71,0x72 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static - void Ins_DELTAP( INS_ARG ) - { - FT_ULong k, nump; - FT_UShort A; - FT_ULong C; - FT_Long B; - - - nump = (FT_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 = (FT_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 = ( (FT_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() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 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 */ - /* Opcode range: 0x73,0x74,0x75 */ - /* Stack: uint32 (2 * uint32)... --> */ - /* */ - static - void Ins_DELTAC( INS_ARG ) - { - FT_ULong nump, k; - FT_ULong A, C; - FT_Long B; - - - nump = (FT_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 = (FT_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 = ( (FT_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() == (FT_Long)C ) - { - B = ( (FT_ULong)B & 0xF ) - 8; - if ( B >= 0 ) - B++; - B = B * 64 / ( 1L << CUR.GS.delta_shift ); - - CUR_Func_move_cvt( A, B ); - } - } - } - - CUR.new_top = CUR.args; - } - - - /*************************************************************************/ - /* */ - /* MISC. INSTRUCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* GETINFO[]: GET INFOrmation */ - /* Opcode range: 0x88 */ - /* 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 ) - { - FT_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.tt_metrics.rotated ) - K |= 0x80; - - /* Has the glyph been stretched ? */ - if ( CUR.tt_metrics.stretched ) - K |= 0x100; - - args[0] = K; - } - - - static - void Ins_UNKNOWN( INS_ARG ) - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - FT_UNUSED_ARG; - - - for ( ; def < limit; def++ ) - { - if ( def->opc == CUR.opcode && def->active ) - { - TT_CallRec* call; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Stack_Overflow; - return; - } - - call = CUR.callStack + CUR.callTop++; - - call->Caller_Range = CUR.curRange; - call->Caller_IP = CUR.IP+1; - call->Cur_Count = 1; - call->Cur_Restart = def->start; - - 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_0x28 */ 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_0x7B */ Ins_UNKNOWN, - /* RUTG */ Ins_RUTG, - /* RDTG */ Ins_RDTG, - /* SANGW */ Ins_SANGW, - /* AA */ Ins_AA, - - /* FlipPT */ Ins_FLIPPT, - /* FlipRgON */ Ins_FLIPRGON, - /* FlipRgOFF */ Ins_FLIPRGOFF, - /* INS_0x83 */ Ins_UNKNOWN, - /* INS_0x84 */ 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_0x8F */ Ins_UNKNOWN, - - /* INS_0x90 */ Ins_UNKNOWN, - /* INS_0x91 */ Ins_UNKNOWN, - /* INS_0x92 */ Ins_UNKNOWN, - /* INS_0x93 */ Ins_UNKNOWN, - /* INS_0x94 */ Ins_UNKNOWN, - /* INS_0x95 */ Ins_UNKNOWN, - /* INS_0x96 */ Ins_UNKNOWN, - /* INS_0x97 */ Ins_UNKNOWN, - /* INS_0x98 */ Ins_UNKNOWN, - /* INS_0x99 */ Ins_UNKNOWN, - /* INS_0x9A */ Ins_UNKNOWN, - /* INS_0x9B */ Ins_UNKNOWN, - /* INS_0x9C */ Ins_UNKNOWN, - /* INS_0x9D */ Ins_UNKNOWN, - /* INS_0x9E */ Ins_UNKNOWN, - /* INS_0x9F */ Ins_UNKNOWN, - - /* INS_0xA0 */ Ins_UNKNOWN, - /* INS_0xA1 */ Ins_UNKNOWN, - /* INS_0xA2 */ Ins_UNKNOWN, - /* INS_0xA3 */ Ins_UNKNOWN, - /* INS_0xA4 */ Ins_UNKNOWN, - /* INS_0xA5 */ Ins_UNKNOWN, - /* INS_0xA6 */ Ins_UNKNOWN, - /* INS_0xA7 */ Ins_UNKNOWN, - /* INS_0xA8 */ Ins_UNKNOWN, - /* INS_0xA9 */ Ins_UNKNOWN, - /* INS_0xAA */ Ins_UNKNOWN, - /* INS_0xAB */ Ins_UNKNOWN, - /* INS_0xAC */ Ins_UNKNOWN, - /* INS_0xAD */ Ins_UNKNOWN, - /* INS_0xAE */ Ins_UNKNOWN, - /* INS_0xAF */ 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 /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - - /*************************************************************************/ - /* */ - /* 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 */ - /* an 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 specification's order. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_RunIns */ - /* */ - /* */ - /* Executes one or more instruction in the execution context. This */ - /* is the main function of the TrueType opcode interpreter. */ - /* */ - /* */ - /* exec :: A handle to the target execution context. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only the object manager and debugger should call this function. */ - /* */ - /* This function is publicly exported because it is directly */ - /* invoked by the TrueType debugger. */ - /* */ - FT_EXPORT_FUNC( FT_Error ) TT_RunIns( TT_ExecContext exc ) - { - FT_Long ins_counter = 0; /* executed instructions counter */ - - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - cur = *exc; -#endif - - /* set CVT functions */ - CUR.tt_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( (FT_Byte)exc->GS.round_state ); - - do - { - CUR.opcode = CUR.code[CUR.IP]; - - if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 ) - { - if ( CUR.IP + 1 > CUR.codeSize ) - goto LErrorCodeOverflow_; - - CUR.length = CUR.code[CUR.IP + 1] + 2; - } - - if ( CUR.IP + CUR.length > CUR.codeSize ) - goto LErrorCodeOverflow_; - - /* 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 - - { - FT_Long* args = CUR.stack + CUR.args; - FT_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 */ - { - FT_Short AA, BB; - - - AA = (FT_Short)( opcode & 1 ) << 14; - BB = AA ^ (FT_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_ARG_ 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_ARG_ args ); - break; - - case 0x14: /* SZP1 */ - Ins_SZP1( EXEC_ARG_ args ); - break; - - case 0x15: /* SZP2 */ - Ins_SZP2( EXEC_ARG_ args ); - break; - - case 0x16: /* SZPS */ - Ins_SZPS( EXEC_ARG_ 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_ARG_ 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_ARG_ args ); - break; - - case 0x27: /* ALIGNPTS */ - Ins_ALIGNPTS( EXEC_ARG_ args ); - break; - - case 0x28: /* ???? */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x29: /* UTP */ - Ins_UTP( EXEC_ARG_ args ); - break; - - case 0x2A: /* LOOPCALL */ - Ins_LOOPCALL( EXEC_ARG_ args ); - break; - - case 0x2B: /* CALL */ - Ins_CALL( EXEC_ARG_ args ); - break; - - case 0x2C: /* FDEF */ - Ins_FDEF( EXEC_ARG_ args ); - break; - - case 0x2D: /* ENDF */ - Ins_ENDF( EXEC_ARG_ args ); - break; - - case 0x2E: /* MDAP */ - case 0x2F: /* MDAP */ - Ins_MDAP( EXEC_ARG_ args ); - break; - - - case 0x30: /* IUP */ - case 0x31: /* IUP */ - Ins_IUP( EXEC_ARG_ args ); - break; - - case 0x32: /* SHP */ - case 0x33: /* SHP */ - Ins_SHP( EXEC_ARG_ args ); - break; - - case 0x34: /* SHC */ - case 0x35: /* SHC */ - Ins_SHC( EXEC_ARG_ args ); - break; - - case 0x36: /* SHZ */ - case 0x37: /* SHZ */ - Ins_SHZ( EXEC_ARG_ args ); - break; - - case 0x38: /* SHPIX */ - Ins_SHPIX( EXEC_ARG_ args ); - break; - - case 0x39: /* IP */ - Ins_IP( EXEC_ARG_ args ); - break; - - case 0x3A: /* MSIRP */ - case 0x3B: /* MSIRP */ - Ins_MSIRP( EXEC_ARG_ args ); - break; - - case 0x3C: /* AlignRP */ - Ins_ALIGNRP( EXEC_ARG_ args ); - break; - - case 0x3D: /* RTDG */ - DO_RTDG - break; - - case 0x3E: /* MIAP */ - case 0x3F: /* MIAP */ - Ins_MIAP( EXEC_ARG_ args ); - break; - - case 0x40: /* NPUSHB */ - Ins_NPUSHB( EXEC_ARG_ args ); - break; - - case 0x41: /* NPUSHW */ - Ins_NPUSHW( EXEC_ARG_ 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_ARG_ args ); - break; - - case 0x48: /* SCFS */ - Ins_SCFS( EXEC_ARG_ args ); - break; - - case 0x49: /* MD */ - case 0x4A: /* MD */ - Ins_MD( EXEC_ARG_ 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_ARG_ 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_ARG_ 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_ARG_ args ); - break; - - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - Ins_DELTAC( EXEC_ARG_ 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_ARG_ 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_ARG_ args ); - break; - - case 0x81: /* FLIPRGON */ - Ins_FLIPRGON( EXEC_ARG_ args ); - break; - - case 0x82: /* FLIPRGOFF */ - Ins_FLIPRGOFF( EXEC_ARG_ args ); - break; - - case 0x83: /* UNKNOWN */ - case 0x84: /* UNKNOWN */ - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - case 0x85: /* SCANCTRL */ - Ins_SCANCTRL( EXEC_ARG_ args ); - break; - - case 0x86: /* SDPVTL */ - case 0x87: /* SDPVTL */ - Ins_SDPVTL( EXEC_ARG_ args ); - break; - - case 0x88: /* GETINFO */ - Ins_GETINFO( EXEC_ARG_ args ); - break; - - case 0x89: /* IDEF */ - Ins_IDEF( EXEC_ARG_ args ); - break; - - case 0x8A: /* ROLL */ - Ins_ROLL( EXEC_ARG_ args ); - break; - - case 0x8B: /* MAX */ - DO_MAX - break; - - case 0x8C: /* MIN */ - DO_MIN - break; - - case 0x8D: /* SCANTYPE */ - Ins_SCANTYPE( EXEC_ARG_ args ); - break; - - case 0x8E: /* INSTCTRL */ - Ins_INSTCTRL( EXEC_ARG_ args ); - break; - - case 0x8F: - Ins_UNKNOWN( EXEC_ARG_ args ); - break; - - default: - if ( opcode >= 0xE0 ) - Ins_MIRP( EXEC_ARG_ args ); - else if ( opcode >= 0xC0 ) - Ins_MDRP( EXEC_ARG_ args ); - else if ( opcode >= 0xB8 ) - Ins_PUSHW( EXEC_ARG_ args ); - else if ( opcode >= 0xB0 ) - Ins_PUSHB( EXEC_ARG_ args ); - else - Ins_UNKNOWN( EXEC_ARG_ args ); - } - - } - -#else - - Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] ); - -#endif /* TT_CONFIG_OPTION_INTERPRETER_SWITCH */ - - if ( CUR.error != TT_Err_Ok ) - { - switch ( CUR.error ) - { - case TT_Err_Invalid_Opcode: /* looking for redefined instructions */ - { - TT_DefRecord* def = CUR.IDefs; - TT_DefRecord* limit = def + CUR.numIDefs; - - - for ( ; def < limit; def++ ) - { - if ( def->active && CUR.opcode == def->opc ) - { - TT_CallRec* callrec; - - - if ( CUR.callTop >= CUR.callSize ) - { - CUR.error = TT_Err_Invalid_Reference; - goto LErrorLabel_; - } - - callrec = &CUR.callStack[CUR.callTop]; - - callrec->Caller_Range = CUR.curRange; - callrec->Caller_IP = CUR.IP + 1; - callrec->Cur_Count = 1; - callrec->Cur_Restart = def->start; - - if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE ) - goto LErrorLabel_; - - goto LSuiteLabel_; - } - } - } - - CUR.error = TT_Err_Invalid_Opcode; - goto LErrorLabel_; - -#if 0 - break; /* Unreachable code warning suppression. */ - /* Leave to remind in case a later change the editor */ - /* to consider break; */ -#endif - - default: - goto LErrorLabel_; - -#if 0 - break; -#endif - } - } - - 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 ) - return TT_Err_Execution_Too_Long; - - 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_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - return TT_Err_Ok; - - LErrorCodeOverflow_: - CUR.error = TT_Err_Code_Overflow; - - LErrorLabel_: - -#ifdef TT_CONFIG_OPTION_STATIC_RASTER - *exc = cur; -#endif - - return CUR.error; - } - - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttinterp.h b/subsys/win32k/freetype/src/truetype/ttinterp.h deleted file mode 100644 index 3283e02..0000000 --- a/subsys/win32k/freetype/src/truetype/ttinterp.h +++ /dev/null @@ -1,278 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttinterp.h */ -/* */ -/* TrueType bytecode interpreter (specification). */ -/* */ -/* Copyright 1996-2000 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 TTINTERP_H -#define TTINTERP_H - - -#ifdef FT_FLAT_COMPILE - -#include "ttobjs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - -#ifndef TT_CONFIG_OPTION_STATIC_INTEPRETER /* indirect implementation */ - -#define EXEC_OP_ TT_ExecContext exc, -#define EXEC_OP TT_ExecContext exc -#define EXEC_ARG_ exc, -#define EXEC_ARG exc - -#else /* static implementation */ - -#define EXEC_OP_ /* void */ -#define EXEC_OP /* void */ -#define EXEC_ARG_ /* void */ -#define EXEC_ARG /* void */ - -#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */ - - - /*************************************************************************/ - /* */ - /* 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 - - - /*************************************************************************/ - /* */ - /* Function types used by the interpreter, depending on various modes */ - /* (e.g. the rounding mode, whether to render a vertical or horizontal */ - /* line etc). */ - /* */ - /*************************************************************************/ - - /* Rounding function */ - typedef FT_F26Dot6 (*TT_Round_Func)( EXEC_OP_ FT_F26Dot6 distance, - FT_F26Dot6 compensation ); - - /* Point displacement along the freedom vector routine */ - typedef void (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone* zone, - FT_UInt point, - FT_F26Dot6 distance ); - - /* Distance projection along one of the projection vectors */ - typedef FT_F26Dot6 (*TT_Project_Func)( EXEC_OP_ FT_Vector* v1, - FT_Vector* v2 ); - - /* reading a cvt value. Take care of non-square pixels if necessary */ - typedef FT_F26Dot6 (*TT_Get_CVT_Func)( EXEC_OP_ FT_ULong index ); - - /* setting or moving a cvt value. Take care of non-square pixels */ - /* if necessary */ - typedef void (*TT_Set_CVT_Func)( EXEC_OP_ FT_ULong index, - FT_F26Dot6 value ); - - - /*************************************************************************/ - /* */ - /* This structure defines a call record, used to manage function calls. */ - /* */ - typedef struct TT_CallRec_ - { - FT_Int Caller_Range; - FT_Long Caller_IP; - FT_Long Cur_Count; - FT_Long Cur_Restart; - - } TT_CallRec, *TT_CallStack; - - - /*************************************************************************/ - /* */ - /* The main structure for the interpreter which collects all necessary */ - /* variables and states. */ - /* */ - typedef struct TT_ExecContextRec_ - { - TT_Face face; - TT_Size size; - FT_Memory memory; - - /* instructions state */ - - FT_Error error; /* last execution error */ - - FT_Long top; /* top of exec. stack */ - - FT_UInt stackSize; /* size of exec. stack */ - FT_Long* stack; /* current exec. stack */ - - FT_Long args; - FT_UInt new_top; /* new top after exec. */ - - TT_GlyphZone zp0, /* zone records */ - zp1, - zp2, - pts, - twilight; - - FT_Size_Metrics metrics; - TT_Size_Metrics tt_metrics; /* size metrics */ - - TT_GraphicsState GS; /* current graphics state */ - - FT_Int curRange; /* current code range number */ - FT_Byte* code; /* current code range */ - FT_Long IP; /* current instruction pointer */ - FT_Long codeSize; /* size of current range */ - - FT_Byte opcode; /* current opcode */ - FT_Int length; /* length of current opcode */ - - FT_Bool step_ins; /* true if the interpreter must */ - /* increment IP after ins. exec */ - FT_Long cvtSize; - FT_Long* cvt; - - FT_UInt glyphSize; /* glyph instructions buffer size */ - FT_Byte* glyphIns; /* glyph instructions buffer */ - - FT_UInt numFDefs; /* number of function defs */ - FT_UInt maxFDefs; /* maximum number of function defs */ - TT_DefArray FDefs; /* table of FDefs entries */ - - FT_UInt numIDefs; /* number of instruction defs */ - FT_UInt maxIDefs; /* maximum number of ins defs */ - TT_DefArray IDefs; /* table of IDefs entries */ - - FT_UInt maxFunc; /* maximum function index */ - FT_UInt maxIns; /* maximum instruction index */ - - FT_Int callTop, /* top of call stack during execution */ - callSize; /* size of call stack */ - TT_CallStack callStack; /* call stack */ - - FT_UShort maxPoints; /* capacity of this context's `pts' */ - FT_Short maxContours; /* record, expressed in points and */ - /* contours. */ - - TT_CodeRangeTable codeRangeTable; /* table of valid code ranges */ - /* useful for the debugger */ - - FT_UShort storeSize; /* size of current storage */ - FT_Long* storage; /* storage area */ - - FT_F26Dot6 period; /* values used for the */ - FT_F26Dot6 phase; /* `SuperRounding' */ - FT_F26Dot6 threshold; - -#if 0 - /* this seems to be unused */ - FT_Int cur_ppem; /* ppem along the current proj vector */ -#endif - - FT_Bool instruction_trap; /* If `True', the interpreter will */ - /* exit after each instruction */ - - TT_GraphicsState default_GS; /* graphics state resulting from */ - /* the prep program */ - FT_Bool is_composite; /* true if the glyph is composite */ - FT_Bool pedantic_hinting; /* true for pedantic interpretation */ - - /* latest interpreter additions */ - - FT_Long F_dot_P; /* dot product of freedom and projection */ - /* vectors */ - TT_Round_Func func_round; /* current rounding function */ - - TT_Project_Func func_project, /* current projection function */ - func_dualproj, /* current dual proj. function */ - func_freeProj; /* current freedom proj. func */ - - TT_Move_Func func_move; /* current point move function */ - - TT_Get_CVT_Func func_read_cvt; /* read a cvt entry */ - TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ - TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - - FT_ULong loadSize; - TT_SubGlyph_Stack loadStack; /* loading subglyph stack */ - - } TT_ExecContextRec; - - - extern const TT_GraphicsState tt_default_graphics_state; - - - LOCAL_DEF - FT_Error TT_Goto_CodeRange( TT_ExecContext exec, - FT_Int range, - FT_Long IP ); - - LOCAL_DEF - FT_Error TT_Set_CodeRange( TT_ExecContext exec, - FT_Int range, - void* base, - FT_Long length ); - - LOCAL_DEF - FT_Error TT_Clear_CodeRange( TT_ExecContext exec, - FT_Int range ); - - FT_EXPORT_DEF( TT_ExecContext ) TT_New_Context( TT_Face face ); - - LOCAL_DEF - FT_Error TT_Done_Context( TT_ExecContext exec ); - - LOCAL_DEF - FT_Error TT_Destroy_Context( TT_ExecContext exec, - FT_Memory memory ); - - LOCAL_DEF - FT_Error TT_Load_Context( TT_ExecContext exec, - TT_Face face, - TT_Size size ); - - LOCAL_DEF - FT_Error TT_Save_Context( TT_ExecContext exec, - TT_Size ins ); - - LOCAL_DEF - FT_Error TT_Run_Context( TT_ExecContext exec, - FT_Bool debug ); - - FT_EXPORT_DEF( FT_Error ) TT_RunIns( TT_ExecContext exec ); - - -#ifdef __cplusplus - } -#endif - -#endif /* TTINTERP_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttobjs.c b/subsys/win32k/freetype/src/truetype/ttobjs.c deleted file mode 100644 index f19ed79..0000000 --- a/subsys/win32k/freetype/src/truetype/ttobjs.c +++ /dev/null @@ -1,734 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.c */ -/* */ -/* Objects manager (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "ttgload.h" -#include "ttpload.h" - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include "ttinterp.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include - - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttobjs - - - /*************************************************************************/ - /* */ - /* GLYPH ZONE FUNCTIONS */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_GlyphZone */ - /* */ - /* */ - /* Deallocates a glyph zone. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone. */ - /* */ - LOCAL_FUNC - void TT_Done_GlyphZone( TT_GlyphZone* zone ) - { - FT_Memory memory = zone->memory; - - - FREE( zone->contours ); - FREE( zone->tags ); - FREE( zone->cur ); - FREE( zone->org ); - - zone->max_points = zone->n_points = 0; - zone->max_contours = zone->n_contours = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_New_GlyphZone */ - /* */ - /* */ - /* Allocates a new glyph zone. */ - /* */ - /* */ - /* memory :: A handle to the current memory object. */ - /* */ - /* maxPoints :: The capacity of glyph zone in points. */ - /* */ - /* maxContours :: The capacity of glyph zone in contours. */ - /* */ - /* */ - /* zone :: A pointer to the target glyph zone record. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_New_GlyphZone( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone* zone ) - { - FT_Error error; - - - if ( maxPoints > 0 ) - maxPoints += 2; - - MEM_Set( zone, 0, sizeof ( *zone ) ); - zone->memory = memory; - - if ( ALLOC_ARRAY( zone->org, maxPoints * 2, FT_F26Dot6 ) || - ALLOC_ARRAY( zone->cur, maxPoints * 2, FT_F26Dot6 ) || - ALLOC_ARRAY( zone->tags, maxPoints, FT_Byte ) || - ALLOC_ARRAY( zone->contours, maxContours, FT_UShort ) ) - { - TT_Done_GlyphZone( zone ); - } - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Face */ - /* */ - /* */ - /* Initializes a given TrueType face object. */ - /* */ - /* */ - /* stream :: The source font stream. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The newly built face object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Library library; - SFNT_Interface* sfnt; - - - library = face->root.driver->root.library; - sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" ); - if ( !sfnt ) - goto Bad_Format; - - /* create input stream from resource */ - if ( FILE_Seek( 0 ) ) - goto Exit; - - /* check that we have a valid TrueType file */ - error = sfnt->init_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - /* We must also be able to accept Mac/GX fonts, as well as OT ones */ - if ( face->format_tag != 0x00010000L && /* MS fonts */ - face->format_tag != TTAG_true ) /* Mac fonts */ - { - FT_TRACE2(( "[not a valid TTF font]\n" )); - goto Bad_Format; - } - - /* If we are performing a simple font format check, exit immediately */ - if ( face_index < 0 ) - return TT_Err_Ok; - - /* Load font directory */ - error = sfnt->load_face( stream, face, face_index, num_params, params ); - if ( error ) - goto Exit; - - error = TT_Load_Locations( face, stream ) || - TT_Load_CVT ( face, stream ) || - TT_Load_Programs ( face, stream ); - - /* initialize standard glyph loading routines */ - TT_Init_Glyph_Loading( face ); - - Exit: - return error; - - Bad_Format: - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Face */ - /* */ - /* */ - /* Finalizes a given face object. */ - /* */ - /* */ - /* face :: A pointer to the face object to destroy. */ - /* */ - LOCAL_DEF - void TT_Done_Face( TT_Face face ) - { - FT_Memory memory = face->root.memory; - FT_Stream stream = face->root.stream; - - SFNT_Interface* sfnt = (SFNT_Interface*)face->sfnt; - - - /* for `extended TrueType formats' (i.e. compressed versions) */ - if ( face->extra.finalizer ) - face->extra.finalizer( face->extra.data ); - - if ( sfnt ) - sfnt->done_face( face ); - - /* freeing the locations table */ - FREE( face->glyph_locations ); - face->num_locations = 0; - - /* freeing the CVT */ - FREE( face->cvt ); - face->cvt_size = 0; - - /* freeing the programs */ - RELEASE_Frame( face->font_program ); - RELEASE_Frame( face->cvt_program ); - face->font_program_size = 0; - face->cvt_program_size = 0; - } - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Size */ - /* */ - /* */ - /* Initializes a new TrueType size object. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Size( TT_Size size ) - { - FT_Error error = TT_Err_Ok; - - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - TT_Face face = (TT_Face)size->root.face; - FT_Memory memory = face->root.memory; - FT_Int i; - - TT_ExecContext exec; - FT_UShort n_twilight; - TT_MaxProfile* maxp = &face->max_profile; - - - size->ttmetrics.valid = FALSE; - - size->max_function_defs = maxp->maxFunctionDefs; - size->max_instruction_defs = maxp->maxInstructionDefs; - - size->num_function_defs = 0; - size->num_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - - size->cvt_size = face->cvt_size; - size->storage_size = maxp->maxStorage; - - /* Set default metrics */ - { - FT_Size_Metrics* metrics = &size->root.metrics; - TT_Size_Metrics* metrics2 = &size->ttmetrics; - - - metrics->x_ppem = 0; - metrics->y_ppem = 0; - - metrics2->rotated = FALSE; - metrics2->stretched = FALSE; - - /* set default compensation (all 0) */ - for ( i = 0; i < 4; i++ ) - metrics2->compensations[i] = 0; - } - - /* allocate function defs, instruction defs, cvt, and storage area */ - if ( ALLOC_ARRAY( size->function_defs, - size->max_function_defs, - TT_DefRecord ) || - - ALLOC_ARRAY( size->instruction_defs, - size->max_instruction_defs, - TT_DefRecord ) || - - ALLOC_ARRAY( size->cvt, - size->cvt_size, FT_Long ) || - - ALLOC_ARRAY( size->storage, - size->storage_size, FT_Long ) ) - - goto Fail_Memory; - - /* reserve twilight zone */ - n_twilight = maxp->maxTwilightPoints; - error = TT_New_GlyphZone( memory, n_twilight, 0, &size->twilight ); - if ( error ) - goto Fail_Memory; - - size->twilight.n_points = n_twilight; - - /* set `face->interpreter' according to the debug hook present */ - { - FT_Library library = face->root.driver->root.library; - - - face->interpreter = (TT_Interpreter) - library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; - if ( !face->interpreter ) - face->interpreter = (TT_Interpreter)TT_RunIns; - } - - /* Fine, now execute the font program! */ - exec = size->context; - /* size objects used during debugging have their own context */ - if ( !size->debug ) - exec = TT_New_Context( face ); - - if ( !exec ) - { - error = TT_Err_Could_Not_Find_Context; - goto Fail_Memory; - } - - size->GS = tt_default_graphics_state; - TT_Load_Context( exec, face, size ); - - exec->callTop = 0; - exec->top = 0; - - exec->period = 64; - exec->phase = 0; - exec->threshold = 0; - - { - FT_Size_Metrics* metrics = &exec->metrics; - TT_Size_Metrics* tt_metrics = &exec->tt_metrics; - - - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics->x_scale = 0; - metrics->y_scale = 0; - - tt_metrics->ppem = 0; - tt_metrics->scale = 0; - tt_metrics->ratio = 0x10000L; - } - - exec->instruction_trap = FALSE; - - exec->cvtSize = size->cvt_size; - exec->cvt = size->cvt; - - exec->F_dot_P = 0x10000L; - - /* allow font program execution */ - TT_Set_CodeRange( exec, - tt_coderange_font, - face->font_program, - face->font_program_size ); - - /* disable CVT and glyph programs coderange */ - TT_Clear_CodeRange( exec, tt_coderange_cvt ); - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - if ( face->font_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); - if ( !error ) - error = face->interpreter( exec ); - - if ( error ) - goto Fail_Exec; - } - else - error = TT_Err_Ok; - - TT_Save_Context( exec, size ); - - if ( !size->debug ) - TT_Done_Context( exec ); - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - size->ttmetrics.valid = FALSE; - return error; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - Fail_Exec: - if ( !size->debug ) - TT_Done_Context( exec ); - - Fail_Memory: - -#endif - - TT_Done_Size( size ); - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Size */ - /* */ - /* */ - /* The TrueType size object finalizer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void TT_Done_Size( TT_Size size ) - { - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - FT_Memory memory = size->root.face->memory; - - - if ( size->debug ) - { - /* the debug context must be deleted by the debugger itself */ - size->context = NULL; - size->debug = FALSE; - } - - FREE( size->cvt ); - size->cvt_size = 0; - - /* free storage area */ - FREE( size->storage ); - size->storage_size = 0; - - /* twilight zone */ - TT_Done_GlyphZone( &size->twilight ); - - FREE( size->function_defs ); - FREE( size->instruction_defs ); - - size->num_function_defs = 0; - size->max_function_defs = 0; - size->num_instruction_defs = 0; - size->max_instruction_defs = 0; - - size->max_func = 0; - size->max_ins = 0; - -#endif - - size->ttmetrics.valid = FALSE; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Reset_Size */ - /* */ - /* */ - /* Resets a TrueType size when resolutions and character dimensions */ - /* have been changed. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_DEF - FT_Error TT_Reset_Size( TT_Size size ) - { - TT_Face face; - FT_Error error = TT_Err_Ok; - - FT_Size_Metrics* metrics; - - - if ( size->ttmetrics.valid ) - return TT_Err_Ok; - - face = (TT_Face)size->root.face; - - metrics = &size->root.metrics; - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return TT_Err_Invalid_PPem; - - /* compute new transformation */ - if ( metrics->x_ppem >= metrics->y_ppem ) - { - size->ttmetrics.scale = metrics->x_scale; - size->ttmetrics.ppem = metrics->x_ppem; - size->ttmetrics.x_ratio = 0x10000L; - size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, - 0x10000L, - metrics->x_ppem ); - } - else - { - size->ttmetrics.scale = metrics->y_scale; - size->ttmetrics.ppem = metrics->y_ppem; - size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, - 0x10000L, - metrics->y_ppem ); - size->ttmetrics.y_ratio = 0x10000L; - } - - /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - { - TT_ExecContext exec; - FT_UInt i, j; - - - /* Scale the cvt values to the new ppem. */ - /* We use by default the y ppem to scale the CVT. */ - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - - /* All twilight points are originally zero */ - for ( j = 0; j < size->twilight.n_points; j++ ) - { - size->twilight.org[j].x = 0; - size->twilight.org[j].y = 0; - size->twilight.cur[j].x = 0; - size->twilight.cur[j].y = 0; - } - - /* clear storage area */ - for ( i = 0; i < size->storage_size; i++ ) - size->storage[i] = 0; - - size->GS = tt_default_graphics_state; - - /* get execution context and run prep program */ - if ( size->debug ) - exec = size->context; - else - exec = TT_New_Context( face ); - /* debugging instances have their own context */ - - if ( !exec ) - return TT_Err_Could_Not_Find_Context; - - TT_Load_Context( exec, face, size ); - - TT_Set_CodeRange( exec, - tt_coderange_cvt, - face->cvt_program, - face->cvt_program_size ); - - TT_Clear_CodeRange( exec, tt_coderange_glyph ); - - exec->instruction_trap = FALSE; - - exec->top = 0; - exec->callTop = 0; - - if ( face->cvt_program_size > 0 ) - { - error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); - if ( error ) - goto End; - - if ( !size->debug ) - error = face->interpreter( exec ); - } - else - error = TT_Err_Ok; - - size->GS = exec->GS; - /* save default graphics state */ - - End: - TT_Save_Context( exec, size ); - - if ( !size->debug ) - TT_Done_Context( exec ); - /* debugging instances keep their context */ - } - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - if ( !error ) - size->ttmetrics.valid = TRUE; - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Init_Driver */ - /* */ - /* */ - /* Initializes a given TrueType driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Init_Driver( TT_Driver driver ) - { - FT_Error error; - - - /* set `extra' in glyph loader */ - error = FT_GlyphLoader_Create_Extra( FT_DRIVER( driver )->glyph_loader ); - - /* init extension registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - if ( !error ) - return TT_Init_Extensions( driver ); -#endif - - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Done_Driver */ - /* */ - /* */ - /* Finalizes a given TrueType driver. */ - /* */ - /* */ - /* driver :: A handle to the target TrueType driver. */ - /* */ - LOCAL_FUNC - void TT_Done_Driver( TT_Driver driver ) - { - /* destroy extensions registry if needed */ - -#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE - - TT_Done_Extensions( driver ); - -#endif - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - /* destroy the execution context */ - if ( driver->context ) - { - TT_Destroy_Context( driver->context, driver->root.root.memory ); - driver->context = NULL; - } - -#endif - - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttobjs.h b/subsys/win32k/freetype/src/truetype/ttobjs.h deleted file mode 100644 index 3e55de3..0000000 --- a/subsys/win32k/freetype/src/truetype/ttobjs.h +++ /dev/null @@ -1,412 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttobjs.h */ -/* */ -/* Objects manager (specification). */ -/* */ -/* Copyright 1996-2000 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 -#include -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Driver */ - /* */ - /* */ - /* A handle to a TrueType driver object. */ - /* */ - typedef struct TT_DriverRec_* TT_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Instance */ - /* */ - /* */ - /* A handle to a TrueType size object. */ - /* */ - typedef struct TT_SizeRec_* TT_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GlyphSlot */ - /* */ - /* */ - /* A handle to a TrueType glyph slot object. */ - /* */ - /* */ - /* This is a direct typedef of FT_GlyphSlot, as there is nothing */ - /* specific about the TrueType glyph slot. */ - /* */ - typedef FT_GlyphSlot TT_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* TT_GraphicsState */ - /* */ - /* */ - /* The TrueType graphics state used during bytecode interpretation. */ - /* */ - typedef struct TT_GraphicsState_ - { - FT_UShort rp0; - FT_UShort rp1; - FT_UShort rp2; - - FT_UnitVector dualVector; - FT_UnitVector projVector; - FT_UnitVector freeVector; - - FT_Long loop; - FT_F26Dot6 minimum_distance; - FT_Int round_state; - - FT_Bool auto_flip; - FT_F26Dot6 control_value_cutin; - FT_F26Dot6 single_width_cutin; - FT_F26Dot6 single_width_value; - FT_Short delta_base; - FT_Short delta_shift; - - FT_Byte instruct_control; - FT_Bool scan_control; - FT_Int scan_type; - - FT_UShort gep0; - FT_UShort gep1; - FT_UShort gep2; - - } TT_GraphicsState; - - - LOCAL_DEF void TT_Done_GlyphZone( TT_GlyphZone* zone ); - - LOCAL_DEF FT_Error TT_New_GlyphZone( FT_Memory memory, - FT_UShort maxPoints, - FT_Short maxContours, - TT_GlyphZone* zone ); - - - /*************************************************************************/ - /* */ - /* EXECUTION SUBTABLES */ - /* */ - /* These sub-tables relate to instruction execution. */ - /* */ - /*************************************************************************/ - - -#define TT_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 */ - /* */ - typedef enum TT_CodeRange_Tag_ - { - tt_coderange_none = 0, - tt_coderange_font, - tt_coderange_cvt, - tt_coderange_glyph - - } TT_CodeRange_Tag; - - - typedef struct TT_CodeRange_ - { - FT_Byte* base; - FT_ULong size; - - } TT_CodeRange; - - typedef TT_CodeRange TT_CodeRangeTable[TT_MAX_CODE_RANGES]; - - - /*************************************************************************/ - /* */ - /* Defines a function/instruction definition record. */ - /* */ - typedef struct TT_DefRecord_ - { - FT_Int range; /* in which code range is it located? */ - FT_Long start; /* where does it start? */ - FT_UInt opc; /* function #, or instruction code */ - FT_Bool active; /* is it active? */ - - } TT_DefRecord, *TT_DefArray; - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct TT_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } TT_Transform; - - - /*************************************************************************/ - /* */ - /* Subglyph loading record. Used to load composite components. */ - /* */ - typedef struct TT_SubglyphRec_ - { - FT_Long index; /* subglyph index; initialized with -1 */ - FT_Bool is_scaled; /* is the subglyph scaled? */ - FT_Bool is_hinted; /* should it be hinted? */ - FT_Bool preserve_pps; /* preserve phantom points? */ - - FT_Long file_offset; - - FT_BBox bbox; - FT_Pos left_bearing; - FT_Pos advance; - - TT_GlyphZone zone; - - FT_Long arg1; /* first argument */ - FT_Long arg2; /* second argument */ - - FT_UShort element_flag; /* current load element flag */ - - TT_Transform transform; /* transformation matrix */ - - FT_Vector pp1, pp2; /* phantom points */ - - } TT_SubGlyphRec, *TT_SubGlyph_Stack; - - - /*************************************************************************/ - /* */ - /* A note regarding non-squared pixels: */ - /* */ - /* (This text will probably go into some docs at some time; for now, it */ - /* is kept here 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, some others are used under 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, */ - /* ratio = 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 TrueType size and context objects. */ - /* */ - typedef struct TT_Size_Metrics_ - { - /* for non-square pixels */ - FT_Long x_ratio; - FT_Long y_ratio; - - FT_UShort ppem; /* maximum ppem size */ - FT_Long ratio; /* current ratio */ - FT_Fixed scale; - - FT_F26Dot6 compensations[4]; /* device-specific compensations */ - - FT_Bool valid; - - FT_Bool rotated; /* `is the glyph rotated?'-flag */ - FT_Bool stretched; /* `is the glyph stretched?'-flag */ - - } TT_Size_Metrics; - - - /*************************************************************************/ - /* */ - /* TrueType size class. */ - /* */ - typedef struct TT_SizeRec_ - { - FT_SizeRec root; - - TT_Size_Metrics ttmetrics; - -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - FT_UInt num_function_defs; /* number of function definitions */ - FT_UInt max_function_defs; - TT_DefArray function_defs; /* table of function definitions */ - - FT_UInt num_instruction_defs; /* number of ins. definitions */ - FT_UInt max_instruction_defs; - TT_DefArray instruction_defs; /* table of ins. definitions */ - - FT_UInt max_func; - FT_UInt max_ins; - - TT_CodeRangeTable codeRangeTable; - - TT_GraphicsState GS; - - FT_ULong cvt_size; /* the scaled control value table */ - FT_Long* cvt; - - FT_UShort storage_size; /* The storage area is now part of */ - FT_Long* storage; /* the instance */ - - TT_GlyphZone 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. */ - - FT_Bool debug; - TT_ExecContext context; - -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - - } TT_SizeRec; - - - /*************************************************************************/ - /* */ - /* TrueType driver class. */ - /* */ - typedef struct TT_DriverRec_ - { - FT_DriverRec root; - TT_ExecContext context; /* execution context */ - TT_GlyphZone zone; /* glyph loader points zone */ - - void* extension_component; - - } TT_DriverRec; - - - /*************************************************************************/ - /* */ - /* Face functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Face( FT_Stream stream, - TT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void TT_Done_Face( TT_Face face ); - - - /*************************************************************************/ - /* */ - /* Size functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Size( TT_Size size ); - - LOCAL_DEF - void TT_Done_Size( TT_Size size ); - - LOCAL_DEF - FT_Error TT_Reset_Size( TT_Size size ); - - - /*************************************************************************/ - /* */ - /* Driver functions */ - /* */ - LOCAL_DEF - FT_Error TT_Init_Driver( TT_Driver driver ); - - LOCAL_DEF - void TT_Done_Driver( TT_Driver driver ); - - -#ifdef __cplusplus - } -#endif - -#endif /* TTOBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttpload.c b/subsys/win32k/freetype/src/truetype/ttpload.c deleted file mode 100644 index b4f6d31..0000000 --- a/subsys/win32k/freetype/src/truetype/ttpload.c +++ /dev/null @@ -1,273 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType glyph data/program tables loader (body). */ -/* */ -/* Copyright 1996-2000 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 - -#ifdef FT_FLAT_COMPILE -#include "ttpload.h" -#else -#include -#endif - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_ttpload - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Locations */ - /* */ - /* */ - /* Loads the locations table. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Locations( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Short LongOffsets; - FT_ULong table_len; - - - FT_TRACE2(( "Locations " )); - LongOffsets = face->header.Index_To_Loc_Format; - - error = face->goto_table( face, TTAG_loca, stream, &table_len ); - if ( error ) - { - error = TT_Err_Locations_Missing; - goto Exit; - } - - if ( LongOffsets != 0 ) - { - face->num_locations = (FT_UShort)( table_len >> 2 ); - - FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations )); - - if ( ALLOC_ARRAY( face->glyph_locations, - face->num_locations, - FT_Long ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_locations * 4L ) ) - goto Exit; - - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = GET_Long(); - } - - FORGET_Frame(); - } - else - { - face->num_locations = (FT_UShort)( table_len >> 1 ); - - FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations )); - - if ( ALLOC_ARRAY( face->glyph_locations, - face->num_locations, - FT_Long ) ) - goto Exit; - - if ( ACCESS_Frame( face->num_locations * 2L ) ) - goto Exit; - { - FT_Long* loc = face->glyph_locations; - FT_Long* limit = loc + face->num_locations; - - - for ( ; loc < limit; loc++ ) - *loc = (FT_Long)( (FT_ULong)GET_UShort() * 2 ); - } - FORGET_Frame(); - } - - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_CVT */ - /* */ - /* */ - /* Loads the control value table into a face object. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_CVT( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_ULong table_len; - - - FT_TRACE2(( "CVT " )); - - error = face->goto_table( face, TTAG_cvt, stream, &table_len ); - if ( error ) - { - FT_TRACE2(( "is missing!\n" )); - - face->cvt_size = 0; - face->cvt = NULL; - error = TT_Err_Ok; - - goto Exit; - } - - face->cvt_size = table_len / 2; - - if ( ALLOC_ARRAY( face->cvt, - face->cvt_size, - FT_Short ) ) - goto Exit; - - if ( ACCESS_Frame( face->cvt_size * 2L ) ) - goto Exit; - - { - FT_Short* cur = face->cvt; - FT_Short* limit = cur + face->cvt_size; - - - for ( ; cur < limit; cur++ ) - *cur = GET_Short(); - } - - FORGET_Frame(); - FT_TRACE2(( "loaded\n" )); - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* TT_Load_Progams */ - /* */ - /* */ - /* Loads the font program and the cvt program. */ - /* */ - /* */ - /* face :: A handle to the target face object. */ - /* */ - /* */ - /* stream :: A handle to the input stream. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error TT_Load_Programs( TT_Face face, - FT_Stream stream ) - { - FT_Error error; - FT_ULong table_len; - - - FT_TRACE2(( "Font program " )); - - /* The font program is optional */ - error = face->goto_table( face, TTAG_fpgm, stream, &table_len ); - if ( error ) - { - face->font_program = NULL; - face->font_program_size = 0; - - FT_TRACE2(( "is missing!\n" )); - } - else - { - face->font_program_size = table_len; - if ( EXTRACT_Frame( table_len, face->font_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size )); - } - - FT_TRACE2(( "Prep program " )); - - error = face->goto_table( face, TTAG_prep, stream, &table_len ); - if ( error ) - { - face->cvt_program = NULL; - face->cvt_program_size = 0; - error = TT_Err_Ok; - - FT_TRACE2(( "is missing!\n" )); - } - else - { - face->cvt_program_size = table_len; - if ( EXTRACT_Frame( table_len, face->cvt_program ) ) - goto Exit; - - FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size )); - } - - Exit: - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/truetype/ttpload.h b/subsys/win32k/freetype/src/truetype/ttpload.h deleted file mode 100644 index 77802a6..0000000 --- a/subsys/win32k/freetype/src/truetype/ttpload.h +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* ttpload.h */ -/* */ -/* TrueType glyph data/program tables loader (specification). */ -/* */ -/* Copyright 1996-2000 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 TTPLOAD_H -#define TTPLOAD_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - LOCAL_DEF - FT_Error TT_Load_Locations( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_CVT( TT_Face face, - FT_Stream stream ); - - LOCAL_DEF - FT_Error TT_Load_Programs( TT_Face face, - FT_Stream stream ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* TTPLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/.cvsignore b/subsys/win32k/freetype/src/type1/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/type1/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/type1/module.mk0 b/subsys/win32k/freetype/src/type1/module.mk0 deleted file mode 100644 index af99eae..0000000 --- a/subsys/win32k/freetype/src/type1/module.mk0 +++ /dev/null @@ -1,6 +0,0 @@ -make_module_list: add_type1_driver - -add_type1_driver: - $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) - diff --git a/subsys/win32k/freetype/src/type1/rules.mk0 b/subsys/win32k/freetype/src/type1/rules.mk0 deleted file mode 100644 index b544446..0000000 --- a/subsys/win32k/freetype/src/type1/rules.mk0 +++ /dev/null @@ -1,74 +0,0 @@ -# -# FreeType 2 Type 1 driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# Type1 driver directory -# -T1_DIR := $(SRC_)type1 -T1_DIR_ := $(T1_DIR)$(SEP) - - -# compilation flags for the driver -# -T1_COMPILE := $(FT_COMPILE) - - -# Type1 driver sources (i.e., C files) -# -T1_DRV_SRC := $(T1_DIR_)t1objs.c \ - $(T1_DIR_)t1load.c \ - $(T1_DIR_)t1parse.c \ - $(T1_DIR_)t1tokens.c \ - $(T1_DIR_)t1driver.c \ - $(T1_DIR_)t1hinter.c \ - $(T1_DIR_)t1afm.c \ - $(T1_DIR_)t1gload.c - -# Type1 driver headers -# -T1_DRV_H := $(T1_DRV_SRC:%.c=%.h) - - -# Type1 driver object(s) -# -# T1_DRV_OBJ_M is used during `multi' builds -# T1_DRV_OBJ_S is used during `single' builds -# -T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) -T1_DRV_OBJ_S := $(OBJ_)type1.$O - -# Type1 driver source file for single build -# -T1_DRV_SRC_S := $(T1_DIR_)type1.c - - -# Type1 driver - single object -# -$(T1_DRV_OBJ_S): $(T1_DRV_SRC_S) $(T1_DRV_SRC) $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $(T1_DRV_SRC_S) - - -# Type1 driver - multiple objects -# -$(OBJ_)%.$O: $(T1_DIR_)%.c $(FREETYPE_H) $(T1_DRV_H) - $(T1_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(T1_DRV_OBJ_S) -DRV_OBJS_M += $(T1_DRV_OBJ_M) - - -# EOF diff --git a/subsys/win32k/freetype/src/type1/t1afm.c b/subsys/win32k/freetype/src/type1/t1afm.c deleted file mode 100644 index 218fbb3..0000000 --- a/subsys/win32k/freetype/src/type1/t1afm.c +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1afm.h" - -#else - -#include - -#endif - - -#include -#include - -#include /* for qsort() */ -#include /* for strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1afm - - - LOCAL_FUNC - void T1_Done_AFM( FT_Memory memory, - T1_AFM* afm ) - { - FREE( afm->kern_pairs ); - afm->num_pairs = 0; - } - - -#undef IS_KERN_PAIR -#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) - -#define IS_ALPHANUM( c ) ( isalnum( c ) || \ - c == '_' || \ - c == '.' ) - - - /* read a glyph name and return the equivalent glyph index */ - static - FT_UInt afm_atoindex( FT_Byte** start, - FT_Byte* limit, - T1_Font* type1 ) - { - FT_Byte* p = *start; - FT_Int len; - FT_UInt result = 0; - char temp[64]; - - - /* skip whitespace */ - while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && - p < limit ) - p++; - *start = p; - - /* now, read glyph name */ - while ( IS_ALPHANUM( *p ) && p < limit ) - p++; - - len = p - *start; - - if ( len > 0 && len < 64 ) - { - FT_Int n; - - - /* copy glyph name to intermediate array */ - MEM_Copy( temp, *start, len ); - temp[len] = 0; - - /* lookup glyph name in face array */ - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 ) - { - result = n; - break; - } - } - } - *start = p; - return result; - } - - - /* read an integer */ - static - int afm_atoi( FT_Byte** start, - FT_Byte* limit ) - { - FT_Byte* p = *start; - int sum = 0; - int sign = 1; - - - /* skip everything that is not a number */ - while ( p < limit && !isdigit( *p ) ) - { - sign = 1; - if ( *p == '-' ) - sign = -1; - - p++; - } - - while ( p < limit && isdigit( *p ) ) - { - sum = sum * 10 + ( *p - '0' ); - p++; - } - *start = p; - - return sum * sign; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - static - int compare_kern_pairs( const void* a, - const void* b ) - { - T1_Kern_Pair* pair1 = (T1_Kern_Pair*)a; - T1_Kern_Pair* pair2 = (T1_Kern_Pair*)b; - - FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); - FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - - - return ( index1 - index2 ); - } - - - /* parse an AFM file -- for now, only read the kerning pairs */ - LOCAL_FUNC - FT_Error T1_Read_AFM( FT_Face t1_face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - FT_Int count = 0; - T1_Kern_Pair* pair; - T1_Font* type1 = &((T1_Face)t1_face)->type1; - T1_AFM* afm = 0; - - - if ( ACCESS_Frame( stream->size ) ) - return error; - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - p = start; - - /* we are now going to count the occurences of `KP' or `KPX' in */ - /* the AFM file */ - count = 0; - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - count++; - } - - /* Actually, kerning pairs are simply optional! */ - if ( count == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( ALLOC( afm, sizeof ( *afm ) ) || - ALLOC_ARRAY( afm->kern_pairs, count, T1_Kern_Pair ) ) - goto Exit; - - /* now, read each kern pair */ - pair = afm->kern_pairs; - afm->num_pairs = count; - - /* save in face object */ - ((T1_Face)t1_face)->afm_data = afm; - - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - { - FT_Byte* q; - - - /* skip keyword (KP or KPX) */ - q = p + 2; - if ( *q == 'X' ) - q++; - - pair->glyph1 = afm_atoindex( &q, limit, type1 ); - pair->glyph2 = afm_atoindex( &q, limit, type1 ); - pair->kerning.x = afm_atoi( &q, limit ); - - pair->kerning.y = 0; - if ( p[2] != 'X' ) - pair->kerning.y = afm_atoi( &q, limit ); - - pair++; - } - } - - /* now, sort the kern pairs according to their glyph indices */ - qsort( afm->kern_pairs, count, sizeof ( T1_Kern_Pair ), - compare_kern_pairs ); - - Exit: - if ( error ) - FREE( afm ); - - FORGET_Frame(); - - return error; - } - - - /* find the kerning for a given glyph pair */ - LOCAL_FUNC - void T1_Get_Kerning( T1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - T1_Kern_Pair *min, *mid, *max; - FT_ULong index = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = afm->kern_pairs; - max = min + afm->num_pairs - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); - - if ( midi == index ) - { - *kerning = mid->kerning; - return; - } - - if ( midi < index ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1afm.h b/subsys/win32k/freetype/src/type1/t1afm.h deleted file mode 100644 index 709154e..0000000 --- a/subsys/win32k/freetype/src/type1/t1afm.h +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* Copyright 1996-2000 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 T1AFM_H -#define T1AFM_H - -#include - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct T1_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; - - } T1_Kern_Pair; - - - typedef struct T1_AFM_ - { - FT_Int num_pairs; - T1_Kern_Pair* kern_pairs; - - } T1_AFM; - - - LOCAL_DEF - FT_Error T1_Read_AFM( FT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void T1_Done_AFM( FT_Memory memory, - T1_AFM* afm ); - - LOCAL_DEF - void T1_Get_Kerning( T1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1AFM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1driver.c b/subsys/win32k/freetype/src/type1/t1driver.c deleted file mode 100644 index c040b00..0000000 --- a/subsys/win32k/freetype/src/type1/t1driver.c +++ /dev/null @@ -1,381 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.c */ -/* */ -/* Type 1 driver interface (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1driver.h" -#include "t1gload.h" -#include "t1afm.h" - -#else - -#include -#include -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1driver - - -#ifndef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - T1_AFM* afm; - - - kerning->x = 0; - kerning->y = 0; - - afm = (T1_AFM*)face->afm_data; - if ( afm ) - T1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); - - return T1_Err_Ok; - } - - -#endif /* T1_CONFIG_OPTION_NO_AFM */ - - - static - FT_Error get_t1_glyph_name( T1_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - - - gname = face->type1.glyph_names[glyph_index]; - - if ( buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if ( len >= buffer_max ) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return T1_Err_Ok; - } - - - static - FT_Module_Interface T1_Get_Interface( FT_Module module, - const char* interface ) - { - FT_UNUSED( module ); - - if ( strcmp( interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_t1_glyph_name; - - return 0; - } - - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Char_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in fractional points. */ - /* */ - /* */ - /* char_width :: The character width expressed in 26.6 */ - /* fractional points. */ - /* */ - /* char_height :: The character height expressed in 26.6 */ - /* fractional points. */ - /* */ - /* horz_resolution :: The horizontal resolution of the output device. */ - /* */ - /* vert_resolution :: The vertical resolution of the output device. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Char_Sizes( T1_Size size, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_UNUSED( char_width ); - FT_UNUSED( char_height ); - FT_UNUSED( horz_resolution ); - FT_UNUSED( vert_resolution ); - - size->valid = FALSE; - - return T1_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Set_Pixel_Sizes */ - /* */ - /* */ - /* A driver method used to reset a size's character sizes (horizontal */ - /* and vertical) expressed in integer pixels. */ - /* */ - /* */ - /* pixel_width :: The character width expressed in integer pixels. */ - /* */ - /* pixel_height :: The character height expressed in integer pixels. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Set_Pixel_Sizes( T1_Size size, - FT_Int pixel_width, - FT_Int pixel_height ) - { - FT_UNUSED( pixel_width ); - FT_UNUSED( pixel_height ); - - size->valid = FALSE; - - return T1_Reset_Size( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) - { - T1_Face face; - FT_UInt result = 0; - PSNames_Interface* psnames; - - - face = (T1_Face)charmap->face; - psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) - { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - } - Exit: - return result; - } - - - - const FT_Driver_Class t1_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( FT_DriverRec ), - - "type1", /* driver name */ - 0x10000L, /* driver version 1.0 */ - 0x20000L, /* driver requires FreeType 2.0 or above */ - - 0, /* module specific interface */ - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) T1_Get_Interface - }, - - sizeof( T1_FaceRec ), - sizeof( T1_SizeRec ), - sizeof( T1_GlyphSlotRec ), - - (FTDriver_initFace) T1_Init_Face, - (FTDriver_doneFace) T1_Done_Face, - (FTDriver_initSize) T1_Init_Size, - (FTDriver_doneSize) T1_Done_Size, - (FTDriver_initGlyphSlot)T1_Init_GlyphSlot, - (FTDriver_doneGlyphSlot)T1_Done_GlyphSlot, - - (FTDriver_setCharSizes) Set_Char_Sizes, - (FTDriver_setPixelSizes)Set_Pixel_Sizes, - (FTDriver_loadGlyph) T1_Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - -#ifdef T1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, -#else - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) T1_Read_AFM, -#endif - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &t1_driver_class; - } - -#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1driver.h b/subsys/win32k/freetype/src/type1/t1driver.h deleted file mode 100644 index 5d615b5..0000000 --- a/subsys/win32k/freetype/src/type1/t1driver.h +++ /dev/null @@ -1,30 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1driver.h */ -/* */ -/* High-level Type 1 driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 T1DRIVER_H -#define T1DRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class; - - -#endif /* T1DRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1gload.c b/subsys/win32k/freetype/src/type1/t1gload.c deleted file mode 100644 index 5363257..0000000 --- a/subsys/win32k/freetype/src/type1/t1gload.c +++ /dev/null @@ -1,1823 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.c */ -/* */ -/* Type 1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "t1gload.h" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1gload - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - void T1_Reset_Builder( T1_Builder* builder, - FT_Bool reset_base ) - { - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - - builder->pass = 0; - builder->hint_point = 0; - - if ( builder->loader ) - { - if ( reset_base ) - FT_GlyphLoader_Rewind( builder->loader ); - - FT_GlyphLoader_Prepare( builder->loader ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* funcs :: Glyph builder functions (or `methods'). */ - /* */ - LOCAL_FUNC - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ) - { - builder->funcs = *funcs; - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->size = size; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = FT_SLOT( glyph )->loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - T1_Reset_Builder( builder, 1 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void T1_Done_Builder( T1_Builder* builder ) - { - T1_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* funcs :: The hinting functions interface. */ - /* */ - LOCAL_FUNC - void T1_Init_Decoder( T1_Decoder* decoder, - const T1_Hinter_Funcs* funcs ) - { - decoder->hinter = *funcs; /* copy hinter interface */ - decoder->top = 0; - decoder->zone = 0; - - decoder->flex_state = 0; - decoder->num_flex_vectors = 0; - - /* Clear loader */ - MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( T1_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode] ); - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name, glyph_name ) == 0 ) - return n; - } - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( T1_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - T1_Face face = decoder->builder.face; - T1_Font* type1 = &face->type1; - - - bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); - achar_index = lookup_glyph_by_stdcharcode( face, achar ); - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->current.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - goto Exit; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - if ( decoder->builder.loader ) - FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - n_base_points = base->n_points; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load `achar' on top of the base outline */ - error = T1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - return error; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - - FT_Outline_Translate( &dummy, adx - asb, ady ); - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_flex */ - /* */ - /* */ - /* Implements the `flex' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* threshold :: The threshold. */ - /* end_x :: The horizontal position of the final flex point. */ - /* end_y :: The vertical position of the final flex point. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_flex( T1_Decoder* decoder, - FT_Pos threshold, - FT_Pos end_x, - FT_Pos end_y ) - { - FT_Vector vec; - FT_Vector* flex = decoder->flex_vectors; - FT_Int n; - - FT_UNUSED( threshold ); - FT_UNUSED( end_x ); - FT_UNUSED( end_y ); - - - /* we don't even try to test the threshold in the non-hinting */ - /* builder, even if the flex operator is said to be a path */ - /* construction statement in the specification. This is better */ - /* left to the hinter. */ - - flex = decoder->flex_vectors; - vec = *flex++; - - for ( n = 0; n < 6; n++ ) - { - flex->x += vec.x; - flex->y += vec.y; - - vec = *flex++; - } - - flex = decoder->flex_vectors; - - return decoder->builder.funcs.rcurve_to( &decoder->builder, - flex[0].x, flex[0].y, - flex[1].x, flex[1].y, - flex[2].x, flex[2].y ) || - - decoder->builder.funcs.rcurve_to( &decoder->builder, - flex[3].x, flex[3].y, - flex[4].x, flex[4].y, - flex[5].x, flex[5].y ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* num_subrs :: The number of sub-routines. */ - /* */ - /* subrs_base :: An array of sub-routines addresses. */ - /* */ - /* subrs_len :: An array of sub-routines lengths. */ - /* */ - /* */ - /* Free error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ) - { - FT_Error error; - T1_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - T1_Builder* builder = &decoder->builder; - T1_Builder_Funcs* builds = &builder->funcs; - T1_Hinter_Funcs* hints = &decoder->hinter; - - static - const FT_Int args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - 0, /* dotsection */ - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - T1_Operator op = op_none; - FT_Long value = 0; - - - /* Start with the decompression of operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ((FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "T1_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /* push value if necessary */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "T1_Parse_CharStrings: stack overflow!\n" )); - goto Syntax_Error; - } - - *top++ = value; - decoder->top = top; - } - - else if ( op == op_callothersubr ) /* check arguments differently */ - { - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - - switch ( top[1] ) - { - case 1: /* start flex feature */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - decoder->flex_vectors[0].x = 0; - decoder->flex_vectors[0].y = 0; - break; - - case 2: /* add flex vector */ - { - FT_Int index; - FT_Vector* flex; - - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - top -= 2; - if ( top < decoder->stack ) - goto Stack_Underflow; - - index = decoder->num_flex_vectors++; - if ( index >= 7 ) - { - FT_ERROR(( "T1_Parse_CharStrings: too many flex vectors!\n" )); - goto Syntax_Error; - } - - flex = decoder->flex_vectors + index; - flex->x += top[0]; - flex->y += top[1]; - } - break; - - case 0: /* end flex feature */ - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - top -= 3; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* now consume the remaining `pop pop setcurrentpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurrentpoint */ - { - FT_ERROR(( "T1_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - decoder->flex_state = 0; - decoder->top = top; - - error = t1operator_flex( decoder, top[0], top[1], top[2] ); - break; - - case 3: /* change hints */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", ip[0], ip[1] )); - goto Syntax_Error; - } - - ip += 2; - - error = hints->change_hints( builder ); - break; - - default: - /* invalid OtherSubrs call */ - Unexpected_OtherSubr: - FT_ERROR(( "T1_Parse_CharStrings: unexpected OtherSubrs [%d %d]\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else - { - FT_Int num_args = args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - error = builds->end_char( builder ); - break; - - case op_hsbw: - error = builds->set_bearing_point( builder, top[0], 0, - top[1], 0 ); - break; - - case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - error = builds->set_bearing_point( builder, top[0], top[1], - top[2], top[3] ); - break; - - case op_closepath: - error = builds->close_path( builder ); - break; - - case op_hlineto: - error = builds->rline_to( builder, top[0], 0 ); - break; - - case op_hmoveto: - error = builds->rmove_to( builder, top[0], 0 ); - break; - - case op_hvcurveto: - error = builds->rcurve_to( builder, top[0], 0, - top[1], top[2], - 0, top[3] ); - break; - - case op_rlineto: - error = builds->rline_to( builder, top[0], top[1] ); - break; - - case op_rmoveto: - /* ignore operator when in flex mode */ - if ( decoder->flex_state == 0 ) - error = builds->rmove_to( builder, top[0], top[1] ); - else - top += 2; - break; - - case op_rrcurveto: - error = builds->rcurve_to( builder, top[0], top[1], - top[2], top[3], - top[4], top[5] ); - break; - - case op_vhcurveto: - error = builds->rcurve_to( builder, 0, top[0], - top[1], top[2], - top[3], 0 ); - break; - - case op_vlineto: - error = builds->rline_to( builder, 0, top[0] ); - break; - - case op_vmoveto: - error = builds->rmove_to( builder, 0, top[0] ); - break; - - case op_dotsection: - error = hints->dot_section( builder ); - break; - - case op_hstem: - error = hints->stem( builder, top[0], top[1], 0 ); - break; - - case op_hstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 0 ); - break; - - case op_vstem: - error = hints->stem( builder, top[0], top[1], 1 ); - break; - - case op_vstem3: - error = hints->stem3( builder, top[0], top[1], top[2], - top[3], top[4], top[5], 1 ); - break; - - case op_div: - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "T1_Parse_CHarStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index = top[0]; - - - if ( index < 0 || index >= num_subrs ) - { - FT_ERROR(( "T1_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "T1_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = subrs_base[index]; - zone->limit = zone->base + subrs_len[index]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "T1_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case op_pop: - FT_ERROR(( "T1_Parse_CharStrings: unexpected POP\n" )); - goto Syntax_Error; - - case op_return: - if ( zone <= decoder->zones ) - { - FT_ERROR(( "T1_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_setcurrentpoint: - FT_ERROR(( "T1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - break; - - default: - FT_ERROR(( "T1_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - } - } - - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Points */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_points' additional outline points. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_points :: The number of points that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the points count in the glyph */ - /* builder. This must be done by the caller itself, after this */ - /* function has been invoked. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Points( T1_Builder* builder, - FT_Int num_points ) - { - return FT_GlyphLoader_Check_Points( builder->loader, num_points, 0 ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Contours */ - /* */ - /* */ - /* Checks that there is enough room in the current load glyph outline */ - /* to accept `num_contours' additional contours. If not, this */ - /* function grows the load outline's arrays accordingly. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder object. */ - /* */ - /* num_contours :: The number of contours that will be added later. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function does NOT update the contours count in the load glyph */ - /* This must be done by the caller itself, after this function is */ - /* invoked. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Contours( T1_Builder* builder, - FT_Int num_contours ) - { - return FT_GlyphLoader_Check_Points( builder->loader, 0, num_contours ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error maxadv_sbw( T1_Decoder* decoder, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ) - { - FT_UNUSED( sbx ); - FT_UNUSED( sby ); - FT_UNUSED( wy ); - - if ( wx > decoder->builder.advance.x ) - decoder->builder.advance.x = wx; - - return -1; /* return an error code to exit the Type 1 parser */ - /* immediately. */ - } - - - static - FT_Int maxadv_error( void ) - { - /* we should never reach this code, unless with a buggy font */ - return -2; - } - - - /* the maxadv_gbuilder_interface is used when computing the maximum */ - /* advance width of all glyphs in a given font. We only process the */ - /* `sbw' operator here, and return an error for all others. */ - - /* Note that `seac' is processed by the T1_Decoder. */ - static - const T1_Builder_Funcs maxadv_builder_interface = - { - (T1_Builder_EndChar) maxadv_error, - (T1_Builder_Sbw) maxadv_sbw, - (T1_Builder_ClosePath)maxadv_error, - (T1_Builder_RLineTo) maxadv_error, - (T1_Builder_RMoveTo) maxadv_error, - (T1_Builder_RCurveTo) maxadv_error - }; - - - /* the maxadv_hinter_interface always return an error. */ - static - const T1_Hinter_Funcs maxadv_hinter_interface = - { - (T1_Hinter_DotSection) maxadv_error, - (T1_Hinter_ChangeHints)maxadv_error, - (T1_Hinter_Stem) maxadv_error, - (T1_Hinter_Stem3) maxadv_error, - }; - - - LOCAL_FUNC - FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) - { - FT_Error error; - T1_Decoder decoder; - FT_Int glyph_index; - T1_Font* type1 = &face->type1; - - - *max_advance = 0; - - /* Initialize load decoder */ - T1_Init_Decoder( &decoder, &maxadv_hinter_interface ); - - T1_Init_Builder( &decoder.builder, face, 0, 0, - &maxadv_builder_interface ); - - /* For each glyph, parse the glyph charstring and extract */ - /* the advance width. */ - for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) - { - /* now get load the unscaled outline */ - error = T1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - /* ignore the error if one occured - skip to next glyph */ - } - - *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /********** The Type 1 hinter is located in `t1hint.c' *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error close_open_path( T1_Builder* builder ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Int num_points; - FT_Int first_point; - - - /* Some fonts, like Hershey, are made of `open paths' which are */ - /* now managed directly by FreeType. In this case, it is necessary */ - /* to close the path by duplicating its points in reverse order, */ - /* which is precisely the purpose of this function. */ - - /* first compute the number of points to duplicate */ - if ( cur->n_contours > 1 ) - first_point = cur->contours[cur->n_contours - 2] + 1; - else - first_point = 0; - - num_points = cur->n_points - first_point - 2; - if ( num_points > 0 ) - { - FT_Vector* source_point; - char* source_tags; - FT_Vector* point; - char* tags; - - - error = T1_Add_Points( builder, num_points ); - if ( error ) - return error; - - point = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; - - source_point = point - 2; - source_tags = tags - 2; - - cur->n_points += num_points; - - if ( builder->load_points ) - do - { - *point++ = *source_point--; - *tags++ = *source_tags--; - num_points--; - - } while ( num_points > 0 ); - } - - builder->path_begun = 0; - return T1_Err_Ok; - } - - - static - FT_Error gload_closepath( T1_Builder* builder ) - { - FT_Outline* cur = builder->current; - - - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( cur->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = cur->points + first; - FT_Vector* p2 = cur->points + cur->n_points - 1; - - - if ( cur->n_contours > 1 ) - { - first = cur->contours[cur->n_contours - 2] + 1; - p1 = cur->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - cur->n_points--; - } - - /* save current contour, if any */ - if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - /* hint last points if necessary -- this is not strictly required */ - /* there, but it helps for debugging, and doesn't affect performance */ - if ( builder->pass == 1 ) - T1_Hint_Points( builder ); -#endif - - builder->path_begun = 0; - return T1_Err_Ok; - } - - - static - FT_Error gload_endchar( T1_Builder* builder ) - { - FT_Error error; - - - /* close path if needed */ - if ( builder->path_begun ) - { - error = close_open_path( builder ); - if ( error ) - return error; - } - - error = gload_closepath( builder ); - - FT_GlyphLoader_Add( builder->loader ); - - return error; - } - - - static - FT_Error gload_sbw( T1_Builder* builder, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ) - { - builder->left_bearing.x += sbx; - builder->left_bearing.y += sby; - builder->advance.x = wx; - builder->advance.y = wy; - - builder->last.x = sbx; - builder->last.y = sby; - - return 0; - } - - - static - FT_Error gload_rlineto( T1_Builder* builder, - FT_Pos dx, - FT_Pos dy ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - - - /* grow buffer if necessary */ - error = T1_Add_Points( builder, 1 ); - if ( error ) - return error; - - if ( builder->load_points ) - { - /* save point */ - vec.x = builder->last.x + dx; - vec.y = builder->last.y + dy; - - cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; - - builder->last = vec; - } - cur->n_points++; - - builder->path_begun = 1; - - return T1_Err_Ok; - } - - - static - FT_Error gload_rmoveto( T1_Builder* builder, - FT_Pos dx, - FT_Pos dy ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - - - /* in the case where `path_begun' is set, we have an `rmoveto' */ - /* after some normal path definition. If the face's paint type */ - /* is set to 1, this means that we have an `open path', also */ - /* called a `stroke'. The FreeType raster doesn't support */ - /* opened paths, so we'll close it explicitely there. */ - - if ( builder->path_begun && builder->face->type1.paint_type == 1 ) - { - if ( builder->face->type1.paint_type == 1 ) - { - error = close_open_path( builder ); - if ( error ) - return error; - } - } - - /* grow buffer if necessary */ - error = T1_Add_Contours( builder, 1 ) || - T1_Add_Points ( builder, 1 ); - if ( error ) - return error; - - /* save current contour, if any */ - if ( cur->n_contours > 0 ) - cur->contours[cur->n_contours - 1] = cur->n_points - 1; - - if ( builder->load_points ) - { - /* save point */ - vec.x = builder->last.x + dx; - vec.y = builder->last.y + dy; - cur->points[cur->n_points] = vec; - cur->tags [cur->n_points] = FT_Curve_Tag_On; - - builder->last = vec; - } - - cur->n_contours++; - cur->n_points++; - - return T1_Err_Ok; - } - - - static - FT_Error gload_rrcurveto( T1_Builder* builder, - FT_Pos dx1, - FT_Pos dy1, - FT_Pos dx2, - FT_Pos dy2, - FT_Pos dx3, - FT_Pos dy3 ) - { - FT_Error error; - FT_Outline* cur = builder->current; - FT_Vector vec; - FT_Vector* points; - char* tags; - - - /* grow buffer if necessary */ - error = T1_Add_Points( builder, 3 ); - if ( error ) - return error; - - if ( builder->load_points ) - { - /* save point */ - points = cur->points + cur->n_points; - tags = cur->tags + cur->n_points; - - vec.x = builder->last.x + dx1; - vec.y = builder->last.y + dy1; - points[0] = vec; - tags[0] = FT_Curve_Tag_Cubic; - - vec.x += dx2; - vec.y += dy2; - points[1] = vec; - tags[1] = FT_Curve_Tag_Cubic; - - vec.x += dx3; - vec.y += dy3; - points[2] = vec; - tags[2] = FT_Curve_Tag_On; - - builder->last = vec; - } - - cur->n_points += 3; - builder->path_begun = 1; - - return T1_Err_Ok; - } - - - static - FT_Error gload_ignore( void ) - { - return 0; - } - - - static - const T1_Builder_Funcs gload_builder_interface = - { - gload_endchar, - gload_sbw, - gload_closepath, - gload_rlineto, - gload_rmoveto, - gload_rrcurveto - }; - - - static - const T1_Builder_Funcs gload_builder_interface_null = - { - (T1_Builder_EndChar) gload_ignore, - (T1_Builder_Sbw) gload_sbw, /* record left bearing */ - (T1_Builder_ClosePath)gload_ignore, - (T1_Builder_RLineTo) gload_ignore, - (T1_Builder_RMoveTo) gload_ignore, - (T1_Builder_RCurveTo) gload_ignore - }; - - - static - const T1_Hinter_Funcs gload_hinter_interface = - { - (T1_Hinter_DotSection) gload_ignore, /* dotsection */ - (T1_Hinter_ChangeHints)gload_ignore, /* changehints */ - (T1_Hinter_Stem) gload_ignore, /* hstem & vstem */ - (T1_Hinter_Stem3) gload_ignore, /* hstem3 & vestem3 */ - }; - - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - - /*************************************************************************/ - /* */ - /* Hinter overview: */ - /* */ - /* This is a two-pass hinter. On the first pass, the hints are all */ - /* recorded by the hinter, and no point is loaded in the outline. */ - /* */ - /* When the first pass is finished, all stems hints are grid-fitted */ - /* at once. */ - /* */ - /* Then, a second pass is performed to load the outline points as */ - /* well as hint/scale them correctly. */ - /* */ - /*************************************************************************/ - - - static - FT_Error t1_load_hinted_glyph( T1_Decoder* decoder, - FT_UInt glyph_index, - FT_Bool recurse ) - { - T1_Builder* builder = &decoder->builder; - T1_GlyphSlot glyph = builder->glyph; - T1_Font* type1 = &builder->face->type1; - FT_UInt old_points, old_contours; - FT_GlyphLoader* loader = decoder->builder.loader; - FT_Error error; - - - /* Pass 1 -- try to load first glyph, simply recording points */ - old_points = loader->base.outline.n_points; - old_contours = loader->base.outline.n_contours; - - FT_GlyphLoader_Prepare( decoder->builder.loader ); - - T1_Reset_Builder( builder, 0 ); - - builder->no_recurse = recurse; - builder->pass = 0; - glyph->hints->hori_stems.num_stems = 0; - glyph->hints->vert_stems.num_stems = 0; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - /* check for composite (i.e. `seac' operator) */ - if ( glyph->root.format == ft_glyph_format_composite ) - { - /* this is a composite glyph, we must then load the first one, */ - /* then load the second one on top of it and translate it by a */ - /* fixed amount. */ - FT_UInt n_base_points; - FT_SubGlyph* subglyph = loader->base.subglyphs; - T1_Size size = builder->size; - FT_Pos dx, dy; - FT_Vector left_bearing, advance; - - - /* clean glyph format */ - glyph->root.format = ft_glyph_format_none; - - /* First load `bchar' in builder */ - builder->no_recurse = 0; - error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load */ - left_bearing = builder->left_bearing; - advance = builder->advance; - - /* Then load `achar' in builder */ - n_base_points = builder->base->n_points; - subglyph++; - error = t1_load_hinted_glyph( decoder, subglyph->index, 0 ); - if ( error ) - goto Exit; - - /* Finally, move the accent */ - dx = FT_MulFix( subglyph->arg1, size->root.metrics.x_scale ); - dy = FT_MulFix( subglyph->arg2, size->root.metrics.y_scale ); - dx = ( dx + 32 ) & -64; - dy = ( dy + 32 ) & -64; - { - FT_Outline dummy; - - - dummy.n_points = loader->base.outline.n_points - n_base_points; - dummy.points = loader->base.outline.points + n_base_points; - - FT_Outline_Translate( &dummy, dx, dy ); - } - - /* restore the left side bearing and */ - /* advance width of the base character */ - builder->left_bearing = left_bearing; - builder->advance = advance; - } - else - { - /* All right, pass 1 is finished, now grid-fit all stem hints */ - T1_Hint_Stems( &decoder->builder ); - - /* undo the end-char */ - builder->base->n_points = old_points; - builder->base->n_contours = old_contours; - - /* Pass 2 -- record and scale/hint the points */ - T1_Reset_Builder( builder, 0 ); - - builder->pass = 1; - builder->no_recurse = 0; - - error = T1_Parse_CharStrings( decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - } - - /* save new glyph tables */ - if ( recurse ) - T1_Done_Builder( builder ); - - Exit: - return error; - } - - -#endif /* !T1_CONFIG_OPTION_DISABLE_HINTER */ - - - LOCAL_FUNC - FT_Error T1_Load_Glyph( T1_GlyphSlot glyph, - T1_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - T1_Decoder decoder; - T1_Face face = (T1_Face)glyph->root.face; - FT_Bool hinting; - T1_Font* type1 = &face->type1; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - glyph->root.format = ft_glyph_format_outline; /* by default */ - - hinting = 0; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - hinting = ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0; - - if ( hinting ) - { - T1_Init_Decoder( &decoder, &t1_hinter_funcs ); - T1_Init_Builder( &decoder.builder, face, size, glyph, - &gload_builder_interface ); - - error = t1_load_hinted_glyph( &decoder, glyph_index, 1 ); - } - else - -#endif /* !T1_CONFIG_OPTION_DISABLE_HINTER */ - - { - T1_Init_Decoder( &decoder, &gload_hinter_interface ); - - T1_Init_Builder( &decoder.builder, face, size, glyph, - &gload_builder_interface ); - - decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0; - - /* now load the unscaled outline */ - error = T1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - - /* save new glyph tables */ - T1_Done_Builder( &decoder.builder ); - } - - /* Now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax */ - if ( !error ) - { - /* for composite glyphs, return only the left side bearing and the */ - /* advance width */ - if ( glyph->root.format == ft_glyph_format_composite ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax + 63 ) & -64; - cbox.yMax = ( cbox.yMax + 63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - glyph->root.outline.flags = 0; - - if ( size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - - glyph->root.outline.flags |= ft_outline_reverse_fill; - - if ( hinting ) - { - /* adjust the advance width */ - /* XXX TODO: consider stem hints grid-fit */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, - glyph->x_scale ); - } - else if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = decoder.builder.base; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - /* Then scale the metrics */ - metrics->width = FT_MulFix( metrics->width, x_scale ); - metrics->height = FT_MulFix( metrics->height, y_scale ); - - metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale ); - metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - } - } - } - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1gload.h b/subsys/win32k/freetype/src/type1/t1gload.h deleted file mode 100644 index e66d083..0000000 --- a/subsys/win32k/freetype/src/type1/t1gload.h +++ /dev/null @@ -1,326 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1gload.h */ -/* */ -/* Type 1 Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2000 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 T1GLOAD_H -#define T1GLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct T1_Builder_ T1_Builder; - - typedef FT_Error (*T1_Builder_EndChar)( T1_Builder* loader ); - - typedef FT_Error (*T1_Builder_Sbw)( T1_Builder* loader, - FT_Pos sbx, - FT_Pos sby, - FT_Pos wx, - FT_Pos wy ); - - typedef FT_Error (*T1_Builder_ClosePath)( T1_Builder* loader ); - - typedef FT_Error (*T1_Builder_RLineTo)( T1_Builder* loader, - FT_Pos dx, - FT_Pos dy ); - - typedef FT_Error (*T1_Builder_RMoveTo)( T1_Builder* loader, - FT_Pos dx, - FT_Pos dy ); - - typedef FT_Error (*T1_Builder_RCurveTo)( T1_Builder* loader, - FT_Pos dx1, - FT_Pos dy1, - FT_Pos dx2, - FT_Pos dy2, - FT_Pos dx3, - FT_Pos dy3 ); - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* glyph builder to implement the outline's `path construction'. */ - /* */ - typedef struct T1_Builder_Funcs_ - { - T1_Builder_EndChar end_char; - T1_Builder_Sbw set_bearing_point; - T1_Builder_ClosePath close_path; - T1_Builder_RLineTo rline_to; - T1_Builder_RMoveTo rmove_to; - T1_Builder_RCurveTo rcurve_to; - - } T1_Builder_Funcs; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (for composite glyphs). */ - /* */ - /* pos_y :: The vertical translation (for composite glyphs). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* no_recurse :: */ - /* */ - /* bbox :: The glyph's bounding box. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: A flag which indicates, if not set, that no points */ - /* are loaded. */ - /* */ - /* pass :: The pass number for multi-pass hinters. */ - /* */ - /* hint_point :: The index of the next point to hint. */ - /* */ - /* funcs :: A table of builder functions used to perform the */ - /* outline's path construction. */ - /* */ - struct T1_Builder_ - { - FT_Memory memory; - T1_Face face; - T1_Size size; - T1_GlyphSlot glyph; - FT_GlyphLoader* loader; - - FT_Outline* current; /* the current glyph outline */ - FT_Outline* base; /* the composite glyph outline */ - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - FT_Bool no_recurse; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - - FT_Int pass; - FT_Int hint_point; - - /* path construction function interface */ - T1_Builder_Funcs funcs; - }; - - - typedef FT_Error (*T1_Hinter_ChangeHints)( T1_Builder* builder ); - - typedef FT_Error (*T1_Hinter_DotSection)( T1_Builder* builder ); - - typedef FT_Error (*T1_Hinter_Stem)( T1_Builder* builder, - FT_Pos pos, - FT_Pos width, - FT_Bool vertical ); - - typedef FT_Error (*T1_Hinter_Stem3)( T1_Builder* builder, - FT_Pos pos0, - FT_Pos width0, - FT_Pos pos1, - FT_Pos width1, - FT_Pos pos2, - FT_Pos width2, - FT_Bool vertical ); - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hinter_Funcs */ - /* */ - /* */ - /* A structure to store the address of various functions used by a */ - /* Type 1 hinter to perform outline hinting. */ - /* */ - typedef struct T1_Hinter_Func_ - { - T1_Hinter_ChangeHints change_hints; - T1_Hinter_DotSection dot_section; - T1_Hinter_Stem stem; - T1_Hinter_Stem3 stem3; - - } T1_Hinter_Funcs; - - - typedef enum T1_Operator_ - { - op_none = 0, - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - op_dotsection, - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } T1_Operator; - - - /* execution context charstring zone */ - typedef struct T1_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } T1_Decoder_Zone; - - - typedef struct T1_Decoder_ - { - T1_Builder builder; - T1_Hinter_Funcs hinter; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - T1_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - T1_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - } T1_Decoder; - - - LOCAL_DEF - void T1_Init_Builder( T1_Builder* builder, - T1_Face face, - T1_Size size, - T1_GlyphSlot glyph, - const T1_Builder_Funcs* funcs ); - - LOCAL_DEF - void T1_Done_Builder( T1_Builder* builder ); - - LOCAL_DEF - void T1_Init_Decoder( T1_Decoder* decoder, - const T1_Hinter_Funcs* funcs ); - - LOCAL_DEF - FT_Error T1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); - - LOCAL_DEF - FT_Error T1_Parse_CharStrings( T1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ); - - LOCAL_DEF - FT_Error T1_Add_Points( T1_Builder* builder, - FT_Int num_points ); - - LOCAL_DEF - FT_Error T1_Add_Contours( T1_Builder* builder, - FT_Int num_contours ); - - LOCAL_DEF - FT_Error T1_Load_Glyph( T1_GlyphSlot glyph, - T1_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1GLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1hinter.c b/subsys/win32k/freetype/src/type1/t1hinter.c deleted file mode 100644 index 15b5897..0000000 --- a/subsys/win32k/freetype/src/type1/t1hinter.c +++ /dev/null @@ -1,1347 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1hinter.c */ -/* */ -/* Type 1 hinter (body). */ -/* */ -/* Copyright 1996-2000 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 Hinter is in charge of fitting th scaled outline to the pixel */ - /* grid in order to considerably improve the quality of the Type 1 font */ - /* driver's output. */ - /* */ - /*************************************************************************/ - - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" -#include "t1hinter.h" - -#else - -#include -#include - -#endif - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1hint - - -#undef ONE_PIXEL -#define ONE_PIXEL 64 - -#undef ROUND -#define ROUND( x ) ( ( x + ONE_PIXEL / 2 ) & -ONE_PIXEL ) - -#undef SCALE -#define SCALE( val ) FT_MulFix( val, scale ) - -/* various constants used to describe the alignment of a horizontal */ -/* stem with regards to the blue zones */ - -#define T1_ALIGN_NONE 0 -#define T1_ALIGN_BOTTOM 1 -#define T1_ALIGN_TOP 2 -#define T1_ALIGN_BOTH 3 - - - /* very simple bubble sort (not a lot of elements, mostly */ - /* pre-sorted, no need for quicksort) */ - - static - void t1_sort_blues( FT_Int* blues, - FT_Int count ) - { - FT_Int i, swap; - FT_Int* cur; - - - for ( i = 2; i < count; i += 2 ) - { - cur = blues + i; - do - { - if ( cur[-1] < cur[0] ) - break; - - swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap; - swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap; - cur -= 2; - - } while ( cur > blues ); - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_set_blue_zones */ - /* */ - /* */ - /* Sets a size object's blue zones during reset. This will compute */ - /* the `snap' zone corresponding to each blue zone. */ - /* */ - /* */ - /* size :: A handle to target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This functions does the following: */ - /* */ - /* 1. It extracts the bottom and top blue zones from the face object. */ - /* */ - /* 2. Each zone is then grown by `BlueFuzz', overlapping is */ - /* eliminated by adjusting the zone edges appropriately. */ - /* */ - /* 3. For each zone, we keep its original font units position, its */ - /* original scaled position, as well as its grown/adjusted edges. */ - /* */ - static - FT_Error t1_set_blue_zones( T1_Size size ) - { - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; - FT_Int n; - FT_Int blues[24]; - FT_Int num_bottom; - FT_Int num_top; - FT_Int num_blues; - T1_Size_Hints* hints = size->hints; - T1_Snap_Zone* zone; - FT_Pos pix, orus; - FT_Pos min, max, threshold; - FT_Fixed scale; - FT_Bool is_bottom; - - - /***********************************************************************/ - /* */ - /* copy bottom and top blue zones in local arrays */ - /* */ - - /* First of all, check the sizes of the /BlueValues and /OtherBlues */ - /* tables. They all must contain an even number of arguments. */ - if ( priv->num_other_blues & 1 || - priv->num_blue_values & 1 ) - { - FT_ERROR(( "t1_set_blue_zones: odd number of blue values\n" )); - return T1_Err_Syntax_Error; - } - - /* copy the bottom blue zones from /OtherBlues */ - num_top = 0; - num_bottom = priv->num_other_blues; - - for ( n = 0; n < num_bottom; n++ ) - blues[n] = priv->other_blues[n]; - - /* add the first blue zone in /BlueValues to the table */ - num_top = priv->num_blue_values - 2; - if ( num_top >= 0 ) - { - blues[num_bottom ] = priv->blue_values[0]; - blues[num_bottom + 1] = priv->blue_values[1]; - - num_bottom += 2; - } - - /* sort the bottom blue zones */ - t1_sort_blues( blues, num_bottom ); - - hints->num_bottom_zones = num_bottom >> 1; - - /* now copy the /BlueValues to the top of the blues array */ - if ( num_top > 0 ) - { - for ( n = 0; n < num_top; n++ ) - blues[num_bottom + n] = priv->blue_values[n + 2]; - - /* sort the top blue zones */ - t1_sort_blues( blues + num_bottom, num_top ); - } - else - num_top = 0; - - num_blues = num_top + num_bottom; - hints->num_blue_zones = ( num_blues ) >> 1; - - /***********************************************************************/ - /* */ - /* build blue snap zones from the local blues arrays */ - /* */ - - scale = size->root.metrics.y_scale; - zone = hints->blue_zones; - threshold = ONE_PIXEL / 4; /* 0.25 pixels */ - - for ( n = 0; n < num_blues; n += 2, zone++ ) - { - is_bottom = n < num_bottom ? 1 : 0; - - orus = blues[n + is_bottom]; /* get alignement coordinate */ - pix = SCALE( orus ); /* scale it */ - - min = SCALE( blues[n ] - priv->blue_fuzz ); - max = SCALE( blues[n + 1] + priv->blue_fuzz ); - - if ( min > pix - threshold ) - min = pix - threshold; - if ( max < pix + threshold ) - max = pix + threshold; - - zone->orus = orus; - zone->pix = pix; - zone->min = min; - zone->max = max; - } - - /* adjust edges in case of overlap */ - zone = hints->blue_zones; - for ( n = 0; n < num_blues - 2; n += 2, zone++ ) - { - if ( n != num_bottom - 2 && - zone[0].max > zone[1].min ) - zone[0].max = zone[1].min = ( zone[0].pix + zone[1].pix ) / 2; - } - - /* compare the current pixel size with the BlueScale value */ - /* to know whether to supress overshoots */ - - hints->supress_overshoots = - size->root.metrics.y_ppem < FT_MulFix( 1000, priv->blue_scale ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* now print the new blue values in tracing mode */ - - FT_TRACE2(( "Blue Zones for size object at $%08lx:\n", (long)size )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-------------------------------\n" )); - - zone = hints->blue_zones; - for ( n = 0; n < hints->num_blue_zones; n++ ) - { - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - zone++; - } - FT_TRACE2(( "\nOvershoots are %s\n\n", - hints->supress_overshoots ? "supressed" : "active" )); - -#endif /* DEBUG_LEVEL_TRACE */ - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_set_snap_zones */ - /* */ - /* */ - /* This function set a size object's stem snap zones. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function performs the following: */ - /* */ - /* 1. It reads and scales the stem snap widths from the parent face. */ - /* */ - /* 2. A `snap zone' is computed for each snap width, by `growing' it */ - /* with a threshold of 1/2 pixel. Overlapping is avoided through */ - /* proper edge adjustment. */ - /* */ - /* 3. Each width whose zone contain the scaled standard set width is */ - /* removed from the table. */ - /* */ - /* 4. Finally, the standard set width is scaled, and its correponding */ - /* `snap zone' is inserted into the sorted snap zones table. */ - /* */ - static - FT_Error t1_set_snap_zones( T1_Size size ) - { - FT_Int n, direction, n_zones, num_zones; - T1_Snap_Zone* zone; - T1_Snap_Zone* base_zone; - FT_Short* orgs; - FT_Pos standard_width; - FT_Fixed scale; - - T1_Face face = (T1_Face)size->root.face; - T1_Private* priv = &face->type1.private_dict; - T1_Size_Hints* hints = size->hints; - - - /* start with horizontal snap zones */ - direction = 0; - standard_width = priv->standard_width[0]; - n_zones = priv->num_snap_widths; - base_zone = hints->snap_widths; - orgs = priv->snap_widths; - scale = size->root.metrics.x_scale; - - while ( direction < 2 ) - { - /*********************************************************************/ - /* */ - /* Read and scale stem snap widths table from the physical font */ - /* record. */ - /* */ - - FT_Pos prev, orus, pix, min, max, threshold; - - - threshold = ONE_PIXEL / 4; - zone = base_zone; - - if ( n_zones > 0 ) - { - orus = *orgs++; - pix = SCALE( orus ); - min = pix - threshold; - max = pix + threshold; - - zone->orus = orus; - zone->pix = pix; - zone->min = min; - prev = pix; - - for ( n = 1; n < n_zones; n++ ) - { - orus = *orgs++; - pix = SCALE( orus ); - - if ( pix - prev < 2 * threshold ) - { - min = max = ( pix + prev ) / 2; - } - else - min = pix - threshold; - - zone->max = max; - zone++; - zone->orus = orus; - zone->pix = pix; - zone->min = min; - - max = pix + threshold; - prev = pix; - } - zone->max = max; - } - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* print the scaled stem snap values in tracing mode */ - - FT_TRACE2(( "Set_Snap_Zones: first %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled original stem snap zones:\n" )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-----------------------------\n" )); - - zone = base_zone; - for ( n = 0; n < n_zones; n++, zone++ ) - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - FT_TRACE2(( "\n" )); - - FT_TRACE2(( "Standard width = %d\n", standard_width )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - /*********************************************************************/ - /* */ - /* Now, each snap width which is in the range of the standard set */ - /* width will be removed from the list. */ - /* */ - - if ( standard_width > 0 ) - { - T1_Snap_Zone* parent; - FT_Pos std_pix, std_min, std_max; - - - std_pix = SCALE( standard_width ); - - std_min = std_pix - threshold; - std_max = std_pix + threshold; - - num_zones = 0; - zone = base_zone; - parent = base_zone; - - for ( n = 0; n < n_zones; n++ ) - { - if ( zone->pix >= std_min && zone->pix <= std_max ) - { - /* this zone must be removed from the list */ - if ( std_min > zone->min ) - std_min = zone->min; - if ( std_max < zone->max ) - std_max = zone->max; - } - else - { - *parent++ = *zone; - num_zones++; - } - zone++; - } - - /*******************************************************************/ - /* */ - /* Now, insert the standard width zone */ - /* */ - - zone = base_zone + num_zones; - while ( zone > base_zone && zone[-1].pix > std_max ) - { - zone[0] = zone[-1]; - zone--; - } - - /* check border zones */ - if ( zone > base_zone && zone[-1].max > std_min ) - zone[-1].max = std_min; - - if ( zone < base_zone + num_zones && zone[1].min < std_max ) - zone[1].min = std_max; - - zone->orus = standard_width; - zone->pix = std_pix; - zone->min = std_min; - zone->max = std_max; - - num_zones++; - } - else - num_zones = n_zones; - - /* save total number of stem snaps now */ - if ( direction ) - hints->num_snap_heights = num_zones; - else - hints->num_snap_widths = num_zones; - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* print the scaled stem snap values in tracing mode */ - - FT_TRACE2(( "Set_Snap_Zones: second %s pass\n", - direction ? "vertical" : "horizontal" )); - - FT_TRACE2(( "Scaled clipped stem snap zones:\n" )); - FT_TRACE2(( " orus pix min max\n" )); - FT_TRACE2(( "-----------------------------\n" )); - - zone = base_zone; - for ( n = 0; n < num_zones; n++, zone++ ) - FT_TRACE2(( " %3d %.2f %.2f %.2f\n", - zone->orus, - zone->pix / 64.0, - zone->min / 64.0, - zone->max / 64.0 )); - FT_TRACE2(( "\n" )); - - FT_TRACE2(( "Standard width = %d\n", standard_width )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - /* continue with vertical snap zone */ - direction++; - standard_width = priv->standard_height[0]; - n_zones = priv->num_snap_heights; - base_zone = hints->snap_heights; - orgs = priv->snap_heights; - scale = size->root.metrics.y_scale; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Size_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given size object. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeType Error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Size_Hinter( T1_Size size ) - { - FT_Memory memory = size->root.face->memory; - - - return MEM_Alloc( size->hints, sizeof ( *size->hints ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Size_Hinter */ - /* */ - /* */ - /* Releases a given size object's hinter structure. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void T1_Done_Size_Hinter( T1_Size size ) - { - FT_Memory memory = size->root.face->memory; - - - FREE( size->hints ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Reset_Size_Hinter */ - /* */ - /* */ - /* Recomputes hinting information when a given size object has */ - /* changed its resolutions/char sizes/pixel sizes. */ - /* */ - /* */ - /* size :: A handle to the size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Reset_Size_Hinter( T1_Size size ) - { - return t1_set_blue_zones( size ) || t1_set_snap_zones( size ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Glyph_Hinter */ - /* */ - /* */ - /* Allocates a new hinter structure for a given glyph slot. */ - /* */ - /* */ - /* glyph :: A handle to the target glyph slot. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - - - return MEM_Alloc( glyph->hints, sizeof ( *glyph->hints ) ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Glyph_Hinter */ - /* */ - /* */ - /* Releases a given glyph slot's hinter structure. */ - /* */ - /* */ - /* glyph :: A handle to the glyph slot. */ - /* */ - LOCAL_FUNC - void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph ) - { - FT_Memory memory = glyph->root.face->memory; - - - FREE( glyph->hints ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** **********/ - /********** HINTED GLYPH LOADER **********/ - /********** **********/ - /********** The following code is in charge of the first **********/ - /********** and second pass when loading a single outline **********/ - /********** **********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static - FT_Error t1_hinter_ignore( void ) - { - /* do nothing, used for `dotsection' which is unsupported for now */ - return 0; - } - - - static - FT_Error t1_hinter_stem( T1_Builder* builder, - FT_Pos pos, - FT_Int width, - FT_Bool vertical ) - { - T1_Stem_Table* stem_table; - T1_Stem_Hint* stems; - T1_Stem_Hint* cur_stem; - FT_Int min, max, n, num_stems; - FT_Bool new_stem; - T1_Glyph_Hints* hinter = builder->glyph->hints; - - - /* select the appropriate stem array */ - stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems; - stems = stem_table->stems; - num_stems = stem_table->num_stems; - - /* Compute minimum and maximum coord for the stem */ - min = pos + ( vertical - ? builder->left_bearing.x - : builder->left_bearing.y ); - - if ( width >= 0 ) - max = min + width; - else - { - /* a negative width indicates a `ghost' stem */ - if ( width == -21 ) - min += width; - - max = min; - } - - /* Now scan the array. If we find a stem with the same borders */ - /* simply activate it. */ - cur_stem = stems; - new_stem = 1; - - for ( n = 0; n < num_stems; n++, cur_stem++ ) - { - if ( cur_stem->min_edge.orus == min && - cur_stem->max_edge.orus == max ) - { - /* This stem is already in the table, simply activate it */ - if ( ( cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE ) == 0 ) - { - cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE; - stem_table->num_active++; - } - new_stem = 0; - break; - } - } - - /* add a new stem to the array if necessary */ - if ( new_stem ) - { - if ( cur_stem >= stems + T1_HINTER_MAX_EDGES ) - { - FT_ERROR(( "t1_hinter_stem: too many stems in glyph charstring\n" )); - return T1_Err_Syntax_Error; - } - - /* on the first pass, we record the stem, otherwise, this is */ - /* a bug in the glyph loader! */ - if ( builder->pass == 0 ) - { - cur_stem->min_edge.orus = min; - cur_stem->max_edge.orus = max; - cur_stem->hint_flags = T1_HINT_FLAG_ACTIVE; - - stem_table->num_stems++; - stem_table->num_active++; - } - else - { - FT_ERROR(( "t1_hinter_stem:" )); - FT_ERROR(( " fatal glyph loader bug -- pass2-stem\n" )); - return T1_Err_Syntax_Error; - } - } - - return T1_Err_Ok; - } - - - static - FT_Error t1_hinter_stem3( T1_Builder* builder, - FT_Pos pos0, - FT_Int width0, - FT_Pos pos1, - FT_Int width1, - FT_Pos pos2, - FT_Int width2, - FT_Bool vertical ) - { - /* For now, simply call `stem' 3 times */ - return t1_hinter_stem( builder, pos0, width0, vertical ) || - t1_hinter_stem( builder, pos1, width1, vertical ) || - t1_hinter_stem( builder, pos2, width2, vertical ); - } - - - static - FT_Error t1_hinter_changehints( T1_Builder* builder ) - { - FT_Int dimension; - T1_Stem_Table* stem_table; - T1_Glyph_Hints* hinter = builder->glyph->hints; - - - /* If we are in the second pass of glyph hinting, we must */ - /* call the function T1_Hint_Points() on the builder in order */ - /* to force the fit the latest points to the pixel grid. */ - if ( builder->pass == 1 ) - T1_Hint_Points( builder ); - - /* Simply de-activate all hints in all arrays */ - stem_table = &hinter->hori_stems; - - for ( dimension = 2; dimension > 0; dimension-- ) - { - T1_Stem_Hint* cur = stem_table->stems; - T1_Stem_Hint* limit = cur + stem_table->num_stems; - - - for ( ; cur < limit; cur++ ) - cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE; - - stem_table->num_active = 0; - stem_table = &hinter->vert_stems; - } - - return T1_Err_Ok; - } - - - const T1_Hinter_Funcs t1_hinter_funcs = - { - (T1_Hinter_ChangeHints)t1_hinter_changehints, - (T1_Hinter_DotSection) t1_hinter_ignore, - (T1_Hinter_Stem) t1_hinter_stem, - (T1_Hinter_Stem3) t1_hinter_stem3 - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** STEM HINTS MANAGEMENT *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the placement of each scaled stem hint. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* t1_sort_hints */ - /* */ - /* */ - /* Sorta the list of active stems in increasing order, through the */ - /* `sort' indexing table. */ - /* */ - /* */ - /* table :: A stem hints table. */ - /* */ - static - void t1_sort_hints( T1_Stem_Table* table ) - { - FT_Int num_stems = table->num_stems; - FT_Int num_active = 0; - FT_Int* sort = table->sort; - T1_Stem_Hint* stems = table->stems; - FT_Int n; - - - /* record active stems in sort table */ - for ( n = 0; n < num_stems; n++ ) - { - if ( stems[n].hint_flags & T1_HINT_FLAG_ACTIVE ) - sort[num_active++] = n; - } - - /* Now sort the indices. There are usually very few stems, */ - /* and they are pre-sorted in 90% cases, so we choose a */ - /* simple bubble sort (quicksort would be slower). */ - for ( n = 1; n < num_active; n++ ) - { - FT_Int p = n - 1; - T1_Stem_Hint* cur = stems + sort[n]; - - - do - { - FT_Int swap; - T1_Stem_Hint* prev = stems + sort[p]; - - - /* note that by definition, the active stems cannot overlap */ - /* so we simply compare their `min' to sort them (we could compare */ - /* their max values also; this wouldn't change anything). */ - if ( prev->min_edge.orus <= cur->min_edge.orus ) - break; - - /* swap elements */ - swap = sort[p ]; - sort[p ] = sort[p + 1]; - sort[p + 1] = swap; - p--; - - } while ( p >= 0 ); - } - - table->num_active = num_active; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_horizontal_stems */ - /* */ - /* */ - /* Computes the location of each scaled horizontal stem hint. This */ - /* takes care of the blue zones and the horizontal stem snap table. */ - /* */ - /* */ - /* table :: The horizontal stem hints table. */ - /* */ - /* hints :: The current size's hint structure. */ - /* */ - /* blueShift :: The value of the /BlueShift as taken from the face */ - /* object. */ - /* */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3, as well as overlapping stems control. */ - /* */ - static - void t1_hint_horizontal_stems( T1_Stem_Table* table, - T1_Size_Hints* hints, - FT_Pos blueShift, - FT_Fixed scale ) - { - T1_Stem_Hint* stem = table->stems; - T1_Stem_Hint* limit = stem + table->num_stems; - - - /* first of all, scale the blueShift */ - blueShift = SCALE( blueShift ); - - /* then scan the horizontal stem table */ - for ( ; stem < limit; stem++ ) - { - FT_Pos bottom_orus = stem->min_edge.orus; - FT_Pos top_orus = stem->max_edge.orus; - - FT_Pos top_pix = SCALE( top_orus ); - FT_Pos bottom_pix = SCALE( bottom_orus ); - FT_Pos width_pix = top_pix - bottom_pix; - - FT_Pos bottom = bottom_pix; - FT_Pos top = top_pix; - FT_Int align = T1_ALIGN_NONE; - - - /*********************************************************************/ - /* */ - /* Snap pixel width if in stem snap range */ - /* */ - - { - T1_Snap_Zone* zone = hints->snap_heights; - T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - - - for ( ; zone < zone_limit; zone++ ) - { - FT_Pos dist; - - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) - { - best_zone = zone; - best_dist = dist; - } - } - - if ( best_zone ) - { - if ( width_pix > best_zone->pix ) - { - width_pix -= 0x20; - if ( width_pix < best_zone->pix ) - width_pix = best_zone->pix; - } - else - { - width_pix += 0x20; - if ( width_pix > best_zone->pix ) - width_pix = best_zone->pix; - } - } - } - - /*********************************************************************/ - /* */ - /* round width - minimum 1 pixel if this isn't a ghost stem */ - /* */ - - if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND( width_pix ); - - - /*********************************************************************/ - /* */ - /* Now check for bottom blue zones alignement */ - /* */ - - { - FT_Int num_blues = hints->num_bottom_zones; - T1_Snap_Zone* blue = hints->blue_zones; - T1_Snap_Zone* blue_limit = blue + num_blues; - - - for ( ; blue < blue_limit; blue++ ) - { - if ( bottom_pix < blue->min ) - break; - - if ( bottom_pix <= blue->max ) - { - align = T1_ALIGN_BOTTOM; - bottom = ROUND( blue->pix ); - - /* implement blue shift */ - if ( !hints->supress_overshoots ) - { - FT_Pos delta = blue->pix - bottom_pix; - - - delta = delta < blueShift ? 0 : ROUND( delta ); - bottom -= delta; - } - } - } - } - - /*********************************************************************/ - /* */ - /* check for top blue zones alignement */ - /* */ - - { - FT_Int num_blues = hints->num_blue_zones - - hints->num_bottom_zones; - - T1_Snap_Zone* blue = hints->blue_zones + - hints->num_bottom_zones; - - T1_Snap_Zone* blue_limit = blue + num_blues; - - - for ( ; blue < blue_limit; blue++ ) - { - if ( top_pix < blue->min ) - break; - - if ( top_pix <= blue->max ) - { - align |= T1_ALIGN_TOP; - top = ROUND( blue->pix ); - - /* implement blue shift */ - if ( !hints->supress_overshoots ) - { - FT_Pos delta = top - blue->pix; - - - delta = delta < blueShift ? 0 : ROUND( delta ); - top += delta; - } - } - } - } - - /*********************************************************************/ - /* */ - /* compute the hinted stem position, according to its alignment */ - /* */ - - switch ( align ) - { - case T1_ALIGN_BOTTOM: /* bottom zone alignment */ - bottom_pix = bottom; - top_pix = bottom + width_pix; - break; - - case T1_ALIGN_TOP: /* top zone alignment */ - top_pix = top; - bottom_pix = top - width_pix; - break; - - case T1_ALIGN_BOTH: /* bottom+top zone alignment */ - bottom_pix = bottom; - top_pix = top; - break; - - default: /* no alignment */ - /* XXX TODO: Add management of controlled stems */ - bottom = ( SCALE( bottom_orus + top_orus ) - width_pix ) / 2; - - bottom_pix = ROUND( bottom ); - top_pix = bottom_pix + width_pix; - } - - stem->min_edge.pix = bottom_pix; - stem->max_edge.pix = top_pix; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_vertical_stems */ - /* */ - /* */ - /* Computes the location of each scaled vertical stem hint. This */ - /* takes care of the vertical stem snap table. */ - /* */ - /* */ - /* table :: The vertical stem hints table. */ - /* hints :: The current size's hint structure. */ - /* scale :: The 16.16 scale used to convert outline units to */ - /* 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ - static - void t1_hint_vertical_stems( T1_Stem_Table* table, - T1_Size_Hints* hints, - FT_Fixed scale ) - { - T1_Stem_Hint* stem = table->stems; - T1_Stem_Hint* limit = stem + table->num_stems; - - - for ( ; stem < limit; stem++ ) - { - FT_Pos stem_left = stem->min_edge.orus; - FT_Pos stem_right = stem->max_edge.orus; - FT_Pos width_pix, left; - - - width_pix = SCALE( stem_right - stem_left ); - - /* Snap pixel width if in stem snap range */ - { - T1_Snap_Zone* zone = hints->snap_heights; - T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights; - FT_Pos best_dist = 32000; - T1_Snap_Zone* best_zone = 0; - - - for ( ; zone < zone_limit; zone++ ) - { - FT_Pos dist; - - - dist = width_pix - zone->min; - if ( dist < 0 ) - dist = -dist; - if ( dist < best_dist ) - { - best_zone = zone; - best_dist = dist; - } - } - - if ( best_zone ) - { - if ( width_pix > best_zone->pix ) - { - width_pix -= 0x20; - if ( width_pix < best_zone->pix ) - width_pix = best_zone->pix; - } - else - { - width_pix += 0x20; - if ( width_pix > best_zone->pix ) - width_pix = best_zone->pix; - } - } - } - - /* round width - minimum 1 pixel if this isn't a ghost stem */ - if ( width_pix > 0 ) - width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL - : ROUND( width_pix ); - - /* now place the snapped and rounded stem */ - - /* XXX TODO: implement controlled stems for the overlapping */ - /* cases */ - - left = ( SCALE( stem_left + stem_right ) - width_pix ) / 2; - - stem->min_edge.pix = ROUND( left ); - stem->max_edge.pix = stem->min_edge.pix + width_pix; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hint_point */ - /* */ - /* */ - /* Grid-fit a coordinate with regards to a given stem hints table. */ - /* */ - /* */ - /* table :: The source stem hints table. */ - /* coord :: The original coordinate, expressed in font units. */ - /* scale :: The 16.16 scale used to convert font units into */ - /* 26.6 pixels. */ - /* */ - /* */ - /* The hinted/scaled value in 26.6 pixels. */ - /* */ - /* */ - /* For now, all stems are hinted independently from each other. It */ - /* might be necessary, for better performance, to introduce the */ - /* notion of `controlled' hints describing things like counter-stems, */ - /* stem3 as well as overlapping stems control. */ - /* */ - static - FT_Pos t1_hint_point( T1_Stem_Table* table, - FT_Pos coord, - FT_Fixed scale ) - { - FT_Int num_active = table->num_active; - FT_Int n; - T1_Stem_Hint* prev = 0; - T1_Stem_Hint* cur = 0; - T1_Edge* min; - T1_Edge* max; - FT_Pos delta; - - - /* only hint when there is at least one stem defined */ - if ( num_active <= 0 ) - return SCALE( coord ); - - /* scan the stem table to determine placement of coordinate */ - /* relative to the list of sorted and stems */ - for ( n = 0; n < num_active; n++, prev = cur ) - { - cur = table->stems + table->sort[n]; - - /* is it on the left of the current edge? */ - delta = cur->min_edge.orus - coord; - if ( delta == 0 ) - return cur->min_edge.pix; - - if ( delta > 0 ) - { - /* if this is the left of the first edge, simply shift */ - if ( !prev ) - return cur->min_edge.pix - SCALE( delta ); - - /* otherwise, interpolate between the maximum of the */ - /* previous stem, and the minimum of the current one */ - min = &prev->max_edge; - max = &cur->min_edge; - - goto Interpolate; - } - - /* is it within the current edge? */ - delta = cur->max_edge.orus - coord; - if ( delta == 0 ) - return cur->max_edge.pix; - - if ( delta > 0 ) - { - /* interpolate within the stem */ - min = &cur->min_edge; - max = &cur->max_edge; - - goto Interpolate; - } - } - - /* apparently, this coordinate is on the right of the last stem */ - delta = coord - cur->max_edge.orus; - return cur->max_edge.pix + SCALE( delta ); - - Interpolate: - return min->pix + FT_MulDiv( coord - min->orus, - max->pix - min->pix, - max->orus - min->orus ); - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Points */ - /* */ - /* */ - /* This function grid-fits several points in a given Type 1 builder */ - /* at once. */ - /* */ - /* */ - /* builder :: A handle to target Type 1 builder. */ - /* */ - LOCAL_FUNC - void T1_Hint_Points( T1_Builder* builder ) - { - FT_Int first = builder->hint_point; - FT_Int last = builder->current->n_points - 1; - - T1_Size size = builder->size; - FT_Fixed scale_x = size->root.metrics.x_scale; - FT_Fixed scale_y = size->root.metrics.y_scale; - - T1_Glyph_Hints* hints = builder->glyph->hints; - T1_Stem_Table* hori_stems = &hints->hori_stems; - T1_Stem_Table* vert_stems = &hints->vert_stems; - - FT_Vector* cur = builder->current->points + first; - FT_Vector* limit = cur + last - first + 1; - - - /* first of all, sort the active stem hints */ - t1_sort_hints( hori_stems ); - t1_sort_hints( vert_stems ); - - for ( ; cur < limit; cur++ ) - { - cur->x = t1_hint_point( vert_stems, cur->x, scale_x ); - cur->y = t1_hint_point( hori_stems, cur->y, scale_y ); - } - - builder->hint_point = builder->current->n_points; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Hint_Stems */ - /* */ - /* */ - /* This function is used to compute the location of each stem hint */ - /* between the first and second passes of the glyph loader on the */ - /* charstring. */ - /* */ - /* */ - /* builder :: A handle to the target builder. */ - /* */ - LOCAL_FUNC - void T1_Hint_Stems( T1_Builder* builder ) - { - T1_Glyph_Hints* hints = builder->glyph->hints; - T1_Private* priv = &builder->face->type1.private_dict; - - T1_Size size = builder->size; - FT_Fixed scale_x = size->root.metrics.x_scale; - FT_Fixed scale_y = size->root.metrics.y_scale; - - - t1_hint_horizontal_stems( &hints->hori_stems, - builder->size->hints, - priv->blue_shift, - scale_y ); - - t1_hint_vertical_stems( &hints->vert_stems, - builder->size->hints, - scale_x ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1hinter.h b/subsys/win32k/freetype/src/type1/t1hinter.h deleted file mode 100644 index e73e2cc..0000000 --- a/subsys/win32k/freetype/src/type1/t1hinter.h +++ /dev/null @@ -1,273 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1hinter.h */ -/* */ -/* Type 1 hinter (body). */ -/* */ -/* Copyright 1996-2000 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 T1HINTER_H -#define T1HINTER_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" -#include "t1gload.h" - -#else - -#include -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Snap_Zone */ - /* */ - /* */ - /* A `snap zone' is used to model either a blue zone or a stem width */ - /* at a given character size. It is made of a minimum and maximum */ - /* edge, defined in 26.6 pixels, as well as an `original' and */ - /* `scaled' position. */ - /* */ - /* The position corresponds to the stem width (for stem snap zones) */ - /* or to the blue position (for blue zones). */ - /* */ - /* */ - /* orus :: The original position in font units. */ - /* */ - /* pix :: The current position in sub-pixel units. */ - /* */ - /* min :: The minimum boundary in sub-pixel units. */ - /* */ - /* max :: The maximum boundary in sub-pixel units. */ - /* */ - typedef struct T1_Snap_Zone_ - { - FT_Pos orus; - FT_Pos pix; - FT_Pos min; - FT_Pos max; - - } T1_Snap_Zone; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Edge */ - /* */ - /* */ - /* A very simple structure used to model a stem edge. */ - /* */ - /* */ - /* orus :: The original edge position in font units. */ - /* */ - /* pix :: The scaled edge position in sub-pixel units. */ - /* */ - typedef struct T1_Edge_ - { - FT_Pos orus; - FT_Pos pix; - - } T1_Edge; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Stem_Hint */ - /* */ - /* */ - /* A simple structure used to model a stem hint. */ - /* */ - /* */ - /* min_edge :: The hint's minimum edge. */ - /* */ - /* max_edge :: The hint's maximum edge. */ - /* */ - /* hint_flags :: Some flags describing the stem properties. */ - /* */ - /* */ - /* The min and max edges of a ghost stem have the same position, even */ - /* if they are coded in a weird way in the charstrings. */ - /* */ - typedef struct T1_Stem_Hint_ - { - T1_Edge min_edge; - T1_Edge max_edge; - FT_Int hint_flags; - - } T1_Stem_Hint; - - -#define T1_HINT_FLAG_ACTIVE 1 /* indicates an active stem */ -#define T1_HINT_FLAG_MIN_BORDER 2 /* unused for now */ -#define T1_HINT_FLAG_MAX_BORDER 4 /* unused for now */ - - /* hinter's configuration constants */ -#define T1_HINTER_MAX_BLUES 24 /* maximum number of blue zones */ -#define T1_HINTER_MAX_SNAPS 16 /* maximum number of stem snap zones */ -#define T1_HINTER_MAX_EDGES 64 /* maximum number of stem hints */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Size_Hints */ - /* */ - /* */ - /* A structure used to model the hinting information related to a size */ - /* object. */ - /* */ - /* */ - /* supress_overshoots :: A boolean flag to tell whether overshoot */ - /* supression should occur. */ - /* */ - /* num_blue_zones :: The total number of blue zones (top+bottom). */ - /* */ - /* num_bottom_zones :: The number of bottom zones. */ - /* */ - /* blue_zones :: The blue zones table. Bottom zones are */ - /* stored first in the table, followed by all */ - /* top zones. */ - /* */ - /* num_snap_widths :: The number of horizontal stem snap zones. */ - /* */ - /* snap_widths :: An array of horizontal stem snap zones. */ - /* */ - /* num_snap_heights :: The number of vertical stem snap zones. */ - /* */ - /* snap_heights :: An array of vertical stem snap zones. */ - /* */ - struct T1_Size_Hints_ - { - FT_Bool supress_overshoots; - - FT_Int num_blue_zones; - FT_Int num_bottom_zones; - T1_Snap_Zone blue_zones[T1_HINTER_MAX_BLUES]; - - FT_Int num_snap_widths; - T1_Snap_Zone snap_widths[T1_HINTER_MAX_SNAPS]; - - FT_Int num_snap_heights; - T1_Snap_Zone snap_heights[T1_HINTER_MAX_SNAPS]; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Stem_Table */ - /* */ - /* */ - /* A simple structure used to model a set of stem hints in a single */ - /* direction during the loading of a given glyph outline. Not all */ - /* stem hints are active at a time. Moreover, stems must be sorted */ - /* regularly. */ - /* */ - /* */ - /* num_stems :: The total number of stems in the table. */ - /* */ - /* num_active :: The number of active stems in the table. */ - /* */ - /* stems :: A table of all stems. */ - /* */ - /* sort :: A table of indices into the stems table, used to */ - /* keep a sorted list of the active stems. */ - /* */ - typedef struct T1_Stem_Table_ - { - FT_Int num_stems; - FT_Int num_active; - - T1_Stem_Hint stems[T1_HINTER_MAX_EDGES]; - FT_Int sort [T1_HINTER_MAX_EDGES]; - - } T1_Stem_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Glyph_Hints */ - /* */ - /* */ - /* A structure used to model the stem hints of a given glyph outline */ - /* during glyph loading. */ - /* */ - /* */ - /* hori_stems :: The horizontal stem hints table. */ - /* vert_stems :: The vertical stem hints table. */ - /* */ - struct T1_Glyph_Hints_ - { - T1_Stem_Table hori_stems; - T1_Stem_Table vert_stems; - }; - - - /*************************************************************************/ - /* */ - /* */ - /* t1_hinter_funcs */ - /* */ - /* */ - /* A table containing the address of various functions used during */ - /* the loading of an hinted scaled outline. */ - /* */ - extern const T1_Hinter_Funcs t1_hinter_funcs; - - - LOCAL_DEF - FT_Error T1_New_Size_Hinter( T1_Size size ); - - LOCAL_DEF - void T1_Done_Size_Hinter( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Reset_Size_Hinter( T1_Size size ); - - LOCAL_DEF - FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph ); - - LOCAL_DEF - void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph ); - - - LOCAL_DEF - void T1_Hint_Points( T1_Builder* builder ); - - LOCAL_DEF - void T1_Hint_Stems( T1_Builder* builder ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* T1HINTER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1load.c b/subsys/win32k/freetype/src/type1/t1load.c deleted file mode 100644 index d480879..0000000 --- a/subsys/win32k/freetype/src/type1/t1load.c +++ /dev/null @@ -1,1594 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.c */ -/* */ -/* Type 1 font loader (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" -#include "t1parse.h" - -#else - -#include -#include - -#endif - - -#include - -#include /* for strncpy(), strncmp(), strlen() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1load - - - typedef FT_Error (*T1_Parse_Func)( T1_Parser* parser ); - - - /*************************************************************************/ - /* */ - /* */ - /* Init_T1_Parser */ - /* */ - /* */ - /* Initializes a given parser object to build a given T1_Face. */ - /* */ - /* */ - /* parser :: A handle to the newly built parser object. */ - /* */ - /* */ - /* face :: A handle to the target Type 1 face object. */ - /* */ - /* tokenizer :: A handle to the target Type 1 token manager. */ - /* */ - LOCAL_FUNC - void Init_T1_Parser( T1_Parser* parser, - T1_Face face, - T1_Tokenizer tokenizer ) - { - parser->error = 0; - parser->face = face; - parser->tokenizer = tokenizer; - parser->top = parser->stack; - parser->limit = parser->stack + T1_MAX_STACK_DEPTH; - - parser->state_index = 0; - parser->state_stack[0] = dict_none; - - parser->encoding_type = t1_encoding_none; - parser->encoding_names = 0; - parser->encoding_offsets = 0; - parser->encoding_lengths = 0; - - parser->dump_tokens = 0; - face->type1.private_dict.lenIV = 4; /* XXX : is it sure? */ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Next_T1_Token */ - /* */ - /* */ - /* Grabs the next significant token from a parser's input stream. */ - /* This function ignores a number of tokens, and translates */ - /* alternate forms into their common ones. */ - /* */ - /* */ - /* parser :: A handle to the source parser. */ - /* */ - /* */ - /* token :: The extracted token descriptor. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Next_T1_Token( T1_Parser* parser, - T1_Token* token ) - { - FT_Error error; - T1_Tokenizer tokzer = parser->tokenizer; - - - L1: - error = Read_Token( tokzer ); - if ( error ) - return error; - - /* we now must ignore a number of tokens like `dup', `executeonly', */ - /* `readonly', etc. */ - *token = tokzer->token; - if ( token->kind == tok_keyword ) - switch( token->kind2 ) - { - case key_dup: - case key_execonly: - case key_readonly: - case key_noaccess: - case key_userdict: - /* do nothing - loop */ - goto L1; - - /* we also translate some other keywords from their alternative */ - /* to their `normal' form */ - - case key_NP_alternate: - token->kind2 = key_NP; - break; - - case key_RD_alternate: - token->kind2 = key_RD; - break; - - case key_ND_alternate: - token->kind2 = key_ND; - break; - - default: - ; - } - -#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE ) - - /* Dump the token when requested. This feature is only available */ - /* in the `error' and `trace' debug levels. */ - if ( parser->dump_tokens ) - { - FT_String temp_string[128]; - FT_Int len; - - - len = token->len; - if ( len > 127 ) - len = 127; - strncpy( temp_string, - (FT_String*)tokzer->base + token->start, - len ); - temp_string[len] = '\0'; - FT_ERROR(( "%s\n", temp_string )); - } - -#endif /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE */ - - return T1_Err_Ok; - } - - - static - FT_Error Expect_Keyword( T1_Parser* parser, - T1_TokenType keyword ) - { - T1_Token token; - FT_Error error; - - - error = Next_T1_Token( parser, &token ); - if ( error ) - goto Exit; - - if ( token.kind != tok_keyword || - token.kind2 != keyword ) - { - error = T1_Err_Syntax_Error; - FT_ERROR(( "Expect_Keyword: keyword `%s' expected.\n", - t1_keywords[keyword - key_first_] )); - } - - Exit: - return error; - } - - - static - FT_Error Expect_Keyword2( T1_Parser* parser, - T1_TokenType keyword1, - T1_TokenType keyword2 ) - { - T1_Token token; - FT_Error error; - - - error = Next_T1_Token( parser, &token ); - if ( error ) - goto Exit; - - if ( token.kind != tok_keyword || - ( token.kind2 != keyword1 && - token.kind2 != keyword2 ) ) - { - error = T1_Err_Syntax_Error; - FT_ERROR(( "Expect_Keyword2: keyword `%s' or `%s' expected.\n", - t1_keywords[keyword1 - key_first_], - t1_keywords[keyword2 - key_first_] )); - } - - Exit: - return error; - } - - - static - void Parse_Encoding( T1_Parser* parser ) - { - T1_Token* token = parser->top+1; - FT_Memory memory = parser->face->root.memory; - T1_Encoding* encode = &parser->face->type1.encoding; - FT_Error error = 0; - - - if ( token->kind == tok_keyword && - ( token->kind2 == key_StandardEncoding || - token->kind2 == key_ExpertEncoding ) ) - { - encode->num_chars = 256; - encode->code_first = 32; - encode->code_last = 255; - - if ( ALLOC_ARRAY( encode->char_index, 256, FT_Short ) ) - goto Exit; - - encode->char_name = 0; /* no need to store glyph names */ - - /* Now copy the encoding */ - switch ( token->kind2 ) - { - case key_ExpertEncoding: - parser->encoding_type = t1_encoding_expert; - break; - - default: - parser->encoding_type = t1_encoding_standard; - break; - } - } - else - { - FT_ERROR(( "Parse_Encoding: invalid encoding type\n" )); - error = T1_Err_Syntax_Error; - } - - Exit: - parser->error = error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE `DEF' KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Font */ - /* */ - /* */ - /* This function performs a `def' if in the Font dictionary. Its */ - /* purpose is to build the T1_Face attributes directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Font( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_Face face = parser->face; - T1_Font* type1 = &face->type1; - - - switch ( top[0].kind2 ) - { - case imm_FontName: - /* in some cases, the /FontName is an immediate like */ - /* /TimesNewRoman. In this case, we simply copy the */ - /* token string (without the /). */ - if ( top[1].kind == tok_immediate ) - { - FT_Memory memory = parser->tokenizer->memory; - FT_Error error; - FT_Int len = top[1].len; - - - if ( ALLOC( type1->font_name, len + 1 ) ) - { - parser->error = error; - return error; - } - - MEM_Copy( type1->font_name, - parser->tokenizer->base + top[1].start, - len ); - type1->font_name[len] = '\0'; - } - else - type1->font_name = CopyString( parser ); - break; - - case imm_Encoding: - Parse_Encoding( parser ); - break; - - case imm_PaintType: - type1->paint_type = (FT_Byte)CopyInteger( parser ); - break; - - case imm_FontType: - type1->font_type = (FT_Byte)CopyInteger( parser ); - break; - - case imm_FontMatrix: - CopyMatrix( parser, &type1->font_matrix ); - break; - - case imm_FontBBox: - CopyBBox( parser, &type1->font_bbox ); - break; - - case imm_UniqueID: - type1->private_dict.unique_id = CopyInteger( parser ); - break; - - case imm_StrokeWidth: - type1->stroke_width = CopyInteger( parser ); - break; - - case imm_FontID: - type1->font_id = CopyInteger( parser ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_FontInfo */ - /* */ - /* */ - /* This function performs a `def' if in the FontInfo dictionary. Its */ - /* purpose is to build the T1_FontInfo structure directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_FontInfo( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_FontInfo* info = &parser->face->type1.font_info; - - - switch ( top[0].kind2 ) - { - case imm_version: - info->version = CopyString( parser ); - break; - - case imm_Notice: - info->notice = CopyString( parser ); - break; - - case imm_FullName: - info->full_name = CopyString( parser ); - break; - - case imm_FamilyName: - info->family_name = CopyString( parser ); - break; - - case imm_Weight: - info->weight = CopyString( parser ); - break; - - case imm_ItalicAngle: - info->italic_angle = CopyInteger( parser ); - break; - - case imm_isFixedPitch: - info->is_fixed_pitch = CopyBoolean( parser ); - break; - - case imm_UnderlinePosition: - info->underline_position = (FT_Short)CopyInteger( parser ); - break; - - case imm_UnderlineThickness: - info->underline_thickness = (FT_Short)CopyInteger( parser ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Private */ - /* */ - /* */ - /* This function performs a `def' if in the Private dictionary. Its */ - /* purpose is to build the T1_Private structure directly from the */ - /* stream. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeTyoe error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Private( T1_Parser* parser ) - { - T1_Token* top = parser->top; - T1_Private* priv = &parser->face->type1.private_dict; - - - switch ( top[0].kind2 ) - { - /* Ignore the definitions of RD, NP, ND, and their alternate forms */ - case imm_RD: - case imm_RD_alternate: - case imm_ND: - case imm_ND_alternate: - case imm_NP: - case imm_NP_alternate: - parser->error = T1_Err_Ok; - break; - - case imm_BlueValues: - CopyArray( parser, &priv->num_blue_values, - priv->blue_values, 14 ); - break; - - case imm_OtherBlues: - CopyArray( parser, &priv->num_other_blues, - priv->other_blues, 10 ); - break; - - case imm_FamilyBlues: - CopyArray( parser, &priv->num_family_blues, - priv->family_blues, 14 ); - break; - - case imm_FamilyOtherBlues: - CopyArray( parser, &priv->num_family_other_blues, - priv->family_other_blues, 10 ); - break; - - case imm_BlueScale: - priv->blue_scale = CopyFloat( parser, 0x10000L ); - break; - - case imm_BlueShift: - priv->blue_shift = CopyInteger( parser ); - break; - - case imm_BlueFuzz: - priv->blue_fuzz = CopyInteger( parser ); - break; - - case imm_StdHW: - CopyArray( parser, 0, (FT_Short*)&priv->standard_width, 1 ); - break; - - case imm_StdVW: - CopyArray( parser, 0, (FT_Short*)&priv->standard_height, 1 ); - break; - - case imm_StemSnapH: - CopyArray( parser, &priv->num_snap_widths, - priv->snap_widths, 12 ); - break; - - case imm_StemSnapV: - CopyArray( parser, &priv->num_snap_heights, - priv->snap_heights, 12 ); - break; - - case imm_ForceBold: - priv->force_bold = CopyBoolean( parser ); - break; - - case imm_LanguageGroup: - priv->language_group = CopyInteger( parser ); - break; - - case imm_password: - priv->password = CopyInteger( parser ); - break; - - case imm_UniqueID: - priv->unique_id = CopyInteger( parser ); - break; - - case imm_lenIV: - priv->lenIV = CopyInteger( parser ); - break; - - case imm_MinFeature: - CopyArray( parser, 0, priv->min_feature, 2 ); - break; - - default: - /* ignore all other things */ - parser->error = T1_Err_Ok; - } - - return parser->error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Def_Error */ - /* */ - /* */ - /* This function returns a simple syntax error when invoked. It is */ - /* used for the `def' keyword if in the `encoding', `subrs', */ - /* `othersubrs', and `charstrings' dictionary states. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Def_Error( T1_Parser* parser ) - { - FT_ERROR(( "Do_Def_Error:" )); - FT_ERROR(( " `def' keyword encountered in bad dictionary/array\n" )); - - parser->error = T1_Err_Syntax_Error; - - return parser->error; - } - - - static - FT_Error Do_Def_Ignore( T1_Parser* parser ) - { - FT_UNUSED( parser ); - return T1_Err_Ok; - } - - - static - T1_Parse_Func def_funcs[dict_max] = - { - Do_Def_Error, - Do_Def_Font, - Do_Def_FontInfo, - Do_Def_Ignore, - Do_Def_Private, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - Do_Def_Ignore, - }; - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE `PUT' KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_Put_Encoding */ - /* */ - /* */ - /* This function performs a `put' if in the Encoding array. The */ - /* glyph name is copied into the T1 recorder, and the charcode and */ - /* glyph name pointer are written into the face object encoding. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_Put_Encoding( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Encoding* encode = &face->type1.encoding; - FT_Int index; - - - /* record and check the character code */ - if ( top[0].kind != tok_number ) - { - FT_TRACE4(( "Do_Put_Encoding: number expected\n" )); - goto Syntax_Error; - } - index = (FT_Int)CopyInteger( parser ); - if ( parser->error ) - return parser->error; - - if ( index < 0 || index >= encode->num_chars ) - { - FT_TRACE4(( "Do_Put_Encoding: invalid character code\n" )); - goto Syntax_Error; - } - - /* record the immediate name */ - if ( top[1].kind != tok_immediate ) - { - FT_TRACE4(( "Do_Put_Encoding: immediate name expected\n" )); - goto Syntax_Error; - } - - /* if the glyph name is `.notdef', store a NULL char name; */ - /* otherwise, record the glyph name */ - if ( top[1].kind == imm_notdef ) - { - parser->table.elements[index] = 0; - parser->table.lengths [index] = 0; - } - else - { - FT_String temp_name[128]; - T1_Token* token = top + 1; - FT_Int len = token->len - 1; - - - /* copy immediate name */ - if ( len > 127 ) - len = 127; - MEM_Copy( temp_name, parser->tokenizer->base + token->start + 1, len ); - temp_name[len] = '\0'; - - error = T1_Add_Table( &parser->table, index, - (FT_Byte*)temp_name, len + 1 ); - - /* adjust code_first and code_last */ - if ( index < encode->code_first ) encode->code_first = index; - if ( index > encode->code_last ) encode->code_last = index; - } - return error; - - Syntax_Error: - /* ignore the error, and simply clear the stack */ - FT_TRACE4(( "Do_Put_Encoding: invalid syntax encountered\n" )); - parser->top = parser->stack; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* IMPLEMENTATION OF THE "RD" KEYWORD DEPENDING ON */ - /* CURRENT DICTIONARY STATE */ - /* */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Do_RD_Subrs */ - /* */ - /* */ - /* This function performs an `RD' if in the Subrs dictionary. It */ - /* simply records the array of bytecodes/charstrings corresponding to */ - /* the sub-routine. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_RD_Subrs( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Tokenizer tokzer = parser->tokenizer; - FT_Int index, count; - - - /* record and check the character code */ - if ( top[0].kind != tok_number || - top[1].kind != tok_number ) - { - FT_ERROR(( "Do_RD_Subrs: number expected\n" )); - goto Syntax_Error; - } - index = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - count = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - if ( index < 0 || index >= face->type1.num_subrs ) - { - FT_ERROR(( "Do_RD_Subrs: invalid character code\n" )); - goto Syntax_Error; - } - - /* decrypt charstring and skip it */ - { - FT_Byte* base = tokzer->base + tokzer->cursor; - - - tokzer->cursor += count; - - /* some fonts use a value of -1 for lenIV to indicate that */ - /* the charstrings are unencoded. */ - /* */ - /* Thanks to Tom Kacvinsky for pointing this out. */ - /* */ - if ( face->type1.private_dict.lenIV >= 0 ) - { - t1_decrypt( base, count, 4330 ); - - base += face->type1.private_dict.lenIV; - count -= face->type1.private_dict.lenIV; - } - - error = T1_Add_Table( &parser->table, index, base, count ); - } - - /* consume the closing NP or `put' */ - error = Expect_Keyword2( parser, key_NP, key_put ); - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Do_RD_CharStrings */ - /* */ - /* */ - /* This function performs an `RD' if in the CharStrings dictionary. */ - /* It simply records the array of bytecodes/charstrings corresponding */ - /* to the glyph program string. */ - /* */ - /* */ - /* parser :: A handle to the current parser. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error Do_RD_Charstrings( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - T1_Face face = parser->face; - T1_Token* top = parser->top; - T1_Tokenizer tokzer = parser->tokenizer; - FT_Int index, count; - - - /* check the character name argument */ - if ( top[0].kind != tok_immediate ) - { - FT_ERROR(( "Do_RD_Charstrings: immediate character name expected\n" )); - goto Syntax_Error; - } - - /* check the count argument */ - if ( top[1].kind != tok_number ) - { - FT_ERROR(( "Do_RD_Charstrings: number expected\n" )); - goto Syntax_Error; - } - - parser->args++; - count = (FT_Int)CopyInteger( parser ); - error = parser->error; - if ( error ) - goto Exit; - - /* record the glyph name and get the corresponding glyph index */ - if ( top[0].kind2 == imm_notdef ) - index = 0; - else - { - FT_String temp_name[128]; - T1_Token* token = top; - FT_Int len = token->len - 1; - - - /* copy immediate name */ - if ( len > 127 ) - len = 127; - MEM_Copy( temp_name, parser->tokenizer->base + token->start + 1, len ); - temp_name[len] = '\0'; - - index = parser->cur_name++; - error = T1_Add_Table( &parser->table, index * 2, - (FT_Byte*)temp_name, len + 1 ); - if ( error ) - goto Exit; - } - - /* decrypt and record charstring, then skip them */ - { - FT_Byte* base = tokzer->base + tokzer->cursor; - - - tokzer->cursor += count; /* skip */ - - if ( face->type1.private_dict.lenIV >= 0 ) - { - t1_decrypt( base, count, 4330 ); - - base += face->type1.private_dict.lenIV; - count -= face->type1.private_dict.lenIV; - } - - error = T1_Add_Table( &parser->table, index * 2 + 1, base, count ); - } - - /* consume the closing `ND' */ - if ( !error ) - error = Expect_Keyword( parser, key_ND ); - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Expect_Dict_Arguments( T1_Parser* parser, - FT_Int num_args, - T1_TokenType immediate, - T1_DictState new_state, - FT_Int* count ) - { - /* check that we have enough arguments in the stack, including */ - /* the `dict' keyword */ - if ( parser->top - parser->stack < num_args ) - { - FT_ERROR(( "Expect_Dict_Arguments: expecting at least %d arguments", - num_args )); - goto Syntax_Error; - } - - /* check that we have the correct immediate, if needed */ - if ( num_args == 2 ) - { - if ( parser->top[-2].kind != tok_immediate || - parser->top[-2].kind2 != immediate ) - { - FT_ERROR(( "Expect_Dict_Arguments: expecting `/%s' dictionary\n", - t1_immediates[immediate - imm_first_] )); - goto Syntax_Error; - } - } - - parser->args = parser->top-1; - - /* check that the count argument is a number */ - if ( parser->args->kind != tok_number ) - { - FT_ERROR(( "Expect_Dict_Arguments:" )); - FT_ERROR(( " expecting numerical count argument for `dict'\n" )); - goto Syntax_Error; - } - - if ( count ) - { - *count = CopyInteger( parser ); - if ( parser->error ) - return parser->error; - } - - /* save the dictionary state */ - parser->state_stack[++parser->state_index] = new_state; - - /* consume the `begin' keyword and clear the stack */ - parser->top -= num_args; - return Expect_Keyword( parser, key_begin ); - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Expect_Array_Arguments( T1_Parser* parser ) - { - T1_Token* top = parser->top; - FT_Error error = T1_Err_Ok; - T1_DictState new_state; - FT_Int count; - T1_Face face = parser->face; - FT_Memory memory = face->root.memory; - - - /* Check arguments format */ - if ( top - parser->stack < 2 ) - { - FT_ERROR(( "Expect_Array_Arguments: two arguments expected\n" )); - error = T1_Err_Stack_Underflow; - goto Exit; - } - - parser->top -= 2; - top -= 2; - parser->args = top + 1; - - if ( top[0].kind != tok_immediate ) - { - FT_ERROR(( "Expect_Array_Arguments:" )); - FT_ERROR(( " first argument must be an immediate name\n" )); - goto Syntax_Error; - } - - if ( top[1].kind != tok_number ) - { - FT_ERROR(( "Expect_Array_Arguments:" )); - FT_ERROR(( " second argument must be a number\n" )); - goto Syntax_Error; - } - - count = (FT_Int)CopyInteger( parser ); - - /* Is this an array we know about? */ - switch ( top[0].kind2 ) - { - case imm_Encoding: - { - T1_Encoding* encode = &face->type1.encoding; - - - new_state = dict_encoding; - - encode->code_first = count; - encode->code_last = 0; - encode->num_chars = count; - - /* Allocate the table of character indices. The table of */ - /* character names is allocated through init_t1_recorder(). */ - if ( ALLOC_ARRAY( encode->char_index, count, FT_Short ) ) - return error; - - error = T1_New_Table( &parser->table, count, memory ); - if ( error ) - goto Exit; - - parser->encoding_type = t1_encoding_array; - } - break; - - case imm_Subrs: - new_state = dict_subrs; - face->type1.num_subrs = count; - - error = T1_New_Table( &parser->table, count, memory ); - if ( error ) - goto Exit; - break; - - case imm_CharStrings: - new_state = dict_charstrings; - break; - - default: - new_state = dict_unknown_array; - } - - parser->state_stack[++parser->state_index] = new_state; - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - } - - - static - FT_Error Finalize_Parsing( T1_Parser* parser ) - { - T1_Face face = parser->face; - T1_Font* type1 = &face->type1; - FT_Memory memory = face->root.memory; - T1_Table* strings = &parser->table; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - FT_Int num_glyphs; - FT_Int n; - FT_Error error; - - - num_glyphs = type1->num_glyphs = parser->cur_name; - - /* allocate glyph names and charstrings arrays */ - if ( ALLOC_ARRAY( type1->glyph_names, num_glyphs, FT_String* ) || - ALLOC_ARRAY( type1->charstrings, num_glyphs, FT_Byte* ) || - ALLOC_ARRAY( type1->charstrings_len, num_glyphs, FT_Int* ) ) - return error; - - /* copy glyph names and charstrings offsets and lengths */ - type1->charstrings_block = strings->block; - for ( n = 0; n < num_glyphs; n++ ) - { - type1->glyph_names[n] = (FT_String*)strings->elements[2 * n]; - type1->charstrings[n] = strings->elements[2 * n + 1]; - type1->charstrings_len[n] = strings->lengths [2 * n + 1]; - } - - /* now free the old tables */ - FREE( strings->elements ); - FREE( strings->lengths ); - - if ( !psnames ) - { - FT_ERROR(( "Finalize_Parsing: `PSNames' module missing!\n" )); - return T1_Err_Unimplemented_Feature; - } - - /* compute encoding if required */ - if ( parser->encoding_type == t1_encoding_none ) - { - FT_ERROR(( "Finalize_Parsing: no encoding specified in font file\n" )); - return T1_Err_Syntax_Error; - } - - { - FT_Int n; - T1_Encoding* encode = &type1->encoding; - - - encode->code_first = encode->num_chars - 1; - encode->code_last = 0; - - for ( n = 0; n < encode->num_chars; n++ ) - { - FT_String** names; - FT_Int index; - FT_Int m; - - - switch ( parser->encoding_type ) - { - case t1_encoding_standard: - index = psnames->adobe_std_encoding[n]; - names = 0; - break; - - case t1_encoding_expert: - index = psnames->adobe_expert_encoding[n]; - names = 0; - break; - - default: - index = n; - names = (FT_String**)parser->encoding_offsets; - } - - encode->char_index[n] = 0; - - if ( index ) - { - FT_String* name; - - - if ( names ) - name = names[index]; - else - name = (FT_String*)psnames->adobe_std_strings(index); - - if ( name ) - { - FT_Int len = strlen( name ); - - - /* lookup glyph index from name */ - for ( m = 0; m < num_glyphs; m++ ) - { - if ( strncmp( type1->glyph_names[m], name, len ) == 0 ) - { - encode->char_index[n] = m; - break; - } - } - - if ( n < encode->code_first ) encode->code_first = n; - if ( n > encode->code_last ) encode->code_last = n; - } - } - } - - parser->encoding_type = t1_encoding_none; - - FREE( parser->encoding_names ); - FREE( parser->encoding_lengths ); - FREE( parser->encoding_offsets ); - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Parse_T1_FontProgram */ - /* */ - /* */ - /* Parses a given Type 1 font file and builds its face object. */ - /* */ - /* */ - /* parser :: A handle to the target parser object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* The parser contains a handle to the target face object. */ - /* */ - LOCAL_FUNC - FT_Error Parse_T1_FontProgram( T1_Parser* parser ) - { - FT_Error error; - T1_Font* type1 = &parser->face->type1; - - - for (;;) - { - T1_Token token; - T1_Token* top; - T1_DictState dict_state; - FT_Int dict_index; - - - error = Next_T1_Token( parser, &token ); - top = parser->top; - dict_index = parser->state_index; - dict_state = parser->state_stack[dict_index]; - - switch ( token.kind ) - { - /* a keyword has been detected */ - case tok_keyword: - switch ( token.kind2 ) - { - case key_dict: - switch ( dict_state ) - { - case dict_none: - /* All right, we are beginning the font dictionary. */ - /* Check that we only have one number argument, then */ - /* consume the `begin' and change to `dict_font' */ - /* state. */ - error = Expect_Dict_Arguments( parser, 1, tok_error, - dict_font, 0 ); - if ( error ) - goto Exit; - - /* clear stack from all the previous content. This */ - /* could be some stupid Postscript code. */ - parser->top = parser->stack; - break; - - case dict_font: - /* This must be the /FontInfo dictionary, so check */ - /* that we have at least two arguments, that they */ - /* are `/FontInfo' and a number, then change the */ - /* dictionary state. */ - error = Expect_Dict_Arguments( parser, 2, imm_FontInfo, - dict_fontinfo, 0 ); - if ( error ) - goto Exit; - break; - - case dict_none2: - error = Expect_Dict_Arguments( parser, 2, imm_Private, - dict_private, 0 ); - if ( error ) - goto Exit; - break; - - case dict_private: - { - T1_Face face = parser->face; - FT_Int count; - - - error = Expect_Dict_Arguments( parser, 2, imm_CharStrings, - dict_charstrings, &count ); - if ( error ) - goto Exit; - - type1->num_glyphs = count; - error = T1_New_Table( &parser->table, count * 2, - face->root.memory ); - if ( error ) - goto Exit; - - /* record `.notdef' as the first glyph in the font */ - error = T1_Add_Table( &parser->table, 0, - (FT_Byte*)".notdef", 8 ); - parser->cur_name = 1; - /* XXX: DO SOMETHING HERE */ - } - break; - - default: - /* All other uses are invalid */ - FT_ERROR(( "Parse_T1_FontProgram:" )); - FT_ERROR(( " invalid use of `dict' keyword\n" )); - goto Syntax_Error; - } - break; - - case key_array: - /* Are we in an array yet? If so, raise an error */ - switch ( dict_state ) - { - case dict_encoding: - case dict_subrs: - case dict_othersubrs: - case dict_charstrings: - case dict_unknown_array: - FT_ERROR(( "Parse_T1_FontProgram: nested array definitions\n" )); - goto Syntax_Error; - - default: - ; - } - error = Expect_Array_Arguments( parser ); - if ( error ) - goto Exit; - break; - - case key_ND: - case key_NP: - case key_def: - /* Are we in an array? If so, finalize it. */ - switch ( dict_state ) - { - case dict_encoding: /* finish encoding array */ - /* copy table names to the face object */ - T1_Done_Table( &parser->table ); - - parser->encoding_names = parser->table.block; - parser->encoding_lengths = parser->table.lengths; - parser->encoding_offsets = parser->table.elements; - - parser->state_index--; - break; - - case dict_subrs: - /* copy recorder sub-routines */ - T1_Done_Table( &parser->table ); - - parser->subrs = parser->table.block; - type1->subrs = parser->table.elements; - type1->subrs_len = parser->table.lengths; - type1->subrs_block = parser->table.block; - - parser->state_index--; - break; - - case dict_charstrings: - case dict_othersubrs: - case dict_unknown_array: - FT_ERROR(( "Parse_T1_FontProgram: unsupported array\n" )); - goto Syntax_Error; - break; - - default: /* normal `def' processing */ - /* Check that we have sufficient operands in the stack */ - if ( top >= parser->stack + 2 ) - { - /* Now check that the first operand is an immediate. */ - /* If so, call the appropriate `def' routine based */ - /* on the current parser state. */ - if ( top[-2].kind == tok_immediate ) - { - parser->top -= 2; - parser->args = parser->top + 1; - error = def_funcs[dict_state](parser); - } - else - { - /* This is an error, but some fonts contain */ - /* stupid Postscript code. We simply ignore */ - /* an invalid `def' by clearing the stack. */ -#if 0 - FT_ERROR(( "Parse_T1_FontProgram: immediate expected\n" )); - goto Syntax_Error; -#else - parser->top = parser->stack; -#endif - } - } - else - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - } - break; - - case key_index: - if ( top <= parser->stack ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - /* simply ignore? */ - parser->top --; - break; - - case key_put: - /* Check that we have sufficient operands in stack */ - if ( top < parser->stack + 2 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 2; - parser->args = parser->top; - - switch ( dict_state ) - { - case dict_encoding: - error = Do_Put_Encoding( parser ); - if ( error ) - goto Exit; - break; - - case dict_unknown_array: /* ignore the `put' */ - break; - - default: -#if 0 - FT_ERROR(( "Parse_T1_FontProgram: invalid context\n" )); - goto Syntax_Error; -#else - /* invalid context; simply ignore the `put' and */ - /* clear the stack (stupid Postscript code) */ - FT_TRACE4(( "Parse_T1_FontProgram: invalid context ignored.\n" )); - parser->top = parser->stack; -#endif - } - break; - - case key_RD: - /* Check that we have sufficient operands in stack */ - if ( top < parser->stack + 2 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 2; - parser->args = parser->top; - switch ( dict_state ) - { - case dict_subrs: - error = Do_RD_Subrs( parser ); - if ( error ) - goto Exit; - break; - - case dict_charstrings: - error = Do_RD_Charstrings( parser ); - if ( error ) - goto Exit; - break; - - default: - FT_ERROR(( "Parse_T1_FontProgram: invalid context\n" )); - goto Syntax_Error; - } - break; - - case key_end: - /* Were we in a dictionary or in an array? */ - if ( dict_index <= 0 ) - { - FT_ERROR(( "Parse_T1_FontProgram: no dictionary defined\n" )); - goto Syntax_Error; - } - - switch ( dict_state ) - { - /* jump to the private dictionary if we are closing the */ - /* `/Font' dictionary */ - case dict_font: - goto Open_Private; - - /* exit the parser when closing the CharStrings dictionary */ - case dict_charstrings: - return Finalize_Parsing( parser ); - - default: - /* Pop the current dictionary state and return to previous */ - /* one. Consume the `def'. */ - - /* Because some buggy fonts (BitStream) have incorrect */ - /* syntax, we never escape from the private dictionary */ - if ( dict_state != dict_private ) - parser->state_index--; - - /* many fonts use `NP' instead of `def' or `put', so */ - /* we simply ignore the next token */ -#if 0 - error = Expect_Keyword2( parser, key_def, key_put ); - if ( error ) - goto Exit; -#else - (void)Expect_Keyword2( parser, key_def, key_put ); -#endif - } - break; - - case key_for: - /* check that we have four arguments and simply */ - /* ignore them */ - if ( top - parser->stack < 4 ) - { - FT_ERROR(( "Parse_T1_FontProgram: not enough arguments\n" )); - goto Stack_Underflow; - } - - parser->top -= 4; - break; - - case key_currentdict: - Open_Private: - parser->state_index = 0; - parser->state_stack[0] = dict_none2; - error = Open_PrivateDict( parser->tokenizer ); - if ( error ) - goto Exit; - break; - - case key_true: - case key_false: - case key_StandardEncoding: - case key_ExpertEncoding: - goto Push_Element; - - default: - FT_ERROR(( "Parse_T1_FontProgram:" )); - FT_ERROR(( " invalid keyword in context\n" )); - error = T1_Err_Syntax_Error; - } - break; - - /* check for the presence of `/BlendAxisTypes' -- we cannot deal */ - /* with multiple master fonts, so we must return a correct error */ - /* code to allow another driver to load them */ - case tok_immediate: - if ( token.kind2 == imm_BlendAxisTypes ) - { - error = FT_Err_Unknown_File_Format; - goto Exit; - } - /* fallthrough */ - - /* A number was detected */ - case tok_string: - case tok_program: - case tok_array: - case tok_hexarray: - case tok_any: - case tok_number: /* push number on stack */ - - Push_Element: - if ( top >= parser->limit ) - { - error = T1_Err_Stack_Overflow; - goto Exit; - } - else - *parser->top++ = token; - break; - - /* anything else is an error per se the spec, but we */ - /* frequently encounter stupid postscript code in fonts, */ - /* so just ignore them */ - default: - error = T1_Err_Ok; /* ignore token */ - } - - if ( error ) - return error; - } - - Exit: - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1load.h b/subsys/win32k/freetype/src/type1/t1load.h deleted file mode 100644 index b1671c6..0000000 --- a/subsys/win32k/freetype/src/type1/t1load.h +++ /dev/null @@ -1,57 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1load.h */ -/* */ -/* Type 1 font loader (specification). */ -/* */ -/* Copyright 1996-2000 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 T1LOAD_H -#define T1LOAD_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1parse.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - LOCAL_DEF - void Init_T1_Parser( T1_Parser* parser, - T1_Face face, - T1_Tokenizer tokenizer ); - - - LOCAL_DEF - FT_Error Parse_T1_FontProgram( T1_Parser* parser ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1LOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1objs.c b/subsys/win32k/freetype/src/type1/t1objs.c deleted file mode 100644 index 31a74a5..0000000 --- a/subsys/win32k/freetype/src/type1/t1objs.c +++ /dev/null @@ -1,544 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.c */ -/* */ -/* Type 1 objects manager (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t1gload.h" -#include "t1load.h" -#include "t1afm.h" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.h" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1objs - - - /*************************************************************************/ - /* */ - /* SIZE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Size */ - /* */ - /* */ - /* The Type 1 size object destructor. Used to discard a given size */ - /* object. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - LOCAL_FUNC - void T1_Done_Size( T1_Size size ) - { - if ( size ) - { - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - T1_Done_Size_Hinter( size ); -#endif - - size->valid = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Size */ - /* */ - /* */ - /* The size object initializer. */ - /* */ - /* */ - /* size :: A handle to the target size object. */ - /* */ - /* */ - /* FreeTrue error code. 0 means success. */ - /* */ - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ) - { - FT_Error error; - - - size->valid = 0; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - error = T1_New_Size_Hinter( size ); - - return error; -#else - - FT_UNUSED( error ); - - return T1_Err_Ok; - -#endif - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Reset_Size */ - /* */ - /* */ - /* Resets an instance to a new pointsize/transform. This function is */ - /* in charge of resetting the blue zones,a s well as the stem snap */ - /* tables for a given size. */ - /* */ - /* */ - /* size :: The target size object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Reset_Size( T1_Size size ) - { - /* recompute ascender, descender, etc. */ - T1_Face face = (T1_Face)size->root.face; - FT_Size_Metrics* metrics = &size->root.metrics; - - - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) - return FT_Err_Invalid_Argument; - - /* Compute root ascender, descender, test height, and max_advance */ - metrics->ascender = ( FT_MulFix( face->root.ascender, - metrics->y_scale ) + 32 ) & -64; - metrics->descender = ( FT_MulFix( face->root.descender, - metrics->y_scale ) + 32 ) & -64; - metrics->height = ( FT_MulFix( face->root.height, - metrics->y_scale ) + 32 ) & -64; - metrics->max_advance = ( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) + 32 ) & -64; - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - return T1_Reset_Size_Hinter( size ); -#else - return 0; -#endif - } - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Face */ - /* */ - /* */ - /* The face object destructor. */ - /* */ - /* */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ - LOCAL_FUNC - void T1_Done_Face( T1_Face face ) - { - FT_Memory memory; - T1_Font* type1 = &face->type1; - - - if ( face ) - { - memory = face->root.memory; - - /* release font info strings */ - { - T1_FontInfo* info = &type1->font_info; - - - FREE( info->version ); - FREE( info->notice ); - FREE( info->full_name ); - FREE( info->family_name ); - FREE( info->weight ); - } - - /* release top dictionary */ - FREE( type1->charstrings_len ); - FREE( type1->charstrings ); - FREE( type1->glyph_names ); - - FREE( type1->subrs ); - FREE( type1->subrs_len ); - - FREE( type1->subrs_block ); - FREE( type1->charstrings_block ); - FREE( type1->glyph_names_block ); - - FREE( type1->encoding.char_index ); - FREE( type1->font_name ); - -#ifndef T1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); -#endif - - /* release unicode map, if any */ - FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; - - face->root.family_name = 0; - face->root.style_name = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_Face */ - /* */ - /* */ - /* The face object constructor. */ - /* */ - /* */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The face record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - T1_Tokenizer tokenizer; - FT_Error error; - PSNames_Interface* psnames; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( face ); - - - face->root.num_faces = 1; - - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Interface*) - FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), - "psnames" ); - - face->psnames = psnames; - } - - /* open the tokenizer, this will also check the font format */ - error = New_Tokenizer( stream, &tokenizer ); - if ( error ) - goto Fail; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Leave; - - /* check the face index */ - if ( face_index != 0 ) - { - FT_ERROR(( "T1_Init_Face: invalid face index\n" )); - error = T1_Err_Invalid_Argument; - goto Leave; - } - - /* Now, load the font program into the face object */ - { - T1_Parser parser; - - - Init_T1_Parser( &parser, face, tokenizer ); - error = Parse_T1_FontProgram( &parser ); - if ( error ) - goto Leave; - - /* Init the face object fields */ - /* Now set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - T1_Font* type1 = &face->type1; - - - root->num_glyphs = type1->num_glyphs; - root->num_charmaps = 1; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - - if ( type1->font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - /* XXX: TODO -- add kerning with .afm support */ - - /* get style name - be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = type1->font_info.family_name; - if ( root->family_name ) - { - char* full = type1->font_info.full_name; - char* family = root->family_name; - - - while ( *family && *full == *family ) - { - family++; - full++; - } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); - } - else - { - /* do we have a `/FontName'? */ - if (type1->font_name) - { - root->family_name = type1->font_name; - root->style_name = "Regular"; - } - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox = type1->font_bbox; - root->units_per_EM = 1000; - root->ascender = (FT_Short)type1->font_bbox.yMax; - root->descender = -(FT_Short)type1->font_bbox.yMin; - root->height = ( ( root->ascender + root->descender) * 12 ) - / 10; - - /* now compute the maximum advance width */ - - root->max_advance_width = type1->private_dict.standard_width[0]; - - /* compute max advance width for proportional fonts */ - if ( !type1->font_info.is_fixed_pitch ) - { - FT_Int max_advance; - - - error = T1_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = max_advance; - else - error = 0; /* clear error */ - } - - root->max_advance_height = root->height; - - root->underline_position = type1->font_info.underline_position; - root->underline_thickness = type1->font_info.underline_thickness; - - root->max_points = 0; - root->max_contours = 0; - } - } - - /* charmap support - synthetize unicode charmap when possible */ - { - FT_Face root = &face->root; - FT_CharMap charmap = face->charmaprecs; - - - /* synthesize a Unicode charmap if there is support in the `PSNames' */ - /* module.. */ - if ( face->psnames ) - { - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - if ( psnames->unicode_value ) - { - error = psnames->build_unicodes( - root->memory, - face->type1.num_glyphs, - (const char**)face->type1.glyph_names, - &face->unicode_map ); - if ( !error ) - { - root->charmap = charmap; - charmap->face = (FT_Face)face; - charmap->encoding = ft_encoding_unicode; - charmap->platform_id = 3; - charmap->encoding_id = 1; - charmap++; - } - - /* simply clear the error in case of failure (which really) */ - /* means that out of memory or no unicode glyph names */ - error = 0; - } - } - - /* now, support either the standard, expert, or custom encodings */ - charmap->face = (FT_Face)face; - charmap->platform_id = 7; /* a new platform id for Adobe fonts ?? */ - - switch ( face->type1.encoding_type ) - { - case t1_encoding_standard: - charmap->encoding = ft_encoding_adobe_standard; - charmap->encoding_id = 0; - break; - - case t1_encoding_expert: - charmap->encoding = ft_encoding_adobe_expert; - charmap->encoding_id = 1; - break; - - default: - charmap->encoding = ft_encoding_adobe_custom; - charmap->encoding_id = 2; - break; - } - - root->charmaps = face->charmaps; - root->num_charmaps = charmap - face->charmaprecs + 1; - face->charmaps[0] = &face->charmaprecs[0]; - face->charmaps[1] = &face->charmaprecs[1]; - } - - Leave: - Done_Tokenizer( tokenizer ); - - Fail: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_GlyphSlot */ - /* */ - /* */ - /* The glyph slot object destructor. */ - /* */ - /* */ - /* glyph :: The glyph slot handle to destroy. */ - /* */ - LOCAL_FUNC - void T1_Done_GlyphSlot( T1_GlyphSlot glyph ) - { -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - T1_Done_Glyph_Hinter( glyph ); - -#else - - FT_UNUSED( glyph ); - -#endif - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Init_GlyphSlot */ - /* */ - /* */ - /* The glyph slot object constructor. */ - /* */ - /* */ - /* glyph :: The glyph slot handle to initialize. */ - /* */ - LOCAL_FUNC - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot glyph ) - { - FT_Error error = FT_Err_Ok; - - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER - - error = T1_New_Glyph_Hinter( glyph ); - -#else - - FT_UNUSED( glyph ); - -#endif - - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1objs.h b/subsys/win32k/freetype/src/type1/t1objs.h deleted file mode 100644 index 47b0a37..0000000 --- a/subsys/win32k/freetype/src/type1/t1objs.h +++ /dev/null @@ -1,172 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1objs.h */ -/* */ -/* Type 1 objects manager (specification). */ -/* */ -/* Copyright 1996-2000 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 T1OBJS_H -#define T1OBJS_H - -#include -#include -#include - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /* The following structures must be defined by the hinter */ - typedef struct T1_Size_Hints_ T1_Size_Hints; - typedef struct T1_Glyph_Hints_ T1_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Driver */ - /* */ - /* */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct T1_DriverRec_* T1_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct T1_SizeRec_* T1_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct T1_GlyphSlotRec_* T1_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct T1_CharMapRec_* T1_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_SizeRec */ - /* */ - /* */ - /* Type 1 size record. */ - /* */ - typedef struct T1_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - T1_Size_Hints* hints; /* defined in the hinter. This allows */ - /* us to experiment with different */ - /* hinting schemes without having to */ - /* change `t1objs' each time. */ - } T1_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_GlyphSlotRec */ - /* */ - /* */ - /* Type 1 glyph slot record. */ - /* */ - typedef struct T1_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Int max_points; - FT_Int max_contours; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - T1_Glyph_Hints* hints; /* defined in the hinter */ - - } T1_GlyphSlotRec; - - - LOCAL_DEF - FT_Error T1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void T1_Done_Face( T1_Face face ); - - LOCAL_DEF - FT_Error T1_Init_Size( T1_Size size ); - - LOCAL_DEF - void T1_Done_Size( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Reset_Size( T1_Size size ); - - LOCAL_DEF - FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot ); - - LOCAL_DEF - void T1_Done_GlyphSlot( T1_GlyphSlot slot ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1OBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1parse.c b/subsys/win32k/freetype/src/type1/t1parse.c deleted file mode 100644 index b025df2..0000000 --- a/subsys/win32k/freetype/src/type1/t1parse.c +++ /dev/null @@ -1,761 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "t1parse.h" - -#else - -#include - -#endif - - -#include /* for sscanf() */ -#include /* for strncpy() */ - - - /*************************************************************************/ - /* */ - /* */ - /* T1_New_Table */ - /* */ - /* */ - /* Initializes a T1_Table structure. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size (i.e. maximum number of elements). */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error T1_New_Table( T1_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) ) - return error; - - if ( ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - { - FREE( table->elements ); - return error; - } - - table->max_elems = count; - table->num_elems = 0; - - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - return error; - } - - - static - FT_Error reallocate_t1_table( T1_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* reallocate the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - table->capacity = new_size; - - /* shift all offsets if necessary */ - if ( old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset ++ ) - if (offset[0]) - offset[0] += delta; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Add_Table */ - /* */ - /* */ - /* Adds an object to a T1_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation failed. */ - /* */ - LOCAL_FUNC - FT_Error T1_Add_Table( T1_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "T1_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Done_Table */ - /* */ - /* */ - /* Finalize a T1_Table (reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void T1_Done_Table( T1_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - { - FT_Long delta = table->block - old_base; - FT_Byte** element = table->elements; - FT_Byte** limit = element + table->max_elems; - - - for ( ; element < limit; element++ ) - if ( element[0] ) - element[0] += delta; - } - } - - - LOCAL_FUNC - FT_String* CopyString( T1_Parser* parser ) - { - FT_String* string = NULL; - T1_Token* token = parser->args++; - FT_Memory memory = parser->tokenizer->memory; - FT_Error error; - - - if ( token->kind == tok_string ) - { - FT_Int len = token->len - 2; - - - if ( ALLOC( string, len + 1 ) ) - { - parser->error = error; - return 0; - } - - MEM_Copy( string, parser->tokenizer->base + token->start + 1, len ); - string[len] = '\0'; - - parser->error = T1_Err_Ok; - } - else - { - FT_ERROR(( "T1_CopyString: syntax error, string token expected!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - return string; - } - - - static - FT_Error parse_int( FT_Byte* base, - FT_Byte* limit, - FT_Long* result ) - { - FT_Bool sign = 0; - FT_Long sum = 0; - - - if ( base >= limit ) - goto Fail; - - /* check sign */ - if ( *base == '+' ) - base++; - - else if ( *base == '-' ) - { - sign++; - base++; - } - - /* parse digits */ - if ( base >= limit ) - goto Fail; - - do - { - sum = ( 10 * sum + ( *base++ - '0' ) ); - - } while ( base < limit ); - - if ( sign ) - sum = -sum; - - *result = sum; - return T1_Err_Ok; - - Fail: - FT_ERROR(( "parse_int: integer expected\n" )); - *result = 0; - return T1_Err_Syntax_Error; - } - - - static - FT_Error parse_float( FT_Byte* base, - FT_Byte* limit, - FT_Long scale, - FT_Long* result ) - { -#if 1 - - /* XXX: We are simply much too lazy to code this function */ - /* properly for now. We will do that when the rest of */ - /* the driver works properly. */ - char temp[32]; - int len = limit - base; - double value; - - - if ( len > 31 ) - goto Fail; - - strncpy( temp, (char*)base, len ); - temp[len] = '\0'; - if ( sscanf( temp, "%lf", &value ) != 1 ) - goto Fail; - - *result = (FT_Long)( scale * value ); - return 0; - -#else - - FT_Byte* cur; - FT_Bool sign = 0; /* sign */ - FT_Long number_int = 0; /* integer part */ - FT_Long number_frac = 0; /* fractional part */ - FT_Long exponent = 0; /* exponent value */ - FT_Int num_frac = 0; /* number of fractional digits */ - - - /* check sign */ - if ( *base == '+' ) - base++; - - else if ( *base == '-' ) - { - sign++; - base++; - } - - /* find integer part */ - cur = base; - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( c == '.' || c == 'e' || c == 'E' ) - break; - - cur++; - } - - if ( cur > base ) - { - error = parse_integer( base, cur, &number_int ); - if ( error ) - goto Fail; - } - - /* read fractional part, if any */ - if ( *cur == '.' ) - { - cur++; - base = cur; - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( c == 'e' || c == 'E' ) - break; - cur++; - } - - num_frac = cur - base; - - if ( cur > base ) - { - error = parse_integer( base, cur, &number_frac ); - if ( error ) - goto Fail; - base = cur; - } - } - - /* read exponent, if any */ - if ( *cur == 'e' || *cur == 'E' ) - { - cur++; - base = cur; - error = parse_integer( base, limit, &exponent ); - if ( error ) - goto Fail; - - /* now check that exponent is within `correct bounds' */ - /* i.e. between -6 and 6 */ - if ( exponent < -6 || exponent > 6 ) - goto Fail; - } - - /* now adjust integer value and exponent for fractional part */ - while ( num_frac > 0 ) - { - number_int *= 10; - exponent--; - num_frac--; - } - - number_int += num_frac; - - /* skip point if any, read fractional part */ - if ( cur + 1 < limit ) - { - if (*cur.. - } - - /* now compute scaled float value */ - /* XXX: incomplete! */ - -#endif /* 1 */ - - Fail: - FT_ERROR(( "parse_float: syntax error!\n" )); - return T1_Err_Syntax_Error; - } - - - static - FT_Error parse_integer( FT_Byte* base, - FT_Byte* limit, - FT_Long* result ) - { - FT_Byte* cur; - - - /* the lexical analyser accepts floats as well as integers */ - /* now; check that we really have an int in this token */ - cur = base; - while ( cur < limit ) - { - FT_Byte c = *cur++; - - - if ( c == '.' || c == 'e' || c == 'E' ) - goto Float_Number; - } - - /* now read the number's value */ - return parse_int( base, limit, result ); - - Float_Number: - /* we really have a float there; simply call parse_float in this */ - /* case with a scale of `10' to perform round */ - { - FT_Error error; - - - error = parse_float( base, limit, 10, result ); - if ( !error ) - { - if ( *result >= 0 ) - *result = ( *result + 5 ) / 10; /* round value */ - else - *result = -( ( 5 - *result ) / 10 ); - } - return error; - } - } - - - LOCAL_FUNC - FT_Long CopyInteger( T1_Parser* parser ) - { - FT_Long sum = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_number ) - { - FT_Byte* base = parser->tokenizer->base + token->start; - FT_Byte* limit = base + token->len; - - - /* now read the number's value */ - parser->error = parse_integer( base, limit, &sum ); - return sum; - } - - FT_ERROR(( "CopyInteger: number expected\n" )); - parser->args--; - parser->error = T1_Err_Syntax_Error; - return 0; - } - - - LOCAL_FUNC - FT_Bool CopyBoolean( T1_Parser* parser ) - { - FT_Error error = T1_Err_Ok; - FT_Bool result = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_keyword ) - { - if ( token->kind2 == key_false ) - result = 0; - - else if ( token->kind2 == key_true ) - result = !0; - - else - goto Fail; - } - else - { - Fail: - FT_ERROR(( "CopyBoolean:" )); - FT_ERROR(( " syntax error; `false' or `true' expected\n" )); - error = T1_Err_Syntax_Error; - } - parser->error = error; - return result; - } - - - LOCAL_FUNC - FT_Long CopyFloat( T1_Parser* parser, - FT_Int scale ) - { - FT_Error error; - FT_Long sum = 0; - T1_Token* token = parser->args++; - - - if ( token->kind == tok_number ) - { - FT_Byte* base = parser->tokenizer->base + token->start; - FT_Byte* limit = base + token->len; - - - error = parser->error = parse_float( base, limit, scale, &sum ); - if ( error ) - goto Fail; - - return sum; - } - - Fail: - FT_ERROR(( "CopyFloat: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - return 0; - } - - - LOCAL_FUNC - void CopyBBox( T1_Parser* parser, - FT_BBox* bbox ) - { - T1_Token* token = parser->args++; - FT_Int n; - FT_Error error; - - - if ( token->kind == tok_program || - token->kind == tok_array ) - { - /* get rid of `['/`]', or `{'/`}' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < 4; n++ ) - { - FT_Long* result; - - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ' ) - cur++; - - /* compute result address */ - switch ( n ) - { - case 0: - result = &bbox->xMin; - break; - case 1: - result = &bbox->yMin; - break; - case 2: - result = &bbox->xMax; - break; - default: - result = &bbox->yMax; - } - - error = parse_integer( start, cur, result ); - if ( error ) - goto Fail; - } - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyBBox: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - - LOCAL_FUNC - void CopyMatrix( T1_Parser* parser, - FT_Matrix* matrix ) - { - T1_Token* token = parser->args++; - FT_Error error; - - - if ( token->kind == tok_array ) - { - /* get rid of `[' and `]' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - FT_Int n; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < 4; n++ ) - { - FT_Long* result; - - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ') - cur++; - - /* compute result address */ - switch ( n ) - { - case 0: - result = &matrix->xx; - break; - case 1: - result = &matrix->yx; - break; - case 2: - result = &matrix->xy; - break; - default: - result = &matrix->yy; - } - - error = parse_float( start, cur, 65536000L, result ); - if ( error ) - goto Fail; - } - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyMatrix: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - - LOCAL_FUNC - void CopyArray( T1_Parser* parser, - FT_Byte* num_elements, - FT_Short* elements, - FT_Int max_elements ) - { - T1_Token* token = parser->args++; - FT_Error error; - - - if ( token->kind == tok_array || - token->kind == tok_program ) /* in the case of MinFeature */ - { - /* get rid of `['/`]', or `{'/`}' */ - FT_Byte* base = parser->tokenizer->base + token->start + 1; - FT_Byte* limit = base + token->len - 2; - FT_Byte* cur; - FT_Byte* start; - FT_Int n; - - - /* read each parameter independently */ - cur = base; - for ( n = 0; n < max_elements; n++ ) - { - FT_Long result; - - - /* test end of string */ - if ( cur >= limit ) - break; - - /* skip whitespace */ - while ( cur < limit && *cur == ' ' ) - cur++; - - /* end of list? */ - if ( cur >= limit ) - break; - - /* skip numbers */ - start = cur; - while ( cur < limit && *cur != ' ' ) - cur++; - - error = parse_integer( start, cur, &result ); - if ( error ) - goto Fail; - - *elements++ = (FT_Short)result; - } - - if ( num_elements ) - *num_elements = (FT_Byte)n; - - parser->error = 0; - return; - } - - Fail: - FT_ERROR(( "CopyArray: syntax error!\n" )); - parser->error = T1_Err_Syntax_Error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1parse.h b/subsys/win32k/freetype/src/type1/t1parse.h deleted file mode 100644 index a064629..0000000 --- a/subsys/win32k/freetype/src/type1/t1parse.h +++ /dev/null @@ -1,261 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.h */ -/* */ -/* Type 1 parser (specification). */ -/* */ -/* Copyright 1996-2000 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 Type1 parser component is in charge of simply parsing the font */ - /* input stream and convert simple tokens and elements into integers, */ - /* floats, matrices, strings, etc. */ - /* */ - /* It is used by the Type1 loader. */ - /* */ - /*************************************************************************/ - - -#ifndef T1PARSE_H -#define T1PARSE_H - -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* T1_DictState */ - /* */ - /* */ - /* An enumeration used to describe the Type 1 parser's state, i.e. */ - /* which dictionary (or array) it is scanning and processing at the */ - /* current moment. */ - /* */ - typedef enum T1_DictState_ - { - dict_none = 0, - dict_font, /* parsing the font dictionary */ - dict_fontinfo, /* parsing the font info dictionary */ - dict_none2, /* beginning to parse the encrypted section */ - dict_private, /* parsing the private dictionary */ - dict_encoding, /* parsing the encoding array */ - dict_subrs, /* parsing the subrs array */ - dict_othersubrs, /* parsing the othersubrs array (?) */ - dict_charstrings, /* parsing the charstrings dictionary */ - dict_unknown_array, /* parsing/ignoring an unknown array */ - dict_unknown_dict, /* parsing/ignoring an unknown dictionary */ - - dict_max /* do not remove from list */ - - } T1_DictState; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Table */ - /* */ - /* */ - /* A T1_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments by */ - /* 1kByte chunks. */ - /* */ - /* max_elems :: The maximum number of elements in table. */ - /* */ - /* num_elems :: The current number of elements in table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The object used for memory operations */ - /* (alloc/realloc). */ - /* */ - typedef struct T1_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } T1_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Parser */ - /* */ - /* */ - /* A Type 1 parser. This object is in charge of parsing Type 1 ASCII */ - /* streams and builds dictionaries for a T1_Face object. */ - /* */ - /* */ - /* error :: The current error code. 0 means success. */ - /* */ - /* face :: The target T1_Face object being built. */ - /* */ - /* tokenizer :: The tokenizer (lexical analyser) used for */ - /* processing the input stream. */ - /* */ - /* dump_tokens :: XXX */ - /* */ - /* stack :: The current token stack. Note that we don't */ - /* use intermediate Postscript objects here! */ - /* */ - /* top :: The current top of token stack. */ - /* */ - /* limit :: The current upper bound of the token stack. */ - /* Used for overflow checks. */ - /* */ - /* args :: The arguments of a given operator. Used and */ - /* increased by the various CopyXXX() functions. */ - /* */ - /* state_index :: The index of the top of the dictionary state */ - /* stack. */ - /* */ - /* state_stack :: The dictionary states stack. */ - /* */ - /* table :: A T1_Table object used to record various kinds */ - /* of dictionaries or arrays (like `/Encoding', */ - /* `/Subrs', `/CharStrings'). */ - /* */ - /* cur_name :: XXX */ - /* */ - /* encoding_type :: XXX */ - /* */ - /* encoding_names :: XXX */ - /* */ - /* encoding_lengths :: XXX */ - /* */ - /* encoding_offsets :: XXX */ - /* */ - /* subrs :: XXX */ - /* */ - /* charstrings :: XXX */ - /* */ - typedef struct T1_Parser_ - { - FT_Error error; - T1_Face face; - - T1_Tokenizer tokenizer; - FT_Bool dump_tokens; - - T1_Token stack[T1_MAX_STACK_DEPTH]; - T1_Token* top; - T1_Token* limit; - T1_Token* args; - - FT_Int state_index; - T1_DictState state_stack[T1_MAX_DICT_DEPTH]; - - T1_Table table; - - FT_Int cur_name; - - T1_EncodingType encoding_type; - FT_Byte* encoding_names; - FT_Int* encoding_lengths; - FT_Byte** encoding_offsets; - - FT_Byte* subrs; - FT_Byte* charstrings; - - } T1_Parser; - - - LOCAL_DEF - FT_Error T1_New_Table( T1_Table* table, - FT_Int count, - FT_Memory memory ); - - LOCAL_DEF - FT_Error T1_Add_Table( T1_Table* table, - FT_Int index, - void* object, - FT_Int length ); - - LOCAL_DEF - void T1_Done_Table( T1_Table* table ); - - - LOCAL_DEF - FT_String* CopyString( T1_Parser* parser ); - - LOCAL_DEF - FT_Long CopyInteger( T1_Parser* parser ); - - LOCAL_DEF - FT_Bool CopyBoolean( T1_Parser* parser ); - - LOCAL_DEF - FT_Long CopyFloat( T1_Parser* parser, - FT_Int scale ); - - LOCAL_DEF - void CopyBBox( T1_Parser* parser, - FT_BBox* bbox ); - - LOCAL_DEF - void CopyMatrix( T1_Parser* parser, - FT_Matrix* matrix ); - - LOCAL_DEF - void CopyArray( T1_Parser* parser, - FT_Byte* num_elements, - FT_Short* elements, - FT_Int max_elements ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1PARSE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1tokens.c b/subsys/win32k/freetype/src/type1/t1tokens.c deleted file mode 100644 index b90024d..0000000 --- a/subsys/win32k/freetype/src/type1/t1tokens.c +++ /dev/null @@ -1,1101 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1parse.c */ -/* */ -/* Type 1 parser (body). */ -/* */ -/* Copyright 1996-2000 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 tokenizer is in charge of loading and reading a Type1 font file */ - /* (either in PFB or PFA format), and extracting successive tokens and */ - /* keywords from its two streams (i.e. the font program, and the private */ - /* dictionary). */ - /* */ - /* Eexec decryption is performed automatically when entering the private */ - /* dictionary, or when retrieving char strings. */ - /* */ - /*************************************************************************/ - - -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "t1tokens.h" -#include "t1load.h" - -#else - -#include -#include - -#endif - - -#include /* for strncmp() */ - - -#undef READ_BUFFER_INCREMENT -#define READ_BUFFER_INCREMENT 0x400 - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t1load - - - /* An array of Type1 keywords supported by this engine. This table */ - /* places the keyword in lexicographical order. It should always */ - /* correspond to the enums `key_xxx'! */ - /* */ - const char* t1_keywords[key_max - key_first_] = - { - "-|", "ExpertEncoding", "ND", "NP", "RD", "StandardEncoding", "array", - "begin", "closefile", "currentdict", "currentfile", "def", "dict", "dup", - "eexec", "end", "executeonly", "false", "for", "index", "noaccess", - "put", "readonly", "true", "userdict", "|", "|-" - }; - - - const char* t1_immediates[imm_max - imm_first_] = - { - "-|", ".notdef", "BlendAxisTypes", "BlueFuzz", "BlueScale", "BlueShift", - "BlueValues", "CharStrings", "Encoding", "FamilyBlues", "FamilyName", - "FamilyOtherBlues", "FID", "FontBBox", "FontID", "FontInfo", "FontMatrix", - "FontName", "FontType", "ForceBold", "FullName", "ItalicAngle", - "LanguageGroup", "Metrics", "MinFeature", "ND", "NP", "Notice", - "OtherBlues", "OtherSubrs", "PaintType", "Private", "RD", "RndStemUp", - "StdHW", "StdVW", "StemSnapH", "StemSnapV", "StrokeWidth", "Subrs", - "UnderlinePosition", "UnderlineThickness", "UniqueID", "Weight", - "isFixedPitch", "lenIV", "password", "version", "|", "|-" - }; - - - /* lexicographic comparison of two strings */ - static - int lexico_strcmp( const char* str1, - int str1_len, - const char* str2 ) - { - int c2 = 0; - - - for ( ; str1_len > 0; str1_len-- ) - { - int c1, diff; - - - c1 = *str1++; - c2 = *str2++; - - diff = c1 - c2; - if ( diff ) - return diff; - }; - - return -*str2; - } - - - /* find a given token/name, performing binary search */ - static - int Find_Name( char* base, - int length, - const char** table, - int table_len ) - { - int left, right; - - - left = 0; - right = table_len - 1; - - while ( right - left > 1 ) - { - int middle = left + ( ( right - left ) >> 1 ); - int cmp; - - - cmp = lexico_strcmp( base, length, table[middle] ); - if ( !cmp ) - return middle; - - if ( cmp < 0 ) - right = middle; - else - left = middle; - } - - if ( !lexico_strcmp( base, length, table[left ] ) ) - return left; - if ( !lexico_strcmp( base, length, table[right] ) ) - return right; - - return -1; - } - - - /* read the small PFB section header */ - static - FT_Error Read_PFB_Tag( FT_Stream stream, - FT_UShort* atag, - FT_ULong* asize ) - { - FT_UShort tag; - FT_ULong size; - FT_Error error; - - - FT_TRACE2(( "Read_PFB_Tag: reading\n" )); - - if ( ACCESS_Frame( 6L ) ) - return error; - - tag = GET_UShort(); - size = GET_ULong(); - - FORGET_Frame(); - - *atag = tag; - *asize = ( ( size & 0xFF ) << 24 ) | - ( ( ( size >> 8 ) & 0xFF ) << 16 ) | - ( ( ( size >> 16 ) & 0xFF ) << 8 ) | - ( ( ( size >> 24 ) & 0xFF ) ); - - FT_TRACE2(( " tag = %04x\n", tag )); - FT_TRACE4(( " asze = %08x\n", size )); - FT_TRACE2(( " size = %08x\n", *asize )); - - return T1_Err_Ok; - } - - - static - FT_Error grow( T1_Tokenizer tokzer ) - { - FT_Error error; - FT_Long left_bytes; - FT_Memory memory = tokzer->memory; - - - left_bytes = tokzer->max - tokzer->limit; - - if ( left_bytes > 0 ) - { - FT_Stream stream = tokzer->stream; - - - if ( left_bytes > READ_BUFFER_INCREMENT ) - left_bytes = READ_BUFFER_INCREMENT; - - FT_TRACE2(( "Growing tokenizer buffer by %d bytes\n", left_bytes )); - - if ( !REALLOC( tokzer->base, tokzer->limit, - tokzer->limit + left_bytes ) && - !FILE_Read( tokzer->base + tokzer->limit, left_bytes ) ) - tokzer->limit += left_bytes; - } - else - { - FT_ERROR(( "Unexpected end of Type1 fragment!\n" )); - error = T1_Err_Invalid_File_Format; - } - - tokzer->error = error; - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1_decrypt */ - /* */ - /* */ - /* Performs the Type 1 charstring decryption process. */ - /* */ - /* */ - /* buffer :: The base address of the data to decrypt. */ - /* length :: The number of bytes to decrypt (beginning from the base */ - /* address. */ - /* seed :: The encryption seed (4330 for charstrings). */ - /* */ - LOCAL_FUNC - void t1_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = ( *buffer ^ ( seed >> 8 ) ); - seed = ( *buffer + seed ) * 52845 + 22719; - *buffer++ = plain; - length--; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* New_Tokenizer */ - /* */ - /* */ - /* Creates a new tokenizer from a given input stream. This function */ - /* automatically recognizes `pfa' or `pfb' files. The function */ - /* Read_Token() can then be used to extract successive tokens from */ - /* the stream. */ - /* */ - /* */ - /* stream :: The input stream. */ - /* */ - /* */ - /* tokenizer :: A handle to a new tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* This function copies the stream handle within the object. Callers */ - /* should not discard `stream'. This is done by the Done_Tokenizer() */ - /* function. */ - /* */ - LOCAL_FUNC - FT_Error New_Tokenizer( FT_Stream stream, - T1_Tokenizer* tokenizer ) - { - FT_Memory memory = stream->memory; - T1_Tokenizer tokzer; - FT_Error error; - FT_UShort tag; - FT_ULong size; - - FT_Byte* tok_base; - FT_ULong tok_limit; - FT_ULong tok_max; - - - *tokenizer = 0; - - /* allocate object */ - if ( FILE_Seek( 0L ) || - ALLOC( tokzer, sizeof ( *tokzer ) ) ) - return error; - - tokzer->stream = stream; - tokzer->memory = stream->memory; - - tokzer->in_pfb = 0; - tokzer->in_private = 0; - - tok_base = 0; - tok_limit = 0; - tok_max = stream->size; - - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error ) - goto Fail; - - if ( tag != 0x8001 ) - { - /* assume that it is a PFA file -- an error will be produced later */ - /* if a character with value > 127 is encountered */ - - /* rewind to start of file */ - if ( FILE_Seek( 0L ) ) - goto Fail; - - size = stream->size; - } - else - tokzer->in_pfb = 1; - - /* if it is a memory-based resource, set up pointer */ - if ( !stream->read ) - { - tok_base = (FT_Byte*)stream->base + stream->pos; - tok_limit = size; - tok_max = size; - - /* check that the `size' field is valid */ - if ( FILE_Skip( size ) ) - goto Fail; - } - else if ( tag == 0x8001 ) - { - /* read segment in memory */ - if ( ALLOC( tok_base, size ) ) - goto Fail; - - if ( FILE_Read( tok_base, size ) ) - { - FREE( tok_base ); - goto Fail; - } - - tok_limit = size; - tok_max = size; - } - - tokzer->base = tok_base; - tokzer->limit = tok_limit; - tokzer->max = tok_max; - tokzer->cursor = 0; - - *tokenizer = tokzer; - - /* now check font format; we must see `%!PS-AdobeFont-1' */ - /* or `%!FontType' */ - { - if ( 16 > tokzer->limit ) - grow( tokzer ); - - if ( tokzer->limit <= 16 || - ( strncmp( (const char*)tokzer->base, "%!PS-AdobeFont-1", 16 ) && - strncmp( (const char*)tokzer->base, "%!FontType", 10 ) ) ) - { - FT_TRACE2(( "[not a Type1 font]\n" )); - error = FT_Err_Unknown_File_Format; - goto Fail; - } - } - return T1_Err_Ok; - - Fail: - FREE( tokzer->base ); - FREE( tokzer ); - return error; - } - - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Done_Tokenizer */ - /* */ - /* */ - /* Closes a given tokenizer. This function will also close the */ - /* stream embedded in the object. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Done_Tokenizer( T1_Tokenizer tokenizer ) - { - FT_Memory memory = tokenizer->memory; - - - /* clear read buffer if needed (disk-based resources) */ - if ( tokenizer->in_private || !tokenizer->stream->base ) - FREE( tokenizer->base ); - - FREE( tokenizer ); - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Open_PrivateDict */ - /* */ - /* */ - /* This function must be called to set the tokenizer to the private */ - /* section of the Type1 file. It recognizes automatically the */ - /* the kind of eexec encryption used (ascii or binary). */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* lenIV :: The value of the `lenIV' variable. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Open_PrivateDict( T1_Tokenizer tokenizer ) - { - T1_Tokenizer tokzer = tokenizer; - FT_Stream stream = tokzer->stream; - FT_Memory memory = tokzer->memory; - FT_Error error = 0; - - FT_UShort tag; - FT_ULong size; - - FT_Byte* private_dict; - - /* are we already in the private dictionary ? */ - if ( tokzer->in_private ) - return 0; - - if ( tokzer->in_pfb ) - { - /* in the case of the PFB format, the private dictionary can be */ - /* made of several segments. We thus first read the number of */ - /* segments to compute the total size of the private dictionary */ - /* then re-read them into memory. */ - FT_Long start_pos = FILE_Pos(); - FT_ULong private_dict_size = 0; - - - for (;;) - { - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - break; - - private_dict_size += size; - - if ( FILE_Skip( size ) ) - goto Fail; - } - - /* check that we have a private dictionary there */ - /* and allocate private dictionary buffer */ - if ( private_dict_size == 0 ) - { - FT_ERROR(( "Open_PrivateDict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); - error = T1_Err_Invalid_File_Format; - goto Fail; - } - - if ( ALLOC( private_dict, private_dict_size ) ) - goto Fail; - - /* read all sections into buffer */ - if ( FILE_Seek( start_pos ) ) - goto Fail_Private; - - private_dict_size = 0; - for (;;) - { - error = Read_PFB_Tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - { - error = 0; - break; - } - - if ( FILE_Read( private_dict + private_dict_size, size ) ) - goto Fail_Private; - - private_dict_size += size; - } - - /* we must free the field `tokzer.base' if we are in a disk-based */ - /* PFB file. */ - if ( stream->read ) - FREE( tokzer->base ); - - tokzer->base = private_dict; - tokzer->cursor = 0; - tokzer->limit = private_dict_size; - tokzer->max = private_dict_size; - } - else - { - char* base; - - - /* we are in a PFA file; read each token until we find `eexec' */ - while ( tokzer->token.kind2 != key_eexec ) - { - error = Read_Token( tokzer ); - if ( error ) - goto Fail; - } - - /* now determine whether the private dictionary is encoded in binary */ - /* or hexadecimal ASCII format. */ - - /* we need to access the next 4 bytes (after the final \r following */ - /* the `eexec' keyword); if they all are hexadecimal digits, then */ - /* we have a case of ASCII storage. */ - while ( tokzer->cursor + 5 > tokzer->limit ) - { - error = grow( tokzer ); - if ( error ) - goto Fail; - } - - /* skip whitespace/line feed after `eexec' */ - base = (char*)tokzer->base + tokzer->cursor + 1; - if ( ( hexa_value( base[0] ) | hexa_value( base[1] ) | - hexa_value( base[2] ) | hexa_value( base[3] ) ) < 0 ) - { - /* binary encoding -- `simply' read the stream */ - - /* if it is a memory-based resource, we need to allocate a new */ - /* storage buffer for the private dictionary, as it must be */ - /* decrypted later */ - if ( stream->base ) - { - size = stream->size - tokzer->cursor - 1; /* remaining bytes */ - - if ( ALLOC( private_dict, size ) ) /* alloc private dict buffer */ - goto Fail; - - /* copy eexec-encrypted bytes */ - MEM_Copy( private_dict, tokzer->base + tokzer->cursor + 1, size ); - - /* reset pointers - forget about file mapping */ - tokzer->base = private_dict; - tokzer->limit = size; - tokzer->max = size; - tokzer->cursor = 0; - } - /* On the opposite, for disk based resources, we simply grow */ - /* the current buffer until its completion, and decrypt the */ - /* bytes within it. In all cases, the `base' buffer will be */ - /* discarded on DoneTokenizer if we are in the private dict. */ - else - { - /* grow the read buffer to the full file */ - while ( tokzer->limit < tokzer->max ) - { - error = grow( tokenizer ); - if ( error ) - goto Fail; - } - - /* set up cursor to first encrypted byte */ - tokzer->cursor++; - } - } - else - { - /* ASCII hexadecimal encoding. This sucks... */ - FT_Byte* write; - FT_Byte* cur; - FT_Byte* limit; - FT_Int count; - - - /* allocate a buffer, read each one byte at a time */ - count = stream->size - tokzer->cursor; - size = count / 2; - - if ( ALLOC( private_dict, size ) ) /* alloc private dict buffer */ - goto Fail; - - write = private_dict; - cur = tokzer->base + tokzer->cursor; - limit = tokzer->base + tokzer->limit; - - /* read each bytes */ - while ( count > 0 ) - { - /* ensure that we can read the next 2 bytes! */ - while ( cur + 2 > limit ) - { - int cursor = cur - tokzer->base; - - - error = grow( tokzer ); - if ( error ) - goto Fail_Private; - cur = tokzer->base + cursor; - limit = tokzer->base + tokzer->limit; - } - - /* check for new line */ - if ( cur[0] == '\r' || cur[0] == '\n' ) - { - cur++; - count--; - } - else - { - int hex1 = hexa_value(cur[0]); - - - /* exit if we have a non-hexadecimal digit which isn't */ - /* a new-line character */ - if ( hex1 < 0 ) - break; - - /* otherwise, store byte */ - *write++ = ( hex1 << 4 ) | hexa_value( cur[1] ); - cur += 2; - count -= 2; - } - } - - /* get rid of old buffer in the case of disk-based resources */ - if ( !stream->base ) - FREE( tokzer->base ); - - /* set up pointers */ - tokzer->base = private_dict; - tokzer->limit = size; - tokzer->max = size; - tokzer->cursor = 0; - } - } - - /* finally, decrypt the private dictionary - and skip the lenIV bytes */ - t1_decrypt( tokzer->base, tokzer->limit, 55665 ); - tokzer->cursor += 4; - - Fail: - return error; - - Fail_Private: - FREE( private_dict ); - goto Fail; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Read_Token */ - /* */ - /* */ - /* Reads a new token from the current input stream. This function */ - /* extracts a token from the font program until Open_PrivateDict() */ - /* has been called. After this, it returns tokens from the */ - /* (eexec-encrypted) private dictionary. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Use the function Read_CharStrings() to read the binary charstrings */ - /* from the private dict. */ - /* */ - LOCAL_FUNC - FT_Error Read_Token( T1_Tokenizer tokenizer ) - { - T1_Tokenizer tok = tokenizer; - FT_Long cur, limit; - FT_Byte* base; - char c, starter, ender; - FT_Bool token_started; - - T1_TokenType kind; - - - tok->error = T1_Err_Ok; - tok->token.kind = tok_any; - - base = tok->base; - limit = tok->limit; - cur = tok->cursor; - - token_started = 0; - - for (;;) - { - if ( cur >= limit ) - { - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - c = (char)base[cur++]; - - /* check that we have an ASCII character */ - if ( (FT_Byte)c > 127 ) - { - FT_ERROR(( "Read_Token:" )); - FT_ERROR(( " unexpected binary data in Type1 fragment!\n" )); - tok->error = T1_Err_Invalid_File_Format; - goto Exit; - } - - switch ( c ) - { - case '\r': - case '\n': - case ' ' : - case '\t': /* skip initial whitespace => skip to next */ - if ( token_started ) - { - /* possibly a name, keyword, wathever */ - tok->token.kind = tok_any; - tok->token.len = cur-tok->token.start - 1; - goto Exit; - } - /* otherwise, skip everything */ - break; - - case '%': /* this is a comment -- skip everything */ - for (;;) - { - FT_Int left = limit - cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - if ( c == '\r' || c == '\n' ) - goto Next; - left--; - } - - if ( grow( tokenizer ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '(': /* a Postscript string */ - kind = tok_string; - ender = ')'; - - L1: - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - } - - { - FT_Int nest_level = 1; - - - starter = c; - for (;;) - { - FT_Int left = limit - cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - - if ( c == starter ) - nest_level++; - - else if ( c == ender ) - { - nest_level--; - if ( nest_level <= 0 ) - { - tok->token.kind = kind; - tok->token.len = cur - tok->token.start; - goto Exit; - } - } - left--; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - } - - case '[': /* a Postscript array */ - if ( token_started ) - goto Any_Token; - - kind = tok_array; - ender = ']'; - goto L1; - break; - - case '{': /* a Postscript program */ - if ( token_started ) - goto Any_Token; - - kind = tok_program; - ender = '}'; - goto L1; - break; - - case '<': /* a Postscript hex byte array? */ - if ( token_started ) - goto Any_Token; - - kind = tok_hexarray; - ender = '>'; - goto L1; - break; - - case '0': /* any number */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ( token_started ) - goto Next; - - tok->token.kind = tok_number; - token_started = 1; - tok->token.start = cur - 1; - - L2: - for (;;) - { - FT_Int left = limit-cur; - - - while ( left > 0 ) - { - c = (char)base[cur++]; - - switch ( c ) - { - case '[': /* ] */ - case '{': /* } */ - case '(': /* ) */ - case '<': - case '/': - goto Any_Token; - - case ' ': - case '\r': - case '\t': - case '\n': - tok->token.len = cur - tok->token.start - 1; - goto Exit; - - default: - ; - } - left--; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '.': /* maybe a number */ - case '-': - case '+': - if ( token_started ) - goto Next; - - token_started = 1; - tok->token.start = cur - 1; - - for (;;) - { - FT_Int left = limit - cur; - - - if ( left > 0 ) - { - /* test for any following digit, interpreted as number */ - c = (char)base[cur]; - tok->token.kind = ( c >= '0' && c <= '9' ? tok_number : tok_any ); - goto L2; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - - case '/': /* maybe an immediate name */ - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - - for (;;) - { - FT_Int left = limit - cur; - - - if ( left > 0 ) - { - /* test for single '/', interpreted as garbage */ - c = (char)base[cur]; - tok->token.kind = ( c == ' ' || c == '\t' || - c == '\r' || c == '\n' ) ? tok_any - : tok_immediate; - goto L2; - } - - if ( grow( tok ) ) - goto Exit; - base = tok->base; - limit = tok->limit; - } - } - else - { - Any_Token: /* possibly a name or wathever */ - cur--; - tok->token.len = cur - tok->token.start; - goto Exit; - } - - default: - if ( !token_started ) - { - token_started = 1; - tok->token.start = cur - 1; - } - } - - Next: - ; - } - - Exit: - tok->cursor = cur; - - if ( !tok->error ) - { - /* now, tries to match keywords and immediate names */ - FT_Int index; - - - switch ( tok->token.kind ) - { - case tok_immediate: /* immediate name */ - index = Find_Name( (char*)( tok->base + tok->token.start + 1 ), - tok->token.len - 1, - t1_immediates, - imm_max - imm_first_ ); - tok->token.kind2 = ( index >= 0 ) - ? (T1_TokenType)( imm_first_ + index ) - : tok_error; - break; - - case tok_any: /* test for keyword */ - index = Find_Name( (char*)( tok->base + tok->token.start ), - tok->token.len, - t1_keywords, - key_max - key_first_ ); - if ( index >= 0 ) - { - tok->token.kind = tok_keyword; - tok->token.kind2 = (T1_TokenType)( key_first_ + index ); - } - else - tok->token.kind2 = tok_error; - break; - - default: - tok->token.kind2 = tok_error; - } - } - return tokenizer->error; - } - - -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* Read_CharStrings */ - /* */ - /* */ - /* Reads a charstrings element from the current input stream. These */ - /* are binary bytes that encode each individual glyph outline. */ - /* */ - /* The caller is responsible for skipping the `lenIV' bytes at the */ - /* start of the record. */ - /* */ - /* */ - /* tokenizer :: The target tokenizer object. */ - /* num_chars :: The number of binary bytes to read. */ - /* */ - /* */ - /* buffer :: The target array of bytes. These are */ - /* eexec-decrypted. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Use the function Read_CharStrings() to read binary charstrings */ - /* from the private dict. */ - /* */ - LOCAL_FUNC - FT_Error Read_CharStrings( T1_Tokenizer tokenizer, - FT_Int num_chars, - FT_Byte* buffer ) - { - for (;;) - { - FT_Int left = tokenizer->limit - tokenizer->cursor; - - - if ( left >= num_chars ) - { - MEM_Copy( buffer, tokenizer->base + tokenizer->cursor, num_chars ); - t1_decrypt( buffer, num_chars, 4330 ); - tokenizer->cursor += num_chars; - return T1_Err_Ok; - } - - if ( grow( tokenizer ) ) - return tokenizer->error; - } - } - -#endif /* 0 */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/t1tokens.h b/subsys/win32k/freetype/src/type1/t1tokens.h deleted file mode 100644 index c51b65c..0000000 --- a/subsys/win32k/freetype/src/type1/t1tokens.h +++ /dev/null @@ -1,258 +0,0 @@ -/***************************************************************************/ -/* */ -/* t1tokens.h */ -/* */ -/* Type 1 tokenizer (specification). */ -/* */ -/* Copyright 1996-2000 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 T1TOKENS_H -#define T1TOKENS_H - - -#ifdef FT_FLAT_COMPILE - -#include "t1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /* enum value of first keyword */ -#define key_first_ 100 - - /* enum value of first immediate name */ -#define imm_first_ 200 - - - typedef enum T1_TokenType_ - { - tok_error = 0, - - tok_eof, /* end of file */ - - /* simple token types */ - - tok_keyword, /* keyword */ - tok_number, /* number (integer or real) */ - tok_string, /* postscript string */ - tok_program, /* postscript program */ - tok_immediate, /* any immediate name */ - tok_array, /* matrix, array, etc.. */ - tok_hexarray, /* array of hexadecimal nibbles */ - tok_any, /* anything else */ - - /* Postscript keywords -- placed in lexicographical order */ - - key_RD_alternate = key_first_, /* `-|' = alternate form of RD */ - key_ExpertEncoding, - key_ND, - key_NP, - key_RD, - key_StandardEncoding, - key_array, - key_begin, - key_closefile, - key_currentdict, - key_currentfile, - key_def, - key_dict, - key_dup, - key_eexec, - key_end, - key_execonly, - key_false, - key_for, - key_index, - key_noaccess, - key_put, - key_readonly, - key_true, - key_userdict, - key_NP_alternate, /* `|' = alternate form of NP */ - key_ND_alternate, /* `|-' = alternate form of ND */ - - key_max, /* always keep this value there */ - - /* Postscript immediate names -- other names will be ignored, except */ - /* in charstrings */ - - imm_RD_alternate = imm_first_, /* `-|' = alternate form of RD */ - imm_notdef, /* `/.notdef' immediate */ - imm_BlendAxisTypes, - imm_BlueFuzz, - imm_BlueScale, - imm_BlueShift, - imm_BlueValues, - imm_CharStrings, - imm_Encoding, - imm_FamilyBlues, - imm_FamilyName, - imm_FamilyOtherBlues, - imm_FID, - imm_FontBBox, - imm_FontID, - imm_FontInfo, - imm_FontMatrix, - imm_FontName, - imm_FontType, - imm_ForceBold, - imm_FullName, - imm_ItalicAngle, - imm_LanguageGroup, - imm_Metrics, - imm_MinFeature, - imm_ND, - imm_NP, - imm_Notice, - imm_OtherBlues, - imm_OtherSubrs, - imm_PaintType, - imm_Private, - imm_RD, - imm_RndStemUp, - imm_StdHW, - imm_StdVW, - imm_StemSnapH, - imm_StemSnapV, - imm_StrokeWidth, - imm_Subrs, - imm_UnderlinePosition, - imm_UnderlineThickness, - imm_UniqueID, - imm_Weight, - - imm_isFixedPitch, - imm_lenIV, - imm_password, - imm_version, - - imm_NP_alternate, /* `|' = alternate form of NP */ - imm_ND_alternate, /* `|-' = alternate form of ND */ - - imm_max /* always keep this value here */ - - } T1_TokenType; - - - /* these arrays are visible for debugging purposes */ - extern const char* t1_keywords[]; - extern const char* t1_immediates[]; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Token */ - /* */ - /* */ - /* A structure used to describe a token in the current input stream. */ - /* Note that the Type1 driver doesn't try to interpret tokens until */ - /* it really needs to. */ - /* */ - /* */ - /* kind :: The token type. Describes the token to the loader. */ - /* */ - /* kind2 :: Detailed token type. */ - /* */ - /* start :: The index of the first character of token in the input */ - /* stream. */ - /* */ - /* len :: The length of the token in characters. */ - /* */ - typedef struct T1_Token_ - { - T1_TokenType kind; /* simple type */ - T1_TokenType kind2; /* detailed type */ - FT_Int start; /* index of first token character */ - FT_Int len; /* length of token in chars */ - - } T1_Token; - - - typedef struct T1_TokenParser_ - { - FT_Memory memory; - FT_Stream stream; - - FT_Bool in_pfb; /* true if PFB file, PFA otherwise */ - FT_Bool in_private; /* true if in private dictionary */ - - FT_Byte* base; /* base address of current read buffer */ - FT_Long cursor; /* current position in read buffer */ - FT_Long limit; /* limit of current read buffer */ - FT_Long max; /* maximum size of read buffer */ - - FT_Error error; /* last error */ - T1_Token token; /* last token read */ - - } T1_TokenParser; - - - /*************************************************************************/ - /* */ - /* */ - /* T1_Tokenizer */ - /* */ - /* */ - /* A handle to an object used to extract tokens from the input. The */ - /* object is able to perform PFA/PFB recognition, eexec decryption of */ - /* the private dictionary, as well as eexec decryption of the */ - /* charstrings. */ - /* */ - typedef T1_TokenParser* T1_Tokenizer; - - - LOCAL_DEF - FT_Error New_Tokenizer( FT_Stream stream, - T1_Tokenizer* tokenizer ); - - LOCAL_DEF - FT_Error Done_Tokenizer( T1_Tokenizer tokenizer ); - - LOCAL_DEF - FT_Error Open_PrivateDict( T1_Tokenizer tokenizer ); - - LOCAL_DEF - FT_Error Read_Token( T1_Tokenizer tokenizer ); - - -#if 0 - LOCAL_DEF - FT_Error Read_CharStrings( T1_Tokenizer tokenizer, - FT_Int num_chars, - FT_Byte* buffer ); -#endif /* 0 */ - - LOCAL_DEF - void t1_decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ); - - -#ifdef __cplusplus - } -#endif - -#endif /* T1TOKENS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1/type1.c b/subsys/win32k/freetype/src/type1/type1.c deleted file mode 100644 index bb93732..0000000 --- a/subsys/win32k/freetype/src/type1/type1.c +++ /dev/null @@ -1,59 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1.c */ -/* */ -/* FreeType Type 1 driver component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "t1driver.c" -#include "t1objs.c" -#include "t1load.c" -#include "t1gload.c" -#include "t1tokens.c" -#include "t1parse.c" - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include "t1hinter.c" -#endif - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.c" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include -#include -#include -#include - -#ifndef T1_CONFIG_OPTION_DISABLE_HINTER -#include -#endif - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/.cvsignore b/subsys/win32k/freetype/src/type1z/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/type1z/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/type1z/Readme.txt b/subsys/win32k/freetype/src/type1z/Readme.txt deleted file mode 100644 index 6502fb9..0000000 --- a/subsys/win32k/freetype/src/type1z/Readme.txt +++ /dev/null @@ -1,10 +0,0 @@ -This directory contains an experimental Type 1 driver that will ultimately -replace the "official" one in "src/type1". - -This driver doesn't provide a mini Postscript interpreter, but uses -pattern matching in order to load data from fonts. It works better and -faster than the official driver, but will replace it only when we finish -the auto-hinting module.. - -You don't need to compile it to support Type 1 fonts, the driver should -co-exist peacefully with the rest of the engine however.. diff --git a/subsys/win32k/freetype/src/type1z/module.mk b/subsys/win32k/freetype/src/type1z/module.mk deleted file mode 100644 index 545887d..0000000 --- a/subsys/win32k/freetype/src/type1z/module.mk +++ /dev/null @@ -1,7 +0,0 @@ -make_module_list: add_type1_driver - -add_type1_driver: - $(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)type1 $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE) - -# EOF diff --git a/subsys/win32k/freetype/src/type1z/rules.mk b/subsys/win32k/freetype/src/type1z/rules.mk deleted file mode 100644 index 3411fd1..0000000 --- a/subsys/win32k/freetype/src/type1z/rules.mk +++ /dev/null @@ -1,72 +0,0 @@ -# -# FreeType 2 Type1z driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# Type1z driver directory -# -T1Z_DIR := $(SRC_)type1z -T1Z_DIR_ := $(T1Z_DIR)$(SEP) - - -# compilation flags for the driver -# -T1Z_COMPILE := $(FT_COMPILE) - - -# Type1 driver sources (i.e., C files) -# -T1Z_DRV_SRC := $(T1Z_DIR_)z1parse.c \ - $(T1Z_DIR_)z1load.c \ - $(T1Z_DIR_)z1driver.c \ - $(T1Z_DIR_)z1afm.c \ - $(T1Z_DIR_)z1gload.c \ - $(T1Z_DIR_)z1objs.c - -# Type1 driver headers -# -T1Z_DRV_H := $(T1Z_DRV_SRC:%.c=%.h) \ - $(T1Z_DIR_)z1tokens.h - - -# Type1z driver object(s) -# -# T1Z_DRV_OBJ_M is used during `multi' builds -# T1Z_DRV_OBJ_S is used during `single' builds -# -T1Z_DRV_OBJ_M := $(T1Z_DRV_SRC:$(T1Z_DIR_)%.c=$(OBJ_)%.$O) -T1Z_DRV_OBJ_S := $(OBJ_)type1z.$O - -# Type1z driver source file for single build -# -T1Z_DRV_SRC_S := $(T1Z_DIR_)type1z.c - - -# Type1z driver - single object -# -$(T1Z_DRV_OBJ_S): $(T1Z_DRV_SRC_S) $(T1Z_DRV_SRC) $(FREETYPE_H) $(T1Z_DRV_H) - $(T1Z_COMPILE) $T$@ $(T1Z_DRV_SRC_S) - - -# Type1z driver - multiple objects -# -$(OBJ_)%.$O: $(T1Z_DIR_)%.c $(FREETYPE_H) $(T1Z_DRV_H) - $(T1Z_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(T1Z_DRV_OBJ_S) -DRV_OBJS_M += $(T1Z_DRV_OBJ_M) - -# EOF diff --git a/subsys/win32k/freetype/src/type1z/type1z.c b/subsys/win32k/freetype/src/type1z/type1z.c deleted file mode 100644 index 54726c2..0000000 --- a/subsys/win32k/freetype/src/type1z/type1z.c +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************/ -/* */ -/* type1z.c */ -/* */ -/* FreeType experimental Type 1 driver component (body only). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#define FT_MAKE_OPTION_SINGLE_OBJECT - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.c" -#include "z1load.c" -#include "z1objs.c" -#include "z1driver.c" -#include "z1gload.c" - -#ifndef Z1_CONFIG_OPTION_NO_AFM -#include "z1afm.c" -#endif - -#else /* FT_FLAT_COMPILE */ - -#include -#include -#include -#include -#include - -#ifndef Z1_CONFIG_OPTION_NO_AFM -#include -#endif - -#endif /* FT_FLAT_COMPILE */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1afm.c b/subsys/win32k/freetype/src/type1z/z1afm.c deleted file mode 100644 index 5c20120..0000000 --- a/subsys/win32k/freetype/src/type1z/z1afm.c +++ /dev/null @@ -1,293 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1afm.c */ -/* */ -/* AFM support for Type 1 fonts (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1afm.h" - -#else - -#include - -#endif - - -#include -#include - -#include /* for qsort() */ -#include /* for strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1afm - - - LOCAL_FUNC - void Z1_Done_AFM( FT_Memory memory, - Z1_AFM* afm ) - { - FREE( afm->kern_pairs ); - afm->num_pairs = 0; - } - - -#undef IS_KERN_PAIR -#define IS_KERN_PAIR( p ) ( p[0] == 'K' && p[1] == 'P' ) - -#define IS_ALPHANUM( c ) ( isalnum( c ) || \ - c == '_' || \ - c == '.' ) - - - /* read a glyph name and return the equivalent glyph index */ - static - FT_UInt afm_atoindex( FT_Byte** start, - FT_Byte* limit, - T1_Font* type1 ) - { - FT_Byte* p = *start; - FT_Int len; - FT_UInt result = 0; - char temp[64]; - - - /* skip whitespace */ - while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) && - p < limit ) - p++; - *start = p; - - /* now, read glyph name */ - while ( IS_ALPHANUM( *p ) && p < limit ) - p++; - - len = p - *start; - - if ( len > 0 && len < 64 ) - { - FT_Int n; - - - /* copy glyph name to intermediate array */ - MEM_Copy( temp, *start, len ); - temp[len] = 0; - - /* lookup glyph name in face array */ - for ( n = 0; n < type1->num_glyphs; n++ ) - { - char* gname = (char*)type1->glyph_names[n]; - - - if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 ) - { - result = n; - break; - } - } - } - *start = p; - return result; - } - - - /* read an integer */ - static - int afm_atoi( FT_Byte** start, - FT_Byte* limit ) - { - FT_Byte* p = *start; - int sum = 0; - int sign = 1; - - - /* skip everything that is not a number */ - while ( p < limit && !isdigit( *p ) ) - { - sign = 1; - if ( *p == '-' ) - sign = -1; - - p++; - } - - while ( p < limit && isdigit( *p ) ) - { - sum = sum * 10 + ( *p - '0' ); - p++; - } - *start = p; - - return sum * sign; - } - - -#undef KERN_INDEX -#define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 ) - - - /* compare two kerning pairs */ - static - int compare_kern_pairs( const void* a, - const void* b ) - { - Z1_Kern_Pair* pair1 = (Z1_Kern_Pair*)a; - Z1_Kern_Pair* pair2 = (Z1_Kern_Pair*)b; - - FT_ULong index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 ); - FT_ULong index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 ); - - - return ( index1 - index2 ); - } - - - /* parse an AFM file -- for now, only read the kerning pairs */ - LOCAL_FUNC - FT_Error Z1_Read_AFM( FT_Face t1_face, - FT_Stream stream ) - { - FT_Error error; - FT_Memory memory = stream->memory; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* p; - FT_Int count = 0; - Z1_Kern_Pair* pair; - T1_Font* type1 = &((T1_Face)t1_face)->type1; - Z1_AFM* afm = 0; - - - if ( ACCESS_Frame( stream->size ) ) - return error; - - start = (FT_Byte*)stream->cursor; - limit = (FT_Byte*)stream->limit; - p = start; - - /* we are now going to count the occurences of `KP' or `KPX' in */ - /* the AFM file */ - count = 0; - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - count++; - } - - /* Actually, kerning pairs are simply optional! */ - if ( count == 0 ) - goto Exit; - - /* allocate the pairs */ - if ( ALLOC( afm, sizeof ( *afm ) ) || - ALLOC_ARRAY( afm->kern_pairs, count, Z1_Kern_Pair ) ) - goto Exit; - - /* now, read each kern pair */ - pair = afm->kern_pairs; - afm->num_pairs = count; - - /* save in face object */ - ((T1_Face)t1_face)->afm_data = afm; - - for ( p = start; p < limit - 3; p++ ) - { - if ( IS_KERN_PAIR( p ) ) - { - FT_Byte* q; - - - /* skip keyword (KP or KPX) */ - q = p + 2; - if ( *q == 'X' ) - q++; - - pair->glyph1 = afm_atoindex( &q, limit, type1 ); - pair->glyph2 = afm_atoindex( &q, limit, type1 ); - pair->kerning.x = afm_atoi( &q, limit ); - - pair->kerning.y = 0; - if ( p[2] != 'X' ) - pair->kerning.y = afm_atoi( &q, limit ); - - pair++; - } - } - - /* now, sort the kern pairs according to their glyph indices */ - qsort( afm->kern_pairs, count, sizeof ( Z1_Kern_Pair ), - compare_kern_pairs ); - - Exit: - if ( error ) - FREE( afm ); - - FORGET_Frame(); - - return error; - } - - - /* find the kerning for a given glyph pair */ - LOCAL_FUNC - void Z1_Get_Kerning( Z1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ) - { - Z1_Kern_Pair *min, *mid, *max; - FT_ULong index = KERN_INDEX( glyph1, glyph2 ); - - - /* simple binary search */ - min = afm->kern_pairs; - max = min + afm->num_pairs - 1; - - while ( min <= max ) - { - FT_ULong midi; - - - mid = min + ( max - min ) / 2; - midi = KERN_INDEX( mid->glyph1, mid->glyph2 ); - - if ( midi == index ) - { - *kerning = mid->kerning; - return; - } - - if ( midi < index ) - min = mid + 1; - else - max = mid - 1; - } - - kerning->x = 0; - kerning->y = 0; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1afm.h b/subsys/win32k/freetype/src/type1z/z1afm.h deleted file mode 100644 index ce7be83..0000000 --- a/subsys/win32k/freetype/src/type1z/z1afm.h +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1afm.h */ -/* */ -/* AFM support for Type 1 fonts (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1AFM_H -#define Z1AFM_H - - -#ifdef FT_FLAT_COMPILE - -#include "z1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - typedef struct Z1_Kern_Pair_ - { - FT_UInt glyph1; - FT_UInt glyph2; - FT_Vector kerning; - - } Z1_Kern_Pair; - - - typedef struct Z1_AFM_ - { - FT_Int num_pairs; - Z1_Kern_Pair* kern_pairs; - - } Z1_AFM; - - - LOCAL_DEF - FT_Error Z1_Read_AFM( FT_Face face, - FT_Stream stream ); - - LOCAL_DEF - void Z1_Done_AFM( FT_Memory memory, - Z1_AFM* afm ); - - LOCAL_DEF - void Z1_Get_Kerning( Z1_AFM* afm, - FT_UInt glyph1, - FT_UInt glyph2, - FT_Vector* kerning ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* Z1AFM_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1driver.c b/subsys/win32k/freetype/src/type1z/z1driver.c deleted file mode 100644 index 401f125..0000000 --- a/subsys/win32k/freetype/src/type1z/z1driver.c +++ /dev/null @@ -1,340 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1driver.c */ -/* */ -/* Experimental Type 1 driver interface (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1driver.h" -#include "z1gload.h" -#include "z1load.h" -#include "z1afm.h" - -#else - -#include -#include -#include -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1driver - - - static - FT_Error get_z1_glyph_name( T1_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_String* gname; - - - gname = face->type1.glyph_names[glyph_index]; - - if ( buffer_max > 0 ) - { - FT_UInt len = strlen( gname ); - - - if (len >= buffer_max) - len = buffer_max - 1; - - MEM_Copy( buffer, gname, len ); - ((FT_Byte*)buffer)[len] = 0; - } - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Interface */ - /* */ - /* */ - /* Each driver can provide one or more extensions to the base */ - /* FreeType API. These can be used to access format specific */ - /* features (e.g., all TrueType/OpenType resources share a common */ - /* file structure and common tables which can be accessed through the */ - /* `sfnt' interface), or more simply generic ones (e.g., the */ - /* `postscript names' interface which can be used to retrieve the */ - /* PostScript name of a given glyph index). */ - /* */ - /* */ - /* driver :: A handle to a driver object. */ - /* */ - /* */ - /* interface :: A string designing the interface. Examples are */ - /* `sfnt', `post_names', `charmaps', etc. */ - /* */ - /* */ - /* A typeless pointer to the extension's interface (normally a table */ - /* of function pointers). Returns NULL if the requested extension */ - /* isn't available (i.e., wasn't compiled in the driver at build */ - /* time). */ - /* */ - static - FT_Module_Interface Get_Interface( FT_Driver driver, - const FT_String* interface ) - { - FT_UNUSED( driver ); - FT_UNUSED( interface ); - - if ( strcmp( (const char*)interface, "glyph_name" ) == 0 ) - return (FT_Module_Interface)get_z1_glyph_name; - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - if ( strcmp( (const char*)interface, "get_mm" ) == 0 ) - return (FT_Module_Interface)Z1_Get_Multi_Master; - - if ( strcmp( (const char*)interface, "set_mm_design") == 0 ) - return (FT_Module_Interface)Z1_Set_MM_Design; - - if ( strcmp( (const char*)interface, "set_mm_blend") == 0 ) - return (FT_Module_Interface)Z1_Set_MM_Blend; -#endif - return 0; - } - - -#ifndef Z1_CONFIG_OPTION_NO_AFM - - /*************************************************************************/ - /* */ - /* */ - /* Get_Kerning */ - /* */ - /* */ - /* A driver method used to return the kerning vector between two */ - /* glyphs of the same face. */ - /* */ - /* */ - /* face :: A handle to the source face object. */ - /* */ - /* left_glyph :: The index of the left glyph in the kern pair. */ - /* */ - /* right_glyph :: The index of the right glyph in the kern pair. */ - /* */ - /* */ - /* kerning :: The kerning vector. This is in font units for */ - /* scalable formats, and in pixels for fixed-sizes */ - /* formats. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - /* */ - /* Only horizontal layouts (left-to-right & right-to-left) are */ - /* supported by this function. Other layouts, or more sophisticated */ - /* kernings are out of scope of this method (the basic driver */ - /* interface is meant to be simple). */ - /* */ - /* They can be implemented by format-specific interfaces. */ - /* */ - static - FT_Error Get_Kerning( T1_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_Vector* kerning ) - { - Z1_AFM* afm; - - - kerning->x = 0; - kerning->y = 0; - - afm = (Z1_AFM*)face->afm_data; - if ( afm ) - Z1_Get_Kerning( afm, left_glyph, right_glyph, kerning ); - - return T1_Err_Ok; - } - - -#endif /* T1_CONFIG_OPTION_NO_AFM */ - - - /*************************************************************************/ - /* */ - /* */ - /* Get_Char_Index */ - /* */ - /* */ - /* Uses a charmap to return a given character code's glyph index. */ - /* */ - /* */ - /* charmap :: A handle to the source charmap object. */ - /* charcode :: The character code. */ - /* */ - /* */ - /* Glyph index. 0 means `undefined character code'. */ - /* */ - static - FT_UInt Get_Char_Index( FT_CharMap charmap, - FT_Long charcode ) - { - T1_Face face; - FT_UInt result = 0; - PSNames_Interface* psnames; - - - face = (T1_Face)charmap->face; - psnames = (PSNames_Interface*)face->psnames; - if ( psnames ) - switch ( charmap->encoding ) - { - /*******************************************************************/ - /* */ - /* Unicode encoding support */ - /* */ - case ft_encoding_unicode: - /* use the `PSNames' module to synthetize the Unicode charmap */ - result = psnames->lookup_unicode( &face->unicode_map, - (FT_ULong)charcode ); - - /* the function returns 0xFFFF if the Unicode charcode has */ - /* no corresponding glyph */ - if ( result == 0xFFFF ) - result = 0; - goto Exit; - - /*******************************************************************/ - /* */ - /* Custom Type 1 encoding */ - /* */ - case ft_encoding_adobe_custom: - { - T1_Encoding* encoding = &face->type1.encoding; - - - if ( charcode >= encoding->code_first && - charcode <= encoding->code_last ) - result = encoding->char_index[charcode]; - goto Exit; - } - - /*******************************************************************/ - /* */ - /* Adobe Standard & Expert encoding support */ - /* */ - default: - if ( charcode < 256 ) - { - FT_UInt code; - FT_Int n; - const char* glyph_name; - - - code = psnames->adobe_std_encoding[charcode]; - if ( charmap->encoding == ft_encoding_adobe_expert ) - code = psnames->adobe_expert_encoding[charcode]; - - glyph_name = psnames->adobe_std_strings( code ); - if ( !glyph_name ) - break; - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - if ( gname && gname[0] == glyph_name[0] && - strcmp( gname, glyph_name ) == 0 ) - { - result = n; - break; - } - } - } - } - Exit: - return result; - } - - - const FT_Driver_Class t1_driver_class = - { - { - ft_module_font_driver | ft_module_driver_scalable, - sizeof( FT_DriverRec ), - - "type1", - 0x10000L, - 0x20000L, - - 0, /* format interface */ - - (FT_Module_Constructor)Z1_Init_Driver, - (FT_Module_Destructor) Z1_Done_Driver, - (FT_Module_Requester) Get_Interface, - }, - - sizeof( T1_FaceRec ), - sizeof( Z1_SizeRec ), - sizeof( Z1_GlyphSlotRec ), - - (FTDriver_initFace) Z1_Init_Face, - (FTDriver_doneFace) Z1_Done_Face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) 0, - (FTDriver_setPixelSizes)0, - (FTDriver_loadGlyph) Z1_Load_Glyph, - (FTDriver_getCharIndex) Get_Char_Index, - -#ifdef Z1_CONFIG_OPTION_NO_AFM - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, -#else - (FTDriver_getKerning) Get_Kerning, - (FTDriver_attachFile) Z1_Read_AFM, -#endif - (FTDriver_getAdvances) 0 - }; - - -#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS - - EXPORT_FUNC( const FT_Driver_Class* ) getDriverClass( void ) - { - return &t1z_driver_class; - } - -#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1driver.h b/subsys/win32k/freetype/src/type1z/z1driver.h deleted file mode 100644 index 08bd544..0000000 --- a/subsys/win32k/freetype/src/type1z/z1driver.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1driver.h */ -/* */ -/* High-level experimental Type 1 driver interface (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1DRIVER_H -#define Z1DRIVER_H - -#include - - FT_EXPORT_VAR( const FT_Driver_Class ) t1_driver_class; - -#endif /* Z1DRIVER_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1gload.c b/subsys/win32k/freetype/src/type1z/z1gload.c deleted file mode 100644 index 455faeb..0000000 --- a/subsys/win32k/freetype/src/type1z/z1gload.c +++ /dev/null @@ -1,1482 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1gload.c */ -/* */ -/* Experimental Type 1 Glyph Loader (body). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "z1gload.h" - -#else - -#include - -#endif - - -#include -#include -#include - -#include /* for strcmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1gload - - - typedef enum Z1_Operator_ - { - op_none = 0, - op_endchar, - op_hsbw, - op_seac, - op_sbw, - op_closepath, - op_hlineto, - op_hmoveto, - op_hvcurveto, - op_rlineto, - op_rmoveto, - op_rrcurveto, - op_vhcurveto, - op_vlineto, - op_vmoveto, - op_dotsection, - op_hstem, - op_hstem3, - op_vstem, - op_vstem3, - op_div, - op_callothersubr, - op_callsubr, - op_pop, - op_return, - op_setcurrentpoint, - - op_max /* never remove this one */ - - } Z1_Operator; - - static - const FT_Int t1_args_count[op_max] = - { - 0, /* none */ - 0, /* endchar */ - 2, /* hsbw */ - 5, /* seac */ - 4, /* sbw */ - 0, /* closepath */ - 1, /* hlineto */ - 1, /* hmoveto */ - 4, /* hvcurveto */ - 2, /* rlineto */ - 2, /* rmoveto */ - 6, /* rrcurveto */ - 4, /* vhcurveto */ - 1, /* vlineto */ - 1, /* vmoveto */ - 0, /* dotsection */ - 2, /* hstem */ - 6, /* hstem3 */ - 2, /* vstem */ - 6, /* vstem3 */ - 2, /* div */ - -1, /* callothersubr */ - 1, /* callsubr */ - 0, /* pop */ - 0, /* return */ - 2 /* setcurrentpoint */ - }; - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Builder */ - /* */ - /* */ - /* Initializes a given glyph builder. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - LOCAL_FUNC - void Z1_Init_Builder( Z1_Builder* builder, - T1_Face face, - Z1_Size size, - Z1_GlyphSlot glyph ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader* loader = glyph->root.loader; - - - builder->loader = loader; - builder->current = &loader->current.outline; - builder->base = &loader->base.outline; - - FT_GlyphLoader_Rewind( loader ); - } - - if ( size ) - { - builder->scale_x = size->root.metrics.x_scale; - builder->scale_y = size->root.metrics.y_scale; - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Builder */ - /* */ - /* */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - LOCAL_FUNC - void Z1_Done_Builder( Z1_Builder* builder ) - { - Z1_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Decoder */ - /* */ - /* */ - /* Initializes a given glyph decoder. */ - /* */ - /* */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - LOCAL_FUNC - void Z1_Init_Decoder( Z1_Decoder* decoder ) - { - decoder->top = 0; - decoder->zone = 0; - decoder->flex_state = 0; - decoder->num_flex_vectors = 0; - decoder->blend = 0; - - /* Clear loader */ - MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) ); - } - - - /* check that there is enough space for `count' more points */ - static - FT_Error check_points( Z1_Builder* builder, - FT_Int count ) - { - return FT_GlyphLoader_Check_Points( builder->loader, count, 0 ); - } - - - /* add a new point; do not check space */ - static - void add_point( Z1_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - - - point->x = x; - point->y = y; - *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic; - - builder->last = *point; - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - static - FT_Error add_point1( Z1_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = check_points( builder, 1 ); - if ( !error ) - add_point( builder, x, y, 1 ); - - return error; - } - - - /* check space for a new contour, then add it */ - static - FT_Error add_contour( Z1_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return FT_Err_Ok; - } - - /* reallocate contours array if necessary */ - error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - static - FT_Error start_point( Z1_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - FT_Error error; - - - builder->path_begun = 1; - error = add_contour( builder ); - if ( error ) - return error; - } - return add_point1( builder, x, y ); - } - - - /* close the current contour */ - static - void close_contour( Z1_Builder* builder ) - { - FT_Outline* outline = builder->current; - - - /* XXX: we must not include the last point in the path if it */ - /* is located on the first point */ - if ( outline->n_points > 1 ) - { - FT_Int first = 0; - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points-1; - - - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - - if ( p1->x == p2->x && p1->y == p2->y ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = outline->n_points - 1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* lookup_glyph_by_stdcharcode */ - /* */ - /* */ - /* Looks up a given glyph by its StandardEncoding charcode. Used */ - /* to implement the SEAC Type 1 operator. */ - /* */ - /* */ - /* face :: The current face object. */ - /* */ - /* charcode :: The character code to look for. */ - /* */ - /* */ - /* A glyph index in the font face. Returns -1 if the corresponding */ - /* glyph wasn't found. */ - /* */ - static - FT_Int lookup_glyph_by_stdcharcode( T1_Face face, - FT_Int charcode ) - { - FT_Int n; - const FT_String* glyph_name; - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - glyph_name = psnames->adobe_std_strings( - psnames->adobe_std_encoding[charcode]); - - for ( n = 0; n < face->type1.num_glyphs; n++ ) - { - FT_String* name = (FT_String*)face->type1.glyph_names[n]; - - - if ( name && strcmp( name,glyph_name ) == 0 ) - return n; - } - - return -1; - } - - - /*************************************************************************/ - /* */ - /* */ - /* t1operator_seac */ - /* */ - /* */ - /* Implements the `seac' Type 1 operator for a Type 1 decoder. */ - /* */ - /* */ - /* decoder :: The current CID decoder. */ - /* */ - /* asb :: The accent's side bearing. */ - /* */ - /* adx :: The horizontal offset of the accent. */ - /* */ - /* ady :: The vertical offset of the accent. */ - /* */ - /* bchar :: The base character's StandardEncoding charcode. */ - /* */ - /* achar :: The accent character's StandardEncoding charcode. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - static - FT_Error t1operator_seac( Z1_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - FT_Int bchar_index, achar_index, n_base_points; - FT_Outline* base = decoder->builder.base; - FT_Vector left_bearing, advance; - T1_Face face = decoder->builder.face; - T1_Font* type1 = &face->type1; - - - bchar_index = lookup_glyph_by_stdcharcode( face, bchar ); - achar_index = lookup_glyph_by_stdcharcode( face, achar ); - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); - return T1_Err_Syntax_Error; - } - - /* if we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( decoder->builder.no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; - FT_GlyphLoader* loader = glyph->loader; - FT_SubGlyph* subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_Check_Subglyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = adx - asb; - subg->arg2 = ady; - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->base.subglyphs; - glyph->format = ft_glyph_format_composite; - - loader->current.num_subglyphs = 2; - } - - /* First load `bchar' in builder */ - /* now load the unscaled outline */ - - FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ - - error = Z1_Parse_CharStrings( decoder, - type1->charstrings [bchar_index], - type1->charstrings_len[bchar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - goto Exit; - - n_base_points = base->n_points; - - /* save the left bearing and width of the base character */ - /* as they will be erased by the next load. */ - - left_bearing = decoder->builder.left_bearing; - advance = decoder->builder.advance; - - decoder->builder.left_bearing.x = 0; - decoder->builder.left_bearing.y = 0; - - /* Now load `achar' on top of */ - /* the base outline */ - error = Z1_Parse_CharStrings( decoder, - type1->charstrings [achar_index], - type1->charstrings_len[achar_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - if ( error ) - return error; - - /* restore the left side bearing and */ - /* advance width of the base character */ - - decoder->builder.left_bearing = left_bearing; - decoder->builder.advance = advance; - - /* Finally, move the accent */ - if ( decoder->builder.load_points ) - { - FT_Outline dummy; - - - dummy.n_points = base->n_points - n_base_points; - dummy.points = base->points + n_base_points; - FT_Outline_Translate( &dummy, adx - asb, ady ); - } - - Exit: - return error; - } - - -#define USE_ARGS( n ) do \ - { \ - top -= n; \ - if ( top < decoder->stack ) \ - goto Stack_Underflow; \ - } while ( 0 ) - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Parse_CharStrings */ - /* */ - /* */ - /* Parses a given Type 1 charstrings program. */ - /* */ - /* */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* charstring_base :: The base address of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* num_subrs :: The number of sub-routines. */ - /* */ - /* subrs_base :: An array of sub-routines addresses. */ - /* */ - /* subrs_len :: An array of sub-routines lengths. */ - /* */ - /* */ - /* Free error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Parse_CharStrings( Z1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ) - { - FT_Error error; - Z1_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - Z1_Builder* builder = &decoder->builder; - FT_Outline* outline; - FT_Pos x, y; - - - /* First of all, initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = T1_Err_Ok; - outline = builder->current; - - x = builder->pos_x; - y = builder->pos_y; - - /* now, execute loop */ - while ( ip < limit ) - { - FT_Int* top = decoder->top; - Z1_Operator op = op_none; - FT_Long value = 0; - - - /*********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - /* */ - - /* first of all, decompress operator or value */ - switch ( *ip++ ) - { - case 1: - op = op_hstem; - break; - - case 3: - op = op_vstem; - break; - case 4: - op = op_vmoveto; - break; - case 5: - op = op_rlineto; - break; - case 6: - op = op_hlineto; - break; - case 7: - op = op_vlineto; - break; - case 8: - op = op_rrcurveto; - break; - case 9: - op = op_closepath; - break; - case 10: - op = op_callsubr; - break; - case 11: - op = op_return; - break; - - case 13: - op = op_hsbw; - break; - case 14: - op = op_endchar; - break; - - case 21: - op = op_rmoveto; - break; - case 22: - op = op_hmoveto; - break; - - case 30: - op = op_vhcurveto; - break; - case 31: - op = op_hvcurveto; - break; - - case 12: - if ( ip > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+EOF)\n" )); - goto Syntax_Error; - } - - switch ( *ip++ ) - { - case 0: - op = op_dotsection; - break; - case 1: - op = op_vstem3; - break; - case 2: - op = op_hstem3; - break; - case 6: - op = op_seac; - break; - case 7: - op = op_sbw; - break; - case 12: - op = op_div; - break; - case 16: - op = op_callothersubr; - break; - case 17: - op = op_pop; - break; - case 33: - op = op_setcurrentpoint; - break; - - default: - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - break; - - case 255: /* four bytes integer */ - if ( ip + 4 > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - value = ( (FT_Long)ip[0] << 24 ) | - ( (FT_Long)ip[1] << 16 ) | - ( (FT_Long)ip[2] << 8 ) | - ip[3]; - ip += 4; - break; - - default: - if ( ip[-1] >= 32 ) - { - if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; - else - { - if ( ++ip > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected EOF in integer\n" )); - goto Syntax_Error; - } - - if ( ip[-2] < 251 ) - value = ( (FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108; - else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); - } - } - else - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid byte (%d)\n", - ip[-1] )); - goto Syntax_Error; - } - } - - /*********************************************************************/ - /* */ - /* Push value on stack, or process operator */ - /* */ - /* */ - if ( op == op_none ) - { - if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) - { - FT_ERROR(( "Z1_Parse_CharStrings: stack overflow!\n" )); - goto Syntax_Error; - } - - FT_TRACE4(( " %ld", value )); - - *top++ = value; - decoder->top = top; - } - else if ( op == op_callothersubr ) /* callothersubr */ - { - FT_TRACE4(( " callothersubr" )); - - if ( top - decoder->stack < 2 ) - goto Stack_Underflow; - - top -= 2; - switch ( top[1] ) - { - case 1: /* start flex feature */ - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - decoder->flex_state = 1; - decoder->num_flex_vectors = 0; - if ( start_point( builder, x, y ) || - check_points( builder, 6 ) ) - goto Memory_Error; - break; - - case 2: /* add flex vectors */ - { - FT_Int index; - - if ( top[0] != 0 ) - goto Unexpected_OtherSubr; - - /* note that we should not add a point for index 0; */ - /* this will move our current position to the flex */ - /* point without adding any point to the outline */ - index = decoder->num_flex_vectors++; - if ( index > 0 && index < 7 ) - add_point( builder, - x, - y, - (FT_Byte)( index == 3 || index == 6 ) ); - } - break; - - case 0: /* end flex feature */ - if ( top[0] != 3 ) - goto Unexpected_OtherSubr; - - if ( decoder->flex_state == 0 || - decoder->num_flex_vectors != 7 ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected flex end\n" )); - goto Syntax_Error; - } - - /* now consume the remaining `pop pop setcurpoint' */ - if ( ip + 6 > limit || - ip[0] != 12 || ip[1] != 17 || /* pop */ - ip[2] != 12 || ip[3] != 17 || /* pop */ - ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */ - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid flex charstring\n" )); - goto Syntax_Error; - } - - ip += 6; - decoder->flex_state = 0; - break; - - case 3: /* change hints */ - if ( top[0] != 1 ) - goto Unexpected_OtherSubr; - - /* eat the following `pop' */ - if ( ip + 2 > limit ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid escape (12+%d)\n", - ip[-1] )); - goto Syntax_Error; - } - - if ( ip[0] != 12 || ip[1] != 17 ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " `pop' expected, found (%d %d)\n", - ip[0], ip[1] )); - goto Syntax_Error; - } - ip += 2; - break; - - case 12: - case 13: - /* counter control hints, clear stack */ - top = decoder->stack; - break; - - case 14: - case 15: - case 16: - case 17: - case 18: /* multiple masters */ - { - T1_Blend* blend = decoder->blend; - FT_UInt num_points, nn, mm; - FT_Int* delta; - FT_Int* values; - - - if ( !blend ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected multiple masters operator!\n" )); - goto Syntax_Error; - } - - num_points = top[1] - 13 + ( top[1] == 18 ); - if ( top[0] != (FT_Int)( num_points * blend->num_designs ) ) - { - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " incorrect number of mm arguments\n" )); - goto Syntax_Error; - } - - top -= blend->num_designs*num_points; - if ( top < decoder->stack ) - goto Stack_Underflow; - - /* we want to compute: */ - /* */ - /* a0*w0 + a1*w1 + ... + ak*wk */ - /* */ - /* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */ - /* however, given that w0 + w1 + ... + wk == 1, we can */ - /* rewrite it easily as: */ - /* */ - /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */ - /* */ - /* where k == num_designs-1 */ - /* */ - /* I guess that's why it's written in this `compact' */ - /* form. */ - /* */ - delta = top + num_points; - values = top; - for ( nn = 0; nn < num_points; nn++ ) - { - FT_Int x = values[0]; - - - for ( mm = 1; mm < blend->num_designs; mm++ ) - x += FT_MulFix( *delta++, blend->weight_vector[mm] ); - - *values++ = x; - } - /* note that `top' will be incremented later by calls to `pop' */ - break; - } - - default: - Unexpected_OtherSubr: - FT_ERROR(( "Z1_Parse_CharStrings: invalid othersubr [%d %d]!\n", - top[0], top[1] )); - goto Syntax_Error; - } - decoder->top = top; - } - else /* general operator */ - { - FT_Int num_args = t1_args_count[op]; - - - if ( top - decoder->stack < num_args ) - goto Stack_Underflow; - - top -= num_args; - - switch ( op ) - { - case op_endchar: - FT_TRACE4(( " endchar" )); - - close_contour( builder ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n\n" )); - return T1_Err_Ok; - - case op_hsbw: - FT_TRACE4(( " hsbw" )); - - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; - - builder->last.x = x = top[0]; - builder->last.y = y = 0; - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], - top[2], top[3], top[4] ); - - case op_sbw: - FT_TRACE4(( " sbw" )); - - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; - - builder->last.x = x = top[0]; - builder->last.y = y = top[1]; - - /* the `metrics_only' indicates that we only want to compute */ - /* the glyph's metrics (lsb + advance width), not load the */ - /* rest of it; so exit immediately */ - if ( builder->metrics_only ) - return T1_Err_Ok; - - break; - - case op_closepath: - FT_TRACE4(( " closepath" )); - - close_contour( builder ); - builder->path_begun = 0; - break; - - case op_hlineto: - FT_TRACE4(( " hlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - goto Add_Line; - - case op_hmoveto: - FT_TRACE4(( " hmoveto" )); - - x += top[0]; - break; - - case op_hvcurveto: - FT_TRACE4(( " hvcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - y += top[3]; - add_point( builder, x, y, 1 ); - break; - - case op_rlineto: - FT_TRACE4(( " rlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - - Add_Line: - if ( add_point1( builder, x, y ) ) - goto Memory_Error; - break; - - case op_rmoveto: - FT_TRACE4(( " rmoveto" )); - - x += top[0]; - y += top[1]; - break; - - case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - x += top[0]; - y += top[1]; - add_point( builder, x, y, 0 ); - - x += top[2]; - y += top[3]; - add_point( builder, x, y, 0 ); - - x += top[4]; - y += top[5]; - add_point( builder, x, y, 1 ); - break; - - case op_vhcurveto: - FT_TRACE4(( " vhcurveto" )); - - if ( start_point( builder, x, y ) || - check_points( builder, 3 ) ) - goto Memory_Error; - - y += top[0]; - add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; - add_point( builder, x, y, 0 ); - x += top[3]; - add_point( builder, x, y, 1 ); - break; - - case op_vlineto: - FT_TRACE4(( " vlineto" )); - - if ( start_point( builder, x, y ) ) - goto Memory_Error; - - y += top[0]; - goto Add_Line; - - case op_vmoveto: - FT_TRACE4(( " vmoveto" )); - - y += top[0]; - break; - - case op_div: - FT_TRACE4(( " div" )); - - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "Z1_Parse_CharStrings: division by 0\n" )); - goto Syntax_Error; - } - break; - - case op_callsubr: - { - FT_Int index; - - - FT_TRACE4(( " callsubr" )); - - index = top[0]; - if ( index < 0 || index >= num_subrs ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invalid subrs index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "Z1_Parse_CharStrings: too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = subrs_base[index]; - zone->limit = zone->base + subrs_len[index]; - zone->cursor = zone->base; - - if ( !zone->base ) - { - FT_ERROR(( "Z1_Parse_CharStrings: invoking empty subrs!\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - break; - } - - case op_pop: - FT_TRACE4(( " pop" )); - - /* theorically, the arguments are already on the stack */ - top++; - break; - - case op_return: - FT_TRACE4(( " return" )); - - if ( zone <= decoder->zones ) - { - FT_ERROR(( "Z1_Parse_CharStrings: unexpected return\n" )); - goto Syntax_Error; - } - - zone--; - ip = zone->cursor; - limit = zone->limit; - decoder->zone = zone; - break; - - case op_dotsection: - FT_TRACE4(( " dotsection" )); - - break; - - case op_hstem: - FT_TRACE4(( " hstem" )); - - break; - - case op_hstem3: - FT_TRACE4(( " hstem3" )); - - break; - - case op_vstem: - FT_TRACE4(( " vstem" )); - - break; - - case op_vstem3: - FT_TRACE4(( " vstem3" )); - - break; - - case op_setcurrentpoint: - FT_TRACE4(( " setcurrentpoint" )); - - FT_ERROR(( "Z1_Parse_CharStrings:" )); - FT_ERROR(( " unexpected `setcurrentpoint'\n" )); - goto Syntax_Error; - - default: - FT_ERROR(( "Z1_Parse_CharStrings: unhandled opcode %d\n", op )); - goto Syntax_Error; - } - - decoder->top = top; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - return error; - - Syntax_Error: - return T1_Err_Syntax_Error; - - Stack_Underflow: - return T1_Err_Stack_Underflow; - - Memory_Error: - return builder->error; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error Z1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ) - { - FT_Error error; - Z1_Decoder decoder; - FT_Int glyph_index; - T1_Font* type1 = &face->type1; - - - *max_advance = 0; - - /* Initialize load decoder */ - Z1_Init_Decoder( &decoder ); - Z1_Init_Builder( &decoder.builder, face, 0, 0 ); - - decoder.blend = face->blend; - decoder.builder.metrics_only = 1; - decoder.builder.load_points = 0; - - /* for each glyph, parse the glyph charstring and extract */ - /* the advance width */ - for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ ) - { - /* now get load the unscaled outline */ - error = Z1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - /* ignore the error if one occured - skip to next glyph */ - } - - *max_advance = decoder.builder.advance.x; - return T1_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** UNHINTED GLYPH LOADER *********/ - /********** *********/ - /********** The following code is in charge of loading a *********/ - /********** single outline. It completely ignores hinting *********/ - /********** and is used when FT_LOAD_NO_HINTING is set. *********/ - /********** *********/ - /********** The Type 1 hinter is located in `t1hint.c' *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - LOCAL_FUNC - FT_Error Z1_Load_Glyph( Z1_GlyphSlot glyph, - Z1_Size size, - FT_Int glyph_index, - FT_Int load_flags ) - { - FT_Error error; - Z1_Decoder decoder; - T1_Face face = (T1_Face)glyph->root.face; - FT_Bool hinting; - T1_Font* type1 = &face->type1; - - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; - - glyph->x_scale = size->root.metrics.x_scale; - glyph->y_scale = size->root.metrics.y_scale; - - glyph->root.outline.n_points = 0; - glyph->root.outline.n_contours = 0; - - hinting = ( load_flags & FT_LOAD_NO_SCALE ) == 0 && - ( load_flags & FT_LOAD_NO_HINTING ) == 0; - - glyph->root.format = ft_glyph_format_outline; - - Z1_Init_Decoder( &decoder ); - Z1_Init_Builder( &decoder.builder, face, size, glyph ); - - decoder.blend = ((T1_Face)glyph->root.face)->blend; - decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0; - - /* now load the unscaled outline */ - error = Z1_Parse_CharStrings( &decoder, - type1->charstrings [glyph_index], - type1->charstrings_len[glyph_index], - type1->num_subrs, - type1->subrs, - type1->subrs_len ); - - /* save new glyph tables */ - Z1_Done_Builder( &decoder.builder ); - - /* now, set the metrics -- this is rather simple, as */ - /* the left side bearing is the xMin, and the top side */ - /* bearing the yMax */ - if ( !error ) - { - glyph->root.outline.flags &= ft_outline_owner; - glyph->root.outline.flags |= ft_outline_reverse_fill; - - /* for composite glyphs, return only left side bearing and */ - /* advance width */ - if ( load_flags & FT_LOAD_NO_RECURSE ) - { - glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x; - glyph->root.metrics.horiAdvance = decoder.builder.advance.x; - } - else - { - FT_BBox cbox; - FT_Glyph_Metrics* metrics = &glyph->root.metrics; - - - /* copy the _unscaled_ advance width */ - metrics->horiAdvance = decoder.builder.advance.x; - - /* make up vertical metrics */ - metrics->vertBearingX = 0; - metrics->vertBearingY = 0; - metrics->vertAdvance = 0; - - glyph->root.format = ft_glyph_format_outline; - - if ( size && size->root.metrics.y_ppem < 24 ) - glyph->root.outline.flags |= ft_outline_high_precision; - -#if 0 - glyph->root.outline.second_pass = TRUE; - glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24; - glyph->root.outline.dropout_mode = 2; -#endif /* 0 */ - - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) - { - /* scale the outline and the metrics */ - FT_Int n; - FT_Outline* cur = decoder.builder.base; - FT_Vector* vec = cur->points; - FT_Fixed x_scale = glyph->x_scale; - FT_Fixed y_scale = glyph->y_scale; - - - /* First of all, scale the points */ - for ( n = cur->n_points; n > 0; n--, vec++ ) - { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); - } - - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* Then scale the metrics */ - metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); - metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); - - metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); - metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); - } - - /* apply the font matrix */ - FT_Outline_Transform( &glyph->root.outline, - &face->type1.font_matrix ); - - /* compute the other metrics */ - FT_Outline_Get_CBox( &glyph->root.outline, &cbox ); - - /* grid fit the bounding box if necessary */ - if ( hinting ) - { - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = ( cbox.xMax+63 ) & -64; - cbox.yMax = ( cbox.yMax+63 ) & -64; - } - - metrics->width = cbox.xMax - cbox.xMin; - metrics->height = cbox.yMax - cbox.yMin; - - metrics->horiBearingX = cbox.xMin; - metrics->horiBearingY = cbox.yMax; - } - } - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1gload.h b/subsys/win32k/freetype/src/type1z/z1gload.h deleted file mode 100644 index e8abaa7..0000000 --- a/subsys/win32k/freetype/src/type1z/z1gload.h +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1gload.h */ -/* */ -/* Experimental Type 1 Glyph Loader (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1GLOAD_H -#define Z1GLOAD_H - - -#ifdef FT_FLAT_COMPILE - -#include "z1objs.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Builder */ - /* */ - /* */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* last :: The last point position. */ - /* */ - /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ - /* */ - /* scale_y :: The vertical scale (FUnits to sub-pixels). */ - /* */ - /* pos_x :: The horizontal translation (for composite glyphs). */ - /* */ - /* pos_y :: The vertical translation (for composite glyphs). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* no_recurse :: */ - /* */ - /* bbox :: The glyph's bounding box. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: A flag which indicates, if not set, that no points */ - /* are loaded. */ - /* */ - /* error :: The current error code. */ - /* */ - /* metrics_only :: A flag whether to compute metrics only. */ - /* */ - typedef struct Z1_Builder_ - { - FT_Memory memory; - T1_Face face; - Z1_GlyphSlot glyph; - FT_GlyphLoader* loader; - - FT_Outline* current; /* the current glyph outline */ - FT_Outline* base; /* the composite glyph outline */ - - FT_Vector last; - - FT_Fixed scale_x; - FT_Fixed scale_y; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Error error; /* only used for memory errors */ - FT_Bool metrics_only; - - } Z1_Builder; - - - /* execution context charstring zone */ - typedef struct Z1_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } Z1_Decoder_Zone; - - - typedef struct Z1_Decoder_ - { - Z1_Builder builder; - - FT_Int stack[T1_MAX_CHARSTRINGS_OPERANDS]; - FT_Int* top; - - Z1_Decoder_Zone zones[T1_MAX_SUBRS_CALLS + 1]; - Z1_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - T1_Blend* blend; /* for multiple masters */ - - } Z1_Decoder; - - - LOCAL_DEF - void Z1_Init_Builder( Z1_Builder* builder, - T1_Face face, - Z1_Size size, - Z1_GlyphSlot glyph ); - - LOCAL_DEF - void Z1_Done_Builder( Z1_Builder* builder ); - - LOCAL_DEF - void Z1_Init_Decoder( Z1_Decoder* decoder ); - - LOCAL_DEF - FT_Error Z1_Compute_Max_Advance( T1_Face face, - FT_Int* max_advance ); - - LOCAL_DEF - FT_Error Z1_Parse_CharStrings( Z1_Decoder* decoder, - FT_Byte* charstring_base, - FT_Int charstring_len, - FT_Int num_subrs, - FT_Byte** subrs_base, - FT_Int* subrs_len ); - - LOCAL_DEF - FT_Error Z1_Load_Glyph( Z1_GlyphSlot glyph, - Z1_Size size, - FT_Int glyph_index, - FT_Int load_flags ); - - -#ifdef __cplusplus - } -#endif - - -#endif /* Z1GLOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1load.c b/subsys/win32k/freetype/src/type1z/z1load.c deleted file mode 100644 index ca8c29d..0000000 --- a/subsys/win32k/freetype/src/type1z/z1load.c +++ /dev/null @@ -1,1725 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1load.c */ -/* */ -/* Experimental Type 1 font loader (body). */ -/* */ -/* Copyright 1996-2000 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 the new and improved Type 1 data loader for FreeType 2. The */ - /* old loader has several problems: it is slow, complex, difficult to */ - /* maintain, and contains incredible hacks to make it accept some */ - /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */ - /* the Type 1 fonts on my machine still aren't loaded correctly by it. */ - /* */ - /* This version is much simpler, much faster and also easier to read and */ - /* maintain by a great order of magnitude. The idea behind it is to */ - /* _not_ try to read the Type 1 token stream with a state machine (i.e. */ - /* a Postscript-like interpreter) but rather to perform simple pattern */ - /* matching. */ - /* */ - /* Indeed, nearly all data definitions follow a simple pattern like */ - /* */ - /* ... /Field ... */ - /* */ - /* where can be a number, a boolean, a string, or an array of */ - /* numbers. There are a few exceptions, namely the encoding, font name, */ - /* charstrings, and subrs; they are handled with a special pattern */ - /* matching routine. */ - /* */ - /* All other common cases are handled very simply. The matching rules */ - /* are defined in the file `t1tokens.h' through the use of several */ - /* macros calls PARSE_XXX. */ - /* */ - /* This file is included twice here; the first time to generate parsing */ - /* callback functions, the second to generate a table of keywords (with */ - /* pointers to the associated callback). */ - /* */ - /* The function `parse_dict' simply scans *linearly* a given dictionary */ - /* (either the top-level or private one) and calls the appropriate */ - /* callback when it encounters an immediate keyword. */ - /* */ - /* This is by far the fastest way one can find to parse and read all */ - /* data. */ - /* */ - /* This led to tremendous code size reduction. Note that later, the */ - /* glyph loader will also be _greatly_ simplified, and the automatic */ - /* hinter will replace the clumsy `t1hinter'. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include - -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1load.h" - -#else - -#include - -#endif - - -#include /* for strncmp(), strcmp() */ -#include /* for isalnum() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1load - - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** MULTIPLE MASTERS SUPPORT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - static - FT_Error t1_allocate_blend( T1_Face face, - FT_UInt num_designs, - FT_UInt num_axis ) - { - T1_Blend* blend; - FT_Memory memory = face->root.memory; - FT_Error error = 0; - - - blend = face->blend; - if ( !blend ) - { - if ( ALLOC( blend, sizeof ( *blend ) ) ) - goto Exit; - - face->blend = blend; - } - - /* allocate design data if needed */ - if ( num_designs > 0 ) - { - if ( blend->num_designs == 0 ) - { - FT_UInt nn; - - - /* allocate the blend `private' and `font_info' dictionaries */ - if ( ALLOC_ARRAY( blend->font_infos[1], num_designs, T1_FontInfo ) || - ALLOC_ARRAY( blend->privates[1], num_designs, T1_Private ) || - ALLOC_ARRAY( blend->weight_vector, num_designs * 2, FT_Fixed ) ) - goto Exit; - - blend->default_weight_vector = blend->weight_vector + num_designs; - - blend->font_infos[0] = &face->type1.font_info; - blend->privates [0] = &face->type1.private_dict; - - for ( nn = 2; nn <= num_designs; nn++ ) - { - blend->privates[nn] = blend->privates [nn - 1] + 1; - blend->font_infos[nn] = blend->font_infos[nn - 1] + 1; - } - - blend->num_designs = num_designs; - } - else if ( blend->num_designs != num_designs ) - goto Fail; - } - - /* allocate axis data if needed */ - if ( num_axis > 0 ) - { - if ( blend->num_axis != 0 && blend->num_axis != num_axis ) - goto Fail; - - blend->num_axis = num_axis; - } - - /* allocate the blend design pos table if needed */ - num_designs = blend->num_designs; - num_axis = blend->num_axis; - if ( num_designs && num_axis && blend->design_pos[0] == 0 ) - { - FT_UInt n; - - - if ( ALLOC_ARRAY( blend->design_pos[0], - num_designs * num_axis, FT_Fixed ) ) - goto Exit; - - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = blend->design_pos[0] + num_axis * n; - } - - Exit: - return error; - - Fail: - error = -1; - goto Exit; - } - - - LOCAL_FUNC - FT_Error Z1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ) - { - T1_Blend* blend = face->blend; - FT_UInt n; - FT_Error error; - - - error = T1_Err_Invalid_Argument; - - if ( blend ) - { - master->num_axis = blend->num_axis; - master->num_designs = blend->num_designs; - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_MM_Axis* axis = master->axis + n; - T1_DesignMap* map = blend->design_map + n; - - - axis->name = blend->axis_names[n]; - axis->minimum = map->design_points[0]; - axis->maximum = map->design_points[map->num_points - 1]; - } - error = 0; - } - return error; - } - - - LOCAL_FUNC - FT_Error Z1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - T1_Blend* blend = face->blend; - FT_Error error; - FT_UInt n, m; - - - error = T1_Err_Invalid_Argument; - - if ( blend && blend->num_axis == num_coords ) - { - /* recompute the weight vector from the blend coordinates */ - error = FT_Err_Ok; - - for ( n = 0; n < blend->num_designs; n++ ) - { - FT_Fixed result = 0x10000L; /* 1.0 fixed */ - - - for ( m = 0; m < blend->num_axis; m++ ) - { - FT_Fixed factor; - - - /* get current blend axis position */ - factor = coords[m]; - if ( factor < 0 ) factor = 0; - if ( factor > 0x10000L ) factor = 0x10000L; - - if ( ( n & ( 1 << m ) ) == 0 ) - factor = 0x10000L - factor; - - result = FT_MulFix( result, factor ); - } - blend->weight_vector[n] = result; - } - - error = FT_Err_Ok; - } - return error; - } - - - LOCAL_FUNC - FT_Error Z1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - T1_Blend* blend = face->blend; - FT_Error error; - FT_UInt n, p; - - - error = T1_Err_Invalid_Argument; - if ( blend && blend->num_axis == num_coords ) - { - /* compute the blend coordinates through the blend design map */ - FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; - - - for ( n = 0; n < blend->num_axis; n++ ) - { - FT_Long design = coords[n]; - FT_Fixed the_blend; - T1_DesignMap* map = blend->design_map + n; - FT_Fixed* designs = map->design_points; - FT_Fixed* blends = map->blend_points; - FT_Int before = -1, after = -1; - - for ( p = 0; p < map->num_points; p++ ) - { - FT_Fixed p_design = designs[p]; - - - /* exact match ? */ - if ( design == p_design ) - { - the_blend = blends[p]; - goto Found; - } - - if ( design < p_design ) - { - after = p; - break; - } - - before = p; - } - - /* now, interpolate if needed */ - if ( before < 0 ) - the_blend = blends[0]; - - else if ( after < 0 ) - the_blend = blends[map->num_points - 1]; - - else - the_blend = FT_MulDiv( design - designs[before], - blends [after] - blends [before], - designs[after] - designs[before] ); - - Found: - final_blends[n] = the_blend; - } - - error = Z1_Set_MM_Blend( face, num_coords, final_blends ); - } - - return error; - } - - - LOCAL_FUNC - void Z1_Done_Blend( T1_Face face ) - { - FT_Memory memory = face->root.memory; - T1_Blend* blend = face->blend; - - - if ( blend ) - { - FT_UInt num_designs = blend->num_designs; - FT_UInt num_axis = blend->num_axis; - FT_UInt n; - - - /* release design pos table */ - FREE( blend->design_pos[0] ); - for ( n = 1; n < num_designs; n++ ) - blend->design_pos[n] = 0; - - /* release blend `private' and `font info' dictionaries */ - FREE( blend->privates[1] ); - FREE( blend->font_infos[1] ); - - for ( n = 0; n < num_designs; n++ ) - { - blend->privates [n] = 0; - blend->font_infos[n] = 0; - } - - /* release weight vectors */ - FREE( blend->weight_vector ); - blend->default_weight_vector = 0; - - /* release axis names */ - for ( n = 0; n < num_axis; n++ ) - FREE( blend->axis_names[n] ); - - /* release design map */ - for ( n = 0; n < num_axis; n++ ) - { - T1_DesignMap* dmap = blend->design_map + n; - - - FREE( dmap->design_points ); - dmap->num_points = 0; - } - - FREE( face->blend ); - } - } - - - static - void parse_blend_axis_types( T1_Face face, - Z1_Loader* loader ) - { - Z1_Token_Rec axis_tokens[ T1_MAX_MM_AXIS ]; - FT_Int n, num_axis; - FT_Error error = 0; - T1_Blend* blend; - FT_Memory memory; - - - /* take an array of objects */ - Z1_ToTokenArray( &loader->parser, axis_tokens, - T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", - num_axis )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* allocate blend if necessary */ - error = t1_allocate_blend( face, 0, (FT_UInt)num_axis ); - if ( error ) - goto Exit; - - blend = face->blend; - memory = face->root.memory; - - /* each token is an immediate containing the name of the axis */ - for ( n = 0; n < num_axis; n++ ) - { - Z1_Token_Rec* token = axis_tokens + n; - FT_Byte* name; - FT_Int len; - - /* skip first slash, if any */ - if (token->start[0] == '/') - token->start++; - - len = token->limit - token->start; - if ( len <= 0 ) - { - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - if ( ALLOC( blend->axis_names[n], len + 1 ) ) - goto Exit; - - name = (FT_Byte*)blend->axis_names[n]; - MEM_Copy( name, token->start, len ); - name[len] = 0; - } - - Exit: - loader->parser.error = error; - } - - - static - void parse_blend_design_positions( T1_Face face, - Z1_Loader* loader ) - { - Z1_Token_Rec design_tokens[ T1_MAX_MM_DESIGNS ]; - FT_Int num_designs; - FT_Int num_axis; - Z1_Parser* parser = &loader->parser; - - FT_Error error = 0; - T1_Blend* blend; - - - /* get the array of design tokens - compute number of designs */ - Z1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) - { - FT_ERROR(( "parse_blend_design_positions:" )); - FT_ERROR(( " incorrect number of designs: %d\n", - num_designs )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - FT_UInt n; - - - blend = face->blend; - num_axis = 0; /* make compiler happy */ - - for ( n = 0; n < (FT_UInt)num_designs; n++ ) - { - Z1_Token_Rec axis_tokens[ T1_MAX_MM_DESIGNS ]; - Z1_Token_Rec* token; - FT_Int axis, n_axis; - - - /* read axis/coordinates tokens */ - token = design_tokens + n; - parser->cursor = token->start - 1; - parser->limit = token->limit + 1; - Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis ); - - if ( n == 0 ) - { - num_axis = n_axis; - error = t1_allocate_blend( face, num_designs, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - } - else if ( n_axis != num_axis ) - { - FT_ERROR(( "parse_blend_design_positions: incorrect table\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* now, read each axis token into the design position */ - for ( axis = 0; axis < n_axis; axis++ ) - { - Z1_Token_Rec* token2 = axis_tokens + axis; - - - parser->cursor = token2->start; - parser->limit = token2->limit; - blend->design_pos[n][axis] = Z1_ToFixed( parser, 0 ); - } - } - - loader->parser.cursor = old_cursor; - loader->parser.limit = old_limit; - } - - Exit: - loader->parser.error = error; - } - - - static - void parse_blend_design_map( T1_Face face, - Z1_Loader* loader ) - { - FT_Error error = 0; - Z1_Parser* parser = &loader->parser; - T1_Blend* blend; - Z1_Token_Rec axis_tokens[ T1_MAX_MM_AXIS ]; - FT_Int n, num_axis; - FT_Byte* old_cursor; - FT_Byte* old_limit; - FT_Memory memory = face->root.memory; - - - Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", - num_axis )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - old_cursor = parser->cursor; - old_limit = parser->limit; - - error = t1_allocate_blend( face, 0, num_axis ); - if ( error ) - goto Exit; - blend = face->blend; - - /* now, read each axis design map */ - for ( n = 0; n < num_axis; n++ ) - { - T1_DesignMap* map = blend->design_map + n; - Z1_Token_Rec* token; - FT_Int p, num_points; - - - token = axis_tokens + n; - parser->cursor = token->start; - parser->limit = token->limit; - - /* count the number of map points */ - { - FT_Byte* p = token->start; - FT_Byte* limit = token->limit; - - - num_points = 0; - for ( ; p < limit; p++ ) - if ( p[0] == '[' ) - num_points++; - } - if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS ) - { - FT_ERROR(( "parse_blend_design_map: incorrect table\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - /* allocate design map data */ - if ( ALLOC_ARRAY( map->design_points, num_points * 2, FT_Fixed ) ) - goto Exit; - map->blend_points = map->design_points + num_points; - map->num_points = (FT_Byte)num_points; - - for ( p = 0; p < num_points; p++ ) - { - map->design_points[p] = Z1_ToInt( parser ); - map->blend_points [p] = Z1_ToFixed( parser, 0 ); - } - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - parser->error = error; - } - - - static - void parse_weight_vector( T1_Face face, - Z1_Loader* loader ) - { - FT_Error error = 0; - Z1_Parser* parser = &loader->parser; - T1_Blend* blend = face->blend; - Z1_Token_Rec master; - FT_UInt n; - FT_Byte* old_cursor; - FT_Byte* old_limit; - - - if ( !blend || blend->num_designs == 0 ) - { - FT_ERROR(( "parse_weight_vector: too early!\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - Z1_ToToken( parser, &master ); - if ( master.type != t1_token_array ) - { - FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - old_cursor = parser->cursor; - old_limit = parser->limit; - - parser->cursor = master.start; - parser->limit = master.limit; - - for ( n = 0; n < blend->num_designs; n++ ) - { - blend->default_weight_vector[n] = - blend->weight_vector[n] = Z1_ToFixed( parser, 0 ); - } - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - parser->error = error; - } - - - /* the keyword `/shareddict' appears in some multiple master fonts */ - /* with a lot of Postscript garbage behind it (that's completely out */ - /* of spec!); we detect it and terminate the parsing */ - /* */ - static - void parse_shared_dict( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - - FT_UNUSED( face ); - - - parser->cursor = parser->limit; - parser->error = 0; - } - -#endif /* Z1_CONFIG_OPTION_NO_MM_SUPPORT */ - - - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** TYPE 1 SYMBOL PARSING *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* First of all, define the token field static variables. This is a set */ - /* of Z1_Field_Rec variables used later. */ - /* */ - /*************************************************************************/ - -#define Z1_NEW_STRING( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_STRING( T1TYPE, _field ); - -#define Z1_NEW_BOOL( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_BOOL( T1TYPE, _field ); - -#define Z1_NEW_NUM( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM( T1TYPE, _field ); - -#define Z1_NEW_FIXED( _name, _field ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED( T1TYPE, _field, _power ); - -#define Z1_NEW_NUM_TABLE( _name, _field, _max, _count ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM_ARRAY( T1TYPE, _field, _count, _max ); - -#define Z1_NEW_FIXED_TABLE( _name, _field, _max, _count ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED_ARRAY( T1TYPE, _field, _count, _max ); - -#define Z1_NEW_NUM_TABLE2( _name, _field, _max ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_NUM_ARRAY2( T1TYPE, _field, _max ); - -#define Z1_NEW_FIXED_TABLE2( _name, _field, _max ) \ - static \ - const Z1_Field_Rec t1_field_ ## _field = \ - Z1_FIELD_FIXED_ARRAY2( T1TYPE, _field, _max ); - - -#define Z1_FONTINFO_STRING( n, f ) Z1_NEW_STRING( n, f ) -#define Z1_FONTINFO_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_FONTINFO_BOOL( n, f ) Z1_NEW_BOOL( n, f ) -#define Z1_PRIVATE_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_PRIVATE_FIXED( n, f ) Z1_NEW_FIXED( n, f ) -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_NEW_NUM_TABLE( n, f, m, c ) -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_NEW_NUM_TABLE2( n, f, m ) -#define Z1_TOPDICT_NUM( n, f ) Z1_NEW_NUM( n, f ) -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_NEW_FIXED_TABLE2( n, f, m ) - - - /* including this file defines all field variables */ -#ifdef FT_FLAT_COMPILE - -#include "z1tokens.h" - -#else - -#include - -#endif - - - /*************************************************************************/ - /* */ - /* Second, define the keyword variables. This is a set of Z1_KeyWord */ - /* structures used to model the way each keyword is `loaded'. */ - /* */ - /*************************************************************************/ - - typedef void (*Z1_Parse_Func)( T1_Face face, - Z1_Loader* loader ); - - - typedef enum Z1_KeyWord_Type_ - { - t1_keyword_callback = 0, - t1_keyword_field, - t1_keyword_field_table - - } Z1_KeyWord_Type; - - - typedef enum Z1_KeyWord_Location_ - { - t1_keyword_type1 = 0, - t1_keyword_font_info, - t1_keyword_private - - } Z1_KeyWord_Location; - - - typedef struct Z1_KeyWord_ - { - const char* name; - Z1_KeyWord_Type type; - Z1_KeyWord_Location location; - Z1_Parse_Func parsing; - const Z1_Field_Rec* field; - - } Z1_KeyWord; - - -#define Z1_KEYWORD_CALLBACK( name, callback ) \ - { \ - name, t1_keyword_callback, t1_keyword_type1, callback, 0 \ - } - -#define Z1_KEYWORD_TYPE1( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_type1, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_font_info, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE( name, f ) \ - { \ - name, t1_keyword_field, t1_keyword_private, 0, &t1_field_ ## f \ - } - -#define Z1_KEYWORD_FONTINFO_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_font_info, 0, \ - &t1_field_ ## f \ - } - -#define Z1_KEYWORD_PRIVATE_TABLE( name, f ) \ - { \ - name, t1_keyword_field_table, t1_keyword_private, 0, \ - &t1_field_ ## f \ - } - - -#undef Z1_FONTINFO_STRING -#undef Z1_FONTINFO_NUM -#undef Z1_FONTINFO_BOOL -#undef Z1_PRIVATE_NUM -#undef Z1_PRIVATE_FIXED -#undef Z1_PRIVATE_NUM_TABLE -#undef Z1_PRIVATE_NUM_TABLE2 -#undef Z1_TOPDICT_NUM -#undef Z1_TOPDICT_NUM_FIXED2 - -#define Z1_FONTINFO_STRING( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_NUM( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_FONTINFO_BOOL( n, f ) Z1_KEYWORD_FONTINFO( n, f ), -#define Z1_PRIVATE_NUM( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_FIXED( n, f ) Z1_KEYWORD_PRIVATE( n, f ), -#define Z1_PRIVATE_NUM_TABLE( n, f, m, c ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_PRIVATE_NUM_TABLE2( n, f, m ) Z1_KEYWORD_PRIVATE_TABLE( n, f ), -#define Z1_TOPDICT_NUM( n, f ) Z1_KEYWORD_TYPE1( n, f ), -#define Z1_TOPDICT_NUM_FIXED2( n, f, m ) Z1_KEYWORD_TYPE1( n, f ), - - - static - FT_Error t1_load_keyword( T1_Face face, - Z1_Loader* loader, - Z1_KeyWord* keyword ) - { - FT_Error error; - void* dummy_object; - void** objects; - FT_UInt max_objects; - T1_Blend* blend = face->blend; - - - /* if the keyword has a dedicated callback, call it */ - if ( keyword->type == t1_keyword_callback ) - { - keyword->parsing( face, loader ); - error = loader->parser.error; - goto Exit; - } - - /* now, the keyword is either a simple field, or a table of fields; */ - /* we are now going to take care of it */ - switch ( keyword->location ) - { - case t1_keyword_font_info: - dummy_object = &face->type1.font_info; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->font_infos; - max_objects = blend->num_designs; - } - break; - - case t1_keyword_private: - dummy_object = &face->type1.private_dict; - objects = &dummy_object; - max_objects = 0; - - if ( blend ) - { - objects = (void**)blend->privates; - max_objects = blend->num_designs; - } - break; - - default: - dummy_object = &face->type1; - objects = &dummy_object; - max_objects = 0; - } - - if ( keyword->type == t1_keyword_field_table ) - error = Z1_Load_Field_Table( &loader->parser, keyword->field, - objects, max_objects, 0 ); - else - error = Z1_Load_Field( &loader->parser, keyword->field, - objects, max_objects, 0 ); - - Exit: - return error; - } - - - static - int is_space( char c ) - { - return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); - } - - - static - int is_alpha( char c ) - { - return ( isalnum( c ) || - ( c == '.' ) || - ( c == '_' ) ); - } - - - static - void skip_whitespace( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - - while ( cur < parser->limit && is_space( *cur ) ) - cur++; - - parser->cursor = cur; - } - - - static - void skip_blackspace( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - - while ( cur < parser->limit && !is_space( *cur ) ) - cur++; - - parser->cursor = cur; - } - - - static - int read_binary_data( Z1_Parser* parser, - FT_Int* size, - FT_Byte** base ) - { - FT_Byte* cur; - FT_Byte* limit = parser->limit; - - - /* the binary data has the following format */ - /* */ - /* `size' [white*] RD white ....... ND */ - /* */ - - skip_whitespace( parser ); - cur = parser->cursor; - - if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 ) - { - *size = Z1_ToInt( parser ); - - skip_whitespace( parser ); - skip_blackspace( parser ); /* `RD' or `-|' or something else */ - - /* there is only one whitespace char after the */ - /* `RD' or `-|' token */ - *base = parser->cursor + 1; - - parser->cursor += *size+1; - return 1; - } - - FT_ERROR(( "read_binary_data: invalid size field\n" )); - parser->error = T1_Err_Invalid_File_Format; - return 0; - } - - - /* we will now define the routines used to handle */ - /* the `/Encoding', `/Subrs', and `/CharStrings' */ - /* dictionaries */ - - static - void parse_font_name( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Error error; - FT_Memory memory = parser->memory; - FT_Int len; - FT_Byte* cur; - FT_Byte* cur2; - FT_Byte* limit; - - - skip_whitespace( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur >= limit - 1 || *cur != '/' ) - return; - - cur++; - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 ) - { - if ( ALLOC( face->type1.font_name, len + 1 ) ) - { - parser->error = error; - return; - } - - MEM_Copy( face->type1.font_name, cur, len ); - face->type1.font_name[len] = '\0'; - } - parser->cursor = cur2; - } - - - static - void parse_font_bbox( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Short temp[4]; - FT_BBox* bbox = &face->type1.font_bbox; - - - (void)Z1_ToCoordArray( parser, 4, temp ); - bbox->xMin = temp[0]; - bbox->yMin = temp[1]; - bbox->xMax = temp[2]; - bbox->yMax = temp[3]; - } - - - static - void parse_font_matrix( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Fixed temp[4]; - - - (void)Z1_ToFixedArray( parser, 4, temp, 3 ); - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - } - - - static - void parse_encoding( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - /* skip whitespace */ - while ( is_space( *cur ) ) - { - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "parse_encoding: out of bounds!\n" )); - parser->error = T1_Err_Invalid_File_Format; - return; - } - } - - /* if we have a number, then the encoding is an array, */ - /* and we must load it now */ - if ( (FT_Byte)( *cur - '0' ) < 10 ) - { - T1_Encoding* encode = &face->type1.encoding; - FT_Int count, n; - Z1_Table* char_table = &loader->encoding_table; - FT_Memory memory = parser->memory; - FT_Error error; - - - /* read the number of entries in the encoding, should be 256 */ - count = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* we use a Z1_Table to store our charnames */ - encode->num_chars = count; - if ( ALLOC_ARRAY( encode->char_index, count, FT_Short ) || - ALLOC_ARRAY( encode->char_name, count, FT_String* ) || - ( error = Z1_New_Table( char_table, count, memory ) ) != 0 ) - { - parser->error = error; - return; - } - - /* Now, we will need to read a record of the form */ - /* ... charcode /charname ... for each entry in our table */ - /* */ - /* We simply look for a number followed by an immediate */ - /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type1 fonts: */ - /* */ - /* 0 1 255 { 1 index exch /.notdef put } for dup */ - /* */ - /* used to clean the encoding array before anything else. */ - /* */ - /* We stop when we encounter a `def'. */ - - cur = parser->cursor; - limit = parser->limit; - n = 0; - - for ( ; cur < limit; ) - { - FT_Byte c; - - - c = *cur; - - /* we stop when we encounter a `def' */ - if ( c == 'd' && cur + 3 < limit ) - { - if ( cur[1] == 'e' && - cur[2] == 'f' && - is_space(cur[-1]) && - is_space(cur[3]) ) - { - FT_TRACE6(( "encoding end\n" )); - break; - } - } - - /* otherwise, we must find a number before anything else */ - if ( (FT_Byte)( c - '0' ) < 10 ) - { - FT_Int charcode; - - - parser->cursor = cur; - charcode = Z1_ToInt( parser ); - cur = parser->cursor; - - /* skip whitespace */ - while ( cur < limit && is_space( *cur ) ) - cur++; - - if ( cur < limit && *cur == '/' ) - { - /* bingo, we have an immediate name -- it must be a */ - /* character name */ - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur - 1; - - parser->error = Z1_Add_Table( char_table, charcode, - cur + 1, len + 1 ); - char_table->elements[charcode][len] = '\0'; - if ( parser->error ) - return; - - cur = cur2; - } - } - else - cur++; - } - - face->type1.encoding_type = t1_encoding_array; - parser->cursor = cur; - } - /* Otherwise, we should have either `StandardEncoding' or */ - /* `ExpertEncoding' */ - else - { - if ( cur + 17 < limit && - strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = t1_encoding_standard; - - else if ( cur + 15 < limit && - strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = t1_encoding_expert; - - else - { - FT_ERROR(( "parse_encoding: invalid token!\n" )); - parser->error = T1_Err_Invalid_File_Format; - } - } - } - - - static - void parse_subrs( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - Z1_Table* table = &loader->subrs; - FT_Memory memory = parser->memory; - FT_Error error; - FT_Int n; - - - loader->num_subrs = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* position the parser right before the `dup' of the first subr */ - skip_whitespace( parser ); - skip_blackspace( parser ); /* `array' */ - skip_whitespace( parser ); - - /* initialize subrs array */ - error = Z1_New_Table( table, loader->num_subrs, memory ); - if ( error ) - goto Fail; - - /* the format is simple: */ - /* */ - /* `index' + binary data */ - /* */ - - for ( n = 0; n < loader->num_subrs; n++ ) - { - FT_Int index, size; - FT_Byte* base; - - - /* If the next token isn't `dup', we are also done. This */ - /* happens when there are `holes' in the Subrs array. */ - if ( strncmp( (char*)parser->cursor, "dup", 3 ) != 0 ) - break; - - index = Z1_ToInt( parser ); - - if ( !read_binary_data( parser, &size, &base ) ) - return; - - /* The binary string is followed by one token, e.g. `NP' */ - /* (bound to `noaccess put') or by two separate tokens: */ - /* `noaccess' & `put'. We position the parser right */ - /* before the next `dup', if any. */ - skip_whitespace( parser ); - skip_blackspace( parser ); /* `NP' or `I' or `noaccess' */ - skip_whitespace( parser ); - - if ( strncmp( (char*)parser->cursor, "put", 3 ) == 0 ) - { - skip_blackspace( parser ); /* skip `put' */ - skip_whitespace( parser ); - } - - /* some fonts use a value of -1 for lenIV to indicate that */ - /* the charstrings are unencoded */ - /* */ - /* thanks to Tom Kacvinsky for pointing this out */ - /* */ - if ( face->type1.private_dict.lenIV >= 0 ) - { - Z1_Decrypt( base, size, 4330 ); - size -= face->type1.private_dict.lenIV; - base += face->type1.private_dict.lenIV; - } - - error = Z1_Add_Table( table, index, base, size ); - if ( error ) - goto Fail; - } - return; - - Fail: - parser->error = error; - } - - - static - void parse_charstrings( T1_Face face, - Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - Z1_Table* code_table = &loader->charstrings; - Z1_Table* name_table = &loader->glyph_names; - FT_Memory memory = parser->memory; - FT_Error error; - - FT_Byte* cur; - FT_Byte* limit = parser->limit; - FT_Int n; - - - loader->num_glyphs = Z1_ToInt( parser ); - if ( parser->error ) - return; - - /* initialize tables */ - error = Z1_New_Table( code_table, loader->num_glyphs, memory ) || - Z1_New_Table( name_table, loader->num_glyphs, memory ); - if ( error ) - goto Fail; - - n = 0; - for (;;) - { - FT_Int size; - FT_Byte* base; - - - /* the format is simple: */ - /* `/glyphname' + binary data */ - /* */ - /* note that we stop when we find a `def' */ - /* */ - skip_whitespace( parser ); - - cur = parser->cursor; - if ( cur >= limit ) - break; - - /* we stop when we find a `def' or `end' keyword */ - if ( *cur == 'd' && - cur + 3 < limit && - cur[1] == 'e' && - cur[2] == 'f' ) - break; - - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' ) - break; - - if ( *cur != '/' ) - skip_blackspace( parser ); - else - { - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - len = cur2 - cur - 1; - - error = Z1_Add_Table( name_table, n, cur + 1, len + 1 ); - if ( error ) - goto Fail; - - /* add a trailing zero to the name table */ - name_table->elements[n][len] = '\0'; - - parser->cursor = cur2; - if ( !read_binary_data( parser, &size, &base ) ) - return; - - if ( face->type1.private_dict.lenIV >= 0 ) - { - Z1_Decrypt( base, size, 4330 ); - size -= face->type1.private_dict.lenIV; - base += face->type1.private_dict.lenIV; - } - - error = Z1_Add_Table( code_table, n, base, size ); - if ( error ) - goto Fail; - - n++; - if ( n >= loader->num_glyphs ) - break; - } - } - loader->num_glyphs = n; - return; - - Fail: - parser->error = error; - } - - - static - const Z1_KeyWord t1_keywords[] = - { - -#ifdef FT_FLAT_COMPILE - -#include "z1tokens.h" - -#else - -#include - -#endif - - /* now add the special functions... */ - Z1_KEYWORD_CALLBACK( "FontName", parse_font_name ), - Z1_KEYWORD_CALLBACK( "FontBBox", parse_font_bbox ), - Z1_KEYWORD_CALLBACK( "FontMatrix", parse_font_matrix ), - Z1_KEYWORD_CALLBACK( "Encoding", parse_encoding ), - Z1_KEYWORD_CALLBACK( "Subrs", parse_subrs ), - Z1_KEYWORD_CALLBACK( "CharStrings", parse_charstrings ), - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - Z1_KEYWORD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ), - Z1_KEYWORD_CALLBACK( "BlendDesignMap", parse_blend_design_map ), - Z1_KEYWORD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ), - Z1_KEYWORD_CALLBACK( "WeightVector", parse_weight_vector ), - Z1_KEYWORD_CALLBACK( "shareddict", parse_shared_dict ), -#endif - - Z1_KEYWORD_CALLBACK( 0, 0 ) - }; - - - static - FT_Error parse_dict( T1_Face face, - Z1_Loader* loader, - FT_Byte* base, - FT_Long size ) - { - Z1_Parser* parser = &loader->parser; - - - parser->cursor = base; - parser->limit = base + size; - parser->error = 0; - - { - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - - - for ( ; cur < limit; cur++ ) - { - /* look for `FontDirectory', which causes problems on some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) - { - FT_Byte* cur2; - - - /* skip the `FontDirectory' keyword */ - cur += 13; - cur2 = cur; - - /* lookup the `known' keyword */ - while ( cur < limit && *cur != 'k' && - strncmp( (char*)cur, "known", 5 ) ) - cur++; - - if ( cur < limit ) - { - Z1_Token_Rec token; - - - /* skip the `known' keyword and the token following it */ - cur += 5; - loader->parser.cursor = cur; - Z1_ToToken( &loader->parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == t1_token_array ) - cur2 = parser->cursor; - } - cur = cur2; - } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_Byte* cur2; - FT_Int len; - - - cur++; - cur2 = cur; - while ( cur2 < limit && is_alpha( *cur2 ) ) - cur2++; - - len = cur2 - cur; - if ( len > 0 && len < 22 ) - { - if ( !loader->fontdata ) - { - if ( strncmp( (char*)cur, "FontInfo", 8 ) == 0 ) - loader->fontdata = 1; - } - else - { - /* now, compare the immediate name to the keyword table */ - Z1_KeyWord* keyword = (Z1_KeyWord*)t1_keywords; - - - for (;;) - { - FT_Byte* name; - - - name = (FT_Byte*)keyword->name; - if ( !name ) - break; - - if ( cur[0] == name[0] && - len == (FT_Int)strlen( (const char*)name ) ) - { - FT_Int n; - - - for ( n = 1; n < len; n++ ) - if ( cur[n] != name[n] ) - break; - - if ( n >= len ) - { - /* we found it -- run the parsing callback! */ - parser->cursor = cur2; - skip_whitespace( parser ); - parser->error = t1_load_keyword( face, loader, keyword ); - if ( parser->error ) - return parser->error; - - cur = parser->cursor; - break; - } - } - keyword++; - } - } - } - } - } - } - return parser->error; - } - - - static - void t1_init_loader( Z1_Loader* loader, - T1_Face face ) - { - FT_UNUSED( face ); - - MEM_Set( loader, 0, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->fontdata = 0; - } - - - static - void t1_done_loader( Z1_Loader* loader ) - { - Z1_Parser* parser = &loader->parser; - - - /* finalize tables */ - Z1_Release_Table( &loader->encoding_table ); - Z1_Release_Table( &loader->charstrings ); - Z1_Release_Table( &loader->glyph_names ); - Z1_Release_Table( &loader->subrs ); - - /* finalize parser */ - Z1_Done_Parser( parser ); - } - - - LOCAL_FUNC - FT_Error Z1_Open_Face( T1_Face face ) - { - Z1_Loader loader; - Z1_Parser* parser; - T1_Font* type1 = &face->type1; - FT_Error error; - - - t1_init_loader( &loader, face ); - - /* default lenIV */ - type1->private_dict.lenIV = 4; - - parser = &loader.parser; - error = Z1_New_Parser( parser, face->root.stream, face->root.memory ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, parser->base_dict, parser->base_len ); - if ( error ) - goto Exit; - - error = Z1_Get_Private_Dict( parser ); - if ( error ) - goto Exit; - - error = parse_dict( face, &loader, parser->private_dict, - parser->private_len ); - if ( error ) - goto Exit; - - /* now, propagate the subrs, charstrings, and glyphnames tables */ - /* to the Type1 data */ - type1->num_glyphs = loader.num_glyphs; - - if ( !loader.subrs.init ) - { - FT_ERROR(( "Z1_Open_Face: no subrs array in face!\n" )); - error = T1_Err_Invalid_File_Format; - } - - if ( !loader.charstrings.init ) - { - FT_ERROR(( "Z1_Open_Face: no charstrings array in face!\n" )); - error = T1_Err_Invalid_File_Format; - } - - loader.subrs.init = 0; - type1->num_subrs = loader.num_subrs; - type1->subrs_block = loader.subrs.block; - type1->subrs = loader.subrs.elements; - type1->subrs_len = loader.subrs.lengths; - - loader.charstrings.init = 0; - type1->charstrings_block = loader.charstrings.block; - type1->charstrings = loader.charstrings.elements; - type1->charstrings_len = loader.charstrings.lengths; - - /* we copy the glyph names `block' and `elements' fields; */ - /* the `lengths' field must be released later */ - type1->glyph_names_block = loader.glyph_names.block; - type1->glyph_names = (FT_String**)loader.glyph_names.elements; - loader.glyph_names.block = 0; - loader.glyph_names.elements = 0; - - /* we must now build type1.encoding when we have a custom */ - /* array.. */ - if ( type1->encoding_type == t1_encoding_array ) - { - FT_Int charcode, index, min_char, max_char; - FT_Byte* char_name; - FT_Byte* glyph_name; - - - /* OK, we do the following: for each element in the encoding */ - /* table, look up the index of the glyph having the same name */ - /* the index is then stored in type1.encoding.char_index, and */ - /* a the name to type1.encoding.char_name */ - - min_char = +32000; - max_char = -32000; - - charcode = 0; - for ( ; charcode < loader.encoding_table.num_elems; charcode++ ) - { - type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = ".notdef"; - - char_name = loader.encoding_table.elements[charcode]; - if ( char_name ) - for ( index = 0; index < type1->num_glyphs; index++ ) - { - glyph_name = (FT_Byte*)type1->glyph_names[index]; - if ( strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) - { - type1->encoding.char_index[charcode] = index; - type1->encoding.char_name [charcode] = (char*)glyph_name; - - if (charcode < min_char) min_char = charcode; - if (charcode > max_char) max_char = charcode; - break; - } - } - } - type1->encoding.code_first = min_char; - type1->encoding.code_last = max_char; - type1->encoding.num_chars = loader.num_chars; - } - - Exit: - t1_done_loader( &loader ); - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1load.h b/subsys/win32k/freetype/src/type1z/z1load.h deleted file mode 100644 index ca4ba98..0000000 --- a/subsys/win32k/freetype/src/type1z/z1load.h +++ /dev/null @@ -1,93 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1load.h */ -/* */ -/* Experimental Type 1 font loader (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1LOAD_H -#define Z1LOAD_H - -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.h" - -#else - -#include - -#endif - - -#ifdef __cplusplus - extern "C" { -#endif - - typedef struct Z1_Loader_ - { - Z1_Parser parser; /* parser used to read the stream */ - - FT_Int num_chars; /* number of characters in encoding */ - Z1_Table encoding_table; /* Z1_Table used to store the */ - /* encoding character names */ - - FT_Int num_glyphs; - Z1_Table glyph_names; - Z1_Table charstrings; - - FT_Int num_subrs; - Z1_Table subrs; - FT_Bool fontdata; - - } Z1_Loader; - - - LOCAL_DEF - FT_Error Z1_Open_Face( T1_Face face ); - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - - LOCAL_DEF - FT_Error Z1_Get_Multi_Master( T1_Face face, - FT_Multi_Master* master ); - - LOCAL_DEF - FT_Error Z1_Set_MM_Blend( T1_Face face, - FT_UInt num_coords, - FT_Fixed* coords ); - - LOCAL_DEF - FT_Error Z1_Set_MM_Design( T1_Face face, - FT_UInt num_coords, - FT_Long* coords ); - - LOCAL_DEF - void Z1_Done_Blend( T1_Face face ); - -#endif /* !Z1_CONFIG_OPTION_NO_MM_SUPPORT */ - - -#ifdef __cplusplus - } -#endif - -#endif /* Z1LOAD_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1objs.c b/subsys/win32k/freetype/src/type1z/z1objs.c deleted file mode 100644 index 97193e3..0000000 --- a/subsys/win32k/freetype/src/type1z/z1objs.c +++ /dev/null @@ -1,398 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1objs.c */ -/* */ -/* Experimental Type 1 objects manager (body). */ -/* */ -/* Copyright 1996-2000 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 - - -#ifdef FT_FLAT_COMPILE - -#include "z1gload.h" -#include "z1load.h" -#include "z1afm.h" - -#else - -#include -#include -#include - -#endif - - -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1objs - - - /*************************************************************************/ - /* */ - /* FACE FUNCTIONS */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Face */ - /* */ - /* */ - /* The face object destructor. */ - /* */ - /* */ - /* face :: A typeless pointer to the face object to destroy. */ - /* */ - LOCAL_FUNC - void Z1_Done_Face( T1_Face face ) - { - FT_Memory memory; - T1_Font* type1 = &face->type1; - - - if ( face ) - { - memory = face->root.memory; - -#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT - /* release multiple masters information */ - Z1_Done_Blend( face ); - face->blend = 0; -#endif - - /* release font info strings */ - { - T1_FontInfo* info = &type1->font_info; - - - FREE( info->version ); - FREE( info->notice ); - FREE( info->full_name ); - FREE( info->family_name ); - FREE( info->weight ); - } - - /* release top dictionary */ - FREE( type1->charstrings_len ); - FREE( type1->charstrings ); - FREE( type1->glyph_names ); - - FREE( type1->subrs ); - FREE( type1->subrs_len ); - - FREE( type1->subrs_block ); - FREE( type1->charstrings_block ); - FREE( type1->glyph_names_block ); - - FREE( type1->encoding.char_index ); - FREE( type1->font_name ); - -#ifndef Z1_CONFIG_OPTION_NO_AFM - /* release afm data if present */ - if ( face->afm_data ) - Z1_Done_AFM( memory, (Z1_AFM*)face->afm_data ); -#endif - - /* release unicode map, if any */ - FREE( face->unicode_map.maps ); - face->unicode_map.num_maps = 0; - - face->root.family_name = 0; - face->root.style_name = 0; - } - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Face */ - /* */ - /* */ - /* The face object constructor. */ - /* */ - /* */ - /* stream :: input stream where to load font data. */ - /* */ - /* face_index :: The index of the font face in the resource. */ - /* */ - /* num_params :: Number of additional generic parameters. Ignored. */ - /* */ - /* params :: Additional generic parameters. Ignored. */ - /* */ - /* */ - /* face :: The face record to build. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - PSNames_Interface* psnames; - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - FT_UNUSED( stream ); - - - face->root.num_faces = 1; - - psnames = (PSNames_Interface*)face->psnames; - if ( !psnames ) - { - psnames = (PSNames_Interface*) - FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psnames" ); - - face->psnames = psnames; - } - - /* open the tokenizer, this will also check the font format */ - error = Z1_Open_Face( face ); - if ( error ) - goto Exit; - - /* if we just wanted to check the format, leave successfully now */ - if ( face_index < 0 ) - goto Exit; - - /* check the face index */ - if ( face_index != 0 ) - { - FT_ERROR(( "Z1_Init_Face: invalid face index\n" )); - error = T1_Err_Invalid_Argument; - goto Exit; - } - - /* Now, load the font program into the face object */ - - /* Init the face object fields */ - /* Now set up root face fields */ - { - FT_Face root = (FT_Face)&face->root; - - - root->num_glyphs = face->type1.num_glyphs; - root->num_charmaps = 1; - - root->face_index = face_index; - root->face_flags = FT_FACE_FLAG_SCALABLE; - - root->face_flags |= FT_FACE_FLAG_HORIZONTAL; - - root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; - - if ( face->type1.font_info.is_fixed_pitch ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( face->blend ) - root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; - - /* XXX: TODO -- add kerning with .afm support */ - - /* get style name -- be careful, some broken fonts only */ - /* have a `/FontName' dictionary entry! */ - root->family_name = face->type1.font_info.family_name; - if ( root->family_name ) - { - char* full = face->type1.font_info.full_name; - char* family = root->family_name; - - - while ( *family && *full == *family ) - { - family++; - full++; - } - - root->style_name = ( *full == ' ' ? full + 1 - : (char *)"Regular" ); - } - else - { - /* do we have a `/FontName'? */ - if ( face->type1.font_name ) - { - root->family_name = face->type1.font_name; - root->style_name = "Regular"; - } - } - - /* no embedded bitmap support */ - root->num_fixed_sizes = 0; - root->available_sizes = 0; - - root->bbox = face->type1.font_bbox; - root->units_per_EM = 1000; - root->ascender = (FT_Short)face->type1.font_bbox.yMax; - root->descender = -(FT_Short)face->type1.font_bbox.yMin; - root->height = ( ( root->ascender + root->descender ) * 12 ) / 10; - - /* now compute the maximum advance width */ - - root->max_advance_width = face->type1.private_dict.standard_width[0]; - - /* compute max advance width for proportional fonts */ - if ( !face->type1.font_info.is_fixed_pitch ) - { - FT_Int max_advance; - - - error = Z1_Compute_Max_Advance( face, &max_advance ); - - /* in case of error, keep the standard width */ - if ( !error ) - root->max_advance_width = max_advance; - else - error = 0; /* clear error */ - } - - root->max_advance_height = root->height; - - root->underline_position = face->type1.font_info.underline_position; - root->underline_thickness = face->type1.font_info.underline_thickness; - - root->max_points = 0; - root->max_contours = 0; - } - - /* charmap support -- synthetize unicode charmap if possible */ - { - FT_Face root = &face->root; - FT_CharMap charmap = face->charmaprecs; - - - /* synthesize a Unicode charmap if there is support in the `PSNames' */ - /* module */ - if ( face->psnames ) - { - PSNames_Interface* psnames = (PSNames_Interface*)face->psnames; - - - if ( psnames->unicode_value ) - { - error = psnames->build_unicodes( - root->memory, - face->type1.num_glyphs, - (const char**)face->type1.glyph_names, - &face->unicode_map ); - if ( !error ) - { - root->charmap = charmap; - charmap->face = (FT_Face)face; - charmap->encoding = ft_encoding_unicode; - charmap->platform_id = 3; - charmap->encoding_id = 1; - charmap++; - } - - /* simply clear the error in case of failure (which really) */ - /* means that out of memory or no unicode glyph names */ - error = FT_Err_Ok; - } - } - - /* now, support either the standard, expert, or custom encoding */ - charmap->face = (FT_Face)face; - charmap->platform_id = 7; /* a new platform id for Adobe fonts? */ - - switch ( face->type1.encoding_type ) - { - case t1_encoding_standard: - charmap->encoding = ft_encoding_adobe_standard; - charmap->encoding_id = 0; - break; - - case t1_encoding_expert: - charmap->encoding = ft_encoding_adobe_expert; - charmap->encoding_id = 1; - break; - - default: - charmap->encoding = ft_encoding_adobe_custom; - charmap->encoding_id = 2; - break; - } - - root->charmaps = face->charmaps; - root->num_charmaps = charmap - face->charmaprecs + 1; - face->charmaps[0] = &face->charmaprecs[0]; - face->charmaps[1] = &face->charmaprecs[1]; - } - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Init_Driver */ - /* */ - /* */ - /* Initializes a given Type 1 driver object. */ - /* */ - /* */ - /* driver :: A handle to the target driver object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Init_Driver( Z1_Driver driver ) - { - FT_UNUSED( driver ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Driver */ - /* */ - /* */ - /* Finalizes a given Type 1 driver. */ - /* */ - /* */ - /* driver :: A handle to the target Type 1 driver. */ - /* */ - LOCAL_DEF - void Z1_Done_Driver( Z1_Driver driver ) - { - FT_UNUSED( driver ); - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1objs.h b/subsys/win32k/freetype/src/type1z/z1objs.h deleted file mode 100644 index c655a67..0000000 --- a/subsys/win32k/freetype/src/type1z/z1objs.h +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1objs.h */ -/* */ -/* Experimental Type 1 objects manager (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1OBJS_H -#define Z1OBJS_H - -#include -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - - /* The following structures must be defined by the hinter */ - typedef struct Z1_Size_Hints_ Z1_Size_Hints; - typedef struct Z1_Glyph_Hints_ Z1_Glyph_Hints; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Driver */ - /* */ - /* */ - /* A handle to a Type 1 driver object. */ - /* */ - typedef struct Z1_DriverRec_ *Z1_Driver; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Size */ - /* */ - /* */ - /* A handle to a Type 1 size object. */ - /* */ - typedef struct Z1_SizeRec_* Z1_Size; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_GlyphSlot */ - /* */ - /* */ - /* A handle to a Type 1 glyph slot object. */ - /* */ - typedef struct Z1_GlyphSlotRec_* Z1_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_CharMap */ - /* */ - /* */ - /* A handle to a Type 1 character mapping object. */ - /* */ - /* */ - /* The Type 1 format doesn't use a charmap but an encoding table. */ - /* The driver is responsible for making up charmap objects */ - /* corresponding to these tables. */ - /* */ - typedef struct Z1_CharMapRec_* Z1_CharMap; - - - /*************************************************************************/ - /* */ - /* HERE BEGINS THE TYPE1 SPECIFIC STUFF */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_SizeRec */ - /* */ - /* */ - /* Type 1 size record. */ - /* */ - typedef struct Z1_SizeRec_ - { - FT_SizeRec root; - FT_Bool valid; - Z1_Size_Hints* hints; /* defined in the hinter. This allows */ - /* us to experiment with different */ - /* hinting schemes without having to */ - /* change `z1objs' each time. */ - } Z1_SizeRec; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_GlyphSlotRec */ - /* */ - /* */ - /* Type 1 glyph slot record. */ - /* */ - typedef struct Z1_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Int max_points; - FT_Int max_contours; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - Z1_Glyph_Hints* hints; /* defined in the hinter */ - - } Z1_GlyphSlotRec; - - - LOCAL_DEF - FT_Error Z1_Init_Face( FT_Stream stream, - T1_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ); - - LOCAL_DEF - void Z1_Done_Face( T1_Face face ); - - LOCAL_DEF - FT_Error Z1_Init_Driver( Z1_Driver driver ); - - LOCAL_DEF - void Z1_Done_Driver( Z1_Driver driver ); - - -#ifdef __cplusplus - } -#endif - -#endif /* Z1OBJS_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1parse.c b/subsys/win32k/freetype/src/type1z/z1parse.c deleted file mode 100644 index 8c2dacb..0000000 --- a/subsys/win32k/freetype/src/type1z/z1parse.c +++ /dev/null @@ -1,1398 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1parse.c */ -/* */ -/* Experimental Type 1 parser (body). */ -/* */ -/* Copyright 1996-2000 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 Type 1 parser is in charge of the following: */ - /* */ - /* - provide an implementation of a growing sequence of objects called */ - /* a `Z1_Table' (used to build various tables needed by the loader). */ - /* */ - /* - opening .pfb and .pfa files to extract their top-level and private */ - /* dictionaries. */ - /* */ - /* - read numbers, arrays & strings from any dictionary. */ - /* */ - /* See `z1load.c' to see how data is loaded from the font file. */ - /* */ - /*************************************************************************/ - - -#include -#include -#include -#include -#include - - -#ifdef FT_FLAT_COMPILE - -#include "z1parse.h" - -#else - -#include - -#endif - - -#include /* for strncmp() */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_z1parse - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** IMPLEMENTATION OF Z1_TABLE OBJECT *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_New_Table */ - /* */ - /* */ - /* Initialises a Z1_Table. */ - /* */ - /* */ - /* table :: The address of the target table. */ - /* */ - /* */ - /* count :: The table size = the maximum number of elements. */ - /* */ - /* memory :: The memory object to use for all subsequent */ - /* reallocations. */ - /* */ - /* */ - /* FreeType error code. 0 means success. */ - /* */ - LOCAL_FUNC - FT_Error Z1_New_Table( Z1_Table* table, - FT_Int count, - FT_Memory memory ) - { - FT_Error error; - - - table->memory = memory; - if ( ALLOC_ARRAY( table->elements, count, FT_Byte* ) || - ALLOC_ARRAY( table->lengths, count, FT_Byte* ) ) - goto Exit; - - table->max_elems = count; - table->init = 0xdeadbeef; - table->num_elems = 0; - table->block = 0; - table->capacity = 0; - table->cursor = 0; - - Exit: - if ( error ) - FREE( table->elements ); - - return error; - } - - - static - void shift_elements( Z1_Table* table, - FT_Byte* old_base ) - { - FT_Long delta = table->block - old_base; - FT_Byte** offset = table->elements; - FT_Byte** limit = offset + table->max_elems; - - - if ( delta ) - for ( ; offset < limit; offset++ ) - { - if ( offset[0] ) - offset[0] += delta; - } - } - - - static - FT_Error reallocate_t1_table( Z1_Table* table, - FT_Int new_size ) - { - FT_Memory memory = table->memory; - FT_Byte* old_base = table->block; - FT_Error error; - - - /* reallocate the base block */ - if ( REALLOC( table->block, table->capacity, new_size ) ) - return error; - - table->capacity = new_size; - - /* shift all offsets if necessary */ - if ( old_base ) - shift_elements( table, old_base ); - - return T1_Err_Ok; - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Add_Table */ - /* */ - /* */ - /* Adds an object to a Z1_Table, possibly growing its memory block. */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* index :: The index of the object in the table. */ - /* */ - /* object :: The address of the object to copy in memory. */ - /* */ - /* length :: The length in bytes of the source object. */ - /* */ - /* */ - /* FreeType error code. 0 means success. An error is returned if a */ - /* reallocation fails. */ - /* */ - LOCAL_FUNC - FT_Error Z1_Add_Table( Z1_Table* table, - FT_Int index, - void* object, - FT_Int length ) - { - if ( index < 0 || index > table->max_elems ) - { - FT_ERROR(( "Z1_Add_Table: invalid index\n" )); - return T1_Err_Syntax_Error; - } - - /* grow the base block if needed */ - if ( table->cursor + length > table->capacity ) - { - FT_Error error; - FT_Int new_size = table->capacity; - - - while ( new_size < table->cursor + length ) - new_size += 1024; - - error = reallocate_t1_table( table, new_size ); - if ( error ) - return error; - } - - /* add the object to the base block and adjust offset */ - table->elements[index] = table->block + table->cursor; - table->lengths [index] = length; - MEM_Copy( table->block + table->cursor, object, length ); - - table->cursor += length; - return T1_Err_Ok; - } - - -#if 0 - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Done_Table */ - /* */ - /* */ - /* Finalizes a Z1_Table (i.e., reallocate it to its current cursor). */ - /* */ - /* */ - /* table :: The target table. */ - /* */ - /* */ - /* This function does NOT release the heap's memory block. It is up */ - /* to the caller to clean it, or reference it in its own structures. */ - /* */ - LOCAL_FUNC - void Z1_Done_Table( Z1_Table* table ) - { - FT_Memory memory = table->memory; - FT_Error error; - FT_Byte* old_base; - - - /* should never fail, as rec.cursor <= rec.size */ - old_base = table->block; - if ( !old_base ) - return; - - (void)REALLOC( table->block, table->capacity, table->cursor ); - table->capacity = table->cursor; - - if ( old_base != table->block ) - shift_elements( table, old_base ); - } - -#endif /* 0 */ - - - LOCAL_FUNC - void Z1_Release_Table( Z1_Table* table ) - { - FT_Memory memory = table->memory; - - - if ( table->init == (FT_Long)0xDEADBEEF ) - { - FREE( table->block ); - FREE( table->elements ); - FREE( table->lengths ); - table->init = 0; - } - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** INPUT STREAM PARSER *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - -#define IS_Z1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) -#define IS_Z1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) - -#define IS_Z1_SPACE( c ) ( IS_Z1_WHITESPACE( c ) || IS_Z1_LINESPACE( c ) ) - - - LOCAL_FUNC - void Z1_Skip_Spaces( Z1_Parser* parser ) - { - FT_Byte* cur = parser->cursor; - FT_Byte* limit = parser->limit; - - - while ( cur < limit ) - { - FT_Byte c = *cur; - - - if ( !IS_Z1_SPACE( c ) ) - break; - cur++; - } - parser->cursor = cur; - } - - - LOCAL_FUNC - void Z1_ToToken( Z1_Parser* parser, - Z1_Token_Rec* token ) - { - FT_Byte* cur; - FT_Byte* limit; - FT_Byte starter, ender; - FT_Int embed; - - - token->type = t1_token_none; - token->start = 0; - token->limit = 0; - - /* first of all, skip space */ - Z1_Skip_Spaces( parser ); - - cur = parser->cursor; - limit = parser->limit; - - if ( cur < limit ) - { - switch ( *cur ) - { - /************* check for strings ***********************/ - case '(': - token->type = t1_token_string; - ender = ')'; - goto Lookup_Ender; - - /************* check for programs/array ****************/ - case '{': - token->type = t1_token_array; - ender = '}'; - goto Lookup_Ender; - - /************* check for table/array ******************/ - case '[': - token->type = t1_token_array; - ender = ']'; - - Lookup_Ender: - embed = 1; - starter = *cur++; - token->start = cur; - while ( cur < limit ) - { - if ( *cur == starter ) - embed++; - else if ( *cur == ender ) - { - embed--; - if ( embed <= 0 ) - { - token->limit = cur++; - break; - } - } - cur++; - } - break; - - /* **************** otherwise, it's any token **********/ - default: - token->start = cur++; - token->type = t1_token_any; - while ( cur < limit && !IS_Z1_SPACE( *cur ) ) - cur++; - - token->limit = cur; - } - - if ( !token->limit ) - { - token->start = 0; - token->type = t1_token_none; - } - - parser->cursor = cur; - } - } - - - LOCAL_FUNC - void Z1_ToTokenArray( Z1_Parser* parser, - Z1_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ) - { - Z1_Token_Rec master; - - - *pnum_tokens = -1; - - Z1_ToToken( parser, &master ); - if ( master.type == t1_token_array ) - { - FT_Byte* old_cursor = parser->cursor; - FT_Byte* old_limit = parser->limit; - Z1_Token_Rec* cur = tokens; - Z1_Token_Rec* limit = cur + max_tokens; - - - parser->cursor = master.start; - parser->limit = master.limit; - - while ( parser->cursor < parser->limit ) - { - Z1_Token_Rec token; - - - Z1_ToToken( parser, &token ); - if ( !token.type ) - break; - - if ( cur < limit ) - *cur = token; - - cur++; - } - - *pnum_tokens = cur - tokens; - - parser->cursor = old_cursor; - parser->limit = old_limit; - } - } - - - static - FT_Long t1_toint( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Long result = 0; - FT_Byte* cur = *cursor; - FT_Byte c, d; - - - for ( ; cur < limit; cur++ ) - { - c = *cur; - d = (FT_Byte)( c - '0' ); - if ( d < 10 ) - break; - - if ( c == '-' ) - { - cur++; - break; - } - } - - if ( cur < limit ) - { - do - { - d = (FT_Byte)( cur[0] - '0' ); - if ( d >= 10 ) - break; - - result = result * 10 + d; - cur++; - - } while ( cur < limit ); - - if ( c == '-' ) - result = -result; - } - - *cursor = cur; - return result; - } - - - static - FT_Long t1_tofixed( FT_Byte** cursor, - FT_Byte* limit, - FT_Long power_ten ) - { - FT_Byte* cur = *cursor; - FT_Long num, divider, result; - FT_Int sign = 0; - FT_Byte d; - - - if ( cur >= limit ) - return 0; - - /* first of all, read the integer part */ - result = t1_toint( &cur, limit ) << 16; - num = 0; - divider = 1; - - if ( result < 0 ) - { - sign = 1; - result = -result; - } - - if ( cur >= limit ) - goto Exit; - - /* read decimal part, if any */ - if ( *cur == '.' && cur + 1 < limit ) - { - cur++; - - for (;;) - { - d = (FT_Byte)( *cur - '0' ); - if ( d >= 10 ) - break; - - if ( divider < 10000000L ) - { - num = num * 10 + d; - divider *= 10; - } - - cur++; - if ( cur >= limit ) - break; - } - } - - /* read exponent, if any */ - if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) - { - cur++; - power_ten += t1_toint( &cur, limit ); - } - - Exit: - /* raise to power of ten if needed */ - while ( power_ten > 0 ) - { - result = result * 10; - num = num * 10; - power_ten--; - } - - while ( power_ten < 0 ) - { - result = result / 10; - divider = divider * 10; - power_ten++; - } - - if ( num ) - result += FT_DivFix( num, divider ); - - if ( sign ) - result = -result; - - *cursor = cur; - return result; - } - - - static - FT_Int t1_tocoordarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_coords, - FT_Short* coords ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) - goto Exit; - - /* check for the beginning of an array. If not, only one number will */ - /* be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the coordinates */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_coords || c == ender ) - break; - - coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - - static - FT_Int t1_tofixedarray( FT_Byte** cursor, - FT_Byte* limit, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - FT_Byte* cur = *cursor; - FT_Int count = 0; - FT_Byte c, ender; - - - if ( cur >= limit ) goto Exit; - - /* check for the beginning of an array. If not, only one number will */ - /* be read */ - c = *cur; - ender = 0; - - if ( c == '[' ) - ender = ']'; - - if ( c == '{' ) - ender = '}'; - - if ( ender ) - cur++; - - /* now, read the values */ - for ( ; cur < limit; ) - { - /* skip whitespace in front of data */ - for (;;) - { - c = *cur; - if ( c != ' ' && c != '\t' ) - break; - - cur++; - if ( cur >= limit ) - goto Exit; - } - - if ( count >= max_values || c == ender ) - break; - - values[count] = t1_tofixed( &cur, limit, power_ten ); - count++; - - if ( !ender ) - break; - } - - Exit: - *cursor = cur; - return count; - } - - -#if 0 - - static - FT_String* t1_tostring( FT_Byte** cursor, - FT_Byte* limit, - FT_Memory memory ) - { - FT_Byte* cur = *cursor; - FT_Int len = 0; - FT_Int count; - FT_String* result; - FT_Error error; - - - /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ - /* that simply doesn't begin with an opening parenthesis, even */ - /* though they have a closing one! E.g. "amuncial.pfb" */ - /* */ - /* We must deal with these ill-fated cases there. Note that */ - /* these fonts didn't work with the old Type 1 driver as the */ - /* notice/copyright was not recognized as a valid string token */ - /* and made the old token parser commit errors. */ - - while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) - cur++; - if ( cur + 1 >= limit ) - return 0; - - if ( *cur == '(' ) - cur++; /* skip the opening parenthesis, if there is one */ - - *cursor = cur; - count = 0; - - /* then, count its length */ - for ( ; cur < limit; cur++ ) - { - if ( *cur == '(' ) - count++; - - else if ( *cur == ')' ) - { - count--; - if ( count < 0 ) - break; - } - } - - len = cur - *cursor; - if ( cur >= limit || ALLOC( result, len + 1 ) ) - return 0; - - /* now copy the string */ - MEM_Copy( result, *cursor, len ); - result[len] = '\0'; - *cursor = cur; - return result; - } - -#endif /* 0 */ - - - static - int t1_tobool( FT_Byte** cursor, - FT_Byte* limit ) - { - FT_Byte* cur = *cursor; - FT_Bool result = 0; - - - /* return 1 if we find `true', 0 otherwise */ - if ( cur + 3 < limit && - cur[0] == 't' && - cur[1] == 'r' && - cur[2] == 'u' && - cur[3] == 'e' ) - { - result = 1; - cur += 5; - } - else if ( cur + 4 < limit && - cur[0] == 'f' && - cur[1] == 'a' && - cur[2] == 'l' && - cur[3] == 's' && - cur[4] == 'e' ) - { - result = 0; - cur += 6; - } - - *cursor = cur; - return result; - } - - - /* Load a simple field (i.e. non-table) into the current list of objects */ - LOCAL_FUNC - FT_Error Z1_Load_Field( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - Z1_Token_Rec token; - FT_Byte* cur; - FT_Byte* limit; - FT_UInt count; - FT_UInt index; - FT_Error error; - - - Z1_ToToken( parser, &token ); - if ( !token.type ) - goto Fail; - - count = 1; - index = 0; - cur = token.start; - limit = token.limit; - - if ( token.type == t1_token_array ) - { - /* if this is an array, and we have no blend, an error occurs */ - if ( max_objects == 0 ) - goto Fail; - - count = max_objects; - index = 1; - } - - for ( ; count > 0; count--, index++ ) - { - FT_Byte* q = (FT_Byte*)objects[index] + field->offset; - FT_Long val; - FT_String* string; - - switch ( field->type ) - { - case t1_field_bool: - val = t1_tobool( &cur, limit ); - goto Store_Integer; - - case t1_field_fixed: - val = t1_tofixed( &cur, limit, 3 ); - goto Store_Integer; - - case t1_field_integer: - val = t1_toint( &cur, limit ); - - Store_Integer: - switch ( field->size ) - { - case 1: - *(FT_Byte*)q = (FT_Byte)val; - break; - - case 2: - *(FT_UShort*)q = (FT_UShort)val; - break; - - case 4: - *(FT_UInt32*)q = (FT_UInt32)val; - break; - - default: /* for 64-bit systems */ - *(FT_Long*)q = val; - } - break; - - case t1_field_string: - { - FT_Memory memory = parser->memory; - FT_UInt len = limit-cur; - - if ( ALLOC( string, len + 1 ) ) - goto Exit; - - MEM_Copy( string, cur, len ); - string[len] = 0; - - *(FT_String**)q = string; - } - break; - - default: - /* an error occured */ - goto Fail; - } - } - - if ( pflags ) - *pflags |= 1L << field->flag_bit; - - error = FT_Err_Ok; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - -#define T1_MAX_TABLE_ELEMENTS 32 - - - LOCAL_FUNC - FT_Error Z1_Load_Field_Table( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ) - { - Z1_Token_Rec elements[T1_MAX_TABLE_ELEMENTS]; - Z1_Token_Rec* token; - FT_Int num_elements; - FT_Error error = 0; - FT_Byte* old_cursor; - FT_Byte* old_limit; - Z1_Field_Rec fieldrec = *(Z1_Field_Rec*)field; - - - Z1_ToTokenArray( parser, elements, 32, &num_elements ); - if ( num_elements < 0 ) - goto Fail; - - if ( num_elements > T1_MAX_TABLE_ELEMENTS ) - num_elements = T1_MAX_TABLE_ELEMENTS; - - old_cursor = parser->cursor; - old_limit = parser->limit; - - /* we store the elements count */ - *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = num_elements; - - /* we now load each element, adjusting the field.offset on each one */ - token = elements; - for ( ; num_elements > 0; num_elements--, token++ ) - { - parser->cursor = token->start; - parser->limit = token->limit; - Z1_Load_Field( parser, &fieldrec, objects, max_objects, 0 ); - fieldrec.offset += fieldrec.size; - } - - if ( pflags ) - *pflags |= 1L << field->flag_bit; - - parser->cursor = old_cursor; - parser->limit = old_limit; - - Exit: - return error; - - Fail: - error = T1_Err_Invalid_File_Format; - goto Exit; - } - - - LOCAL_FUNC - FT_Long Z1_ToInt ( Z1_Parser* parser ) - { - return t1_toint( &parser->cursor, parser->limit ); - } - - - LOCAL_FUNC - FT_Long Z1_ToFixed( Z1_Parser* parser, - FT_Int power_ten ) - { - return t1_tofixed( &parser->cursor, parser->limit, power_ten ); - } - - - LOCAL_FUNC - FT_Int Z1_ToCoordArray( Z1_Parser* parser, - FT_Int max_coords, - FT_Short* coords ) - { - return t1_tocoordarray( &parser->cursor, parser->limit, - max_coords, coords ); - } - - - LOCAL_FUNC - FT_Int Z1_ToFixedArray( Z1_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ) - { - return t1_tofixedarray( &parser->cursor, parser->limit, - max_values, values, power_ten ); - } - - -#if 0 - - LOCAL_FUNC - FT_String* Z1_ToString( Z1_Parser* parser ) - { - return t1_tostring( &parser->cursor, parser->limit, parser->memory ); - } - - - LOCAL_FUNC - FT_Bool Z1_ToBool( Z1_Parser* parser ) - { - return t1_tobool( &parser->cursor, parser->limit ); - } - -#endif /* 0 */ - - - static - FT_Error read_pfb_tag( FT_Stream stream, - FT_UShort* tag, - FT_Long* size ) - { - FT_Error error; - - - if ( READ_UShort( *tag ) ) - goto Exit; - - if ( *tag == 0x8001 || *tag == 0x8002 ) - { - FT_Long asize; - - - if ( READ_ULong( asize ) ) - goto Exit; - - /* swap between big and little endianness */ - *size = ( ( asize & 0xFF000000L ) >> 24 ) | - ( ( asize & 0x00FF0000L ) >> 8 ) | - ( ( asize & 0x0000FF00L ) << 8 ) | - ( ( asize & 0x000000FFL ) << 24 ); - } - - Exit: - return error; - } - - - LOCAL_FUNC - FT_Error Z1_New_Parser( Z1_Parser* parser, - FT_Stream stream, - FT_Memory memory ) - { - FT_Error error; - FT_UShort tag; - FT_Long size; - - - parser->stream = stream; - parser->memory = memory; - parser->base_len = 0; - parser->base_dict = 0; - parser->private_len = 0; - parser->private_dict = 0; - parser->in_pfb = 0; - parser->in_memory = 0; - parser->single_block = 0; - - parser->cursor = 0; - parser->limit = 0; - - /******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 1 parser, we try to locate and load */ - /* the base dictionary if this is possible (i.e. for PFB */ - /* files). Otherwise, we load the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only setup pointers */ - /* in the case of a memory-based stream. Otherwise, we */ - /* allocate and load the base dictionary in it. */ - /* */ - /* parser->in_pfb is set if we are in a binary (".pfb") font. */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ - - /* try to compute the size of the base dictionary; */ - /* look for a Postscript binary file tag, i.e 0x8001 */ - if ( FILE_Seek( 0L ) ) - goto Exit; - - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Exit; - - if ( tag != 0x8001 ) - { - /* assume that this is a PFA file for now; an error will */ - /* be produced later when more things are checked */ - (void)FILE_Seek( 0L ); - size = stream->size; - } - else - parser->in_pfb = 1; - - /* now, try to load `size' bytes of the `base' dictionary we */ - /* found previously */ - - /* if it is a memory-based resource, set up pointers */ - if ( !stream->read ) - { - parser->base_dict = (FT_Byte*)stream->base + stream->pos; - parser->base_len = size; - parser->in_memory = 1; - - /* check that the `size' field is valid */ - if ( FILE_Skip( size ) ) - goto Exit; - } - else - { - /* read segment in memory */ - if ( ALLOC( parser->base_dict, size ) || - FILE_Read( parser->base_dict, size ) ) - goto Exit; - parser->base_len = size; - } - - /* Now check font format; we must see `%!PS-AdobeFont-1' */ - /* or `%!FontType' */ - { - if ( size <= 16 || - ( strncmp( (const char*)parser->base_dict, - "%!PS-AdobeFont-1", 16 ) && - strncmp( (const char*)parser->base_dict, - "%!FontType", 10 ) ) ) - { - FT_TRACE2(( "[not a Type1 font]\n" )); - error = FT_Err_Unknown_File_Format; - } - else - { - parser->cursor = parser->base_dict; - parser->limit = parser->cursor + parser->base_len; - } - } - - Exit: - if ( error && !parser->in_memory ) - FREE( parser->base_dict ); - - return error; - } - - - LOCAL_FUNC - void Z1_Done_Parser( Z1_Parser* parser ) - { - FT_Memory memory = parser->memory; - - - /* always free the private dictionary */ - FREE( parser->private_dict ); - - /* free the base dictionary only when we have a disk stream */ - if ( !parser->in_memory ) - FREE( parser->base_dict ); - } - - - /* return the value of an hexadecimal digit */ - static - int hexa_value( char c ) - { - unsigned int d; - - - d = (unsigned int)( c - '0' ); - if ( d <= 9 ) - return (int)d; - - d = (unsigned int)( c - 'a' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - d = (unsigned int)( c - 'A' ); - if ( d <= 5 ) - return (int)( d + 10 ); - - return -1; - } - - - LOCAL_FUNC - void Z1_Decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ) - { - while ( length > 0 ) - { - FT_Byte plain; - - - plain = ( *buffer ^ ( seed >> 8 ) ); - seed = ( *buffer + seed ) * 52845 + 22719; - *buffer++ = plain; - length--; - } - } - - - LOCAL_FUNC - FT_Error Z1_Get_Private_Dict( Z1_Parser* parser ) - { - FT_Stream stream = parser->stream; - FT_Memory memory = parser->memory; - FT_Error error = 0; - FT_Long size; - - - if ( parser->in_pfb ) - { - /* in the case of the PFB format, the private dictionary can be */ - /* made of several segments. We thus first read the number of */ - /* segments to compute the total size of the private dictionary */ - /* then re-read them into memory. */ - FT_Long start_pos = FILE_Pos(); - FT_UShort tag; - FT_Long size; - - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error ) - goto Fail; - - if ( tag != 0x8002 ) - break; - - parser->private_len += size; - - if ( FILE_Skip( size ) ) - goto Fail; - } - - /* Check that we have a private dictionary there */ - /* and allocate private dictionary buffer */ - if ( parser->private_len == 0 ) - { - FT_ERROR(( "Z1_Get_Private_Dict:" )); - FT_ERROR(( " invalid private dictionary section\n" )); - error = T1_Err_Invalid_File_Format; - goto Fail; - } - - if ( FILE_Seek( start_pos ) || - ALLOC( parser->private_dict, parser->private_len ) ) - goto Fail; - - parser->private_len = 0; - for (;;) - { - error = read_pfb_tag( stream, &tag, &size ); - if ( error || tag != 0x8002 ) - { - error = FT_Err_Ok; - break; - } - - if ( FILE_Read( parser->private_dict + parser->private_len, size ) ) - goto Fail; - - parser->private_len += size; - } - } - else - { - /* we have already `loaded' the whole PFA font file into memory; */ - /* if this is a memory resource, allocate a new block to hold */ - /* the private dict. Otherwise, simply overwrite into the base */ - /* dictionary block in the heap. */ - - /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; - - - for (;;) - { - c = cur[0]; - if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* newline + 4 chars */ - { - if ( cur[1] == 'e' && cur[2] == 'x' && - cur[3] == 'e' && cur[4] == 'c' ) - { - cur += 6; /* we skip the newling after the `eexec' */ - - /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */ - /* skip the extra \n if we find it */ - if ( cur[0] == '\n' ) - cur++; - - break; - } - } - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "Z1_Get_Private_Dict:" )); - FT_ERROR(( " could not find `eexec' keyword\n" )); - error = T1_Err_Invalid_File_Format; - goto Exit; - } - } - - /* now determine where to write the _encrypted_ binary private */ - /* dictionary. We overwrite the base dictionary for disk-based */ - /* resources and allocate a new block otherwise */ - - size = parser->base_len - ( cur - parser->base_dict); - - if ( parser->in_memory ) - { - /* note that we allocate one more byte to put a terminating `0' */ - if ( ALLOC( parser->private_dict, size + 1 ) ) - goto Fail; - parser->private_len = size; - } - else - { - parser->single_block = 1; - parser->private_dict = parser->base_dict; - parser->private_len = size; - parser->base_dict = 0; - parser->base_len = 0; - } - - /* now determine whether the private dictionary is encoded in binary */ - /* or hexadecimal ASCII format -- decode it accordingly */ - - /* we need to access the next 4 bytes (after the final \r following */ - /* the `eexec' keyword); if they all are hexadecimal digits, then */ - /* we have a case of ASCII storage */ - - if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) | - hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 ) - - /* binary encoding -- `simply' copy the private dict */ - MEM_Copy( parser->private_dict, cur, size ); - - else - { - /* ASCII hexadecimal encoding */ - - FT_Byte* write; - FT_Int count; - - - write = parser->private_dict; - count = 0; - - for ( ;cur < limit; cur++ ) - { - int hex1; - - - /* check for newline */ - if ( cur[0] == '\r' || cur[0] == '\n' ) - continue; - - /* exit if we have a non-hexadecimal digit that isn't a newline */ - hex1 = hexa_value( cur[0] ); - if ( hex1 < 0 || cur + 1 >= limit ) - break; - - /* otherwise, store byte */ - *write++ = ( hex1 << 4 ) | hexa_value( cur[1] ); - count++; - cur++; - } - - /* put a safeguard */ - parser->private_len = write - parser->private_dict; - *write++ = 0; - } - } - - /* we now decrypt the encoded binary private dictionary */ - Z1_Decrypt( parser->private_dict, parser->private_len, 55665 ); - parser->cursor = parser->private_dict; - parser->limit = parser->cursor + parser->private_len; - - Fail: - Exit: - return error; - } - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1parse.h b/subsys/win32k/freetype/src/type1z/z1parse.h deleted file mode 100644 index d0b6a65..0000000 --- a/subsys/win32k/freetype/src/type1z/z1parse.h +++ /dev/null @@ -1,363 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1parse.h */ -/* */ -/* Experimental Type 1 parser (specification). */ -/* */ -/* Copyright 1996-2000 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 Z1PARSE_H -#define Z1PARSE_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - - /* simple enumeration type used to identify token types */ - typedef enum Z1_Token_Type_ - { - t1_token_none = 0, - t1_token_any, - t1_token_string, - t1_token_array, - - /* do not remove */ - t1_token_max - - } Z1_Token_Type; - - - /* a simple structure used to identify tokens */ - typedef struct Z1_Token_Rec_ - { - FT_Byte* start; /* first character of token in input stream */ - FT_Byte* limit; /* first character after the token */ - Z1_Token_Type type; /* type of token.. */ - - } Z1_Token_Rec; - - - /* enumeration type used to identify object fields */ - typedef enum Z1_Field_Type_ - { - t1_field_none = 0, - t1_field_bool, - t1_field_integer, - t1_field_fixed, - t1_field_string, - t1_field_integer_array, - t1_field_fixed_array, - - /* do not remove */ - t1_field_max - - } Z1_Field_Type; - - - /* structure type used to model object fields */ - typedef struct Z1_Field_Rec_ - { - Z1_Field_Type type; /* type of field */ - FT_UInt offset; /* offset of field in object */ - FT_UInt size; /* size of field in bytes */ - FT_UInt array_max; /* maximum number of elements for array */ - FT_UInt count_offset; /* offset of element count for arrays */ - FT_Int flag_bit; /* bit number for field flag */ - - } Z1_Field_Rec; - - -#define Z1_FIELD_REF( s, f ) ( ((s*)0)->f ) - -#define Z1_FIELD_BOOL( _ftype, _fname ) \ - { \ - t1_field_bool, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_NUM( _ftype, _fname ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_FIXED( _ftype, _fname, _power ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_STRING( _ftype, _fname ) \ - { \ - t1_field_string, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname ) ), \ - 0, 0, 0 \ - } - -#define Z1_FIELD_NUM_ARRAY( _ftype, _fname, _fcount, _fmax ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fcount ), \ - 0 \ - } - -#define Z1_FIELD_FIXED_ARRAY( _ftype, _fname, _fcount, _fmax ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fcount ), \ - 0 \ - } - -#define Z1_FIELD_NUM_ARRAY2( _ftype, _fname, _fmax ) \ - { \ - t1_field_integer, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - 0, 0 \ - } - -#define Z1_FIELD_FIXED_ARRAY2( _ftype, _fname, _fmax ) \ - { \ - t1_field_fixed, \ - (FT_UInt)(char*)&Z1_FIELD_REF( _ftype, _fname ), \ - sizeof ( Z1_FIELD_REF( _ftype, _fname )[0] ), \ - _fmax, \ - 0, 0 \ - } - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Table */ - /* */ - /* */ - /* A Z1_Table is a simple object used to store an array of objects in */ - /* a single memory block. */ - /* */ - /* */ - /* block :: The address in memory of the growheap's block. This */ - /* can change between two object adds, due to the use of */ - /* reallocation. */ - /* */ - /* cursor :: The current top of the grow heap within its block. */ - /* */ - /* capacity :: The current size of the heap block. Increments in */ - /* 1kByte blocks. */ - /* */ - /* init :: A boolean. Set when the table has been initialized */ - /* (the table user should set this field). */ - /* */ - /* max_elems :: The maximum number of elements in the table. */ - /* */ - /* num_elems :: The current number of elements in the table. */ - /* */ - /* elements :: A table of element addresses within the block. */ - /* */ - /* lengths :: A table of element sizes within the block. */ - /* */ - /* memory :: The memory object used for memory operations */ - /* (allocation/reallocation). */ - /* */ - typedef struct Z1_Table_ - { - FT_Byte* block; /* current memory block */ - FT_Int cursor; /* current cursor in memory block */ - FT_Int capacity; /* current size of memory block */ - FT_Long init; - - FT_Int max_elems; - FT_Int num_elems; - FT_Byte** elements; /* addresses of table elements */ - FT_Int* lengths; /* lengths of table elements */ - - FT_Memory memory; - - } Z1_Table; - - - /*************************************************************************/ - /* */ - /* */ - /* Z1_Parser */ - /* */ - /* */ - /* A Z1_Parser is an object used to parse a Type 1 fonts very */ - /* quickly. */ - /* */ - /* */ - /* stream :: The current input stream. */ - /* */ - /* memory :: The current memory object. */ - /* */ - /* base_dict :: A pointer to the top-level dictionary. */ - /* */ - /* base_len :: The length in bytes of the top dictionary. */ - /* */ - /* private_dict :: A pointer to the private dictionary. */ - /* */ - /* private_len :: The length in bytes of the private dictionary. */ - /* */ - /* in_pfb :: A boolean. Indicates that we are handling a PFB */ - /* file. */ - /* */ - /* in_memory :: A boolean. Indicates a memory-based stream. */ - /* */ - /* single_block :: A boolean. Indicates that the private dictionary */ - /* is stored in lieu of the base dictionary. */ - /* */ - /* cursor :: The current parser cursor. */ - /* */ - /* limit :: The current parser limit (first byte after the */ - /* current dictionary). */ - /* */ - /* error :: The current parsing error. */ - /* */ - typedef struct Z1_Parser_ - { - FT_Stream stream; - FT_Memory memory; - - FT_Byte* base_dict; - FT_Int base_len; - - FT_Byte* private_dict; - FT_Int private_len; - - FT_Byte in_pfb; - FT_Byte in_memory; - FT_Byte single_block; - - FT_Byte* cursor; - FT_Byte* limit; - FT_Error error; - - } Z1_Parser; - - - LOCAL_DEF - FT_Error Z1_New_Table( Z1_Table* table, - FT_Int count, - FT_Memory memory ); - - - LOCAL_DEF - FT_Error Z1_Add_Table( Z1_Table* table, - FT_Int index, - void* object, - FT_Int length ); - -#if 0 - LOCAL_DEF - void Z1_Done_Table( Z1_Table* table ); -#endif - - LOCAL_DEF - void Z1_Release_Table( Z1_Table* table ); - - LOCAL_DEF - FT_Long Z1_ToInt( Z1_Parser* parser ); - - LOCAL_DEF - FT_Long Z1_ToFixed( Z1_Parser* parser, - FT_Int power_ten ); - - LOCAL_DEF - FT_Int Z1_ToCoordArray( Z1_Parser* parser, - FT_Int max_coords, - FT_Short* coords ); - - LOCAL_DEF - FT_Int Z1_ToFixedArray( Z1_Parser* parser, - FT_Int max_values, - FT_Fixed* values, - FT_Int power_ten ); - -#if 0 - LOCAL_DEF - FT_String* Z1_ToString( Z1_Parser* parser ); - - LOCAL_DEF - FT_Bool Z1_ToBool( Z1_Parser* parser ); -#endif - - - LOCAL_DEF - void Z1_Skip_Spaces( Z1_Parser* parser ); - - LOCAL_DEF - void Z1_ToToken( Z1_Parser* parser, - Z1_Token_Rec* token ); - - LOCAL_FUNC - void Z1_ToTokenArray( Z1_Parser* parser, - Z1_Token_Rec* tokens, - FT_UInt max_tokens, - FT_Int* pnum_tokens ); - - LOCAL_DEF - FT_Error Z1_Load_Field( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - LOCAL_DEF - FT_Error Z1_Load_Field_Table( Z1_Parser* parser, - const Z1_Field_Rec* field, - void** objects, - FT_UInt max_objects, - FT_ULong* pflags ); - - - LOCAL_DEF - FT_Error Z1_New_Parser( Z1_Parser* parser, - FT_Stream stream, - FT_Memory memory ); - - LOCAL_DEF - FT_Error Z1_Get_Private_Dict( Z1_Parser* parser ); - - LOCAL_DEF - void Z1_Decrypt( FT_Byte* buffer, - FT_Int length, - FT_UShort seed ); - - LOCAL_DEF - void Z1_Done_Parser( Z1_Parser* parser ); - -#ifdef __cplusplus - } -#endif - -#endif /* Z1PARSE_H */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/type1z/z1tokens.h b/subsys/win32k/freetype/src/type1z/z1tokens.h deleted file mode 100644 index 73c0228..0000000 --- a/subsys/win32k/freetype/src/type1z/z1tokens.h +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************/ -/* */ -/* z1tokens.h */ -/* */ -/* Experimental Type 1 tokenizer (specification). */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#undef T1TYPE -#define T1TYPE T1_FontInfo - - Z1_FONTINFO_STRING( "version", version ) - Z1_FONTINFO_STRING( "Notice", notice ) - Z1_FONTINFO_STRING( "FullName", full_name ) - Z1_FONTINFO_STRING( "FamilyName", family_name ) - Z1_FONTINFO_STRING( "Weight", weight ) - - Z1_FONTINFO_NUM ( "ItalicAngle", italic_angle ) - Z1_FONTINFO_BOOL ( "isFixedPitch", is_fixed_pitch ) - Z1_FONTINFO_NUM ( "UnderlinePosition", underline_position ) - Z1_FONTINFO_NUM ( "UnderlineThickness", underline_thickness ) - - -#undef T1TYPE -#define T1TYPE T1_Private - - Z1_PRIVATE_NUM ( "UniqueID", unique_id ) - Z1_PRIVATE_NUM ( "lenIV", lenIV ) - Z1_PRIVATE_NUM ( "LanguageGroup", language_group ) - Z1_PRIVATE_NUM ( "password", password ) - - Z1_PRIVATE_FIXED ( "BlueScale", blue_scale ) - Z1_PRIVATE_NUM ( "BlueShift", blue_shift ) - Z1_PRIVATE_NUM ( "BlueFuzz", blue_fuzz ) - - Z1_PRIVATE_NUM_TABLE ( "BlueValues", blue_values, 14, num_blue_values ) - Z1_PRIVATE_NUM_TABLE ( "OtherBlues", other_blues, 10, num_other_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyBlues", family_blues, 14, num_family_blues ) - Z1_PRIVATE_NUM_TABLE ( "FamilyOtherBlues", family_other_blues, 10, \ - num_family_other_blues ) - - Z1_PRIVATE_NUM_TABLE2( "StdHW", standard_width, 1 ) - Z1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 ) - Z1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 ) - - Z1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths ) - Z1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights ) - - -#undef T1TYPE -#define T1TYPE T1_Font - - Z1_TOPDICT_NUM( "PaintType", paint_type ) - Z1_TOPDICT_NUM( "FontType", font_type ) - Z1_TOPDICT_NUM( "StrokeWidth", stroke_width ) - - -#if 0 - - /* define the font info dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1.font_info) - - PARSE_STRING( "version", version ) - PARSE_STRING( "Notice", notice ) - PARSE_STRING( "FullName", full_name ) - PARSE_STRING( "FamilyName", family_name ) - PARSE_STRING( "Weight", weight ) - - PARSE_INT ( "ItalicAngle", italic_angle ) - PARSE_BOOL ( "isFixedPitch", is_fixed_pitch ) - PARSE_NUM ( "UnderlinePosition", underline_position, FT_Short ) - PARSE_NUM ( "UnderlineThickness", underline_thickness, FT_UShort ) - - - /* define the private dict parsing callbacks */ -#undef FACE -#define FACE (face->type1.private_dict) - - PARSE_INT ("UniqueID", unique_id ) - PARSE_INT ("lenIV", lenIV ) - - PARSE_COORDS ( "BlueValues", num_blues, 14, blue_values) - PARSE_COORDS ( "OtherBlues", num_other_blues, 10, other_blues) - - PARSE_COORDS ( "FamilyBlues", num_family_blues, 14, family_blues ) - PARSE_COORDS ( "FamilyOtherBlues", num_family_other_blues, 10, - family_other_blues ) - - PARSE_FIXED ( "BlueScale", blue_scale ) - PARSE_INT ( "BlueShift", blue_shift ) - - PARSE_INT ( "BlueFuzz", blue_fuzz ) - - PARSE_COORDS2( "StdHW", 1, standard_width ) - PARSE_COORDS2( "StdVW", 1, standard_height ) - - PARSE_COORDS ( "StemSnapH", num_snap_widths, 12, stem_snap_widths ) - PARSE_COORDS ( "StemSnapV", num_snap_heights, 12, stem_snap_heights ) - - PARSE_INT ( "LanguageGroup", language_group ) - PARSE_INT ( "password", password ) - PARSE_COORDS2( "MinFeature", 2, min_feature ) - - - /* define the top-level dictionary parsing callbacks */ -#undef FACE -#define FACE (face->type1) - -/*PARSE_STRING ( "FontName", font_name ) -- handled by special routine */ - PARSE_NUM ( "PaintType", paint_type, FT_Byte ) - PARSE_NUM ( "FontType", font_type, FT_Byte ) - PARSE_FIXEDS2( "FontMatrix", 4, font_matrix ) -/*PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special routine */ - PARSE_INT ( "StrokeWidth", stroke_width ) - -#undef FACE - -#endif /* 0 */ - - -/* END */ diff --git a/subsys/win32k/freetype/src/winfonts/.cvsignore b/subsys/win32k/freetype/src/winfonts/.cvsignore deleted file mode 100644 index bd0e3df..0000000 --- a/subsys/win32k/freetype/src/winfonts/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.d -*.o -*.sym diff --git a/subsys/win32k/freetype/src/winfonts/module.mk b/subsys/win32k/freetype/src/winfonts/module.mk deleted file mode 100644 index 5c12eb6..0000000 --- a/subsys/win32k/freetype/src/winfonts/module.mk +++ /dev/null @@ -1,6 +0,0 @@ -make_module_list: add_windows_driver - -add_windows_driver: - $(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER) - $(ECHO_DRIVER)winfnt $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE) - diff --git a/subsys/win32k/freetype/src/winfonts/rules.mk b/subsys/win32k/freetype/src/winfonts/rules.mk deleted file mode 100644 index 8396894..0000000 --- a/subsys/win32k/freetype/src/winfonts/rules.mk +++ /dev/null @@ -1,64 +0,0 @@ -# -# FreeType 2 Windows FNT/FON driver configuration rules -# - - -# Copyright 1996-2000 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. - - -# Windows driver directory -# -FNT_DIR := $(SRC_)winfonts -FNT_DIR_ := $(FNT_DIR)$(SEP) - - -FNT_COMPILE := $(FT_COMPILE) - - -# Windows driver sources (i.e., C files) -# -FNT_DRV_SRC := $(FNT_DIR_)winfnt.c - -# Windows driver headers -# -FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h) - - -# Windows driver object(s) -# -# FNT_DRV_OBJ_M is used during `multi' builds -# FNT_DRV_OBJ_S is used during `single' builds -# -FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR_)%.c=$(OBJ_)%.$O) -FNT_DRV_OBJ_S := $(OBJ_)winfnt.$O - -# Windows driver source file for single build -# -FNT_DRV_SRC_S := $(FNT_DIR_)winfnt.c - - -# Windows driver - single object -# -$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $(FNT_DRV_SRC_S) - - -# Windows driver - multiple objects -# -$(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H) - $(FNT_COMPILE) $T$@ $< - - -# update main driver object lists -# -DRV_OBJS_S += $(FNT_DRV_OBJ_S) -DRV_OBJS_M += $(FNT_DRV_OBJ_M) - -# EOF diff --git a/subsys/win32k/freetype/src/winfonts/winfnt.c b/subsys/win32k/freetype/src/winfonts/winfnt.c deleted file mode 100644 index bacd7ad..0000000 --- a/subsys/win32k/freetype/src/winfonts/winfnt.c +++ /dev/null @@ -1,623 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.c */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2000 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. */ -/* */ -/***************************************************************************/ - - -#ifdef FT_FLAT_COMPILE - -#include "winfnt.h" - -#else - -#include - -#endif - - -#include -#include -#include -#include - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_winfnt - - - static - const FT_Frame_Field winmz_header_fields[] = - { - FT_FRAME_START( 64 ), - FT_FRAME_USHORT_LE ( WinMZ_Header, magic ), - FT_FRAME_SKIP_BYTES( 29 * 2 ), - FT_FRAME_ULONG_LE ( WinMZ_Header, lfanew ), - FT_FRAME_END - }; - - static - const FT_Frame_Field winne_header_fields[] = - { - FT_FRAME_START( 40 ), - FT_FRAME_USHORT_LE ( WinNE_Header, magic ), - FT_FRAME_SKIP_BYTES( 34 ), - FT_FRAME_USHORT_LE ( WinNE_Header, resource_tab_offset ), - FT_FRAME_USHORT_LE ( WinNE_Header, rname_tab_offset ), - FT_FRAME_END - }; - - static - const FT_Frame_Field winfnt_header_fields[] = - { - FT_FRAME_START( 134 ), - FT_FRAME_USHORT_LE( WinFNT_Header, version ), - FT_FRAME_ULONG_LE ( WinFNT_Header, file_size ), - FT_FRAME_BYTES ( WinFNT_Header, copyright, 60 ), - FT_FRAME_USHORT_LE( WinFNT_Header, file_type ), - FT_FRAME_USHORT_LE( WinFNT_Header, nominal_point_size ), - FT_FRAME_USHORT_LE( WinFNT_Header, vertical_resolution ), - FT_FRAME_USHORT_LE( WinFNT_Header, horizontal_resolution ), - FT_FRAME_USHORT_LE( WinFNT_Header, ascent ), - FT_FRAME_USHORT_LE( WinFNT_Header, internal_leading ), - FT_FRAME_USHORT_LE( WinFNT_Header, external_leading ), - FT_FRAME_BYTE ( WinFNT_Header, italic ), - FT_FRAME_BYTE ( WinFNT_Header, underline ), - FT_FRAME_BYTE ( WinFNT_Header, strike_out ), - FT_FRAME_USHORT_LE( WinFNT_Header, weight ), - FT_FRAME_BYTE ( WinFNT_Header, charset ), - FT_FRAME_USHORT_LE( WinFNT_Header, pixel_width ), - FT_FRAME_USHORT_LE( WinFNT_Header, pixel_height ), - FT_FRAME_BYTE ( WinFNT_Header, pitch_and_family ), - FT_FRAME_USHORT_LE( WinFNT_Header, avg_width ), - FT_FRAME_USHORT_LE( WinFNT_Header, max_width ), - FT_FRAME_BYTE ( WinFNT_Header, first_char ), - FT_FRAME_BYTE ( WinFNT_Header, last_char ), - FT_FRAME_BYTE ( WinFNT_Header, default_char ), - FT_FRAME_BYTE ( WinFNT_Header, break_char ), - FT_FRAME_USHORT_LE( WinFNT_Header, bytes_per_row ), - FT_FRAME_ULONG_LE ( WinFNT_Header, device_offset ), - FT_FRAME_ULONG_LE ( WinFNT_Header, face_name_offset ), - FT_FRAME_ULONG_LE ( WinFNT_Header, bits_pointer ), - FT_FRAME_ULONG_LE ( WinFNT_Header, bits_offset ), - FT_FRAME_BYTE ( WinFNT_Header, reserved ), - FT_FRAME_ULONG_LE ( WinFNT_Header, flags ), - FT_FRAME_USHORT_LE( WinFNT_Header, A_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, B_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, C_space ), - FT_FRAME_USHORT_LE( WinFNT_Header, color_table_offset ), - FT_FRAME_BYTES ( WinFNT_Header, reserved, 4 ), - FT_FRAME_END - }; - - - static - void fnt_done_font( FT_Stream stream, - FNT_Font* font ) - { - if ( font->fnt_frame ) - RELEASE_Frame( font->fnt_frame ); - - font->fnt_size = 0; - font->fnt_frame = 0; - } - - - static - FT_Error fnt_load_font( FT_Stream stream, - FNT_Font* font ) - { - FT_Error error; - WinFNT_Header* header = &font->header; - - - /* first of all, read the FNT header */ - if ( FILE_Seek( font->offset ) || - READ_Fields( winfnt_header_fields, header ) ) - goto Exit; - - /* check header */ - if ( header->version != 0x200 && - header->version != 0x300 ) - { - FT_TRACE2(( "[not a valid FNT file]\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - if ( header->file_type & 1 ) - { - FT_TRACE2(( "can't handle vector FNT fonts\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - /* small fixup -- some fonts have the `pixel_width' field set to 0 */ - if ( header->pixel_width == 0 ) - header->pixel_width = header->pixel_height; - - /* this is a FNT file/table, we now extract its frame */ - if ( FILE_Seek( font->offset ) || - EXTRACT_Frame( header->file_size, font->fnt_frame ) ) - goto Exit; - - Exit: - return error; - } - - - static - void fnt_done_fonts( FNT_Face face ) - { - FT_Memory memory = FT_FACE(face)->memory; - FT_Stream stream = FT_FACE(face)->stream; - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + face->num_fonts; - - - for ( ; cur < limit; cur++ ) - fnt_done_font( stream, cur ); - - FREE( face->fonts ); - face->num_fonts = 0; - } - - static - FT_Error fnt_get_dll_fonts( FNT_Face face ) - { - FT_Error error; - FT_Stream stream = FT_FACE(face)->stream; - FT_Memory memory = FT_FACE(face)->memory; - WinMZ_Header mz_header; - - - face->fonts = 0; - face->num_fonts = 0; - - /* does it begin with a MZ header? */ - if ( FILE_Seek( 0 ) || - READ_Fields( winmz_header_fields, &mz_header ) ) - goto Exit; - - error = FT_Err_Unknown_File_Format; - if ( mz_header.magic == WINFNT_MZ_MAGIC ) - { - /* yes, now look for a NE header in the file */ - WinNE_Header ne_header; - - - if ( FILE_Seek( mz_header.lfanew ) || - READ_Fields( winne_header_fields, &ne_header ) ) - goto Exit; - - error = FT_Err_Unknown_File_Format; - if ( ne_header.magic == WINFNT_NE_MAGIC ) - { - /* good, now look in the resource table for each FNT resource */ - FT_ULong res_offset = mz_header.lfanew + - ne_header.resource_tab_offset; - - FT_UShort size_shift; - FT_UShort font_count = 0; - FT_ULong font_offset = 0; - - - if ( FILE_Seek( res_offset ) || - ACCESS_Frame( ne_header.rname_tab_offset - - ne_header.resource_tab_offset ) ) - goto Exit; - - size_shift = GET_UShortLE(); - - for (;;) - { - FT_UShort type_id, count; - - - type_id = GET_UShortLE(); - if ( !type_id ) - break; - - count = GET_UShortLE(); - - if ( type_id == 0x8008 ) - { - font_count = count; - font_offset = FILE_Pos() + 4 + ( stream->cursor - stream->limit ); - break; - } - - stream->cursor += 4 + count * 12; - } - FORGET_Frame(); - - if ( !font_count || !font_offset ) - { - FT_TRACE2(( "this file doesn't contain any FNT resources!\n" )); - error = FT_Err_Unknown_File_Format; - goto Exit; - } - - if ( FILE_Seek( font_offset ) || - ALLOC_ARRAY( face->fonts, font_count, FNT_Font ) ) - goto Exit; - - face->num_fonts = font_count; - - if ( ACCESS_Frame( (FT_Long)font_count * 12 ) ) - goto Exit; - - /* now read the offset and position of each FNT font */ - { - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - cur->offset = (FT_ULong)GET_UShortLE() << size_shift; - cur->fnt_size = (FT_ULong)GET_UShortLE() << size_shift; - cur->size_shift = size_shift; - stream->cursor += 8; - } - } - FORGET_Frame(); - - /* finally, try to load each font there */ - { - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + font_count; - - - for ( ; cur < limit; cur++ ) - { - error = fnt_load_font( stream, cur ); - if ( error ) - goto Fail; - } - } - } - } - - Fail: - if ( error ) - fnt_done_fonts( face ); - - Exit: - return error; - } - - - static - void FNT_Done_Face( FNT_Face face ) - { - FT_Memory memory = FT_FACE_MEMORY( face ); - - - fnt_done_fonts( face ); - - FREE( face->root.available_sizes ); - face->root.num_fixed_sizes = 0; - } - - - static - FT_Error FNT_Init_Face( FT_Stream stream, - FNT_Face face, - FT_Int face_index, - FT_Int num_params, - FT_Parameter* params ) - { - FT_Error error; - FT_Memory memory = FT_FACE_MEMORY( face ); - - FT_UNUSED( num_params ); - FT_UNUSED( params ); - FT_UNUSED( face_index ); - - - /* try to load several fonts from a DLL */ - error = fnt_get_dll_fonts( face ); - if ( error ) - { - /* this didn't work, now try to load a single FNT font */ - FT_Memory memory = FT_FACE_MEMORY( face ); - FNT_Font* font; - - if ( ALLOC( face->fonts, sizeof ( *face->fonts ) ) ) - goto Exit; - - face->num_fonts = 1; - font = face->fonts; - - font->offset = 0; - font->fnt_size = stream->size; - - error = fnt_load_font( stream, font ); - if ( error ) - goto Fail; - } - - /* all right, one or more fonts were loaded; we now need to */ - /* fill the root FT_Face fields with relevant information */ - { - FT_Face root = FT_FACE( face ); - FNT_Font* fonts = face->fonts; - FNT_Font* limit = fonts + face->num_fonts; - FNT_Font* cur; - - - root->num_faces = 1; - root->face_flags = FT_FACE_FLAG_FIXED_SIZES | - FT_FACE_FLAG_HORIZONTAL; - - if ( fonts->header.avg_width == fonts->header.max_width ) - root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - - if ( fonts->header.italic ) - root->style_flags |= FT_STYLE_FLAG_ITALIC; - - if ( fonts->header.weight >= 800 ) - root->style_flags |= FT_STYLE_FLAG_BOLD; - - /* Setup the `fixed_sizes' array */ - if ( ALLOC_ARRAY( root->available_sizes, face->num_fonts, - FT_Bitmap_Size ) ) - goto Fail; - - root->num_fixed_sizes = face->num_fonts; - - { - FT_Bitmap_Size* size = root->available_sizes; - - - for ( cur = fonts; cur < limit; cur++, size++ ) - { - size->width = cur->header.pixel_width; - size->height = cur->header.pixel_height; - } - } - - /* Setup the `charmaps' array */ - root->charmaps = &face->charmap_handle; - root->num_charmaps = 1; - - face->charmap.encoding = ft_encoding_unicode; - face->charmap.platform_id = 3; - face->charmap.encoding_id = 1; - face->charmap.face = root; - - face->charmap_handle = &face->charmap; - - root->charmap = face->charmap_handle; - - /* setup remaining flags */ - root->num_glyphs = fonts->header.last_char - - fonts->header.first_char + 1; - - root->family_name = (FT_String*)fonts->fnt_frame + - fonts->header.face_name_offset; - root->style_name = "Regular"; - - if ( root->style_flags & FT_STYLE_FLAG_BOLD ) - { - if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = "Bold Italic"; - else - root->style_name = "Bold"; - } - else if ( root->style_flags & FT_STYLE_FLAG_ITALIC ) - root->style_name = "Italic"; - } - - Fail: - if ( error ) - FNT_Done_Face( face ); - - Exit: - return error; - } - - - static - FT_Error FNT_Set_Pixel_Size( FNT_Size size ) - { - /* look up a font corresponding to the current pixel size */ - FNT_Face face = (FNT_Face)FT_SIZE_FACE( size ); - FNT_Font* cur = face->fonts; - FNT_Font* limit = cur + face->num_fonts; - - - size->font = 0; - for ( ; cur < limit; cur++ ) - { - /* we only compare the character height, as fonts used some strange */ - /* values */ - if ( cur->header.pixel_height == size->root.metrics.y_ppem ) - { - size->font = cur; - - size->root.metrics.ascender = cur->header.ascent * 64; - size->root.metrics.descender = ( cur->header.pixel_height - - cur->header.ascent ) * 64; - size->root.metrics.height = cur->header.pixel_height * 64; - break; - } - } - - return ( size->font ? FT_Err_Ok : FT_Err_Invalid_Argument ); - } - - - static - FT_UInt FNT_Get_Char_Index( FT_CharMap charmap, - FT_ULong char_code ) - { - FT_UInt result = char_code; - - - if ( charmap ) - { - FNT_Font* font = ((FNT_Face)charmap->face)->fonts; - FT_UInt first = font->header.first_char; - FT_UInt count = font->header.last_char - first + 1; - - - char_code -= first; - if ( char_code < count ) - result = char_code + 1; - else - result = 0; - } - - return result; - } - - - static - FT_Error FNT_Load_Glyph( FT_GlyphSlot slot, - FNT_Size size, - FT_UInt glyph_index, - FT_Int load_flags ) - { - FNT_Font* font = size->font; - FT_Error error = 0; - FT_Byte* p; - FT_Int len; - FT_Bitmap* bitmap = &slot->bitmap; - FT_ULong offset; - FT_Bool new_format; - - FT_UNUSED( slot ); - FT_UNUSED( load_flags ); - - - if ( !font ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - if ( glyph_index > 0 ) - glyph_index--; - else - glyph_index = font->header.default_char - font->header.first_char; - - new_format = font->header.version == 0x300; - len = new_format ? 6 : 4; - - /* jump to glyph entry */ - p = font->fnt_frame + 118 + len * glyph_index; - - bitmap->width = NEXT_ShortLE(p); - - if ( new_format ) - offset = NEXT_ULongLE(p); - else - offset = NEXT_UShortLE(p); - - /* jump to glyph data */ - p = font->fnt_frame + /* font->header.bits_offset */ + offset; - - /* allocate and build bitmap */ - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Int pitch = ( bitmap->width + 7 ) >> 3; - FT_Byte* column; - FT_Byte* write; - - - bitmap->pitch = pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = ft_pixel_mode_mono; - - if ( ALLOC( bitmap->buffer, pitch * bitmap->rows ) ) - goto Exit; - - column = (FT_Byte*)bitmap->buffer; - - for ( ; pitch > 0; pitch--, column++ ) - { - FT_Byte* limit = p + bitmap->rows; - - - for ( write = column; p < limit; p++, write += bitmap->pitch ) - write[0] = p[0]; - } - } - - slot->flags = ft_glyph_own_bitmap; - slot->bitmap_left = 0; - slot->bitmap_top = font->header.ascent; - slot->format = ft_glyph_format_bitmap; - - /* now set up metrics */ - slot->metrics.horiAdvance = bitmap->width << 6; - slot->metrics.horiBearingX = 0; - slot->metrics.horiBearingY = slot->bitmap_top << 6; - - slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; - - Exit: - return error; - } - - - const FT_Driver_Class winfnt_driver_class = - { - { - ft_module_font_driver, - sizeof ( FT_DriverRec ), - - "winfonts", - 0x10000L, - 0x20000L, - - 0, - - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - }, - - sizeof( FNT_FaceRec ), - sizeof( FNT_SizeRec ), - sizeof( FT_GlyphSlotRec ), - - (FTDriver_initFace) FNT_Init_Face, - (FTDriver_doneFace) FNT_Done_Face, - (FTDriver_initSize) 0, - (FTDriver_doneSize) 0, - (FTDriver_initGlyphSlot)0, - (FTDriver_doneGlyphSlot)0, - - (FTDriver_setCharSizes) FNT_Set_Pixel_Size, - (FTDriver_setPixelSizes)FNT_Set_Pixel_Size, - - (FTDriver_loadGlyph) FNT_Load_Glyph, - (FTDriver_getCharIndex) FNT_Get_Char_Index, - - (FTDriver_getKerning) 0, - (FTDriver_attachFile) 0, - (FTDriver_getAdvances) 0 - }; - - -/* END */ diff --git a/subsys/win32k/freetype/src/winfonts/winfnt.h b/subsys/win32k/freetype/src/winfonts/winfnt.h deleted file mode 100644 index eaf308b..0000000 --- a/subsys/win32k/freetype/src/winfonts/winfnt.h +++ /dev/null @@ -1,150 +0,0 @@ -/***************************************************************************/ -/* */ -/* winfnt.h */ -/* */ -/* FreeType font driver for Windows FNT/FON files */ -/* */ -/* Copyright 1996-2000 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 WINFNT_H -#define WINFNT_H - -#include - - - typedef struct WinMZ_Header_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort lfanew; - - } WinMZ_Header; - - - typedef struct WinNE_Header_ - { - FT_UShort magic; - /* skipped content */ - FT_UShort resource_tab_offset; - FT_UShort rname_tab_offset; - - } WinNE_Header; - - - typedef struct WinNameInfo_ - { - FT_UShort offset; - FT_UShort length; - FT_UShort flags; - FT_UShort id; - FT_UShort handle; - FT_UShort usage; - - } WinNameInfo; - - - typedef struct WinResourceInfo_ - { - FT_UShort type_id; - FT_UShort count; - - } WinResourceInfo; - - -#define WINFNT_MZ_MAGIC 0x5A4D -#define WINFNT_NE_MAGIC 0x454E - - - typedef struct WinFNT_Header_ - { - FT_UShort version; - FT_ULong file_size; - FT_Byte copyright[60]; - FT_UShort file_type; - FT_UShort nominal_point_size; - FT_UShort vertical_resolution; - FT_UShort horizontal_resolution; - FT_UShort ascent; - FT_UShort internal_leading; - FT_UShort external_leading; - FT_Byte italic; - FT_Byte underline; - FT_Byte strike_out; - FT_UShort weight; - FT_Byte charset; - FT_UShort pixel_width; - FT_UShort pixel_height; - FT_Byte pitch_and_family; - FT_UShort avg_width; - FT_UShort max_width; - FT_Byte first_char; - FT_Byte last_char; - FT_Byte default_char; - FT_Byte break_char; - FT_UShort bytes_per_row; - FT_ULong device_offset; - FT_ULong face_name_offset; - FT_ULong bits_pointer; - FT_ULong bits_offset; - FT_Byte reserved; - FT_ULong flags; - FT_UShort A_space; - FT_UShort B_space; - FT_UShort C_space; - FT_UShort color_table_offset; - FT_Byte reserved2[4]; - - } WinFNT_Header; - - - typedef struct FNT_Font_ - { - FT_ULong offset; - FT_Int size_shift; - - WinFNT_Header header; - - FT_Byte* fnt_frame; - FT_ULong fnt_size; - - } FNT_Font; - - - typedef struct FNT_SizeRec_ - { - FT_SizeRec root; - FNT_Font* font; - - } FNT_SizeRec, *FNT_Size; - - - typedef struct FNT_FaceRec_ - { - FT_FaceRec root; - - FT_UInt num_fonts; - FNT_Font* fonts; - - FT_CharMap charmap_handle; - FT_CharMapRec charmap; /* a single charmap per face */ - - } FNT_FaceRec, *FNT_Face; - - - FT_EXPORT_VAR( const FT_Driver_Class ) winfnt_driver_class; - - -#endif /* WINFNT_H */ - - -/* END */ diff --git a/subsys/win32k/include/dce.h b/subsys/win32k/include/dce.h index 54c76b3..9c20318 100644 --- a/subsys/win32k/include/dce.h +++ b/subsys/win32k/include/dce.h @@ -44,5 +44,6 @@ PDCE DCE_FreeDCE(PDCE dce); VOID DCE_FreeWindowDCE(HWND); INT DCE_ExcludeRgn(HDC, HWND, HRGN); BOOL DCE_InvalidateDCE(HWND, const PRECTL); +BOOL DCE_InternalDelete(PDCE dce); #endif diff --git a/subsys/win32k/include/guicheck.h b/subsys/win32k/include/guicheck.h index 60fca50..9c6024b 100644 --- a/subsys/win32k/include/guicheck.h +++ b/subsys/win32k/include/guicheck.h @@ -7,7 +7,7 @@ VOID W32kGuiCheck(VOID); VOID -W32kGraphicsCheck(VOID); +W32kGraphicsCheck(BOOL Create); #endif /* __WIN32K_GUICHECK_H */ diff --git a/subsys/win32k/include/inteng.h b/subsys/win32k/include/inteng.h new file mode 100644 index 0000000..8303ba0 --- /dev/null +++ b/subsys/win32k/include/inteng.h @@ -0,0 +1,38 @@ +#ifndef __WIN32K_INTENG_H +#define __WIN32K_INTENG_H + +/* Definitions of IntEngXxx functions */ + +extern BOOL STDCALL IntEngLineTo(SURFOBJ *Surface, + CLIPOBJ *Clip, + BRUSHOBJ *Brush, + LONG x1, + LONG y1, + LONG x2, + LONG y2, + RECTL *RectBounds, + MIX mix); +BOOL STDCALL IntEngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, + SURFOBJ *Mask, + CLIPOBJ *ClipRegion, + XLATEOBJ *ColorTranslation, + RECTL *DestRect, + POINTL *SourcePoint, + POINTL *MaskOrigin, + BRUSHOBJ *Brush, + POINTL *BrushOrigin, + ROP4 rop4); + +XLATEOBJ *IntEngCreateXlate(USHORT DestPalType, + USHORT SourcePalType, + HPALETTE PaletteDest, + HPALETTE PaletteSource); + +extern BOOL STDCALL IntEngPolyline(SURFOBJ *DestSurf, + CLIPOBJ *Clip, + BRUSHOBJ *Brush, + CONST LPPOINT pt, + LONG dCount, + MIX mix); +#endif diff --git a/subsys/win32k/include/winsta.h b/subsys/win32k/include/winsta.h index 96eef24..ddbf173 100644 --- a/subsys/win32k/include/winsta.h +++ b/subsys/win32k/include/winsta.h @@ -36,6 +36,8 @@ PDESKTOP_OBJECT W32kGetActiveDesktop(VOID); VOID W32kInitializeDesktopGraphics(VOID); +VOID +W32kEndDesktopGraphics(VOID); HDC W32kGetScreenDC(VOID); diff --git a/subsys/win32k/main/dllmain.c b/subsys/win32k/main/dllmain.c index 63a475c..d2f9a2e 100644 --- a/subsys/win32k/main/dllmain.c +++ b/subsys/win32k/main/dllmain.c @@ -17,7 +17,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include extern SSDT Win32kSSDT[]; @@ -91,26 +91,39 @@ DllMain ( return(Status); } + Status = InitTimerImpl(); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to initialize timer implementation.\n"); + return(Status); + } + return STATUS_SUCCESS; } +PEPROCESS W32kDeviceProcess; BOOLEAN STDCALL W32kInitialize (VOID) { DPRINT("in W32kInitialize\n"); + + W32kDeviceProcess = PsGetCurrentProcess(); + InitGdiObjectHandleTable (); // Create surface used to draw the internal font onto +#ifdef TODO CreateCellCharSurface(); - - // Create stock objects, ie. precreated objects commonly used by win32 applications - CreateStockObjects(); +#endif // Initialize FreeType library if(!InitFontSupport()) return FALSE; + // Create stock objects, ie. precreated objects commonly used by win32 applications + CreateStockObjects(); + return TRUE; } diff --git a/subsys/win32k/makefile b/subsys/win32k/makefile index 7584dee..d9cc199 100644 --- a/subsys/win32k/makefile +++ b/subsys/win32k/makefile @@ -2,7 +2,7 @@ PATH_TO_TOP = ../.. -TARGET_TYPE = export_driver +TARGET_TYPE = subsystem TARGET_NAME = win32k @@ -10,6 +10,10 @@ TARGET_BASE = 0x0 TARGET_ENTRY = _DllMain@8 +TARGET_DDKLIBS = freetype.a + +FREETYPE_DIR = $(PATH_TO_TOP)/lib/freetype + include $(PATH_TO_TOP)/config ifeq ($(DBG), 1) @@ -18,20 +22,29 @@ else CFLAGS_DBG := endif -TARGET_CFLAGS = $(CFLAGS_DBG) -I$(PATH_TO_TOP)/ntoskrnl/include -DUNICODE -Wall +TARGET_CFLAGS = $(CFLAGS_DBG) -I$(PATH_TO_TOP)/ntoskrnl/include -I$(FREETYPE_DIR)/include -DUNICODE -Wall + +TARGET_LFLAGS = $(PATH_TO_TOP)/dk/nkm/lib/freetype.a ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o \ eng/copybits.o eng/device.o eng/handle.o eng/lineto.o eng/paint.o \ - eng/palette.o eng/surface.o eng/xlate.o eng/transblt.o eng/mouse.o + eng/palette.o eng/surface.o eng/xlate.o eng/transblt.o eng/mouse.o \ + eng/misc.o + MAIN_OBJECTS = main/dllmain.o main/svctabm.o + MISC_OBJECTS = misc/driver.o misc/error.o misc/math.o misc/object.o + LDR_OBJECTS = ldr/loader.o + NTUSER_OBJECTS = ntuser/class.o ntuser/guicheck.o ntuser/hook.o \ ntuser/message.o ntuser/msgqueue.o ntuser/stubs.o \ ntuser/userobj.o ntuser/window.o ntuser/winsta.o \ ntuser/input.o ntuser/keyboard.o ntuser/callback.o \ ntuser/winpos.o ntuser/painting.o ntuser/metric.o \ - ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o + ntuser/windc.o ntuser/prop.o ntuser/scrollbar.o \ + ntuser/timer.o + OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ objects/color.o objects/coord.o objects/dc.o \ objects/fillshap.o objects/gdiobj.o objects/icm.o \ @@ -39,8 +52,10 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ objects/path.o objects/pen.o objects/print.o \ objects/region.o objects/text.o objects/wingl.o \ objects/bezier.o objects/objconv.o objects/dib.o \ - objects/palette.o objects/rect.o -DIB_OBJECTS = dib/dib1bpp.o dib/dib4bpp.o dib/dib24bpp.o + objects/palette.o objects/rect.o objects/polyfill.o + +DIB_OBJECTS = dib/dib.o dib/dib1bpp.o dib/dib4bpp.o dib/dib8bpp.o dib/dib16bpp.o \ + dib/dib24bpp.o dib/dib32bpp.o FREETYPE_OBJECTS = freetype/ctype.o freetype/grfont.o \ freetype/src/base/ftsystem.o freetype/src/base/ftdebug.o \ freetype/src/base/ftinit.o freetype/src/base/ftbase.o \ @@ -55,7 +70,7 @@ STUBS_OBJECTS = stubs/stubs.o TARGET_OBJECTS = \ $(ENG_OBJECTS) $(MAIN_OBJECTS) $(MISC_OBJECTS) $(LDR_OBJECTS) \ $(NTUSER_OBJECTS) $(OBJECTS_OBJECTS) $(STUBS_OBJECTS) \ - $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(FREETYPE_OBJECTS) $(DIB_OBJECTS) + $(MATH_OBJECTS) $(FLOAT_OBJECTS) $(DIB_OBJECTS) TARGET_CLEAN = $(DEP_FILES) \ dib/*.o \ @@ -75,7 +90,7 @@ include $(TOOLS_PATH)/helper.mk # Automatic dependency tracking DEP_OBJECTS := $(TARGET_OBJECTS) DEP_EXCLUDE_FILTER := main/svctabm.d -include $(PATH_TO_TOP)/tools/depend.mk +#include $(PATH_TO_TOP)/tools/depend.mk main/svctabm.o: main/svctab.c diff --git a/subsys/win32k/misc/driver.c b/subsys/win32k/misc/driver.c index 881a168..c701f6f 100644 --- a/subsys/win32k/misc/driver.c +++ b/subsys/win32k/misc/driver.c @@ -11,14 +11,16 @@ #include #include #include +#include #include -//#include "../../ntoskrnl/include/internal/module.h" #include #include #define NDEBUG #include +#define DRIVER_TAG TAG('G', 'D', 'R', 'V') + typedef struct _GRAPHICS_DRIVER { PWSTR Name; @@ -32,14 +34,16 @@ static PGRAPHICS_DRIVER GenericDriver = 0; BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver) { - PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver)); + PGRAPHICS_DRIVER Driver = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Driver), DRIVER_TAG); DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name ); if (!Driver) return FALSE; Driver->ReferenceCount = 0; Driver->EnableDriver = EnableDriver; if (Name) { - Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR)); + Driver->Name = ExAllocatePoolWithTag(PagedPool, + (wcslen(Name) + 1) * sizeof(WCHAR), + DRIVER_TAG); wcscpy(Driver->Name, Name); Driver->Next = DriverList; DriverList = Driver; @@ -56,16 +60,69 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver) return TRUE; } -PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) +PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) { + static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\"; + static WCHAR DefaultExtension[] = L".DLL"; SYSTEM_LOAD_IMAGE GdiDriverInfo; GRAPHICS_DRIVER *Driver = DriverList; NTSTATUS Status; + WCHAR *FullName; + LPCWSTR p; + BOOL PathSeparatorFound; + BOOL DotFound; + UINT Size; + + DotFound = FALSE; + PathSeparatorFound = FALSE; + p = Name; + while (L'\0' != *p) + { + if (L'\\' == *p || L'/' == *p) + { + PathSeparatorFound = TRUE; + DotFound = FALSE; + } + else if (L'.' == *p) + { + DotFound = TRUE; + } + p++; + } + + Size = (wcslen(Name) + 1) * sizeof(WCHAR); + if (! PathSeparatorFound) + { + Size += sizeof(DefaultPath) - sizeof(WCHAR); + } + if (! DotFound) + { + Size += sizeof(DefaultExtension) - sizeof(WCHAR); + } + FullName = ExAllocatePoolWithTag(PagedPool, Size, DRIVER_TAG); + if (NULL == FullName) + { + DPRINT1("Out of memory\n"); + return NULL; + } + if (PathSeparatorFound) + { + FullName[0] = L'\0'; + } + else + { + wcscpy(FullName, DefaultPath); + } + wcscat(FullName, Name); + if (! DotFound) + { + wcscat(FullName, DefaultExtension); + } /* First see if the driver hasn't already been loaded */ - while (Driver && Name) + while (Driver && FullName) { - if (!_wcsicmp( Driver->Name, Name)) + if (!_wcsicmp( Driver->Name, FullName)) { return Driver->EnableDriver; } @@ -73,8 +130,9 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) } /* If not, then load it */ - RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)Name); + RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)FullName); Status = ZwSetSystemInformation (SystemLoadImage, &GdiDriverInfo, sizeof(SYSTEM_LOAD_IMAGE)); + ExFreePool(FullName); if (!NT_SUCCESS(Status)) return NULL; DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint); @@ -169,6 +227,9 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name) HANDLE DisplayHandle; NTSTATUS Status; + /* Switch to process context in which handle is to be valid */ + KeAttachProcess(W32kDeviceProcess); + RtlInitUnicodeStringFromLiteral(&DeviceName, L"\\??\\DISPLAY1"); InitializeObjectAttributes(&ObjectAttributes, &DeviceName, @@ -181,6 +242,9 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name) &Iosb, 0, FILE_SYNCHRONOUS_IO_ALERT); + + KeDetachProcess(); + if (!NT_SUCCESS(Status)) { DPRINT("ZwOpenFile() failed (Status %lx)\n", Status); diff --git a/subsys/win32k/ntuser/guicheck.c b/subsys/win32k/ntuser/guicheck.c index 1db5dd8..5440c41 100644 --- a/subsys/win32k/ntuser/guicheck.c +++ b/subsys/win32k/ntuser/guicheck.c @@ -34,13 +34,28 @@ static ULONG NrGuiApplicationsRunning = 0; /* FUNCTIONS *****************************************************************/ VOID -W32kGraphicsCheck(VOID) +W32kGraphicsCheck(BOOL Create) { - if (NrGuiApplicationsRunning == 0) + if (Create) { - W32kInitializeDesktopGraphics(); + if (0 == NrGuiApplicationsRunning) + { + W32kInitializeDesktopGraphics(); + } + NrGuiApplicationsRunning++; + } + else + { + if (0 < NrGuiApplicationsRunning) + { + NrGuiApplicationsRunning--; + } + if (0 == NrGuiApplicationsRunning) + { + W32kEndDesktopGraphics(); + } } - NrGuiApplicationsRunning++; + } VOID diff --git a/subsys/win32k/ntuser/input.c b/subsys/win32k/ntuser/input.c index 337c75e..edd347d 100644 --- a/subsys/win32k/ntuser/input.c +++ b/subsys/win32k/ntuser/input.c @@ -18,7 +18,7 @@ #include #include #include -#include "../../drivers/input/include/mouse.h" +#include #define NDEBUG #include diff --git a/subsys/win32k/ntuser/message.c b/subsys/win32k/ntuser/message.c index b687dc4..73f1646 100644 --- a/subsys/win32k/ntuser/message.c +++ b/subsys/win32k/ntuser/message.c @@ -325,9 +325,23 @@ NtUserPostMessage(HWND hWnd, WPARAM wParam, LPARAM lParam) { - UNIMPLEMENTED; + PUSER_MESSAGE_QUEUE ThreadQueue; + + if (WM_QUIT == Msg) + { + ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; + + ThreadQueue->QuitPosted = TRUE; + ThreadQueue->QuitExitCode = wParam; + + return TRUE; + } + else + { + UNIMPLEMENTED; - return 0; + return FALSE; + } } BOOL STDCALL diff --git a/subsys/win32k/ntuser/metric.c b/subsys/win32k/ntuser/metric.c index 819214a..70894a5 100644 --- a/subsys/win32k/ntuser/metric.c +++ b/subsys/win32k/ntuser/metric.c @@ -24,43 +24,130 @@ /* FUNCTIONS *****************************************************************/ +/* FIXME: Alot of thse values should NOT be hardcoded but they are */ ULONG STDCALL NtUserGetSystemMetrics(ULONG Index) { switch (Index) { - case SM_CXSCREEN: - return(640); - case SM_CYSCREEN: - return(480); - case SM_CXMINTRACK: - return(100); - case SM_CYMINTRACK: - return(28); + case SM_ARRANGE: + return(8); + case SM_CLEANBOOT: + return(0); + case SM_CMOUSEBUTTONS: + return(2); + case SM_CXBORDER: + case SM_CYBORDER: + return(1); + case SM_CXCURSOR: + case SM_CYCURSOR: + return(32); case SM_CXDLGFRAME: - return(4); case SM_CYDLGFRAME: + return(3); + case SM_CXDOUBLECLK: + case SM_CYDOUBLECLK: return(4); + case SM_CXDRAG: + case SM_CYDRAG: + return(2); + case SM_CXEDGE: + case SM_CYEDGE: + return(2); case SM_CXFRAME: - return(5); case SM_CYFRAME: - return(5); - case SM_CXBORDER: - return(1); - case SM_CYBORDER: - return(1); - case SM_CXVSCROLL: - return(17); + return(4); + case SM_CXFULLSCREEN: + return(640); + case SM_CYFULLSCREEN: + return(480); + case SM_CXHSCROLL: case SM_CYHSCROLL: - return(17); - case SM_CYCAPTION: - return(20); + return(16); + case SM_CXHTHUMB: + return(16); + case SM_CXICON: + case SM_CYICON: + return(32); + case SM_CXICONSPACING: + case SM_CYICONSPACING: + return(75); + case SM_CXMAXIMIZED: + return(NtUserGetSystemMetrics(SM_CXSCREEN) + 8); /* This seems to be 8 + pixels greater than + the screen width */ + case SM_CYMAXIMIZED: + return(NtUserGetSystemMetrics(SM_CYSCREEN) - 20); /* This seems to be 20 + pixels less than + the screen height, + taskbar maybe? */ + case SM_CXMAXTRACK: + return(NtUserGetSystemMetrics(SM_CYSCREEN) + 12); + case SM_CYMAXTRACK: + return(NtUserGetSystemMetrics(SM_CYSCREEN) + 12); + case SM_CXMENUCHECK: + case SM_CYMENUCHECK: + return(13); + case SM_CXMENUSIZE: + case SM_CYMENUSIZE: + return(18); + case SM_CXMIN: + return(112); + case SM_CYMIN: + return(27); + case SM_CXMINIMIZED: + return(160); + case SM_CYMINIMIZED: + return(24); + case SM_CXMINSPACING: + return(160); + case SM_CYMINSPACING: + return(24); + case SM_CXMINTRACK: + return(112); + case SM_CYMINTRACK: + return(27); + case SM_CXSCREEN: + return(640); + case SM_CYSCREEN: + return(480); case SM_CXSIZE: case SM_CYSIZE: return(18); + case SM_CXSMICON: + case SM_CYSMICON: + return(16); case SM_CXSMSIZE: + return(12); case SM_CYSMSIZE: - return(14); + return(15); + case SM_CXVSCROLL: + case SM_CYVSCROLL: + return(16); + case SM_CYCAPTION: + return(19); + case SM_CYKANJIWINDOW: + return 0; + case SM_CYMENU: + return(19); + case SM_CYSMCAPTION: + return(16); + case SM_CYVTHUMB: + case SM_DBCSENABLED: + case SM_DEBUG: + case SM_MENUDROPALIGNMENT: + case SM_MIDEASTENABLED: + return(0); + case SM_MOUSEPRESENT: + return(1); + case SM_NETWORK: + return(3); + case SM_PENWINDOWS: + case SM_SECURE: + case SM_SHOWSOUNDS: + case SM_SLOWMACHINE: + case SM_SWAPBUTTON: + return(0); default: return(0xFFFFFFFF); } diff --git a/subsys/win32k/ntuser/painting.c b/subsys/win32k/ntuser/painting.c index 9f4e321..1eefd47 100644 --- a/subsys/win32k/ntuser/painting.c +++ b/subsys/win32k/ntuser/painting.c @@ -492,7 +492,7 @@ PaintRedrawWindow(HWND hWnd, const RECT* UpdateRect, HRGN UpdateRgn, } else { - W32kGetClientRect(hWnd, &Rect2); + W32kGetClientRect(Window, &Rect2); hRgn = UnsafeW32kCreateRectRgnIndirect(&Rect2); } } @@ -584,11 +584,11 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread) } ExAcquireFastMutex(&BaseWindow->ChildrenListLock); - current_entry = Thread->WindowListHead.Flink; - while (current_entry != &Thread->WindowListHead) + current_entry = BaseWindow->ChildrenListHead.Flink; + while (current_entry != &BaseWindow->ChildrenListHead) { Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT, - ThreadListEntry); + ChildrenListHead); if (Window->Style & WS_VISIBLE) { hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread); @@ -760,7 +760,6 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) { return(NULL); } - if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) { DbgPrint("[ayes:0]"); } else { DbgPrint("[ano:0]"); } /*testing*/ IsIcon = Window->Style & WS_MINIMIZE && NtUserGetClassLong(Window->Self, GCL_HICON); @@ -818,7 +817,6 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs) if (Window->Flags & WINDOWOBJECT_NEED_ERASEBACKGRD) { BOOLEAN Result; -DbgPrint("[dne:0]"); Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBACKGRD; Result = NtUserSendMessage(hWnd, IsIcon ? WM_ICONERASEBKGND : WM_ERASEBKGND, @@ -828,10 +826,58 @@ DbgPrint("[dne:0]"); } else { -DbgPrint("[dne:1]"); lPs->fErase = FALSE; } ObmDereferenceObject(Window); return(lPs->hdc); } + +DWORD +STDCALL +NtUserInvalidateRect( + HWND hWnd, + CONST RECT *lpRect, + WINBOOL bErase) +{ + HRGN hRGN; + hRGN = W32kCreateRectRgnIndirect(lpRect); + return NtUserInvalidateRgn(hWnd, hRGN, bErase); +} + +DWORD +STDCALL +NtUserInvalidateRgn( + HWND hWnd, + HRGN hRgn, + WINBOOL bErase) +{ + PWINDOW_OBJECT WindowObject; + + WindowObject = W32kGetWindowObject(hWnd); + if (WindowObject == NULL) + { + return(FALSE); + } + + if( WindowObject->UpdateRegion == NULL ) + { + WindowObject->UpdateRegion = W32kCreateRectRgn (0, 0, 1, 1); + if (!W32kCombineRgn(WindowObject->UpdateRegion, hRgn, hRgn, RGN_COPY )) + { + W32kReleaseWindowObject(WindowObject); + return(FALSE); + } + } + + if (!W32kCombineRgn(WindowObject->UpdateRegion, WindowObject->UpdateRegion, hRgn, RGN_OR )) + { + W32kReleaseWindowObject(WindowObject); + return(FALSE); + } + + W32kReleaseWindowObject(WindowObject); + W32kSendMessage(hWnd, WM_PAINT, 0, 0, FALSE); + return(TRUE); +} + diff --git a/subsys/win32k/ntuser/stubs.c b/subsys/win32k/ntuser/stubs.c index f848bd5..fbb0052 100644 --- a/subsys/win32k/ntuser/stubs.c +++ b/subsys/win32k/ntuser/stubs.c @@ -1112,30 +1112,6 @@ NtUserInitTask( DWORD STDCALL -NtUserInvalidateRect( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL -NtUserInvalidateRgn( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserIsClipboardFormatAvailable( DWORD Unknown0) { @@ -1146,17 +1122,6 @@ NtUserIsClipboardFormatAvailable( DWORD STDCALL -NtUserKillTimer( - DWORD Unknown0, - DWORD Unknown1) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserLoadKeyboardLayoutEx( DWORD Unknown0, DWORD Unknown1, @@ -1585,19 +1550,6 @@ NtUserSetSystemMenu( DWORD STDCALL -NtUserSetSystemTimer( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserSetThreadState( DWORD Unknown0, DWORD Unknown1) @@ -1609,19 +1561,6 @@ NtUserSetThreadState( DWORD STDCALL -NtUserSetTimer( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserShowCaret( DWORD Unknown0) { diff --git a/subsys/win32k/ntuser/timer.c b/subsys/win32k/ntuser/timer.c new file mode 100644 index 0000000..6d174a9 --- /dev/null +++ b/subsys/win32k/ntuser/timer.c @@ -0,0 +1,362 @@ +/* + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Window timers messages + * FILE: subsys/win32k/ntuser/timer.c + * PROGRAMER: Gunnar + * REVISION HISTORY: + * + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + + +static FAST_MUTEX Mutex; +static LIST_ENTRY TimerListHead; +static KTIMER Timer; +static RTL_BITMAP HandleLessTimersBitMap; +static PVOID HandleLessTimersBitMapBuffer; +static ULONG HintIndex = 0; +static HANDLE MsgTimerThreadHandle; +static CLIENT_ID MsgTimerThreadId; + + +typedef struct _MSG_TIMER_ENTRY{ + LIST_ENTRY ListEntry; + LARGE_INTEGER Timeout; + HANDLE ThreadID; + UINT Period; + MSG Msg; +} MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY; + + +/* FUNCTIONS *****************************************************************/ + + +//return true if the new timer became the first entry +BOOL +FASTCALL +InsertTimerAscendingOrder(PMSG_TIMER_ENTRY NewTimer) +{ + PLIST_ENTRY EnumEntry, InsertAfter; + PMSG_TIMER_ENTRY MsgTimer; + + InsertAfter = NULL; + + EnumEntry = TimerListHead.Flink; + while (EnumEntry != &TimerListHead) + { + MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); + if (NewTimer->Timeout.QuadPart > MsgTimer->Timeout.QuadPart) + { + InsertAfter = EnumEntry; + } + EnumEntry = EnumEntry->Flink; + } + + if (InsertAfter) + { + InsertTailList(InsertAfter, &NewTimer->ListEntry); + return FALSE; + } + + //insert as first entry + InsertHeadList(&TimerListHead, &NewTimer->ListEntry); + return TRUE; + +} + +PMSG_TIMER_ENTRY +FASTCALL +RemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID) +{ + PMSG_TIMER_ENTRY MsgTimer; + PLIST_ENTRY EnumEntry; + + //remove timer if allready in the queue + EnumEntry = TimerListHead.Flink; + while (EnumEntry != &TimerListHead) + { + MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); + if (MsgTimer->Msg.hwnd == hWnd && + MsgTimer->Msg.wParam == (WPARAM)IDEvent && + MsgTimer->ThreadID == ThreadID) + { + RemoveEntryList(EnumEntry); + return MsgTimer; + } + EnumEntry = EnumEntry->Flink; + } + + return NULL; +} + + + + +NTSTATUS +STDCALL +NtUserSetTimer( + HWND hWnd, + UINT_PTR * IDEvent, + UINT Period, + TIMERPROC TimerFunc + ) +{ + ULONG Index; + PMSG_TIMER_ENTRY MsgTimer = NULL; + PMSG_TIMER_ENTRY NewTimer; + LARGE_INTEGER CurrentTime; + HANDLE ThreadID; + + //FIXME: WINE: window must be owned by the calling thread +#if 0 + if (hWnd && !(hWnd = WIN_IsCurrentThread(hWnd)) + { + return STATUS_UNSUCCESSFUL; + } + +#endif + + ThreadID = PsGetCurrentThreadId(); + KeQuerySystemTime(&CurrentTime); + ExAcquireFastMutex(&Mutex); + + if (hWnd == NULL) + { + //find a free, handle-less timer id + Index = RtlFindClearBitsAndSet(&HandleLessTimersBitMap, 1, HintIndex); + if (Index == -1) + { + return STATUS_UNSUCCESSFUL; + } + + *IDEvent = HintIndex = Index + 1; + } + else + { + //remove timer if allready in the queue + MsgTimer = RemoveTimer(hWnd, *IDEvent, ThreadID); + } + + if (MsgTimer) + { + //modify existing (removed) timer + NewTimer = MsgTimer; + + NewTimer->Period = Period; + NewTimer->Timeout.QuadPart = CurrentTime.QuadPart + (Period * 10000); + NewTimer->Msg.lParam = (LPARAM)TimerFunc; + } + else + { + //FIXME: use lookaside? + NewTimer = ExAllocatePool(PagedPool, sizeof(MSG_TIMER_ENTRY)); + + NewTimer->Msg.hwnd = hWnd; + NewTimer->Msg.message = WM_TIMER; + NewTimer->Msg.wParam = (WPARAM)*IDEvent; + NewTimer->Msg.lParam = (LPARAM)TimerFunc; + NewTimer->Period = Period; + NewTimer->Timeout.QuadPart = CurrentTime.QuadPart + (Period * 10000); + NewTimer->ThreadID = ThreadID; + } + + if (InsertTimerAscendingOrder(NewTimer)) + { + //new timer is first in queue and expires first + KeSetTimer(&Timer, NewTimer->Timeout, NULL); + } + + ExReleaseFastMutex(&Mutex); + + return STATUS_SUCCESS; +} + + +NTSTATUS +STDCALL +NtUserKillTimer( + HWND hWnd, + UINT_PTR IDEvent) +{ + PMSG_TIMER_ENTRY MsgTimer; + + ExAcquireFastMutex(&Mutex); + + //handle-less timer? + if (hWnd == NULL) + { + if (!RtlAreBitsSet(&HandleLessTimersBitMap, IDEvent - 1, 1)) + { + //bit was not set + ExReleaseFastMutex(&Mutex); + return STATUS_UNSUCCESSFUL; + } + + RtlClearBits(&HandleLessTimersBitMap, IDEvent - 1, 1); + } + + MsgTimer = RemoveTimer(hWnd, IDEvent, PsGetCurrentThreadId()); + + ExReleaseFastMutex(&Mutex); + + if (MsgTimer == NULL) + { + //didn't find timer + return STATUS_UNSUCCESSFUL; + } + + //FIXME: use lookaside? + ExFreePool(MsgTimer); + + return STATUS_SUCCESS; +} + + + + +DWORD +STDCALL +NtUserSetSystemTimer( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3) +{ + UNIMPLEMENTED + + return 0; +} + + +static NTSTATUS STDCALL +TimerThreadMain() +{ + NTSTATUS Status; + LARGE_INTEGER CurrentTime; + PLIST_ENTRY EnumEntry; + PMSG_TIMER_ENTRY MsgTimer; + PETHREAD Thread; + + for (;;) + { + + Status = KeWaitForSingleObject( &Timer, + Executive, + KernelMode, + FALSE, + NULL + ); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error waiting in TimerThreadMain\n"); + KeBugCheck(0); + } + + ExAcquireFastMutex(&Mutex); + + KeQuerySystemTime(&CurrentTime); + + EnumEntry = TimerListHead.Flink; + while (EnumEntry != &TimerListHead) + { + MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); + EnumEntry = EnumEntry->Flink; + + if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart) + { + RemoveEntryList(&MsgTimer->ListEntry); + + /* + * FIXME: 1) Find a faster way of getting the thread message queue? (lookup by id is slow) + * 2) Kill all timers for thread when the thread exits? + */ + + if (!NT_SUCCESS(PsLookupThreadByThreadId(MsgTimer->ThreadID, &Thread))) + { + //FIXME: remove all other timers for this thread also? + ExFreePool(MsgTimer); + continue; + } + + /* + * FIXME: small window here, where the thread can exit between the thread lookup + * and the message posting (missing ref count?) + */ + MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, MsqCreateMessage(&MsgTimer->Msg)); + + //set up next periodic timeout + MsgTimer->Timeout.QuadPart += (MsgTimer->Period * 10000); + InsertTimerAscendingOrder(MsgTimer); + + } + else + { + break; + } + } + + //set up next timeout from first entry (if any) + if (!IsListEmpty(&TimerListHead)) + { + MsgTimer = CONTAINING_RECORD( TimerListHead.Flink, MSG_TIMER_ENTRY, ListEntry); + KeSetTimer(&Timer, MsgTimer->Timeout, NULL); + } + + ExReleaseFastMutex(&Mutex); + + } + +} + + + +NTSTATUS +InitTimerImpl() +{ + NTSTATUS Status; + + InitializeListHead(&TimerListHead); + KeInitializeTimer(&Timer); + ExInitializeFastMutex(&Mutex); + + //windows 2000 has room for 32768 handle-less timers + HandleLessTimersBitMapBuffer = ExAllocatePool(PagedPool, PAGE_SIZE); + RtlInitializeBitMap(&HandleLessTimersBitMap, + HandleLessTimersBitMapBuffer, + PAGE_SIZE * sizeof(ULONG)); + + //yes we need this, since ExAllocatePool isn't supposed to zero out allocated memory + RtlClearAllBits(&HandleLessTimersBitMap); + + Status = PsCreateSystemThread(&MsgTimerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &MsgTimerThreadId, + TimerThreadMain, + NULL); + return Status; +} + + + + + + diff --git a/subsys/win32k/ntuser/windc.c b/subsys/win32k/ntuser/windc.c index 2cc09e8..7f34d4f 100644 --- a/subsys/win32k/ntuser/windc.c +++ b/subsys/win32k/ntuser/windc.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -528,4 +529,31 @@ NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags) return(Dce->hDC); } +BOOL +DCE_InternalDelete(PDCE Dce) +{ + PDCE PrevInList; + + if (Dce == FirstDce) + { + FirstDce = Dce->next; + PrevInList = Dce; + } + else + { + for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next) + { + if (Dce == PrevInList->next) + { + PrevInList->next = Dce->next; + break; + } + } + assert(NULL != PrevInList); + } + + return NULL != PrevInList; +} + + /* EOF */ diff --git a/subsys/win32k/ntuser/window.c b/subsys/win32k/ntuser/window.c index e7d7757..863e685 100644 --- a/subsys/win32k/ntuser/window.c +++ b/subsys/win32k/ntuser/window.c @@ -11,6 +11,7 @@ /* INCLUDES ******************************************************************/ #include +#include #include #include #include @@ -23,9 +24,12 @@ #include #include -//#define NDEBUG +#define NDEBUG +#include #include +#define TAG_WNAM TAG('W', 'N', 'A', 'M') + /* FUNCTIONS *****************************************************************/ HWND STDCALL @@ -155,20 +159,35 @@ W32kReleaseWindowObject(PWINDOW_OBJECT Window) ObmDereferenceObject(Window); } +/*! + * Internal function. + * Returns client window rectangle relative to the upper-left corner of client area. + * + * \note Does not check the validity of the parameters +*/ VOID W32kGetClientRect(PWINDOW_OBJECT WindowObject, PRECT Rect) { + ASSERT( WindowObject ); + ASSERT( Rect ); + Rect->left = Rect->top = 0; Rect->right = WindowObject->ClientRect.right - WindowObject->ClientRect.left; Rect->bottom = WindowObject->ClientRect.bottom - WindowObject->ClientRect.top; } +/*! + * Internal Function. + * Return the dimension of the window in the screen coordinates. +*/ BOOL STDCALL W32kGetWindowRect(HWND hWnd, LPRECT Rect) { PWINDOW_OBJECT WindowObject; + ASSERT( Rect ); + WindowObject = W32kGetWindowObject(hWnd); if (WindowObject == NULL) { @@ -183,10 +202,50 @@ W32kGetWindowRect(HWND hWnd, LPRECT Rect) return(TRUE); } +/*! + * Return the dimension of the window in the screen coordinates. + * \param hWnd window handle. + * \param Rect pointer to the buffer where the coordinates are returned. +*/ BOOL STDCALL NtUserGetWindowRect(HWND hWnd, LPRECT Rect) { - return(W32kGetWindowRect(hWnd, Rect)); + RECT SafeRect; + BOOL bRet; + + bRet = W32kGetWindowRect(hWnd, &SafeRect); + if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))){ + return(FALSE); + } + return( bRet ); +} + +/*! + * Returns client window rectangle relative to the upper-left corner of client area. + * + * \param hWnd window handle. + * \param Rect pointer to the buffer where the coordinates are returned. + * +*/ +BOOL STDCALL +NtUserGetClientRect(HWND hWnd, LPRECT Rect) +{ + PWINDOW_OBJECT WindowObject; + RECT SafeRect; + + WindowObject = W32kGetWindowObject(hWnd); + if (WindowObject == NULL) + { + return(FALSE); + } + W32kGetClientRect(WindowObject, &SafeRect); + if (! NT_SUCCESS(MmCopyToCaller(Rect, &SafeRect, sizeof(RECT)))) + { + return(FALSE); + } + + W32kReleaseWindowObject(WindowObject); + return(TRUE); } HWND @@ -208,15 +267,17 @@ HWND W32kGetFocusWindow(VOID) { PUSER_MESSAGE_QUEUE Queue; - Queue = (PUSER_MESSAGE_QUEUE)W32kGetActiveDesktop()->ActiveMessageQueue; + PDESKTOP_OBJECT pdo = W32kGetActiveDesktop(); + + if( !pdo ) + return NULL; + + Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue; + if (Queue == NULL) - { return(NULL); - } else - { return(Queue->FocusWindow); - } } @@ -227,6 +288,9 @@ W32kGetWindowProc(HWND Wnd) WNDPROC WndProc; WindowObject = W32kGetWindowObject(Wnd); + if( !WindowObject ) + return NULL; + WndProc = WindowObject->Class->Class.lpfnWndProc; W32kReleaseWindowObject(Wnd); return(WndProc); @@ -343,12 +407,11 @@ NtUserCreateWindowEx(DWORD dwExStyle, POINT MaxSize, MaxPos, MinTrack, MaxTrack; CREATESTRUCTW Cs; LRESULT Result; - DPRINT("NtUserCreateWindowEx\n"); /* Initialize gui state if necessary. */ W32kGuiCheck(); - W32kGraphicsCheck(); + W32kGraphicsCheck(TRUE); if (!RtlCreateUnicodeString(&WindowName, lpWindowName->Buffer)) { @@ -410,7 +473,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, */ WindowObject->Class = ClassObject; WindowObject->ExStyle = dwExStyle; - WindowObject->Style = dwStyle; + WindowObject->Style = dwStyle | WIN_NCACTIVATED; WindowObject->x = x; WindowObject->y = y; WindowObject->Width = nWidth; @@ -426,6 +489,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, &WindowObject->SiblingListEntry); InitializeListHead(&WindowObject->ChildrenListHead); InitializeListHead(&WindowObject->PropListHead); + ExInitializeFastMutex(&WindowObject->ChildrenListLock); RtlInitUnicodeString(&WindowObject->WindowName, WindowName.Buffer); RtlFreeUnicodeString(&WindowName); @@ -466,8 +530,9 @@ NtUserCreateWindowEx(DWORD dwExStyle, */ InsertTailList(&PsGetWin32Thread()->Desktop->WindowListHead, &WindowObject->DesktopListEntry); - - /* FIXME: Maybe allocate a DCE for this window. */ + /* Allocate a DCE for this window. */ + if (dwStyle & CS_OWNDC) WindowObject->Dce = DceAllocDCE(WindowObject->Self,DCE_WINDOW_DC); + /* FIXME: Handle "CS_CLASSDC" */ /* Initialize the window dimensions. */ WindowObject->WindowRect.left = x; @@ -496,7 +561,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->ClientRect = WindowObject->WindowRect; /* FIXME: Initialize the window menu. */ - + /* Initialize the window's scrollbars */ if (dwStyle & WS_VSCROLL) SCROLL_CreateScrollBar(WindowObject, SB_VERT); @@ -556,6 +621,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->ClientRect.left, WindowObject->ClientRect.bottom - WindowObject->ClientRect.top); + DPRINT("NtUserCreateWindow(): About to send WM_SIZE\n"); W32kCallWindowProc(NULL, WindowObject->Self, WM_SIZE, SIZE_RESTORED, lParam); @@ -623,7 +689,7 @@ NtUserDeferWindowPos(HDWP WinPosInfo, BOOLEAN STDCALL NtUserDestroyWindow(HWND Wnd) { - UNIMPLEMENTED + W32kGraphicsCheck(FALSE); return 0; } @@ -734,11 +800,9 @@ NtUserGetOpenClipboardWindow(VOID) } DWORD STDCALL -NtUserGetWindowDC(DWORD Unknown0) +NtUserGetWindowDC(HWND hWnd) { - UNIMPLEMENTED - - return 0; + return NtUserGetDCEx( hWnd, 0, DCX_USESTYLE | DCX_WINDOW ); } DWORD STDCALL @@ -768,17 +832,79 @@ NtUserLockWindowUpdate(DWORD Unknown0) return 0; } -DWORD STDCALL -NtUserMoveWindow(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5) +BOOL STDCALL +NtUserMoveWindow( + HWND hWnd, + int X, + int Y, + int nWidth, + int nHeight, + BOOL bRepaint) { - UNIMPLEMENTED + PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd); + ULONG uStyle, uExStyle; + WINDOWPOS pWinPos; - return 0; + if (!Window) return FALSE; + + uStyle = Window->Style; + uExStyle = Window->ExStyle; + pWinPos.hwnd = hWnd; + + pWinPos.x = X; + pWinPos.y = Y; + if (nWidth > NtUserGetSystemMetrics(SM_CXMIN)) + pWinPos.cx = pWinPos.x + nWidth; + else + pWinPos.cx = pWinPos.x + NtUserGetSystemMetrics(SM_CXMIN); + + if (nHeight > NtUserGetSystemMetrics(SM_CYMIN)) + pWinPos.cy = pWinPos.x + nHeight; + else + pWinPos.cy = pWinPos.y + NtUserGetSystemMetrics(SM_CYMIN); + NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pWinPos); + + Window->WindowRect.top = Window->ClientRect.top = pWinPos.y; + Window->WindowRect.left = Window->ClientRect.left = pWinPos.x; + Window->WindowRect.bottom = Window->ClientRect.bottom = pWinPos.cy; + Window->WindowRect.right = Window->ClientRect.right = pWinPos.cx; + + if (!(uStyle & WS_THICKFRAME)) + { + Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYFIXEDFRAME); + Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYFIXEDFRAME); + Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXFIXEDFRAME); + Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXFIXEDFRAME); + } + else + { + Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYSIZEFRAME); + Window->ClientRect.bottom -= NtUserGetSystemMetrics(SM_CYSIZEFRAME); + Window->ClientRect.left += NtUserGetSystemMetrics(SM_CXSIZEFRAME); + Window->ClientRect.right -= NtUserGetSystemMetrics(SM_CXSIZEFRAME); + } + + if (uStyle & WS_CAPTION) + Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYCAPTION); + if ( Window->Class->Class.lpszMenuName) + { + Window->ClientRect.top += NtUserGetSystemMetrics(SM_CYMENU); + } + + NtUserSendMessage(hWnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pWinPos); + + NtUserSendMessage(hWnd, WM_MOVE, 0, MAKEWORD(Window->ClientRect.left, + Window->ClientRect.top)); + + NtUserSendMessage(hWnd, WM_SIZE, 0, MAKEWORD(Window->ClientRect.right - + Window->ClientRect.left, + Window->ClientRect.bottom - + Window->ClientRect.top)); + + /* FIXME: Send WM_NCCALCSIZE */ + W32kReleaseWindowObject(Window); + if (bRepaint) NtUserSendMessage(hWnd, WM_PAINT, 0, 0); + return TRUE; } DWORD STDCALL @@ -800,15 +926,24 @@ NtUserRealChildWindowFromPoint(DWORD Unknown0, return 0; } -DWORD STDCALL -NtUserRedrawWindow(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) +NTSTATUS STDCALL +NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate, UINT flags) { - UNIMPLEMENTED + RECT SafeUpdateRect; + NTSTATUS Status; - return 0; + if (NULL != lprcUpdate) + { + Status = MmCopyFromCaller(&SafeUpdateRect, lprcUpdate, sizeof(RECT)); + if (! NT_SUCCESS(Status)) + { + return Status; + } + } + + return PaintRedrawWindow(hWnd, NULL == lprcUpdate ? NULL : &SafeUpdateRect, hrgnUpdate, + flags, 0) ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; +; } UINT STDCALL @@ -938,7 +1073,9 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index) Result = (DWORD)WindowObject->Class->Class.lpfnWndProc; break; } - + case GWL_ID: + break; + default: { DPRINT1("NtUserGetWindowLong(): Unsupported index %d\n", Index); @@ -971,18 +1108,17 @@ NtUserSetWindowPlacement(DWORD Unknown0, return 0; } -DWORD STDCALL -NtUserSetWindowPos(DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6) +BOOL +STDCALL NtUserSetWindowPos( + HWND hWnd, + HWND hWndInsertAfter, + int X, + int Y, + int cx, + int cy, + UINT uFlags) { - UNIMPLEMENTED - - return 0; + return WinPosSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); } DWORD STDCALL @@ -1023,6 +1159,18 @@ NtUserShowWindowAsync(DWORD Unknown0, return 0; } +BOOL STDCALL NtUserUpdateWindow( HWND hWnd ) +{ + PWINDOW_OBJECT pWindow = W32kGetWindowObject( hWnd); + + if (!pWindow) + return FALSE; + if (pWindow->UpdateRegion) + NtUserSendMessage( hWnd, WM_PAINT,0,0); + W32kReleaseWindowObject(pWindow); + return TRUE; +} + DWORD STDCALL NtUserUpdateLayeredWindow(DWORD Unknown0, DWORD Unknown1, diff --git a/subsys/win32k/ntuser/winsta.c b/subsys/win32k/ntuser/winsta.c index 1bec018..9833d55 100644 --- a/subsys/win32k/ntuser/winsta.c +++ b/subsys/win32k/ntuser/winsta.c @@ -847,6 +847,18 @@ W32kInitializeDesktopGraphics(VOID) NtUserAcquireOrReleaseInputOwnership(FALSE); } +VOID +W32kEndDesktopGraphics(VOID) +{ + NtUserAcquireOrReleaseInputOwnership(TRUE); + EnableMouse(FALSE); + if (NULL != ScreenDeviceContext) + { + W32kDeleteDC(ScreenDeviceContext); + ScreenDeviceContext = NULL; + } +} + HDC W32kGetScreenDC(VOID) { diff --git a/subsys/win32k/objects/bitmaps.c b/subsys/win32k/objects/bitmaps.c index f8d37ca..9a55690 100644 --- a/subsys/win32k/objects/bitmaps.c +++ b/subsys/win32k/objects/bitmaps.c @@ -4,6 +4,7 @@ #include //#include #include "../eng/handle.h" +#include #define NDEBUG #include @@ -26,7 +27,7 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest, POINTL SourcePoint; PBITMAPOBJ DestBitmapObj; PBITMAPOBJ SrcBitmapObj; - BOOL Status, SurfDestAlloc, SurfSrcAlloc; + BOOL Status, SurfDestAlloc, SurfSrcAlloc, XlateAlloc; PPALOBJ DCLogPal; PPALGDI PalDestGDI, PalSourceGDI; PXLATEOBJ XlateObj = NULL; @@ -48,6 +49,7 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest, SurfDestAlloc = FALSE; SurfSrcAlloc = FALSE; + XlateAlloc = FALSE; // Determine surfaces to be used in the bitblt SurfDest = (PSURFOBJ)AccessUserObject(DCDest->Surface); @@ -81,15 +83,17 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest, PalDestGDI = (PPALGDI)AccessInternalObject(DestPalette); PalSourceGDI = (PPALGDI)AccessInternalObject(SourcePalette); - XlateObj = (PXLATEOBJ)EngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette); + XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestGDI->Mode, PalSourceGDI->Mode, DestPalette, SourcePalette); + XlateAlloc = TRUE; } // Perform the bitblt operation - Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP); + Status = IntEngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP); - if(SurfDestAlloc == TRUE) ExFreePool(SurfDest); - if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc); + if (XlateAlloc) EngDeleteXlate(XlateObj); + if (SurfDestAlloc) ExFreePool(SurfDest); + if (SurfSrcAlloc) ExFreePool(SurfSrc); DC_ReleasePtr(hDCDest); DC_ReleasePtr(hDCSrc); diff --git a/subsys/win32k/objects/brush.c b/subsys/win32k/objects/brush.c index 1b71ec0..f64f874 100644 --- a/subsys/win32k/objects/brush.c +++ b/subsys/win32k/objects/brush.c @@ -9,6 +9,7 @@ #include //#include #include +#include #define NDEBUG #include @@ -221,17 +222,17 @@ BOOL STDCALL W32kPatBlt(HDC hDC, DestRect.top = YLeft + Height + dc->w.DCOrgY; DestRect.bottom = YLeft + dc->w.DCOrgY; } - ret = EngBitBlt(SurfObj, - NULL, - NULL, - NULL, - NULL, - &DestRect, - NULL, - NULL, - BrushObj, - NULL, - PATCOPY); + ret = IntEngBitBlt(SurfObj, + NULL, + NULL, + NULL, + NULL, + &DestRect, + NULL, + NULL, + BrushObj, + NULL, + PATCOPY); } GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); DC_ReleasePtr( hDC ); diff --git a/subsys/win32k/objects/cliprgn.c b/subsys/win32k/objects/cliprgn.c index 8ec98ac..0b00d4e 100644 --- a/subsys/win32k/objects/cliprgn.c +++ b/subsys/win32k/objects/cliprgn.c @@ -8,7 +8,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include VOID @@ -54,7 +54,7 @@ HRGN WINAPI SaveVisRgn(HDC hdc) return copy; } -INT WINAPI +INT STDCALL W32kSelectVisRgn(HDC hdc, HRGN hrgn) { int retval; diff --git a/subsys/win32k/objects/color.c b/subsys/win32k/objects/color.c index c56e447..5e82373 100644 --- a/subsys/win32k/objects/color.c +++ b/subsys/win32k/objects/color.c @@ -4,11 +4,14 @@ #include #include #include +#include #include #include +#include #include "../eng/handle.h" +#include -// #define NDEBUG +#define NDEBUG #include int COLOR_gapStart = 256; @@ -58,12 +61,16 @@ ULONG W32kGetSysColor(int nIndex) HPEN STDCALL W32kGetSysColorPen(int nIndex) { - return(W32kCreatePen(PS_SOLID, 1, COLOR_sysPalTemplate[nIndex])); + COLORREF Col; + memcpy(&Col, COLOR_sysPalTemplate + nIndex, sizeof(COLORREF)); + return(W32kCreatePen(PS_SOLID, 1, Col)); } HBRUSH STDCALL W32kGetSysColorBrush(int nIndex) { - return(W32kCreateSolidBrush(COLOR_sysPalTemplate[nIndex])); + COLORREF Col; + memcpy(&Col, COLOR_sysPalTemplate + nIndex, sizeof(COLORREF)); + return(W32kCreateSolidBrush(Col)); } //forward declarations @@ -331,7 +338,7 @@ UINT STDCALL W32kRealizePalette(HDC hDC) if(dc->w.flags != DC_MEMORY) { // Device managed DC - palPtr->logicalToSystem = EngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette); + palPtr->logicalToSystem = IntEngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette); } // GDI_ReleaseObj(dc->w.hPalette); diff --git a/subsys/win32k/objects/coord.c b/subsys/win32k/objects/coord.c index cf3b344..5b9e370 100644 --- a/subsys/win32k/objects/coord.c +++ b/subsys/win32k/objects/coord.c @@ -11,36 +11,41 @@ #include #include +#include #include #include - -//#define NDEBUG +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ -BOOL STDCALL W32kCombineTransform(LPXFORM XFormResult, - CONST LPXFORM xform1, - CONST LPXFORM xform2) +BOOL STDCALL W32kCombineTransform(LPXFORM UnsafeXFormResult, + CONST LPXFORM Unsafexform1, + CONST LPXFORM Unsafexform2) { XFORM xformTemp; + XFORM xform1, xform2; /* Check for illegal parameters */ - if (!XFormResult || !xform1 || !xform2) + if (!UnsafeXFormResult || !Unsafexform1 || !Unsafexform2) { return FALSE; } + + MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) ); + MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) ); + /* Create the result in a temporary XFORM, since xformResult may be * equal to xform1 or xform2 */ - xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21; - xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22; - xformTemp.eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21; - xformTemp.eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22; - xformTemp.eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx; - xformTemp.eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy; + xformTemp.eM11 = xform1.eM11 * xform2.eM11 + xform1.eM12 * xform2.eM21; + xformTemp.eM12 = xform1.eM11 * xform2.eM12 + xform1.eM12 * xform2.eM22; + xformTemp.eM21 = xform1.eM21 * xform2.eM11 + xform1.eM22 * xform2.eM21; + xformTemp.eM22 = xform1.eM21 * xform2.eM12 + xform1.eM22 * xform2.eM22; + xformTemp.eDx = xform1.eDx * xform2.eM11 + xform1.eDy * xform2.eM21 + xform2.eDx; + xformTemp.eDy = xform1.eDx * xform2.eM12 + xform1.eDy * xform2.eM22 + xform2.eDy; /* Copy the result to xformResult */ - *XFormResult = xformTemp; + MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) ); return TRUE; } @@ -57,13 +62,25 @@ FLOAT x, y; y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy; } +/*! + * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode, + * world transfrom, viewport origin settings for the given device context. + * \param hDC device context. + * \param Points an array of POINT structures (in/out). + * \param Count number of elements in the array of POINT structures. + * \return TRUE if success. +*/ BOOL STDCALL W32kDPtoLP(HDC hDC, - LPPOINT Points, + LPPOINT UnsafePoints, int Count) { PDC Dc; ULONG i; + LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT)); + + ASSERT(Points); + MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) ); Dc = DC_HandleToPtr (hDC); if (Dc == NULL || !Dc->w.vport2WorldValid) @@ -76,6 +93,8 @@ W32kDPtoLP(HDC hDC, CoordDPtoLP(Dc, &Points[i]); } DC_ReleasePtr( hDC ); + + MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) ); return(TRUE); } @@ -130,11 +149,23 @@ CoordLPtoDP(PDC Dc, LPPOINT Point) y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy; } +/*! + * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode, + * world transfrom, viewport origin settings for the given device context. + * \param hDC device context. + * \param Points an array of POINT structures (in/out). + * \param Count number of elements in the array of POINT structures. + * \return TRUE if success. +*/ BOOL STDCALL -W32kLPtoDP(HDC hDC, LPPOINT Points, INT Count) +W32kLPtoDP(HDC hDC, LPPOINT UnsafePoints, INT Count) { PDC Dc; ULONG i; + LPPOINT Points = (LPPOINT) ExAllocatePool( PagedPool, Count*sizeof(POINT)); + + ASSERT(Points); + MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) ); Dc = DC_HandleToPtr (hDC); if (Dc == NULL) @@ -147,16 +178,22 @@ W32kLPtoDP(HDC hDC, LPPOINT Points, INT Count) CoordLPtoDP(Dc, &Points[i]); } DC_ReleasePtr( hDC ); + MmCopyToCaller( UnsafePoints, Points, Count*sizeof(POINT) ); return(TRUE); } BOOL STDCALL W32kModifyWorldTransform(HDC hDC, - CONST LPXFORM XForm, + CONST LPXFORM UnsafeXForm, DWORD Mode) { PDC dc; + LPXFORM XForm = (LPXFORM) ExAllocatePool( PagedPool, sizeof( XFORM ) ); + + ASSERT( XForm ); + + MmCopyFromCaller( XForm, UnsafeXForm, sizeof( XFORM ) ); dc = DC_HandleToPtr (hDC); if (!dc) diff --git a/subsys/win32k/objects/dc.c b/subsys/win32k/objects/dc.c index 7727c29..d72b684 100644 --- a/subsys/win32k/objects/dc.c +++ b/subsys/win32k/objects/dc.c @@ -19,8 +19,9 @@ #include #include #include "../eng/handle.h" +#include -//#define NDEBUG +#define NDEBUG #include static GDIDEVICE PrimarySurface; @@ -85,8 +86,6 @@ INT STDCALL func_name( HDC hdc, INT mode ) \ } -VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap); - // --------------------------------------------------------- File Statics static void W32kSetDCState16(HDC hDC, HDC hDCSave); @@ -102,7 +101,6 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) { PDC NewDC, OrigDC = NULL; HBITMAP hBitmap; - SIZEL onebyone; HDC hNewDC; OrigDC = DC_HandleToPtr(hDC); @@ -139,11 +137,6 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) NewDC->DevInfo = OrigDC->DevInfo; } - // Create a 1x1 monochrome bitmap surface - onebyone.cx = 1; - onebyone.cy = 1; - NewDC->Surface = EngCreateBitmap(onebyone, 1, BMF_1BPP, 0, NULL); - /* DriverName is copied in the AllocDC routine */ if(OrigDC == NULL) { NewDC->DeviceDriver = DRIVER_FindMPDriver(NewDC->DriverName); @@ -162,7 +155,7 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) /* Create default bitmap */ if (!(hBitmap = W32kCreateBitmap( 1, 1, 1, 1, NULL ))) { - DC_ReleasePtr( hNewDC ); + DC_ReleasePtr( hNewDC ); DC_FreeDC( hNewDC ); return NULL; } @@ -170,6 +163,7 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) NewDC->w.bitsPerPixel = 1; NewDC->w.hBitmap = hBitmap; NewDC->w.hFirstBitmap = hBitmap; + NewDC->Surface = BitmapToSurf(BITMAPOBJ_HandleToPtr(hBitmap)); if(OrigDC != NULL) { @@ -184,13 +178,61 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) return hNewDC; } +static BOOL STDCALL FindDriverFileNames(PUNICODE_STRING DriverFileNames) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + UNICODE_STRING RegistryPath; + NTSTATUS Status; + + RtlInitUnicodeString(&RegistryPath, NULL); + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].Name = L"\\Device\\Video0"; + QueryTable[0].EntryContext = &RegistryPath; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, + L"VIDEO", + QueryTable, + NULL, + NULL); + if (! NT_SUCCESS(Status)) + { + DPRINT1("No \\Device\\Video0 value in DEVICEMAP\\VIDEO found\n"); + return FALSE; + } + + DPRINT("RegistryPath %S\n", RegistryPath.Buffer); + + QueryTable[0].Name = L"InstalledDisplayDrivers"; + QueryTable[0].EntryContext = DriverFileNames; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + RegistryPath.Buffer, + QueryTable, + NULL, + NULL); + RtlFreeUnicodeString(&RegistryPath); + if (! NT_SUCCESS(Status)) + { + DPRINT1("No InstalledDisplayDrivers value in service entry found\n"); + return FALSE; + } + + DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer); + + return TRUE; +} + BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, LPCWSTR Device) { - PGD_ENABLEDRIVER GDEnableDriver; + PGD_ENABLEDRIVER GDEnableDriver; HANDLE DeviceDriver; - DRVENABLEDATA DED; + DRVENABLEDATA DED; PSURFOBJ SurfObj; + UNICODE_STRING DriverFileNames; + PWSTR CurrentName; + BOOL GotDriver; /* Open the miniport driver */ if ((DeviceDriver = DRIVER_FindMPDriver(Driver)) == NULL) @@ -199,22 +241,64 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, return(FALSE); } - /* Get the DDI driver's entry point */ - /* FIXME: Retrieve DDI driver name from registry */ - if ((GDEnableDriver = DRIVER_FindDDIDriver(L"\\SystemRoot\\system32\\drivers\\vgaddi.dll")) == NULL) + /* Retrieve DDI driver names from registry */ + RtlInitUnicodeString(&DriverFileNames, NULL); + if (! FindDriverFileNames(&DriverFileNames)) { - DPRINT("FindDDIDriver failed\n"); + DPRINT("FindDriverFileNames failed\n"); return(FALSE); } - /* Call DDI driver's EnableDriver function */ - RtlZeroMemory(&DED, sizeof(DED)); + /* DriverFileNames may be a list of drivers in REG_SZ_MULTI format, scan all of + them until a good one found */ + CurrentName = DriverFileNames.Buffer; + GotDriver = FALSE; + while (! GotDriver && CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) + { + /* Get the DDI driver's entry point */ + GDEnableDriver = DRIVER_FindDDIDriver(CurrentName); + if (NULL == GDEnableDriver) + { + DPRINT("FindDDIDriver failed for %S\n", CurrentName); + } + else + { + /* Call DDI driver's EnableDriver function */ + RtlZeroMemory(&DED, sizeof(DED)); - if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED)) + if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED)) + { + DPRINT("DrvEnableDriver failed for %S\n", CurrentName); + } + else + { + GotDriver = TRUE; + } + } + + if (! GotDriver) + { + /* Skip to the next name but never get past the Unicode string */ + while (L'\0' != *CurrentName && + CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) + { + CurrentName++; + } + if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) + { + CurrentName++; + } + } + } + RtlFreeUnicodeString(&DriverFileNames); + if (! GotDriver) { - DPRINT("DrvEnableDriver failed\n"); - return(FALSE); + DPRINT("No suitable driver found\n"); + return FALSE; } + + DPRINT("Display driver %S loaded\n", DriverName); + DPRINT("Building DDI Functions\n"); /* Construct DDI driver function dispatch table */ @@ -267,8 +351,10 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, PrimarySurface.Handle = PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.PDev); - SurfObj = (PSURFOBJ)AccessUserObject(PrimarySurface.Handle); + SurfObj = (PSURFOBJ)AccessUserObject((ULONG) PrimarySurface.Handle); SurfObj->dhpdev = PrimarySurface.PDev; + + return TRUE; } HDC STDCALL W32kCreateDC(LPCWSTR Driver, @@ -276,9 +362,10 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver, LPCWSTR Output, CONST PDEVMODEW InitData) { - HDC hNewDC; - PDC NewDC; - HDC hDC = NULL; + HDC hNewDC; + PDC NewDC; + HDC hDC = NULL; + PSURFGDI SurfGDI; /* Check for existing DC object */ if ((hNewDC = DC_FindOpenDC(Driver)) != NULL) @@ -323,19 +410,21 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver, /* FIXME: get mode selection information from somewhere */ NewDC->DMW.dmLogPixels = 96; - NewDC->DMW.dmBitsPerPel = 4; - NewDC->DMW.dmPelsWidth = 640; - NewDC->DMW.dmPelsHeight = 480; + SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) PrimarySurface.Handle); + NewDC->DMW.dmBitsPerPel = SurfGDI->BitsPerPixel; + NewDC->DMW.dmPelsWidth = SurfGDI->SurfObj.sizlBitmap.cx; + NewDC->DMW.dmPelsHeight = SurfGDI->SurfObj.sizlBitmap.cy; NewDC->DMW.dmDisplayFlags = 0; NewDC->DMW.dmDisplayFrequency = 0; - NewDC->w.bitsPerPixel = 4; // FIXME: set this here?? + NewDC->w.bitsPerPixel = SurfGDI->BitsPerPixel; // FIXME: set this here?? NewDC->w.hPalette = NewDC->DevInfo.hpalDefault; DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel); - NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, 640, 480); + NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, SurfGDI->SurfObj.sizlBitmap.cx, + SurfGDI->SurfObj.sizlBitmap.cy); DC_ReleasePtr( hNewDC ); /* Initialize the DC state */ @@ -405,8 +494,10 @@ BOOL STDCALL W32kDeleteDC(HDC DCHandle) W32kSelectObject (DCHandle, STOCK_WHITE_BRUSH); W32kSelectObject (DCHandle, STOCK_SYSTEM_FONT); DC_LockDC (DCHandle); W32kSelectObject does not recognize stock objects yet */ + BITMAPOBJ_ReleasePtr(DCToDelete->w.hBitmap); if (DCToDelete->w.flags & DC_MEMORY) { + EngDeleteSurface (DCToDelete->Surface); W32kDeleteObject (DCToDelete->w.hFirstBitmap); } } @@ -929,15 +1020,14 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) { HGDIOBJ objOrg; BITMAPOBJ *pb; - PSURFOBJ surfobj; - PSURFGDI surfgdi; PDC dc; PPENOBJ pen; PBRUSHOBJ brush; PXLATEOBJ XlateObj; PPALGDI PalGDI; WORD objectMagic; - ULONG NumColors; + COLORREF *ColorMap; + ULONG NumColors, Index; if(!hDC || !hGDIObj) return NULL; @@ -953,49 +1043,52 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) dc->w.hPen = hGDIObj; // Convert the color of the pen to the format of the DC - PalGDI = (PPALGDI)AccessInternalObject(dc->w.hPalette); - if( PalGDI ){ - XlateObj = (PXLATEOBJ)EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); + PalGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette); + if( PalGDI ){ + XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); pen = GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); - if( pen ){ - pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); - } - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); - } + if( pen ){ + pen->logpen.lopnColor = XLATEOBJ_iXlate(XlateObj, pen->logpen.lopnColor); + } + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + EngDeleteXlate(XlateObj); + } break; + case GO_BRUSH_MAGIC: objOrg = (HGDIOBJ)dc->w.hBrush; dc->w.hBrush = (HBRUSH) hGDIObj; // Convert the color of the brush to the format of the DC - PalGDI = (PPALGDI)AccessInternalObject(dc->w.hPalette); - if( PalGDI ){ - XlateObj = (PXLATEOBJ)EngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); + PalGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette); + if( PalGDI ){ + XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); brush = GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); - if( brush ){ - brush->iSolidColor = XLATEOBJ_iXlate(XlateObj, brush->logbrush.lbColor); - } - GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC); - } + if( brush ){ + brush->iSolidColor = XLATEOBJ_iXlate(XlateObj, brush->logbrush.lbColor); + } + GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC); + EngDeleteXlate(XlateObj); + } break; - case GO_FONT_MAGIC: + + case GO_FONT_MAGIC: objOrg = (HGDIOBJ)dc->w.hFont; dc->w.hFont = (HFONT) hGDIObj; + TextIntRealizeFont(dc->w.hFont); break; + case GO_BITMAP_MAGIC: // must be memory dc to select bitmap if (!(dc->w.flags & DC_MEMORY)) return NULL; objOrg = (HGDIOBJ)dc->w.hBitmap; - // setup mem dc for drawing into bitmap - pb = BITMAPOBJ_HandleToPtr (hGDIObj); - dc->w.hBitmap = CreateGDIHandle(sizeof( SURFGDI ), sizeof( SURFOBJ )); // Assign the DC's bitmap - - surfobj = (PSURFOBJ) AccessUserObject( dc->w.hBitmap ); - surfgdi = (PSURFGDI) AccessInternalObject( dc->w.hBitmap ); - BitmapToSurf(hDC, surfgdi, surfobj, pb); // Put the bitmap in a surface - - dc->Surface = dc->w.hBitmap; + /* Release the old bitmap, lock the new one and convert it to a SURF */ + EngDeleteSurface(dc->Surface); + BITMAPOBJ_ReleasePtr(objOrg); + dc->w.hBitmap = hGDIObj; + pb = BITMAPOBJ_HandleToPtr(hGDIObj); + dc->Surface = BitmapToSurf(pb); // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null] if(pb->dib) @@ -1008,11 +1101,19 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; } - dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, pb->ColorMap, 0, 0, 0); + ColorMap = ExAllocatePool(PagedPool, sizeof(COLORREF) * NumColors); + for (Index = 0; Index < NumColors; Index++) + { + ColorMap[Index] = RGB(pb->ColorMap[Index].rgbRed, + pb->ColorMap[Index].rgbGreen, + pb->ColorMap[Index].rgbBlue); + } + dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, (ULONG *) ColorMap, 0, 0, 0); + ExFreePool(ColorMap); } else - if((pb->dib->dsBmih.biBitCount > 8) && (pb->dib->dsBmih.biBitCount < 24)) + if(16 == pb->dib->dsBmih.biBitCount) { - dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0); + dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0x7c00, 0x03e0, 0x001f); } else if(pb->dib->dsBmih.biBitCount >= 24) { @@ -1022,6 +1123,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel; } break; + #if UPDATEREGIONS case GO_REGION_MAGIC: /* objOrg = (HGDIOBJ)hDC->region; */ @@ -1225,7 +1327,7 @@ void DC_InitDC(HDC DCHandle) // W32kRealizeDefaultPalette(DCHandle); W32kSelectObject(DCHandle, W32kGetStockObject( WHITE_BRUSH )); - //W32kSelectObject(DCHandle, hPen); + W32kSelectObject(DCHandle, W32kGetStockObject( BLACK_PEN )); //W32kSelectObject(DCHandle, hFont); // CLIPPING_UpdateGCRegion(DCToInit); diff --git a/subsys/win32k/objects/dib.c b/subsys/win32k/objects/dib.c index 2e2e86e..869cad6 100644 --- a/subsys/win32k/objects/dib.c +++ b/subsys/win32k/objects/dib.c @@ -3,11 +3,12 @@ #include #include #include -#include #include "../eng/handle.h" #include +#include -VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap); +#define NDEBUG +#include UINT STDCALL W32kSetDIBColorTable(HDC hDC, UINT StartIndex, @@ -97,13 +98,11 @@ INT STDCALL W32kSetDIBits(HDC hDC, lpRGB = &bmi->bmiColors[0]; // Create a temporary surface for the destination bitmap - DestBitmap = (HBITMAP)CreateGDIHandle(sizeof(SURFGDI), sizeof(SURFOBJ)); + DestBitmap = BitmapToSurf(bitmap); DestSurf = (PSURFOBJ) AccessUserObject( DestBitmap ); DestGDI = (PSURFGDI) AccessInternalObject( DestBitmap ); - BitmapToSurf(hDC, DestGDI, DestSurf, bitmap); - // Create source surface SourceSize.cx = bmi->bmiHeader.biWidth; SourceSize.cy = abs(bmi->bmiHeader.biHeight); @@ -134,7 +133,7 @@ INT STDCALL W32kSetDIBits(HDC hDC, DIB_Palette = BuildDIBPalette(bmi, &DIB_Palette_Type); // Determine XLATEOBJ for color translation - XlateObj = EngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette); + XlateObj = IntEngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette); // Zero point ZeroPoint.x = 0; @@ -155,6 +154,8 @@ INT STDCALL W32kSetDIBits(HDC hDC, } // Clean up + EngDeleteXlate(XlateObj); + EngDeletePalette(DIB_Palette); EngDeleteSurface(SourceBitmap); EngDeleteSurface(DestBitmap); @@ -351,7 +352,7 @@ HBITMAP STDCALL W32kCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header, } else { - DbgPrint("(%ld): wrong size for data\n", data->bmiHeader.biSize ); + DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize ); return 0; } } @@ -426,7 +427,7 @@ HBITMAP DIB_CreateDIBSection( UINT Entries = 0; BITMAP bm; - DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", + DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB"); @@ -448,7 +449,7 @@ HBITMAP DIB_CreateDIBSection( if (section) /* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, 0L, offset, totalSize); */ - DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n"); + DPRINT("DIB_CreateDIBSection: Cannot yet handle section DIBs\n"); else if (ovr_pitch && offset) bm.bmBits = (LPVOID) offset; else { @@ -529,7 +530,7 @@ HBITMAP DIB_CreateDIBSection( // Clean up in case of errors if (!res || !bmp || !dib || !bm.bmBits) { - DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits); + DPRINT("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits); /* if (bm.bmBits) { if (section) @@ -656,7 +657,7 @@ int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width, *compr = 0; return 0; } - DbgPrint("(%ld): wrong size for header\n", header->biSize ); + DPRINT("(%ld): wrong size for header\n", header->biSize ); return -1; } diff --git a/subsys/win32k/objects/fillshap.c b/subsys/win32k/objects/fillshap.c index a5e424e..d387975 100644 --- a/subsys/win32k/objects/fillshap.c +++ b/subsys/win32k/objects/fillshap.c @@ -6,8 +6,9 @@ #include #include #include +#include -// #define NDEBUG +#define NDEBUG #include BOOL @@ -51,15 +52,136 @@ W32kPie(HDC hDC, UNIMPLEMENTED; } +//ALTERNATE Selects alternate mode (fills the area between odd-numbered and even-numbered +//polygon sides on each scan line). +//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and +//even-numbered polygon sides on each scan line. That is, GDI fills the area between the +//first and second side, between the third and fourth side, and so on. +extern BOOL FillPolygon_ALTERNATE(SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj, + MIX RopMode, + CONST PPOINT Points, + int Count, + RECTL BoundRect, + int OrigX, + int OrigY); + + +//WINDING Selects winding mode (fills any region with a nonzero winding value). +//When the fill mode is WINDING, GDI fills any region that has a nonzero winding value. +//This value is defined as the number of times a pen used to draw the polygon would go around the region. +//The direction of each edge of the polygon is important. +extern BOOL FillPolygon_WINDING(SURFOBJ *SurfObj, + PBRUSHOBJ BrushObj,MIX RopMode, + CONST PPOINT Points, + int Count, + RECTL BoundRect, + int OrigX, + int OrigY); + +//This implementation is blatantly ripped off from W32kRectangle BOOL STDCALL W32kPolygon(HDC hDC, - CONST PPOINT Points, - int Count) + CONST PPOINT Points, + int Count) { - UNIMPLEMENTED; + DC *dc = DC_HandleToPtr(hDC); + SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface); + PBRUSHOBJ OutBrushObj, FillBrushObj; + BOOL ret; + PRECTL RectBounds; + PENOBJ *pen; + RECTL DestRect; + int CurrentPoint; + + DPRINT("In W32kPolygon()\n"); + + if(0 == dc) + return FALSE; + + if(0 == Points) + return FALSE; + + if (2 > Count) + return FALSE; + + RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + //ei not yet implemented ASSERT(RectBounds); + + DestRect.bottom = Points[0].y + dc->w.DCOrgY + 1; + DestRect.top = Points[0].y + dc->w.DCOrgY; + DestRect.right = Points[0].y + dc->w.DCOrgX; + DestRect.left = Points[0].y + dc->w.DCOrgX + 1; + + + + if(PATH_IsPathOpen(dc->w.path)) + { + ret = PATH_Polygon(hDC, Points, Count); + } + else + { + //Get the current pen. + pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); + ASSERT(pen); + OutBrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC ); + + // Draw the Polygon Edges with the current pen + for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint) + { + DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y + dc->w.DCOrgY); + DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y + dc->w.DCOrgY); + DestRect.right = MAX(DestRect.right, Points[CurrentPoint].y + dc->w.DCOrgX); + DestRect.left = MIN(DestRect.left, Points[CurrentPoint].y + dc->w.DCOrgX); + }//for + + //Now fill the polygon with the current brush. + FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); + // determine the fill mode to fill the polygon. + if (dc->w.polyFillMode == WINDING) + ret = FillPolygon_WINDING(SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect, dc->w.DCOrgX, dc->w.DCOrgY); + else//default + ret = FillPolygon_ALTERNATE(SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect, dc->w.DCOrgX, dc->w.DCOrgY); + // Draw the Polygon Edges with the current pen + for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint) + { + POINT To,From; + //Let CurrentPoint be i + //if i+1 > Count, Draw a line from Points[i] to Points[0] + //Draw a line from Points[i] to Points[i+1] + if (CurrentPoint + 1 >= Count) + { + To = Points[CurrentPoint]; + From = Points[0]; + } + else + { + From = Points[CurrentPoint]; + To = Points[CurrentPoint + 1]; + } + DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y ); + ret = EngLineTo(SurfObj, + NULL, // ClipObj, + OutBrushObj, + From.x + dc->w.DCOrgX, + From.y + dc->w.DCOrgY, + To.x + dc->w.DCOrgX, + To.y + dc->w.DCOrgY, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + }//for + GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); + }// else + + GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + DC_ReleasePtr( hDC ); + return ret; } + BOOL STDCALL W32kPolyPolygon(HDC hDC, @@ -106,33 +228,33 @@ W32kRectangle(HDC hDC, TopRect += dc->w.DCOrgY; BottomRect += dc->w.DCOrgY; - ret = EngLineTo(SurfObj, - NULL, // ClipObj, - BrushObj, - LeftRect, TopRect, RightRect, TopRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX - - ret = EngLineTo(SurfObj, - NULL, // ClipObj, - BrushObj, - RightRect, TopRect, RightRect, BottomRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX - - ret = EngLineTo(SurfObj, - NULL, // ClipObj, - BrushObj, - LeftRect, BottomRect, RightRect, BottomRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX - - ret = EngLineTo(SurfObj, - NULL, // ClipObj, - BrushObj, - LeftRect, TopRect, LeftRect, BottomRect, - RectBounds, // Bounding rectangle - dc->w.ROPmode); // MIX */ + ret = IntEngLineTo(SurfObj, + NULL, // ClipObj, + BrushObj, + LeftRect, TopRect, RightRect, TopRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = IntEngLineTo(SurfObj, + NULL, // ClipObj, + BrushObj, + RightRect, TopRect, RightRect, BottomRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = IntEngLineTo(SurfObj, + NULL, // ClipObj, + BrushObj, + LeftRect, BottomRect, RightRect, BottomRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX + + ret = IntEngLineTo(SurfObj, + NULL, // ClipObj, + BrushObj, + LeftRect, TopRect, LeftRect, BottomRect, + RectBounds, // Bounding rectangle + dc->w.ROPmode); // MIX */ // FIXME: BrushObj is obtained above; decide which one is correct BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC); diff --git a/subsys/win32k/objects/gdiobj.c b/subsys/win32k/objects/gdiobj.c index f7c85c4..9fe343f 100644 --- a/subsys/win32k/objects/gdiobj.c +++ b/subsys/win32k/objects/gdiobj.c @@ -8,6 +8,7 @@ #undef WIN32_LEAN_AND_MEAN #include #include +#include #include #include #include @@ -51,7 +52,7 @@ static LOGPEN BlackPen = static LOGPEN NullPen = { PS_NULL, { 0, 0 }, 0 }; -static LOGFONT OEMFixedFont = +static LOGFONTW OEMFixedFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET, 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" }; @@ -60,38 +61,38 @@ static LOGFONT OEMFixedFont = segment, and (c) Solaris assembler is stupid. */ static UINT align_OEMFixedFont = 1; -static LOGFONT AnsiFixedFont = +static LOGFONTW AnsiFixedFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" }; static UINT align_AnsiFixedFont = 1; -static LOGFONT AnsiVarFont = +static LOGFONTW AnsiVarFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; static UINT align_AnsiVarFont = 1; -static LOGFONT SystemFont = +static LOGFONTW SystemFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"System" }; static UINT align_SystemFont = 1; -static LOGFONT DeviceDefaultFont = +static LOGFONTW DeviceDefaultFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"" }; static UINT align_DeviceDefaultFont = 1; -static LOGFONT SystemFixedFont = +static LOGFONTW SystemFixedFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, L"" }; static UINT align_SystemFixedFont = 1; /* FIXME: Is this correct? */ -static LOGFONT DefaultGuiFont = +static LOGFONTW DefaultGuiFont = { 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"MS Sans Serif" }; @@ -277,6 +278,9 @@ BOOL GDIOBJ_FreeObj(HGDIOBJ hObj, WORD Magic, DWORD Flag) case GO_BRUSH_MAGIC: case GO_FONT_MAGIC: break; + case GO_DCE_MAGIC: + bRet = DCE_InternalDelete( (PDCE) Obj ); + break; } handleEntry->hProcessId = 0; ExFreePool (handleEntry->pObject); @@ -521,18 +525,17 @@ VOID CreateStockObjects(void) StockObjects[NULL_PEN] = W32kCreatePenIndirect(&NullPen); GDIOBJ_MarkObjectGlobal(StockObjects[NULL_PEN]); - StockObjects[OEM_FIXED_FONT] = W32kCreateFontIndirect(&OEMFixedFont); + (void) TextIntCreateFontIndirect(&OEMFixedFont, &StockObjects[OEM_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[OEM_FIXED_FONT]); - StockObjects[ANSI_FIXED_FONT] = W32kCreateFontIndirect(&AnsiFixedFont); + (void) TextIntCreateFontIndirect(&AnsiFixedFont, &StockObjects[ANSI_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[ANSI_FIXED_FONT]); - StockObjects[SYSTEM_FONT] = W32kCreateFontIndirect(&SystemFont); + (void) TextIntCreateFontIndirect(&SystemFont, &StockObjects[SYSTEM_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FONT]); - StockObjects[DEVICE_DEFAULT_FONT] = - W32kCreateFontIndirect(&DeviceDefaultFont); + (void) TextIntCreateFontIndirect(&DeviceDefaultFont, &StockObjects[DEVICE_DEFAULT_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[DEVICE_DEFAULT_FONT]); - StockObjects[SYSTEM_FIXED_FONT] = W32kCreateFontIndirect(&SystemFixedFont); + (void) TextIntCreateFontIndirect(&SystemFixedFont, &StockObjects[SYSTEM_FIXED_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[SYSTEM_FIXED_FONT]); - StockObjects[DEFAULT_GUI_FONT] = W32kCreateFontIndirect(&DefaultGuiFont); + (void) TextIntCreateFontIndirect(&DefaultGuiFont, &StockObjects[DEFAULT_GUI_FONT]); GDIOBJ_MarkObjectGlobal(StockObjects[DEFAULT_GUI_FONT]); StockObjects[DEFAULT_PALETTE] = (HGDIOBJ*)PALETTE_Init(); diff --git a/subsys/win32k/objects/icm.c b/subsys/win32k/objects/icm.c index 12720fe..4b81c8e 100644 --- a/subsys/win32k/objects/icm.c +++ b/subsys/win32k/objects/icm.c @@ -5,7 +5,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include BOOL diff --git a/subsys/win32k/objects/line.c b/subsys/win32k/objects/line.c index c4b1ac1..a71e204 100644 --- a/subsys/win32k/objects/line.c +++ b/subsys/win32k/objects/line.c @@ -2,16 +2,19 @@ #undef WIN32_LEAN_AND_MEAN #include +#include #include #include #include #include #include #include +#include -// #define NDEBUG +#define NDEBUG #include + BOOL STDCALL W32kAngleArc(HDC hDC, @@ -109,6 +112,9 @@ W32kLineTo(HDC hDC, BOOL ret; PPENOBJ pen; PROSRGNDATA reg; +#ifndef TODO + RECT defaultrect; +#endif if(!dc) return FALSE; @@ -120,18 +126,28 @@ W32kLineTo(HDC hDC, ASSERT( pen ); // not yet implemented ASSERT( reg ); +#ifndef TODO + if (NULL == reg) { + defaultrect.left = 0; + defaultrect.top = 0; + defaultrect.right = 640; + defaultrect.bottom = 480; + + reg = &defaultrect; + } +#endif /* Draw the line according to the DC origin */ - ret = EngLineTo(SurfObj, - NULL, // ClipObj - PenToBrushObj(dc, pen), - dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY, - dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd, - reg, // Bounding rectangle - dc->w.ROPmode); // MIX - - GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); - GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + ret = IntEngLineTo(SurfObj, + NULL, // ClipObj + PenToBrushObj(dc, pen), + dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY, + dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd, + reg, // Bounding rectangle + dc->w.ROPmode); // MIX + + GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); } if(ret) { dc->w.CursPosX = XEnd; @@ -244,7 +260,72 @@ W32kPolyline(HDC hDC, CONST LPPOINT pt, int Count) { - UNIMPLEMENTED; + DC *dc = DC_HandleToPtr(hDC); + SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface); + BOOL ret; + LONG i; + PPENOBJ pen; + PROSRGNDATA reg; + POINT *pts; + + if (!dc) + return(FALSE); + + if(PATH_IsPathOpen(dc->w.path)) + { + ret = PATH_Polyline(hDC, pt, Count); + } + else + { + pen = (PPENOBJ) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC); + reg = (PROSRGNDATA)GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC); + + ASSERT( pen ); + + //FIXME: Do somthing with reg... + + //Allocate "Count" bytes of memory to hold a safe copy of pt + if (!(pts=ExAllocatePool(NonPagedPool, sizeof(POINT) * Count))) + { + GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + DC_ReleasePtr( hDC ); + return(FALSE); + } + + //safly copy pt to local version + if (STATUS_SUCCESS!=MmCopyFromCaller(pts, pt, sizeof(POINT) * Count)) + { + ExFreePool(pts); + GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + DC_ReleasePtr( hDC ); + return(FALSE); + } + + //offset the array of point by the dc->w.DCOrg + for(i=0; iw.DCOrgX; + pts[i].y += dc->w.DCOrgY; + } + + //get IntEngPolyline to do the drawing. + ret = IntEngPolyline(SurfObj, + NULL, + PenToBrushObj(dc, pen), + pts, + Count, + dc->w.ROPmode); + + //Clean up + ExFreePool(pts); + GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC ); + GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC); + } + + DC_ReleasePtr( hDC ); + return(ret); } BOOL diff --git a/subsys/win32k/objects/metafile.c b/subsys/win32k/objects/metafile.c index 441c288..073be0a 100644 --- a/subsys/win32k/objects/metafile.c +++ b/subsys/win32k/objects/metafile.c @@ -5,7 +5,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include HENHMETAFILE diff --git a/subsys/win32k/objects/objconv.c b/subsys/win32k/objects/objconv.c index c3582a1..fc8c8f9 100644 --- a/subsys/win32k/objects/objconv.c +++ b/subsys/win32k/objects/objconv.c @@ -13,7 +13,7 @@ #include #include "../eng/objects.h" -//#define NDEBUG +#define NDEBUG #include @@ -30,32 +30,22 @@ PBRUSHOBJ PenToBrushObj(PDC dc, PENOBJ *pen) return BrushObj; } -VOID BitmapToSurf(HDC hdc, PSURFGDI SurfGDI, PSURFOBJ SurfObj, PBITMAPOBJ Bitmap) +HBITMAP BitmapToSurf(PBITMAPOBJ BitmapObj) { - ASSERT( SurfGDI ); - if( Bitmap ){ - if(Bitmap->dib) - { - SurfGDI->BitsPerPixel = Bitmap->dib->dsBm.bmBitsPixel; - SurfObj->lDelta = Bitmap->dib->dsBm.bmWidthBytes; - SurfObj->pvBits = Bitmap->dib->dsBm.bmBits; - SurfObj->cjBits = Bitmap->dib->dsBm.bmHeight * Bitmap->dib->dsBm.bmWidthBytes; - } else { - SurfGDI->BitsPerPixel = Bitmap->bitmap.bmBitsPixel; - SurfObj->lDelta = Bitmap->bitmap.bmWidthBytes; - SurfObj->pvBits = Bitmap->bitmap.bmBits; - SurfObj->cjBits = Bitmap->bitmap.bmHeight * Bitmap->bitmap.bmWidthBytes; - } - SurfObj->sizlBitmap = Bitmap->size; // FIXME: alloc memory for our own struct? - } - - SurfObj->dhsurf = NULL; - SurfObj->hsurf = NULL; - SurfObj->dhpdev = NULL; - SurfObj->hdev = NULL; - SurfObj->pvScan0 = SurfObj->pvBits; // start of bitmap - SurfObj->iUniq = 0; // not sure.. - SurfObj->iBitmapFormat = BitmapFormat(SurfGDI->BitsPerPixel, BI_RGB); - SurfObj->iType = STYPE_BITMAP; - SurfObj->fjBitmap = BMF_TOPDOWN; + HBITMAP BitmapHandle; + + if (NULL != BitmapObj->dib) + { + BitmapHandle = EngCreateBitmap(BitmapObj->size, BitmapObj->dib->dsBm.bmWidthBytes, + BitmapFormat(BitmapObj->dib->dsBm.bmBitsPixel, BI_RGB), + 0, BitmapObj->dib->dsBm.bmBits); + } + else + { + BitmapHandle = EngCreateBitmap(BitmapObj->size, BitmapObj->bitmap.bmWidthBytes, + BitmapFormat(BitmapObj->bitmap.bmBitsPixel, BI_RGB), + 0, BitmapObj->bitmap.bmBits); + } + + return BitmapHandle; } diff --git a/subsys/win32k/objects/paint.c b/subsys/win32k/objects/paint.c index f1aa922..b0d688f 100644 --- a/subsys/win32k/objects/paint.c +++ b/subsys/win32k/objects/paint.c @@ -6,7 +6,7 @@ //#include #include -// #define NDEBUG +#define NDEBUG #include BOOL diff --git a/subsys/win32k/objects/path.c b/subsys/win32k/objects/path.c index c61ec65..65e0e0f 100644 --- a/subsys/win32k/objects/path.c +++ b/subsys/win32k/objects/path.c @@ -12,7 +12,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include #define NUM_ENTRIES_INITIAL 16 /* Initial size of points / flags arrays */ diff --git a/subsys/win32k/objects/pen.c b/subsys/win32k/objects/pen.c index d46cc60..63cf49f 100644 --- a/subsys/win32k/objects/pen.c +++ b/subsys/win32k/objects/pen.c @@ -3,7 +3,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include HPEN diff --git a/subsys/win32k/objects/polyfill.c b/subsys/win32k/objects/polyfill.c new file mode 100644 index 0000000..e57b5d2 --- /dev/null +++ b/subsys/win32k/objects/polyfill.c @@ -0,0 +1,548 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Various Polygon Filling routines for Polygon() + * FILE: subsys/win32k/objects/polyfill.c + * PROGRAMER: Mark Tempel + * REVISION HISTORY: + * 21/2/2003: Created + */ + +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +#define PFILL_EDGE_ALLOC_TAG 0x45465044 + +/* +** This struct is used for book keeping during polygon filling routines. +*/ +typedef struct _tagPFILL_EDGE +{ + /*Basic line information*/ + int FromX; + int FromY; + int ToX; + int ToY; + int dx; + int dy; + int MinX; + int MaxX; + int MinY; + int MaxY; + + /*Active Edge List information*/ + int XIntercept; + int ErrorTerm; + int ErrorTermAdjUp; + int ErrorTermAdjDown; + int XPerY; + int Direction; + + /* The next edge in the Edge List*/ + struct _tagPFILL_EDGE * pNext; +} PFILL_EDGE, *PPFILL_EDGE; + +typedef PPFILL_EDGE PFILL_EDGE_LIST; + +static void DEBUG_PRINT_EDGELIST(PFILL_EDGE_LIST list) +{ + PPFILL_EDGE pThis = list; + if (0 == list) + { + DPRINT("List is NULL\n"); + return; + } + + while(0 != pThis) + { + DPRINT("EDGE: (%d, %d) to (%d, %d)\n", pThis->FromX, pThis->FromY, pThis->ToX, pThis->ToY); + pThis = pThis->pNext; + } +} + +/* +** Hide memory clean up. +*/ +static void POLYGONFILL_DestroyEdge(PPFILL_EDGE pEdge) +{ + if (0 != pEdge) + EngFreeMem(pEdge); +} + +/* +** Clean up a list. +*/ +static void POLYGONFILL_DestroyEdgeList(PFILL_EDGE_LIST list) +{ + PPFILL_EDGE pThis = 0; + PPFILL_EDGE pNext = 0; + + pThis = list; + while (0 != pThis) + { + //DPRINT("Destroying Edge\n"); + pNext = pThis->pNext; + POLYGONFILL_DestroyEdge(pThis); + pThis = pNext; + } + +} + +/* +** This makes and initiaizes an Edge struct for a line between two points. +*/ +static PPFILL_EDGE POLYGONFILL_MakeEdge(POINT From, POINT To) +{ + PPFILL_EDGE rc = (PPFILL_EDGE)EngAllocMem(FL_ZERO_MEMORY, sizeof(PFILL_EDGE), PFILL_EDGE_ALLOC_TAG); + + if (0 != rc) + { + //DPRINT("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y); + //Now Fill the struct. + rc->FromX = From.x; + rc->FromY = From.y; + rc->ToX = To.x; + rc->ToY = To.y; + + rc->dx = To.x - From.x; + rc->dy = To.y - From.y; + rc->MinX = MIN(To.x, From.x); + rc->MaxX = MAX(To.x, From.x); + rc->MinY = MIN(To.y, From.y); + rc->MaxY = MAX(To.y, From.y); + + if (rc->MinY == To.y) + rc->XIntercept = To.x; + else + rc->XIntercept = From.x; + + rc->ErrorTermAdjDown = rc->dy; + rc->Direction = (rc->dx < 0)?(-1):(1); + + if (rc->dx >= 0) /*edge goes l to r*/ + { + rc->ErrorTerm = 0; + } + else/*edge goes r to l*/ + { + rc->ErrorTerm = -rc->dy +1; + } + + /*Now which part of the slope is greater?*/ + if (rc->dy == 0) + { + rc->XPerY = 0; + rc->ErrorTermAdjUp = 0; + } + else if (rc->dy >= rc->dx) + { + rc->XPerY = 0; + rc->ErrorTermAdjUp = rc->dx; + } + else + { + rc->XPerY = rc->dx / rc->dy; + rc->ErrorTermAdjUp = rc->dx % rc->dy; + } + + rc->pNext = 0; + } + return rc; +} +/* +** My Edge comparison routine. +** This is for scan converting polygon fill. +** Fist sort by MinY, then Minx, then slope. +** +** This comparison will help us determine which +** lines will become active first when scanning from +** top (min y) to bottom (max y). +** +** Return Value Meaning +** Negative integer element1 < element2 +** Zero element1 = element2 +** Positive integer element1 > element2 +*/ +static INT PFILL_EDGE_Compare(PPFILL_EDGE Edge1, PPFILL_EDGE Edge2) +{ + //DPRINT("In PFILL_EDGE_Compare()\n"); + if (Edge1->MinY == Edge2->MinY) + { + //DPRINT("In PFILL_EDGE_Compare() MinYs are equal\n"); + if (Edge1->MinX == Edge2->MinX) + { + if (0 == Edge2->dx || 0 == Edge1->dx) + { + return Edge1->dx - Edge2->dx; + } + else + { + return (Edge1->dy/Edge1->dx) - (Edge2->dy/Edge2->dx); + } + } + else + { + return Edge1->MinX - Edge2->MinX; + } + } + //DPRINT("In PFILL_EDGE_Compare() returning: %d\n",Edge1->MinY - Edge2->MinY); + return Edge1->MinY - Edge2->MinY; + +} + + +/* +** Insert an edge into a list keeping the list in order. +*/ +static void POLYGONFILL_ListInsert(PFILL_EDGE_LIST *list, PPFILL_EDGE NewEdge) +{ + PPFILL_EDGE pThis; + if (0 != list && 0 != NewEdge) + { + pThis = *list; + //DPRINT("In POLYGONFILL_ListInsert()\n"); + /* + ** First lets check to see if we have a new smallest value. + */ + if (0 < PFILL_EDGE_Compare(pThis, NewEdge)) + { + NewEdge->pNext = pThis; + *list = NewEdge; + return; + } + /* + ** Ok, now scan to the next spot to put this item. + */ + while (0 > PFILL_EDGE_Compare(pThis, NewEdge)) + { + if (0 == pThis->pNext) + break; + + pThis = pThis->pNext; + } + + NewEdge->pNext = pThis->pNext; + pThis->pNext = NewEdge; + //DEBUG_PRINT_EDGELIST(*list); + } +} + +/* +** Create a list of edges for a list of points. +*/ +static PFILL_EDGE_LIST POLYGONFILL_MakeEdgeList(PPOINT Points, int Count) +{ + int CurPt = 0; + int SeqNum = 0; + PPFILL_EDGE rc = 0; + PPFILL_EDGE NextEdge = 0; + + if (0 != Points && 2 <= Count) + { + //Establish the list with the first two points. + rc = POLYGONFILL_MakeEdge(Points[0],Points[1]); + if (0 == rc) return rc; + + for (CurPt = 1; CurPt < Count; ++CurPt,++SeqNum) + { + if (CurPt == Count - 1) + { + NextEdge = POLYGONFILL_MakeEdge(Points[CurPt],Points[0]); + } + else + { + NextEdge = POLYGONFILL_MakeEdge(Points[CurPt],Points[CurPt + 1]); + } + if (0 != NextEdge) + { + POLYGONFILL_ListInsert(&rc, NextEdge); + } + else + { + DPRINT("Out Of MEMORY!! NextEdge = 0\n"); + } + } + } + return rc; +} + + +/* +** This slow routine uses the data stored in the edge list to +** calculate the x intercepts for each line in the edge list +** for scanline Scanline. +**TODO: Get rid of this floating point arithmetic +*/ +static void POLYGONFILL_UpdateScanline(PPFILL_EDGE pEdge, int Scanline) +{ + + int Coord = 0; + float XCoord = 0; + if (0 == pEdge->dy) return; + + XCoord = (Scanline*pEdge->dx - pEdge->FromY*pEdge->dx)/pEdge->dy + pEdge->FromX; + Coord = XCoord + 0.5; + + //DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at %d\n", + // pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, Coord); + pEdge->XIntercept = Coord; + + + /*pEdge->XIntercept += pEdge->XPerY; + + if ((pEdge->ErrorTerm += pEdge->ErrorTermAdjUp) > 0) + { + pEdge->XIntercept += pEdge->Direction; + pEdge->ErrorTerm -= pEdge->ErrorTermAdjDown; + }*/ +} + +/* +** This routine removes an edge from the global edge list and inserts it into +** the active edge list (preserving the order). +** An edge is considered Active if the current scanline intersects it. +** +** Note: once an edge is no longer active, it is deleted. +*/ +static void POLYGONFILL_AECInsertInOrder(PFILL_EDGE_LIST *list, PPFILL_EDGE pEdge) +{ + BOOL Done = FALSE; + PPFILL_EDGE pThis = 0; + PPFILL_EDGE pPrev = 0; + pThis = *list; + while(0 != pThis && !Done) + { + /*pEdge goes before pThis*/ + if (pThis->XIntercept > pEdge->XIntercept) + { + if (*list == pThis) + { + *list = pEdge; + } + else + { + pPrev->pNext = pEdge; + } + pEdge->pNext = pThis; + Done = TRUE; + } + pPrev = pThis; + pThis = pThis->pNext; + } +} + +/* +** This routine reorders the Active Edge collection (list) after all +** the now inactive edges have been removed. +*/ +static void POLYGONFILL_AECReorder(PFILL_EDGE_LIST *AEC) +{ + PPFILL_EDGE pThis = 0; + PPFILL_EDGE pPrev = 0; + PPFILL_EDGE pTarg = 0; + pThis = *AEC; + + while (0 != pThis) + { + /*We are at the end of the list*/ + if (0 == pThis->pNext) + { + return; + } + + /*If the next item is out of order, pull it from the list and + re-insert it, and don't advance pThis.*/ + if (pThis->XIntercept > pThis->pNext->XIntercept) + { + pTarg = pThis->pNext; + pThis->pNext = pTarg->pNext; + pTarg->pNext = 0; + POLYGONFILL_AECInsertInOrder(AEC, pTarg); + } + else/*In order, advance pThis*/ + { + pPrev = pThis; + pThis = pThis->pNext; + } + } + +} +/* +** This method updates the Active edge collection for the scanline Scanline. +*/ +static void POLYGONFILL_UpdateActiveEdges(int Scanline, PFILL_EDGE_LIST *GEC, PFILL_EDGE_LIST *AEC) +{ + PPFILL_EDGE pThis = 0; + PPFILL_EDGE pAECLast = 0; + PPFILL_EDGE pPrev = 0; + DPRINT("In POLYGONFILL_UpdateActiveEdges() Scanline: %d\n", Scanline); + /*First scan through GEC and look for any edges that have become active*/ + pThis = *GEC; + while (0 != pThis && pThis->MinY <= Scanline) + { + //DPRINT("Moving Edge to AEC\n"); + /*Remove the edge from GEC and put it into AEC*/ + if (pThis->MinY <= Scanline) + { + /*Always peel off the front of the GEC*/ + *GEC = pThis->pNext; + + /*Now put this edge at the end of AEC*/ + if (0 == *AEC) + { + *AEC = pThis; + pThis->pNext = 0; + pAECLast = pThis; + } + else if(0 == pAECLast) + { + pAECLast = *AEC; + while(0 != pAECLast->pNext) + { + pAECLast = pAECLast->pNext; + } + + pAECLast->pNext = pThis; + pThis->pNext = 0; + pAECLast = pThis; + } + else + { + pAECLast->pNext = pThis; + pThis->pNext = 0; + pAECLast = pThis; + + } + } + + pThis = *GEC; + } + /*Now remove any edges in the AEC that are no longer active and Update the XIntercept in the AEC*/ + pThis = *AEC; + while (0 != pThis) + { + /*First check to see if this item is deleted*/ + if (pThis->MaxY <= Scanline) + { + //DPRINT("Removing Edge from AEC\n"); + if (0 == pPrev)/*First element in the list*/ + { + *AEC = pThis->pNext; + } + else + { + pPrev->pNext = pThis->pNext; + } + POLYGONFILL_DestroyEdge(pThis); + } + else/*Otherwise, update the scanline*/ + { + POLYGONFILL_UpdateScanline(pThis, Scanline); + pPrev = pThis; + } + /*List Upkeep*/ + if (0 == pPrev)/*First element in the list*/ + { + pThis = *AEC; + } + else + { + pThis = pPrev->pNext; + } + } + /*Last re Xintercept order the AEC*/ + POLYGONFILL_AECReorder(AEC); + +} + +/* +** This method fills the portion of the polygon that intersects with the scanline +** Scanline. +*/ +static void POLYGONFILL_FillScanLine(int ScanLine, PFILL_EDGE_LIST ActiveEdges, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, int OrigX, int OrigY) +{ + BOOL OnOdd = TRUE; + RECTL BoundRect; + int XInterceptOdd,XInterceptEven,ret; + PPFILL_EDGE pThis = ActiveEdges; + + while (0 != pThis) + { + if (OnOdd) + { + XInterceptOdd = pThis->XIntercept; + OnOdd = FALSE; + } + else + { + BoundRect.top = ScanLine + OrigY - 1; + BoundRect.bottom = ScanLine + OrigY + 1; + BoundRect.left = XInterceptOdd + OrigX - 2; + BoundRect.right = XInterceptEven + OrigX; + + XInterceptEven = pThis->XIntercept; + DPRINT("Fill Line (%d, %d) to (%d, %d)\n",XInterceptOdd - 1,ScanLine ,XInterceptEven - 1,ScanLine ); + ret = EngLineTo(SurfObj, + NULL, // ClipObj, + BrushObj, + XInterceptOdd + OrigX - 1, + ScanLine + OrigY, + XInterceptEven + OrigX - 1, + ScanLine + OrigY, + &BoundRect, // Bounding rectangle + RopMode); // MIX + OnOdd = TRUE; + } + pThis = pThis->pNext; + } +} + +//ALTERNATE Selects alternate mode (fills the area between odd-numbered and even-numbered +//polygon sides on each scan line). +//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and +//even-numbered polygon sides on each scan line. That is, GDI fills the area between the +//first and second side, between the third and fourth side, and so on. +BOOL FillPolygon_ALTERNATE(SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect, int OrigX, int OrigY) +{ + PFILL_EDGE_LIST list = 0; + PFILL_EDGE_LIST ActiveEdges = 0; + int ScanLine; + DPRINT("FillPolygon_ALTERNATE\n"); + + //Create Edge List. + list = POLYGONFILL_MakeEdgeList(Points, Count); + //DEBUG_PRINT_EDGELIST(list); + if (0 == list) return FALSE; + + //For each Scanline from BoundRect.bottom to BoundRect.top, + //determine line segments to draw + for (ScanLine = BoundRect.top + 1; ScanLine < BoundRect.bottom ; ++ScanLine) + { + POLYGONFILL_UpdateActiveEdges(ScanLine, &list, &ActiveEdges); + //DEBUG_PRINT_EDGELIST(ActiveEdges); + POLYGONFILL_FillScanLine(ScanLine, ActiveEdges, SurfObj, BrushObj, RopMode, OrigX, OrigY); + } + + //Free Edge List. If any are left. + POLYGONFILL_DestroyEdgeList(list); + + return TRUE; +} + +//WINDING Selects winding mode (fills any region with a nonzero winding value). +//When the fill mode is WINDING, GDI fills any region that has a nonzero winding value. +//This value is defined as the number of times a pen used to draw the polygon would go around the region. +//The direction of each edge of the polygon is important. +BOOL FillPolygon_WINDING(SURFOBJ *SurfObj, PBRUSHOBJ BrushObj,MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect, int OrigX, int OrigY) +{ + DPRINT("FillPolygon_WINDING\n"); + return FALSE; +} \ No newline at end of file diff --git a/subsys/win32k/objects/print.c b/subsys/win32k/objects/print.c index b8b4528..c9bc0ab 100644 --- a/subsys/win32k/objects/print.c +++ b/subsys/win32k/objects/print.c @@ -3,7 +3,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include INT diff --git a/subsys/win32k/objects/rect.c b/subsys/win32k/objects/rect.c index 3c88969..fdc11e3 100644 --- a/subsys/win32k/objects/rect.c +++ b/subsys/win32k/objects/rect.c @@ -4,7 +4,7 @@ #include #include -//#define NDEBUG +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ diff --git a/subsys/win32k/objects/region.c b/subsys/win32k/objects/region.c index e81184d..c71f2fe 100644 --- a/subsys/win32k/objects/region.c +++ b/subsys/win32k/objects/region.c @@ -11,7 +11,7 @@ #include -// #define NDEBUG +#define NDEBUG #include BOOL STDCALL diff --git a/subsys/win32k/objects/text.c b/subsys/win32k/objects/text.c index ded81fd..b5e7026 100644 --- a/subsys/win32k/objects/text.c +++ b/subsys/win32k/objects/text.c @@ -3,14 +3,19 @@ #undef WIN32_LEAN_AND_MEAN #include #include +#include +#include #include #include #include -#include +#include +#include FT_FREETYPE_H #include "../eng/handle.h" -// #define NDEBUG +#include + +#define NDEBUG #include FT_Library library; @@ -33,14 +38,57 @@ BOOL InitFontSupport() return FALSE; } +#ifndef TODO + W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\arial.ttf"); +#endif W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\helb____.ttf"); W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\timr____.ttf"); - DbgPrint("All fonts loaded\n"); + DPRINT("All fonts loaded\n"); return TRUE; } +static NTSTATUS +GetFontObjectsFromTextObj(PTEXTOBJ TextObj, HFONT *FontHandle, PFONTOBJ *FontObj, PFONTGDI *FontGDI) +{ + UINT i; + NTSTATUS Status = STATUS_SUCCESS; + + ASSERT(NULL != TextObj && NULL != TextObj->GDIFontHandle); + if (NULL != TextObj && NULL != TextObj->GDIFontHandle) + { + if (NT_SUCCESS(Status) && NULL != FontHandle) + { + *FontHandle = TextObj->GDIFontHandle; + } + if (NT_SUCCESS(Status) && NULL != FontObj) + { + *FontObj = AccessUserObject((ULONG) TextObj->GDIFontHandle); + if (NULL == *FontObj) + { + ASSERT(FALSE); + Status = STATUS_INVALID_HANDLE; + } + } + if (NT_SUCCESS(Status) && NULL != FontGDI) + { + *FontGDI = AccessInternalObject((ULONG) TextObj->GDIFontHandle); + if (NULL == *FontGDI) + { + ASSERT(FALSE); + Status = STATUS_INVALID_HANDLE; + } + } + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + return Status; +} + int STDCALL W32kAddFontResource(LPCWSTR Filename) @@ -62,8 +110,8 @@ W32kAddFontResource(LPCWSTR Filename) IO_STATUS_BLOCK Iosb; NewFont = (HFONT)CreateGDIHandle(sizeof( FONTGDI ), sizeof( FONTOBJ )); - FontObj = (PFONTOBJ) AccessUserObject( NewFont ); - FontGDI = (PFONTGDI) AccessInternalObject( NewFont ); + FontObj = (PFONTOBJ) AccessUserObject( (ULONG) NewFont ); + FontGDI = (PFONTGDI) AccessInternalObject( (ULONG) NewFont ); RtlCreateUnicodeString(&uFileName, (LPWSTR)Filename); @@ -74,7 +122,7 @@ W32kAddFontResource(LPCWSTR Filename) if (!NT_SUCCESS(Status)) { - DbgPrint("Could not open module file: %S\n", Filename); + DPRINT1("Could not open module file: %S\n", Filename); return 0; } @@ -82,7 +130,7 @@ W32kAddFontResource(LPCWSTR Filename) Status = NtQueryInformationFile(FileHandle, &Iosb, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation); if (!NT_SUCCESS(Status)) { - DbgPrint("Could not get file size\n"); + DPRINT1("Could not get file size\n"); return 0; } @@ -92,7 +140,7 @@ W32kAddFontResource(LPCWSTR Filename) if (buffer == NULL) { - DbgPrint("could not allocate memory for module"); + DPRINT1("could not allocate memory for module"); return 0; } @@ -100,7 +148,7 @@ W32kAddFontResource(LPCWSTR Filename) Status = NtReadFile(FileHandle, 0, 0, 0, &Iosb, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0); if (!NT_SUCCESS(Status)) { - DbgPrint("could not read module file into memory"); + DPRINT1("could not read module file into memory"); ExFreePool(buffer); return 0; } @@ -110,12 +158,12 @@ W32kAddFontResource(LPCWSTR Filename) error = FT_New_Memory_Face(library, buffer, size, 0, &face); if (error == FT_Err_Unknown_File_Format) { - DbgPrint("Unknown font file format\n"); + DPRINT1("Unknown font file format\n"); return 0; } else if (error) { - DbgPrint("Error reading font file (error code: %u)\n", error); // 48 + DPRINT1("Error reading font file (error code: %u)\n", error); // 48 return 0; } @@ -127,9 +175,8 @@ W32kAddFontResource(LPCWSTR Filename) FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent; - DbgPrint("Family name: %s\n", face->family_name); - DbgPrint("Style name: %s\n", face->style_name); - DbgPrint("Num glyphs: %u\n", face->num_glyphs); + DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name); + DPRINT("Num glyphs: %u\n", face->num_glyphs); // Add this font resource to the font table FontTable[FontsLoaded].hFont = NewFont; @@ -145,24 +192,60 @@ W32kAddFontResource(LPCWSTR Filename) return 1; } +NTSTATUS +TextIntCreateFontIndirect(CONST LPLOGFONTW lf, HFONT *NewFont) +{ + PTEXTOBJ TextObj; + NTSTATUS Status = STATUS_SUCCESS; + + *NewFont = TEXTOBJ_AllocText(); + if (NULL != *NewFont) + { + TextObj = TEXTOBJ_LockText(*NewFont); + if (NULL != TextObj) + { + memcpy(&TextObj->logfont, lf, sizeof(LOGFONTW)); + if (lf->lfEscapement != lf->lfOrientation) + { + /* this should really depend on whether GM_ADVANCED is set */ + TextObj->logfont.lfOrientation = TextObj->logfont.lfEscapement; + } + TEXTOBJ_UnlockText(*NewFont); + } + else + { + ASSERT(FALSE); + Status = STATUS_INVALID_HANDLE; + } + } + else + { + Status = STATUS_NO_MEMORY; + } + + return Status; +} + HFONT STDCALL W32kCreateFont(int Height, - int Width, - int Escapement, - int Orientation, - int Weight, - DWORD Italic, - DWORD Underline, - DWORD StrikeOut, - DWORD CharSet, - DWORD OutputPrecision, - DWORD ClipPrecision, - DWORD Quality, - DWORD PitchAndFamily, - LPCWSTR Face) -{ - LOGFONT logfont; + int Width, + int Escapement, + int Orientation, + int Weight, + DWORD Italic, + DWORD Underline, + DWORD StrikeOut, + DWORD CharSet, + DWORD OutputPrecision, + DWORD ClipPrecision, + DWORD Quality, + DWORD PitchAndFamily, + LPCWSTR Face) +{ + LOGFONTW logfont; + HFONT NewFont; + NTSTATUS Status = STATUS_SUCCESS; logfont.lfHeight = Height; logfont.lfWidth = Width; @@ -178,40 +261,45 @@ W32kCreateFont(int Height, logfont.lfQuality = Quality; logfont.lfPitchAndFamily = PitchAndFamily; - if(Face) - memcpy(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName)); + if (NULL != Face) + { + Status = MmCopyFromCaller(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName)); + } else - logfont.lfFaceName[0] = '\0'; + { + logfont.lfFaceName[0] = L'\0'; + } + + if (NT_SUCCESS(Status)) + { + Status = TextIntCreateFontIndirect(&logfont, &NewFont); + } - return W32kCreateFontIndirect(&logfont); + return NT_SUCCESS(Status) ? NewFont : NULL; } HFONT STDCALL -W32kCreateFontIndirect(CONST LPLOGFONT lf) +W32kCreateFontIndirect(CONST LPLOGFONTW lf) { - HFONT hFont = 0; - PTEXTOBJ fontPtr; + LOGFONTW SafeLogfont; + HFONT NewFont; + NTSTATUS Status = STATUS_SUCCESS; - if (lf) + if (NULL != lf) { - if(hFont = TEXTOBJ_AllocText()) + Status = MmCopyFromCaller(&SafeLogfont, lf, sizeof(LOGFONTW)); + if (NT_SUCCESS(Status)) { - fontPtr = TEXTOBJ_LockText( hFont ); - ASSERT( fontPtr ); //I want to know when this happens - if( fontPtr ){ - memcpy(&fontPtr->logfont, lf, sizeof(LOGFONT)); - - if (lf->lfEscapement != lf->lfOrientation) { - /* this should really depend on whether GM_ADVANCED is set */ - fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement; - } - TEXTOBJ_UnlockText( hFont ); - } + Status = TextIntCreateFontIndirect(&SafeLogfont, &NewFont); } } + else + { + Status = STATUS_INVALID_PARAMETER; + } - return hFont; + return NT_SUCCESS(Status) ? NewFont : NULL; } BOOL @@ -228,7 +316,7 @@ int STDCALL W32kEnumFontFamilies(HDC hDC, LPCWSTR Family, - FONTENUMPROC EnumFontFamProc, + FONTENUMPROCW EnumFontFamProc, LPARAM lParam) { UNIMPLEMENTED; @@ -237,8 +325,8 @@ W32kEnumFontFamilies(HDC hDC, int STDCALL W32kEnumFontFamiliesEx(HDC hDC, - LPLOGFONT Logfont, - FONTENUMPROC EnumFontFamExProc, + LPLOGFONTW Logfont, + FONTENUMPROCW EnumFontFamExProc, LPARAM lParam, DWORD Flags) { @@ -249,7 +337,7 @@ int STDCALL W32kEnumFonts(HDC hDC, LPCWSTR FaceName, - FONTENUMPROC FontFunc, + FONTENUMPROCW FontFunc, LPARAM lParam) { UNIMPLEMENTED; @@ -374,7 +462,7 @@ UINT STDCALL W32kGetOutlineTextMetrics(HDC hDC, UINT Data, - LPOUTLINETEXTMETRIC otm) + LPOUTLINETEXTMETRICW otm) { UNIMPLEMENTED; } @@ -423,26 +511,26 @@ W32kGetTextExtentPoint(HDC hDC, int Count, LPSIZE Size) { - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc = (PDC)AccessUserObject((ULONG) hDC); PFONTGDI FontGDI; FT_Face face; FT_GlyphSlot glyph; INT error, pitch, glyph_index, i; ULONG TotalWidth = 0, MaxHeight = 0, CurrentChar = 0, SpaceBetweenChars = 5; - FontGDI = (PFONTGDI)AccessInternalObject(dc->w.hFont); + FontGDI = (PFONTGDI)AccessInternalObject((ULONG) dc->w.hFont); for(i=0; iglyph; if (glyph->format == ft_glyph_format_outline) { error = FT_Render_Glyph(glyph, ft_render_mode_mono); - if(error) DbgPrint("WARNING: Failed to render glyph!\n"); + if(error) DPRINT1("WARNING: Failed to render glyph!\n"); pitch = glyph->bitmap.pitch; } else { pitch = glyph->bitmap.width; @@ -482,16 +570,59 @@ W32kGetTextFace(HDC hDC, BOOL STDCALL -W32kGetTextMetrics(HDC hDC, - LPTEXTMETRIC tm) +W32kGetTextMetrics(HDC hDC, + LPTEXTMETRICW tm) { - PDC dc = (PDC)AccessUserObject(hDC); + PDC dc; + PTEXTOBJ TextObj; PFONTGDI FontGDI; + NTSTATUS Status = STATUS_SUCCESS; + TEXTMETRICW SafeTm; + FT_Face Face; + ULONG Error; - FontGDI = (PFONTGDI)AccessInternalObject(dc->w.hFont); - memcpy(tm, &FontGDI->TextMetric, sizeof(TEXTMETRIC)); + dc = DC_HandleToPtr(hDC); + if (NULL == dc || NULL == tm) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + TextObj = TEXTOBJ_LockText(dc->w.hFont); + if (NULL != TextObj) + { + Status = GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI); + if (NT_SUCCESS(Status)) + { + Face = FontGDI->face; + Error = FT_Set_Pixel_Sizes(Face, TextObj->logfont.lfHeight, + TextObj->logfont.lfWidth); + if (0 != Error) + { + DPRINT1("Error in setting pixel sizes: %u\n", Error); + Status = STATUS_UNSUCCESSFUL; + } + else + { + memcpy(&SafeTm, &FontGDI->TextMetric, sizeof(TEXTMETRICW)); + SafeTm.tmAscent = (Face->size->metrics.ascender + 32) / 64; // units above baseline + SafeTm.tmDescent = (Face->size->metrics.descender + 32) / 64; // units below baseline + SafeTm.tmHeight = (Face->size->metrics.ascender + + Face->size->metrics.descender + 32) / 64; + Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW)); + } + } + TEXTOBJ_UnlockText(dc->w.hFont); + } + else + { + ASSERT(FALSE); + Status = STATUS_INVALID_HANDLE; + } + DC_ReleasePtr(hDC); + } - return TRUE; + return NT_SUCCESS(Status); } BOOL @@ -576,11 +707,11 @@ W32kTextOut(HDC hDC, // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate) DC *dc = DC_HandleToPtr(hDC); - SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface); - int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j, sx, sy, scc; + SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface); + int error, glyph_index, n, i; FT_Face face; FT_GlyphSlot glyph; - ULONG TextLeft, TextTop, SpaceBetweenChars = 2, pitch, previous; + ULONG TextLeft, TextTop, pitch, previous; FT_Bool use_kerning; RECTL DestRect, MaskRect; POINTL SourcePoint, BrushOrigin; @@ -591,7 +722,6 @@ W32kTextOut(HDC hDC, SIZEL bitSize; FT_CharMap found = 0, charmap; INT yoff; - HFONT hFont = 0; PFONTOBJ FontObj; PFONTGDI FontGDI; PTEXTOBJ TextObj; @@ -608,51 +738,41 @@ W32kTextOut(HDC hDC, TextObj = TEXTOBJ_LockText(dc->w.hFont); - for(i=0; ilogfont.lfFaceName) == 0) - hFont = FontTable[i].hFont; - } - - if(hFont == 0) + if (! NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI))) { - DbgPrint("Specified font %s is not loaded\n", TextObj->logfont.lfFaceName); - goto fail; + goto fail; } - - FontObj = (PFONTOBJ)AccessUserObject(hFont); - FontGDI = (PFONTGDI)AccessInternalObject(hFont); face = FontGDI->face; if (face->charmap == NULL) { - DbgPrint("WARNING: No charmap selected!\n"); - DbgPrint("This font face has %d charmaps\n", face->num_charmaps); + DPRINT("WARNING: No charmap selected!\n"); + DPRINT("This font face has %d charmaps\n", face->num_charmaps); for (n = 0; n < face->num_charmaps; n++) { charmap = face->charmaps[n]; - DbgPrint("found charmap encoding: %u\n", charmap->encoding); + DPRINT("found charmap encoding: %u\n", charmap->encoding); if (charmap->encoding != 0) { found = charmap; break; } } - if (!found) DbgPrint("WARNING: Could not find desired charmap!\n"); + if (!found) DPRINT1("WARNING: Could not find desired charmap!\n"); error = FT_Set_Charmap(face, found); - if (error) DbgPrint("WARNING: Could not set the charmap!\n"); + if (error) DPRINT1("WARNING: Could not set the charmap!\n"); } error = FT_Set_Pixel_Sizes(face, TextObj->logfont.lfHeight, TextObj->logfont.lfWidth); if(error) { - DbgPrint("Error in setting pixel sizes: %u\n", error); + DPRINT1("Error in setting pixel sizes: %u\n", error); goto fail; } // Create the brush - PalDestGDI = (PPALGDI)AccessInternalObject(dc->w.hPalette); - XlateObj = (PXLATEOBJ)EngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); + PalDestGDI = (PPALGDI)AccessInternalObject((ULONG) dc->w.hPalette); + XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL); hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor)); Brush = BRUSHOBJ_LockBrush(hBrush); EngDeleteXlate(XlateObj); @@ -684,7 +804,7 @@ W32kTextOut(HDC hDC, glyph_index = FT_Get_Char_Index(face, *String); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); if(error) { - DbgPrint("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index); + DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index); goto fail; } glyph = face->glyph; @@ -701,7 +821,7 @@ W32kTextOut(HDC hDC, { error = FT_Render_Glyph(glyph, ft_render_mode_mono); if(error) { - DbgPrint("WARNING: Failed to render glyph!\n"); + DPRINT1("WARNING: Failed to render glyph!\n"); goto fail; } pitch = glyph->bitmap.pitch; @@ -713,8 +833,8 @@ W32kTextOut(HDC hDC, DestRect.top = TextTop + yoff - glyph->bitmap_top; DestRect.right = TextLeft + glyph->bitmap.width; DestRect.bottom = DestRect.top + glyph->bitmap.rows; - bitSize.cx = pitch-1; - bitSize.cy = glyph->bitmap.rows-1; + bitSize.cx = pitch; + bitSize.cy = glyph->bitmap.rows; MaskRect.right = glyph->bitmap.width; MaskRect.bottom = glyph->bitmap.rows; @@ -722,10 +842,10 @@ W32kTextOut(HDC hDC, // Then use memset with 0 to clear it and sourcerect to limit the work of the transbitblt HSourceGlyph = EngCreateBitmap(bitSize, pitch, BMF_1BPP, 0, glyph->bitmap.buffer); - SourceGlyphSurf = (PSURFOBJ)AccessUserObject(HSourceGlyph); + SourceGlyphSurf = (PSURFOBJ)AccessUserObject((ULONG) HSourceGlyph); // Use the font data as a mask to paint onto the DCs surface using a brush - EngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC); + IntEngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC); EngDeleteSurface(HSourceGlyph); @@ -758,3 +878,50 @@ W32kTranslateCharsetInfo(PDWORD Src, { UNIMPLEMENTED; } + +NTSTATUS +TextIntRealizeFont(HFONT FontHandle) +{ + UINT i; + NTSTATUS Status = STATUS_SUCCESS; + PTEXTOBJ TextObj; + + TextObj = TEXTOBJ_LockText(FontHandle); + ASSERT(TextObj); + if (NULL != TextObj) + { + for(i = 0; NULL == TextObj->GDIFontHandle && i < FontsLoaded; i++) + { + if (0 == wcscmp(FontTable[i].FaceName, TextObj->logfont.lfFaceName)) + { + TextObj->GDIFontHandle = FontTable[i].hFont; + } + } + + if (NULL == TextObj->GDIFontHandle) + { + if (0 != FontsLoaded) + { + DPRINT("Requested font %S not found, using first available font\n", + TextObj->logfont.lfFaceName) + TextObj->GDIFontHandle = FontTable[0].hFont; + } + else + { + DPRINT1("Requested font %S not found, no fonts loaded at all\n", + TextObj->logfont.lfFaceName) + Status = STATUS_NOT_FOUND; + } + } + + ASSERT(! NT_SUCCESS(Status) || NULL != TextObj->GDIFontHandle); + + TEXTOBJ_UnlockText(FontHandle); + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + return Status; +} diff --git a/subsys/win32k/objects/wingl.c b/subsys/win32k/objects/wingl.c index 0973cf0..97a90fd 100644 --- a/subsys/win32k/objects/wingl.c +++ b/subsys/win32k/objects/wingl.c @@ -4,7 +4,7 @@ #include #include -// #define NDEBUG +#define NDEBUG #include INT diff --git a/subsys/win32k/stubs/stubs.c b/subsys/win32k/stubs/stubs.c index 0f1898f..8e381d7 100644 --- a/subsys/win32k/stubs/stubs.c +++ b/subsys/win32k/stubs/stubs.c @@ -71,7 +71,6 @@ STUB(EngTextOut) STUB(EngUnicodeToMultiByteN) STUB(EngUnloadImage) STUB(EngUnlockDriverObj) -STUB(EngUnlockSurface) STUB(EngUnmapEvent) STUB(EngUnmapFontFile) STUB(EngUnsecureMem) diff --git a/subsys/win32k/win32k.def b/subsys/win32k/win32k.def index 4fa8151..0fe8679 100644 --- a/subsys/win32k/win32k.def +++ b/subsys/win32k/win32k.def @@ -72,7 +72,7 @@ EngMapFontFile EngMapModule EngMarkBandingSurface EngMovePointer -EngMulDiv +EngMulDiv@12 EngMultiByteToUnicodeN EngMultiByteToWideChar EngPaint@20 @@ -101,7 +101,7 @@ EngTransparentBlt@32 EngUnicodeToMultiByteN EngUnloadImage EngUnlockDriverObj -EngUnlockSurface +EngUnlockSurface@4 EngUnmapEvent EngUnmapFontFile ; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory diff --git a/subsys/win32k/win32k.edf b/subsys/win32k/win32k.edf index e93e9e9..6867fc8 100644 --- a/subsys/win32k/win32k.edf +++ b/subsys/win32k/win32k.edf @@ -72,7 +72,7 @@ EngMapFontFile EngMapModule EngMarkBandingSurface EngMovePointer -EngMulDiv +EngMulDiv=EngMulDiv@12 EngMultiByteToUnicodeN EngMultiByteToWideChar EngPaint=EngPaint@20 @@ -101,7 +101,7 @@ EngTransparentBlt=EngTransparentBlt@32 EngUnicodeToMultiByteN EngUnloadImage EngUnlockDriverObj -EngUnlockSurface +EngUnlockSurface=EngUnlockSurface@4 EngUnmapEvent EngUnmapFontFile ; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory diff --git a/system.hiv b/system.hiv index d1d5648..4eaab52 100644 --- a/system.hiv +++ b/system.hiv @@ -57,7 +57,7 @@ REGEDIT4 "UNC"="\Device\Mup" [\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager\Environment] -"ComSpec"=expand:"%SystemRoot%\system32\shell.exe" +"ComSpec"=expand:"%SystemRoot%\system32\cmd.exe" "OS"=expand:"ReactOS" "Path"=expand:"%SystemRoot%\system32;%SystemRoot%" "windir"=expand:"%SystemRoot%" @@ -218,7 +218,7 @@ REGEDIT4 "ErrorControl"=dword:00000001 "Group"="PNP_TDI" "ImagePath"=expand:"system32\drivers\packet.sys" -"Start"=dword:00000002 +"Start"=dword:00000004 "Type"=dword:00000001 [\Registry\Machine\SYSTEM\ControlSet001\Services\Packet\Linkage] @@ -290,6 +290,19 @@ REGEDIT4 "Start"=dword:00000001 "Type"=dword:00000001 +[\Registry\Machine\SYSTEM\ControlSet001\Services\Vga\Device0] +"InstalledDisplayDrivers"=multi:"vgaddi" + +[\Registry\Machine\SYSTEM\ControlSet001\Services\vmx_svga] +"ErrorControl"=dword:00000000 +"Group"="Video" +"ImagePath"=expand:"system32\drivers\vmx_svga.sys" +"Start"=dword:00000004 +"Type"=dword:00000001 + +[\Registry\Machine\SYSTEM\ControlSet001\Services\vmx_svga\Device0] +"InstalledDisplayDrivers"=multi:"vmx_fb" + [\Registry\Machine\SYSTEM\ControlSet002] [\Registry\Machine\SYSTEM\Select] @@ -302,7 +315,7 @@ REGEDIT4 "CmdLine"="setup -newsetup" "OsLoaderPath"="\" "SetupType"=dword:00000000 -"SystemPartition"="\Device\HarddiskVolume1" +"SystemPartition"="\Device\Harddisk0\Partition1" "SystemSetupInProgress"=dword:00000000 [\Registry\Machine\SOFTWARE] @@ -326,5 +339,5 @@ REGEDIT4 [\Registry\Machine\SOFTWARE\ReactOS\Windows NT\CurrentVersion] [\Registry\Machine\SOFTWARE\ReactOS\Windows NT\CurrentVersion\WinLogon] -"Shell"=expand:"%SystemRoot%\System32\Shell.exe" +"Shell"=expand:"%SystemRoot%\System32\cmd.exe" "StartServices"=dword:00000001 diff --git a/tools/.cvsignore b/tools/.cvsignore index cea22db..28e71f2 100644 --- a/tools/.cvsignore +++ b/tools/.cvsignore @@ -2,9 +2,11 @@ buildno depends rcopy +rline rmkdir rrmdir mkconfig +mkflpimg rdel rsym rtouch diff --git a/tools/Makefile b/tools/Makefile index cee144c..c38b40a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -5,14 +5,16 @@ TOOLS = \ depends$(EXE_POSTFIX) \ rcopy$(EXE_POSTFIX) \ rdel$(EXE_POSTFIX) \ + rline$(EXE_POSTFIX) \ rmkdir$(EXE_POSTFIX) \ rrmdir$(EXE_POSTFIX) \ rsym$(EXE_POSTFIX) \ - rtouch$(EXE_POSTFIX) + rtouch$(EXE_POSTFIX) \ + mkflpimg$(EXE_POSTFIX) CLEAN_FILES = $(TOOLS) -all: $(TOOLS) wmc_directory_target +all: $(TOOLS) wmc_target cdmake_target mkhive_target buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h $(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c @@ -34,6 +36,15 @@ rdel$(EXE_POSTFIX): rdel.c $(HOST_CC) $(CFLAGS) rdel.c -o rdel$(EXE_POSTFIX) ifeq ($(HOST),mingw32-linux) +rline$(EXE_POSTFIX): rline.c + $(HOST_CC) $(CFLAGS) -DUNIX_PATHS rline.c -o rline$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +rline$(EXE_POSTFIX): rmkdir.c + $(HOST_CC) $(CFLAGS) -DDOS_PATHS rline.c -o rline$(EXE_POSTFIX) +endif + +ifeq ($(HOST),mingw32-linux) rmkdir$(EXE_POSTFIX): rmkdir.c $(HOST_CC) $(CFLAGS) -DUNIX_PATHS rmkdir.c -o rmkdir$(EXE_POSTFIX) endif @@ -69,19 +80,39 @@ rtouch$(EXE_POSTFIX): rtouch.c $(HOST_CC) $(CFLAGS) -DDOS_PATHS rtouch.c -o rtouch$(EXE_POSTFIX) endif +ifeq ($(HOST),mingw32-linux) +mkflpimg$(EXE_POSTFIX): mkflpimg.c + $(HOST_CC) $(CFLAGS) -DUNIX_PATHS mkflpimg.c -o mkflpimg$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +mkflpimg$(EXE_POSTFIX): mkflpimg.c + $(HOST_CC) $(CFLAGS) -DDOS_PATHS mkflpimg.c -o mkflpimg$(EXE_POSTFIX) +endif + + +wmc_target: + $(MAKE) -C wmc wmc$(EXE_POSTFIX) + +cdmake_target: + $(MAKE) -C cdmake cdmake$(EXE_POSTFIX) + +mkhive_target: + $(MAKE) -C mkhive mkhive$(EXE_POSTFIX) -wmc_directory_target: - make -C wmc wmc$(EXE_POSTFIX) ifeq ($(HOST),mingw32-linux) clean: - make -C wmc clean + $(MAKE) -C cdmake clean + $(MAKE) -C mkhive clean + $(MAKE) -C wmc clean rm mkconfig rm $(TOOLS) endif ifeq ($(HOST),mingw32-windows) clean: - make -C wmc clean + $(MAKE) -C cdmake clean + $(MAKE) -C mkhive clean + $(MAKE) -C wmc clean del *$(EXE_POSTFIX) endif diff --git a/tools/cdmake/.cvsignore b/tools/cdmake/.cvsignore new file mode 100644 index 0000000..7165a12 --- /dev/null +++ b/tools/cdmake/.cvsignore @@ -0,0 +1,10 @@ +cdmake +*.coff +*.d +*.exe +*.o +*.sym +*.dsp +*.dsw +*.ncb +*.opt diff --git a/tools/cdmake/Makefile b/tools/cdmake/Makefile new file mode 100644 index 0000000..34dc6cf --- /dev/null +++ b/tools/cdmake/Makefile @@ -0,0 +1,40 @@ +# +# CD-Maker +# +PATH_TO_TOP = ../.. + +TARGET=cdmake$(EXE_POSTFIX) + +all: $(TARGET) + +OBJECTS = cdmake.o llmosrt.o + +CLEAN_FILES = *.o cdmake$(EXE_POSTFIX) + +HOST_CFLAGS = -I. + +cdmake.o: cdmake.c + $(HOST_CC) $(HOST_CFLAGS) -c cdmake.c -o cdmake.o + +llmosrt.o: llmosrt.c + $(HOST_CC) $(HOST_CFLAGS) -c llmosrt.c -o llmosrt.o + +cdmake$(EXE_POSTFIX): $(OBJECTS) + $(HOST_CC) $(OBJECTS) -o cdmake$(EXE_POSTFIX) + +ifeq ($(HOST),mingw32-linux) +clean: + rm -f *.o + rm -f cdmake$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +clean: + del *.o + del cdmake$(EXE_POSTFIX) +endif + +.phony: clean + +include $(PATH_TO_TOP)/rules.mak + +# EOF diff --git a/tools/cdmake/cdmake.c b/tools/cdmake/cdmake.c new file mode 100644 index 0000000..78830b9 --- /dev/null +++ b/tools/cdmake/cdmake.c @@ -0,0 +1,1320 @@ +/* $Id$ */ +/* CD-ROM Maker + by Philip J. Erdelsky + pje@acm.org + http://www.alumni.caltech.edu/~pje/ + + ElTorito-Support + by Eric Kohl + ekohl@rz-online.de + + Linux port + by Casper S. Hornstrup + chorns@users.sourceforge.net + */ + +/* According to his website, this file was released into the public domain by Phillip J. Erdelsky */ + +#include +#include +#include +#include +#include +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#include +#endif +#include +#include +#include +#ifndef WIN32 +#ifndef MAX_PATH +#define MAX_PATH 260 +#endif +#define DIR_SEPARATOR_CHAR '/' +#define DIR_SEPARATOR_STRING "/" +#else +#define DIR_SEPARATOR_CHAR '\\' +#define DIR_SEPARATOR_STRING "\\" +#endif + + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef int BOOL; + +const BOOL TRUE = 1; +const BOOL FALSE = 0; + +// file system parameters + +#define MAX_LEVEL 8 +#define MAX_NAME_LENGTH 8 +#define MAX_EXTENSION_LENGTH 3 +#define SECTOR_SIZE 2048 +#define BUFFER_SIZE (8 * SECTOR_SIZE) + +const BYTE HIDDEN_FLAG = 1; +const BYTE DIRECTORY_FLAG = 2; + + +struct cd_image +{ + FILE *file; + DWORD sector; // sector to receive next byte + int offset; // offset of next byte in sector + int count; // number of bytes in buffer + char filespecs[128]; + BYTE *buffer; +}; + +typedef struct date_and_time +{ + BYTE second; + BYTE minute; + BYTE hour; + BYTE day; + BYTE month; + WORD year; +} DATE_AND_TIME, *PDATE_AND_TIME; + +typedef struct directory_record +{ + struct directory_record *next_in_directory; + struct directory_record *next_in_path_table; /* directory record only */ + struct directory_record *next_in_memory; + struct directory_record *first_record; /* directory record only */ + struct directory_record *parent; + BYTE flags; + char name[MAX_NAME_LENGTH+1]; + char name_on_cd[MAX_NAME_LENGTH+1]; + char extension[MAX_EXTENSION_LENGTH+1]; + char extension_on_cd[MAX_EXTENSION_LENGTH+1]; + DATE_AND_TIME date_and_time; + DWORD sector; + DWORD size; + unsigned level; /* directory record only */ + WORD path_table_index; /* directory record only */ +} DIR_RECORD, *PDIR_RECORD; + + +typedef enum directory_record_type +{ + DOT_RECORD, + DOT_DOT_RECORD, + SUBDIRECTORY_RECORD, + FILE_RECORD +} DIR_RECORD_TYPE, *PDIR_RECORD_TYPE; + + +PDIR_RECORD sort_linked_list(PDIR_RECORD, + unsigned, int (*)(PDIR_RECORD, PDIR_RECORD)); + + +static char DIRECTORY_TIMESTAMP[] = "~Y$'KOR$.3K&"; + +static jmp_buf error; +static struct cd_image cd; + +char volume_label[32]; +DIR_RECORD root; +char source[512]; +char *end_source; +enum {QUIET, NORMAL, VERBOSE} verbosity; +BOOL show_progress; +DWORD size_limit; +BOOL accept_punctuation_marks; + +DWORD total_sectors; +DWORD path_table_size; +DWORD little_endian_path_table_sector; +DWORD big_endian_path_table_sector; +DWORD number_of_files; +DWORD bytes_in_files; +DWORD unused_bytes_at_ends_of_files; +DWORD number_of_directories; +DWORD bytes_in_directories; + +char bootimage[512]; +BOOL eltorito; +DWORD boot_catalog_sector; +DWORD boot_image_sector; + +/*----------------------------------------------------------------------------- +This function edits a 32-bit unsigned number into a comma-delimited form, such +as 4,294,967,295 for the largest possible number, and returns a pointer to a +static buffer containing the result. It suppresses leading zeros and commas, +but optionally pads the result with blanks at the left so the result is always +exactly 13 characters long (excluding the terminating zero). + +CAUTION: A statement containing more than one call on this function, such as +printf("%s, %s", edit_with_commas(a), edit_with_commas(b)), will produce +incorrect results because all calls use the same static bufffer. +-----------------------------------------------------------------------------*/ + +static char *edit_with_commas(DWORD x, BOOL pad) +{ + static char s[14]; + unsigned i = 13; + do + { + if (i % 4 == 2) s[--i] = ','; + s[--i] = x % 10 + '0'; + } while ((x/=10) != 0); + if (pad) + { + while (i > 0) s[--i] = ' '; + } + return s + i; +} + +/*----------------------------------------------------------------------------- +This function releases all allocated memory blocks. +-----------------------------------------------------------------------------*/ + +static void release_memory(void) +{ + while (root.next_in_memory != NULL) + { + struct directory_record *next = + root.next_in_memory->next_in_memory; + free (root.next_in_memory); + root.next_in_memory = next; + } + if (cd.buffer != NULL) + { + free (cd.buffer); + cd.buffer = NULL; + } +} + +/*----------------------------------------------------------------------------- +This function edits and displays an error message and then jumps back to the +error exit point in main(). +-----------------------------------------------------------------------------*/ + +#define error_exit(fmt,args...) \ +{ \ + printf(fmt,##args); \ + printf("\n"); \ + if (cd.file != NULL) \ + fclose(cd.file); \ + release_memory(); \ + exit(1); \ +} + +/*----------------------------------------------------------------------------- +This function, which is called only on the second pass, and only when the +buffer is not empty, flushes the buffer to the CD-ROM image. +-----------------------------------------------------------------------------*/ + +static void flush_buffer(void) +{ + if (fwrite(cd.buffer, cd.count, 1, cd.file) < 1) + error_exit("File write error"); + cd.count = 0; + if (show_progress) + { + printf("\r%s ", + edit_with_commas((total_sectors - cd.sector) * SECTOR_SIZE, TRUE)); + } +} + +/*----------------------------------------------------------------------------- +This function writes a single byte to the CD-ROM image. On the first pass (in +which cd.handle < 0), it does not actually write anything but merely updates +the file pointer as though the byte had been written. +-----------------------------------------------------------------------------*/ + +static void write_byte(BYTE x) +{ + if (cd.file != NULL) + { + cd.buffer[cd.count] = x; + if (++cd.count == BUFFER_SIZE) + flush_buffer(); + } + if (++cd.offset == SECTOR_SIZE) + { + cd.sector++; + cd.offset = 0; + } +} + +/*----------------------------------------------------------------------------- +These functions write a word or double word to the CD-ROM image with the +specified endianity. +-----------------------------------------------------------------------------*/ + +static void write_little_endian_word(WORD x) +{ + write_byte(x); + write_byte(x >> 8); +} + +static void write_big_endian_word(WORD x) +{ + write_byte(x >> 8); + write_byte(x); +} + +static void write_both_endian_word(WORD x) +{ + write_little_endian_word(x); + write_big_endian_word(x); +} + +static void write_little_endian_dword(DWORD x) +{ + write_byte(x); + write_byte(x >> 8); + write_byte(x >> 16); + write_byte(x >> 24); +} + +static void write_big_endian_dword(DWORD x) +{ + write_byte(x >> 24); + write_byte(x >> 16); + write_byte(x >> 8); + write_byte(x); +} + +static void write_both_endian_dword(DWORD x) +{ + write_little_endian_dword(x); + write_big_endian_dword(x); +} + +/*----------------------------------------------------------------------------- +This function writes enough zeros to fill out the end of a sector, and leaves +the file pointer at the beginning of the next sector. If the file pointer is +already at the beginning of a sector, it writes nothing. +-----------------------------------------------------------------------------*/ + +static void fill_sector(void) +{ + while (cd.offset != 0) + write_byte(0); +} + +/*----------------------------------------------------------------------------- +This function writes a string to the CD-ROM image. The terminating \0 is not +written. +-----------------------------------------------------------------------------*/ + +static void write_string(char *s) +{ + while (*s != 0) + write_byte(*s++); +} + +/*----------------------------------------------------------------------------- +This function writes a block of identical bytes to the CD-ROM image. +-----------------------------------------------------------------------------*/ + +static void write_block(unsigned count, BYTE value) +{ + while (count != 0) + { + write_byte(value); + count--; + } +} + +/*----------------------------------------------------------------------------- +This function writes a directory record to the CD_ROM image. +-----------------------------------------------------------------------------*/ + +static void +write_directory_record(PDIR_RECORD d, + DIR_RECORD_TYPE DirType) +{ + unsigned identifier_size; + unsigned record_size; + + switch (DirType) + { + case DOT_RECORD: + case DOT_DOT_RECORD: + identifier_size = 1; + break; + case SUBDIRECTORY_RECORD: + identifier_size = strlen(d->name_on_cd); + break; + case FILE_RECORD: + identifier_size = strlen(d->name_on_cd) + 2; + if (d->extension_on_cd[0] != 0) + identifier_size += 1 + strlen(d->extension_on_cd); + break; + } + record_size = 33 + identifier_size; + if ((identifier_size & 1) == 0) + record_size++; + if (cd.offset + record_size > SECTOR_SIZE) + fill_sector(); + write_byte(record_size); + write_byte(0); // number of sectors in extended attribute record + write_both_endian_dword(d->sector); + write_both_endian_dword(d->size); + write_byte(d->date_and_time.year - 1900); + write_byte(d->date_and_time.month); + write_byte(d->date_and_time.day); + write_byte(d->date_and_time.hour); + write_byte(d->date_and_time.minute); + write_byte(d->date_and_time.second); + write_byte(0); // GMT offset + write_byte(d->flags); + write_byte(0); // file unit size for an interleaved file + write_byte(0); // interleave gap size for an interleaved file + write_both_endian_word((WORD) 1); // volume sequence number + write_byte(identifier_size); + switch (DirType) + { + case DOT_RECORD: + write_byte(0); + break; + case DOT_DOT_RECORD: + write_byte(1); + break; + case SUBDIRECTORY_RECORD: + write_string(d->name_on_cd); + break; + case FILE_RECORD: + write_string(d->name_on_cd); + if (d->extension_on_cd[0] != 0) + { + write_byte('.'); + write_string(d->extension_on_cd); + } + write_string(";1"); + break; + } + if ((identifier_size & 1) == 0) + write_byte(0); +} + +/*----------------------------------------------------------------------------- +This function converts the date and time words from an ffblk structure and +puts them into a date_and_time structure. +-----------------------------------------------------------------------------*/ + +static void convert_date_and_time(PDATE_AND_TIME dt, time_t *time) +{ + struct tm *timedef; + + timedef = localtime(time); + + dt->second = timedef->tm_sec; + dt->minute = timedef->tm_min; + dt->hour = timedef->tm_hour; + dt->day = timedef->tm_mday; + dt->month = timedef->tm_mon; + dt->year = timedef->tm_year + 1900; +} + +/*----------------------------------------------------------------------------- +This function checks the specified character, if necessary, and +generates an error if it is a punctuation mark other than an underscore. +It also converts small letters to capital letters and returns the +result. +-----------------------------------------------------------------------------*/ + +static int check_for_punctuation(int c, char *name) +{ + c = toupper(c & 0xFF); + if (!accept_punctuation_marks && !isalnum(c) && c != '_') + error_exit("Punctuation mark in %s", name); + return c; +} + +/*----------------------------------------------------------------------------- +This function creates a new directory record with the information from the +specified ffblk. It links it into the beginning of the directory list +for the specified parent and returns a pointer to the new record. +-----------------------------------------------------------------------------*/ + +#if WIN32 + +/* Win32 version */ +PDIR_RECORD +new_directory_record (struct _finddata_t *f, + PDIR_RECORD parent) +{ + PDIR_RECORD d; + char *s; + char *t; + char *n; + + d = malloc(sizeof(DIR_RECORD)); + if (d == NULL) + error_exit("Insufficient memory"); + d->next_in_memory = root.next_in_memory; + root.next_in_memory = d; + { + s = f->name; + t = d->name_on_cd; + n = d->name; + + while (*s != 0) + { + if (*s == '.') + { + s++; + break; + } + + *t++ = check_for_punctuation(*s, f->name); + *n = *s; + s++; + n++; + } + *t = 0; + strcpy(d->extension, s); + t = d->extension_on_cd; + while (*s != 0) + *t++ = check_for_punctuation(*s++, f->name); + *t = 0; + *n = 0; + } + convert_date_and_time(&d->date_and_time, &f->time_create); + if (f->attrib & _A_SUBDIR) + { + if (d->extension[0] != 0) + error_exit("Directory with extension %s", f->name); + d->flags = DIRECTORY_FLAG; + } + else + d->flags = f->attrib & _A_HIDDEN ? HIDDEN_FLAG : 0; + d->size = f->size; + d->next_in_directory = parent->first_record; + parent->first_record = d; + d->parent = parent; + return d; +} + +#else + +/* Linux version */ +PDIR_RECORD +new_directory_record (struct dirent *entry, + struct stat *stbuf, + PDIR_RECORD parent) +{ + PDIR_RECORD d; + char *s; + char *t; + char *n; + + d = malloc(sizeof(DIR_RECORD)); + if (d == NULL) + error_exit("Insufficient memory"); + d->next_in_memory = root.next_in_memory; + root.next_in_memory = d; + { + s = entry->d_name; + t = d->name_on_cd; + n = d->name; + + while (*s != 0) + { + if (*s == '.') + { + s++; + break; + } + + *t++ = check_for_punctuation(*s, entry->d_name); + *n = *s; + s++; + n++; + } + *t = 0; + strcpy(d->extension, s); + t = d->extension_on_cd; + while (*s != 0) + *t++ = check_for_punctuation(*s++, entry->d_name); + *t = 0; + *n = 0; + } + + convert_date_and_time(&d->date_and_time, &stbuf->st_mtime); + if (entry->d_type == DT_DIR) + { + if (d->extension[0] != 0) + error_exit("Directory with extension %s", entry->d_name); + d->flags = DIRECTORY_FLAG; + } + else + d->flags = entry->d_name[0] == '.' ? HIDDEN_FLAG : 0; + d->size = stbuf->st_size; + d->next_in_directory = parent->first_record; + parent->first_record = d; + d->parent = parent; + return d; +} + +#endif + +/*----------------------------------------------------------------------------- +This function compares two directory records according to the ISO9660 rules +for directory sorting and returns a negative value if p is before q, or a +positive value if p is after q. +-----------------------------------------------------------------------------*/ + +static int compare_directory_order(PDIR_RECORD p, PDIR_RECORD q) +{ + int n = strcmp(p->name_on_cd, q->name_on_cd); + if (n == 0) + n = strcmp(p->extension_on_cd, q->extension_on_cd); + return n; +} + +/*----------------------------------------------------------------------------- +This function compares two directory records (which must represent +directories) according to the ISO9660 rules for path table sorting and returns +a negative value if p is before q, or a positive vlaue if p is after q. +-----------------------------------------------------------------------------*/ + +static int compare_path_table_order(PDIR_RECORD p, PDIR_RECORD q) +{ + int n = p->level - q->level; + if (p == q) + return 0; + if (n == 0) + { + n = compare_path_table_order(p->parent, q->parent); + if (n == 0) + n = compare_directory_order(p, q); + } + return n; +} + +/*----------------------------------------------------------------------------- +This function appends the specified string to the buffer source[]. +-----------------------------------------------------------------------------*/ + +static void append_string_to_source(char *s) +{ + while (*s != 0) + *end_source++ = *s++; +} + +/*----------------------------------------------------------------------------- +This function scans all files from the current source[] (which must end in \, +and represents a directory already in the database as d), +and puts the appropriate directory records into the database in memory, with +the specified root. It calls itself recursively to scan all subdirectories. +-----------------------------------------------------------------------------*/ + +#ifdef WIN32 + +static void +make_directory_records (PDIR_RECORD d) +{ + PDIR_RECORD new_d; + struct _finddata_t f; + char *old_end_source; + int findhandle; + + d->first_record = NULL; + strcpy(end_source, "*.*"); + + findhandle =_findfirst(source, &f); + if (findhandle != 0) + { + do + { + if ((f.attrib & (_A_HIDDEN | _A_SUBDIR)) == 0 && f.name[0] != '.') + { + if (strcmp(f.name, DIRECTORY_TIMESTAMP) == 0) + { + convert_date_and_time(&d->date_and_time, &f.time_create); + } + else + { + if (verbosity == VERBOSE) + { + old_end_source = end_source; + strcpy(end_source, f.name); + printf("%d: file %s\n", d->level, source); + end_source = old_end_source; + } + (void) new_directory_record(&f, d); + } + } + } + while (_findnext(findhandle, &f) == 0); + + _findclose(findhandle); + } + + strcpy(end_source, "*.*"); + findhandle= _findfirst(source, &f); + if (findhandle) + { + do + { + if (f.attrib & _A_SUBDIR && f.name[0] != '.') + { + old_end_source = end_source; + append_string_to_source(f.name); + *end_source++ = DIR_SEPARATOR_CHAR; + if (verbosity == VERBOSE) + { + *end_source = 0; + printf("%d: directory %s\n", d->level + 1, source); + } + if (d->level < MAX_LEVEL) + { + new_d = new_directory_record(&f, d); + new_d->next_in_path_table = root.next_in_path_table; + root.next_in_path_table = new_d; + new_d->level = d->level + 1; + make_directory_records(new_d); + } + else + { + error_exit("Directory is nested too deep"); + } + end_source = old_end_source; + } + } + while (_findnext(findhandle, &f) == 0); + + _findclose(findhandle); + } + + // sort directory + d->first_record = sort_linked_list(d->first_record, 0, compare_directory_order); +} + +#else + +/* Linux version */ +static void +make_directory_records (PDIR_RECORD d) +{ + PDIR_RECORD new_d; + DIR *dirp; + struct dirent *entry; + char *old_end_source; + struct stat stbuf; + char buf[MAX_PATH]; + + d->first_record = NULL; + + dirp = opendir(source); + + if (dirp != NULL) + { + while ((entry = readdir (dirp)) != NULL) + { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; // skip self and parent + + if (entry->d_type == DT_REG) // normal file + { + // Check for an absolute path + if (source[0] == DIR_SEPARATOR_CHAR) + { + strcpy(buf, source); + strcat(buf, DIR_SEPARATOR_STRING); + strcat(buf, entry->d_name); + } + else + { + getcwd(buf, sizeof(buf)); + strcat(buf, DIR_SEPARATOR_STRING); + strcat(buf, source); + strcat(buf, entry->d_name); + } + if (stat(buf, &stbuf) == -1) + { + error_exit("Can't access '%s' (%s)\n", buf, strerror(errno)); + return; + } + + if (strcmp(entry->d_name, DIRECTORY_TIMESTAMP) == 0) + { + convert_date_and_time(&d->date_and_time, &stbuf.st_size); + } + else + { + if (verbosity == VERBOSE) + { + printf("%d: file %s\n", d->level, buf); + } + (void) new_directory_record(entry, &stbuf, d); + } + } + } + closedir (dirp); + } + else + { + error_exit("Can't open %s\n", source); + return; + } + + dirp = opendir(source); + if (dirp != NULL) + { + while ((entry = readdir (dirp)) != NULL) + { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; // skip self and parent + + if (entry->d_type == DT_DIR) // directory + { + old_end_source = end_source; + append_string_to_source(entry->d_name); + *end_source++ = DIR_SEPARATOR_CHAR; + if (verbosity == VERBOSE) + { + *end_source = 0; + printf("%d: directory %s\n", d->level + 1, source); + } + if (d->level < MAX_LEVEL) + { + // Check for an absolute path + if (source[0] == DIR_SEPARATOR_CHAR) + { + strcpy(buf, source); + } + else + { + getcwd(buf, sizeof(buf)); + strcat(buf, DIR_SEPARATOR_STRING); + strcat(buf, source); + } + if (stat(buf, &stbuf) == -1) + { + error_exit("Can't access '%s' (%s)\n", buf, strerror(errno)); + return; + } + new_d = new_directory_record(entry, &stbuf, d); + new_d->next_in_path_table = root.next_in_path_table; + root.next_in_path_table = new_d; + new_d->level = d->level + 1; + make_directory_records(new_d); + } + else + { + error_exit("Directory is nested too deep"); + } + end_source = old_end_source; + } + } + closedir (dirp); + } + + // sort directory + d->first_record = sort_linked_list(d->first_record, 0, compare_directory_order); +} + +#endif + +/*----------------------------------------------------------------------------- +This function loads the file specifications for the file or directory +corresponding to the specified directory record into the source[] buffer. It +is recursive. +-----------------------------------------------------------------------------*/ + +static void get_file_specifications(PDIR_RECORD d) +{ + if (d != &root) + { + get_file_specifications(d->parent); + append_string_to_source(d->name); + if ((d->flags & DIRECTORY_FLAG) == 0 && d->extension[0] != 0) + { + *end_source++ = '.'; + append_string_to_source(d->extension); + } + if (d->flags & DIRECTORY_FLAG) + *end_source++ = DIR_SEPARATOR_CHAR; + } +} + +static void pass(void) +{ + PDIR_RECORD d; + PDIR_RECORD q; + unsigned int i; + char *t; + unsigned int index; + unsigned int name_length; + DWORD size; + DWORD number_of_sectors; + char *old_end_source; + int n; + FILE *file; + + // first 16 sectors are zeros + + write_block(16 * SECTOR_SIZE, 0); + + // Primary Volume Descriptor + + write_string("\1CD001\1"); + write_byte(0); + write_block(32, ' '); // system identifier + + t = volume_label; + for (i = 0; i < 32; i++) + write_byte(*t != 0 ? toupper(*t++) : ' '); + + write_block(8, 0); + write_both_endian_dword(total_sectors); + write_block(32, 0); + write_both_endian_word((WORD) 1); // volume set size + write_both_endian_word((WORD) 1); // volume sequence number + write_both_endian_word((WORD) 2048); // sector size + write_both_endian_dword(path_table_size); + write_little_endian_dword(little_endian_path_table_sector); + write_little_endian_dword((DWORD) 0); // second little endian path table + write_big_endian_dword(big_endian_path_table_sector); + write_big_endian_dword((DWORD) 0); // second big endian path table + write_directory_record(&root, DOT_RECORD); + write_block(128, ' '); // volume set identifier + write_block(128, ' '); // publisher identifier + write_block(128, ' '); // data preparer identifier + write_block(128, ' '); // application identifier + write_block(37, ' '); // copyright file identifier + write_block(37, ' '); // abstract file identifier + write_block(37, ' '); // bibliographic file identifier + write_string("0000000000000000"); // volume creation + write_byte(0); + write_string("0000000000000000"); // most recent modification + write_byte(0); + write_string("0000000000000000"); // volume expires + write_byte(0); + write_string("0000000000000000"); // volume is effective + write_byte(0); + write_byte(1); + write_byte(0); + fill_sector(); + + + // Boot Volume Descriptor + + if (eltorito == TRUE) + { + write_byte(0); + write_string("CD001\1"); + write_string("EL TORITO SPECIFICATION"); // identifier + write_block(9, 0); // padding + write_block(32, 0); // unused + write_little_endian_dword(boot_catalog_sector); // pointer to boot catalog + fill_sector(); + } + + + // Volume Descriptor Set Terminator + + write_string("\377CD001\1"); + fill_sector(); + + + // Boot Catalog + + if (eltorito == TRUE) + { + boot_catalog_sector = cd.sector; + + // Validation entry + write_byte(1); + write_byte(0); // x86 boot code + write_little_endian_word(0); // reserved + write_string("ReactOS Foundation"); + write_block(6, 0); // padding + write_little_endian_word(0x62E); // checksum + write_little_endian_word(0xAA55); // signature + + // default entry + write_byte(0x88); // bootable + write_byte(0); // no emulation + write_big_endian_word(0); // load segment = default (0x07c0) + write_byte(0); // partition type + write_byte(0); // unused + write_little_endian_word(4); // sector count + write_little_endian_dword(boot_image_sector); // sector count + + fill_sector(); + } + + + // Boot Image + + if (eltorito == TRUE) + { + boot_image_sector = cd.sector; + + file = fopen(bootimage, "rb"); + if (file == NULL) + error_exit("Can't open %s\n", bootimage); + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + while (size > 0) + { + n = BUFFER_SIZE - cd.count; + if ((DWORD) n > size) + n = size; + if (fread (cd.buffer + cd.count, n, 1, file) < 1) + { + fclose(file); + error_exit("Read error in file %s\n", bootimage); + } + cd.count += n; + if (cd.count == BUFFER_SIZE) + flush_buffer(); + cd.sector += n / SECTOR_SIZE; + cd.offset += n % SECTOR_SIZE; + size -= n; + } + fclose(file); +// fill_sector(); + } + + + // Little Endian Path Table + + little_endian_path_table_sector = cd.sector; + write_byte(1); + write_byte(0); // number of sectors in extended attribute record + write_little_endian_dword(root.sector); + write_little_endian_word((WORD) 1); + write_byte(0); + write_byte(0); + + index = 1; + root.path_table_index = 1; + for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table) + { + name_length = strlen(d->name_on_cd); + write_byte(name_length); + write_byte(0); // number of sectors in extended attribute record + write_little_endian_dword(d->sector); + write_little_endian_word(d->parent->path_table_index); + write_string(d->name_on_cd); + if (name_length & 1) + write_byte(0); + d->path_table_index = ++index; + } + + path_table_size = (cd.sector - little_endian_path_table_sector) * + SECTOR_SIZE + cd.offset; + fill_sector(); + + // Big Endian Path Table + + big_endian_path_table_sector = cd.sector; + write_byte(1); + write_byte(0); // number of sectors in extended attribute record + write_big_endian_dword(root.sector); + write_big_endian_word((WORD) 1); + write_byte(0); + write_byte(0); + + for (d = root.next_in_path_table; d != NULL; d = d->next_in_path_table) + { + name_length = strlen(d->name_on_cd); + write_byte(name_length); + write_byte(0); // number of sectors in extended attribute record + write_big_endian_dword(d->sector); + write_big_endian_word(d->parent->path_table_index); + write_string(d->name_on_cd); + if (name_length & 1) + write_byte(0); + } + fill_sector(); + + + // directories and files + + for (d = &root; d != NULL; d = d->next_in_path_table) + { + // write directory + + d->sector = cd.sector; + write_directory_record(d, DOT_RECORD); + write_directory_record(d == &root ? d : d->parent, DOT_DOT_RECORD); + for (q = d->first_record; q != NULL; q = q->next_in_directory) + { + write_directory_record(q, + q->flags & DIRECTORY_FLAG ? SUBDIRECTORY_RECORD : FILE_RECORD); + } + fill_sector(); + d->size = (cd.sector - d->sector) * SECTOR_SIZE; + number_of_directories++; + bytes_in_directories += d->size; + + // write file data + + for (q = d->first_record; q != NULL; q = q->next_in_directory) + { + if ((q->flags & DIRECTORY_FLAG) == 0) + { + q->sector = cd.sector; + size = q->size; + if (cd.file == NULL) + { + number_of_sectors = (size + SECTOR_SIZE - 1) / SECTOR_SIZE; + cd.sector += number_of_sectors; + number_of_files++; + bytes_in_files += size; + unused_bytes_at_ends_of_files += + number_of_sectors * SECTOR_SIZE - size; + } + else + { + old_end_source = end_source; + get_file_specifications(q); + *end_source = 0; + if (verbosity == VERBOSE) + printf("Writing %s\n", source); + file = fopen(source, "rb"); + if (file == NULL) + error_exit("Can't open %s\n", source); + fseek(file, 0, SEEK_SET); + while (size > 0) + { + n = BUFFER_SIZE - cd.count; + if ((DWORD) n > size) + n = size; + if (fread (cd.buffer + cd.count, n, 1, file) < 1) + { + fclose(file); + error_exit("Read error in file %s\n", source); + } + cd.count += n; + if (cd.count == BUFFER_SIZE) + flush_buffer(); + cd.sector += n / SECTOR_SIZE; + cd.offset += n % SECTOR_SIZE; + size -= n; + } + fclose(file); + end_source = old_end_source; + fill_sector(); + } + } + } + } + + total_sectors = (DWORD)cd.sector; +} + +static char HELP[] = + "CDMAKE [-q] [-v] [-p] [-s N] [-m] [-b bootimage] source volume image\n" + "\n" + " source specifications of base directory containing all files to\n" + " be written to CD-ROM image\n" + " volume volume label\n" + " image image file or device\n" + " -q quiet mode - display nothing but error messages\n" + " -v verbose mode - display file information as files are\n" + " scanned and written - overrides -p option\n" + " -p show progress while writing\n" + " -s N abort operation before beginning write if image will be\n" + " larger than N megabytes (i.e. 1024*1024*N bytes)\n" + " -m accept punctuation marks other than underscores in\n" + " names and extensions\n" + " -b bootimage create bootable ElTorito CD-ROM using 'no emulation' mode\n"; + +/*----------------------------------------------------------------------------- +Program execution starts here. +-----------------------------------------------------------------------------*/ + +int main(int argc, char **argv) +{ + BOOL q_option = FALSE; + BOOL v_option = FALSE; + int i; + char *t; + + if (argc < 2) + { + puts(HELP); + return 1; + } + + if (setjmp(error)) + return 1; + + // initialize root directory + + cd.buffer = malloc (BUFFER_SIZE); + if (cd.buffer == NULL) + error_exit("Insufficient memory"); + + memset(&root, 0, sizeof(root)); + root.level = 1; + root.flags = DIRECTORY_FLAG; + + // initialize CD-ROM write buffer + + cd.file = NULL; + cd.filespecs[0] = 0; + + // initialize parameters + + verbosity = NORMAL; + size_limit = 0; + show_progress = FALSE; + accept_punctuation_marks = FALSE; + source[0] = 0; + volume_label[0] = 0; + + eltorito = FALSE; + + // scan command line arguments + + for (i = 1; i < argc; i++) + { + if (memcmp(argv[i], "-s", 2) == 0) + { + t = argv[i] + 2; + if (*t == 0) + { + if (++i < argc) + t = argv[i]; + else + error_exit("Missing size limit parameter"); + } + while (isdigit(*t)) + size_limit = size_limit * 10 + *t++ - '0'; + if (size_limit < 1 || size_limit > 800) + error_exit("Invalid size limit"); + size_limit <<= 9; // convert megabyte to sector count + } + else if (strcmp(argv[i], "-q") == 0) + q_option = TRUE; + else if (strcmp(argv[i], "-v") == 0) + v_option = TRUE; + else if (strcmp(argv[i], "-p") == 0) + show_progress = TRUE; + else if (strcmp(argv[i], "-m") == 0) + accept_punctuation_marks = TRUE; + else if (strcmp(argv[i], "-b") == 0) + { + strcpy(bootimage, argv[++i]); + eltorito = TRUE; + } + else if (i + 2 < argc) + { + strcpy(source, argv[i++]); + strncpy(volume_label, argv[i++], sizeof(volume_label) - 1); + strcpy(cd.filespecs, argv[i]); + } + else + error_exit("Missing command line argument"); + } + if (v_option) + { + show_progress = FALSE; + verbosity = VERBOSE; + } + else if (q_option) + { + verbosity = QUIET; + show_progress = FALSE; + } + if (source[0] == 0) + error_exit("Missing source directory"); + if (volume_label[0] == 0) + error_exit("Missing volume label"); + if (cd.filespecs[0] == 0) + error_exit("Missing image file specifications"); + + + // set source[] and end_source to source directory, with a terminating directory separator + + end_source = source + strlen(source); + if (end_source[-1] == ':') + *end_source++ = '.'; + if (end_source[-1] != DIR_SEPARATOR_CHAR) + *end_source++ = DIR_SEPARATOR_CHAR; + + // scan all files and create directory structure in memory + + make_directory_records(&root); + + // sort path table entries + + root.next_in_path_table = sort_linked_list(root.next_in_path_table, 1, + compare_path_table_order); + + // initialize CD-ROM write buffer + + cd.file = NULL; + cd.sector = 0; + cd.offset = 0; + cd.count = 0; + + // make non-writing pass over directory structure to obtain the proper + // sector numbers and offsets and to determine the size of the image + + number_of_files = bytes_in_files = number_of_directories = + bytes_in_directories = unused_bytes_at_ends_of_files =0; + pass(); + + if (verbosity >= NORMAL) + { + printf("%s bytes ", edit_with_commas(bytes_in_files, TRUE)); + printf("in %s files\n", edit_with_commas(number_of_files, FALSE)); + printf("%s unused bytes at ends of files\n", + edit_with_commas(unused_bytes_at_ends_of_files, TRUE)); + printf("%s bytes ", edit_with_commas(bytes_in_directories, TRUE)); + printf("in %s directories\n", + edit_with_commas(number_of_directories, FALSE)); + printf("%s other bytes\n", edit_with_commas(root.sector * SECTOR_SIZE, TRUE)); + puts("-------------"); + printf("%s total bytes\n", + edit_with_commas(total_sectors * SECTOR_SIZE, TRUE)); + puts("============="); + } + + if (size_limit != 0 && total_sectors > size_limit) + error_exit("Size limit exceeded"); + + // re-initialize CD-ROM write buffer + + cd.file = fopen(cd.filespecs, "w+b"); + if (cd.file == NULL) + error_exit("Can't open image file %s", cd.filespecs); + cd.sector = 0; + cd.offset = 0; + cd.count = 0; + + + // make writing pass over directory structure + + pass(); + + if (cd.count > 0) + flush_buffer(); + if (show_progress) + printf("\r \n"); + if (fclose(cd.file) != 0) + { + cd.file = NULL; + error_exit("File write error in image file %s", cd.filespecs); + } + + if (verbosity >= NORMAL) + puts("CD-ROM image made successfully"); + + release_memory(); + return 0; +} + +/* EOF */ diff --git a/tools/cdmake/llmosrt.c b/tools/cdmake/llmosrt.c new file mode 100644 index 0000000..ef2e179 --- /dev/null +++ b/tools/cdmake/llmosrt.c @@ -0,0 +1,106 @@ +/* $Id$ */ +/* A Linked-List Memory Sort + by Philip J. Erdelsky + pje@acm.org + http://www.alumni.caltech.edu/~pje/ +*/ + +/* According to his website, this file was released into the public domain by Phillip J. Erdelsky */ + + +#include + +void *sort_linked_list(void *p, unsigned index, int (*compare)(void *, void *)) +{ + unsigned base; + unsigned long block_size; + + struct record + { + struct record *next[1]; + /* other members not directly accessed by this function */ + }; + + struct tape + { + struct record *first, *last; + unsigned long count; + } tape[4]; + + /* Distribute the records alternately to tape[0] and tape[1]. */ + + tape[0].count = tape[1].count = 0L; + tape[0].first = NULL; + base = 0; + while (p != NULL) + { + struct record *next = ((struct record *)p)->next[index]; + ((struct record *)p)->next[index] = tape[base].first; + tape[base].first = ((struct record *)p); + tape[base].count++; + p = next; + base ^= 1; + } + + /* If the list is empty or contains only a single record, then */ + /* tape[1].count == 0L and this part is vacuous. */ + + for (base = 0, block_size = 1L; tape[base+1].count != 0L; + base ^= 2, block_size <<= 1) + { + int dest; + struct tape *tape0, *tape1; + tape0 = tape + base; + tape1 = tape + base + 1; + dest = base ^ 2; + tape[dest].count = tape[dest+1].count = 0; + for (; tape0->count != 0; dest ^= 1) + { + unsigned long n0, n1; + struct tape *output_tape = tape + dest; + n0 = n1 = block_size; + while (1) + { + struct record *chosen_record; + struct tape *chosen_tape; + if (n0 == 0 || tape0->count == 0) + { + if (n1 == 0 || tape1->count == 0) + break; + chosen_tape = tape1; + n1--; + } + else if (n1 == 0 || tape1->count == 0) + { + chosen_tape = tape0; + n0--; + } + else if ((*compare)(tape0->first, tape1->first) > 0) + { + chosen_tape = tape1; + n1--; + } + else + { + chosen_tape = tape0; + n0--; + } + chosen_tape->count--; + chosen_record = chosen_tape->first; + chosen_tape->first = chosen_record->next[index]; + if (output_tape->count == 0) + output_tape->first = chosen_record; + else + output_tape->last->next[index] = chosen_record; + output_tape->last = chosen_record; + output_tape->count++; + } + } + } + + if (tape[base].count > 1L) + tape[base].last->next[index] = NULL; + return tape[base].first; +} + +/* EOF */ diff --git a/tools/cdmake/readme.txt b/tools/cdmake/readme.txt new file mode 100644 index 0000000..fd0301b --- /dev/null +++ b/tools/cdmake/readme.txt @@ -0,0 +1,94 @@ + CD-ROM Maker + Philip J. Erdelsky + +The CDMAKE utility converts files from DOS/Windows format to ISO9660 +(CD-ROM) format. + +First, gather all the files to be converted and put them into a single +base directory and its subdirectories, arranged just the way you want +them on the CD-ROM. Remember that ISO9660 allows subdirectories to be +nested only eight levels deep. Therefore, if the base directory is +C:\CDROM, + + C:\CDROM\D2\D3\D4\D5\D6\D7\D8\FOO.TXT is permitted, but + + C:\CDROM\D2\D3\D4\D5\D6\D7\D8\D9\FOO.TXT is forbidden. + +Also, ISO9660 does not allow directories to have extensions, although +DOS does. + +Finally, the characters in file and directory names and file extensions +must be letters, digits or underscores. Other punctuation marks +permitted by DOS/Windows are forbidden by ISO9660. You can use the -c +option to override this restriction, but the resulting CD-ROM may not be +readable on systems other than DOS/Windows. + +Files in the base directory will be written to the root directory of the +CD-ROM image. All subdirectories of the base directory will appear as +subdirectories of the root directory of the CD-ROM image. Their +contents, and the contents of their subdirectories, down to the eighth +level, will be faithfully copied to the CD-ROM image. + +System files will not be written to the CD-ROM image. Hidden files will +be written to the CD-ROM image, and will retain their hidden attributes. +Read-only files will be written, and will remain read-only on the +CD-ROM, but this does not distinguish them in any way, because on a +CD-ROM all files are read-only. The archive attribute will be lost. + +File and directory date and time stamps will be preserved in the CD-ROM +image. + +The utility is called up by a command line of the following form: + + CDMAKE [-q] [-v] [-p] [-s N] [-m] [-b bootimage] source volume image + + source specifications of base directory containing all files to + be written to CD-ROM image + + volume volume label + + image image file or device + + -q quiet mode - display nothing but error messages + + -v verbose mode - display file information as files are + scanned and written - overrides -p option + + -p show progress while writing + + -s N abort operation before beginning write if image will be + larger than N megabytes (i.e. 1024*1024*N bytes) + + -m accept punctuation marks other than underscores in + names and extensions + + -b bootimage create bootable ElTorito CD-ROM using 'no emulation' mode + + +The utility makes three passes over the source files: + + (1) The scanning pass, in which the names and extensions are + checked for validity, and the names, extensions, sizes, dates, + times and attributes are recorded internally. The files are not + actually read during this pass. + + (2) The layout pass, in which the sizes and positions of + directories, files and other items in the CD-ROM image are + determined. + + (3) The writing pass, in which the files are actually read and the + CD-ROM image is actually written to the specified file or + device. The image is always written sequentially. + +If neither the -q nor the -v option is used, CDMAKE will display the +volume label, size, number of files and directories and the total bytes +in each at the end of the layout pass. + +If the -p option is used, and is not overridden by the -v option, then +during the writing pass, CDMAKE will display the number of bytes still +to be written to the CD-ROM image, updating it frequently. The number +will decrease as the operation progresses, and will reach zero when the +operation is complete. + +The operation of CDMAKE can be aborted by typing Ctrl-C when the utility +is displaying text of any kind. diff --git a/tools/helper.mk b/tools/helper.mk index 646bdd9..f505a5a 100644 --- a/tools/helper.mk +++ b/tools/helper.mk @@ -14,13 +14,15 @@ # bootpgm = Boot program # miniport = Kernel mode driver that does not link with ntoskrnl.exe or hal.dll # gdi_driver = Kernel mode graphics driver that link with win32k.sys +# subsystem = Kernel subsystem +# kmdll = Kernel mode DLL # $TARGET_APPTYPE = Application type (windows,native,console) # $TARGET_NAME = Base name of output file and .rc, .def, and .edf files # $TARGET_OBJECTS = Object files that compose the module # $TARGET_HEADERS = Header files that the object files depend on (optional) # $TARGET_DEFNAME = Base name of .def and .edf files (optional) # $TARGET_BASENAME = Base name of output file (overrides $TARGET_NAME if it exists) (optional) -# $TARGET_EXTENSION = Extesion of the output file (optional) +# $TARGET_EXTENSION = Extension of the output file (optional) # $TARGET_DDKLIBS = DDK libraries that are to be imported by the module (optional) # $TARGET_SDKLIBS = SDK libraries that are to be imported by the module (optional) # $TARGET_LIBS = Other libraries that are to be imported by the module (optional) @@ -40,6 +42,8 @@ # $TARGET_LIBPATH = Destination path for import libraries (optional) # $TARGET_INSTALLDIR = Destination path when installed (optional) # $TARGET_PCH = Filename of header to use to generate a PCH if supported by the compiler (optional) +# $TARGET_BOOTSTRAP = Wether this file is needed to bootstrap the installation (no,yes) (optional) +# $TARGET_BOOTSTRAP_NAME = Name on the installation medium (optional) # $WINE_MODE = Compile using WINE headers (no,yes) (optional) # $WINE_RC = Name of .rc file for WINE modules (optional) @@ -50,6 +54,26 @@ ifeq ($(TARGET_PATH),) TARGET_PATH := . endif +ifeq ($(ARCH),i386) + MK_ARCH_ID := _M_IX86 +endif + +ifeq ($(ARCH),alpha) + MK_ARCH_ID := _M_ALPHA +endif + +ifeq ($(ARCH),mips) + MK_ARCH_ID := _M_MIPS +endif + +ifeq ($(ARCH),powerpc) + MK_ARCH_ID := _M_PPC +endif + +# unknown architecture +ifeq ($(MK_ARCH_ID),) + MK_ARCH_ID := _M_UNKNOWN +endif ifeq ($(TARGET_TYPE),program) MK_MODE := user @@ -72,6 +96,7 @@ endif MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := .a MK_INSTALLDIR := bin + MK_BOOTCDDIR := system32 MK_DISTDIR := apps ifeq ($(WINE_RC),) MK_RES_BASE := $(TARGET_NAME) @@ -95,6 +120,7 @@ ifeq ($(TARGET_TYPE),proglib) MK_IMPLIBDEFPATH := $(SDK_PATH_LIB) MK_IMPLIB_EXT := .a MK_INSTALLDIR := bin + MK_BOOTCDDIR := system32 MK_DISTDIR := apps MK_RES_BASE := $(TARGET_NAME) endif @@ -120,6 +146,7 @@ endif MK_IMPLIBDEFPATH := $(SDK_PATH_LIB) MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32 + MK_BOOTCDDIR := system32 MK_DISTDIR := dlls ifeq ($(WINE_RC),) MK_RES_BASE := $(TARGET_NAME) @@ -129,6 +156,7 @@ endif endif ifeq ($(TARGET_TYPE),library) + TARGET_NORC := yes MK_MODE := static MK_EXETYPE := MK_DEFEXT := .a @@ -142,8 +170,9 @@ ifeq ($(TARGET_TYPE),library) MK_IMPLIBONLY := no MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := - MK_INSTALLDIR := system32 - MK_DISTDIR := # FIXME + MK_INSTALLDIR := # none + MK_BOOTCDDIR := system32 + MK_DISTDIR := # none MK_RES_BASE := endif @@ -162,6 +191,7 @@ ifeq ($(TARGET_TYPE),driver_library) MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) MK_IMPLIB_EXT := .a MK_INSTALLDIR := $(DDK_PATH_INC) + MK_BOOTCDDIR := . MK_DISTDIR := # FIXME MK_RES_BASE := endif @@ -181,6 +211,7 @@ ifeq ($(TARGET_TYPE),driver) MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32/drivers + MK_BOOTCDDIR := . MK_DISTDIR := drivers MK_RES_BASE := $(TARGET_NAME) endif @@ -200,6 +231,7 @@ ifeq ($(TARGET_TYPE),export_driver) MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32/drivers + MK_BOOTCDDIR := . MK_DISTDIR := drivers MK_RES_BASE := $(TARGET_NAME) endif @@ -219,6 +251,7 @@ ifeq ($(TARGET_TYPE),hal) MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32 + MK_BOOTCDDIR := . MK_DISTDIR := dlls MK_RES_BASE := $(TARGET_NAME) endif @@ -238,6 +271,7 @@ ifeq ($(TARGET_TYPE),bootpgm) MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32 + MK_BOOTCDDIR := system32 MK_DISTDIR := # FIXME MK_RES_BASE := $(TARGET_NAME) endif @@ -257,6 +291,7 @@ ifeq ($(TARGET_TYPE),miniport) MK_IMPLIBDEFPATH := MK_IMPLIB_EXT := .a MK_INSTALLDIR := system32/drivers + MK_BOOTCDDIR := . MK_DISTDIR := drivers MK_RES_BASE := $(TARGET_NAME) endif @@ -275,8 +310,9 @@ ifeq ($(TARGET_TYPE),gdi_driver) MK_IMPLIBONLY := no MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) MK_IMPLIB_EXT := .a - MK_INSTALLDIR := system32/drivers - MK_DISTDIR := drivers + MK_INSTALLDIR := system32 + MK_BOOTCDDIR := . + MK_DISTDIR := dlls MK_RES_BASE := $(TARGET_NAME) endif @@ -321,6 +357,44 @@ ifeq ($(TARGET_TYPE),proglib) endif endif +ifeq ($(TARGET_TYPE),subsystem) + MK_MODE := kernel + MK_EXETYPE := dll + MK_DEFEXT := .sys + MK_DEFENTRY := _DriverEntry@8 + MK_DDKLIBS := ntoskrnl.a hal.a + MK_SDKLIBS := + MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_RCFLAGS := --include-dir $(SDK_PATH_INC) + MK_IMPLIB := yes + MK_IMPLIBONLY := no + MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) + MK_IMPLIB_EXT := .a + MK_INSTALLDIR := system32 + MK_DISTDIR := drivers + MK_RES_BASE := $(TARGET_NAME) +endif + +ifeq ($(TARGET_TYPE),kmdll) + MK_MODE := kernel + MK_EXETYPE := dll + MK_DEFEXT := .dll + MK_DEFENTRY := 0x0 + MK_DDKLIBS := ntoskrnl.a hal.a + MK_SDKLIBS := + MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_RCFLAGS := --include-dir $(SDK_PATH_INC) + MK_IMPLIB := yes + MK_IMPLIBONLY := no + MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) + MK_IMPLIB_EXT := .a + MK_INSTALLDIR := system32 + MK_DISTDIR := drivers + MK_RES_BASE := $(TARGET_NAME) +endif + MK_RESOURCE := $(MK_RES_BASE).coff @@ -330,6 +404,11 @@ ifneq ($(TARGET_INSTALLDIR),) endif +ifneq ($(BOOTCD_INSTALL),) + MK_INSTALLDIR := . +endif + + ifeq ($(TARGET_LIBPATH),) MK_IMPLIBPATH := $(MK_IMPLIBDEFPATH) else @@ -388,6 +467,11 @@ ifeq ($(MK_MODE),kernel) endif +ifneq ($(TARGET_LIBS),) + MK_LIBS := $(TARGET_LIBS) $(MK_LIBS) +endif + + ifeq ($(TARGET_BASE),) TARGET_BASE := $(MK_DEFBASE) endif @@ -404,8 +488,9 @@ endif include $(PATH_TO_TOP)/config +TARGET_ASFLAGS += -march=$(ARCH) -D$(MK_ARCH_ID) TARGET_CFLAGS += $(MK_CFLAGS) -TARGET_CFLAGS += -pipe -march=$(ARCH) +TARGET_CFLAGS += -pipe -march=$(ARCH) -D$(MK_ARCH_ID) ifeq ($(DBG),1) TARGET_ASFLAGS += -g TARGET_CFLAGS += -g @@ -413,7 +498,7 @@ TARGET_LFLAGS += -g endif TARGET_CPPFLAGS += $(MK_CPPFLAGS) -TARGET_CPPFLAGS += -pipe -march=$(ARCH) +TARGET_CPPFLAGS += -pipe -march=$(ARCH) -D$(MK_ARCH_ID) TARGET_RCFLAGS += $(MK_RCFLAGS) @@ -425,7 +510,12 @@ TARGET_NFLAGS += $(MK_NFLAGS) MK_GCCLIBS := $(addprefix -l, $(TARGET_GCCLIBS)) -MK_FULLNAME := $(MK_BASENAME)$(MK_EXT) +ifeq ($(MK_MODE),static) + MK_FULLNAME := $(SDK_PATH_LIB)/$(MK_BASENAME)$(MK_EXT) +else + MK_FULLNAME := $(MK_BASENAME)$(MK_EXT) +endif + MK_IMPLIB_FULLNAME := $(MK_BASENAME)$(MK_IMPLIB_EXT) MK_NOSTRIPNAME := $(MK_BASENAME).nostrip$(MK_EXT) @@ -563,6 +653,12 @@ ifeq ($(MK_MODE),static) $(MK_FULLNAME): $(TARGET_OBJECTS) $(AR) -r $(MK_FULLNAME) $(TARGET_OBJECTS) +# Static libraries dont have a nostrip version +$(MK_NOSTRIPNAME): + - + +.phony: $(MK_NOSTRIPNAME) + endif # MK_MODE endif # MK_IMPLIBONLY @@ -601,7 +697,7 @@ ifneq ($(TARGET_HEADERS),) $(TARGET_OBJECTS): $(TARGET_HEADERS) endif -# install and dist rules +# install, dist and bootcd rules ifeq ($(MK_IMPLIBONLY),yes) @@ -611,15 +707,46 @@ install: dist: +bootcd: + else # MK_IMPLIBONLY +# Don't install static libraries +ifeq ($(MK_MODE),static) + +install: + - + +else # MK_MODE + install: $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME) +endif # MK_MODE + + +ifeq ($(INSTALL_SYMBOLS),no) + +$(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME): + $(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME) + +else # INSTALL_SYMBOLS + +# Don't install static libraries +ifeq ($(MK_MODE),static) + +install: + - + +else # MK_MODE + $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(MK_BASENAME).sym $(CP) $(MK_FULLNAME) $(INSTALL_DIR)/$(MK_INSTALLDIR)/$(MK_FULLNAME) $(CP) $(MK_BASENAME).sym $(INSTALL_DIR)/symbols/$(MK_BASENAME).sym +endif # MK_MODE + +endif # INSTALL_SYMBOLS dist: $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME) @@ -627,10 +754,30 @@ $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME): $(MK_FULLNAME) $(CP) $(MK_FULLNAME) $(DIST_DIR)/$(MK_DISTDIR)/$(MK_FULLNAME) $(CP) $(MK_BASENAME).sym $(DIST_DIR)/symbols/$(MK_BASENAME).sym +# Bootstrap files for the bootable CD +ifeq ($(TARGET_BOOTSTRAP),yes) + +ifneq ($(TARGET_BOOTSTRAP_NAME),) +MK_BOOTSTRAP_NAME := $(TARGET_BOOTSTRAP_NAME) +else # TARGET_BOOTSTRAP_NAME +MK_BOOTSTRAP_NAME := $(MK_FULLNAME) +endif # TARGET_BOOTSTRAP_NAME + +bootcd: $(BOOTCD_DIR)/reactos/$(MK_BOOTCDDIR)/$(MK_BOOTSTRAP_NAME) + +$(BOOTCD_DIR)/reactos/$(MK_BOOTCDDIR)/$(MK_BOOTSTRAP_NAME): + $(CP) $(MK_FULLNAME) $(BOOTCD_DIR)/reactos/$(MK_BOOTCDDIR)/$(MK_BOOTSTRAP_NAME) + +else # TARGET_BOOTSTRAP + +bootcd: + +endif # TARGET_BOOTSTRAP + endif # MK_IMPLIBONLY -.phony: all depends implib clean install dist depends +.phony: all depends implib clean install dist bootcd depends # Precompiled header support diff --git a/tools/mkflpimg.c b/tools/mkflpimg.c new file mode 100644 index 0000000..5f5defe --- /dev/null +++ b/tools/mkflpimg.c @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include + +#define N_CYLINDERS 80 +#define ROOT_ENTRY_SIZE 32 + +#define SECTOR_SIZE 512 +#define SECTORS_PER_CLUSTER 1 +#define N_RESERVED 1 +#define N_FATS 2 +#define N_ROOT_ENTRIES 224 +#define SECTORS_PER_DISK (N_HEADS * N_CYLINDERS * SECTORS_PER_TRACK) +#define MEDIA_TYPE 0xf0 +#define SECTORS_PER_FAT 9 +#define SECTORS_PER_TRACK 18 +#define N_HEADS 2 +#define SIGNATURE 0x29 /* only MS? */ +#define END_SIGNATURE 0xaa55 + + +#define ATTR_READONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME 0x08 +#define ATTR_SUBDIR 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_RES1 0x40 +#define ATTR_RES2 0x80 + + +typedef unsigned char disk_sector_t[SECTOR_SIZE]; + +typedef struct boot_sector +{ + unsigned short jmp; + unsigned char nop; + char oem[8]; + unsigned short bytes_per_sector; + unsigned char sectors_per_cluster; + unsigned short reserved_sectors; + unsigned char n_fats; + unsigned short n_root_entries; + unsigned short n_sectors; + unsigned char media_type; + unsigned short sectors_per_fat; + unsigned short sectors_per_track; + unsigned short n_heads; + unsigned long hidden_sectors; + unsigned long huge_sectors; + unsigned char drive; + unsigned char reserved; + unsigned char signature; + unsigned long volume_id; + char volume_label[11]; + char file_system[8]; + unsigned char boot_code[SECTOR_SIZE - 62 - 2]; + unsigned short end_signature; +} __attribute__ ((packed)) boot_sector_t; + + +typedef struct root_entry +{ + char name[8]; + char extension[3]; + unsigned char attribute; + unsigned char reserved[10]; + unsigned short time; + unsigned short date; + unsigned short cluster; + unsigned long size; +} __attribute ((packed)) root_entry_t; + + +disk_sector_t *new_image(char *bsfname) +{ + FILE *bsf; + disk_sector_t *img; + boot_sector_t boot_sec; + root_entry_t *root; + + if ((bsf = fopen(bsfname, "rb")) == NULL) + { + printf("Boot sector image file %s not found!\n", bsfname); + return NULL; + } + if (fread(&boot_sec, 1, SECTOR_SIZE, bsf) != SECTOR_SIZE) + { + printf("Unable to read boot sector image file %s!\n", bsfname); + fclose(bsf); + return NULL; + } + fclose(bsf); + + if ( (boot_sec.bytes_per_sector != SECTOR_SIZE) || + (boot_sec.sectors_per_cluster != SECTORS_PER_CLUSTER) || + (boot_sec.reserved_sectors != N_RESERVED) || + (boot_sec.n_fats != N_FATS) || + (boot_sec.n_root_entries != N_ROOT_ENTRIES) || + (boot_sec.n_sectors != SECTORS_PER_DISK) || + (boot_sec.media_type != MEDIA_TYPE) || + (boot_sec.sectors_per_fat != SECTORS_PER_FAT) || + (boot_sec.sectors_per_track != SECTORS_PER_TRACK) || + (boot_sec.n_heads != N_HEADS) || +// (boot_sec.signature != SIGNATURE) || + (boot_sec.end_signature != END_SIGNATURE) ) + { + printf("Invalid boot sector in file %s\n", bsfname); + return NULL; + } + + if ((img = (disk_sector_t *)malloc(SECTOR_SIZE * SECTORS_PER_DISK)) == NULL) + { + printf("Not enough memory!\n"); + return NULL; + } + + memset(img, 0, SECTOR_SIZE * SECTORS_PER_TRACK); + memcpy(img, &boot_sec, SECTOR_SIZE); + + root = (root_entry_t *)img[N_RESERVED + N_FATS * SECTORS_PER_FAT]; + strncpy(root->name, "REACTOS ", 11); + root->attribute = ATTR_VOLUME; + + return img; +} + + +void create_root_entry(root_entry_t *root, char *fname, + unsigned short cluster, unsigned long size) +{ + int i, j; + time_t t; + struct tm *localt; + + i = 0; + j = 0; + while ((fname[j] != '\0') && (fname[j] != '.') && (i < 8)) + { + root->name[i] = toupper(fname[j]); + i++; + j++; + } + while (i < 8) + { + root->name[i] = ' '; + i++; + } + if (fname[j] == '.') + { + i = 0; + j++; + while ((fname[j] != '\0') && (i < 3)) + { + root->extension[i] = toupper(fname[j]); + i++; + j++; + } + while (i < 3) + { + root->extension[i] = ' '; + i++; + } + } + else + { + i = 0; + while (i < 3) + { + root->extension[i] = ' '; + i++; + } + } + + root->attribute = ATTR_ARCHIVE; + t = time(0); + localt = localtime(&t); + root->time = (((localt->tm_hour & 0x001f) << 11) | + ((localt->tm_min & 0x003f) << 5) | + ((localt->tm_sec / 2) & 0x001f)); + root->date = ((((localt->tm_year - 80) & 0x007f) << 9) | + (((localt->tm_mon + 1) & 0x000f) << 5) | + (localt->tm_mday & 0x001f)); + root->cluster = cluster; + root->size = size; +} + + +void update_fat(unsigned char *fat, int cl_start, int cl_end) +{ + int i, k; + unsigned short *cl; + + for (i = cl_start; i < cl_end - 1; i++) + { + k = (i - 2) * 3 / 2; + cl = ((unsigned short *)&fat[k]); + if (i & 1) + { + *cl = (*cl & 0x000f) | (((i + 1) & 0x0fff) << 4); + } + else + { + *cl = (*cl & 0xf000) | ((i + 1) & 0x0fff); + } + } + k = (i - 2) * 3 / 2; + cl = ((unsigned short *)&fat[k]); + if (i & 1) + { + *cl = (*cl & 0x000f) | 0xfff0; + } + else + { + *cl = (*cl & 0xf000) | 0x0fff; + } +} + + +int copy_files(disk_sector_t *img, char *filenames[], int n_files) +{ + int i, k; + FILE *f; + int cl_start, cl_end; + unsigned char *fat1, *fat2; + root_entry_t *root; + unsigned long n, size; + + fat1 = (unsigned char *)img[N_RESERVED]; + fat2 = (unsigned char *)img[N_RESERVED + SECTORS_PER_FAT]; + root = (root_entry_t *)img[N_RESERVED + N_FATS * SECTORS_PER_FAT]; + + k = N_RESERVED + + N_FATS * SECTORS_PER_FAT + + N_ROOT_ENTRIES * ROOT_ENTRY_SIZE / SECTOR_SIZE; + + cl_end = 1; + + if (n_files > N_ROOT_ENTRIES) + { + n_files = N_ROOT_ENTRIES; + } + + for (i = 0; i < n_files; i++) + { + cl_start = cl_end + 1; + if ((f = fopen(filenames[i], "rb")) == NULL) + { + printf("Error opening file %s!", filenames[i]); + return 1; + } + + printf(" %s\n", filenames[i]); + + size = 0; + while ((n = fread(img[k], 1, SECTOR_SIZE, f)) > 0) + { + size += n; + cl_end++; + k++; + } + fclose(f); + + root++; + create_root_entry(root, filenames[i], cl_start, size); + + update_fat(fat1, cl_start, cl_end); + } + memcpy(fat2, fat1, SECTORS_PER_FAT * SECTOR_SIZE); + + return 0; +} + + +int write_image(disk_sector_t *img, char *imgname) +{ + FILE *f; + + if ((f = fopen(imgname, "rb")) != NULL) + { + printf("Image file %s already exists!\n", imgname); + fclose(f); + free(img); + return 1; + } + + f = fopen(imgname, "wb"); + if (fwrite(img, SECTOR_SIZE, SECTORS_PER_DISK, f) != SECTORS_PER_DISK) + { + printf("Unable to write image file %s\n!", imgname); + fclose(f); + free(img); + return 1; + } + fclose(f); + + free(img); + return 0; +} + + +int main(int argc, char *argv[]) +{ + disk_sector_t *img; + char *imgname; + char *bsfname; + char **filenames; + int n_files; + + if (argc < 4) + { + printf("Usage: mkflpimg \n"); + return 1; + } + + imgname = argv[1]; + bsfname = argv[2]; + filenames = &argv[3]; + n_files = argc - 3; + + printf("Creating image ...\n"); + if ((img = new_image(bsfname)) == NULL) + { + return 1; + } + + printf("Copying files ...\n"); + + if (copy_files(img, filenames, n_files)) + { + return 1; + } + + printf("Writing image file ...\n"); + + if (write_image(img, imgname)) + { + return 1; + } + + printf("Finished.\n"); + + return 0; +} + diff --git a/tools/mkhive/.cvsignore b/tools/mkhive/.cvsignore new file mode 100644 index 0000000..f6a0ee6 --- /dev/null +++ b/tools/mkhive/.cvsignore @@ -0,0 +1,2 @@ +*.exe +mkhive diff --git a/tools/mkhive/Makefile b/tools/mkhive/Makefile new file mode 100644 index 0000000..cb50408 --- /dev/null +++ b/tools/mkhive/Makefile @@ -0,0 +1,49 @@ +# +# Hive-Maker +# +PATH_TO_TOP = ../.. + +TARGET = mkhive$(EXE_POSTFIX) + +all: $(TARGET) + +OBJECTS = mkhive.o binhive.o infcache.o reginf.o registry.o + +CLEAN_FILES = *.o mkhive$(EXE_POSTFIX) + +HOST_CFLAGS = -I. + +mkhive.o: mkhive.c + $(HOST_CC) $(HOST_CFLAGS) -c mkhive.c -o mkhive.o + +binhive.o: binhive.c + $(HOST_CC) $(HOST_CFLAGS) -c binhive.c -o binhive.o + +infcache.o: infcache.c + $(HOST_CC) $(HOST_CFLAGS) -c infcache.c -o infcache.o + +reginf.o: reginf.c + $(HOST_CC) $(HOST_CFLAGS) -c reginf.c -o reginf.o + +registry.o: registry.c + $(HOST_CC) $(HOST_CFLAGS) -c registry.c -o registry.o + +mkhive$(EXE_POSTFIX): $(OBJECTS) + $(HOST_CC) $(OBJECTS) -o mkhive$(EXE_POSTFIX) + +ifeq ($(HOST),mingw32-linux) +clean: + rm -f *.o + rm -f mkhive$(EXE_POSTFIX) +endif +ifeq ($(HOST),mingw32-windows) +clean: + del *.o + del mkhive$(EXE_POSTFIX) +endif + +.phony: clean + +include $(PATH_TO_TOP)/rules.mak + +# EOF diff --git a/tools/mkhive/binhive.c b/tools/mkhive/binhive.c new file mode 100644 index 0000000..cdae158 --- /dev/null +++ b/tools/mkhive/binhive.c @@ -0,0 +1,1385 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/binhive.c + * PURPOSE: Binary hive export code + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +//#include +#include +#include + +#include "mkhive.h" +#include "binhive.h" +#include "registry.h" + + +#define REG_HIVE_ID 0x66676572 +#define REG_BIN_ID 0x6e696268 +#define REG_KEY_CELL_ID 0x6b6e +#define REG_HASH_TABLE_BLOCK_ID 0x666c +#define REG_VALUE_CELL_ID 0x6b76 + +#define REG_BLOCK_SIZE 4096 +#define REG_HBIN_DATA_OFFSET 32 +#define REG_INIT_BLOCK_LIST_SIZE 32 +#define REG_INIT_HASH_TABLE_SIZE 3 +#define REG_EXTEND_HASH_TABLE_SIZE 4 +#define REG_VALUE_LIST_CELL_MULTIPLE 4 + +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) +#define ROUND_DOWN(N, S) ((N) - ((N) % (S))) + +#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V)) + + +// BLOCK_OFFSET = offset in file after header block +typedef ULONG BLOCK_OFFSET, *PBLOCK_OFFSET; + +typedef unsigned long long FILETIME; + +/* header for registry hive file : */ +typedef struct _HIVE_HEADER +{ + /* Hive identifier "regf" (0x66676572) */ + ULONG BlockId; + + /* Update counter */ + ULONG UpdateCounter1; + + /* Update counter */ + ULONG UpdateCounter2; + + /* When this hive file was last modified */ + FILETIME DateModified; + + /* Registry format version ? (1?) */ + ULONG Unused3; + + /* Registry format version ? (3?) */ + ULONG Unused4; + + /* Registry format version ? (0?) */ + ULONG Unused5; + + /* Registry format version ? (1?) */ + ULONG Unused6; + + /* Offset into file from the byte after the end of the base block. + If the hive is volatile, this is the actual pointer to the KEY_CELL */ + BLOCK_OFFSET RootKeyCell; + + /* Size of each hive block ? */ + ULONG BlockSize; + + /* (1?) */ + ULONG Unused7; + + /* Name of hive file */ + WCHAR FileName[64]; + + /* ? */ + ULONG Unused8[83]; + + /* Checksum of first 0x200 bytes */ + ULONG Checksum; +} __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER; + +typedef struct _HBIN +{ + /* Bin identifier "hbin" (0x6E696268) */ + ULONG BlockId; + + /* Block offset of this bin */ + BLOCK_OFFSET BlockOffset; + + /* Size in bytes, multiple of the block size (4KB) */ + ULONG BlockSize; + + /* ? */ + ULONG Unused1; + + /* When this bin was last modified */ + FILETIME DateModified; + + /* ? */ + ULONG Unused2; +} __attribute__((packed)) HBIN, *PHBIN; + +typedef struct _CELL_HEADER +{ + /* <0 if used, >0 if free */ + LONG CellSize; +} __attribute__((packed)) CELL_HEADER, *PCELL_HEADER; + +typedef struct _KEY_CELL +{ + /* Size of this cell */ + LONG CellSize; + + /* Key cell identifier "kn" (0x6b6e) */ + USHORT Id; + + /* ? */ + USHORT Type; + + /* Time of last flush */ + FILETIME LastWriteTime; + + /* ? */ + ULONG UnUsed1; + + /* Block offset of parent key cell */ + BLOCK_OFFSET ParentKeyOffset; + + /* Count of sub keys for the key in this key cell */ + ULONG NumberOfSubKeys; + + /* ? */ + ULONG UnUsed2; + + /* Block offset of has table for FIXME: subkeys/values? */ + BLOCK_OFFSET HashTableOffset; + + /* ? */ + ULONG UnUsed3; + + /* Count of values contained in this key cell */ + ULONG NumberOfValues; + + /* Block offset of VALUE_LIST_CELL */ + BLOCK_OFFSET ValuesOffset; + + /* Block offset of security cell */ + BLOCK_OFFSET SecurityKeyOffset; + + /* Block offset of registry key class */ + BLOCK_OFFSET ClassNameOffset; + + /* ? */ + ULONG Unused4[5]; + + /* Size in bytes of key name */ + USHORT NameSize; + + /* Size of class name in bytes */ + USHORT ClassSize; + + /* Name of key (not zero terminated) */ + UCHAR Name[0]; +} __attribute__((packed)) KEY_CELL, *PKEY_CELL; + +/* KEY_CELL.Type constants */ +#define REG_LINK_KEY_CELL_TYPE 0x10 +#define REG_KEY_CELL_TYPE 0x20 +#define REG_ROOT_KEY_CELL_TYPE 0x2c + + +// hash record : +// HashValue=four letters of value's name +typedef struct _HASH_RECORD +{ + BLOCK_OFFSET KeyOffset; + ULONG HashValue; +} __attribute__((packed)) HASH_RECORD, *PHASH_RECORD; + +typedef struct _HASH_TABLE_CELL +{ + LONG CellSize; + USHORT Id; + USHORT HashTableSize; + HASH_RECORD Table[0]; +} __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL; + +typedef struct _VALUE_LIST_CELL +{ + LONG CellSize; + BLOCK_OFFSET Values[0]; +} __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL; + +typedef struct _VALUE_CELL +{ + LONG CellSize; + USHORT Id; // "kv" + USHORT NameSize; // length of Name + LONG DataSize; // length of datas in the cell pointed by DataOffset + BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set + ULONG DataType; + USHORT Flags; + USHORT Unused1; + UCHAR Name[0]; /* warning : not zero terminated */ +} __attribute__((packed)) VALUE_CELL, *PVALUE_CELL; + +/* VALUE_CELL.Flags constants */ +#define REG_VALUE_NAME_PACKED 0x0001 + + +typedef struct _DATA_CELL +{ + LONG CellSize; + UCHAR Data[0]; +} __attribute__((packed)) DATA_CELL, *PDATA_CELL; + +typedef struct _REGISTRY_HIVE +{ + ULONG FileSize; + PHIVE_HEADER HiveHeader; + ULONG BlockListSize; + PHBIN *BlockList; + ULONG FreeListSize; + ULONG FreeListMax; + PCELL_HEADER *FreeList; + BLOCK_OFFSET *FreeListOffset; +} REGISTRY_HIVE, *PREGISTRY_HIVE; + +/* FUNCTIONS ****************************************************************/ + +static VOID +CmiCreateDefaultHiveHeader(PHIVE_HEADER Header) +{ + assert(Header); + memset (Header, 0, REG_BLOCK_SIZE); + Header->BlockId = REG_HIVE_ID; + Header->UpdateCounter1 = 0; + Header->UpdateCounter2 = 0; + Header->DateModified = 0ULL; + Header->Unused3 = 1; + Header->Unused4 = 3; + Header->Unused5 = 0; + Header->Unused6 = 1; + Header->Unused7 = 1; + Header->RootKeyCell = 0; + Header->BlockSize = REG_BLOCK_SIZE; + Header->Unused6 = 1; + Header->Checksum = 0; +} + + +static VOID +CmiCreateDefaultBinCell(PHBIN BinCell) +{ + assert(BinCell); + memset (BinCell, 0, REG_BLOCK_SIZE); + BinCell->BlockId = REG_BIN_ID; + BinCell->DateModified = 0ULL; + BinCell->BlockSize = REG_BLOCK_SIZE; +} + + +static VOID +CmiCreateDefaultRootKeyCell(PKEY_CELL RootKeyCell) +{ + assert(RootKeyCell); + memset (RootKeyCell, 0, sizeof(KEY_CELL)); + RootKeyCell->CellSize = -sizeof(KEY_CELL); + RootKeyCell->Id = REG_KEY_CELL_ID; + RootKeyCell->Type = REG_ROOT_KEY_CELL_TYPE; + RootKeyCell->LastWriteTime = 0ULL; + RootKeyCell->ParentKeyOffset = 0; + RootKeyCell->NumberOfSubKeys = 0; + RootKeyCell->HashTableOffset = -1; + RootKeyCell->NumberOfValues = 0; + RootKeyCell->ValuesOffset = -1; + RootKeyCell->SecurityKeyOffset = 0; + RootKeyCell->ClassNameOffset = -1; + RootKeyCell->NameSize = 0; + RootKeyCell->ClassSize = 0; +} + + +static PREGISTRY_HIVE +CmiCreateRegistryHive (VOID) +{ + PREGISTRY_HIVE Hive; + PCELL_HEADER FreeCell; + PKEY_CELL RootKeyCell; + PHBIN BinCell; + + Hive = (PREGISTRY_HIVE) malloc (sizeof(REGISTRY_HIVE)); + if (Hive == NULL) + { + return NULL; + } + memset (Hive, 0, sizeof(REGISTRY_HIVE)); + + DPRINT("Hive %x\n", Hive); + + /* Create hive beader (aka 'base block') */ + Hive->HiveHeader = (PHIVE_HEADER) malloc (REG_BLOCK_SIZE); + if (Hive->HiveHeader == NULL) + { + free (Hive); + return NULL; + } + CmiCreateDefaultHiveHeader(Hive->HiveHeader); + Hive->FileSize = REG_BLOCK_SIZE; + + /* Allocate block list */ + Hive->BlockListSize = 1; + Hive->BlockList = malloc (sizeof(PHBIN) * Hive->BlockListSize); + if (Hive->BlockList == NULL) + { + free (Hive->HiveHeader); + free (Hive); + return NULL; + } + + /* Allocate free cell list */ + Hive->FreeListMax = 32; + Hive->FreeList = malloc(sizeof(PCELL_HEADER) * Hive->FreeListMax); + if (Hive->FreeList == NULL) + { + free (Hive->BlockList); + free (Hive->HiveHeader); + free (Hive); + return NULL; + } + Hive->FreeListOffset = malloc(sizeof(BLOCK_OFFSET) * Hive->FreeListMax); + if (Hive->FreeListOffset == NULL) + { + free (Hive->FreeList); + free (Hive->BlockList); + free (Hive->HiveHeader); + free (Hive); + return NULL; + } + + /* Allocate first bin */ + Hive->BlockList[0] = (PHBIN) malloc (REG_BLOCK_SIZE); + if (Hive->BlockList[0] == NULL) + { + free (Hive->FreeListOffset); + free (Hive->FreeList); + free (Hive->BlockList); + free (Hive->HiveHeader); + free (Hive); + return NULL; + } + Hive->FileSize += REG_BLOCK_SIZE; + + /* Init first bin */ + BinCell = (PHBIN)Hive->BlockList[0]; + CmiCreateDefaultBinCell(BinCell); + BinCell->BlockOffset = 0; + + /* Init root key cell */ + RootKeyCell = (PKEY_CELL)((ULONG_PTR)BinCell + REG_HBIN_DATA_OFFSET); + CmiCreateDefaultRootKeyCell(RootKeyCell); + Hive->HiveHeader->RootKeyCell = REG_HBIN_DATA_OFFSET; + + /* Init free cell */ + FreeCell = (PCELL_HEADER)((ULONG_PTR)RootKeyCell + sizeof(KEY_CELL)); + FreeCell->CellSize = REG_BLOCK_SIZE - (REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL)); + + Hive->FreeList[0] = FreeCell; + Hive->FreeListOffset[0] = REG_HBIN_DATA_OFFSET + sizeof(KEY_CELL); + Hive->FreeListSize++; + + return Hive; +} + + +static VOID +CmiDestroyRegistryHive (PREGISTRY_HIVE Hive) +{ + PHBIN Bin; + ULONG i; + + if (Hive == NULL) + return; + + /* Release free offset list */ + if (Hive->FreeListOffset != NULL) + free (Hive->FreeListOffset); + + /* Release free list */ + if (Hive->FreeList != NULL) + free (Hive->FreeList); + + if (Hive->BlockList != NULL) + { + /* Release bins */ + Bin = NULL; + for (i = 0; i < Hive->BlockListSize; i++) + { + if ((Hive->BlockList[i] != NULL) && + (Hive->BlockList[i] != Bin)) + { + Bin = Hive->BlockList[i]; + + DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", + i, Bin->BlockOffset, Bin->BlockSize); + + free (Bin); + } + } + + /* Release block list */ + free (Hive->BlockList); + } + + /* Release hive header */ + if (Hive->HiveHeader != NULL) + free (Hive->HiveHeader); + + /* Release hive */ + free (Hive); +} + + +static PVOID +CmiGetBlock(PREGISTRY_HIVE Hive, + BLOCK_OFFSET BlockOffset, + PHBIN * ppBin) +{ + PHBIN pBin; + ULONG BlockIndex; + + if (ppBin) + *ppBin = NULL; + + if (BlockOffset == (ULONG_PTR) -1) + return NULL; + + BlockIndex = BlockOffset / 4096; + if (BlockIndex >= Hive->BlockListSize) + return NULL; + + pBin = Hive->BlockList[BlockIndex]; + if (ppBin) + *ppBin = pBin; + + return (PVOID)((ULONG_PTR)pBin + (BlockOffset - pBin->BlockOffset)); +} + + +static BOOL +CmiMergeFree(PREGISTRY_HIVE RegistryHive, + PCELL_HEADER FreeBlock, + BLOCK_OFFSET FreeOffset) +{ + BLOCK_OFFSET BlockOffset; + BLOCK_OFFSET BinOffset; + ULONG BlockSize; + ULONG BinSize; + PHBIN Bin; + ULONG i; + + DPRINT("CmiMergeFree(Block %lx Offset %lx Size %lx) called\n", + FreeBlock, FreeOffset, FreeBlock->CellSize); + + CmiGetBlock(RegistryHive, + FreeOffset, + &Bin); + DPRINT("Bin %p\n", Bin); + if (Bin == NULL) + return FALSE; + + BinOffset = Bin->BlockOffset; + BinSize = Bin->BlockSize; + DPRINT("Bin %p Offset %lx Size %lx\n", Bin, BinOffset, BinSize); + + for (i = 0; i < RegistryHive->FreeListSize; i++) + { + BlockOffset = RegistryHive->FreeListOffset[i]; + BlockSize = RegistryHive->FreeList[i]->CellSize; + if (BlockOffset > BinOffset && + BlockOffset < BinOffset + BinSize) + { + DPRINT("Free block: Offset %lx Size %lx\n", + BlockOffset, BlockSize); + + if ((i < (RegistryHive->FreeListSize - 1)) && + (BlockOffset + BlockSize == FreeOffset) && + (FreeOffset + FreeBlock->CellSize == RegistryHive->FreeListOffset[i + 1])) + { + DPRINT("Merge current block with previous and next block\n"); + + RegistryHive->FreeList[i]->CellSize += + (FreeBlock->CellSize + RegistryHive->FreeList[i + 1]->CellSize); + + FreeBlock->CellSize = 0; + RegistryHive->FreeList[i + 1]->CellSize = 0; + + + if ((i + 2) < RegistryHive->FreeListSize) + { + memmove (&RegistryHive->FreeList[i + 1], + &RegistryHive->FreeList[i + 2], + sizeof(RegistryHive->FreeList[0]) + * (RegistryHive->FreeListSize - i - 2)); + memmove (&RegistryHive->FreeListOffset[i + 1], + &RegistryHive->FreeListOffset[i + 2], + sizeof(RegistryHive->FreeListOffset[0]) + * (RegistryHive->FreeListSize - i - 2)); + } + RegistryHive->FreeListSize--; + + return TRUE; + } + else if (BlockOffset + BlockSize == FreeOffset) + { + DPRINT("Merge current block with previous block\n"); + + RegistryHive->FreeList[i]->CellSize += FreeBlock->CellSize; + FreeBlock->CellSize = 0; + + return TRUE; + } + else if (FreeOffset + FreeBlock->CellSize == BlockOffset) + { + DPRINT("Merge current block with next block\n"); + + FreeBlock->CellSize += RegistryHive->FreeList[i]->CellSize; + RegistryHive->FreeList[i]->CellSize = 0; + RegistryHive->FreeList[i] = FreeBlock; + RegistryHive->FreeListOffset[i] = FreeOffset; + + return TRUE; + } + } + } + + return FALSE; +} + + +static BOOL +CmiAddFree(PREGISTRY_HIVE RegistryHive, + PCELL_HEADER FreeBlock, + BLOCK_OFFSET FreeOffset, + BOOL MergeFreeBlocks) +{ + PCELL_HEADER *tmpList; + BLOCK_OFFSET *tmpListOffset; + LONG minInd; + LONG maxInd; + LONG medInd; + + assert(RegistryHive); + assert(FreeBlock); + + DPRINT("FreeBlock %.08lx FreeOffset %.08lx\n", + FreeBlock, FreeOffset); + + /* Merge free blocks */ + if (MergeFreeBlocks == TRUE) + { + if (CmiMergeFree(RegistryHive, FreeBlock, FreeOffset)) + return TRUE; + } + + if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax) + { + tmpList = malloc (sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32)); + if (tmpList == NULL) + { + return FALSE; + } + + tmpListOffset = malloc (sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax + 32)); + if (tmpListOffset == NULL) + { + free (tmpList); + return FALSE; + } + + if (RegistryHive->FreeListMax) + { + memmove (tmpList, + RegistryHive->FreeList, + sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax)); + memmove (tmpListOffset, + RegistryHive->FreeListOffset, + sizeof(BLOCK_OFFSET) * (RegistryHive->FreeListMax)); + free (RegistryHive->FreeList); + free (RegistryHive->FreeListOffset); + } + RegistryHive->FreeList = tmpList; + RegistryHive->FreeListOffset = tmpListOffset; + RegistryHive->FreeListMax += 32; + } + + /* Add new offset to free list, maintaining list in ascending order */ + if ((RegistryHive->FreeListSize == 0) + || (RegistryHive->FreeListOffset[RegistryHive->FreeListSize-1] < FreeOffset)) + { + /* Add to end of list */ + RegistryHive->FreeList[RegistryHive->FreeListSize] = FreeBlock; + RegistryHive->FreeListOffset[RegistryHive->FreeListSize++] = FreeOffset; + } + else if (RegistryHive->FreeListOffset[0] > FreeOffset) + { + /* Add to begin of list */ + memmove (&RegistryHive->FreeList[1], + &RegistryHive->FreeList[0], + sizeof(RegistryHive->FreeList[0]) * RegistryHive->FreeListSize); + memmove (&RegistryHive->FreeListOffset[1], + &RegistryHive->FreeListOffset[0], + sizeof(RegistryHive->FreeListOffset[0]) * RegistryHive->FreeListSize); + RegistryHive->FreeList[0] = FreeBlock; + RegistryHive->FreeListOffset[0] = FreeOffset; + RegistryHive->FreeListSize++; + } + else + { + /* Search where to insert */ + minInd = 0; + maxInd = RegistryHive->FreeListSize - 1; + while ((maxInd - minInd) > 1) + { + medInd = (minInd + maxInd) / 2; + if (RegistryHive->FreeListOffset[medInd] > FreeOffset) + maxInd = medInd; + else + minInd = medInd; + } + + /* Insert before maxInd */ + memmove (&RegistryHive->FreeList[maxInd+1], + &RegistryHive->FreeList[maxInd], + sizeof(RegistryHive->FreeList[0]) * (RegistryHive->FreeListSize - minInd)); + memmove (&RegistryHive->FreeListOffset[maxInd + 1], + &RegistryHive->FreeListOffset[maxInd], + sizeof(RegistryHive->FreeListOffset[0]) * (RegistryHive->FreeListSize-minInd)); + RegistryHive->FreeList[maxInd] = FreeBlock; + RegistryHive->FreeListOffset[maxInd] = FreeOffset; + RegistryHive->FreeListSize++; + } + + return TRUE; +} + + +static BOOL +CmiAddBin(PREGISTRY_HIVE RegistryHive, + PVOID *NewBlock, + PBLOCK_OFFSET NewBlockOffset) +{ + PCELL_HEADER tmpBlock; + PHBIN * tmpBlockList; + PHBIN tmpBin; + + tmpBin = malloc (REG_BLOCK_SIZE); + if (tmpBin == NULL) + { + return FALSE; + } + memset (tmpBin, 0, REG_BLOCK_SIZE); + + tmpBin->BlockId = REG_BIN_ID; + tmpBin->BlockOffset = RegistryHive->FileSize - REG_BLOCK_SIZE; + RegistryHive->FileSize += REG_BLOCK_SIZE; + tmpBin->BlockSize = REG_BLOCK_SIZE; + tmpBin->Unused1 = 0; + tmpBin->DateModified = 0ULL; + tmpBin->Unused2 = 0; + + /* Increase size of list of blocks */ + tmpBlockList = malloc (sizeof(PHBIN) * (RegistryHive->BlockListSize + 1)); + if (tmpBlockList == NULL) + { + free (tmpBin); + return FALSE; + } + + if (RegistryHive->BlockListSize > 0) + { + memcpy (tmpBlockList, + RegistryHive->BlockList, + sizeof(PHBIN) * RegistryHive->BlockListSize); + free (RegistryHive->BlockList); + } + + RegistryHive->BlockList = tmpBlockList; + RegistryHive->BlockList[RegistryHive->BlockListSize++] = tmpBin; + + /* Initialize a free block in this heap : */ + tmpBlock = (PCELL_HEADER)((ULONG_PTR) tmpBin + REG_HBIN_DATA_OFFSET); + tmpBlock->CellSize = (REG_BLOCK_SIZE - REG_HBIN_DATA_OFFSET); + + *NewBlock = (PVOID) tmpBlock; + + if (NewBlockOffset) + *NewBlockOffset = tmpBin->BlockOffset + REG_HBIN_DATA_OFFSET; + + return TRUE; +} + + +static BOOL +CmiAllocateBlock(PREGISTRY_HIVE RegistryHive, + PVOID *Block, + LONG BlockSize, + PBLOCK_OFFSET pBlockOffset) +{ + PCELL_HEADER NewBlock; + PHBIN pBin; + ULONG i; + + *Block = NULL; + + /* Round to 16 bytes multiple */ + BlockSize = (BlockSize + sizeof(ULONG) + 15) & 0xfffffff0; + + /* first search in free blocks */ + NewBlock = NULL; + for (i = 0; i < RegistryHive->FreeListSize; i++) + { + if (RegistryHive->FreeList[i]->CellSize >= BlockSize) + { + NewBlock = RegistryHive->FreeList[i]; + if (pBlockOffset) + *pBlockOffset = RegistryHive->FreeListOffset[i]; + + if ((i + 1) < RegistryHive->FreeListSize) + { + memmove (&RegistryHive->FreeList[i], + &RegistryHive->FreeList[i + 1], + sizeof(RegistryHive->FreeList[0]) + * (RegistryHive->FreeListSize - i - 1)); + memmove (&RegistryHive->FreeListOffset[i], + &RegistryHive->FreeListOffset[i + 1], + sizeof(RegistryHive->FreeListOffset[0]) + * (RegistryHive->FreeListSize - i - 1)); + } + RegistryHive->FreeListSize--; + break; + } + } + + /* Need to extend hive file : */ + if (NewBlock == NULL) + { + /* Add a new block */ + if (!CmiAddBin(RegistryHive, (PVOID *)&NewBlock , pBlockOffset)) + return FALSE; + } + + *Block = NewBlock; + + /* Split the block in two parts */ + if (NewBlock->CellSize > BlockSize) + { + NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize); + NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize; + CmiAddFree (RegistryHive, + NewBlock, + *pBlockOffset + BlockSize, + TRUE); + } + else if (NewBlock->CellSize < BlockSize) + { + return FALSE; + } + + memset(*Block, 0, BlockSize); + ((PCELL_HEADER)(*Block))->CellSize = -BlockSize; + + return TRUE; +} + + +static BOOL +CmiAllocateHashTableCell (PREGISTRY_HIVE Hive, + PBLOCK_OFFSET HBOffset, + ULONG SubKeyCount) +{ + PHASH_TABLE_CELL HashCell; + ULONG NewHashSize; + BOOL Status; + + NewHashSize = ROUND_UP(sizeof(HASH_TABLE_CELL) + + (SubKeyCount - 1) * sizeof(HASH_RECORD), + 0x10); + Status = CmiAllocateBlock (Hive, + (PVOID*) &HashCell, + NewHashSize, + HBOffset); + if ((HashCell == NULL) || (Status == FALSE)) + { + return FALSE; + } + + HashCell->Id = REG_HASH_TABLE_BLOCK_ID; + HashCell->HashTableSize = SubKeyCount; + + return TRUE; +} + + +static BOOL +CmiAddKeyToParentHashTable (PREGISTRY_HIVE Hive, + BLOCK_OFFSET ParentKeyOffset, + PKEY_CELL NewKeyCell, + BLOCK_OFFSET NKBOffset) +{ + PHASH_TABLE_CELL HashBlock; + PKEY_CELL ParentKeyCell; + ULONG i; + + ParentKeyCell = CmiGetBlock (Hive, + ParentKeyOffset, + NULL); + if (ParentKeyCell == NULL) + { + DPRINT1 ("CmiGetBlock() failed\n"); + return FALSE; + } + + HashBlock =CmiGetBlock (Hive, + ParentKeyCell->HashTableOffset, + NULL); + if (HashBlock == NULL) + { + DPRINT1 ("CmiGetBlock() failed\n"); + return FALSE; + } + + for (i = 0; i < HashBlock->HashTableSize; i++) + { + if (HashBlock->Table[i].KeyOffset == 0) + { + HashBlock->Table[i].KeyOffset = NKBOffset; + memcpy (&HashBlock->Table[i].HashValue, + NewKeyCell->Name, + 4); + ParentKeyCell->NumberOfSubKeys++; + return TRUE; + } + } + + return FALSE; +} + + +static BOOL +CmiAllocateValueListCell (PREGISTRY_HIVE Hive, + PBLOCK_OFFSET ValueListOffset, + ULONG ValueCount) +{ + PVALUE_LIST_CELL ValueListCell; + ULONG ValueListSize; + BOOL Status; + + ValueListSize = ROUND_UP (ValueCount * sizeof(BLOCK_OFFSET), + 0x10); + Status = CmiAllocateBlock (Hive, + (PVOID)&ValueListCell, + ValueListSize, + ValueListOffset); + if ((ValueListCell == NULL) || (Status == FALSE)) + { + DPRINT1 ("CmiAllocateBlock() failed\n"); + return FALSE; + } + + return TRUE; +} + + +static BOOL +CmiAllocateValueCell(PREGISTRY_HIVE Hive, + PVALUE_CELL *ValueCell, + BLOCK_OFFSET *ValueCellOffset, + PCHAR ValueName) +{ + PVALUE_CELL NewValueCell; + ULONG NameSize; + BOOL Status; + + NameSize = (ValueName == NULL) ? 0 : strlen (ValueName); + Status = CmiAllocateBlock(Hive, + (PVOID*)&NewValueCell, + sizeof(VALUE_CELL) + NameSize, + ValueCellOffset); + if ((NewValueCell == NULL) || (Status == FALSE)) + { + DPRINT1 ("CmiAllocateBlock() failed\n"); + return FALSE; + } + + NewValueCell->Id = REG_VALUE_CELL_ID; + NewValueCell->NameSize = NameSize; + if (NameSize > 0) + { + memcpy (NewValueCell->Name, + ValueName, + NameSize); + NewValueCell->Flags = REG_VALUE_NAME_PACKED; + } + NewValueCell->DataType = 0; + NewValueCell->DataSize = 0; + NewValueCell->DataOffset = -1; + + *ValueCell = NewValueCell; + + return TRUE; +} + + +static BOOL +CmiAddValueToKeyValueList(PREGISTRY_HIVE Hive, + BLOCK_OFFSET KeyCellOffset, + BLOCK_OFFSET ValueCellOffset) +{ + PVALUE_LIST_CELL ValueListCell; + PKEY_CELL KeyCell; + + KeyCell = CmiGetBlock (Hive, KeyCellOffset, NULL); + if (KeyCell == NULL) + { + DPRINT1 ("CmiGetBlock() failed\n"); + return FALSE; + } + + ValueListCell = CmiGetBlock (Hive, KeyCell->ValuesOffset, NULL); + if (ValueListCell == NULL) + { + DPRINT1 ("CmiGetBlock() failed\n"); + return FALSE; + } + + ValueListCell->Values[KeyCell->NumberOfValues] = ValueCellOffset; + KeyCell->NumberOfValues++; + + return TRUE; +} + + +static VOID +memexpand (PWCHAR Dst, + PCHAR Src, + ULONG Length) +{ + ULONG i; + + for (i = 0; i < Length; i++) + Dst[i] = (WCHAR)Src[i]; +} + + +static BOOL +CmiExportValue (PREGISTRY_HIVE Hive, + BLOCK_OFFSET KeyCellOffset, + HKEY Key, + PVALUE Value) +{ + BLOCK_OFFSET ValueCellOffset; + BLOCK_OFFSET DataCellOffset; + PVALUE_CELL ValueCell; + PDATA_CELL DataCell; + ULONG SrcDataSize; + ULONG DstDataSize; + ULONG DataType; + PUCHAR Data; + BOOL Expand = FALSE; + + DPRINT ("CmiExportValue('%s') called\n", (Value == NULL) ? "" : (PCHAR)Value->Name); + DPRINT ("DataSize %lu\n", (Value == NULL) ? Key->DataSize : Value->DataSize); + + /* Allocate value cell */ + if (!CmiAllocateValueCell(Hive, &ValueCell, &ValueCellOffset, (Value == NULL) ? NULL : Value->Name)) + { + return FALSE; + } + + if (!CmiAddValueToKeyValueList(Hive, KeyCellOffset, ValueCellOffset)) + { + return FALSE; + } + + if (Value == NULL) + { + DataType = Key->DataType; + SrcDataSize = Key->DataSize; + Data = Key->Data; + } + else + { + DataType = Value->DataType; + SrcDataSize = Value->DataSize; + Data = Value->Data; + } + + DstDataSize = SrcDataSize; + if (DataType == REG_SZ || + DataType == REG_EXPAND_SZ || + DataType == REG_MULTI_SZ) + { + DstDataSize *= sizeof(WCHAR); + Expand = TRUE; + } + + if (DstDataSize <= sizeof(BLOCK_OFFSET)) + { + ValueCell->DataSize = DstDataSize | 0x80000000; + ValueCell->DataType = DataType; + if (Expand) + { + memexpand ((PWCHAR)&ValueCell->DataOffset, + (PCHAR)&Data, + SrcDataSize); + } + else + { + memcpy (&ValueCell->DataOffset, + &Data, + SrcDataSize); + } + } + else + { + if (!CmiAllocateBlock (Hive, + (PVOID *)&DataCell, + DstDataSize, + &DataCellOffset)) + { + return FALSE; + } + + ValueCell->DataOffset = DataCellOffset; + ValueCell->DataSize = DstDataSize; + ValueCell->DataType = DataType; + + if (Expand) + { + if (SrcDataSize <= sizeof(BLOCK_OFFSET)) + { + memexpand ((PWCHAR)DataCell->Data, + (PCHAR)&Data, + SrcDataSize); + } + else + { + memexpand ((PWCHAR)DataCell->Data, + Data, + SrcDataSize); + } + } + else + { + memcpy (DataCell->Data, + Data, + SrcDataSize); + } + } + + return TRUE; +} + + +static BOOL +CmiExportSubKey (PREGISTRY_HIVE Hive, + BLOCK_OFFSET ParentKeyOffset, + HKEY ParentKey, + HKEY Key) +{ + BLOCK_OFFSET NKBOffset; + PKEY_CELL NewKeyCell; + ULONG KeyCellSize; + ULONG SubKeyCount; + ULONG ValueCount; + PLIST_ENTRY Entry; + HKEY SubKey; + PVALUE Value; + + DPRINT ("CmiExportSubKey('%s') called\n", Key->Name); + + /* Don't export links */ + if (Key->DataType == REG_LINK) + return TRUE; + + /* Allocate key cell */ + KeyCellSize = sizeof(KEY_CELL) + Key->NameSize - 1; + if (!CmiAllocateBlock (Hive, (PVOID)&NewKeyCell, KeyCellSize, &NKBOffset)) + { + DPRINT1 ("CmiAllocateBlock() failed\n"); + return FALSE; + } + + /* Initialize key cell */ + NewKeyCell->Id = REG_KEY_CELL_ID; + NewKeyCell->Type = REG_KEY_CELL_TYPE; + NewKeyCell->LastWriteTime = 0ULL; + NewKeyCell->ParentKeyOffset = ParentKeyOffset; + NewKeyCell->NumberOfSubKeys = 0; + NewKeyCell->HashTableOffset = -1; + NewKeyCell->NumberOfValues = 0; + NewKeyCell->ValuesOffset = -1; + NewKeyCell->SecurityKeyOffset = -1; + NewKeyCell->NameSize = Key->NameSize - 1; + NewKeyCell->ClassNameOffset = -1; + memcpy (NewKeyCell->Name, + Key->Name, + Key->NameSize - 1); + + /* Add key cell to the parent key's hash table */ + if (!CmiAddKeyToParentHashTable (Hive, + ParentKeyOffset, + NewKeyCell, + NKBOffset)) + { + DPRINT1 ("CmiAddKeyToParentHashTable() failed\n"); + return FALSE; + } + + ValueCount = RegGetValueCount (Key); + DPRINT ("ValueCount: %lu\n", ValueCount); + if (ValueCount > 0) + { + /* Allocate value list cell */ + CmiAllocateValueListCell (Hive, + &NewKeyCell->ValuesOffset, + ValueCount); + + if (Key->DataSize != 0) + { + if (!CmiExportValue (Hive, NKBOffset, Key, NULL)) + return FALSE; + } + + /* Enumerate values */ + Entry = Key->ValueList.Flink; + while (Entry != &Key->ValueList) + { + Value = CONTAINING_RECORD(Entry, + VALUE, + ValueList); + + if (!CmiExportValue (Hive, NKBOffset, Key, Value)) + return FALSE; + + Entry = Entry->Flink; + } + } + + SubKeyCount = RegGetSubKeyCount (Key); + DPRINT ("SubKeyCount: %lu\n", SubKeyCount); + if (SubKeyCount > 0) + { + /* Allocate hash table cell */ + CmiAllocateHashTableCell (Hive, + &NewKeyCell->HashTableOffset, + SubKeyCount); + + /* Enumerate subkeys */ + Entry = Key->SubKeyList.Flink; + while (Entry != &Key->SubKeyList) + { + SubKey = CONTAINING_RECORD(Entry, + KEY, + KeyList); + + if (!CmiExportSubKey (Hive, NKBOffset, Key, SubKey)) + return FALSE; + + Entry = Entry->Flink; + } + } + + return TRUE; +} + + +static VOID +CmiCalcHiveChecksum (PREGISTRY_HIVE Hive) +{ + PULONG Buffer; + ULONG Sum; + ULONG i; + + Buffer = (PULONG)Hive->HiveHeader; + Sum = 0; + for (i = 0; i < 127; i++) + Sum += Buffer[i]; + + Hive->HiveHeader->Checksum = Sum; +} + + +BOOL +CmiExportHive (PREGISTRY_HIVE Hive, + PCHAR KeyName) +{ + PKEY_CELL KeyCell; + HKEY Key; + ULONG i; + ULONG SubKeyCount; + ULONG ValueCount; + PLIST_ENTRY Entry; + HKEY SubKey; + PVALUE Value; + + DPRINT ("CmiExportHive(%p, '%s') called\n", Hive, KeyName); + + if (RegOpenKey (NULL, KeyName, &Key) != ERROR_SUCCESS) + { + DPRINT1 ("RegOpenKey() failed\n"); + return FALSE; + } + + DPRINT ("Name: %s\n", KeyName); + + KeyCell = CmiGetBlock (Hive, + Hive->HiveHeader->RootKeyCell, + NULL); + if (KeyCell == NULL) + { + DPRINT1 ("CmiGetBlock() failed\n"); + return FALSE; + } + + ValueCount = RegGetValueCount (Key); + DPRINT ("ValueCount: %lu\n", ValueCount); + if (ValueCount > 0) + { + /* Allocate value list cell */ + CmiAllocateValueListCell (Hive, + &KeyCell->ValuesOffset, + ValueCount); + + if (Key->DataSize != 0) + { + if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyCell, Key, NULL)) + return FALSE; + } + + /* Enumerate values */ + Entry = Key->ValueList.Flink; + while (Entry != &Key->ValueList) + { + Value = CONTAINING_RECORD(Entry, + VALUE, + ValueList); + + if (!CmiExportValue (Hive, Hive->HiveHeader->RootKeyCell, Key, Value)) + return FALSE; + + Entry = Entry->Flink; + } + } + + SubKeyCount = RegGetSubKeyCount (Key); + DPRINT ("SubKeyCount: %lu\n", SubKeyCount); + if (SubKeyCount > 0) + { + /* Allocate hash table cell */ + CmiAllocateHashTableCell (Hive, + &KeyCell->HashTableOffset, + SubKeyCount); + + /* Enumerate subkeys */ + Entry = Key->SubKeyList.Flink; + while (Entry != &Key->SubKeyList) + { + SubKey = CONTAINING_RECORD(Entry, + KEY, + KeyList); + + if (!CmiExportSubKey (Hive, Hive->HiveHeader->RootKeyCell, Key, SubKey)) + return FALSE; + + Entry = Entry->Flink; + } + } + + CmiCalcHiveChecksum (Hive); + + return TRUE; +} + + +static BOOL +CmiWriteHive(PREGISTRY_HIVE Hive, + PCHAR FileName) +{ + PHBIN Bin; + FILE *File; + ULONG i; + + /* FIXME: Calculate header checksum */ + + File = fopen (FileName, "w+b"); + if (File == NULL) + { + + return FALSE; + } + + fseek (File, 0, SEEK_SET); + + /* Write hive header */ + fwrite (Hive->HiveHeader, REG_BLOCK_SIZE, 1, File); + + Bin = NULL; + for (i = 0; i < Hive->BlockListSize; i++) + { + if (Hive->BlockList[i] != Bin) + { + Bin = Hive->BlockList[i]; + + DPRINT ("Bin[%lu]: Offset 0x%lx Size 0x%lx\n", + i, Bin->BlockOffset, Bin->BlockSize); + + fwrite (Bin, Bin->BlockSize, 1, File); + } + } + + fclose (File); + + return TRUE; +} + + +BOOL +ExportBinaryHive (PCHAR FileName, + PCHAR KeyName) +{ + PREGISTRY_HIVE Hive; + + printf (" Creating binary hive: %s\n", FileName); + + Hive = CmiCreateRegistryHive (); + if (Hive == NULL) + return FALSE; + + if (!CmiExportHive (Hive, KeyName)) + { + CmiDestroyRegistryHive (Hive); + return FALSE; + } + + if (!CmiWriteHive (Hive, FileName)) + { + CmiDestroyRegistryHive (Hive); + return FALSE; + } + + CmiDestroyRegistryHive (Hive); + + return TRUE; +} + +/* EOF */ diff --git a/tools/mkhive/binhive.h b/tools/mkhive/binhive.h new file mode 100644 index 0000000..1ab398b --- /dev/null +++ b/tools/mkhive/binhive.h @@ -0,0 +1,36 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/binhive.h + * PURPOSE: Binary hive export code + * PROGRAMMER: Eric Kohl + */ + +#ifndef __BINHIVE_H__ +#define __BINHIVE_H__ + +BOOL +ExportBinaryHive (PCHAR FileName, + PCHAR KeyName); + +#endif /* __BINHIVE_H__ */ + +/* EOF */ diff --git a/tools/mkhive/infcache.c b/tools/mkhive/infcache.c new file mode 100644 index 0000000..6c3fbc4 --- /dev/null +++ b/tools/mkhive/infcache.c @@ -0,0 +1,1479 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/infcache.c + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#include "mkhive.h" +#include "infcache.h" + + +#define CONTROL_Z '\x1a' +#define MAX_SECTION_NAME_LEN 255 +#define MAX_FIELD_LEN 511 /* larger fields get silently truncated */ +/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */ +#define MAX_STRING_LEN (MAX_INF_STRING_LENGTH+1) + + +typedef struct _INFCACHEFIELD +{ + struct _INFCACHEFIELD *Next; + struct _INFCACHEFIELD *Prev; + + CHAR Data[1]; +} INFCACHEFIELD, *PINFCACHEFIELD; + + +typedef struct _INFCACHELINE +{ + struct _INFCACHELINE *Next; + struct _INFCACHELINE *Prev; + + LONG FieldCount; + + PCHAR Key; + + PINFCACHEFIELD FirstField; + PINFCACHEFIELD LastField; + +} INFCACHELINE, *PINFCACHELINE; + + +typedef struct _INFCACHESECTION +{ + struct _INFCACHESECTION *Next; + struct _INFCACHESECTION *Prev; + + PINFCACHELINE FirstLine; + PINFCACHELINE LastLine; + + LONG LineCount; + + CHAR Name[1]; +} INFCACHESECTION, *PINFCACHESECTION; + + +typedef struct _INFCACHE +{ + PINFCACHESECTION FirstSection; + PINFCACHESECTION LastSection; + + PINFCACHESECTION StringsSection; +} INFCACHE, *PINFCACHE; + + +/* parser definitions */ + +enum parser_state +{ + LINE_START, /* at beginning of a line */ + SECTION_NAME, /* parsing a section name */ + KEY_NAME, /* parsing a key name */ + VALUE_NAME, /* parsing a value name */ + EOL_BACKSLASH, /* backslash at end of line */ + QUOTES, /* inside quotes */ + LEADING_SPACES, /* leading spaces */ + TRAILING_SPACES, /* trailing spaces */ + COMMENT, /* inside a comment */ + NB_PARSER_STATES +}; + +struct parser +{ + const CHAR *start; /* start position of item being parsed */ + const CHAR *end; /* end of buffer */ + PINFCACHE file; /* file being built */ + enum parser_state state; /* current parser state */ + enum parser_state stack[4]; /* state stack */ + int stack_pos; /* current pos in stack */ + + PINFCACHESECTION cur_section; /* pointer to the section being parsed*/ + PINFCACHELINE line; /* current line */ + unsigned int line_pos; /* current line position in file */ + unsigned int error; /* error code */ + unsigned int token_len; /* current token len */ + CHAR token[MAX_FIELD_LEN+1]; /* current token */ +}; + +typedef const CHAR * (*parser_state_func)( struct parser *parser, const CHAR *pos ); + +/* parser state machine functions */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ); +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ); +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ); +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ); +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ); +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ); + +static const parser_state_func parser_funcs[NB_PARSER_STATES] = +{ + line_start_state, /* LINE_START */ + section_name_state, /* SECTION_NAME */ + key_name_state, /* KEY_NAME */ + value_name_state, /* VALUE_NAME */ + eol_backslash_state, /* EOL_BACKSLASH */ + quotes_state, /* QUOTES */ + leading_spaces_state, /* LEADING_SPACES */ + trailing_spaces_state, /* TRAILING_SPACES */ + comment_state /* COMMENT */ +}; + + +/* PRIVATE FUNCTIONS ********************************************************/ + +static PINFCACHELINE +InfpCacheFreeLine (PINFCACHELINE Line) +{ + PINFCACHELINE Next; + PINFCACHEFIELD Field; + + if (Line == NULL) + { + return NULL; + } + + Next = Line->Next; + if (Line->Key != NULL) + { + free (Line->Key); + Line->Key = NULL; + } + + /* Remove data fields */ + while (Line->FirstField != NULL) + { + Field = Line->FirstField->Next; + free (Line->FirstField); + Line->FirstField = Field; + } + Line->LastField = NULL; + + free (Line); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFreeSection (PINFCACHESECTION Section) +{ + PINFCACHESECTION Next; + + if (Section == NULL) + { + return NULL; + } + + /* Release all keys */ + Next = Section->Next; + while (Section->FirstLine != NULL) + { + Section->FirstLine = InfpCacheFreeLine (Section->FirstLine); + } + Section->LastLine = NULL; + + free (Section); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFindSection (PINFCACHE Cache, + PCHAR Name) +{ + PINFCACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL) + { + return NULL; + } + + /* iterate through list of sections */ + Section = Cache->FirstSection; + while (Section != NULL) + { + if (strcasecmp (Section->Name, Name) == 0) + { + return Section; + } + + /* get the next section*/ + Section = Section->Next; + } + + return NULL; +} + + +static PINFCACHESECTION +InfpCacheAddSection (PINFCACHE Cache, + PCHAR Name) +{ + PINFCACHESECTION Section = NULL; + ULONG Size; + + if (Cache == NULL || Name == NULL) + { + DPRINT ("Invalid parameter\n"); + return NULL; + } + + /* Allocate and initialize the new section */ + Size = sizeof(INFCACHESECTION) + strlen (Name); + Section = (PINFCACHESECTION)malloc (Size); + if (Section == NULL) + { + DPRINT ("RtlAllocateHeap() failed\n"); + return NULL; + } + memset (Section, 0, Size); + + /* Copy section name */ + strcpy (Section->Name, Name); + + /* Append section */ + if (Cache->FirstSection == NULL) + { + Cache->FirstSection = Section; + Cache->LastSection = Section; + } + else + { + Cache->LastSection->Next = Section; + Section->Prev = Cache->LastSection; + Cache->LastSection = Section; + } + + return Section; +} + + +static PINFCACHELINE +InfpCacheAddLine (PINFCACHESECTION Section) +{ + PINFCACHELINE Line; + + if (Section == NULL) + { + DPRINT("Invalid parameter\n"); + return NULL; + } + + Line = (PINFCACHELINE)malloc (sizeof(INFCACHELINE)); + if (Line == NULL) + { + DPRINT("RtlAllocateHeap() failed\n"); + return NULL; + } + memset (Line, 0, sizeof(INFCACHELINE)); + + /* Append line */ + if (Section->FirstLine == NULL) + { + Section->FirstLine = Line; + Section->LastLine = Line; + } + else + { + Section->LastLine->Next = Line; + Line->Prev = Section->LastLine; + Section->LastLine = Line; + } + Section->LineCount++; + + return Line; +} + + +static PVOID +InfpAddKeyToLine (PINFCACHELINE Line, + PCHAR Key) +{ + if (Line == NULL) + return NULL; + + if (Line->Key != NULL) + return NULL; + + Line->Key = (PCHAR)malloc (strlen (Key) + 1); + if (Line->Key == NULL) + return NULL; + + strcpy (Line->Key, Key); + + return (PVOID)Line->Key; +} + + +static PVOID +InfpAddFieldToLine (PINFCACHELINE Line, + PCHAR Data) +{ + PINFCACHEFIELD Field; + ULONG Size; + + Size = sizeof(INFCACHEFIELD) + strlen(Data); + Field = (PINFCACHEFIELD)malloc (Size); + if (Field == NULL) + { + return NULL; + } + memset (Field, 0, Size); + strcpy (Field->Data, Data); + + /* Append key */ + if (Line->FirstField == NULL) + { + Line->FirstField = Field; + Line->LastField = Field; + } + else + { + Line->LastField->Next = Field; + Field->Prev = Line->LastField; + Line->LastField = Field; + } + Line->FieldCount++; + + return (PVOID)Field; +} + + +static PINFCACHELINE +InfpCacheFindKeyLine (PINFCACHESECTION Section, + PCHAR Key) +{ + PINFCACHELINE Line; + + Line = Section->FirstLine; + while (Line != NULL) + { + if (Line->Key != NULL && strcasecmp (Line->Key, Key) == 0) + { + return Line; + } + + Line = Line->Next; + } + + return NULL; +} + + +/* push the current state on the parser stack */ +inline static void push_state( struct parser *parser, enum parser_state state ) +{ +// assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) ); + parser->stack[parser->stack_pos++] = state; +} + + +/* pop the current state */ +inline static void pop_state( struct parser *parser ) +{ +// assert( parser->stack_pos ); + parser->state = parser->stack[--parser->stack_pos]; +} + + +/* set the parser state and return the previous one */ +inline static enum parser_state set_state( struct parser *parser, enum parser_state state ) +{ + enum parser_state ret = parser->state; + parser->state = state; + return ret; +} + + +/* check if the pointer points to an end of file */ +inline static int is_eof( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || *ptr == CONTROL_Z); +} + + +/* check if the pointer points to an end of line */ +inline static int is_eol( struct parser *parser, const CHAR *ptr ) +{ + return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\r' /*'\n'*/); +} + + +/* push data from current token start up to pos into the current token */ +static int push_token( struct parser *parser, const CHAR *pos ) +{ + int len = pos - parser->start; + const CHAR *src = parser->start; + CHAR *dst = parser->token + parser->token_len; + + if (len > MAX_FIELD_LEN - parser->token_len) + len = MAX_FIELD_LEN - parser->token_len; + + parser->token_len += len; + for ( ; len > 0; len--, dst++, src++) + *dst = *src ? *src : ' '; + *dst = 0; + parser->start = pos; + + return 0; +} + + + +/* add a section with the current token as name */ +static PVOID add_section_from_token( struct parser *parser ) +{ + PINFCACHESECTION Section; + + if (parser->token_len > MAX_SECTION_NAME_LEN) + { + parser->error = STATUS_SECTION_NAME_TOO_LONG; + return NULL; + } + + Section = InfpCacheFindSection (parser->file, + parser->token); + if (Section == NULL) + { + /* need to create a new one */ + Section= InfpCacheAddSection (parser->file, + parser->token); + if (Section == NULL) + { + parser->error = STATUS_NOT_ENOUGH_MEMORY; + return NULL; + } + } + + parser->token_len = 0; + parser->cur_section = Section; + + return (PVOID)Section; +} + + +/* add a field containing the current token to the current line */ +static struct field *add_field_from_token( struct parser *parser, int is_key ) +{ + PVOID field; + CHAR *text; + + if (!parser->line) /* need to start a new line */ + { + if (parser->cur_section == NULL) /* got a line before the first section */ + { + parser->error = STATUS_WRONG_INF_STYLE; + return NULL; + } + + parser->line = InfpCacheAddLine (parser->cur_section); + if (parser->line == NULL) + goto error; + } + else + { +// assert(!is_key); + } + + if (is_key) + { + field = InfpAddKeyToLine(parser->line, parser->token); + } + else + { + field = InfpAddFieldToLine(parser->line, parser->token); + } + + if (field != NULL) + { + parser->token_len = 0; + return field; + } + +error: + parser->error = STATUS_NOT_ENOUGH_MEMORY; + return NULL; +} + + +/* close the current line and prepare for parsing a new one */ +static void close_current_line( struct parser *parser ) +{ + parser->line = NULL; +} + + + +/* handler for parser LINE_START state */ +static const CHAR *line_start_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { +// case '\n': + case '\r': + p++; + parser->line_pos++; + close_current_line( parser ); + break; + case ';': + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case '[': + parser->start = p + 1; + set_state( parser, SECTION_NAME ); + return p + 1; + default: + if (!isspace(*p)) + { + parser->start = p; + set_state( parser, KEY_NAME ); + return p; + } + break; + } + } + close_current_line( parser ); + return NULL; +} + + +/* handler for parser SECTION_NAME state */ +static const CHAR *section_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ']') + { + push_token( parser, p ); + if (add_section_from_token( parser ) == NULL) + return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); /* ignore everything else on the line */ + return p + 1; + } + } + parser->error = STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */ + return NULL; +} + + +/* handler for parser KEY_NAME state */ +static const CHAR *key_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == ',') break; + switch(*p) + { + + case '=': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 1 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, KEY_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, KEY_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, KEY_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + set_state( parser, VALUE_NAME ); + return p; +} + + +/* handler for parser VALUE_NAME state */ +static const CHAR *value_name_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + switch(*p) + { + case ';': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + push_state( parser, LINE_START ); + set_state( parser, COMMENT ); + return p + 1; + case ',': + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, LEADING_SPACES ); + return p + 1; + case '"': + push_token( parser, token_end ); + parser->start = p + 1; + push_state( parser, VALUE_NAME ); + set_state( parser, QUOTES ); + return p + 1; + case '\\': + push_token( parser, token_end ); + parser->start = p; + push_state( parser, VALUE_NAME ); + set_state( parser, EOL_BACKSLASH ); + return p; + default: + if (!isspace(*p)) token_end = p + 1; + else + { + push_token( parser, p ); + push_state( parser, VALUE_NAME ); + set_state( parser, TRAILING_SPACES ); + return p; + } + break; + } + } + push_token( parser, token_end ); + if (!add_field_from_token( parser, 0 )) return NULL; + set_state( parser, LINE_START ); + return p; +} + + +/* handler for parser EOL_BACKSLASH state */ +static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eof( parser, p ); p++) + { + switch(*p) + { +// case '\n': + case '\r': + parser->line_pos++; +// parser->start = p + 1; + parser->start = p + 2; + set_state( parser, LEADING_SPACES ); +// return p + 1; + return p + 2; + case '\\': + continue; + case ';': + push_state( parser, EOL_BACKSLASH ); + set_state( parser, COMMENT ); + return p + 1; + default: + if (isspace(*p)) + continue; + push_token( parser, p ); + pop_state( parser ); + return p; + } + } + parser->start = p; + pop_state( parser ); + + return p; +} + + +/* handler for parser QUOTES state */ +static const CHAR *quotes_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p, *token_end = parser->start; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '"') + { + if (p+1 < parser->end && p[1] == '"') /* double quotes */ + { + push_token( parser, p + 1 ); + parser->start = token_end = p + 2; + p++; + } + else /* end of quotes */ + { + push_token( parser, p ); + parser->start = p + 1; + pop_state( parser ); + return p + 1; + } + } + } + push_token( parser, p ); + pop_state( parser ); + return p; +} + + +/* handler for parser LEADING_SPACES state */ +static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\\') + { + parser->start = p; + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + parser->start = p; + pop_state( parser ); + return p; +} + + +/* handler for parser TRAILING_SPACES state */ +static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p; + + for (p = pos; !is_eol( parser, p ); p++) + { + if (*p == '\\') + { + set_state( parser, EOL_BACKSLASH ); + return p; + } + if (!isspace(*p)) + break; + } + pop_state( parser ); + return p; +} + + +/* handler for parser COMMENT state */ +static const CHAR *comment_state( struct parser *parser, const CHAR *pos ) +{ + const CHAR *p = pos; + + while (!is_eol( parser, p )) + p++; + pop_state( parser ); + return p; +} + + +/* parse a complete buffer */ +static BOOL +InfpParseBuffer (PINFCACHE file, + const CHAR *buffer, + const CHAR *end, + PULONG error_line) +{ + struct parser parser; + const CHAR *pos = buffer; + + parser.start = buffer; + parser.end = end; + parser.file = file; + parser.line = NULL; + parser.state = LINE_START; + parser.stack_pos = 0; + parser.cur_section = NULL; + parser.line_pos = 1; + parser.error = 0; + parser.token_len = 0; + + /* parser main loop */ + while (pos) + pos = (parser_funcs[parser.state])(&parser, pos); + + if (parser.error) + { + if (error_line) + *error_line = parser.line_pos; + return parser.error; + } + + /* find the [strings] section */ + file->StringsSection = InfpCacheFindSection (file, + "Strings"); + + return TRUE; +} + + + +/* PUBLIC FUNCTIONS *********************************************************/ + +BOOL +InfOpenFile(PHINF InfHandle, + PCHAR FileName, + PULONG ErrorLine) +{ + FILE *File; + PCHAR FileBuffer; + ULONG FileLength; + PINFCACHE Cache; + + *InfHandle = NULL; + *ErrorLine = (ULONG)-1; + + /* Open the inf file */ + File = fopen (FileName, "rb"); + if (File == NULL) + { + DPRINT("fopen() failed\n"); + return FALSE; + } + + DPRINT("fopen() successful\n"); + + /* Query file size */ + fseek (File, 0, SEEK_END); + FileLength = ftell (File); + fseek (File, 0, SEEK_SET); + + DPRINT("File size: %lu\n", FileLength); + + /* Allocate file buffer */ + FileBuffer = malloc (FileLength + 1); + if (FileBuffer == NULL) + { + DPRINT1("malloc() failed\n"); + fclose (File); + return FALSE; + } + + /* Read file */ + if (fread (FileBuffer, FileLength, 1, File) < 0) + { + DPRINT ("fread() failed\n"); + fclose (File); + free (FileBuffer); + return FALSE; + } + + fclose (File); + + /* Append string terminator */ + FileBuffer[FileLength] = 0; + + /* Allocate infcache header */ + Cache = (PINFCACHE)malloc (sizeof(INFCACHE)); + if (Cache == NULL) + { + DPRINT("malloc() failed\n"); + free (FileBuffer); + return FALSE; + } + + /* Initialize inicache header */ + memset (Cache, 0, sizeof(INFCACHE)); + + /* Parse the inf buffer */ + if (!InfpParseBuffer (Cache, + FileBuffer, + FileBuffer + FileLength, + ErrorLine)) + { + free (Cache); + free (FileBuffer); + return FALSE; + } + + /* Free file buffer */ + free (FileBuffer); + + *InfHandle = (HINF)Cache; + + return TRUE; +} + + +VOID +InfCloseFile(HINF InfHandle) +{ + PINFCACHE Cache; + + Cache = (PINFCACHE)InfHandle; + + if (Cache == NULL) + { + return; + } + + while (Cache->FirstSection != NULL) + { + Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection); + } + Cache->LastSection = NULL; + + free (Cache); +} + + +BOOL +InfFindFirstLine (HINF InfHandle, + PCHAR Section, + PCHAR Key, + PINFCONTEXT Context) +{ + PINFCACHE Cache; + PINFCACHESECTION CacheSection; + PINFCACHELINE CacheLine; + + if (InfHandle == NULL || Section == NULL || Context == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + Cache = (PINFCACHE)InfHandle; + + /* Iterate through list of sections */ + CacheSection = Cache->FirstSection; + while (Section != NULL) + { + DPRINT("Comparing '%s' and '%s'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (strcasecmp(CacheSection->Name, Section) == 0) + { + if (Key != NULL) + { + CacheLine = InfpCacheFindKeyLine (CacheSection, (PCHAR)Key); + } + else + { + CacheLine = CacheSection->FirstLine; + } + + if (CacheLine == NULL) + return FALSE; + + Context->Inf = (PVOID)Cache; + Context->Section = (PVOID)CacheSection; + Context->Line = (PVOID)CacheLine; + + return TRUE; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + + DPRINT("Section not found\n"); + + return FALSE; +} + + +BOOL +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL) + return FALSE; + + if (ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + if (CacheLine->Next == NULL) + return FALSE; + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)(CacheLine->Next); + + return TRUE; +} + + +BOOL +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL) + return FALSE; + + CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && strcasecmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +BOOL +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && strcasecmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +LONG +InfGetLineCount(HINF InfHandle, + PCHAR Section) +{ + PINFCACHE Cache; + PINFCACHESECTION CacheSection; + + if (InfHandle == NULL || Section == NULL) + { + DPRINT("Invalid parameter\n"); + return -1; + } + + Cache = (PINFCACHE)InfHandle; + + /* Iterate through list of sections */ + CacheSection = Cache->FirstSection; + while (Section != NULL) + { + DPRINT("Comparing '%s' and '%s'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (strcasecmp(CacheSection->Name, Section) == 0) + { + return CacheSection->LineCount; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + + DPRINT("Section not found\n"); + + return -1; +} + + +/* InfGetLineText */ + + +LONG +InfGetFieldCount(PINFCONTEXT Context) +{ + if (Context == NULL || Context->Line == NULL) + return 0; + + return ((PINFCACHELINE)Context->Line)->FieldCount; +} + + +BOOL +InfGetBinaryField (PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + ULONG Size; + PUCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Size = CacheLine->FieldCount - FieldIndex + 1; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + /* Copy binary data */ + Ptr = ReturnBuffer; + while (CacheField != NULL) + { + *Ptr = (UCHAR)strtoul (CacheField->Data, NULL, 16); + + Ptr++; + CacheField = CacheField->Next; + } + } + + return TRUE; +} + + +BOOL +InfGetIntField (PINFCONTEXT Context, + ULONG FieldIndex, + PLONG IntegerValue) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + PCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || IntegerValue == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + *IntegerValue = strtol (Ptr, NULL, 0); + + return TRUE; +} + + +BOOL +InfGetMultiSzField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + PINFCACHEFIELD FieldPtr; + ULONG Index; + ULONG Size; + PCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + /* Calculate the required buffer size */ + FieldPtr = CacheField; + Size = 0; + while (FieldPtr != NULL) + { + Size += (strlen (FieldPtr->Data) + 1); + FieldPtr = FieldPtr->Next; + } + Size++; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + /* Copy multi-sz string */ + Ptr = ReturnBuffer; + FieldPtr = CacheField; + while (FieldPtr != NULL) + { + Size = strlen (FieldPtr->Data) + 1; + + strcpy (Ptr, FieldPtr->Data); + + Ptr = Ptr + Size; + FieldPtr = FieldPtr->Next; + } + *Ptr = 0; + } + + return TRUE; +} + + +BOOL +InfGetStringField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + PCHAR Ptr; + ULONG Size; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + Size = strlen (Ptr) + 1; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + strcpy (ReturnBuffer, Ptr); + } + + return TRUE; +} + + + + +BOOL +InfGetData (PINFCONTEXT Context, + PCHAR *Key, + PCHAR *Data) +{ + PINFCACHELINE CacheKey; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheKey = (PINFCACHELINE)Context->Line; + if (Key != NULL) + *Key = CacheKey->Key; + + if (Data != NULL) + { + if (CacheKey->FirstField == NULL) + { + *Data = NULL; + } + else + { + *Data = CacheKey->FirstField->Data; + } + } + + return TRUE; +} + + +BOOL +InfGetDataField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR *Data) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + ULONG Index; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { + DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + *Data = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + *Data = CacheField->Data; + } + + return TRUE; +} + + +/* EOF */ diff --git a/tools/mkhive/infcache.h b/tools/mkhive/infcache.h new file mode 100644 index 0000000..40403b3 --- /dev/null +++ b/tools/mkhive/infcache.h @@ -0,0 +1,132 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/infcache.h + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#ifndef __INFCACHE_H__ +#define __INFCACHE_H__ + + +#define STATUS_BAD_SECTION_NAME_LINE (0xC0700001) +#define STATUS_SECTION_NAME_TOO_LONG (0xC0700002) +#define STATUS_WRONG_INF_STYLE (0xC0700003) +#define STATUS_NOT_ENOUGH_MEMORY (0xC0700004) + +#define MAX_INF_STRING_LENGTH 512 + +typedef PVOID HINF, *PHINF; + +typedef struct _INFCONTEXT +{ + PVOID Inf; +// PVOID CurrentInf; + PVOID Section; + PVOID Line; +} INFCONTEXT, *PINFCONTEXT; + + +/* FUNCTIONS ****************************************************************/ + +BOOL +InfOpenFile (PHINF InfHandle, + PCHAR FileName, + PULONG ErrorLine); + +VOID +InfCloseFile (HINF InfHandle); + + +BOOL +InfFindFirstLine (HINF InfHandle, + PCHAR Section, + PCHAR Key, + PINFCONTEXT Context); + +BOOL +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut); + +BOOL +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut); + +BOOL +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut); + + +LONG +InfGetLineCount (HINF InfHandle, + PCHAR Section); + +LONG +InfGetFieldCount (PINFCONTEXT Context); + + +BOOL +InfGetBinaryField (PINFCONTEXT Context, + ULONG FieldIndex, + PUCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +BOOL +InfGetIntField (PINFCONTEXT Context, + ULONG FieldIndex, + PLONG IntegerValue); + +BOOL +InfGetMultiSzField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + +BOOL +InfGetStringField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR ReturnBuffer, + ULONG ReturnBufferSize, + PULONG RequiredSize); + + + +BOOL +InfGetData (PINFCONTEXT Context, + PCHAR *Key, + PCHAR *Data); + +BOOL +InfGetDataField (PINFCONTEXT Context, + ULONG FieldIndex, + PCHAR *Data); + +#endif /* __INFCACHE_H__ */ + +/* EOF */ diff --git a/tools/mkhive/mkhive.c b/tools/mkhive/mkhive.c new file mode 100644 index 0000000..839f76a --- /dev/null +++ b/tools/mkhive/mkhive.c @@ -0,0 +1,149 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/mkhive.c + * PURPOSE: Hive maker + * PROGRAMMER: Eric Kohl + */ + +#include +#include + +#include "mkhive.h" +#include "registry.h" +#include "reginf.h" +#include "binhive.h" + +#ifndef WIN32 +#ifndef PATH_MAX +#define PATH_MAX 260 +#endif +#define DIR_SEPARATOR_CHAR '/' +#define DIR_SEPARATOR_STRING "/" +#else +#define DIR_SEPARATOR_CHAR '\\' +#define DIR_SEPARATOR_STRING "\\" +#endif + + +void usage (void) +{ + printf ("Usage: mkhive \n\n"); + printf (" srcdir - inf files are read from this directory\n"); + printf (" dstdir - binary hive files are created in this directory\n"); +} + +void convert_path(char *dst, char *src) +{ + int i; + + i = 0; + while (src[i] != 0) + { +#ifdef WIN32 + if (src[i] == '/') + { + dst[i] = '\\'; + } +#else + if (src[i] == '\\') + { + dst[i] = '/'; + } +#endif + else + { + dst[i] = src[i]; + } + + i++; + } + dst[i] = 0; +} + + +int main (int argc, char *argv[]) +{ + char FileName[PATH_MAX]; + + printf ("Binary hive maker\n"); + + if (argc < 3) + { + usage (); + return 1; + } + + RegInitializeRegistry (); + + convert_path (FileName, argv[1]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "hivesys.inf"); + ImportRegistryFile (FileName, "AddReg", FALSE); + + convert_path (FileName, argv[1]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "hivecls.inf"); + ImportRegistryFile (FileName, "AddReg", FALSE); + + convert_path (FileName, argv[1]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "hivesft.inf"); + ImportRegistryFile (FileName, "AddReg", FALSE); + + convert_path (FileName, argv[1]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "hivedef.inf"); + ImportRegistryFile (FileName, "AddReg", FALSE); + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "system"); + ExportBinaryHive (FileName, "\\Registry\\Machine\\SYSTEM"); + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "software"); + ExportBinaryHive (FileName, "\\Registry\\Machine\\SOFTWARE"); + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "sam"); + ExportBinaryHive (FileName, "\\Registry\\Machine\\SAM"); + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "security"); + ExportBinaryHive (FileName, "\\Registry\\Machine\\SECURITY"); + + convert_path (FileName, argv[2]); + strcat (FileName, DIR_SEPARATOR_STRING); + strcat (FileName, "default"); + ExportBinaryHive (FileName, "\\Registry\\User\\.DEFAULT"); + +// RegShutdownRegistry (); + + printf (" Done.\n"); + + return 0; +} + +/* EOF */ diff --git a/tools/mkhive/mkhive.h b/tools/mkhive/mkhive.h new file mode 100644 index 0000000..b78f25f --- /dev/null +++ b/tools/mkhive/mkhive.h @@ -0,0 +1,77 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/mkhive.h + * PURPOSE: Hive maker + * PROGRAMMER: Eric Kohl + */ + +#ifndef __MKHIVE_H__ +#define __MKHIVE_H__ + + +#define VOID void +typedef void *PVOID; +typedef char CHAR, *PCHAR; +typedef short WCHAR, *PWCHAR; +typedef unsigned char UCHAR, *PUCHAR; +typedef short SHORT, *PSHORT; +typedef unsigned short USHORT, *PUSHORT; +typedef long LONG, *PLONG; +typedef unsigned long ULONG, *PULONG; + +typedef unsigned long ULONG_PTR; + +typedef int BOOL, *PBOOL; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif + + +#ifndef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + + +/* Debugging macros */ + +#define DPRINT1(args...) do { printf("(%s:%d) ",__FILE__,__LINE__); printf(args); } while(0); +#define CHECKPOINT1 do { printf("%s:%d\n",__FILE__,__LINE__); } while(0); + +#define DPRINT(args...) +#define CHECKPOINT + + +#endif /* __MKHIVE_H__ */ + +/* EOF */ diff --git a/tools/mkhive/reginf.c b/tools/mkhive/reginf.c new file mode 100644 index 0000000..3cd68dc --- /dev/null +++ b/tools/mkhive/reginf.c @@ -0,0 +1,470 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/reginf.h + * PURPOSE: Inf file import code + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include + +#include "mkhive.h" +#include "registry.h" +#include "infcache.h" + + + +#define FLG_ADDREG_BINVALUETYPE 0x00000001 +#define FLG_ADDREG_NOCLOBBER 0x00000002 +#define FLG_ADDREG_DELVAL 0x00000004 +#define FLG_ADDREG_APPEND 0x00000008 +#define FLG_ADDREG_KEYONLY 0x00000010 +#define FLG_ADDREG_OVERWRITEONLY 0x00000020 +#define FLG_ADDREG_TYPE_SZ 0x00000000 +#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000 +#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000 +#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE) +#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE) + + +/* FUNCTIONS ****************************************************************/ + +static BOOL +GetRootKey (PCHAR Name) +{ + if (!strcasecmp (Name, "HKCR")) + { + strcpy (Name, "\\Registry\\Machine\\SOFTWARE\\Classes\\"); + return TRUE; + } + + if (!strcasecmp (Name, "HKCU")) + { + strcpy (Name, "\\Registry\\User\\.DEFAULT\\"); + return TRUE; + } + + if (!strcasecmp (Name, "HKLM")) + { + strcpy (Name, "\\Registry\\Machine\\"); + return TRUE; + } + + if (!strcasecmp (Name, "HKU")) + { + strcpy (Name, "\\Registry\\User\\"); + return TRUE; + } + +#if 0 + if (!strcasecmp (Name, "HKR")) + return FALSE; +#endif + + return FALSE; +} + + +/*********************************************************************** + * append_multi_sz_value + * + * Append a multisz string to a multisz registry value. + */ +#if 0 +static void +append_multi_sz_value (HANDLE hkey, + const WCHAR *value, + const WCHAR *strings, + DWORD str_size ) +{ + DWORD size, type, total; + WCHAR *buffer, *p; + + if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; + if (type != REG_MULTI_SZ) return; + + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return; + if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; + + /* compare each string against all the existing ones */ + total = size; + while (*strings) + { + int len = strlenW(strings) + 1; + + for (p = buffer; *p; p += strlenW(p) + 1) + if (!strcmpiW( p, strings )) break; + + if (!*p) /* not found, need to append it */ + { + memcpy( p, strings, len * sizeof(WCHAR) ); + p[len] = 0; + total += len; + } + strings += len; + } + if (total != size) + { + TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) ); + RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total ); + } + done: + HeapFree( GetProcessHeap(), 0, buffer ); +} +#endif + +/*********************************************************************** + * delete_multi_sz_value + * + * Remove a string from a multisz registry value. + */ +#if 0 +static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string ) +{ + DWORD size, type; + WCHAR *buffer, *src, *dst; + + if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return; + if (type != REG_MULTI_SZ) return; + /* allocate double the size, one for value before and one for after */ + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return; + if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done; + src = buffer; + dst = buffer + size; + while (*src) + { + int len = strlenW(src) + 1; + if (strcmpiW( src, string )) + { + memcpy( dst, src, len * sizeof(WCHAR) ); + dst += len; + } + src += len; + } + *dst++ = 0; + if (dst != buffer + 2*size) /* did we remove something? */ + { + TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) ); + RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, + (BYTE *)(buffer + size), dst - (buffer + size) ); + } + done: + HeapFree( GetProcessHeap(), 0, buffer ); +} +#endif + +/*********************************************************************** + * do_reg_operation + * + * Perform an add/delete registry operation depending on the flags. + */ +static BOOL +do_reg_operation(HKEY KeyHandle, + PCHAR ValueName, + PINFCONTEXT Context, + ULONG Flags) +{ + CHAR EmptyStr = (CHAR)0; + ULONG Type; + ULONG Size; +// NTSTATUS Status; + + if (Flags & FLG_ADDREG_DELVAL) /* deletion */ + { +#if 0 + if (ValueName) + { + RegDeleteValueW( hkey, value ); + } + else + { + RegDeleteKeyW( hkey, NULL ); + } +#endif + return TRUE; + } + + if (Flags & FLG_ADDREG_KEYONLY) + return TRUE; + +#if 0 + if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY)) + { + BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL ); + if (exists && (flags & FLG_ADDREG_NOCLOBBER)) + return TRUE; + if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY)) + return TRUE; + } +#endif + + switch (Flags & FLG_ADDREG_TYPE_MASK) + { + case FLG_ADDREG_TYPE_SZ: + Type = REG_SZ; + break; + + case FLG_ADDREG_TYPE_MULTI_SZ: + Type = REG_MULTI_SZ; + break; + + case FLG_ADDREG_TYPE_EXPAND_SZ: + Type = REG_EXPAND_SZ; + break; + + case FLG_ADDREG_TYPE_BINARY: + Type = REG_BINARY; + break; + + case FLG_ADDREG_TYPE_DWORD: + Type = REG_DWORD; + break; + + case FLG_ADDREG_TYPE_NONE: + Type = REG_NONE; + break; + + default: + Type = Flags >> 16; + break; + } + + if (!(Flags & FLG_ADDREG_BINVALUETYPE) || + (Type == REG_DWORD && InfGetFieldCount (Context) == 5)) + { + PCHAR Str = NULL; + + if (Type == REG_MULTI_SZ) + { + if (!InfGetMultiSzField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Str = malloc (Size); + if (Str == NULL) + return FALSE; + + InfGetMultiSzField (Context, 5, Str, Size, NULL); + } + + if (Flags & FLG_ADDREG_APPEND) + { + if (Str == NULL) + return TRUE; + +// append_multi_sz_value( hkey, value, str, size ); + + free (Str); + return TRUE; + } + /* else fall through to normal string handling */ + } + else + { + if (!InfGetStringField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Str = malloc (Size); + if (Str == NULL) + return FALSE; + + InfGetStringField (Context, 5, Str, Size, NULL); + } + } + + if (Type == REG_DWORD) + { + ULONG dw = Str ? strtol (Str, NULL, 0) : 0; + + DPRINT("setting dword %s to %lx\n", ValueName, dw); + + RegSetValue (KeyHandle, + ValueName, + Type, + (PVOID)&dw, + sizeof(ULONG)); + } + else + { + DPRINT ("setting value %wZ to %S\n", ValueName, Str); + + if (Str) + { + RegSetValue (KeyHandle, + ValueName, + Type, + (PVOID)Str, + Size); + } + else + { + RegSetValue (KeyHandle, + ValueName, + Type, + (PVOID)&EmptyStr, + sizeof(CHAR)); + } + } + free (Str); + } + else /* get the binary data */ + { + PUCHAR Data = NULL; + + if (!InfGetBinaryField (Context, 5, NULL, 0, &Size)) + Size = 0; + + if (Size) + { + Data = malloc (Size); + if (Data == NULL) + return FALSE; + + DPRINT("setting binary data %s len %lu\n", ValueName, Size); + InfGetBinaryField (Context, 5, Data, Size, NULL); + } + + RegSetValue (KeyHandle, + ValueName, + Type, + (PVOID)Data, + Size); + + free (Data); + } + + return TRUE; +} + + +/*********************************************************************** + * registry_callback + * + * Called once for each AddReg and DelReg entry in a given section. + */ +static BOOL +registry_callback (HINF hInf, PCHAR Section, BOOL Delete) +{ + CHAR Buffer[MAX_INF_STRING_LENGTH]; + PCHAR ValuePtr; + ULONG Flags; + ULONG Length; + + INFCONTEXT Context; + HKEY KeyHandle; + BOOL Ok; + + + Ok = InfFindFirstLine (hInf, Section, NULL, &Context); + + for (;Ok; Ok = InfFindNextLine (&Context, &Context)) + { + /* get root */ + if (!InfGetStringField (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL)) + continue; + if (!GetRootKey (Buffer)) + continue; + + /* get key */ + Length = strlen (Buffer); + if (!InfGetStringField (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL)) + *Buffer = 0; + + DPRINT("KeyName: <%s>\n", Buffer); + + /* get flags */ + if (!InfGetIntField (&Context, 4, (PLONG)&Flags)) + Flags = 0; + + DPRINT("Flags: %lx\n", Flags); + + if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY)) + { + if (RegOpenKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) + { + DPRINT("RegOpenKey(%s) failed\n", Buffer); + continue; /* ignore if it doesn't exist */ + } + } + else + { + if (RegCreateKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS) + { + DPRINT("RegCreateKey(%s) failed\n", Buffer); + continue; + } + } + + /* get value name */ + if (InfGetStringField (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL)) + { + ValuePtr = Buffer; + } + else + { + ValuePtr = NULL; + } + + /* and now do it */ + if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags)) + { + return FALSE; + } + } + + return TRUE; +} + + +BOOL +ImportRegistryFile(PCHAR FileName, + PCHAR Section, + BOOL Delete) +{ + HINF hInf; + ULONG ErrorLine; + + /* Load inf file from install media. */ + if (!InfOpenFile(&hInf, FileName, &ErrorLine)) + { + DPRINT1 ("InfOpenFile() failed\n"); + return FALSE; + } + + if (!registry_callback (hInf, "AddReg", FALSE)) + { + DPRINT1 ("registry_callback() failed\n"); + } + + InfCloseFile (hInf); + + return TRUE; +} + +/* EOF */ diff --git a/tools/mkhive/reginf.h b/tools/mkhive/reginf.h new file mode 100644 index 0000000..65cfd92 --- /dev/null +++ b/tools/mkhive/reginf.h @@ -0,0 +1,37 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/reginf.h + * PURPOSE: Inf file import code + * PROGRAMMER: Eric Kohl + */ + +#ifndef __REGINF_H__ +#define __REGINF_H__ + +BOOL +ImportRegistryFile(PCHAR Filename, + PCHAR Section, + BOOL Delete); + +#endif /* __REGINF_H__ */ + +/* EOF */ diff --git a/tools/mkhive/registry.c b/tools/mkhive/registry.c new file mode 100644 index 0000000..f29b9d4 --- /dev/null +++ b/tools/mkhive/registry.c @@ -0,0 +1,714 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/registry.c + * PURPOSE: Registry code + * PROGRAMMER: Eric Kohl + */ + +/* + * TODO: + * - Implement RegDeleteKey(). + * - Implement RegQueryMultipleValue(). + * - Fix RegEnumValue(). + */ + +#include +#include + +#include "mkhive.h" +#include "registry.h" + + +static HKEY RootKey; + + +VOID +RegInitializeRegistry(VOID) +{ + HKEY ControlSetKey; + HKEY LinkKey; + + /* Create root key */ + RootKey = (HKEY)malloc(sizeof(KEY)); + + InitializeListHead(&RootKey->SubKeyList); + InitializeListHead(&RootKey->ValueList); + InitializeListHead(&RootKey->KeyList); + + RootKey->SubKeyCount = 0; + RootKey->ValueCount = 0; + + RootKey->NameSize = 2; + RootKey->Name = (PUCHAR)malloc(2); + strcpy(RootKey->Name, "\\"); + + RootKey->DataType = 0; + RootKey->DataSize = 0; + RootKey->Data = NULL; + + /* Create SYSTEM key */ + RegCreateKey(RootKey, + "Registry\\Machine\\SYSTEM", + NULL); + + /* Create link 'CurrentControlSet' --> 'ControlSet001' */ + RegCreateKey(RootKey, + "Registry\\Machine\\SYSTEM\\ControlSet001", + &ControlSetKey); + + RegCreateKey(RootKey, + "Registry\\Machine\\SYSTEM\\CurrentControlSet", + &LinkKey); + + RegSetValue(LinkKey, + NULL, + REG_LINK, + (PUCHAR)&ControlSetKey, + sizeof(PVOID)); + + /* Create HARDWARE key */ + RegCreateKey(RootKey, + "Registry\\Machine\\HARDWARE", + NULL); + + /* Create SAM key */ + RegCreateKey(RootKey, + "Registry\\Machine\\SAM", + NULL); + + /* Create SECURITY key */ + RegCreateKey(RootKey, + "Registry\\Machine\\SECURITY", + NULL); + + /* Create DEFAULT key */ + RegCreateKey(RootKey, + "Registry\\User\\.DEFAULT", + NULL); +} + + +LONG +RegCreateKey(HKEY ParentKey, + PCHAR KeyName, + PHKEY Key) +{ + PLIST_ENTRY Ptr; + HKEY SearchKey = INVALID_HANDLE_VALUE; + HKEY CurrentKey; + HKEY NewKey; + PCHAR p; + PCHAR name; + int subkeyLength; + int stringLength; + + DPRINT ("KeyName '%s'\n", KeyName); + + if (*KeyName == '\\') + { + KeyName++; + CurrentKey = RootKey; + } + else if (ParentKey == NULL) + { + CurrentKey = RootKey; + } + else + { + CurrentKey = ParentKey; + } + + /* Check whether current key is a link */ + if (CurrentKey->DataType == REG_LINK) + { + CurrentKey = (HKEY)CurrentKey->Data; + } + + while (*KeyName != 0) + { + DPRINT ("KeyName '%s'\n", KeyName); + + if (*KeyName == '\\') + KeyName++; + p = strchr (KeyName, '\\'); + if ((p != NULL) && (p != KeyName)) + { + subkeyLength = p - KeyName; + stringLength = subkeyLength + 1; + name = KeyName; + } + else + { + subkeyLength = strlen (KeyName); + stringLength = subkeyLength; + name = KeyName; + } + + Ptr = CurrentKey->SubKeyList.Flink; + while (Ptr != &CurrentKey->SubKeyList) + { + DPRINT ("Ptr 0x%x\n", Ptr); + + SearchKey = CONTAINING_RECORD(Ptr, + KEY, + KeyList); + DPRINT ("SearchKey 0x%x\n", SearchKey); + DPRINT ("Searching '%s'\n", SearchKey->Name); + if (strncmp (SearchKey->Name, name, subkeyLength) == 0) + break; + + Ptr = Ptr->Flink; + } + + if (Ptr == &CurrentKey->SubKeyList) + { + /* no key found -> create new subkey */ + NewKey = (HKEY)malloc (sizeof(KEY)); + if (NewKey == NULL) + return ERROR_OUTOFMEMORY; + + InitializeListHead (&NewKey->SubKeyList); + InitializeListHead (&NewKey->ValueList); + + NewKey->SubKeyCount = 0; + NewKey->ValueCount = 0; + + NewKey->DataType = 0; + NewKey->DataSize = 0; + NewKey->Data = NULL; + + InsertTailList (&CurrentKey->SubKeyList, &NewKey->KeyList); + CurrentKey->SubKeyCount++; + + NewKey->NameSize = subkeyLength + 1; + NewKey->Name = (PCHAR)malloc (NewKey->NameSize); + if (NewKey->Name == NULL) + return(ERROR_OUTOFMEMORY); + memcpy(NewKey->Name, name, subkeyLength); + NewKey->Name[subkeyLength] = 0; + + DPRINT ("NewKey 0x%x\n", NewKey); + DPRINT ("NewKey '%s' Length %d\n", NewKey->Name, NewKey->NameSize); + + CurrentKey = NewKey; + } + else + { + CurrentKey = SearchKey; + + /* Check whether current key is a link */ + if (CurrentKey->DataType == REG_LINK) + { + CurrentKey = (HKEY)CurrentKey->Data; + } + } + + KeyName = KeyName + stringLength; + } + + if (Key != NULL) + *Key = CurrentKey; + + return ERROR_SUCCESS; +} + + +LONG +RegDeleteKey(HKEY Key, + PCHAR Name) +{ + + + if (strchr(Name, '\\') != NULL) + return(ERROR_INVALID_PARAMETER); + + + + return(ERROR_SUCCESS); +} + + +LONG +RegEnumKey(HKEY Key, + ULONG Index, + PCHAR Name, + PULONG NameSize) +{ + PLIST_ENTRY Ptr; + HKEY SearchKey; + ULONG Count = 0; + ULONG Size; + + Ptr = Key->SubKeyList.Flink; + while (Ptr != &Key->SubKeyList) + { + if (Index == Count) + break; + + Count++; + Ptr = Ptr->Flink; + } + + if (Ptr == &Key->SubKeyList) + return(ERROR_NO_MORE_ITEMS); + + SearchKey = CONTAINING_RECORD(Ptr, + KEY, + KeyList); + + DPRINT ("Name '%s' Length %d\n", SearchKey->Name, SearchKey->NameSize); + + Size = min(SearchKey->NameSize, *NameSize); + *NameSize = Size; + memcpy(Name, SearchKey->Name, Size); + + return(ERROR_SUCCESS); +} + + +LONG +RegOpenKey(HKEY ParentKey, + PCHAR KeyName, + PHKEY Key) +{ + PLIST_ENTRY Ptr; + HKEY SearchKey = INVALID_HANDLE_VALUE; + HKEY CurrentKey; + PCHAR p; + PCHAR name; + int subkeyLength; + int stringLength; + + DPRINT("KeyName '%s'\n", KeyName); + + *Key = NULL; + + if (*KeyName == '\\') + { + KeyName++; + CurrentKey = RootKey; + } + else if (ParentKey == NULL) + { + CurrentKey = RootKey; + } + else + { + CurrentKey = ParentKey; + } + + /* Check whether current key is a link */ + if (CurrentKey->DataType == REG_LINK) + { + CurrentKey = (HKEY)CurrentKey->Data; + } + + while (*KeyName != 0) + { + DPRINT ("KeyName '%s'\n", KeyName); + + if (*KeyName == '\\') + KeyName++; + p = strchr(KeyName, '\\'); + if ((p != NULL) && (p != KeyName)) + { + subkeyLength = p - KeyName; + stringLength = subkeyLength + 1; + name = KeyName; + } + else + { + subkeyLength = strlen(KeyName); + stringLength = subkeyLength; + name = KeyName; + } + + Ptr = CurrentKey->SubKeyList.Flink; + while (Ptr != &CurrentKey->SubKeyList) + { + DPRINT ("Ptr 0x%x\n", Ptr); + + SearchKey = CONTAINING_RECORD(Ptr, + KEY, + KeyList); + + DPRINT ("SearchKey 0x%x\n", SearchKey); + DPRINT ("Searching '%s'\n", SearchKey->Name); + + if (strncmp(SearchKey->Name, name, subkeyLength) == 0) + break; + + Ptr = Ptr->Flink; + } + + if (Ptr == &CurrentKey->SubKeyList) + { + return(ERROR_PATH_NOT_FOUND); + } + else + { + CurrentKey = SearchKey; + + /* Check whether current key is a link */ + if (CurrentKey->DataType == REG_LINK) + { + CurrentKey = (HKEY)CurrentKey->Data; + } + } + + KeyName = KeyName + stringLength; + } + + if (Key != NULL) + *Key = CurrentKey; + + return(ERROR_SUCCESS); +} + + +LONG +RegSetValue(HKEY Key, + PCHAR ValueName, + ULONG Type, + PUCHAR Data, + ULONG DataSize) +{ + PLIST_ENTRY Ptr; + PVALUE Value = NULL; + + DPRINT ("Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n", + (int)Key, ValueName, (int)Type, (int)Data, (int)DataSize); + + if ((ValueName == NULL) || (*ValueName == 0)) + { + /* set default value */ + if ((Key->Data != NULL) && (Key->DataSize > sizeof(PUCHAR))) + { + free(Key->Data); + } + + if (DataSize <= sizeof(PUCHAR)) + { + Key->DataSize = DataSize; + Key->DataType = Type; + memcpy(&Key->Data, Data, DataSize); + } + else + { + Key->Data = (PUCHAR)malloc(DataSize); + Key->DataSize = DataSize; + Key->DataType = Type; + memcpy(Key->Data, Data, DataSize); + } + } + else + { + /* set non-default value */ + Ptr = Key->ValueList.Flink; + while (Ptr != &Key->ValueList) + { + Value = CONTAINING_RECORD(Ptr, + VALUE, + ValueList); + + DPRINT ("Value->Name '%s'\n", Value->Name); + + if (strcasecmp(Value->Name, ValueName) == 0) + break; + + Ptr = Ptr->Flink; + } + + if (Ptr == &Key->ValueList) + { + /* add new value */ + DPRINT("No value found - adding new value\n"); + + Value = (PVALUE)malloc(sizeof(VALUE)); + if (Value == NULL) + return(ERROR_OUTOFMEMORY); + InsertTailList(&Key->ValueList, &Value->ValueList); + Key->ValueCount++; + Value->NameSize = strlen(ValueName)+1; + Value->Name = (PCHAR)malloc(Value->NameSize); + if (Value->Name == NULL) + return(ERROR_OUTOFMEMORY); + strcpy(Value->Name, ValueName); + Value->DataType = REG_NONE; + Value->DataSize = 0; + Value->Data = NULL; + } + + /* set new value */ + if ((Value->Data != NULL) && (Value->DataSize > sizeof(PUCHAR))) + { + free(Value->Data); + } + + if (DataSize <= sizeof(PUCHAR)) + { + Value->DataSize = DataSize; + Value->DataType = Type; + memcpy(&Value->Data, Data, DataSize); + } + else + { + Value->Data = (PUCHAR)malloc(DataSize); + if (Value->Data == NULL) + return(ERROR_OUTOFMEMORY); + Value->DataType = Type; + Value->DataSize = DataSize; + memcpy(Value->Data, Data, DataSize); + } + } + return(ERROR_SUCCESS); +} + + +LONG +RegQueryValue(HKEY Key, + PCHAR ValueName, + PULONG Type, + PUCHAR Data, + PULONG DataSize) +{ + ULONG Size; + PLIST_ENTRY Ptr; + PVALUE Value = NULL; + + if ((ValueName == NULL) || (*ValueName == 0)) + { + /* query default value */ + if (Key->Data == NULL) + return(ERROR_INVALID_PARAMETER); + + if (Type != NULL) + *Type = Key->DataType; + if ((Data != NULL) && (DataSize != NULL)) + { + if (Key->DataSize <= sizeof(PUCHAR)) + { + Size = min(Key->DataSize, *DataSize); + memcpy(Data, &Key->Data, Size); + *DataSize = Size; + } + else + { + Size = min(Key->DataSize, *DataSize); + memcpy(Data, Key->Data, Size); + *DataSize = Size; + } + } + else if ((Data == NULL) && (DataSize != NULL)) + { + *DataSize = Key->DataSize; + } + } + else + { + /* query non-default value */ + Ptr = Key->ValueList.Flink; + while (Ptr != &Key->ValueList) + { + Value = CONTAINING_RECORD(Ptr, + VALUE, + ValueList); + + DPRINT("Searching for '%s'. Value name '%s'\n", ValueName, Value->Name); + + if (strcasecmp(Value->Name, ValueName) == 0) + break; + + Ptr = Ptr->Flink; + } + + if (Ptr == &Key->ValueList) + return(ERROR_INVALID_PARAMETER); + + if (Type != NULL) + *Type = Value->DataType; + if ((Data != NULL) && (DataSize != NULL)) + { + if (Value->DataSize <= sizeof(PUCHAR)) + { + Size = min(Value->DataSize, *DataSize); + memcpy(Data, &Value->Data, Size); + *DataSize = Size; + } + else + { + Size = min(Value->DataSize, *DataSize); + memcpy(Data, Value->Data, Size); + *DataSize = Size; + } + } + else if ((Data == NULL) && (DataSize != NULL)) + { + *DataSize = Value->DataSize; + } + } + + return(ERROR_SUCCESS); +} + + +LONG +RegDeleteValue(HKEY Key, + PCHAR ValueName) +{ + PLIST_ENTRY Ptr; + PVALUE Value = NULL; + + if ((ValueName == NULL) || (*ValueName == 0)) + { + /* delete default value */ + if (Key->Data != NULL) + free(Key->Data); + Key->Data = NULL; + Key->DataSize = 0; + Key->DataType = 0; + } + else + { + /* delete non-default value */ + Ptr = Key->ValueList.Flink; + while (Ptr != &Key->ValueList) + { + Value = CONTAINING_RECORD(Ptr, + VALUE, + ValueList); + if (strcmp(Value->Name, ValueName) == 0) + break; + + Ptr = Ptr->Flink; + } + + if (Ptr == &Key->ValueList) + return(ERROR_INVALID_PARAMETER); + + /* delete value */ + Key->ValueCount--; + if (Value->Name != NULL) + free(Value->Name); + Value->Name = NULL; + Value->NameSize = 0; + + if (Value->DataSize > sizeof(PUCHAR)) + { + if (Value->Data != NULL) + free(Value->Data); + } + Value->Data = NULL; + Value->DataSize = 0; + Value->DataType = 0; + + RemoveEntryList(&Value->ValueList); + free(Value); + } + return(ERROR_SUCCESS); +} + + +LONG +RegEnumValue(HKEY Key, + ULONG Index, + PCHAR ValueName, + PULONG NameSize, + PULONG Type, + PUCHAR Data, + PULONG DataSize) +{ + PLIST_ENTRY Ptr; + PVALUE Value; + ULONG Count = 0; + + if (Key->Data != NULL) + { + if (Index > 0) + { + Index--; + } + else + { + /* enumerate default value */ + if (ValueName != NULL) + *ValueName = 0; + if (Type != NULL) + *Type = Key->DataType; + if (DataSize != NULL) + *DataSize = Key->DataSize; + + /* FIXME: return more values */ + } + } + + Ptr = Key->ValueList.Flink; + while (Ptr != &Key->ValueList) + { + if (Index == Count) + break; + + Count++; + Ptr = Ptr->Flink; + } + + if (Ptr == &Key->ValueList) + return(ERROR_NO_MORE_ITEMS); + + Value = CONTAINING_RECORD(Ptr, + VALUE, + ValueList); + + /* FIXME: return values */ + + return(ERROR_SUCCESS); +} + + +ULONG +RegGetSubKeyCount (HKEY Key) +{ + return Key->SubKeyCount; +} + + +ULONG +RegGetValueCount (HKEY Key) +{ + if (Key->DataSize != 0) + return Key->ValueCount + 1; + + return Key->ValueCount; +} + + + +#if 0 +LONG +RegQueryMultipleValue(HKEY Key, + ...) +{ + return(ERROR_SUCCESS); +} +#endif + +/* EOF */ diff --git a/tools/mkhive/registry.h b/tools/mkhive/registry.h new file mode 100644 index 0000000..fd87ecd --- /dev/null +++ b/tools/mkhive/registry.h @@ -0,0 +1,306 @@ +/* + * ReactOS kernel + * Copyright (C) 2003 ReactOS Team + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id$ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS hive maker + * FILE: tools/mkhive/registry.h + * PURPOSE: Registry code + * PROGRAMMER: Eric Kohl + */ + +#ifndef __REGISTRY_H__ +#define __REGISTRY_H__ + + +#define INVALID_HANDLE_VALUE NULL + +typedef struct _LIST_ENTRY +{ + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; +} LIST_ENTRY, *PLIST_ENTRY; + + +typedef struct _REG_KEY +{ + LIST_ENTRY KeyList; + LIST_ENTRY SubKeyList; + LIST_ENTRY ValueList; + + ULONG SubKeyCount; + ULONG ValueCount; + + ULONG NameSize; + PUCHAR Name; + + /* default data */ + ULONG DataType; + ULONG DataSize; + PUCHAR Data; +} KEY, *HKEY, **PHKEY; + + +typedef struct _REG_VALUE +{ + LIST_ENTRY ValueList; + + /* value name */ + ULONG NameSize; + PUCHAR Name; + + /* value data */ + ULONG DataType; + ULONG DataSize; + PUCHAR Data; +} VALUE, *PVALUE; + + +#define ERROR_SUCCESS 0L +#define ERROR_PATH_NOT_FOUND 2L +#define ERROR_OUTOFMEMORY 14L +#define ERROR_INVALID_PARAMETER 87L +#define ERROR_MORE_DATA 234L +#define ERROR_NO_MORE_ITEMS 259L + + +#define assert(x) + +/* + * VOID + * InitializeListHead ( + * PLIST_ENTRY ListHead + * ); + * + * FUNCTION: Initializes a double linked list + * ARGUMENTS: + * ListHead = Caller supplied storage for the head of the list + */ +#define InitializeListHead(ListHead) \ +{ \ + (ListHead)->Flink = (ListHead); \ + (ListHead)->Blink = (ListHead); \ +} + + +/* + * VOID + * InsertHeadList ( + * PLIST_ENTRY ListHead, + * PLIST_ENTRY Entry + * ); + * + * FUNCTION: Inserts an entry in a double linked list + * ARGUMENTS: + * ListHead = Head of the list + * Entry = Entry to insert + */ +#define InsertHeadList(ListHead, ListEntry) \ +{ \ + PLIST_ENTRY OldFlink; \ + OldFlink = (ListHead)->Flink; \ + (ListEntry)->Flink = OldFlink; \ + (ListEntry)->Blink = (ListHead); \ + OldFlink->Blink = (ListEntry); \ + (ListHead)->Flink = (ListEntry); \ + assert((ListEntry) != NULL); \ + assert((ListEntry)->Blink!=NULL); \ + assert((ListEntry)->Blink->Flink == (ListEntry)); \ + assert((ListEntry)->Flink != NULL); \ + assert((ListEntry)->Flink->Blink == (ListEntry)); \ +} + + +/* + * VOID + * InsertTailList ( + * PLIST_ENTRY ListHead, + * PLIST_ENTRY Entry + * ); + * + * FUNCTION: + * Inserts an entry in a double linked list + * + * ARGUMENTS: + * ListHead = Head of the list + * Entry = Entry to insert + */ +#define InsertTailList(ListHead, ListEntry) \ +{ \ + PLIST_ENTRY OldBlink; \ + OldBlink = (ListHead)->Blink; \ + (ListEntry)->Flink = (ListHead); \ + (ListEntry)->Blink = OldBlink; \ + OldBlink->Flink = (ListEntry); \ + (ListHead)->Blink = (ListEntry); \ + assert((ListEntry) != NULL); \ + assert((ListEntry)->Blink != NULL); \ + assert((ListEntry)->Blink->Flink == (ListEntry)); \ + assert((ListEntry)->Flink != NULL); \ + assert((ListEntry)->Flink->Blink == (ListEntry)); \ +} + +/* + * BOOLEAN + * IsListEmpty ( + * PLIST_ENTRY ListHead + * ); + * + * FUNCTION: + * Checks if a double linked list is empty + * + * ARGUMENTS: + * ListHead = Head of the list +*/ +#define IsListEmpty(ListHead) \ + ((ListHead)->Flink == (ListHead)) + + +/* + *VOID + *RemoveEntryList ( + * PLIST_ENTRY Entry + * ); + * + * FUNCTION: + * Removes an entry from a double linked list + * + * ARGUMENTS: + * ListEntry = Entry to remove + */ +#define RemoveEntryList(ListEntry) \ +{ \ + PLIST_ENTRY OldFlink; \ + PLIST_ENTRY OldBlink; \ + assert((ListEntry) != NULL); \ + assert((ListEntry)->Blink!=NULL); \ + assert((ListEntry)->Blink->Flink == (ListEntry)); \ + assert((ListEntry)->Flink != NULL); \ + assert((ListEntry)->Flink->Blink == (ListEntry)); \ + OldFlink = (ListEntry)->Flink; \ + OldBlink = (ListEntry)->Blink; \ + OldFlink->Blink = OldBlink; \ + OldBlink->Flink = OldFlink; \ + (ListEntry)->Flink = NULL; \ + (ListEntry)->Blink = NULL; \ +} + +/* + * PURPOSE: Returns the byte offset of a field within a structure + */ +#define FIELD_OFFSET(Type,Field) (LONG)(&(((Type *)(0))->Field)) + +/* + * PURPOSE: Returns the base address structure if the caller knows the + * address of a field within the structure + * ARGUMENTS: + * Address = address of the field + * Type = Type of the whole structure + * Field = Name of the field whose address is none + */ +#define CONTAINING_RECORD(Address,Type,Field) \ + (Type *)(((LONG)Address) - FIELD_OFFSET(Type,Field)) + + +#define REG_NONE 0 +#define REG_SZ 1 +#define REG_EXPAND_SZ 2 +#define REG_BINARY 3 +#define REG_DWORD 4 +#define REG_DWORD_BIG_ENDIAN 5 +#define REG_DWORD_LITTLE_ENDIAN 4 +#define REG_LINK 6 +#define REG_MULTI_SZ 7 +#define REG_RESOURCE_LIST 8 +#define REG_FULL_RESOURCE_DESCRIPTOR 9 +#define REG_RESOURCE_REQUIREMENTS_LIST 10 + + + +VOID +RegInitializeRegistry(VOID); + +LONG +RegCreateKey(HKEY ParentKey, + PCHAR KeyName, + PHKEY Key); + +LONG +RegDeleteKey(HKEY Key, + PCHAR Name); + +LONG +RegEnumKey(HKEY Key, + ULONG Index, + PCHAR Name, + PULONG NameSize); + +LONG +RegOpenKey(HKEY ParentKey, + PCHAR KeyName, + PHKEY Key); + + +LONG +RegSetValue(HKEY Key, + PCHAR ValueName, + ULONG Type, + PUCHAR Data, + ULONG DataSize); + +LONG +RegQueryValue(HKEY Key, + PCHAR ValueName, + PULONG Type, + PUCHAR Data, + PULONG DataSize); + +LONG +RegDeleteValue(HKEY Key, + PCHAR ValueName); + +LONG +RegEnumValue(HKEY Key, + ULONG Index, + PCHAR ValueName, + PULONG NameSize, + PULONG Type, + PUCHAR Data, + PULONG DataSize); + +ULONG +RegGetSubKeyCount (HKEY Key); + +ULONG +RegGetValueCount (HKEY Key); + + +#if 0 +BOOL +RegImportTextHive(PCHAR ChunkBase, + U32 ChunkSize); + +BOOL +RegImportBinaryHive(PCHAR ChunkBase, + U32 ChunkSize); +#endif + +#endif /* __REGISTRY_H__ */ + +/* EOF */ + diff --git a/tools/rline.c b/tools/rline.c new file mode 100755 index 0000000..fe3a15c --- /dev/null +++ b/tools/rline.c @@ -0,0 +1,137 @@ +/* + * Copy a text file with end-of-line character transformation (EOL) + * + * Usage: rline input-file output-file + */ +#include +#include +#include +#include + +char* convert_path(char* origpath) +{ + char* newpath; + int i; + + newpath = strdup(origpath); + + i = 0; + while (newpath[i] != 0) + { +#ifdef UNIX_PATHS + if (newpath[i] == '\\') + { + newpath[i] = '/'; + } +#else +#ifdef DOS_PATHS + if (newpath[i] == '/') + { + newpath[i] = '\\'; + } +#endif +#endif + i++; + } + return(newpath); +} + +int +fsize (FILE * f) +{ + struct stat st; + int fh = fileno (f); + + if (fh < 0 || fstat (fh, &st) < 0) + return -1; + return (int) st.st_size; +} + +int main(int argc, char* argv[]) +{ + char* path1; + char* path2; + FILE* in; + FILE* out; + char* in_buf; + char* out_buf; + int in_size; + int in_ptr; + int linelen; + int n_in; + int n_out; + char eol_buf[2]; + + /* Terminate the line with windows EOL characters (CRLF) */ + eol_buf[0] = '\r'; + eol_buf[1] = '\n'; + + if (argc != 3) + { + fprintf(stderr, "Wrong argument count\n"); + exit(1); + } + + path1 = convert_path(argv[1]); + path2 = convert_path(argv[2]); + + in = fopen(path1, "rb"); + if (in == NULL) + { + perror("Cannot open input file"); + exit(1); + } + + in_size = fsize(in); + in_buf = malloc(in_size); + if (in_buf == NULL) + { + perror("Not enough free memory"); + fclose(in); + exit(1); + } + + out = fopen(path2, "wb"); + if (out == NULL) + { + perror("Cannot open output file"); + fclose(in); + exit(1); + } + + /* Read it all in */ + n_in = fread(in_buf, 1, in_size, in); + + in_ptr = 0; + while (in_ptr < in_size) + { + linelen = 0; + + while ((in_ptr + linelen < in_size) && (in_buf[in_ptr + linelen] != '\r') && (in_buf[in_ptr + linelen] != '\n')) + { + linelen++; + } + if (linelen > 0) + { + n_out = fwrite(&in_buf[in_ptr], 1, linelen, out); + in_ptr += linelen; + } + /* Terminate the line */ + n_out = fwrite(&eol_buf[0], 1, sizeof(eol_buf), out); + + if ((in_ptr < in_size) && (in_buf[in_ptr] == '\r')) + { + in_ptr++; + } + + if ((in_ptr < in_size) && (in_buf[in_ptr] == '\n')) + { + in_ptr++; + } + } + + free(in_buf); + fclose(in); + + exit(0); +} diff --git a/txtsetup.sif b/txtsetup.sif deleted file mode 100644 index a4eb3f2..0000000 --- a/txtsetup.sif +++ /dev/null @@ -1,98 +0,0 @@ -[Version] -Signature = "$ReactOS$" - -[Directories] -1 = "\" -2 = system32 -3 = system32\drivers -4 = system32\config -5 = media -6 = media\fonts -7 = bin - -[SourceFiles] -ntoskrnl.exe = 2 -hal.dll = 2 - -acpi.sys = 3 -isapnp.sys = 3 - -beep.sys = 3 -blue.sys = 3 -floppy.sys = 3 -null.sys = 3 -serial.sys = 3 -vgaddi.dll = 3 -vgamp.sys = 3 -vidport.sys = 3 - -cdfs.sys = 3 -fs_rec.sys = 3 -msfs.sys = 3 -mup.sys = 3 -npfs.sys = 3 -ntfs.sys = 3 -vfatfs.sys = 3 - -keyboard.sys = 3 -mouclass.sys = 3 -psaux.sys = 3 - -unbzip2.sys = 3 - -afd.sys = 3 -ne2000.sys = 3 -ndis.sys = 3 -npf.sys = 3 -;packet.sys = 3 -tcpip.sys = 3 -tdi.sys = 3 - -atapi.sys = 3 -cdrom.sys = 3 -class2.sys = 3 -disk.sys = 3 -scsiport.sys = 3 - -advapi32.dll = 2 -crtdll.dll = 2 -fmifs.dll = 2 -gdi32.dll = 2 -kernel32.dll = 2 -msafd.dll = 2 -msvcrt.dll = 2 -ntdll.dll = 2 -;ole32.dll = 2 -;oleaut32.dll = 2 -packet.dll = 2 -secur32.dll = 2 -;shell32.dll = 2 -user32.dll = 2 -version.dll = 2 -winedbgc.dll = 2 -winmm.dll = 2 -ws2_32.dll = 2 -ws2help.dll = 2 -wshirda.dll = 2 - -eventlog.exe = 2 -rpcss.exe = 2 -csrss.exe = 2 -ntvdm.exe = 2 -smss.exe = 2 -autochk.exe = 2 -gstart.exe = 2 -;lsass.exe = 2 -services.exe = 2 -shell.exe = 2 -winlogon.exe = 2 - -win32k.sys = 3 - -helb____.ttf = 6 -timr____.ttf = 6 - -system.hiv = 4 - -[SetupData] -DefaultPath = \reactos -- 1.8.3.1